From 0c6b4af7c43c2f791a3f8431c2061dc8757e928c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 31 Jul 2017 12:41:59 +0200 Subject: [PATCH 0001/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..fb128760 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-es_extended +FXServer ES Extended From 089dbcc1a5b3baa2eaca09b8f43d6c14d83cdaaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 31 Jul 2017 12:45:58 +0200 Subject: [PATCH 0002/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..ff49686e --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-async +FXServer Async From 9954bec81228b19479730969a76fb75afa2b3b0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 31 Jul 2017 12:46:59 +0200 Subject: [PATCH 0003/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..62c42769 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_menu_default +FXServer ESX Menu Default From 5bd0f9e9a5986d74ebc0465b712db6648d7a92bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 31 Jul 2017 12:48:36 +0200 Subject: [PATCH 0004/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..8bcad85e --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_menu_list +FXServer ESX Menu List From 73f0d5dd0ee5318e03b9bb5003573ef2e88df66a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 31 Jul 2017 12:49:49 +0200 Subject: [PATCH 0005/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..dd06a18e --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_menu_dialog +FXServer ESX Menu Dialog From 7aeae4820957198efac7b78eb8d77c81fff349d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 31 Jul 2017 12:52:06 +0200 Subject: [PATCH 0006/3224] Add files --- .../[essential]/es_extended/__resource.lua | 44 + .../es_extended/client/functions.lua | 781 ++++++++++++++++++ .../[essential]/es_extended/client/main.lua | 372 +++++++++ resources/[essential]/es_extended/config.lua | 89 ++ .../[essential]/es_extended/html/css/app.css | 101 +++ .../es_extended/html/fonts/bankgothic.ttf | Bin 0 -> 36272 bytes .../es_extended/html/fonts/pdown.ttf | Bin 0 -> 151512 bytes .../es_extended/html/img/accounts/bank.png | Bin 0 -> 1015 bytes .../html/img/accounts/black_money.png | Bin 0 -> 1030 bytes .../es_extended/html/img/cursor.png | Bin 0 -> 272 bytes .../es_extended/html/img/keys/enter.png | Bin 0 -> 941 bytes .../es_extended/html/img/keys/return.png | Bin 0 -> 376 bytes .../[essential]/es_extended/html/js/app.js | 114 +++ .../es_extended/html/js/mustache.min.js | 1 + .../[essential]/es_extended/html/ui.html | 16 + .../es_extended/server/classes/player.lua | 382 +++++++++ .../es_extended/server/commands.lua | 48 ++ .../[essential]/es_extended/server/common.lua | 28 + .../es_extended/server/functions.lua | 176 ++++ .../[essential]/es_extended/server/main.lua | 524 ++++++++++++ resources/[esx]/[ui]/esx_menu_default | 1 + resources/[esx]/[ui]/esx_menu_dialog | 1 + resources/[esx]/[ui]/esx_menu_list | 1 + resources/async | 1 + 24 files changed, 2680 insertions(+) create mode 100644 resources/[essential]/es_extended/__resource.lua create mode 100644 resources/[essential]/es_extended/client/functions.lua create mode 100644 resources/[essential]/es_extended/client/main.lua create mode 100644 resources/[essential]/es_extended/config.lua create mode 100644 resources/[essential]/es_extended/html/css/app.css create mode 100644 resources/[essential]/es_extended/html/fonts/bankgothic.ttf create mode 100644 resources/[essential]/es_extended/html/fonts/pdown.ttf create mode 100644 resources/[essential]/es_extended/html/img/accounts/bank.png create mode 100644 resources/[essential]/es_extended/html/img/accounts/black_money.png create mode 100644 resources/[essential]/es_extended/html/img/cursor.png create mode 100644 resources/[essential]/es_extended/html/img/keys/enter.png create mode 100644 resources/[essential]/es_extended/html/img/keys/return.png create mode 100644 resources/[essential]/es_extended/html/js/app.js create mode 100644 resources/[essential]/es_extended/html/js/mustache.min.js create mode 100644 resources/[essential]/es_extended/html/ui.html create mode 100644 resources/[essential]/es_extended/server/classes/player.lua create mode 100644 resources/[essential]/es_extended/server/commands.lua create mode 100644 resources/[essential]/es_extended/server/common.lua create mode 100644 resources/[essential]/es_extended/server/functions.lua create mode 100644 resources/[essential]/es_extended/server/main.lua create mode 160000 resources/[esx]/[ui]/esx_menu_default create mode 160000 resources/[esx]/[ui]/esx_menu_dialog create mode 160000 resources/[esx]/[ui]/esx_menu_list create mode 160000 resources/async diff --git a/resources/[essential]/es_extended/__resource.lua b/resources/[essential]/es_extended/__resource.lua new file mode 100644 index 00000000..4157559d --- /dev/null +++ b/resources/[essential]/es_extended/__resource.lua @@ -0,0 +1,44 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'ES Extended' + +server_scripts { + '@async/async.lua', + '@mysql-async/lib/MySQL.lua', + 'config.lua', + 'server/common.lua', + 'server/classes/player.lua', + 'server/functions.lua', + 'server/main.lua', + 'server/commands.lua' +} + +client_scripts { + 'config.lua', + 'client/functions.lua', + 'client/main.lua' +} + +ui_page { + 'html/ui.html' +} + +files { + + 'html/ui.html', + + 'html/css/app.css', + + 'html/js/mustache.min.js', + 'html/js/app.js', + + 'html/fonts/pdown.ttf', + 'html/fonts/bankgothic.ttf', + + 'html/img/cursor.png', + 'html/img/keys/enter.png', + 'html/img/keys/return.png', + + 'html/img/accounts/bank.png', + 'html/img/accounts/black_money.png' +} \ No newline at end of file diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua new file mode 100644 index 00000000..8e52a0b2 --- /dev/null +++ b/resources/[essential]/es_extended/client/functions.lua @@ -0,0 +1,781 @@ +local charset = {} + +for i = 48, 57 do table.insert(charset, string.char(i)) end +for i = 65, 90 do table.insert(charset, string.char(i)) end +for i = 97, 122 do table.insert(charset, string.char(i)) end + +ESX = {} +ESX.CurrentRequestId = 0 +ESX.ServerCallbacks = {} +ESX.TimeoutCallbacks = {} +ESX.UI = {} +ESX.UI.HUD = {} +ESX.UI.HUD.RegisteredElements = {} +ESX.UI.Menu = {} +ESX.UI.Menu.RegisteredTypes = {} +ESX.UI.Menu.Opened = {} +ESX.Game = {} + +ESX.GetRandomString = function(length) + + math.randomseed(GetGameTimer()) + + if length > 0 then + return ESX.GetRandomString(length - 1) .. charset[math.random(1, #charset)] + else + return '' + end + +end + +ESX.SetTimeout = function(msec, cb) + table.insert(ESX.TimeoutCallbacks, { + time = GetGameTimer() + msec, + cb = cb + }) +end + +ESX.ShowNotification = function(msg) + SetNotificationTextEntry('STRING') + AddTextComponentString(msg) + DrawNotification(0,1) +end + +ESX.TriggerServerCallback = function(name, cb, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z) + + ESX.ServerCallbacks[ESX.CurrentRequestId] = cb + + TriggerServerEvent('esx:triggerServerCallback', name, ESX.CurrentRequestId, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z) + + if ESX.CurrentRequestId < 65535 then + ESX.CurrentRequestId = ESX.CurrentRequestId + 1 + else + ESX.CurrentRequestId = 0 + end + +end + +ESX.UI.HUD.SetDisplay = function(opacity) + + SendNUIMessage({ + action = 'setHUDDisplay', + opacity = opacity + }) + +end + +ESX.UI.HUD.RegisterElement = function(name, index, priority, html, data) + + local found = false + + for i=1, #ESX.UI.HUD.RegisteredElements, 1 do + if ESX.UI.HUD.RegisteredElements[i] == name then + found = true + break + end + end + + if found then + return + end + + table.insert(ESX.UI.HUD.RegisteredElements, name) + + SendNUIMessage({ + action = 'insertHUDElement', + name = name, + index = index, + priority = priority, + html = html, + data = data, + }) + + ESX.UI.HUD.UpdateElement(name, data) + +end + +ESX.UI.HUD.RemoveElement = function(name) + + for i=1, #ESX.UI.HUD.RegisteredElements, 1 do + if ESX.UI.HUD.RegisteredElements[i] == name then + table.remove(ESX.UI.HUD.RegisteredElements, i) + break + end + end + + SendNUIMessage({ + action = 'deleteHUDElement', + name = name + }) + +end + +ESX.UI.HUD.UpdateElement = function(name, data) + + SendNUIMessage({ + action = 'updateHUDElement', + name = name, + data = data, + }) + +end + +ESX.UI.Menu.RegisterType = function(type, open, close) + + ESX.UI.Menu.RegisteredTypes[type] = { + open = open, + close = close, + } + +end + +ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change) + + local menu = {} + + menu.type = type + menu.namespace = namespace + menu.name = name + menu.data = data + menu.submit = submit + menu.cancel = cancel + menu.change = change + + menu.close = function() + + ESX.UI.Menu.RegisteredTypes[type].close(namespace, name) + + for i=1, #ESX.UI.Menu.Opened, 1 do + if ESX.UI.Menu.Opened[i].type == type and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then + ESX.UI.Menu.Opened[i] = nil + end + end + + end + + menu.update = function(query, newData) + + for i=1, #menu.data.elements, 1 do + + local match = true + + for k,v in pairs(query) do + if menu.data.elements[i][k] ~= v then + match = false + end + end + + if match then + for k,v in pairs(newData) do + menu.data.elements[i][k] = v + end + end + + ESX.UI.Menu.RegisteredTypes[type].open(namespace, name, menu.data) + + end + + end + + menu.setElement = function(i, key, val) + menu.data.elements[i][key] = val + end + + table.insert(ESX.UI.Menu.Opened, menu) + + ESX.UI.Menu.RegisteredTypes[type].open(namespace, name, data) + +end + +ESX.UI.Menu.Close = function(type, namespace, name) + + for i=1, #ESX.UI.Menu.Opened, 1 do + if ESX.UI.Menu.Opened[i].type == type and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then + ESX.UI.Menu.Opened[i].close() + ESX.UI.Menu.Opened[i] = nil + end + end + +end + +ESX.UI.Menu.CloseAll = function() + + for i=1, #ESX.UI.Menu.Opened, 1 do + ESX.UI.Menu.Opened[i].close() + ESX.UI.Menu.Opened[i] = nil + end + +end + +ESX.UI.Menu.GetOpened = function(type, namespace, name) + + for i=1, #ESX.UI.Menu.Opened, 1 do + if ESX.UI.Menu.Opened[i].type == type and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then + return ESX.UI.Menu.Opened[i] + end + end + +end + +ESX.UI.Menu.IsOpen = function(type, namespace, name) + return ESX.UI.Menu.GetOpened(type, namespace, name) ~= nil +end + +ESX.UI.ShowInventoryItemNotification = function(add, item, count) + SendNUIMessage({ + action = 'inventoryNotification', + add = add, + item = item, + count = count + }) +end + +ESX.GetWeaponList = function() + return Config.Weapons +end + +ESX.GetWeaponLabel = function(name) + + name = string.upper(name) + local weapons = ESX.GetWeaponList() + + for i=1, #weapons, 1 do + if weapons[i].name == name then + return weapons[i].label + end + end + +end + +ESX.Game.GetPlayers = function() + + local maxPlayers = Config.MaxPlayers + local players = {} + + for i=0, maxPlayers, 1 do + + local ped = GetPlayerPed(i) + + if DoesEntityExist(ped) then + table.insert(players, i) + end + end + + return players + +end + +ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) + + local playerPed = GetPlayerPed(-1) + local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) + + Citizen.CreateThread(function() + + RequestModel(model) + + while not HasModelLoaded(model) do + Citizen.Wait(0) + end + + local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, true, false) + + SetNetworkIdCanMigrate(id, true) + SetEntityAsMissionEntity(vehicle, true, true) + SetVehicleHasBeenOwnedByPlayer(vehicle, true) + SetModelAsNoLongerNeeded(model) + + RequestCollisionAtCoord(coords.x, coords.y, coords.z) + + while not HasCollisionLoadedAroundEntity(vehicle) do + RequestCollisionAtCoord(coords.x, coords.x, coords.x) + Citizen.Wait(0) + end + + local id = NetworkGetNetworkIdFromEntity(vehicle) + + if cb ~= nil then + cb(vehicle) + end + + end) + +end + +ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) + + local playerPed = GetPlayerPed(-1) + local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) + + Citizen.CreateThread(function() + + RequestModel(model) + + while not HasModelLoaded(model) do + Citizen.Wait(0) + end + + local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, false, false) + local id = NetworkGetNetworkIdFromEntity(vehicle) + + SetNetworkIdCanMigrate(id, true) + SetEntityAsMissionEntity(vehicle, true, true) + SetVehicleHasBeenOwnedByPlayer(vehicle, true) + SetModelAsNoLongerNeeded(model) + + RequestCollisionAtCoord(coords.x, coords.y, coords.z) + + while not HasCollisionLoadedAroundEntity(vehicle) do + RequestCollisionAtCoord(coords.x, coords.x, coords.x) + Citizen.Wait(0) + end + + if cb ~= nil then + cb(vehicle) + end + + end) + +end + +ESX.Game.GetClosestPlayer = function() + + local players = ESX.Game.GetPlayers() + local closestDistance = -1 + local closestPlayer = -1 + local playerPed = GetPlayerPed(-1) + local playerCoords = GetEntityCoords(playerPed) + + for i=1, #players, 1 do + + local target = GetPlayerPed(players[i]) + + -- if target ~= playerPed then + + local targetCoords = GetEntityCoords(target) + local distance = GetDistanceBetweenCoords(targetCoords.x, targetCoords.y, targetCoords.z, playerCoords.x, playerCoords.y, playerCoords.z, true) + + if closestDistance == -1 or closestDistance > distance then + closestPlayer = players[i] + closestDistance = distance + end + + -- end + + end + + return closestPlayer, closestDistance +end + +ESX.Game.GetPlayersInArea = function(coords, area) + + local players = ESX.Game.GetPlayers() + local playersInArea = {} + + for i=1, #players, 1 do + + local target = GetPlayerPed(players[i]) + local targetCoords = GetEntityCoords(target) + local distance = GetDistanceBetweenCoords(targetCoords.x, targetCoords.y, targetCoords.z, coords.x, coords.y, coords.z, true) + + if distance <= area then + table.insert(playersInArea, players[i]) + end + + end + + return playersInArea +end + +ESX.Game.GetVehicleProperties = function(vehicle) + + local colour1, colour2 = GetVehicleColours(vehicle) + local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) + + return { + + model = GetEntityModel(vehicle), + + plate = GetVehicleNumberPlateText(vehicle), + plateIndex = GetVehicleNumberPlateTextIndex(vehicle), + + health = GetEntityHealth(vehicle), + dirtLevel = GetVehicleDirtLevel(vehicle), + + color1 = colour1, + color2 = colour2, + pearlescentColor = pearlescentColor, + wheelColor = wheelColor, + + wheels = GetVehicleWheelType(vehicle), + windowTint = GetVehicleWindowTint(vehicle), + + neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), + + modSpoilers = GetVehicleMod(vehicle, 0), + modFrontBumper = GetVehicleMod(vehicle, 1), + modRearBumper = GetVehicleMod(vehicle, 2), + modSideSkirt = GetVehicleMod(vehicle, 3), + modExhaust = GetVehicleMod(vehicle, 4), + modFrame = GetVehicleMod(vehicle, 5), + modGrille = GetVehicleMod(vehicle, 6), + modHood = GetVehicleMod(vehicle, 7), + modFender = GetVehicleMod(vehicle, 8), + modRightFender = GetVehicleMod(vehicle, 9), + modRoof = GetVehicleMod(vehicle, 10), + + modEngine = GetVehicleMod(vehicle, 11), + modBrakes = GetVehicleMod(vehicle, 12), + modTransmission = GetVehicleMod(vehicle, 13), + modHorns = GetVehicleMod(vehicle, 14), + modSuspension = GetVehicleMod(vehicle, 15), + modArmor = GetVehicleMod(vehicle, 16), + + modTurbo = IsToggleModOn(vehicle, 18), + modXenon = IsToggleModOn(vehicle, 22), + + modFrontWheels = GetVehicleMod(vehicle, 23), + modBackWheels = GetVehicleMod(vehicle, 24) + } + +end + +ESX.Game.SetVehicleProperties = function(vehicle, props) + + SetVehicleModKit(vehicle, 0) + + if props.plate ~= nil then + SetVehicleNumberPlateText(vehicle, props.plate) + end + + if props.plateIndex ~= nil then + SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex) + end + + if props.health ~= nil then + SetEntityHealth(vehicle, props.health) + end + + if props.dirtLevel ~= nil then + SetVehicleDirtLevel(vehicle, props.dirtLevel) + end + + if props.color1 ~= nil and props.color2 ~= nil then + SetVehicleColours(vehicle, props.color1, props.color2) + end + + if props.pearlescentColor ~= nil and props.wheelColor ~= nil then + SetVehicleExtraColours(vehicle, props.pearlescentColor, props.wheelColor) + end + + if props.wheels ~= nil then + SetVehicleWheelType(vehicle, props.wheels) + end + + if props.windowTint ~= nil then + SetVehicleWindowTint(vehicle, props.windowTint) + end + + if props.neonColor ~= nil then + SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) + end + + if props.modSpoilers ~= nil then + SetVehicleMod(vehicle, 0, props.modSpoilers, false) + end + + if props.modFrontBumper ~= nil then + SetVehicleMod(vehicle, 1, props.modFrontBumper, false) + end + + if props.modRearBumper ~= nil then + SetVehicleMod(vehicle, 2, props.modRearBumper, false) + end + + if props.modSideSkirt ~= nil then + SetVehicleMod(vehicle, 3, props.modSideSkirt, false) + end + + if props.modExhaust ~= nil then + SetVehicleMod(vehicle, 4, props.modExhaust, false) + end + + if props.modFrame ~= nil then + SetVehicleMod(vehicle, 5, props.modFrame, false) + end + + if props.modGrille ~= nil then + SetVehicleMod(vehicle, 6, props.modGrille, false) + end + + if props.modHood ~= nil then + SetVehicleMod(vehicle, 7, props.modHood, false) + end + + if props.modFender ~= nil then + SetVehicleMod(vehicle, 8, props.modFender, false) + end + + if props.modRightFender ~= nil then + SetVehicleMod(vehicle, 9, props.modRightFender, false) + end + + if props.modRoof ~= nil then + SetVehicleMod(vehicle, 10, props.modRoof, false) + end + + if props.modEngine ~= nil then + SetVehicleMod(vehicle, 11, props.modEngine, false) + end + + if props.modBrakes ~= nil then + SetVehicleMod(vehicle, 12, props.modBrakes, false) + end + + if props.modTransmission ~= nil then + SetVehicleMod(vehicle, 13, props.modTransmission, false) + end + + if props.modHorns ~= nil then + SetVehicleMod(vehicle, 14, props.modHorns, false) + end + + if props.modSuspension ~= nil then + SetVehicleMod(vehicle, 15, props.modSuspension, false) + end + + if props.modArmor ~= nil then + SetVehicleMod(vehicle, 16, props.modArmor, false) + end + + if props.modTurbo ~= nil then + ToggleVehicleMod(vehicle, 18, props.modTurbo) + end + + if props.modXenon ~= nil then + ToggleVehicleMod(vehicle, 22, props.modXenon) + end + + if props.modFrontWheels ~= nil then + SetVehicleMod(vehicle, 23, props.modFrontWheels, false) + end + + if props.modBackWheels ~= nil then + SetVehicleMod(vehicle, 24, props.modBackWheels, false) + end + +end + +ESX.ShowInventory = function() + + ESX.TriggerServerCallback('esx:getPlayerData', function(data) + + local playerPed = GetPlayerPed(-1) + local elements = {} + + table.insert(elements, { + label = '[Cash] $' .. data.money, + count = data.money, + type = 'item_money', + value = 'money', + usable = false + }) + + for i=1, #data.accounts, 1 do + table.insert(elements, { + label = '[' .. data.accounts[i].label .. '] $' .. data.accounts[i].money, + count = data.accounts[i].money, + type = 'item_account', + value = data.accounts[i].name, + usable = false + }) + end + + for i=1, #data.inventory, 1 do + + if data.inventory[i].count > 0 then + table.insert(elements, { + label = data.inventory[i].label .. ' x' .. data.inventory[i].count, + count = data.inventory[i].count, + type = 'item_standard', + value = data.inventory[i].name, + usable = data.inventory[i].usable + }) + end + + end + + for i=1, #Config.Weapons, 1 do + + local weaponHash = GetHashKey(Config.Weapons[i].name) + + if HasPedGotWeapon(playerPed, weaponHash, false) and Config.Weapons[i].name ~= 'WEAPON_UNARMED' then + + local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) + + table.insert(elements, { + label = Config.Weapons[i].label .. ' x1 [' .. ammo .. ']', + count = 1, + type = 'item_weapon', + value = Config.Weapons[i].name, + usable = false + }) + + end + end + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'inventory', + { + title = 'Inventaire', + align = 'bottom-right', + elements = elements, + }, + function(data, menu) + + menu.close() + + local elements = {} + + if data.current.usable then + table.insert(elements, {label = 'Utiliser', action = 'use', type = data.current.type, value = data.current.value}) + end + + table.insert(elements, {label = 'Donner', action = 'give', type = data.current.type, value = data.current.value}) + table.insert(elements, {label = 'Jeter', action = 'remove', type = data.current.type, value = data.current.value}) + table.insert(elements, {label = 'Retour', action = 'return'}) + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'inventory_item', + { + title = 'Inventaire', + align = 'bottom-right', + elements = elements, + }, + function(data, menu) + + local item = data.current.value + local type = data.current.type + + if data.current.action == 'give' then + + if type == 'item_weapon' then + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 1) + else + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'inventory_item_count_give', + { + title = 'Quantité' + }, + function(data2, menu) + + local quantity = tonumber(data2.value) + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification('Aucun joueur à proximité') + else + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) + end + + menu.close() + end, + function(data2, menu) + menu.close() + end + ) + + end + + elseif data.current.action == 'remove' then + + if type == 'item_weapon' then + TriggerServerEvent('esx:removeInventoryItem', type, item, 1) + else + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'inventory_item_count_remove', + { + title = 'Quantité' + }, + function(data2, menu) + + local quantity = tonumber(data2.value) + + if quantity == nil then + ESX.ShowNotification('Montant invalide') + else + + menu.close() + + TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) + + end + + end, + function(data2, menu) + menu.close() + end + ) + + end + + elseif data.current.action == 'return' then + ESX.UI.Menu.CloseAll() + ESX.ShowInventory() + end + + end, + function(data, menu) + ESX.UI.Menu.CloseAll() + ESX.ShowInventory() + end + ) + + end, + function(data, menu) + menu.close() + end + ) + + end) + +end + +AddEventHandler('esx:getSharedObject', function(cb) + cb(ESX) +end) + +RegisterNetEvent('esx:serverCallback') +AddEventHandler('esx:serverCallback', function(requestId, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z) + ESX.ServerCallbacks[requestId](a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z) + ESX.ServerCallbacks[requestId] = nil +end) + +RegisterNetEvent('esx:showNotification') +AddEventHandler('esx:showNotification', function(msg) + ESX.ShowNotification(msg) +end) + +-- SetTimeout +Citizen.CreateThread(function() + while true do + + Citizen.Wait(0) + + local currTime = GetGameTimer() + + for i=1, #ESX.TimeoutCallbacks, 1 do + + if currTime >= ESX.TimeoutCallbacks[i].time then + ESX.TimeoutCallbacks[i].cb() + ESX.TimeoutCallbacks[i] = nil + end + + end + + end +end) \ No newline at end of file diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua new file mode 100644 index 00000000..a2e1adb1 --- /dev/null +++ b/resources/[essential]/es_extended/client/main.lua @@ -0,0 +1,372 @@ +local Keys = { + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, + ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, + ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, + ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, + ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 +} + +local GUI = {} +GUI.Time = 0 +local PlayerLoaded = false +local LoadoutLoaded = false +local IsPaused = false +local LastLoadout = {} + +RegisterNetEvent('esx:playerLoaded') +AddEventHandler('esx:playerLoaded', function(xPlayer) + + PlayerLoaded = true + + for i=1, #xPlayer.accounts, 1 do + + local accountTpl = '
 {{money}}
' + + ESX.UI.HUD.RegisterElement('account_' .. xPlayer.accounts[i].name, i-1, 0, accountTpl, { + money = 0 + }) + + ESX.UI.HUD.UpdateElement('account_' .. xPlayer.accounts[i].name, { + money = xPlayer.accounts[i].money + }) + + end + + local jobTpl = '
{{job_label}} - {{grade_label}}
' + + if xPlayer.job.grade_label == '' then + jobTpl = '
{{job_label}}
' + end + + ESX.UI.HUD.RegisterElement('job', #xPlayer.accounts, 0, jobTpl, { + job_label = '', + grade_label = '' + }) + + ESX.UI.HUD.UpdateElement('job', { + job_label = xPlayer.job.label, + grade_label = xPlayer.job.grade_label + }) + +end) + +AddEventHandler('playerSpawned', function() + + Citizen.CreateThread(function() + + while not PlayerLoaded do + Citizen.Wait(0) + end + + ESX.TriggerServerCallback('esx:getPlayerData', function(data) + + local playerPed = GetPlayerPed(-1) + + -- Restore position + if data.lastPosition ~= nil then + SetEntityCoords(playerPed, data.lastPosition.x, data.lastPosition.y, data.lastPosition.z) + end + + -- Restore loadout + for i=1, #data.loadout, 1 do + local weaponHash = GetHashKey(data.loadout[i].name) + GiveWeaponToPed(playerPed, weaponHash, data.loadout[i].ammo, false, false) + end + + LoadoutLoaded = true + + end) + + end) + +end) + +AddEventHandler('skinchanger:LoadDefaultModel', function() + LoadoutLoaded = false +end) + +AddEventHandler('skinchanger:modelLoaded', function() + + -- Restore loadout + ESX.TriggerServerCallback('esx:getPlayerData', function(data) + + local playerPed = GetPlayerPed(-1) + + for i=1, #data.loadout, 1 do + local weaponHash = GetHashKey(data.loadout[i].name) + GiveWeaponToPed(playerPed, weaponHash, data.loadout[i].ammo, false, false) + end + + LoadoutLoaded = true + + end) + +end) + +RegisterNetEvent('esx:setAccountMoney') +AddEventHandler('esx:setAccountMoney', function(account) + ESX.UI.HUD.UpdateElement('account_' .. account.name, { + money = account.money + }) +end) + +RegisterNetEvent('esx:addInventoryItem') +AddEventHandler('esx:addInventoryItem', function(item, count) + + ESX.UI.ShowInventoryItemNotification(true, item, count) + + if ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then + ESX.ShowInventory() + end + +end) + +RegisterNetEvent('esx:removeInventoryItem') +AddEventHandler('esx:removeInventoryItem', function(item, count) + + ESX.UI.ShowInventoryItemNotification(false, item, count) + + if ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then + ESX.ShowInventory() + end + +end) + +RegisterNetEvent('esx:addWeapon') +AddEventHandler('esx:addWeapon', function(weaponName, ammo) + local playerPed = GetPlayerPed(-1) + local weaponHash = GetHashKey(weaponName) + + GiveWeaponToPed(playerPed, weaponHash, ammo, false, false) +end) + +RegisterNetEvent('esx:removeWeapon') +AddEventHandler('esx:removeWeapon', function(weaponName) + local playerPed = GetPlayerPed(-1) + local weaponHash = GetHashKey(weaponName) + + RemoveWeaponFromPed(playerPed, weaponHash) +end) + +-- Commands +RegisterNetEvent('esx:teleport') +AddEventHandler('esx:teleport', function(pos) + + pos.x = pos.x + 0.0 + pos.y = pos.y + 0.0 + pos.z = pos.z + 0.0 + + RequestCollisionAtCoord(pos.x, pos.y, pos.z) + + while not HasCollisionLoadedAroundEntity(GetPlayerPed(-1)) do + RequestCollisionAtCoord(pos.x, pos.y, pos.z) + Citizen.Wait(0) + end + + SetEntityCoords(GetPlayerPed(-1), pos.x, pos.y, pos.z) + +end) + +RegisterNetEvent('esx:setJob') +AddEventHandler('esx:setJob', function(job) + ESX.UI.HUD.UpdateElement('job', { + job_label = job.label, + grade_label = job.grade_label + }) +end) + +RegisterNetEvent('esx:loadIPL') +AddEventHandler('esx:loadIPL', function(name) + + Citizen.CreateThread(function() + LoadMpDlcMaps() + EnableMpDlcMaps(true) + RequestIpl(name) + end) + +end) + +RegisterNetEvent('esx:unloadIPL') +AddEventHandler('esx:unloadIPL', function(name) + + Citizen.CreateThread(function() + RemoveIpl(name) + end) + +end) + +RegisterNetEvent('esx:playAnim') +AddEventHandler('esx:playAnim', function(dict, anim) + + Citizen.CreateThread(function() + + local pid = PlayerPedId() + + RequestAnimDict(dict) + + while not HasAnimDictLoaded(dict) do + Wait(0) + end + + TaskPlayAnim(pid, dict, anim, 1.0, -1.0, 20000, 0, 1, true, true, true) + + end) + +end) + +RegisterNetEvent('esx:playEmote') +AddEventHandler('esx:playEmote', function(emote) + + Citizen.CreateThread(function() + + local playerPed = GetPlayerPed(-1) + + TaskStartScenarioInPlace(playerPed, emote, 0, false); + Wait(20000) + ClearPedTasks(playerPed) + + end) + +end) + +RegisterNetEvent('esx:spawnVehicle') +AddEventHandler('esx:spawnVehicle', function(model) + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + ESX.Game.SpawnVehicle(model, coords, 90.0, function(vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + end) + +end) + +-- Pause menu disable HUD display +Citizen.CreateThread(function() + while true do + Citizen.Wait(1) + if IsPauseMenuActive() and not IsPaused then + IsPaused = true + TriggerEvent('es:setMoneyDisplay', 0.0) + ESX.UI.HUD.SetDisplay(0.0) + elseif not IsPauseMenuActive() and IsPaused then + IsPaused = false + TriggerEvent('es:setMoneyDisplay', 1.0) + ESX.UI.HUD.SetDisplay(1.0) + end + end +end) + +-- Save loadout +Citizen.CreateThread(function() + + while true do + + Wait(0) + + local playerPed = GetPlayerPed(-1) + local loadout = {} + local loadoutChanged = false + + if IsPedDeadOrDying(playerPed) then + LoadoutLoaded = false + end + + for i=1, #Config.Weapons, 1 do + + local weaponHash = GetHashKey(Config.Weapons[i].name) + + if HasPedGotWeapon(playerPed, weaponHash, false) and Config.Weapons[i].name ~= 'WEAPON_UNARMED' then + + local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) + + if LastLoadout[Config.Weapons[i].name] == nil or LastLoadout[Config.Weapons[i].name] ~= ammo then + loadoutChanged = true + end + + LastLoadout[Config.Weapons[i].name] = ammo + + table.insert(loadout, { + name = Config.Weapons[i].name, + ammo = ammo, + label = Config.Weapons[i].label + }) + + else + + if LastLoadout[Config.Weapons[i].name] ~= nil then + loadoutChanged = true + end + + LastLoadout[Config.Weapons[i].name] = nil + + end + + end + + if loadoutChanged and LoadoutLoaded then + TriggerServerEvent('esx:updateLoadout', loadout) + end + + end +end) + +-- Menu interactions +Citizen.CreateThread(function() + while true do + + Wait(0) + + if IsControlPressed(0, Keys["F2"]) and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') and (GetGameTimer() - GUI.Time) > 150 then + ESX.ShowInventory() + GUI.Time = GetGameTimer() + end + + end +end) + +-- Dot above head +if Config.ShowDotAbovePlayer then + + Citizen.CreateThread(function() + while true do + + Citizen.Wait(0) + + local players = ESX.Game.GetPlayers() + + for i = 1, #players, 1 do + if players[i] ~= PlayerId() then + local ped = GetPlayerPed(players[i]) + local headId = Citizen.InvokeNative(0xBFEFE3321A3F5015, ped, ('·'), false, false, '', false) + end + end + + end + end) + +end + +-- Disable wanted level +if Config.DisableWantedLevel then + + Citizen.CreateThread(function() + while true do + + Citizen.Wait(0) + + local playerId = PlayerId() + + if GetPlayerWantedLevel(playerId) ~= 0 then + SetPlayerWantedLevel(playerId, 0, false) + SetPlayerWantedLevelNow(playerId, false) + end + + end + end) + +end \ No newline at end of file diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua new file mode 100644 index 00000000..22f1c7c9 --- /dev/null +++ b/resources/[essential]/es_extended/config.lua @@ -0,0 +1,89 @@ +Config = {} +Config.MaxPlayers = 32 +Config.Accounts = {'bank', 'black_money'} +Config.AccountLabels = {bank = 'Banque', black_money = 'Argent Sale'} +Config.PaycheckInterval = 7 * 60000 +Config.ShowDotAbovePlayer = false +Config.DisableWantedLevel = true +Config.RemoveInventoryItemDelay = 5 * 60000 + +Config.Weapons = { + + {name = 'WEAPON_KNIFE', label = 'Couteau'}, + {name = 'WEAPON_NIGHTSTICK', label = 'Matraque'}, + {name = 'WEAPON_HAMMER', label = 'Marteau'}, + {name = 'WEAPON_BAT', label = 'Bat'}, + {name = 'WEAPON_GOLFCLUB', label = 'Club de golfe'}, + {name = 'WEAPON_CROWBAR', label = 'Pied de biche'}, + {name = 'WEAPON_PISTOL', label = 'Pistolet'}, + {name = 'WEAPON_COMBATPISTOL', label = 'Pistolet de combat'}, + {name = 'WEAPON_APPISTOL', label = 'Pistolet automatique'}, + {name = 'WEAPON_PISTOL50', label = 'Pistolet calibre 50'}, + {name = 'WEAPON_MICROSMG', label = 'Micro SMG'}, + {name = 'WEAPON_SMG', label = 'SMG'}, + {name = 'WEAPON_ASSAULTSMG', label = 'SMG d\'assaut'}, + {name = 'WEAPON_ASSAULTRIFLE', label = 'Fusil d\'assaut'}, + {name = 'WEAPON_CARBINERIFLE', label = 'Carabine d\'assaut'}, + {name = 'WEAPON_ADVANCEDRIFLE', label = 'Fusil avancé'}, + {name = 'WEAPON_MG', label = 'Mitrailleuse'}, + {name = 'WEAPON_COMBATMG', label = 'Mitrailleuse de combat'}, + {name = 'WEAPON_PUMPSHOTGUN', label = 'Fusil à pompe'}, + {name = 'WEAPON_SAWNOFFSHOTGUN', label = 'Carabine à canon scié'}, + {name = 'WEAPON_ASSAULTSHOTGUN', label = 'Carabine d\'assaut'}, + {name = 'WEAPON_BULLPUPSHOTGUN', label = 'Carabine Bullpup'}, + {name = 'WEAPON_STUNGUN', label = 'Tazer'}, + {name = 'WEAPON_SNIPERRIFLE', label = 'Fusil de sniper'}, + {name = 'WEAPON_HEAVYSNIPER', label = 'Fusil de sniper lourd'}, + {name = 'WEAPON_REMOTESNIPER', label = 'Fusil de sniper à distance'}, + {name = 'WEAPON_GRENADELAUNCHER', label = 'Lance-grenade'}, + {name = 'WEAPON_RPG', label = 'Lance-rocket'}, + {name = 'WEAPON_STINGER', label = 'Lance-Missile Stinger'}, + {name = 'WEAPON_MINIGUN', label = 'Minigun'}, + {name = 'WEAPON_GRENADE', label = 'Grenade'}, + {name = 'WEAPON_STICKYBOMB', label = 'Bombe collante'}, + {name = 'WEAPON_SMOKEGRENADE', label = 'Grenade fumigène'}, + {name = 'WEAPON_BZGAS', 'Grenade à gaz BZ'}, + {name = 'WEAPON_MOLOTOV', 'Cocktail molotov'}, + {name = 'WEAPON_FIREEXTINGUISHER', 'Extincteur'}, + {name = 'WEAPON_PETROLCAN', 'Jerrican d\'essence'}, + {name = 'WEAPON_DIGISCANNER', 'Digiscanner'}, + {name = 'WEAPON_BALL', 'Balle'}, + {name = 'WEAPON_SNSPISTOL', label = 'Pistolet SNS'}, + {name = 'WEAPON_BOTTLE', label = 'Bouteille'}, + {name = 'WEAPON_GUSENBERG', label = 'Balayeuse Gusenberg'}, + {name = 'WEAPON_SPECIALCARBINE', label = 'Carabine spéciale'}, + {name = 'WEAPON_HEAVYPISTOL', label = 'Pistolet lourd'}, + {name = 'WEAPON_BULLPUPRIFLE', label = 'Fusil Bullpup'}, + {name = 'WEAPON_DAGGER', label = 'Poignard'}, + {name = 'WEAPON_VINTAGEPISTOL', label = 'Pistolet vintage'}, + {name = 'WEAPON_FIREWORK', label = 'Feu d\'artifice'}, + {name = 'WEAPON_MUSKET', label = 'Mousquet'}, + {name = 'WEAPON_HEAVYSHOTGUN', label = 'Fusil à pompe lourd'}, + {name = 'WEAPON_MARKSMANRIFLE', label = 'Fusil Marksman'}, + {name = 'WEAPON_HOMINGLAUNCHER', label = 'Lance tête-chercheuse'}, + {name = 'WEAPON_PROXMINE', label = 'Mine de proximité'}, + {name = 'WEAPON_SNOWBALL', label = 'Boule de neige'}, + {name = 'WEAPON_FLAREGUN', label = 'Lance fusée de détresse'}, + {name = 'WEAPON_GARBAGEBAG', label = 'Sac poubelle'}, + {name = 'WEAPON_HANDCUFFS', label = 'Menottes'}, + {name = 'WEAPON_COMBATPDW', label = 'Arme de défense personnelle'}, + {name = 'WEAPON_MARKSMANPISTOL', label = 'Pistolet Marksman'}, + {name = 'WEAPON_KNUCKLE', label = 'Poing américain'}, + {name = 'WEAPON_HATCHET', label = 'Hachette'}, + {name = 'WEAPON_RAILGUN', label = 'Canon éléctrique'}, + {name = 'WEAPON_MACHETE', label = 'Machetta'}, + {name = 'WEAPON_MACHINEPISTOL', label = 'Pistolet mitrailleur'}, + {name = 'WEAPON_SWITCHBLADE', label = 'Couteau à cran d\'arrêt'}, + {name = 'WEAPON_REVOLVER', label = 'Revolver'}, + {name = 'WEAPON_DBSHOTGUN', label = 'Fusil à pompe double canon'}, + {name = 'WEAPON_COMPACTRIFLE', label = 'Fusil compact'}, + {name = 'WEAPON_AUTOSHOTGUN', label = 'Fusil à pompe automatique'}, + {name = 'WEAPON_BATTLEAXE', label = 'Hache de combat'}, + {name = 'WEAPON_COMPACTLAUNCHER', label = 'Lanceur compact'}, + {name = 'WEAPON_MINISMG', label = 'Mini SMG'}, + {name = 'WEAPON_PIPEBOMB', label = 'Bombe tuyau'}, + {name = 'WEAPON_POOLCUE', label = 'Queue de billard'}, + {name = 'WEAPON_WRENCH', label = 'Clé'}, + {name = 'GADGET_NIGHTVISION', label = 'Vision nocturne'}, + {name = 'GADGET_PARACHUTE', label = 'Parachute'}, +} \ No newline at end of file diff --git a/resources/[essential]/es_extended/html/css/app.css b/resources/[essential]/es_extended/html/css/app.css new file mode 100644 index 00000000..2f72814b --- /dev/null +++ b/resources/[essential]/es_extended/html/css/app.css @@ -0,0 +1,101 @@ +@font-face { + font-family: 'Pricedown'; + src: url('../fonts/pdown.ttf') /* TTF file for CSS3 browsers */ +} + +@font-face { + font-family: 'bankgothic'; + src: url('../fonts/bankgothic.ttf') /* TTF file for CSS3 browsers */ +} + +html { + overflow: hidden; +} + +#cursor { + position: absolute; + z-index: 999999; + display: none; +} + +#hud { + position : absolute; + font-family: 'Pricedown'; + font-size : 35px; + color : white; + padding : 4px; + text-shadow: + -1px -1px 0 #000, + 1px -1px 0 #000, + -1px 1px 0 #000, + 1px 1px 0 #000; + + text-align: right; + top : 80; + right : 40; +} + +#inventory_notifications { + font-family: bankgothic; + position : absolute; + right : 40; + bottom : 40; + font-size : 2em; + font-weight: bold; + color : #FFF; + text-shadow: + -1px -1px 0 #000, + 1px -1px 0 #000, + -1px 1px 0 #000, + 1px 1px 0 #000; +} + +.menu { + font-family: 'Open Sans', sans-serif; + min-width : 400px; + min-height: : 250px; + color : #fff; + position : absolute; + left : 40; + top : 0; +} + +.menu .head { + font-family: 'Open Sans', sans-serif; + font-size: 28px; + padding: 10px; + background: #1A1A1A; + border-bottom: 3px solid #BC1635; + border-radius: 10px 10px 0 0; + -webkit-border-radius: 10px 10px 0 0; + -moz-border-radius: 10px 10px 0 0; + -o-border-radius: 10px 10px 0 0; + box-shadow: inset 0px 1px 0 rgba(255, 255, 255, 0.28); + -webkit-box-shadow: inset 0px 1px 0 rgba(255, 255, 255, 0.28); + -moz-box-shadow: inset 0px 1px 0 rgba(255, 255, 255, 0.28); + -o-box-shadow: inset 0px 1px 0 rgba(255, 255, 255, 0.28); + box-shadow: 1px 1px 10px 4px rgba(0, 0, 0, 0.4); +} +.menu .head span { + font-family: 'Pricedown'; + font-size: 28px; + padding-left: 15px; + padding-top: 6px; +} + +.menu .menu-items .menu-item { + font-family : 'Open Sans', sans-serif; + font-size : 14px; + height : 40px; + display : block; + background-color: #f1f1f1; + box-shadow : inset 1px 0px 0px 1px #b8b8b8; + height : 32px; + line-height : 32px; + color : #3A3A3A; + text-align : center; +} + +.menu .menu-items .menu-item.selected { + background-color: #ccc; +} diff --git a/resources/[essential]/es_extended/html/fonts/bankgothic.ttf b/resources/[essential]/es_extended/html/fonts/bankgothic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f3d8049b052a1f9cfd27557eb3675bc85ce4b9fc GIT binary patch literal 36272 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 D`#l06 literal 0 HcmV?d00001 diff --git a/resources/[essential]/es_extended/html/fonts/pdown.ttf b/resources/[essential]/es_extended/html/fonts/pdown.ttf new file mode 100644 index 0000000000000000000000000000000000000000..69c76cf3f2a6bbc93f570124554fec06d7bbac25 GIT binary patch literal 151512 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 literal 0 HcmV?d00001 diff --git a/resources/[essential]/es_extended/html/img/accounts/bank.png b/resources/[essential]/es_extended/html/img/accounts/bank.png new file mode 100644 index 0000000000000000000000000000000000000000..eb36dc8e70242136858874dc04024f41a4a0ffe4 GIT binary patch literal 1015 zcmV(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZowVTiq@}o(XxOP=4eyC973P=U1kRsFroRJ#! z(58{#776h;aLEM;L{SeVNSr|QQXy1+3PCF$LRAh>$;D}$6yr9(+&K1ncOM65H{N(1 z#D$Kuhc`R(oq6-#%=d|SpP}3h7iYue{}eqbkx7XFRFr{CNQ8)Xb~jy=7uE?4gk`F&OBwm4 zCoMHTH>$?xM%AIWM*@A{$sTp={U_D<+^9-VTDxK-EK`kLJ+5RzDnM!ek$H}yvF_~J zI*(=_0U-a;0)z8Wb)S zQLZ90W&QVw7&*Bd#kDto4a&FO>rT+B>2t%_D-HHP*Nt0qx&3jG%#?*w*}g}u7*V?q zC7?WT9&9^T7ittfS!~IwsWS)S-1}*T;uj^>ZdO>nzDliBXXNxy;O7swHVm3ETF1EN z4>(O1#JYDsk>%W4c>Lb8d62J?Ix`%Uf2Yk(iFNB}y6}hU)_oQ5>d!CYZn)gNQs$4D zKRXVhm%qw}1`)u%qg{dS$JcVyN_M3G6VnGdaH2iso z*ZbP|p!QdtrOPGu48|kL$mfBbu>v}-m+cT8XD>e8k&fM(*Y<#MYaY*k@Ki@S_G~Xi l#{maD><5W>*iW*51^`FRlAF&_hJ*kB002ovPDHLkV1iBj&&U7( literal 0 HcmV?d00001 diff --git a/resources/[essential]/es_extended/html/img/accounts/black_money.png b/resources/[essential]/es_extended/html/img/accounts/black_money.png new file mode 100644 index 0000000000000000000000000000000000000000..a42f6aa5191115bd04d04a728fb3c3463e6f4345 GIT binary patch literal 1030 zcmV+h1o``kP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZT+Hn2g&!y2+1h(>773hKd&LYji7 zJxDS2q!OyV*_F1(HYnsEh!-iPJ(ZSP4aAjfgeH{rV4AN*TFttfb$4bmZx7v>?##{# z?V&y}hv%8+>;1pa$1D1}yJgw3cww6SpVXsi=&FhUWSBxsRZ)ZpHLjQ@PC%vrF-;5A zcci3ZS)uWZC+3;63 zP5NhNQG_7k$iD&Ti^Y6K$y>Lur5_yG;D0)PoSwjGx9WA?yK@Hs5kM{?1izg=O;;2A zE;12U>4j-}Ke7u86iTH~$S#kLGN9`%@&R4v!+raho}Ul3%PuT1H9YLaYQ8!YA?Of- zVztV(#YN7~&4oJYkHxr{N_qVKVv+mBqQ_rKrRWbJ>C*YRIj$`(Qmj_#5W-hqGN!6> zV{%d^3_~`GGW5GJG9sN!Mmm{{ygWMU$&U>V%5RSxkxnKfFN}=5(nrED_VAxIbo05=N-zC3)GHzE;!+1%vw@o_Ie!Z2_5K&81r!?IKr zh1|)L^k^EFQYm)L%mA>fvlD<*LqnXsdzb!LjLmA5H@mvL+HiFMpO3e$U&jh*>&SnZ zV$Kc?zZa1REj@pHO6~;d1>2x z`tTvs=`>qSb=2%5?DW0_oIrm*E|tjU^S*KVxKv_5*ZFQ`g|C;En1A||AJ*1bt5o_1QC~4jk~{59$PIcV{Q6qIgLP zKq^8|I&+4yWpT4m;NyGu+76Wq2dk9|S8_RzKNyeuf?vty+6KQmHpaPRl6W-Aj+7n(5dsSW zU}|`nua=fVm(h*oWj@%uw`CvvUM_QEd6{>0J#-nldmtFgTgU5_if`vg<{vZ*r`$_iK0G#)*@UBUHMF0Q*07*qoM6N<$f`k9( AtN;K2 literal 0 HcmV?d00001 diff --git a/resources/[essential]/es_extended/html/img/cursor.png b/resources/[essential]/es_extended/html/img/cursor.png new file mode 100644 index 0000000000000000000000000000000000000000..39536f953d701b36a90dc56084bafd988371a2fb GIT binary patch literal 272 zcmeAS@N?(olHy`uVBq!ia0vp^q9Dw{1|(OCFP#RYSkfJR9T^xl_H+M9WCij$3p^r= z85sBufiR<}hF1enP_o1|q9iy!t)x7$D3zfgF*C13FE6!3!9>qM&(L5k7uNxxqFzrI z#}Etut!FreS`>I(0^ikVp5f1PInc0ibrsXWO3z8Ee_BE>W<&%Ean9H1Y|@_Ma)5tI zP3vrppG@U}o4EJ`H!a-_TKCSz%v`zHX&3lrYRgJzbSuAt9 z@6PvoS_%Jm+&BGp_A+yZ?Fo&SwU@JtJ?kA`YTb#E`^&mC!8qZZWp1Mjt5em&H79@$ OWAJqKb6Mw<&;$S!<6)ox literal 0 HcmV?d00001 diff --git a/resources/[essential]/es_extended/html/img/keys/enter.png b/resources/[essential]/es_extended/html/img/keys/enter.png new file mode 100644 index 0000000000000000000000000000000000000000..3eb9a1f69f58c651517329c92d28cdb1c605f165 GIT binary patch literal 941 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h5*QjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ISV`@iy0XB4ude`@%$Aj3=GUpo-U3d6>)E`8wN=`3bZEbov^iFaeu%P z(=cbwj44wlOz4rm5xb{;*Ri~}uR6cp(A&Mg;nJ7c^H#o^DiE{vT2%I1{SRyZiuLSP z%I`LO*R@CY*bePa+aw;ZJ8?S+Bq+DcEWq?az(jNYVCfZ787ofAZePh8!fO)pBkQX z_v_cMN3~tQ9xnRXb?ICkwaPbd-|8+sfB5~ocaKb5*$ZEQP2MMD?ps&IpveBkTdrZ6 zxw-l0$rY8AfmJN&5XWi1Tr~N;qpPCYQm=EdrvtPXJvz5h@~FDPw92D`R+fPvAFW@~ zU8c75`%1Gbh1a`Q>?qE0`*<(h^|W${-y)Ec<2}XS`n>x2)3WZB?5;)4TWYMP-*<76OIq zPp@4X%Z+C%*K#BUX=ORzsAov;Kl`m>i&y`Jz)nzj*Qmyplm-1%6v*YUbiCHwmEO<$ zF|Z@`-}HhOKR<9>X}?rT5Bm9ye^tw4euv}#-v4JmQzRDkY{|X*_d_{Xwfto_xNQ|y z-^Qlff58%JWZtYCU#*y5vIf?_WBTiPU(9hK5Tmx!-~Iodkpb3zr{Lwk`bljQz#(xy zvE05v9vtTHlU}QP{nuV*08Uf+$??{$l9IqgWxio$Zh{XeF$LeaxXn-#^iFnsKzTLkWYeXNfKEXTvUB0pJdzPZ}OMgdS+TyQ( lJso37+@RE7f9~qla<)GklNn{1`ISV`@iy0XBj({-ZRBb+Kpaxz~7srr_xVN`&cQqS`I9#;&|Ns0smZ-L@ zqu)%cbtmkrE=&Hfsn_t^{^k|)kLw3AbqG7mVR+;>`#|k>^_ZL6&QAQlndu0pf*(U6 zREkAFy}^PJuTYF$!{g|Ur7IbD{_6-gJlsE>3DGO)9eE;D=anIC*ESQi{xCV$~42}L!4TJCrkQD1~tJw zr&teYqgpL=o@s|#!;B|~71m*K { + + ESX = {}; + ESX.HUDElements = []; + + ESX.setHUDDisplay = function(opacity){ + $('#hud').css('opacity', opacity); + } + + ESX.insertHUDElement = function(name, index, priority, html, data){ + + ESX.HUDElements.push({ + name : name, + index : index, + priority : priority, + html : html, + data : data + }) + + ESX.HUDElements.sort((a,b) => { + return a.index - b.index || b.priority - a.priority; + }) + + } + + ESX.updateHUDElement = function(name, data){ + + for(let i=0; i' + notif + ''); + + $('#inventory_notifications').append(elem); + + $(elem).delay(3000).fadeOut(1000, function(){ + elem.remove(); + }) + } + + window.onData = (data) => { + + switch(data.action){ + + case 'setHUDDisplay' : { + ESX.setHUDDisplay(data.opacity); + break; + } + + case 'insertHUDElement' : { + ESX.insertHUDElement(data.name, data.index, data.priority, data.html, data.data); + break; + } + + case 'updateHUDElement' : { + ESX.updateHUDElement(data.name, data.data); + break; + } + + case 'deleteHUDElement' : { + ESX.deleteHUDElement(data.name); + break; + } + + case 'inventoryNotification' : { + ESX.inventoryNotification(data.add, data.item, data.count) + } + + } + + } + + window.onload = function(e){ + window.addEventListener('message', (event) => { + onData(event.data) + }); + } + +})() \ No newline at end of file diff --git a/resources/[essential]/es_extended/html/js/mustache.min.js b/resources/[essential]/es_extended/html/js/mustache.min.js new file mode 100644 index 00000000..520cfcb9 --- /dev/null +++ b/resources/[essential]/es_extended/html/js/mustache.min.js @@ -0,0 +1 @@ +(function defineMustache(global,factory){if(typeof exports==="object"&&exports&&typeof exports.nodeName!=="string"){factory(exports)}else if(typeof define==="function"&&define.amd){define(["exports"],factory)}else{global.Mustache={};factory(global.Mustache)}})(this,function mustacheFactory(mustache){var objectToString=Object.prototype.toString;var isArray=Array.isArray||function isArrayPolyfill(object){return objectToString.call(object)==="[object Array]"};function isFunction(object){return typeof object==="function"}function typeStr(obj){return isArray(obj)?"array":typeof obj}function escapeRegExp(string){return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}function hasProperty(obj,propName){return obj!=null&&typeof obj==="object"&&propName in obj}var regExpTest=RegExp.prototype.test;function testRegExp(re,string){return regExpTest.call(re,string)}var nonSpaceRe=/\S/;function isWhitespace(string){return!testRegExp(nonSpaceRe,string)}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(string){return String(string).replace(/[&<>"'`=\/]/g,function fromEntityMap(s){return entityMap[s]})}var whiteRe=/\s*/;var spaceRe=/\s+/;var equalsRe=/\s*=/;var curlyRe=/\s*\}/;var tagRe=/#|\^|\/|>|\{|&|=|!/;function parseTemplate(template,tags){if(!template)return[];var sections=[];var tokens=[];var spaces=[];var hasTag=false;var nonSpace=false;function stripSpace(){if(hasTag&&!nonSpace){while(spaces.length)delete tokens[spaces.pop()]}else{spaces=[]}hasTag=false;nonSpace=false}var openingTagRe,closingTagRe,closingCurlyRe;function compileTags(tagsToCompile){if(typeof tagsToCompile==="string")tagsToCompile=tagsToCompile.split(spaceRe,2);if(!isArray(tagsToCompile)||tagsToCompile.length!==2)throw new Error("Invalid tags: "+tagsToCompile);openingTagRe=new RegExp(escapeRegExp(tagsToCompile[0])+"\\s*");closingTagRe=new RegExp("\\s*"+escapeRegExp(tagsToCompile[1]));closingCurlyRe=new RegExp("\\s*"+escapeRegExp("}"+tagsToCompile[1]))}compileTags(tags||mustache.tags);var scanner=new Scanner(template);var start,type,value,chr,token,openSection;while(!scanner.eos()){start=scanner.pos;value=scanner.scanUntil(openingTagRe);if(value){for(var i=0,valueLength=value.length;i0?sections[sections.length-1][4]:nestedTokens;break;default:collector.push(token)}}return nestedTokens}function Scanner(string){this.string=string;this.tail=string;this.pos=0}Scanner.prototype.eos=function eos(){return this.tail===""};Scanner.prototype.scan=function scan(re){var match=this.tail.match(re);if(!match||match.index!==0)return"";var string=match[0];this.tail=this.tail.substring(string.length);this.pos+=string.length;return string};Scanner.prototype.scanUntil=function scanUntil(re){var index=this.tail.search(re),match;switch(index){case-1:match=this.tail;this.tail="";break;case 0:match="";break;default:match=this.tail.substring(0,index);this.tail=this.tail.substring(index)}this.pos+=match.length;return match};function Context(view,parentContext){this.view=view;this.cache={".":this.view};this.parent=parentContext}Context.prototype.push=function push(view){return new Context(view,this)};Context.prototype.lookup=function lookup(name){var cache=this.cache;var value;if(cache.hasOwnProperty(name)){value=cache[name]}else{var context=this,names,index,lookupHit=false;while(context){if(name.indexOf(".")>0){value=context.view;names=name.split(".");index=0;while(value!=null&&index")value=this.renderPartial(token,context,partials,originalTemplate);else if(symbol==="&")value=this.unescapedValue(token,context);else if(symbol==="name")value=this.escapedValue(token,context);else if(symbol==="text")value=this.rawValue(token);if(value!==undefined)buffer+=value}return buffer};Writer.prototype.renderSection=function renderSection(token,context,partials,originalTemplate){var self=this;var buffer="";var value=context.lookup(token[1]);function subRender(template){return self.render(template,context,partials)}if(!value)return;if(isArray(value)){for(var j=0,valueLength=value.length;j + + + + + +
+
+ + + + + + + + \ No newline at end of file diff --git a/resources/[essential]/es_extended/server/classes/player.lua b/resources/[essential]/es_extended/server/classes/player.lua new file mode 100644 index 00000000..954dcf63 --- /dev/null +++ b/resources/[essential]/es_extended/server/classes/player.lua @@ -0,0 +1,382 @@ +function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, lastPosition) + + local self = {} + + self.player = player + self.accounts = accounts + self.inventory = inventory + self.job = job + self.loadout = loadout + self.name = name + self.lastPosition = lastPosition + + self.source = self.player.get('source') + self.identifier = self.player.get('identifier') + + self.setMoney = function(m) + self.player.setMoney(m) + end + + self.getMoney = function() + return self.player.get('money') + end + + self.setBankBalance = function(m) + self.player.setBankBalance(m) + end + + self.getBank = function() + return self.player.get('bank') + end + + self.getCoords = function() + return self.player.get('coords') + end + + self.setCoords = function(x, y, z) + self.player.coords = {x = x, y = y, z = z} + end + + self.kick = function(r) + self.player.kick(r) + end + + self.addMoney = function(m) + self.player.addMoney(m) + end + + self.removeMoney = function(m) + self.player.removeMoney(m) + end + + self.addBank = function(m) + self.player.addBank(m) + end + + self.removeBank = function(m) + self.player.removeBank(m) + end + + self.displayMoney = function(m) + self.player.displayMoney(m) + end + + self.displayBank = function(m) + self.player.displayBank(m) + end + + self.setSessionVar = function(key, value) + self.player.setSessionVar(key, value) + end + + self.getSessionVar = function(k) + return self.player.getSessionVar(k) + end + + self.getPermissions = function() + return self.player.getPermissions() + end + + self.setPermissions = function(p) + self.player.setPermissions(p) + end + + self.getIdentifier = function() + return self.player.getIdentifier() + end + + self.getGroup = function() + return self.player.getGroup() + end + + self.set = function(k, v) + self.player.set(k, v) + end + + self.get = function(k) + return self.player.get(k) + end + + self.getPlayer = function() + return self.player + end + + self.getAccounts = function() + + local accounts = {} + + for i=1, #Config.Accounts, 1 do + + if Config.Accounts[i] == 'bank' then + + table.insert(accounts, { + name = 'bank', + money = self.get('bank'), + label = Config.AccountLabels['bank'] + }) + + else + + for j=1, #self.accounts, 1 do + if self.accounts[j].name == Config.Accounts[i] then + table.insert(accounts, self.accounts[j]) + end + end + + end + end + + return accounts + + end + + self.getAccount = function(a) + + if a == 'bank' then + + return { + name = 'bank', + money = self.get('bank'), + label = Config.AccountLabels['bank'] + } + + end + + for i=1, #self.accounts, 1 do + if self.accounts[i].name == a then + return self.accounts[i] + end + end + end + + self.getInventory = function() + return self.inventory + end + + self.getJob = function() + return self.job + end + + self.getLoadout = function() + return self.loadout + end + + self.getName = function() + return self.name + end + + self.getLastPosition = function() + return self.lastPosition + end + + self.getMissingAccounts = function(cb) + + MySQL.Async.fetchAll( + 'SELECT * FROM `user_accounts` WHERE `identifier` = @identifier', + { + ['@identifier'] = self.getIdentifier() + }, + function(result) + + local missingAccounts = {}; + + for i=1, #Config.Accounts, 1 do + + if Config.Accounts[i] ~= 'bank' then + + local found = false + + for j=1, #result, 1 do + if Config.Accounts[i] == result[j].name then + found = true + end + end + + if not found then + table.insert(missingAccounts, Config.Accounts[i]) + end + + end + + end + + cb(missingAccounts) + + end + ) + + end + + self.createAccounts = function(missingAccounts, cb) + + for i=1, #missingAccounts, 1 do + MySQL.Async.execute( + 'INSERT INTO `user_accounts` (identifier, name) VALUES (@identifier, @name)', + { + ['@identifier'] = self.getIdentifier(), + ['@name'] = missingAccounts[i] + }, + function(rowsChanged) + if cb ~= nil then + cb() + end + end + ) + end + + end + + self.setAccountMoney = function(a, m) + + local account = self.getAccount(a) + local prevMoney = account.money + local newMoney = m + + account.money = newMoney + + if a == 'bank' then + self.set('bank', newMoney) + end + + TriggerClientEvent('esx:setAccountMoney', self.source, account) + end + + self.addAccountMoney = function(a, m) + + local account = self.getAccount(a) + local newMoney = account.money + m + + account.money = newMoney + + if a == 'bank' then + self.set('bank', newMoney) + end + + TriggerClientEvent('esx:setAccountMoney', self.source, account) + end + + self.removeAccountMoney = function(a, m) + local account = self.getAccount(a) + local newMoney = account.money - m + + account.money = newMoney + + if a == 'bank' then + self.set('bank', newMoney) + end + + TriggerClientEvent('esx:setAccountMoney', self.source, account) + end + + self.getInventoryItem = function(name) + + for i=1, #self.inventory, 1 do + if self.inventory[i].name == name then + return self.inventory[i] + end + end + + end + + self.addInventoryItem = function(name, count) + + local item = self.getInventoryItem(name) + local newCount = item.count + count + item.count = newCount + + TriggerEvent("esx:onAddInventoryItem", self.source, item, count) + TriggerClientEvent("esx:addInventoryItem", self.source, item, count) + + end + + self.removeInventoryItem = function(name, count) + + local item = self.getInventoryItem(name) + local newCount = item.count - count + item.count = newCount + + TriggerEvent("esx:onRemoveInventoryItem", self.source, item, count) + TriggerClientEvent("esx:removeInventoryItem", self.source, item, count) + + end + + self.setJob = function(name, grade) + + MySQL.Async.fetchAll( + 'SELECT * FROM `jobs` WHERE `name` = @name', + { + ['@name'] = name + }, + function(result) + + self.job['id'] = result[1].id + self.job['name'] = result[1].name + self.job['label'] = result[1].label + + MySQL.Async.fetchAll( + 'SELECT * FROM `job_grades` WHERE `job_name` = @job_name AND `grade` = @grade', + { + ['@job_name'] = name, + ['@grade'] = grade + }, + function(result) + + self.job['grade'] = grade + self.job['grade_name'] = result[1].name + self.job['grade_label'] = result[1].label + self.job['grade_salary'] = result[1].salary + + self.job['skin_male'] = nil + self.job['skin_female'] = nil + + if result[1].skin_male ~= nil then + self.job['skin_male'] = json.decode(result[1].skin_male) + end + + if result[1].skin_female ~= nil then + self.job['skin_female'] = json.decode(result[1].skin_female) + end + + TriggerClientEvent("esx:setJob", self.source, self.job) + + end + ) + + end + ) + + end + + self.addWeapon = function(weaponName, ammo) + + local weaponLabel = weaponName + + for i=1, #Config.Weapons, 1 do + if Config.Weapons[i].name == weaponName then + weaponLabel = Config.Weapons[i].label + break + end + end + + TriggerClientEvent('esx:addWeapon', self.source, weaponName, ammo) + TriggerClientEvent("esx:addInventoryItem", self.source, {label = weaponLabel}, 1) + end + + self.removeWeapon = function(weaponName) + + local weaponLabel = weaponName + + for i=1, #Config.Weapons, 1 do + if Config.Weapons[i].name == weaponName then + weaponLabel = Config.Weapons[i].label + break + end + end + + TriggerClientEvent('esx:removeWeapon', self.source, weaponName) + TriggerClientEvent("esx:removeInventoryItem", self.source, {label = weaponLabel}, 1) + end + + return self + +end \ No newline at end of file diff --git a/resources/[essential]/es_extended/server/commands.lua b/resources/[essential]/es_extended/server/commands.lua new file mode 100644 index 00000000..2d4ccc12 --- /dev/null +++ b/resources/[essential]/es_extended/server/commands.lua @@ -0,0 +1,48 @@ +TriggerEvent('es:addGroupCommand', 'tp', 'admin', function(source, args, user) + + TriggerClientEvent("esx:teleport", source, { + x = tonumber(args[2]), + y = tonumber(args[3]), + z = tonumber(args[4]) + }) + +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end) + +TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, user) + local xPlayer = ESX.GetPlayerFromId(args[2]) + xPlayer.setJob(args[3], tonumber(args[4])) +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end, {help = 'Assigner job => setjob [id] [job] [grade_id]'}) + +TriggerEvent('es:addGroupCommand', 'loadipl', 'admin', function(source, args, user) + TriggerClientEvent('esx:loadIPL', -1, args[2]) +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end, {help = 'Charger ipl'}) + +TriggerEvent('es:addGroupCommand', 'unloadipl', 'admin', function(source, args, user) + TriggerClientEvent('esx:unloadIPL', -1, args[2]) +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end, {help = 'Décharger ipl'}) + +TriggerEvent('es:addGroupCommand', 'playanim', 'admin', function(source, args, user) + TriggerClientEvent('esx:playAnim', -1, args[2], args[3]) +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end, {help = 'Jouer animation'}) + +TriggerEvent('es:addGroupCommand', 'playemote', 'admin', function(source, args, user) + TriggerClientEvent('esx:playEmote', -1, args[2]) +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end, {help = 'Jouer emote'}) + +TriggerEvent('es:addGroupCommand', 'car', 'admin', function(source, args, user) + TriggerClientEvent('esx:spawnVehicle', source, args[2]) +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end, {help = 'Spawn un véhicule'}) \ No newline at end of file diff --git a/resources/[essential]/es_extended/server/common.lua b/resources/[essential]/es_extended/server/common.lua new file mode 100644 index 00000000..915707f8 --- /dev/null +++ b/resources/[essential]/es_extended/server/common.lua @@ -0,0 +1,28 @@ +ESX = {} +ESX.Players = {} +ESX.UsableItemsCallbacks = {} +ESX.Items = {} +ESX.ServerCallbacks = {} + +AddEventHandler('esx:getSharedObject', function(cb) + cb(ESX) +end) + +AddEventHandler('onMySQLReady', function () + + MySQL.Async.fetchAll( + 'SELECT * FROM items', + {}, + function(result) + + for i=1, #result, 1 do + ESX.Items[result[i].name] = { + label = result[i].label, + limit = result[i].limit + } + end + + end + ) + +end) \ No newline at end of file diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua new file mode 100644 index 00000000..44b01413 --- /dev/null +++ b/resources/[essential]/es_extended/server/functions.lua @@ -0,0 +1,176 @@ +local charset = {} + +for i = 48, 57 do table.insert(charset, string.char(i)) end +for i = 65, 90 do table.insert(charset, string.char(i)) end +for i = 97, 122 do table.insert(charset, string.char(i)) end + +ESX.GetRandomString = function(length) + + math.randomseed(os.time()) + + if length > 0 then + return ESX.GetRandomString(length - 1) .. charset[math.random(1, #charset)] + else + return '' + end + +end + +ESX.RegisterServerCallback = function(name, cb) + ESX.ServerCallbacks[name] = cb +end + +ESX.TriggerServerCallback = function(name, requestId, source, cb, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z) + ESX.ServerCallbacks[name](source, cb, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z) +end + +ESX.SavePlayer = function(xPlayer, cb) + + local asyncTasks = {} + xPlayer.lastPosition = xPlayer.get('coords') + + -- User accounts + for i=1, #xPlayer.accounts, 1 do + + table.insert(asyncTasks, function(cb) + + MySQL.Async.execute( + 'UPDATE user_accounts SET `money` = @money WHERE identifier = @identifier AND name = @name', + { + ['@money'] = xPlayer.accounts[i].money, + ['@identifier'] = xPlayer.identifier, + ['@name'] = xPlayer.accounts[i].name + }, + function(rowsChanged) + cb() + end + ) + + end) + + end + + -- Inventory items + for i=1, #xPlayer.inventory, 1 do + + table.insert(asyncTasks, function(cb) + + MySQL.Async.execute( + 'UPDATE user_inventory SET `count` = @count WHERE identifier = @identifier AND item = @item', + { + ['@count'] = xPlayer.inventory[i].count, + ['@identifier'] = xPlayer.identifier, + ['@item'] = xPlayer.inventory[i].name + }, + function(rowsChanged) + cb() + end + ) + + end) + + end + + -- Job, loadout and position + table.insert(asyncTasks, function(cb) + + MySQL.Async.execute( + 'UPDATE users SET `job` = @job, `job_grade` = @job_grade, `loadout` = @loadout, `position` = @position WHERE identifier = @identifier', + { + ['@job'] = xPlayer.job.name, + ['@job_grade'] = xPlayer.job.grade, + ['@loadout'] = json.encode(xPlayer.loadout), + ['@position'] = json.encode(xPlayer.lastPosition), + ['@identifier'] = xPlayer.identifier + }, + function(rowsChanged) + cb() + end + ) + + end) + + Async.parallel(asyncTasks, function(results) + + RconPrint('[SAVED] ' .. xPlayer.name .. "\n") + + if cb ~= nil then + cb() + end + + end) + +end + +ESX.SavePlayers = function(cb) + + local asyncTasks = {} + local players = ESX.GetPlayers() + + for k,v in pairs(players) do + table.insert(asyncTasks, function(cb) + ESX.SavePlayer(v, cb) + end) + end + + Async.parallelLimit(asyncTasks, 15, function(results) + + RconPrint('[SAVED] All players' .. "\n") + + if cb ~= nil then + cb() + end + + end) + +end + +ESX.StartDBSync = function() + + function saveData() + ESX.SavePlayers() + SetTimeout(60000, saveData) + end + + SetTimeout(60000, saveData) + +end + +ESX.GetPlayers = function() + return ESX.Players +end + +ESX.GetPlayerFromId = function(source) + return ESX.Players[tonumber(source)] +end + +ESX.GetPlayerFromIdentifier = function(identifier) + + for k,v in pairs(ESX.Players) do + if v.identifier == identifier then + return v + end + end + +end + +ESX.RegisterUsableItem = function(item, cb) + ESX.UsableItemsCallbacks[item] = cb +end + +ESX.UseItem = function(source, item) + ESX.UsableItemsCallbacks[item](source) +end + +RegisterServerEvent('esx:clientLog') +AddEventHandler('esx:clientLog', function(msg) + RconPrint(msg) +end) + +RegisterServerEvent('esx:triggerServerCallback') +AddEventHandler('esx:triggerServerCallback', function(name, requestId, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z) + local _source = source + ESX.TriggerServerCallback(name, requestID, _source, function(a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z) + TriggerClientEvent('esx:serverCallback', _source, requestId, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z) + end, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z) +end) diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua new file mode 100644 index 00000000..251d70c8 --- /dev/null +++ b/resources/[essential]/es_extended/server/main.lua @@ -0,0 +1,524 @@ +AddEventHandler('es:playerLoaded', function(source, _player) + + local _source = source + local tasks = {} + + local userData = { + accounts = {}, + inventory = {}, + job = {}, + loadout = {}, + playerName = GetPlayerName(_source), + lastPosition = nil + } + + TriggerEvent('es:getPlayerFromId', _source, function(player) + + -- Update user name in DB + table.insert(tasks, function(cb) + + MySQL.Async.execute( + 'UPDATE `users` SET `name` = @name WHERE `identifier` = @identifier', + { + ['@identifier'] = player.getIdentifier(), + ['@name'] = userData.playerName + }, + function(rowsChanged) + cb() + end + ) + + end) + + -- Get accounts + table.insert(tasks, function(cb) + + MySQL.Async.fetchAll( + 'SELECT * FROM `user_accounts` WHERE `identifier` = @identifier', + { + ['@identifier'] = player.getIdentifier() + }, + function(accounts) + + for i=1, #Config.Accounts, 1 do + for j=1, #accounts, 1 do + if accounts[j].name == Config.Accounts[i] then + table.insert(userData.accounts, { + name = accounts[j].name, + money = accounts[j].money, + label = Config.AccountLabels[accounts[j].name] + }) + end + end + + end + + cb() + end + ) + + end) + + -- Get Inventory + table.insert(tasks, function(cb) + + MySQL.Async.fetchAll( + 'SELECT * FROM `user_inventory` WHERE `identifier` = @identifier', + { + ['@identifier'] = player.getIdentifier() + }, + function(inventory) + + for i=1, #inventory, 1 do + table.insert(userData.inventory, { + name = inventory[i].item, + count = inventory[i].count, + label = ESX.Items[inventory[i].item].label, + limit = ESX.Items[inventory[i].item].limit, + usable = ESX.UsableItemsCallbacks[inventory[i].item] ~= nil + }) + end + + for k,v in pairs(ESX.Items) do + + local found = false + + for j=1, #userData.inventory, 1 do + if userData.inventory[j].name == k then + found = true + break + end + end + + if not found then + + table.insert(userData.inventory, { + name = k, + count = 0, + label = ESX.Items[k].label, + limit = ESX.Items[k].limit, + usable = ESX.UsableItemsCallbacks[k] ~= nil + }) + + MySQL.Async.execute( + 'INSERT INTO user_inventory (identifier, item, count) VALUES (@identifier, @item, @count)', + { + ['@identifier'] = player.getIdentifier(), + ['@item'] = k, + ['@count'] = 0 + } + ) + + end + + end + + table.sort(userData.inventory, function(a,b) + return a.label < b.label + end) + + cb() + end + ) + + end) + + -- Get job and loadout + table.insert(tasks, function(cb) + + local tasks2 = {} + + -- Get job name, grade and last position + table.insert(tasks2, function(cb2) + + MySQL.Async.fetchAll( + 'SELECT * FROM `users` WHERE `identifier` = @identifier', + { + ['@identifier'] = player.getIdentifier() + }, + function(result) + + userData.job['name'] = result[1].job + userData.job['grade'] = result[1].job_grade + + if result[1].loadout ~= nil then + userData.loadout = json.decode(result[1].loadout) + end + + if result[1].position ~= nil then + userData.lastPosition = json.decode(result[1].position) + end + + cb2() + + end + ) + + end) + + -- Get job label + table.insert(tasks2, function(cb2) + + MySQL.Async.fetchAll( + 'SELECT * FROM `jobs` WHERE `name` = @name', + { + ['@name'] = userData.job.name + }, + function(result) + + userData.job['label'] = result[1].label + + cb2() + + end + ) + + end) + + -- Get job grade data + table.insert(tasks2, function(cb2) + + MySQL.Async.fetchAll( + 'SELECT * FROM `job_grades` WHERE `job_name` = @job_name AND `grade` = @grade', + { + ['@job_name'] = userData.job.name, + ['@grade'] = userData.job.grade + }, + function(result) + + userData.job['grade_name'] = result[1].name + userData.job['grade_label'] = result[1].label + userData.job['grade_salary'] = result[1].salary + + userData.job['skin_male'] = {} + userData.job['skin_female'] = {} + + if result[1].skin_male ~= nil then + userData.job['skin_male'] = json.decode(result[1].skin_male) + end + + if result[1].skin_female ~= nil then + userData.job['skin_female'] = json.decode(result[1].skin_female) + end + + cb2() + + end + ) + + end) + + Async.series(tasks2, cb) + + end) + + -- Run Tasks + Async.parallel(tasks, function(results) + + local xPlayer = CreateExtendedPlayer(player, userData.accounts, userData.inventory, userData.job, userData.loadout, userData.playerName, userData.lastPosition) + + xPlayer.getMissingAccounts(function(missingAccounts) + + if #missingAccounts > 0 then + + for i=1, #missingAccounts, 1 do + table.insert(xPlayer.accounts, { + name = missingAccounts[i], + money = 0, + label = Config.AccountLabels[missingAccounts[i]] + }) + end + + xPlayer.createAccounts(missingAccounts) + end + + ESX.Players[_source] = xPlayer + + TriggerEvent('esx:playerLoaded', _source) + + TriggerClientEvent('esx:playerLoaded', _source, { + accounts = xPlayer.getAccounts(), + inventory = xPlayer.getInventory(), + job = xPlayer.getJob(), + loadout = xPlayer.getLoadout(), + lastPosition = xPlayer.getLastPosition(), + money = xPlayer.player.get('money') + }) + + xPlayer.player.displayMoney(xPlayer.get('money')) + + end) + + end) + + end) + +end) + +AddEventHandler('playerDropped', function() + + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) + + if xPlayer ~= nil then + + TriggerEvent('esx:playerDropped', _source) + + ESX.SavePlayer(xPlayer, function() + ESX.Players[_source] = nil + end) + + end + +end) + +RegisterServerEvent('esx:updateLoadout') +AddEventHandler('esx:updateLoadout', function(loadout) + local xPlayer = ESX.GetPlayerFromId(source) + xPlayer.loadout = loadout +end) + +RegisterServerEvent('esx:giveInventoryItem') +AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCount) + + local _source = source + + local sourceXPlayer = ESX.GetPlayerFromId(_source) + local targetXPlayer = ESX.GetPlayerFromId(target) + + if type == 'item_standard' then + + local sourceItem = sourceXPlayer.getInventoryItem(itemName) + local targetItem = targetXPlayer.getInventoryItem(itemName) + + if itemCount > 0 and sourceItem.count >= itemCount then + + if targetItem.limit ~= -1 and (targetItem.count + sourceItem.count) > targetItem.limit then + TriggerClientEvent('esx:showNotification', target, 'Action impossible, depassement de la limite d\'inventaire pour ~b~' .. targetXPlayer.name) + else + sourceXPlayer.removeInventoryItem(itemName, itemCount) + targetXPlayer.addInventoryItem (itemName, itemCount) + + TriggerClientEvent('esx:showNotification', _source, 'Vous avez donné ~g~x' .. itemCount .. ' ' .. ESX.Items[itemName].label .. '~s~ à ~b~' .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', target, 'Vous avez reçu ~g~x' .. itemCount .. ' ' .. ESX.Items[itemName].label .. '~s~ par ~b~' .. sourceXPlayer.name) + end + + else + TriggerClientEvent('esx:showNotification', target, 'Action impossible, ~r~quantité invalide') + end + + elseif type == 'item_money' then + + if itemCount > 0 and sourceXPlayer.player.get('money') >= itemCount then + + sourceXPlayer.removeMoney(itemCount) + targetXPlayer.addMoney(itemCount) + + TriggerClientEvent('esx:showNotification', _source, 'Vous avez donné ~g~$' .. itemCount .. '~s~ à ~b~' .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', target, 'Vous avez reçu ~g~$' .. itemCount .. '~s~ par ~b~' .. sourceXPlayer.name) + + else + TriggerClientEvent('esx:showNotification', target, 'Action impossible, ~r~montant invalide') + end + + elseif type == 'item_account' then + + if itemCount > 0 and sourceXPlayer.getAccount(itemName).money >= itemCount then + + sourceXPlayer.removeAccountMoney(itemName, itemCount) + targetXPlayer.addAccountMoney(itemName, itemCount) + + TriggerClientEvent('esx:showNotification', _source, 'Vous avez donné [' .. Config.AccountLabels[itemName] .. '] ~g~$' .. itemCount .. '~s~ à ~b~' .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', target, 'Vous avez reçu [' .. Config.AccountLabels[itemName] .. '] ~g~$' .. itemCount .. '~s~ par ~b~' .. sourceXPlayer.name) + + else + TriggerClientEvent('esx:showNotification', target, 'Action impossible, ~r~montant invalide') + end + + elseif type == 'item_weapon' then + + sourceXPlayer.removeWeapon(itemName) + targetXPlayer.addWeapon(itemName, itemCount) + + local weaponLabel = itemName + + for i=1, #Config.Weapons, 1 do + if Config.Weapons[i].name == itemName then + weaponLabel = Config.Weapons[i].label + break + end + end + + TriggerClientEvent('esx:showNotification', _source, 'Vous avez donné x1 ' .. ' ~g~' .. weaponLabel .. '~s~ à ~b~' .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', target, 'Vous avez reçu x1 ' .. ' ~g~' .. weaponLabel .. '~s~ par ~b~' .. sourceXPlayer.name) + end + +end) + +RegisterServerEvent('esx:removeInventoryItem') +AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) + + local _source = source + + if type == 'item_standard' then + + if itemCount == nil or itemCount <= 0 then + TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~quantité invalide') + else + + local xPlayer = ESX.GetPlayerFromId(source) + local foundItem = nil + + for i=1, #xPlayer.inventory, 1 do + if xPlayer.inventory[i].name == itemName then + foundItem = xPlayer.inventory[i] + end + end + + if itemCount > foundItem.count then + TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~quantité invalide') + else + + TriggerClientEvent('esx:showNotification', _source, '~r~Suppression~s~ dans 5 minutes') + + SetTimeout(Config.RemoveInventoryItemDelay, function() + + local remainingCount = xPlayer.getInventoryItem(itemName).count + local total = itemCount + + if remainingCount < itemCount then + total = remainingCount + end + + if total > 0 then + xPlayer.removeInventoryItem(itemName, total) + TriggerClientEvent('esx:showNotification', _source, 'Vous avez ~r~jeté~s~ ' .. foundItem.label .. ' x' .. total) + end + + end) + + end + + end + + elseif type == 'item_money' then + + if itemCount == nil or itemCount <= 0 then + TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~montant invalide') + else + + local xPlayer = ESX.GetPlayerFromId(source) + + if itemCount > xPlayer.player.get('money') then + TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~montant invalide') + else + + TriggerClientEvent('esx:showNotification', _source, '~r~Suppression~s~ dans 5 minutes') + + SetTimeout(Config.RemoveInventoryItemDelay, function() + + local remainingCount = xPlayer.player.get('money') + local total = itemCount + + if remainingCount < itemCount then + total = remainingCount + end + + if total > 0 then + xPlayer.removeMoney(total) + TriggerClientEvent('esx:showNotification', _source, 'Vous avez ~r~jeté~s~ [Cash] $' .. total) + end + + end) + + end + + end + + elseif type == 'item_account' then + + if itemCount == nil or itemCount <= 0 then + TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~montant invalide') + else + + local xPlayer = ESX.GetPlayerFromId(source) + + if itemCount > xPlayer.getAccount(itemName).money then + TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~montant invalide') + else + + TriggerClientEvent('esx:showNotification', _source, '~r~Suppression~s~ dans 5 minutes') + + SetTimeout(Config.RemoveInventoryItemDelay, function() + + local remainingCount = xPlayer.getAccount(itemName).money + local total = itemCount + + if remainingCount < itemCount then + total = remainingCount + end + + if total > 0 then + xPlayer.removeAccountMoney(itemName, total) + TriggerClientEvent('esx:showNotification', _source, 'Vous avez ~r~jeté~s~ [Cash] $' .. total) + end + + end) + + end + + end + + elseif type == 'item_weapon' then + + local weaponLabel = itemName + + for i=1, #Config.Weapons, 1 do + if Config.Weapons[i].name == itemName then + weaponLabel = Config.Weapons[i].label + break + end + end + + SetTimeout(Config.RemoveInventoryItemDelay, function() + xPlayer.removeWeapon(itemName) + TriggerClientEvent('esx:showNotification', _source, 'Vous avez ~r~jeté~s~ x1 ' .. ' ~g~' .. weaponLabel) + end) + + end + +end) + +ESX.RegisterServerCallback('esx:getPlayerData', function(source, cb) + + local xPlayer = ESX.GetPlayerFromId(source) + + cb({ + accounts = xPlayer.getAccounts(), + inventory = xPlayer.getInventory(), + job = xPlayer.getJob(), + loadout = xPlayer.getLoadout(), + lastPosition = xPlayer.getLastPosition(), + money = xPlayer.player.get('money') + }) + +end) + +ESX.RegisterServerCallback('esx:getOtherPlayerData', function(source, cb, target) + + local xPlayer = ESX.GetPlayerFromId(target) + + cb({ + accounts = xPlayer.getAccounts(), + inventory = xPlayer.getInventory(), + job = xPlayer.getJob(), + loadout = xPlayer.getLoadout(), + lastPosition = xPlayer.getLastPosition(), + money = xPlayer.player.get('money') + }) + +end) + +TriggerEvent("es:addGroup", "jobmaster", "user", function(group) end) + +ESX.StartDBSync() diff --git a/resources/[esx]/[ui]/esx_menu_default b/resources/[esx]/[ui]/esx_menu_default new file mode 160000 index 00000000..9954bec8 --- /dev/null +++ b/resources/[esx]/[ui]/esx_menu_default @@ -0,0 +1 @@ +Subproject commit 9954bec81228b19479730969a76fb75afa2b3b0c diff --git a/resources/[esx]/[ui]/esx_menu_dialog b/resources/[esx]/[ui]/esx_menu_dialog new file mode 160000 index 00000000..73f0d5dd --- /dev/null +++ b/resources/[esx]/[ui]/esx_menu_dialog @@ -0,0 +1 @@ +Subproject commit 73f0d5dd0ee5318e03b9bb5003573ef2e88df66a diff --git a/resources/[esx]/[ui]/esx_menu_list b/resources/[esx]/[ui]/esx_menu_list new file mode 160000 index 00000000..5bd0f9e9 --- /dev/null +++ b/resources/[esx]/[ui]/esx_menu_list @@ -0,0 +1 @@ +Subproject commit 5bd0f9e9a5986d74ebc0465b712db6648d7a92bd diff --git a/resources/async b/resources/async new file mode 160000 index 00000000..089dbcc1 --- /dev/null +++ b/resources/async @@ -0,0 +1 @@ +Subproject commit 089dbcc1a5b3baa2eaca09b8f43d6c14d83cdaaf From a2c8d748875b465d2b9dff4070226fb0ea0a7344 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 31 Jul 2017 12:53:17 +0200 Subject: [PATCH 0007/3224] Add files --- __resource.lua | 6 ++++ async.lua | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 __resource.lua create mode 100644 async.lua diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..647efcea --- /dev/null +++ b/__resource.lua @@ -0,0 +1,6 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'Async' + +server_script 'async.lua' +client_script 'async.lua' \ No newline at end of file diff --git a/async.lua b/async.lua new file mode 100644 index 00000000..3c7ab7c8 --- /dev/null +++ b/async.lua @@ -0,0 +1,82 @@ +if Citizen and Citizen.CreateThread then + CreateThread = Citizen.CreateThread +end + +Async = {} + +function Async.parallel(tasks, cb) + + local remaining = #tasks + local results = {} + + for i=1, #tasks, 1 do + + CreateThread(function() + + tasks[i](function(result) + + table.insert(results, result) + + remaining = remaining - 1; + + if remaining == 0 then + cb(results) + end + + end) + + end) + + end + +end + +function Async.parallelLimit(tasks, limit, cb) + + local remaining = #tasks + local running = 0 + local queue = {} + local results = {} + + for i=1, #tasks, 1 do + table.insert(queue, tasks[i]) + end + + local function processQueue() + + if #queue == 0 then + return + end + + while running < limit and #queue > 0 do + + local task = table.remove(queue, 1) + + running = running + 1 + + task(function(result) + + table.insert(results, result) + + remaining = remaining - 1; + running = running - 1 + + if remaining == 0 then + cb(results) + end + + end) + + end + + CreateThread(processQueue) + + end + + processQueue() + +end + +function Async.series(tasks, cb) + Async.parallelLimit(tasks, 1, cb) +end From b8b9753005ac7636502a123f8d81cfb43d199d47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 31 Jul 2017 12:54:23 +0200 Subject: [PATCH 0008/3224] Add files --- __resource.lua | 23 ++ client/main.lua | 167 +++++++++++++++ config.lua | 74 +++++++ html/css/app.css | 93 ++++++++ html/fonts/bankgothic.ttf | Bin 0 -> 36272 bytes html/fonts/pdown.ttf | Bin 0 -> 151512 bytes html/img/accounts/bank.png | Bin 0 -> 1015 bytes html/img/accounts/black_money.png | Bin 0 -> 1030 bytes html/img/cursor.png | Bin 0 -> 272 bytes html/img/keys/enter.png | Bin 0 -> 941 bytes html/img/keys/return.png | Bin 0 -> 376 bytes html/js/app.js | 344 ++++++++++++++++++++++++++++++ html/js/mustache.min.js | 1 + html/ui.html | 15 ++ 14 files changed, 717 insertions(+) create mode 100644 __resource.lua create mode 100644 client/main.lua create mode 100644 config.lua create mode 100644 html/css/app.css create mode 100644 html/fonts/bankgothic.ttf create mode 100644 html/fonts/pdown.ttf create mode 100644 html/img/accounts/bank.png create mode 100644 html/img/accounts/black_money.png create mode 100644 html/img/cursor.png create mode 100644 html/img/keys/enter.png create mode 100644 html/img/keys/return.png create mode 100644 html/js/app.js create mode 100644 html/js/mustache.min.js create mode 100644 html/ui.html diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..3774ff9e --- /dev/null +++ b/__resource.lua @@ -0,0 +1,23 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'ESX Menu Default' + +client_scripts { + 'client/main.lua' +} + +ui_page { + 'html/ui.html' +} + +files { + 'html/ui.html', + 'html/css/app.css', + 'html/js/mustache.min.js', + 'html/js/app.js', + 'html/fonts/pdown.ttf', + 'html/fonts/bankgothic.ttf', + 'html/img/cursor.png', + 'html/img/keys/enter.png', + 'html/img/keys/return.png', +} \ No newline at end of file diff --git a/client/main.lua b/client/main.lua new file mode 100644 index 00000000..e975e51c --- /dev/null +++ b/client/main.lua @@ -0,0 +1,167 @@ +ESX = nil + +Citizen.CreateThread(function() + + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end + + local Keys = { + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, + ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, + ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, + ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, + ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 + } + + local GUI = {} + GUI.Time = 0 + local MenuType = 'default' + + 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 + + Wait(0) + + if IsControlPressed(0, Keys['ENTER']) and (GetGameTimer() - GUI.Time) > 150 then + + SendNUIMessage({ + action = 'controlPressed', + control = 'ENTER' + }) + + GUI.Time = GetGameTimer() + + end + + if IsControlPressed(0, Keys['BACKSPACE']) and (GetGameTimer() - GUI.Time) > 150 then + + SendNUIMessage({ + action = 'controlPressed', + control = 'BACKSPACE' + }) + + GUI.Time = GetGameTimer() + + end + + if IsControlPressed(0, Keys['TOP']) and (GetGameTimer() - GUI.Time) > 150 then + + SendNUIMessage({ + action = 'controlPressed', + control = 'TOP' + }) + + GUI.Time = GetGameTimer() + + end + + if IsControlPressed(0, Keys['DOWN']) and (GetGameTimer() - GUI.Time) > 150 then + + SendNUIMessage({ + action = 'controlPressed', + control = 'DOWN' + }) + + GUI.Time = GetGameTimer() + + end + + if IsControlPressed(0, Keys['LEFT']) and (GetGameTimer() - GUI.Time) > 150 then + + SendNUIMessage({ + action = 'controlPressed', + control = 'LEFT' + }) + + GUI.Time = GetGameTimer() + + end + + if IsControlPressed(0, Keys['RIGHT']) and (GetGameTimer() - GUI.Time) > 150 then + + SendNUIMessage({ + action = 'controlPressed', + control = 'RIGHT' + }) + + GUI.Time = GetGameTimer() + + end + + end + end) + +end) \ No newline at end of file diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..81e8ddf6 --- /dev/null +++ b/config.lua @@ -0,0 +1,74 @@ +Config = {} + +Config.accounts = {'bank', 'black_money'} +Config.accountLabels = {'Banque', 'Argent Sale'} +Config.PaycheckInterval = 7 * 60000 +Config.ShowDotAbovePlayer = false +Config.RemoveInventoryItemDelay = 5 * 60000 + +Config.Weapons = { + + {name = 'WEAPON_UNARMED'}, + {name = 'WEAPON_ANIMAL'}, + {name = 'WEAPON_COUGAR'}, + {name = 'WEAPON_KNIFE'}, + {name = 'WEAPON_NIGHTSTICK'}, + {name = 'WEAPON_HAMMER'}, + {name = 'WEAPON_BAT'}, + {name = 'WEAPON_GOLFCLUB'}, + {name = 'WEAPON_CROWBAR'}, + {name = 'WEAPON_PISTOL'}, + {name = 'WEAPON_COMBATPISTOL'}, + {name = 'WEAPON_APPISTOL'}, + {name = 'WEAPON_PISTOL50'}, + {name = 'WEAPON_MICROSMG'}, + {name = 'WEAPON_SMG'}, + {name = 'WEAPON_ASSAULTSMG'}, + {name = 'WEAPON_ASSAULTRIFLE'}, + {name = 'WEAPON_CARBINERIFLE'}, + {name = 'WEAPON_ADVANCEDRIFLE'}, + {name = 'WEAPON_MG'}, + {name = 'WEAPON_COMBATMG'}, + {name = 'WEAPON_PUMPSHOTGUN'}, + {name = 'WEAPON_SAWNOFFSHOTGUN'}, + {name = 'WEAPON_ASSAULTSHOTGUN'}, + {name = 'WEAPON_BULLPUPSHOTGUN'}, + {name = 'WEAPON_STUNGUN'}, + {name = 'WEAPON_SNIPERRIFLE'}, + {name = 'WEAPON_HEAVYSNIPER'}, + {name = 'WEAPON_REMOTESNIPER'}, + {name = 'WEAPON_GRENADELAUNCHER'}, + {name = 'WEAPON_GRENADELAUNCHER_SMOKE'}, + {name = 'WEAPON_RPG'}, + {name = 'WEAPON_PASSENGER_ROCKET'}, + {name = 'WEAPON_AIRSTRIKE_ROCKET'}, + {name = 'WEAPON_STINGER'}, + {name = 'WEAPON_MINIGUN'}, + {name = 'WEAPON_GRENADE'}, + {name = 'WEAPON_STICKYBOMB'}, + {name = 'WEAPON_SMOKEGRENADE'}, + {name = 'WEAPON_BZGAS'}, + {name = 'WEAPON_MOLOTOV'}, + {name = 'WEAPON_FIREEXTINGUISHER'}, + {name = 'WEAPON_PETROLCAN'}, + {name = 'WEAPON_DIGISCANNER'}, + {name = 'WEAPON_BRIEFCASE'}, + {name = 'WEAPON_BRIEFCASE_02'}, + {name = 'WEAPON_BALL'}, + {name = 'WEAPON_FLARE'}, + {name = 'WEAPON_VEHICLE_ROCKET'}, + {name = 'WEAPON_BARBED_WIRE'}, + {name = 'WEAPON_DROWNING'}, + {name = 'WEAPON_DROWNING_IN_VEHICLE'}, + {name = 'WEAPON_BLEEDING'}, + {name = 'WEAPON_ELECTRIC_FENCE'}, + {name = 'WEAPON_EXPLOSION'}, + {name = 'WEAPON_FALL'}, + {name = 'WEAPON_EXHAUSTION'}, + {name = 'WEAPON_HIT_BY_WATER_CANNON'}, + {name = 'WEAPON_RAMMED_BY_CAR'}, + {name = 'WEAPON_RUN_OVER_BY_CAR'}, + {name = 'WEAPON_HELI_CRASH'}, + {name = 'WEAPON_FIRE'} + +} \ No newline at end of file diff --git a/html/css/app.css b/html/css/app.css new file mode 100644 index 00000000..2739eada --- /dev/null +++ b/html/css/app.css @@ -0,0 +1,93 @@ +@font-face { + font-family: bankgothic; + src: url('../fonts/bankgothic.ttf'); +} + +@font-face { + font-family: pcdown; + src: url('../fonts/pdown.ttf'); +} +.menu { + font-family: bankgothic; + min-width : 400px; + color : #fff; + box-shadow : 0px 0px 50px 0px #000; + position : absolute; +} + +.menu.align-left { + left: 40; + top : 50%; + transform: translate(0, -50%); +} + +.menu.align-top-left { + left: 40; + top : 40; +} + +.menu.align-top { + left: 50%; + top : 40; + transform: translate(-50%, 0); +} + +.menu.align-top-right { + right: 10; + top : 40; +} + +.menu.align-right { + right: 40; + top : 50%; + transform: translate(0, -50%); +} + +.menu.align-bottom-right { + right : 40; + bottom: 40; +} + +.menu.align-bottom { + left : 50%; + bottom: 40; + transform: translate(-50%, 0); +} + +.menu.align-bottom-left { + left : 40; + bottom: 40; +} + +.menu.align-center { + left : 50%; + top : 50%; + transform: translate(-50%, -50%); +} + +.menu .head { + background-color: #506be6; + text-align : center; + height : 40px; + line-height : 40px; +} + +.menu .menu-items { + max-height : 600px; + overflow-y : auto; +} + +.menu .menu-items .menu-item { + height : 40px; + display : block; + background-color: #f1f1f1; + box-shadow : inset 1px 0px 0px 1px #b8b8b8; + height : 32px; + line-height : 32px; + color : #3A3A3A; + text-align : center; +} + +.menu .menu-items .menu-item.selected { + background-color: #d0d0d0; +} \ No newline at end of file diff --git a/html/fonts/bankgothic.ttf b/html/fonts/bankgothic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f3d8049b052a1f9cfd27557eb3675bc85ce4b9fc GIT binary patch literal 36272 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
D;NyGoM}BX%_3nO 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 D`#l06 literal 0 HcmV?d00001 diff --git a/html/fonts/pdown.ttf b/html/fonts/pdown.ttf new file mode 100644 index 0000000000000000000000000000000000000000..69c76cf3f2a6bbc93f570124554fec06d7bbac25 GIT binary patch literal 151512 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 literal 0 HcmV?d00001 diff --git a/html/img/accounts/bank.png b/html/img/accounts/bank.png new file mode 100644 index 0000000000000000000000000000000000000000..eb36dc8e70242136858874dc04024f41a4a0ffe4 GIT binary patch literal 1015 zcmV(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZowVTiq@}o(XxOP=4eyC973P=U1kRsFroRJ#! z(58{#776h;aLEM;L{SeVNSr|QQXy1+3PCF$LRAh>$;D}$6yr9(+&K1ncOM65H{N(1 z#D$Kuhc`R(oq6-#%=d|SpP}3h7iYue{}eqbkx7XFRFr{CNQ8)Xb~jy=7uE?4gk`F&OBwm4 zCoMHTH>$?xM%AIWM*@A{$sTp={U_D<+^9-VTDxK-EK`kLJ+5RzDnM!ek$H}yvF_~J zI*(=_0U-a;0)z8Wb)S zQLZ90W&QVw7&*Bd#kDto4a&FO>rT+B>2t%_D-HHP*Nt0qx&3jG%#?*w*}g}u7*V?q zC7?WT9&9^T7ittfS!~IwsWS)S-1}*T;uj^>ZdO>nzDliBXXNxy;O7swHVm3ETF1EN z4>(O1#JYDsk>%W4c>Lb8d62J?Ix`%Uf2Yk(iFNB}y6}hU)_oQ5>d!CYZn)gNQs$4D zKRXVhm%qw}1`)u%qg{dS$JcVyN_M3G6VnGdaH2iso z*ZbP|p!QdtrOPGu48|kL$mfBbu>v}-m+cT8XD>e8k&fM(*Y<#MYaY*k@Ki@S_G~Xi l#{maD><5W>*iW*51^`FRlAF&_hJ*kB002ovPDHLkV1iBj&&U7( literal 0 HcmV?d00001 diff --git a/html/img/accounts/black_money.png b/html/img/accounts/black_money.png new file mode 100644 index 0000000000000000000000000000000000000000..a42f6aa5191115bd04d04a728fb3c3463e6f4345 GIT binary patch literal 1030 zcmV+h1o``kP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZT+Hn2g&!y2+1h(>773hKd&LYji7 zJxDS2q!OyV*_F1(HYnsEh!-iPJ(ZSP4aAjfgeH{rV4AN*TFttfb$4bmZx7v>?##{# z?V&y}hv%8+>;1pa$1D1}yJgw3cww6SpVXsi=&FhUWSBxsRZ)ZpHLjQ@PC%vrF-;5A zcci3ZS)uWZC+3;63 zP5NhNQG_7k$iD&Ti^Y6K$y>Lur5_yG;D0)PoSwjGx9WA?yK@Hs5kM{?1izg=O;;2A zE;12U>4j-}Ke7u86iTH~$S#kLGN9`%@&R4v!+raho}Ul3%PuT1H9YLaYQ8!YA?Of- zVztV(#YN7~&4oJYkHxr{N_qVKVv+mBqQ_rKrRWbJ>C*YRIj$`(Qmj_#5W-hqGN!6> zV{%d^3_~`GGW5GJG9sN!Mmm{{ygWMU$&U>V%5RSxkxnKfFN}=5(nrED_VAxIbo05=N-zC3)GHzE;!+1%vw@o_Ie!Z2_5K&81r!?IKr zh1|)L^k^EFQYm)L%mA>fvlD<*LqnXsdzb!LjLmA5H@mvL+HiFMpO3e$U&jh*>&SnZ zV$Kc?zZa1REj@pHO6~;d1>2x z`tTvs=`>qSb=2%5?DW0_oIrm*E|tjU^S*KVxKv_5*ZFQ`g|C;En1A||AJ*1bt5o_1QC~4jk~{59$PIcV{Q6qIgLP zKq^8|I&+4yWpT4m;NyGu+76Wq2dk9|S8_RzKNyeuf?vty+6KQmHpaPRl6W-Aj+7n(5dsSW zU}|`nua=fVm(h*oWj@%uw`CvvUM_QEd6{>0J#-nldmtFgTgU5_if`vg<{vZ*r`$_iK0G#)*@UBUHMF0Q*07*qoM6N<$f`k9( AtN;K2 literal 0 HcmV?d00001 diff --git a/html/img/cursor.png b/html/img/cursor.png new file mode 100644 index 0000000000000000000000000000000000000000..39536f953d701b36a90dc56084bafd988371a2fb GIT binary patch literal 272 zcmeAS@N?(olHy`uVBq!ia0vp^q9Dw{1|(OCFP#RYSkfJR9T^xl_H+M9WCij$3p^r= z85sBufiR<}hF1enP_o1|q9iy!t)x7$D3zfgF*C13FE6!3!9>qM&(L5k7uNxxqFzrI z#}Etut!FreS`>I(0^ikVp5f1PInc0ibrsXWO3z8Ee_BE>W<&%Ean9H1Y|@_Ma)5tI zP3vrppG@U}o4EJ`H!a-_TKCSz%v`zHX&3lrYRgJzbSuAt9 z@6PvoS_%Jm+&BGp_A+yZ?Fo&SwU@JtJ?kA`YTb#E`^&mC!8qZZWp1Mjt5em&H79@$ OWAJqKb6Mw<&;$S!<6)ox literal 0 HcmV?d00001 diff --git a/html/img/keys/enter.png b/html/img/keys/enter.png new file mode 100644 index 0000000000000000000000000000000000000000..3eb9a1f69f58c651517329c92d28cdb1c605f165 GIT binary patch literal 941 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h5*QjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ISV`@iy0XB4ude`@%$Aj3=GUpo-U3d6>)E`8wN=`3bZEbov^iFaeu%P z(=cbwj44wlOz4rm5xb{;*Ri~}uR6cp(A&Mg;nJ7c^H#o^DiE{vT2%I1{SRyZiuLSP z%I`LO*R@CY*bePa+aw;ZJ8?S+Bq+DcEWq?az(jNYVCfZ787ofAZePh8!fO)pBkQX z_v_cMN3~tQ9xnRXb?ICkwaPbd-|8+sfB5~ocaKb5*$ZEQP2MMD?ps&IpveBkTdrZ6 zxw-l0$rY8AfmJN&5XWi1Tr~N;qpPCYQm=EdrvtPXJvz5h@~FDPw92D`R+fPvAFW@~ zU8c75`%1Gbh1a`Q>?qE0`*<(h^|W${-y)Ec<2}XS`n>x2)3WZB?5;)4TWYMP-*<76OIq zPp@4X%Z+C%*K#BUX=ORzsAov;Kl`m>i&y`Jz)nzj*Qmyplm-1%6v*YUbiCHwmEO<$ zF|Z@`-}HhOKR<9>X}?rT5Bm9ye^tw4euv}#-v4JmQzRDkY{|X*_d_{Xwfto_xNQ|y z-^Qlff58%JWZtYCU#*y5vIf?_WBTiPU(9hK5Tmx!-~Iodkpb3zr{Lwk`bljQz#(xy zvE05v9vtTHlU}QP{nuV*08Uf+$??{$l9IqgWxio$Zh{XeF$LeaxXn-#^iFnsKzTLkWYeXNfKEXTvUB0pJdzPZ}OMgdS+TyQ( lJso37+@RE7f9~qla<)GklNn{1`ISV`@iy0XBj({-ZRBb+Kpaxz~7srr_xVN`&cQqS`I9#;&|Ns0smZ-L@ zqu)%cbtmkrE=&Hfsn_t^{^k|)kLw3AbqG7mVR+;>`#|k>^_ZL6&QAQlndu0pf*(U6 zREkAFy}^PJuTYF$!{g|Ur7IbD{_6-gJlsE>3DGO)9eE;D=anIC*ESQi{xCV$~42}L!4TJCrkQD1~tJw zr&teYqgpL=o@s|#!;B|~71m*K' + + '
{{title}}
' + + ''+ + '' + + '' + ; + + window.ESX_MENU = {}; + ESX_MENU.ResourceName = 'esx_menu_default'; + ESX_MENU.opened = {}; + ESX_MENU.focus = []; + ESX_MENU.pos = {}; + + ESX_MENU.open = function(namespace, name, data){ + + if(typeof ESX_MENU.opened[namespace] == 'undefined') + ESX_MENU.opened[namespace] = {}; + + if(typeof ESX_MENU.opened[namespace][name] != 'undefined') + ESX_MENU.close(namespace, name); + + if(typeof ESX_MENU.pos[namespace] == 'undefined') + ESX_MENU.pos[namespace] = {}; + + for(let i=0; i { + + switch(data.action){ + + case 'openMenu' : { + ESX_MENU.open(data.namespace, data.name, data.data); + break; + } + + case 'closeMenu' : { + ESX_MENU.close(data.namespace, data.name); + break; + } + + case 'controlPressed' : { + + switch(data.control){ + + case 'ENTER' : { + + let focused = ESX_MENU.getFocused(); + let menu = ESX_MENU.opened[focused.namespace][focused.name]; + let pos = ESX_MENU.pos[focused.namespace][focused.name]; + let elem = menu.elements[pos]; + + if(menu.elements.length > 0) + ESX_MENU.submit(focused.namespace, focused.name, elem); + + break; + } + + case 'BACKSPACE' : { + + let focused = ESX_MENU.getFocused(); + + ESX_MENU.cancel(focused.namespace, focused.name); + + break; + } + + case 'TOP' : { + + let focused = ESX_MENU.getFocused(); + let menu = ESX_MENU.opened[focused.namespace][focused.name]; + let pos = ESX_MENU.pos[focused.namespace][focused.name]; + + if(pos > 0) + ESX_MENU.pos[focused.namespace][focused.name]--; + + let elem = menu.elements[ESX_MENU.pos[focused.namespace][focused.name]]; + + for(let i=0; i 0){ + elem.value--; + ESX_MENU.change(focused.namespace, focused.name, elem) + } + + ESX_MENU.render(); + + break; + } + + default: break; + + } + + $('#menu_' + focused.namespace + '_' + focused.name).find('.menu-item.selected')[0].scrollIntoView(); + + break; + } + + case 'RIGHT' : { + + let focused = ESX_MENU.getFocused(); + let menu = ESX_MENU.opened[focused.namespace][focused.name]; + let pos = ESX_MENU.pos[focused.namespace][focused.name]; + let elem = menu.elements[pos]; + + switch(elem.type){ + + case 'default': break; + + case 'slider' : { + + if(typeof elem.options != 'undefined' && elem.value < elem.options.length - 1){ + elem.value++; + ESX_MENU.change(focused.namespace, focused.name, elem) + } + + if(typeof elem.max != 'undefined' && elem.value < elem.max){ + elem.value++; + ESX_MENU.change(focused.namespace, focused.name, elem) + } + + ESX_MENU.render(); + + break; + } + + default: break; + + } + + $('#menu_' + focused.namespace + '_' + focused.name).find('.menu-item.selected')[0].scrollIntoView(); + + break; + } + + default : break; + + } + + break; + } + + } + + } + + window.onload = function(e){ + window.addEventListener('message', (event) => { + onData(event.data) + }); + } + +})() \ No newline at end of file diff --git a/html/js/mustache.min.js b/html/js/mustache.min.js new file mode 100644 index 00000000..520cfcb9 --- /dev/null +++ b/html/js/mustache.min.js @@ -0,0 +1 @@ +(function defineMustache(global,factory){if(typeof exports==="object"&&exports&&typeof exports.nodeName!=="string"){factory(exports)}else if(typeof define==="function"&&define.amd){define(["exports"],factory)}else{global.Mustache={};factory(global.Mustache)}})(this,function mustacheFactory(mustache){var objectToString=Object.prototype.toString;var isArray=Array.isArray||function isArrayPolyfill(object){return objectToString.call(object)==="[object Array]"};function isFunction(object){return typeof object==="function"}function typeStr(obj){return isArray(obj)?"array":typeof obj}function escapeRegExp(string){return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}function hasProperty(obj,propName){return obj!=null&&typeof obj==="object"&&propName in obj}var regExpTest=RegExp.prototype.test;function testRegExp(re,string){return regExpTest.call(re,string)}var nonSpaceRe=/\S/;function isWhitespace(string){return!testRegExp(nonSpaceRe,string)}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(string){return String(string).replace(/[&<>"'`=\/]/g,function fromEntityMap(s){return entityMap[s]})}var whiteRe=/\s*/;var spaceRe=/\s+/;var equalsRe=/\s*=/;var curlyRe=/\s*\}/;var tagRe=/#|\^|\/|>|\{|&|=|!/;function parseTemplate(template,tags){if(!template)return[];var sections=[];var tokens=[];var spaces=[];var hasTag=false;var nonSpace=false;function stripSpace(){if(hasTag&&!nonSpace){while(spaces.length)delete tokens[spaces.pop()]}else{spaces=[]}hasTag=false;nonSpace=false}var openingTagRe,closingTagRe,closingCurlyRe;function compileTags(tagsToCompile){if(typeof tagsToCompile==="string")tagsToCompile=tagsToCompile.split(spaceRe,2);if(!isArray(tagsToCompile)||tagsToCompile.length!==2)throw new Error("Invalid tags: "+tagsToCompile);openingTagRe=new RegExp(escapeRegExp(tagsToCompile[0])+"\\s*");closingTagRe=new RegExp("\\s*"+escapeRegExp(tagsToCompile[1]));closingCurlyRe=new RegExp("\\s*"+escapeRegExp("}"+tagsToCompile[1]))}compileTags(tags||mustache.tags);var scanner=new Scanner(template);var start,type,value,chr,token,openSection;while(!scanner.eos()){start=scanner.pos;value=scanner.scanUntil(openingTagRe);if(value){for(var i=0,valueLength=value.length;i0?sections[sections.length-1][4]:nestedTokens;break;default:collector.push(token)}}return nestedTokens}function Scanner(string){this.string=string;this.tail=string;this.pos=0}Scanner.prototype.eos=function eos(){return this.tail===""};Scanner.prototype.scan=function scan(re){var match=this.tail.match(re);if(!match||match.index!==0)return"";var string=match[0];this.tail=this.tail.substring(string.length);this.pos+=string.length;return string};Scanner.prototype.scanUntil=function scanUntil(re){var index=this.tail.search(re),match;switch(index){case-1:match=this.tail;this.tail="";break;case 0:match="";break;default:match=this.tail.substring(0,index);this.tail=this.tail.substring(index)}this.pos+=match.length;return match};function Context(view,parentContext){this.view=view;this.cache={".":this.view};this.parent=parentContext}Context.prototype.push=function push(view){return new Context(view,this)};Context.prototype.lookup=function lookup(name){var cache=this.cache;var value;if(cache.hasOwnProperty(name)){value=cache[name]}else{var context=this,names,index,lookupHit=false;while(context){if(name.indexOf(".")>0){value=context.view;names=name.split(".");index=0;while(value!=null&&index")value=this.renderPartial(token,context,partials,originalTemplate);else if(symbol==="&")value=this.unescapedValue(token,context);else if(symbol==="name")value=this.escapedValue(token,context);else if(symbol==="text")value=this.rawValue(token);if(value!==undefined)buffer+=value}return buffer};Writer.prototype.renderSection=function renderSection(token,context,partials,originalTemplate){var self=this;var buffer="";var value=context.lookup(token[1]);function subRender(template){return self.render(template,context,partials)}if(!value)return;if(isArray(value)){for(var j=0,valueLength=value.length;j + + + + + + + + + + + + + + \ No newline at end of file From f3300e27cb18d2a6b5d32bf9e36df0a398bd45ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 31 Jul 2017 12:54:38 +0200 Subject: [PATCH 0009/3224] Add files --- __resource.lua | 23 ++++ client/main.lua | 134 ++++++++++++++++++++++++ config.lua | 74 +++++++++++++ html/css/app.css | 87 ++++++++++++++++ html/fonts/bankgothic.ttf | Bin 0 -> 36272 bytes html/fonts/pdown.ttf | Bin 0 -> 151512 bytes html/img/accounts/bank.png | Bin 0 -> 1015 bytes html/img/accounts/black_money.png | Bin 0 -> 1030 bytes html/img/cursor.png | Bin 0 -> 431 bytes html/img/keys/enter.png | Bin 0 -> 941 bytes html/img/keys/return.png | Bin 0 -> 376 bytes html/js/app.js | 167 ++++++++++++++++++++++++++++++ html/js/mustache.min.js | 1 + html/ui.html | 15 +++ 14 files changed, 501 insertions(+) create mode 100644 __resource.lua create mode 100644 client/main.lua create mode 100644 config.lua create mode 100644 html/css/app.css create mode 100644 html/fonts/bankgothic.ttf create mode 100644 html/fonts/pdown.ttf create mode 100644 html/img/accounts/bank.png create mode 100644 html/img/accounts/black_money.png create mode 100644 html/img/cursor.png create mode 100644 html/img/keys/enter.png create mode 100644 html/img/keys/return.png create mode 100644 html/js/app.js create mode 100644 html/js/mustache.min.js create mode 100644 html/ui.html diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..29f472c9 --- /dev/null +++ b/__resource.lua @@ -0,0 +1,23 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'ESX Menu Dialog' + +client_scripts { + 'client/main.lua' +} + +ui_page { + 'html/ui.html' +} + +files { + 'html/ui.html', + 'html/css/app.css', + 'html/js/mustache.min.js', + 'html/js/app.js', + 'html/fonts/pdown.ttf', + 'html/fonts/bankgothic.ttf', + 'html/img/cursor.png', + 'html/img/keys/enter.png', + 'html/img/keys/return.png', +} \ No newline at end of file diff --git a/client/main.lua b/client/main.lua new file mode 100644 index 00000000..6b4e3e7f --- /dev/null +++ b/client/main.lua @@ -0,0 +1,134 @@ +ESX = nil + +Citizen.CreateThread(function() + + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end + + local Keys = { + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, + ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, + ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, + ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, + ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 + } + + local GUI = {} + GUI.Time = 0 + local MenuType = 'dialog' + local OpenedMenus = {} + + local openMenu = function(namespace, name, data) + + OpenedMenus[namespace .. '_' .. name] = true + + SendNUIMessage({ + action = 'openMenu', + namespace = namespace, + name = name, + data = data, + }) + + ESX.SetTimeout(200, function() + SetNuiFocus(true, true) + end) + + end + + local closeMenu = function(namespace, name) + + OpenedMenus[namespace .. '_' .. name] = nil + local OpenedMenuCount = 0 + + SendNUIMessage({ + action = 'closeMenu', + namespace = namespace, + name = name, + data = data, + }) + + for k,v in pairs(OpenedMenus) do + if v == true then + OpenedMenuCount = OpenedMenuCount + 1 + end + end + + if OpenedMenuCount == 0 then + SetNuiFocus(false) + end + + 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) + + if menu.change ~= nil then + menu.change(data, menu) + end + + cb('OK') + end) + + Citizen.CreateThread(function() + while true do + + Wait(0) + + local OpenedMenuCount = 0 + + for k,v in pairs(OpenedMenus) do + if v == true then + OpenedMenuCount = OpenedMenuCount + 1 + end + end + + if OpenedMenuCount > 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 + + end + + end + end) + +end) \ No newline at end of file diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..81e8ddf6 --- /dev/null +++ b/config.lua @@ -0,0 +1,74 @@ +Config = {} + +Config.accounts = {'bank', 'black_money'} +Config.accountLabels = {'Banque', 'Argent Sale'} +Config.PaycheckInterval = 7 * 60000 +Config.ShowDotAbovePlayer = false +Config.RemoveInventoryItemDelay = 5 * 60000 + +Config.Weapons = { + + {name = 'WEAPON_UNARMED'}, + {name = 'WEAPON_ANIMAL'}, + {name = 'WEAPON_COUGAR'}, + {name = 'WEAPON_KNIFE'}, + {name = 'WEAPON_NIGHTSTICK'}, + {name = 'WEAPON_HAMMER'}, + {name = 'WEAPON_BAT'}, + {name = 'WEAPON_GOLFCLUB'}, + {name = 'WEAPON_CROWBAR'}, + {name = 'WEAPON_PISTOL'}, + {name = 'WEAPON_COMBATPISTOL'}, + {name = 'WEAPON_APPISTOL'}, + {name = 'WEAPON_PISTOL50'}, + {name = 'WEAPON_MICROSMG'}, + {name = 'WEAPON_SMG'}, + {name = 'WEAPON_ASSAULTSMG'}, + {name = 'WEAPON_ASSAULTRIFLE'}, + {name = 'WEAPON_CARBINERIFLE'}, + {name = 'WEAPON_ADVANCEDRIFLE'}, + {name = 'WEAPON_MG'}, + {name = 'WEAPON_COMBATMG'}, + {name = 'WEAPON_PUMPSHOTGUN'}, + {name = 'WEAPON_SAWNOFFSHOTGUN'}, + {name = 'WEAPON_ASSAULTSHOTGUN'}, + {name = 'WEAPON_BULLPUPSHOTGUN'}, + {name = 'WEAPON_STUNGUN'}, + {name = 'WEAPON_SNIPERRIFLE'}, + {name = 'WEAPON_HEAVYSNIPER'}, + {name = 'WEAPON_REMOTESNIPER'}, + {name = 'WEAPON_GRENADELAUNCHER'}, + {name = 'WEAPON_GRENADELAUNCHER_SMOKE'}, + {name = 'WEAPON_RPG'}, + {name = 'WEAPON_PASSENGER_ROCKET'}, + {name = 'WEAPON_AIRSTRIKE_ROCKET'}, + {name = 'WEAPON_STINGER'}, + {name = 'WEAPON_MINIGUN'}, + {name = 'WEAPON_GRENADE'}, + {name = 'WEAPON_STICKYBOMB'}, + {name = 'WEAPON_SMOKEGRENADE'}, + {name = 'WEAPON_BZGAS'}, + {name = 'WEAPON_MOLOTOV'}, + {name = 'WEAPON_FIREEXTINGUISHER'}, + {name = 'WEAPON_PETROLCAN'}, + {name = 'WEAPON_DIGISCANNER'}, + {name = 'WEAPON_BRIEFCASE'}, + {name = 'WEAPON_BRIEFCASE_02'}, + {name = 'WEAPON_BALL'}, + {name = 'WEAPON_FLARE'}, + {name = 'WEAPON_VEHICLE_ROCKET'}, + {name = 'WEAPON_BARBED_WIRE'}, + {name = 'WEAPON_DROWNING'}, + {name = 'WEAPON_DROWNING_IN_VEHICLE'}, + {name = 'WEAPON_BLEEDING'}, + {name = 'WEAPON_ELECTRIC_FENCE'}, + {name = 'WEAPON_EXPLOSION'}, + {name = 'WEAPON_FALL'}, + {name = 'WEAPON_EXHAUSTION'}, + {name = 'WEAPON_HIT_BY_WATER_CANNON'}, + {name = 'WEAPON_RAMMED_BY_CAR'}, + {name = 'WEAPON_RUN_OVER_BY_CAR'}, + {name = 'WEAPON_HELI_CRASH'}, + {name = 'WEAPON_FIRE'} + +} \ No newline at end of file diff --git a/html/css/app.css b/html/css/app.css new file mode 100644 index 00000000..55577105 --- /dev/null +++ b/html/css/app.css @@ -0,0 +1,87 @@ +@font-face { + font-family: bankgothic; + src: url('../fonts/bankgothic.ttf'); +} + +@font-face { + font-family: pcdown; + src: url('../fonts/pdown.ttf'); +} + +#cursor { + position: absolute; + z-index: 999999999; + display: none; +} + +#controls { + font-family : pcdown; + font-size : 3em; + color : #FFF; + position : absolute; + bottom : 40; + right : 40; + + text-shadow: + -1px -1px 0 #000, + 1px -1px 0 #000, + -1px 1px 0 #000, + 1px 1px 0 #000 + ; +} + +.controls { + display: none; +} + +.dialog { + + font-family : bankgothic; + background-color: #fff; + color : #fff; + box-shadow : 0px 0px 50px 0px #000; + position : absolute; + overflow : hidden; + top : 50%; + left : 50%; + width : 600px; + height : 104px; + transform : translate(-50%, -50%); +} + +.dialog.big { + height: 200px; +} + +.dialog .head { + background-color: #506be6; + text-align : center; + height : 40px; +} + +.dialog .head span:before { + content: ""; + display: inline-block; + height: 100%; + vertical-align: middle; +} + +.dialog input[type="text"] { + width : 100%; + height: 32px; +} + +.dialog textarea { + width : 100%; + height: 128px; +} + +.dialog button[name="submit"] { + width : 75%; + height: 32px; +} + +.dialog button[name="cancel"] { + width : 25%; + height: 32px; +} \ No newline at end of file diff --git a/html/fonts/bankgothic.ttf b/html/fonts/bankgothic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f3d8049b052a1f9cfd27557eb3675bc85ce4b9fc GIT binary patch literal 36272 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
D;NyGoM}BX%_3nO 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 D`#l06 literal 0 HcmV?d00001 diff --git a/html/fonts/pdown.ttf b/html/fonts/pdown.ttf new file mode 100644 index 0000000000000000000000000000000000000000..69c76cf3f2a6bbc93f570124554fec06d7bbac25 GIT binary patch literal 151512 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 literal 0 HcmV?d00001 diff --git a/html/img/accounts/bank.png b/html/img/accounts/bank.png new file mode 100644 index 0000000000000000000000000000000000000000..eb36dc8e70242136858874dc04024f41a4a0ffe4 GIT binary patch literal 1015 zcmV(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZowVTiq@}o(XxOP=4eyC973P=U1kRsFroRJ#! z(58{#776h;aLEM;L{SeVNSr|QQXy1+3PCF$LRAh>$;D}$6yr9(+&K1ncOM65H{N(1 z#D$Kuhc`R(oq6-#%=d|SpP}3h7iYue{}eqbkx7XFRFr{CNQ8)Xb~jy=7uE?4gk`F&OBwm4 zCoMHTH>$?xM%AIWM*@A{$sTp={U_D<+^9-VTDxK-EK`kLJ+5RzDnM!ek$H}yvF_~J zI*(=_0U-a;0)z8Wb)S zQLZ90W&QVw7&*Bd#kDto4a&FO>rT+B>2t%_D-HHP*Nt0qx&3jG%#?*w*}g}u7*V?q zC7?WT9&9^T7ittfS!~IwsWS)S-1}*T;uj^>ZdO>nzDliBXXNxy;O7swHVm3ETF1EN z4>(O1#JYDsk>%W4c>Lb8d62J?Ix`%Uf2Yk(iFNB}y6}hU)_oQ5>d!CYZn)gNQs$4D zKRXVhm%qw}1`)u%qg{dS$JcVyN_M3G6VnGdaH2iso z*ZbP|p!QdtrOPGu48|kL$mfBbu>v}-m+cT8XD>e8k&fM(*Y<#MYaY*k@Ki@S_G~Xi l#{maD><5W>*iW*51^`FRlAF&_hJ*kB002ovPDHLkV1iBj&&U7( literal 0 HcmV?d00001 diff --git a/html/img/accounts/black_money.png b/html/img/accounts/black_money.png new file mode 100644 index 0000000000000000000000000000000000000000..a42f6aa5191115bd04d04a728fb3c3463e6f4345 GIT binary patch literal 1030 zcmV+h1o``kP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZT+Hn2g&!y2+1h(>773hKd&LYji7 zJxDS2q!OyV*_F1(HYnsEh!-iPJ(ZSP4aAjfgeH{rV4AN*TFttfb$4bmZx7v>?##{# z?V&y}hv%8+>;1pa$1D1}yJgw3cww6SpVXsi=&FhUWSBxsRZ)ZpHLjQ@PC%vrF-;5A zcci3ZS)uWZC+3;63 zP5NhNQG_7k$iD&Ti^Y6K$y>Lur5_yG;D0)PoSwjGx9WA?yK@Hs5kM{?1izg=O;;2A zE;12U>4j-}Ke7u86iTH~$S#kLGN9`%@&R4v!+raho}Ul3%PuT1H9YLaYQ8!YA?Of- zVztV(#YN7~&4oJYkHxr{N_qVKVv+mBqQ_rKrRWbJ>C*YRIj$`(Qmj_#5W-hqGN!6> zV{%d^3_~`GGW5GJG9sN!Mmm{{ygWMU$&U>V%5RSxkxnKfFN}=5(nrED_VAxIbo05=N-zC3)GHzE;!+1%vw@o_Ie!Z2_5K&81r!?IKr zh1|)L^k^EFQYm)L%mA>fvlD<*LqnXsdzb!LjLmA5H@mvL+HiFMpO3e$U&jh*>&SnZ zV$Kc?zZa1REj@pHO6~;d1>2x z`tTvs=`>qSb=2%5?DW0_oIrm*E|tjU^S*KVxKv_5*ZFQ`g|C;En1A||AJ*1bt5o_1QC~4jk~{59$PIcV{Q6qIgLP zKq^8|I&+4yWpT4m;NyGu+76Wq2dk9|S8_RzKNyeuf?vty+6KQmHpaPRl6W-Aj+7n(5dsSW zU}|`nua=fVm(h*oWj@%uw`CvvUM_QEd6{>0J#-nldmtFgTgU5_if`vg<{vZ*r`$_iK0G#)*@UBUHMF0Q*07*qoM6N<$f`k9( AtN;K2 literal 0 HcmV?d00001 diff --git a/html/img/cursor.png b/html/img/cursor.png new file mode 100644 index 0000000000000000000000000000000000000000..6ada58a4e3550f496cac2c9d447ea33829dc3148 GIT binary patch literal 431 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=DjSK$uZf!>a)(C|TkfQ4*Y=R#Ki=l*&+$n3-3imzP?iV4`QB zXK3b~uOhs#!ahWd2$lKAA=PHj|R?Wsg9S z`&IHf2TyHlIAOqZsdTPq)6`tXk4zn|Njeo`DMAiTswGpzq8#fu6%>W6+_={&lrx=B z=9FF78YZCCu*UO6c2ovyq=>^bl`o>YTbkBzDfl?`XD$?dvXJ3ZxKn?|!l?<2DS8Y0 zw_G?i*Wv#6pzB}7&rSE3^kmiIEf=_qI1?&ELnG>f__R}!4{lb7OW5{jGVi-q@r>JL zQS0`+Vdg%_of6shpK-s;hJ$+xD(A&NJAGfzAl~K>+jpi;ra%QQmqv{b^I4DFWiZrz V^21*%)dLuw44$rjF6*2UngBc`p>O~I literal 0 HcmV?d00001 diff --git a/html/img/keys/enter.png b/html/img/keys/enter.png new file mode 100644 index 0000000000000000000000000000000000000000..3eb9a1f69f58c651517329c92d28cdb1c605f165 GIT binary patch literal 941 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h5*QjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ISV`@iy0XB4ude`@%$Aj3=GUpo-U3d6>)E`8wN=`3bZEbov^iFaeu%P z(=cbwj44wlOz4rm5xb{;*Ri~}uR6cp(A&Mg;nJ7c^H#o^DiE{vT2%I1{SRyZiuLSP z%I`LO*R@CY*bePa+aw;ZJ8?S+Bq+DcEWq?az(jNYVCfZ787ofAZePh8!fO)pBkQX z_v_cMN3~tQ9xnRXb?ICkwaPbd-|8+sfB5~ocaKb5*$ZEQP2MMD?ps&IpveBkTdrZ6 zxw-l0$rY8AfmJN&5XWi1Tr~N;qpPCYQm=EdrvtPXJvz5h@~FDPw92D`R+fPvAFW@~ zU8c75`%1Gbh1a`Q>?qE0`*<(h^|W${-y)Ec<2}XS`n>x2)3WZB?5;)4TWYMP-*<76OIq zPp@4X%Z+C%*K#BUX=ORzsAov;Kl`m>i&y`Jz)nzj*Qmyplm-1%6v*YUbiCHwmEO<$ zF|Z@`-}HhOKR<9>X}?rT5Bm9ye^tw4euv}#-v4JmQzRDkY{|X*_d_{Xwfto_xNQ|y z-^Qlff58%JWZtYCU#*y5vIf?_WBTiPU(9hK5Tmx!-~Iodkpb3zr{Lwk`bljQz#(xy zvE05v9vtTHlU}QP{nuV*08Uf+$??{$l9IqgWxio$Zh{XeF$LeaxXn-#^iFnsKzTLkWYeXNfKEXTvUB0pJdzPZ}OMgdS+TyQ( lJso37+@RE7f9~qla<)GklNn{1`ISV`@iy0XBj({-ZRBb+Kpaxz~7srr_xVN`&cQqS`I9#;&|Ns0smZ-L@ zqu)%cbtmkrE=&Hfsn_t^{^k|)kLw3AbqG7mVR+;>`#|k>^_ZL6&QAQlndu0pf*(U6 zREkAFy}^PJuTYF$!{g|Ur7IbD{_6-gJlsE>3DGO)9eE;D=anIC*ESQi{xCV$~42}L!4TJCrkQD1~tJw zr&teYqgpL=o@s|#!;B|~71m*K' + + '
{{title}}
' + + '{{#isDefault}}{{/isDefault}}' + + '{{#isBig}} + + + + + + + +
+
Ajouter un contact
+
+
+ + + + +
+
+
+ + + + + + + + + + + \ No newline at end of file diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..14d1afdb --- /dev/null +++ b/server/main.lua @@ -0,0 +1,309 @@ +ESX = nil + +TriggerEvent('esx:getSharedObject', function(obj) + ESX = obj +end) + +local RegisteredCallbacks = {} +local DisptachRequestId = 0 + +function GenerateUniquePhoneNumber() + + local foundNumber = false + local phoneNumber = nil + + while not foundNumber do + + phoneNumber = math.random(10000, 99999) + + local result = MySQL.Sync.fetchAll( + 'SELECT COUNT(*) as count FROM users WHERE phone_number = @phoneNumber', + { + ['@phoneNumber'] = phoneNumber + } + ) + + local count = tonumber(result[1].count) + + if count == 0 then + foundNumber = true + end + + end + + return phoneNumber +end + +function GetDistpatchRequestId() + + local requestId = DisptachRequestId + + if DisptachRequestId < 65535 then + DisptachRequestId = DisptachRequestId + 1 + else + DisptachRequestId = 0 + end + + return requestId + +end + +AddEventHandler('esx_phone:getDistpatchRequestId', function(cb) + cb(GetDistpatchRequestId()) +end) + +AddEventHandler('onResourceStart', function(ressource) + if ressource == 'esx_phone' then + TriggerEvent('esx_phone:ready') + end +end) + +AddEventHandler('esx:playerLoaded', function(source) + + local xPlayer = ESX.GetPlayerFromId(source) + + MySQL.Async.fetchAll( + 'SELECT * FROM users WHERE identifier = @identifier', + { + ['@identifier'] = xPlayer.identifier + }, + function(result) + + local phoneNumber = result[1].phone_number + + if phoneNumber == nil then + + phoneNumber = GenerateUniquePhoneNumber() + + MySQL.Async.execute( + 'UPDATE users SET phone_number = @phone_number WHERE identifier = @identifier', + { + ['@identifier'] = xPlayer.identifier, + ['@phone_number'] = phoneNumber + } + ) + end + + xPlayer.set('phoneNumber', phoneNumber) + + local contacts = {} + + MySQL.Async.fetchAll( + 'SELECT * FROM user_contacts WHERE identifier = @identifier ORDER BY name ASC', + { + ['@identifier'] = xPlayer.identifier + }, + function(result2) + + for i=1, #result2, 1 do + + table.insert(contacts, { + name = result2[i].name, + number = result2[i].number, + online = false + }) + + local xPlayers = ESX.GetPlayers() + + for k, v in pairs(xPlayers) do + if v.get('phoneNumber') == contacts[i].number then + contacts[i].online = true + end + end + + end + + xPlayer.set('contacts', contacts) + + TriggerClientEvent('esx_phone:loaded', source, phoneNumber, contacts) + + end + ) + + end + ) + +end) + + +RegisterServerEvent('esx_phone:reload') +AddEventHandler('esx_phone:reload', function(phoneNumber) + + local xPlayer = ESX.GetPlayerFromId(source) + local contacts = {} + + MySQL.Async.fetchAll( + 'SELECT * FROM user_contacts WHERE identifier = @identifier ORDER BY name ASC', + { + ['@identifier'] = xPlayer.identifier + }, + function(result2) + + for i=1, #result2, 1 do + + table.insert(contacts, { + name = result2[i].name, + number = result2[i].number, + online = false + }) + + local xPlayers = ESX.GetPlayers() + + for k, v in pairs(xPlayers) do + if v.get('phoneNumber') == contacts[i].number then + contacts[i].online = true + end + end + + end + + xPlayer['contacts'] = contacts + + TriggerClientEvent('esx_phone:loaded', source, phoneNumber, contacts) + + end + ) + +end) + +RegisterServerEvent('esx_phone:registerCallback') +AddEventHandler('esx_phone:registerCallback', function(cb) + table.insert(RegisteredCallbacks, cb) +end) + +RegisterServerEvent('esx_phone:send') +AddEventHandler('esx_phone:send', function(phoneNumber, message, anon) + for i=1, #RegisteredCallbacks, 1 do + RegisteredCallbacks[i](source, phoneNumber, message, anon) + end +end) + +RegisterServerEvent('esx_phone:addPlayerContact') +AddEventHandler('esx_phone:addPlayerContact', function(phoneNumber, contactName) + + local xPlayers = ESX.GetPlayers() + local foundNumber = false + local foundPlayer = nil + + MySQL.Async.fetchAll( + 'SELECT phone_number FROM users WHERE phone_number = @number', + { + ['@number'] = phoneNumber + }, + function(result) + + if result[1] ~= nil then + foundNumber = true + end + + if foundNumber then + + local xPlayer = ESX.GetPlayerFromId(source) + + if phoneNumber == xPlayer.get('phoneNumber') then + TriggerClientEvent('esx:showNotification', _source, 'Vous ne pouvez pas vous ajouter vous-même') + else + + local hasAlreadyAdded = false + local contacts = xPlayer.get('contacts') + + for i=1, #contacts, 1 do + if contacts[i].number == phoneNumber then + hasAlreadyAdded = true + end + end + + if hasAlreadyAdded then + TriggerClientEvent('esx:showNotification', _source, 'Ce numéro est déja dans votre liste de contacts') + else + + table.insert(contacts, { + name = contactName, + number = phoneNumber, + }) + + xPlayer.set('contacts', contacts) + + MySQL.Async.execute( + 'INSERT INTO user_contacts (identifier, name, number) VALUES (@identifier, @name, @number)', + { + ['@identifier'] = xPlayer.identifier, + ['@name'] = contactName, + ['@number'] = phoneNumber + }, + function(rowsChanged) + + TriggerClientEvent('esx:showNotification', _source, 'Contact ajouté') + + local xPlayers = ESX.GetPlayers() + local isOnline = false + + for k,v in pairs(xPlayers) do + if v.get('phoneNumber') == phoneNumber then + isOnline = true + break + end + end + + TriggerClientEvent('esx_phone:addContact', source, contactName, phoneNumber, isOnline) + end + ) + + end + end + + else + TriggerClientEvent('esx:showNotification', source, 'Ce numéro n\'est pas attribué...') + end + + end + ) + +end) + +AddEventHandler('esx_phone:ready', function() + TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) + + local xPlayer = ESX.GetPlayerFromId(source) + local xPlayers = ESX.GetPlayers() + local job = 'player' + + print('MESSAGE => ' .. xPlayer.name .. '@' .. phoneNumber .. ' : ' .. message) + + for k, v in pairs(xPlayers) do + + if phoneNumber == "police" then + + if v.job.name == 'cop' then + job = "ALERTE POLICE" + TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, job, GetDistpatchRequestId()) + end + + elseif phoneNumber == "ambulance" then + + if v.job.name == 'ambulance' then + job = "ALERTE AMBULANCE" + TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, job, GetDistpatchRequestId()) + + end + + elseif phoneNumber == "depanneur" then + + if v.job.name == 'depanneur' then + job = "APPEL DÉPANNEUR" + TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, job, GetDistpatchRequestId()) + end + + elseif v.get('phoneNumber') == phoneNumber then + TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, job, false) + end + + end + + end) +end) + +RegisterServerEvent('esx_phone:stopDispatch') +AddEventHandler('esx_phone:stopDispatch', function(dispatchRequestId) + TriggerClientEvent('esx_phone:stopDispatch', -1, dispatchRequestId, GetPlayerName(source)) +end) \ No newline at end of file From edfbb54d03ba56502ecacf02c7b8463c61eca0b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 11:08:51 +0200 Subject: [PATCH 0029/3224] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 185d67a3..3521c712 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,12 @@ FXServer esx_phone [INSTALLATION] 1) CD in your resources folder - -2) +2) Clone the repository ``` git clone https://github.com/FXServer-ESX/fxserver-esx_phone ``` -3) Add this in your server.cfg : +3) Import esx_phone.sql in your database +4) Add this in your server.cfg : ``` start esx_phone From 6df8b18357144ed74c907cc1519c5f1f7d7d695b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 11:10:03 +0200 Subject: [PATCH 0030/3224] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 3521c712..1a435268 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ # fxserver-esx_phone FXServer esx_phone +[INFO] + +Original script by FiveDev => https://github.com/FiveDev-FR/esx_phone-by-FiveDev + [INSTALLATION] 1) CD in your resources folder From bcdcdb91c28c48c0592f90ebaf30ed483d09ebac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 11:17:15 +0200 Subject: [PATCH 0031/3224] Update README.md --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index f88ada79..8b2041d7 100644 --- a/README.md +++ b/README.md @@ -20,4 +20,15 @@ start es_extended start esx_menu_default start esx_menu_list start esx_menu_dialog +``` + +4) Create a resource or add this in an existing resource : + +``` +`server.lua + +TriggerEvent('es:setDefaultSettings', { + nativeMoneySystem = false, +}); + ``` \ No newline at end of file From 9016f70ef69c15c631edc080e6ee39801b68ed1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 11:17:37 +0200 Subject: [PATCH 0032/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8b2041d7..325054d4 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ start esx_menu_dialog 4) Create a resource or add this in an existing resource : ``` -`server.lua +server.lua TriggerEvent('es:setDefaultSettings', { nativeMoneySystem = false, From 7a79e41e97a20ada5507e238a24a91bc5257028c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 11:19:02 +0200 Subject: [PATCH 0033/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..d61d51c1 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-skinchanger +FXServer SkinChanger From 463d5899e1a595d3c7100203a1dddddb809d0693 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 11:19:52 +0200 Subject: [PATCH 0034/3224] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1a435268..244d4fd1 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,11 @@ Original script by FiveDev => https://github.com/FiveDev-FR/esx_phone-by-FiveDev 1) CD in your resources folder 2) Clone the repository ``` -git clone https://github.com/FXServer-ESX/fxserver-esx_phone +git clone https://github.com/FXServer-ESX/fxserver-esx_phone esx_phone ``` 3) Import esx_phone.sql in your database 4) Add this in your server.cfg : ``` start esx_phone -``` \ No newline at end of file +``` From 70bf511780831b6ad5e48e7937f5ddabccdc6b17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 11:21:32 +0200 Subject: [PATCH 0035/3224] Add files --- README.md | 13 +++ __resource.lua | 8 ++ client/main.lua | 217 ++++++++++++++++++++++++++++++++++++++++++++ skinchanger.net.dll | Bin 0 -> 8192 bytes 4 files changed, 238 insertions(+) create mode 100644 __resource.lua create mode 100644 client/main.lua create mode 100644 skinchanger.net.dll diff --git a/README.md b/README.md index d61d51c1..31d80153 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,15 @@ # fxserver-skinchanger FXServer SkinChanger + +[INSTALLATION] + +1) CD in your resources folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-skinchanger skinchanger +``` +3) Add this in your server.cfg : + +``` +start skinchanger +``` diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..430df89c --- /dev/null +++ b/__resource.lua @@ -0,0 +1,8 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'SkinChanger' + +client_scripts { + 'skinchanger.net.dll', + 'client/main.lua' +} \ No newline at end of file diff --git a/client/main.lua b/client/main.lua new file mode 100644 index 00000000..314858e0 --- /dev/null +++ b/client/main.lua @@ -0,0 +1,217 @@ +local Components = { + {label = 'Sexe', name = 'sex', value = 0}, + {label = 'Visage', name = 'face', value = 0}, + {label = 'Peau', name = 'skin', value = 0}, + {label = 'Type Barbe', name = 'beard_1', value = 0}, + {label = 'Taille barbe', name = 'beard_2', value = 0}, + {label = 'Couleur barbe 1', name = 'beard_3', value = 0}, + {label = 'Couleur barbe 2', name = 'beard_4', value = 0}, + {label = 'Cheveux 1', name = 'hair_1', value = 0}, + {label = 'Cheveux 2', name = 'hair_2', value = 0}, + {label = 'Couleur cheveux 1', name = 'hair_color_1', value = 0}, + {label = 'Couleur cheveux 2', name = 'hair_color_2', value = 0}, + {label = 'T-Shirt 1', name = 'tshirt_1', value = 0}, + {label = 'T-Shirt 2', name = 'tshirt_2', value = 0, textureof = 'tshirt_1'}, + {label = 'Torse 1', name = 'torso_1', value = 0}, + {label = 'Torse 2', name = 'torso_2', value = 0, textureof = 'torso_1'}, + {label = 'Calques 1', name = 'decals_1', value = 0}, + {label = 'Calques 2', name = 'decals_2', value = 0, textureof = 'decals_1'}, + {label = 'Bras', name = 'arms', value = 0}, + {label = 'Jambes 1', name = 'pants_1', value = 0}, + {label = 'Jambes 2', name = 'pants_2', value = 0, textureof = 'pants_1'}, + {label = 'Chaussures 1', name = 'shoes_1', value = 0}, + {label = 'Chaussures 2', name = 'shoes_2', value = 0, textureof = 'shoes_1'}, + {label = 'Masque 1', name = 'mask_1', value = 0}, + {label = 'Masque 2', name = 'mask_2', value = 0, textureof = 'mask_1'}, + {label = 'Gilet pare-balle 1', name = 'bproof_1', value = 0}, + {label = 'Gilet pare-balle 2', name = 'bproof_2', value = 0, textureof = 'bproof_1'}, + {label = 'Chaine 1', name = 'chain_1', value = 0}, + {label = 'Chaine 2', name = 'chain_2', value = 0, textureof = 'chain_1'}, + {label = 'Casque 1', name = 'helmet_1', value = 0}, + {label = 'Casque 2', name = 'helmet_2', value = 0, textureof = 'helmet_1'}, + {label = 'Lunettes 1', name = 'glasses_1', value = 0}, + {label = 'Lunettes 2', name = 'glasses_2', value = 0, textureof = 'glasses_1'}, +} + +local LastSex = 0 +local LoadSkin = nil +local LoadClothes = nil +local Character = {} + +for i=1, #Components, 1 do + Character[Components[i].name] = Components[i].value +end + +function GetMaxVals() + + local playerPed = GetPlayerPed(-1) + + local data = { + sex = 1, + face = 45, + skin = 45, + beard_1 = GetNumHeadOverlayValues(1), + beard_2 = 10, + beard_3 = 63, + beard_4 = 63, + hair_1 = GetNumberOfPedDrawableVariations(playerPed, 2) - 1, + hair_2 = GetNumberOfPedTextureVariations(playerPed, 2, Character['hair_1']) - 1, + hair_color_1 = 22, + hair_color_2 = 4, + tshirt_1 = GetNumberOfPedDrawableVariations(playerPed, 8) - 1, + tshirt_2 = GetNumberOfPedTextureVariations(playerPed, 8, Character['tshirt_1']) - 1, + torso_1 = GetNumberOfPedDrawableVariations(playerPed, 11) - 1, + torso_2 = GetNumberOfPedTextureVariations(playerPed, 11, Character['torso_1']) - 1, + decals_1 = GetNumberOfPedDrawableVariations(playerPed, 10) - 1, + decals_2 = GetNumberOfPedTextureVariations(playerPed, 10, Character['decals_1']) - 1, + arms = GetNumberOfPedDrawableVariations(playerPed, 3) - 1, + pants_1 = GetNumberOfPedDrawableVariations(playerPed, 4) - 1, + pants_2 = GetNumberOfPedTextureVariations(playerPed, 4, Character['pants_1']) - 1, + shoes_1 = GetNumberOfPedDrawableVariations(playerPed, 6) - 1, + shoes_2 = GetNumberOfPedTextureVariations(playerPed, 6, Character['shoes_1']) - 1, + mask_1 = GetNumberOfPedDrawableVariations(playerPed, 1) - 1, + mask_2 = GetNumberOfPedTextureVariations(playerPed, 1, Character['mask_1']) - 1, + bproof_1 = GetNumberOfPedDrawableVariations(playerPed, 9) - 1, + bproof_2 = GetNumberOfPedTextureVariations(playerPed, 9, Character['bproof_1']) - 1, + chain_1 = GetNumberOfPedDrawableVariations(playerPed, 7) - 1, + chain_2 = GetNumberOfPedTextureVariations(playerPed, 7, Character['chain_1']) - 1, + helmet_1 = GetNumberOfPedPropDrawableVariations(playerPed, 0) - 1, + helmet_2 = GetNumberOfPedTextureVariations(playerPed, 0, Character['helmet_1']) - 1, + glasses_1 = GetNumberOfPedPropDrawableVariations(playerPed, 1) - 1, + glasses_2 = GetNumberOfPedTextureVariations(playerPed, 1, Character['glasses_1'] - 1), + } + + return data + +end + +function ApplySkin(skin, clothes) + + local playerPed = GetPlayerPed(-1) + + for k,v in pairs(skin) do + Character[k] = v + end + + if clothes ~= nil then + + for k,v in pairs(clothes) do + if + k ~= 'sex' and + k ~= 'face' and + k ~= 'skin' and + k ~= 'beard_1' and + k ~= 'beard_2' and + k ~= 'beard_3' and + k ~= 'beard_4' and + k ~= 'hair_1' and + k ~= 'hair_2' and + k ~= 'hair_color_1' and + k ~= 'hair_color_2' + then + Character[k] = v + end + end + + end + + SetPedHeadBlendData(playerPed, Character['face'], Character['face'], Character['face'], Character['skin'], Character['skin'], Character['skin'], 1.0, 1.0, 1.0, true) + SetPedHeadOverlay(playerPed, 1, Character['beard_1'], (Character['beard_2'] / 10) + 0.0) -- Beard + SetPedHeadOverlayColor(playerPed, 1, 1, Character['beard_3'], Character['beard_4']) -- Beard Color + SetPedComponentVariation(playerPed, 2, Character['hair_1'], Character['hair_2'], 2) -- Hair + SetPedHairColor(playerPed, Character['hair_color_1'], Character['hair_color_2']) -- Hair Color + SetPedComponentVariation(playerPed, 8, Character['tshirt_1'],Character['tshirt_2'], 2) -- Tshirt + SetPedComponentVariation(playerPed, 11, Character['torso_1'], Character['torso_2'], 2) -- torso parts + SetPedComponentVariation(playerPed, 3, Character['arms'], 0, 2) -- torso + SetPedComponentVariation(playerPed, 10, Character['decals_1'], Character['decals_2'], 2) -- decals + SetPedComponentVariation(playerPed, 4, Character['pants_1'], Character['pants_2'], 2) -- pants + SetPedComponentVariation(playerPed, 6, Character['shoes_1'], Character['shoes_2'], 2) -- shoes + SetPedComponentVariation(playerPed, 1, Character['mask_1'], Character['mask_2'], 2) -- mask + SetPedComponentVariation(playerPed, 9, Character['bproof_1'], Character['bproof_2'], 2) -- bulletproof + SetPedComponentVariation(playerPed, 7, Character['chain_1'], Character['chain_2'], 2) -- chain + SetPedPropIndex(playerPed, 0, Character['helmet_1'], Character['helmet_2'], 2) -- Helmet + SetPedPropIndex(playerPed, 1, Character['glasses_1'], Character['glasses_2'], 2) -- Glasses + +end + +AddEventHandler('skinchanger:getData', function(cb) + + local components = json.decode(json.encode(Components)) + + for k,v in pairs(Character) do + for i=1, #components, 1 do + if k == components[i].name then + components[i].value = v + end + end + end + + cb(components, GetMaxVals()) +end) + +AddEventHandler('skinchanger:change', function(key, val) + + Character[key] = val + + if key == 'sex' then + TriggerEvent('skinchanger:loadSkin', Character) + else + ApplySkin(Character) + end + +end) + +AddEventHandler('skinchanger:getSkin', function(cb) + cb(Character) +end) + +AddEventHandler('skinchanger:modelLoaded', function() + + if LoadSkin ~= nil then + + ApplySkin(LoadSkin) + LoadSkin = nil + + end + + if LoadClothes ~= nil then + + ApplySkin(LoadClothes.playerSkin, LoadClothes.clothesSkin) + LoadClothes = nil + + end + +end) + +RegisterNetEvent('skinchanger:loadSkin') +AddEventHandler('skinchanger:loadSkin', function(skin) + + LoadSkin = skin + + if skin['sex'] == 0 then + TriggerEvent('skinchanger:LoadDefaultModel', true) + else + TriggerEvent('skinchanger:LoadDefaultModel', false) + end + + LastSex = skin['sex'] + +end) + +RegisterNetEvent('skinchanger:loadClothes') +AddEventHandler('skinchanger:loadClothes', function(playerSkin, clothesSkin) + + LoadClothes = { + playerSkin = playerSkin, + clothesSkin = clothesSkin + } + + if playerSkin['sex'] == 0 then + TriggerEvent('skinchanger:LoadDefaultModel', true) + else + TriggerEvent('skinchanger:LoadDefaultModel', false) + end + + LastSex = skin['sex'] + +end) \ No newline at end of file diff --git a/skinchanger.net.dll b/skinchanger.net.dll new file mode 100644 index 0000000000000000000000000000000000000000..315d79e572ca46eba6b42ac480c88da7ca77d449 GIT binary patch literal 8192 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 literal 0 HcmV?d00001 From d533effb9741bc0c954669036b4c3519a6d8e4e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 11:31:24 +0200 Subject: [PATCH 0036/3224] Update README.md --- README.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/README.md b/README.md index 31d80153..f09dba02 100644 --- a/README.md +++ b/README.md @@ -13,3 +13,72 @@ git clone https://github.com/FXServer-ESX/fxserver-skinchanger skinchanger ``` start skinchanger ``` + +[HOWTO] + +``` +local isMale = true + +local skin = { + sex = 1, + face = 0, + skin = 0, + beard_1 = 0, + beard_2 = 0, + beard_3 = 0, + beard_4 = 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, + 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 = 0, + helmet_2 = 0, + glasses_1 = 0, + glasses_2 = 0, + } +} + +-- Load freemode model +TriggerEvent('skinchanger:LoadDefaultModel', isMale) + +-- Load skin +TriggerEvent('skinchanger:loadSkin', skin) + +-- you can also load only some components : +TriggerEvent('skinchanger:loadSkin', { + beard_1 = 0, + beard_2 = 0, + } +}) + +-- Get list of components and maxVals +TriggerEvent('skinchanger:getData', function(components, maxVals) + + print('Components => ' .. json.encode(components)) + print('MaxVals => ' .. json.encode(maxVals)) + +end) + +-- Get current skin +TriggerEvent('skinchanger:getSkin', function(skin) + print(json.encode(skin)) +end) + +``` From ebecf8e0e28ce6fa9d006fdf44dd1f5b9d92f1ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 11:32:19 +0200 Subject: [PATCH 0037/3224] Update README.md --- README.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f09dba02..7f9e4cb0 100644 --- a/README.md +++ b/README.md @@ -42,17 +42,16 @@ local skin = { 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, + mask_1 = 0, + mask_2 = 0, + bproof_1 = 0, + bproof_2 = 0, + chain_1 = 0, + chain_2 = 0, helmet_1 = 0, helmet_2 = 0, glasses_1 = 0, glasses_2 = 0, - } } -- Load freemode model From ecc06ced9acf193d692fde4e851ad86ad9b4c2d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 11:32:48 +0200 Subject: [PATCH 0038/3224] Update README.md --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 7f9e4cb0..d9183941 100644 --- a/README.md +++ b/README.md @@ -64,15 +64,12 @@ TriggerEvent('skinchanger:loadSkin', skin) TriggerEvent('skinchanger:loadSkin', { beard_1 = 0, beard_2 = 0, - } }) -- Get list of components and maxVals TriggerEvent('skinchanger:getData', function(components, maxVals) - print('Components => ' .. json.encode(components)) print('MaxVals => ' .. json.encode(maxVals)) - end) -- Get current skin From d17270a0fca79f677fc6e290891183133601ce88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 11:37:56 +0200 Subject: [PATCH 0039/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..ed3a9a04 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_skin +FXServer ESX Skin From 047f22841a6e5a1e9bca851fbc21c4d357f6f229 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 11:39:06 +0200 Subject: [PATCH 0040/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d9183941..9e133a9b 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ git clone https://github.com/FXServer-ESX/fxserver-skinchanger skinchanger start skinchanger ``` -[HOWTO] +[USAGE] ``` local isMale = true From cb58dafe51b6e6b7d302bda6942b285882f02fee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 11:40:07 +0200 Subject: [PATCH 0041/3224] Add files --- README.md | 13 +++ __resource.lua | 12 +++ client/main.lua | 206 ++++++++++++++++++++++++++++++++++++++++++++++++ server/main.lua | 55 +++++++++++++ 4 files changed, 286 insertions(+) create mode 100644 __resource.lua create mode 100644 client/main.lua create mode 100644 server/main.lua diff --git a/README.md b/README.md index ed3a9a04..4fd1f966 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,15 @@ # fxserver-esx_skin FXServer ESX Skin + +[INSTALLATION] + +1) CD in your resources folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-esx_skin esx_skin +``` +3) Add this in your server.cfg : + +``` +start esx_skin +``` diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..ae7fbeac --- /dev/null +++ b/__resource.lua @@ -0,0 +1,12 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'ESX Skin' + +server_scripts { + '@mysql-async/lib/MySQL.lua', + 'server/main.lua' +} + +client_scripts { + 'client/main.lua' +} diff --git a/client/main.lua b/client/main.lua new file mode 100644 index 00000000..8f65df36 --- /dev/null +++ b/client/main.lua @@ -0,0 +1,206 @@ +ESX = nil +local HasLoadedModel = false +local LastSkin = nil + +Citizen.CreateThread(function() + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end +end) + +function OpenMenu(submitCb, cancelCb, restrict) + + TriggerEvent('skinchanger:getSkin', function(skin) + LastSkin = skin + end) + + TriggerEvent('skinchanger:getData', function(components, maxVals) + + local elements = {} + local _components = {} + + -- Restrict menu + if restrict == nil then + for i=1, #components, 1 do + _components[i] = components[i] + end + else + for i=1, #components, 1 do + + local found = false + + for j=1, #restrict, 1 do + if components[i].name == restrict[j] then + found = true + end + end + + if found then + table.insert(_components, components[i]) + end + + end + end + + -- Insert elements + for i=1, #_components, 1 do + + local data = { + label = _components[i].label, + name = _components[i].name, + value = _components[i].value, + textureof = _components[i].textureof, + type = 'slider' + } + + for k,v in pairs(maxVals) do + if k == _components[i].name then + data.max = v + end + end + + table.insert(elements, data) + + end + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'skin', + { + title = 'Skin Menu', + align = 'top-left', + elements = elements + }, + submitCb, + function(data, menu) + + menu.close() + + TriggerEvent('skinchanger:loadSkin', LastSkin) + + if cancelCb ~= nil then + cancelCb(data, menu) + end + + end, + function(data, menu) + + TriggerEvent('skinchanger:getSkin', function(skin) + + if skin[data.current.name] ~= data.current.value then + + -- Change skin element + TriggerEvent('skinchanger:change', data.current.name, data.current.value) + + -- Update max values + TriggerEvent('skinchanger:getData', function(components, maxVals) + for i=1, #elements, 1 do + if elements[i].textureof ~= nil then + + local newData = {max = maxVals[elements[i].name]} + + if data.current.name == elements[i].textureof then + newData.value = 0 + end + + menu.update({name = elements[i].name}, newData) + + end + end + end) + + end + + end) + + end + ) + + end) + +end + +function OpenSaveableMenu(submitCb, cancelCb, restrict) + + TriggerEvent('skinchanger:getSkin', function(skin) + LastSkin = skin + end) + + OpenMenu(function(data, menu) + + menu.close() + + TriggerEvent('skinchanger:getSkin', function(skin) + + TriggerServerEvent('esx_skin:save', skin) + + if submitCb ~= nil then + submitCb(data, menu) + end + + end) + + end, cancelCb, restrict) + +end + +AddEventHandler('playerSpawned', function() + TriggerEvent('skinchanger:LoadDefaultModel', true) +end) + +AddEventHandler('esx_skin:getLastSkin', function(cb) + cb(LastSkin) +end) + +RegisterNetEvent('esx_skin:openMenu') +AddEventHandler('esx_skin:openMenu', function(submitCb, cancelCb) + OpenMenu(submitCb, cancelCb, nil) +end) + +RegisterNetEvent('esx_skin:openRestrictedMenu') +AddEventHandler('esx_skin:openRestrictedMenu', function(submitCb, cancelCb, restrict) + OpenMenu(submitCb, cancelCb, restrict) +end) + +RegisterNetEvent('esx_skin:openSaveableMenu') +AddEventHandler('esx_skin:openSaveableMenu', function(submitCb, cancelCb) + OpenSaveableMenu(submitCb, cancelCb, nil) +end) + +RegisterNetEvent('esx_skin:openSaveableRestrictedMenu') +AddEventHandler('esx_skin:openSaveableRestrictedMenu', function(submitCb, cancelCb, restrict) + OpenSaveableMenu(submitCb, cancelCb, restrict) +end) + +AddEventHandler('skinchanger:modelLoaded', function() + + if not HasLoadedModel then + + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) + + HasLoadedModel = true + + if skin == nil then + OpenSaveableMenu(nil, nil, nil) + else + TriggerEvent('skinchanger:loadSkin', skin) + end + + end) + + end +end) + +Citizen.CreateThread(function() + while true do + + Citizen.Wait(0) + + local playerPed = GetPlayerPed(-1) + + if IsEntityDead(playerPed) then + HasLoadedModel = false + end + + end +end) \ No newline at end of file diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..708f9fbb --- /dev/null +++ b/server/main.lua @@ -0,0 +1,55 @@ +ESX = nil + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +RegisterServerEvent('esx_skin:save') +AddEventHandler('esx_skin:save', function(skin) + + local xPlayer = ESX.GetPlayerFromId(source) + + MySQL.Async.execute( + 'UPDATE users SET `skin` = @skin WHERE identifier = @identifier', + { + ['@skin'] = json.encode(skin), + ['@identifier'] = xPlayer.identifier + } + ) + +end) + +ESX.RegisterServerCallback('esx_skin:getPlayerSkin', function(source, cb) + + local xPlayer = ESX.GetPlayerFromId(source) + + MySQL.Async.fetchAll( + 'SELECT * FROM users WHERE identifier = @identifier', + { + ['@identifier'] = xPlayer.identifier + }, + function(users) + + local user = users[1] + local skin = nil + + local jobSkin = { + skin_male = xPlayer.job.skin_male, + skin_female = xPlayer.job.skin_female + } + + if user.skin ~= nil then + skin = json.decode(user.skin) + end + + cb(skin, jobSkin) + + end + ) + +end) + +-- Commands +TriggerEvent('es:addGroupCommand', 'skin', "admin", function(source, args, user) + TriggerClientEvent('esx_skin:openSaveableMenu', source) +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, 'Insufficienct permissions!') +end) \ No newline at end of file From 1081f133b07b698db5158b81025b7ee861062484 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 11:43:15 +0200 Subject: [PATCH 0042/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..a34ae4fc --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_addonaccount +ESX AddonAccount From 1c68b1b6245830050c1316d6467e2b0af773dd37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 11:51:40 +0200 Subject: [PATCH 0043/3224] Update README.md --- README.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/README.md b/README.md index a34ae4fc..0aede570 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,36 @@ # fxserver-esx_addonaccount ESX AddonAccount + +[INSTALLATION] + +1) CD in your resources folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-esx_addonaccount esx_addonaccount +``` +3) Add this in your server.cfg : + +``` +start esx_addonaccount +``` + +[USAGE] + +There is two types of accounts : shared and not shared. + +- Shared accounts dont belong to a specific user. Example : society account. +- Not shared accounts are created for every user in the server. Example : property black money + +You must create the account in the database (addon_account) before using it : + +name = name of the account, label = label of the account, shared (0 or 1) = Is account shared + +``` +TriggerEvent('esx_addonaccount:getSharedAccount', 'society_realestateagent', function(account) + account.addMoney(500) +end) + +TriggerEvent('esx_addonaccount:getAccount', 'property_black_money', 'steam:0123456789', function(account) + account.removeMoney(500) +end) +``` From efa899a6a3bba403728812577954e9f3c5ad8a30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 11:54:00 +0200 Subject: [PATCH 0044/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0aede570..14e7d938 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ start esx_addonaccount There is two types of accounts : shared and not shared. - Shared accounts dont belong to a specific user. Example : society account. -- Not shared accounts are created for every user in the server. Example : property black money +- Not shared accounts are created for every user in the server. They are created in db when player is loaded, Example : property black money You must create the account in the database (addon_account) before using it : From 25c04168b5852c1fce051a0c1367c6ef28d9ab7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 11:55:48 +0200 Subject: [PATCH 0045/3224] Add files --- __resource.lua | 9 +++ server/classes/addonaccount.lua | 61 ++++++++++++++++ server/main.lua | 119 ++++++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+) create mode 100644 __resource.lua create mode 100644 server/classes/addonaccount.lua create mode 100644 server/main.lua diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..4bb086e3 --- /dev/null +++ b/__resource.lua @@ -0,0 +1,9 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'ESX AddonAccount' + +server_scripts { + '@mysql-async/lib/MySQL.lua', + 'server/classes/addonaccount.lua', + 'server/main.lua' +} diff --git a/server/classes/addonaccount.lua b/server/classes/addonaccount.lua new file mode 100644 index 00000000..333fe7db --- /dev/null +++ b/server/classes/addonaccount.lua @@ -0,0 +1,61 @@ +function CreateAddonAccount(name, owner, money) + + local self = {} + + self.name = name + self.owner = owner + self.money = 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 + } + ) + 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 + } + ) + end + + end + + return self + +end \ No newline at end of file diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..1f93a25c --- /dev/null +++ b/server/main.lua @@ -0,0 +1,119 @@ +ESX = nil +local AccountsIndex = {} +local Accounts = {} +local SharedAccounts = {} + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +AddEventHandler('onMySQLReady', function () + + local result = MySQL.Sync.fetchAll('SELECT * FROM addon_account') + + 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 + + else + money = result2[1].money + end + + local addonAccount = CreateAddonAccount(name, nil, money) + SharedAccounts[name] = addonAccount + + end + + end + +end) + +function GetAccount(name, owner) + for i=1, #Accounts[name], 1 do + if Accounts[name][i].owner == owner then + return Accounts[name][i] + end + end +end + +function GetSharedAccount(name) + return SharedAccounts[name] +end + +AddEventHandler('esx_addonaccount:getAccount', function(name, owner, cb) + cb(GetAccount(name, owner)) +end) + +AddEventHandler('esx_addonaccount:getSharedAccount', function(name, cb) + cb(GetSharedAccount(name)) +end) + +AddEventHandler('esx:playerLoaded', function(source) + + local xPlayer = ESX.GetPlayerFromId(source) + local addonAccounts = {} + + for i=1, #AccountsIndex, 1 do + + local name = AccountsIndex[i] + 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 + } + ) + + account = CreateAddonAccount(name, xPlayer.identifier, 0) + table.insert(Accounts[name], account) + end + + table.insert(addonAccounts, account) + + end + + xPlayer.set('addonAccounts', addonAccounts) + +end) From ecb357285879a7d19b61256639549e07e7e8fd33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 11:56:36 +0200 Subject: [PATCH 0046/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..6ff79975 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_addoninventory +ESX AddonInventory From 0e988247fa9fa15ebb729f075b3f73e87f32600b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 11:59:31 +0200 Subject: [PATCH 0047/3224] Update README.md --- README.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/README.md b/README.md index 6ff79975..8324bdbc 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,36 @@ # fxserver-esx_addoninventory ESX AddonInventory + +[INSTALLATION] + +1) CD in your resources folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-esx_addoninventory esx_addoninventory +``` +3) Add this in your server.cfg : + +``` +start esx_addoninventory +``` + +[USAGE] + +There is two types of inventories : shared and not shared. + +- Shared inventories dont belong to a specific user. Example : foodstore items. +- Not shared inventories are created for every user in the server. They are created in db when player is loaded, Example : property items money + +You must create the inventory in the database (addon_inventory) before using it : + +name = name of the inventory, label = label of the inventory, shared (0 or 1) = Is inventory shared + +``` +TriggerEvent('esx_addoninventory:getSharedInventory', 'main_grocery', function(inventory) + inventory.addItem('bread', 1) +end) + +TriggerEvent('esx_addoninventory:getInventory', 'property', 'steam:0123456789', function(inventory) + inventory.removeItem('water', 1) +end) +``` From 1a7f048e7ea420b06a456828f3babbfcb694584e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 12:01:13 +0200 Subject: [PATCH 0048/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8324bdbc..692405a5 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ start esx_addoninventory There is two types of inventories : shared and not shared. - Shared inventories dont belong to a specific user. Example : foodstore items. -- Not shared inventories are created for every user in the server. They are created in db when player is loaded, Example : property items money +- Not shared inventories are created for every user in the server. They are created in db when player is loaded, Example : property items You must create the inventory in the database (addon_inventory) before using it : From 65f67f4e0f0c512bf40bba5cd121d7d33f68a1e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 12:02:21 +0200 Subject: [PATCH 0049/3224] Add files --- __resource.lua | 9 +++ server/classes/addoninventory.lua | 102 ++++++++++++++++++++++++ server/main.lua | 125 ++++++++++++++++++++++++++++++ 3 files changed, 236 insertions(+) create mode 100644 __resource.lua create mode 100644 server/classes/addoninventory.lua create mode 100644 server/main.lua diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..44dce451 --- /dev/null +++ b/__resource.lua @@ -0,0 +1,9 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'ESX AddonInventory' + +server_scripts { + '@mysql-async/lib/MySQL.lua', + 'server/classes/addoninventory.lua', + 'server/main.lua' +} \ No newline at end of file diff --git a/server/classes/addoninventory.lua b/server/classes/addoninventory.lua new file mode 100644 index 00000000..fca3dbe9 --- /dev/null +++ b/server/classes/addoninventory.lua @@ -0,0 +1,102 @@ +function CreateAddonInventory(name, owner, items) + + local self = {} + + self.name = name + self.owner = owner + self.items = items + + self.addItem = function(name, count) + + local item = self.getItem(name) + item.count = item.count + count + + self.saveItem(name, item.count) + end + + self.removeItem = function(name, count) + + local item = self.getItem(name) + item.count = item.count - count + + self.saveItem(name, item.count) + end + + self.setItem = function(name, count) + + local item = self.getItem(name) + item.count = count + + self.saveItem(name, item.count) + end + + self.getItem = function(name) + + for i=1, #self.items, 1 do + if self.items[i].name == name then + return self.items[i] + end + end + + item = { + name = name, + count = 0, + label = Items[name] + } + + 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)', + { + ['@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)', + { + ['@inventory_name'] = self.name, + ['@item_name'] = name, + ['@count'] = 0, + ['@owner'] = self.owner + } + ) + end + + return item + + end + + 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', + { + ['@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', + { + ['@inventory_name'] = self.name, + ['@item_name'] = name, + ['@count'] = count, + ['@owner'] = self.owner + } + ) + end + + end + + return self + +end + diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..a821db2d --- /dev/null +++ b/server/main.lua @@ -0,0 +1,125 @@ +ESX = nil +Items = {} +local InventoriesIndex = {} +local Inventories = {} +local SharedInventories = {} + + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +AddEventHandler('onMySQLReady', function() + + local items = MySQL.Sync.fetchAll('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') + + 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', + { + ['@inventory_name'] = name + } + ) + + if shared == 0 then + + table.insert(InventoriesIndex, name) + + Inventories[name] = {} + local items = {} + + for j=1, #result2, 1 do + + local itemName = result2[j].name + local itemCount = result2[j].count + local itemOwner = result2[j].owner + + if items[itemOwner] == nil then + items[itemOwner] = {} + end + + table.insert(items[itemOwner], { + name = itemName, + count = itemCount, + label = Items[itemName] + }) + + end + + for k,v in pairs(items) do + local addonInventory = CreateAddonInventory(name, k, v) + table.insert(Inventories[name], addonInventory) + end + + else + + local items = {} + + for j=1, #result2, 1 do + table.insert(items, { + name = result2[j].name, + count = result2[j].count, + label = Items[result2[j].name] + }) + end + + local addonInventory = CreateAddonInventory(name, nil, items) + SharedInventories[name] = addonInventory + + end + + end + +end) + +function GetInventory(name, owner) + for i=1, #Inventories[name], 1 do + if Inventories[name][i].owner == owner then + return Inventories[name][i] + end + end +end + +function GetSharedInventory(name) + return SharedInventories[name] +end + +AddEventHandler('esx_addoninventory:getInventory', function(name, owner, cb) + cb(GetInventory(name, owner)) +end) + +AddEventHandler('esx_addoninventory:getSharedInventory', function(name, cb) + cb(GetSharedInventory(name)) +end) + +AddEventHandler('esx:playerLoaded', function(source) + + local xPlayer = ESX.GetPlayerFromId(source) + local addonInventories = {} + + for i=1, #InventoriesIndex, 1 do + + local name = InventoriesIndex[i] + local inventory = GetInventory(name, xPlayer.identifier) + + if inventory == nil then + inventory = CreateAddonInventory(name, xPlayer.identifier, {}) + table.insert(Inventories[name], inventory) + end + + table.insert(addonInventories, inventory) + + end + + xPlayer.set('addonInventories', addonInventories) + +end) From a92a42ff19e83b19488f84e8f7ed0c02d11586cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 12:08:06 +0200 Subject: [PATCH 0050/3224] Add SQL file --- README.md | 3 ++- esx_addonaccount.sql | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 esx_addonaccount.sql diff --git a/README.md b/README.md index 14e7d938..01c6336d 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,8 @@ ESX AddonAccount ``` git clone https://github.com/FXServer-ESX/fxserver-esx_addonaccount esx_addonaccount ``` -3) Add this in your server.cfg : +3) Import esx_addonaccount.sql in your database +4) Add this in your server.cfg : ``` start esx_addonaccount diff --git a/esx_addonaccount.sql b/esx_addonaccount.sql new file mode 100644 index 00000000..fa0fb335 --- /dev/null +++ b/esx_addonaccount.sql @@ -0,0 +1,15 @@ +CREATE TABLE `addon_account` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `label` varchar(255) NOT NULL, + `shared` int(11) NOT NULL, + PRIMARY KEY (`id`) +); + +CREATE TABLE `addon_account_data` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `account_name` varchar(255) DEFAULT NULL, + `money` double NOT NULL, + `owner` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +); From e93392f283f0c9d5cf81c1fa5854462e9d191020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 12:08:42 +0200 Subject: [PATCH 0051/3224] Add SQL file --- README.md | 3 ++- esx_addoninventory.sql | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 esx_addoninventory.sql diff --git a/README.md b/README.md index 692405a5..66b8939d 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,8 @@ ESX AddonInventory ``` git clone https://github.com/FXServer-ESX/fxserver-esx_addoninventory esx_addoninventory ``` -3) Add this in your server.cfg : +3) Import esx_addoninventory.sql in your database +1) Add this in your server.cfg : ``` start esx_addoninventory diff --git a/esx_addoninventory.sql b/esx_addoninventory.sql new file mode 100644 index 00000000..a02c5700 --- /dev/null +++ b/esx_addoninventory.sql @@ -0,0 +1,16 @@ +CREATE TABLE `addon_inventory` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `label` varchar(255) NOT NULL, + `shared` int(11) NOT NULL, + PRIMARY KEY (`id`) +); + +CREATE TABLE `addon_inventory_items` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `inventory_name` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `count` int(11) NOT NULL, + `owner` varchar(60) DEFAULT NULL, + PRIMARY KEY (`id`) +); From 3a6c27904b641e81d36a6a625de3daf9833b6a36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 13:50:25 +0200 Subject: [PATCH 0052/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..ec02458a --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_datastore +FXServer ESX DataStore From 21a38402a278fd7bcaf05c751546c5bd7e1487d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 13:56:33 +0200 Subject: [PATCH 0053/3224] Update README.md --- README.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/README.md b/README.md index ec02458a..94257ea7 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,53 @@ # fxserver-esx_datastore FXServer ESX DataStore + +[INSTALLATION] + +1) CD in your resources folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-esx_datastore esx_datastore +``` +3) Import esx_datastore.sql in your database +1) Add this in your server.cfg : + +``` +start esx_datastore +``` + +[USAGE] + +There is two types of datastores : shared and not shared. + +- Shared datastores dont belong to a specific user. Example : property (weapons, dressing). +- Not shared datastores are created for every user in the server. They are created in db when player is loaded, Example : police armory + +You must create the datastore in the database (datastore) before using it : + +name = name of the datastore, label = label of the datastore, shared (0 or 1) = Is datastore shared + +``` +TriggerEvent('esx_datastore:getSharedDataStore', 'police', function(store) + + local weapons = store.get('weapons') + + if weapons == nil then + weapons = {} + end + + table.insert(weapons, {name = 'WEAPON_PUMPSHOTGUN', ammo = 50}) + + store.set('weapons', weapons) + +end) + +TriggerEvent('esx_datastore:getDataStore', 'property', 'steam:0123456789', function(store) + + local dressing = store.get('dressing') + + if dressing == nil then + dressing = {} + end + +end) +``` From 4dacb8eef133f85f6be3ac8e4db871def960391d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 13:58:37 +0200 Subject: [PATCH 0054/3224] Add files --- __resource.lua | 9 +++ esx_datastore.sql | 15 +++++ server/classes/datastore.lua | 44 ++++++++++++++ server/main.lua | 112 +++++++++++++++++++++++++++++++++++ 4 files changed, 180 insertions(+) create mode 100644 __resource.lua create mode 100644 esx_datastore.sql create mode 100644 server/classes/datastore.lua create mode 100644 server/main.lua diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..41f5b73e --- /dev/null +++ b/__resource.lua @@ -0,0 +1,9 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'ESX DataStore' + +server_scripts { + '@mysql-async/lib/MySQL.lua', + 'server/classes/datastore.lua', + 'server/main.lua' +} \ No newline at end of file diff --git a/esx_datastore.sql b/esx_datastore.sql new file mode 100644 index 00000000..d9bc4fd5 --- /dev/null +++ b/esx_datastore.sql @@ -0,0 +1,15 @@ +CREATE TABLE `datastore` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `label` varchar(255) NOT NULL, + `shared` int(11) NOT NULL, + PRIMARY KEY (`id`) +); + +CREATE TABLE `datastore_data` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `owner` varchar(255) NOT NULL, + `data` longtext, + PRIMARY KEY (`id`) +); \ No newline at end of file diff --git a/server/classes/datastore.lua b/server/classes/datastore.lua new file mode 100644 index 00000000..482c493c --- /dev/null +++ b/server/classes/datastore.lua @@ -0,0 +1,44 @@ +function CreateDataStore(name, owner, data) + + local self = {} + + self.name = name + self.owner = owner + self.data = data + + self.set = function(key, val) + data[key] = val + self.save() + end + + self.get = function(key) + return data[key] + end + + self.save = 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, + } + ) + 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, + } + ) + end + + end + + return self + +end + diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..f5f1e7d3 --- /dev/null +++ b/server/main.lua @@ -0,0 +1,112 @@ +ESX = nil +Items = {} +local DataStoresIndex = {} +local DataStores = {} +local SharedDatastores = {} + + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +AddEventHandler('onMySQLReady', function() + + local result = MySQL.Sync.fetchAll('SELECT * FROM datastore') + + 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 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 items = {} + + local storeName = result2[1].name + local storeData = (result2[1].data == nil and {} or json.decode(result2[1].data)) + + local dataStore = CreateDataStore(storeName, nil, storeData) + SharedDatastores[name] = dataStore + + end + + end + +end) + +function GetDataStore(name, owner) + for i=1, #DataStores[name], 1 do + if DataStores[name][i].owner == owner then + return DataStores[name][i] + end + end +end + +function GetSharedDataStore(name) + return SharedDataStores[name] +end + +AddEventHandler('esx_datastore:getDataStore', function(name, owner, cb) + cb(GetDataStore(name, owner)) +end) + +AddEventHandler('esx_datastore:getSharedDataStore', function(name, cb) + cb(GetSharedDataStore(name)) +end) + +AddEventHandler('esx:playerLoaded', function(source) + + local xPlayer = ESX.GetPlayerFromId(source) + local dataStores = {} + + for i=1, #DataStoresIndex, 1 do + + local name = DataStoresIndex[i] + local dataStore = GetDataStore(name, xPlayer.identifier) + + if dataStore == nil then + + MySQL.Async.execute( + 'INSERT INTO datastore_data (name, owner, data) VALUES (@name, @owner, @data)', + { + ['@name'] = name, + ['@owner'] = xPlayer.identifier, + ['@data'] = '{}' + } + ) + + dataStore = CreateDataStore(name, xPlayer.identifier, {}) + table.insert(DataStores[name], dataStore) + end + + table.insert(dataStores, dataStore) + + end + + xPlayer.set('dataStores', dataStores) + +end) From 6971fd933f6ed0b266e52fe46976ab0a1ce0716c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 14:05:18 +0200 Subject: [PATCH 0055/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..d0892968 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-cron +FXServer CRON From e716775d72ee4d23b31078116abb9987cec0f157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 14:06:36 +0200 Subject: [PATCH 0056/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 01c6336d..f7b2b790 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ESX AddonAccount [INSTALLATION] -1) CD in your resources folder +1) CD in your resources/[ESX] folder 2) Clone the repository ``` git clone https://github.com/FXServer-ESX/fxserver-esx_addonaccount esx_addonaccount From ffc6054d3368a55f94b33b9991ac55a6cb0dc32b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 14:06:56 +0200 Subject: [PATCH 0057/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 66b8939d..141fe098 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ESX AddonInventory [INSTALLATION] -1) CD in your resources folder +1) CD in your resources/[ESX] folder 2) Clone the repository ``` git clone https://github.com/FXServer-ESX/fxserver-esx_addoninventory esx_addoninventory From 14b8c27bb6a293af26b5cd5d60f939d1375fe430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 14:07:20 +0200 Subject: [PATCH 0058/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 94257ea7..9757fde1 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ FXServer ESX DataStore [INSTALLATION] -1) CD in your resources folder +1) CD in your resources/[ESX] folder 2) Clone the repository ``` git clone https://github.com/FXServer-ESX/fxserver-esx_datastore esx_datastore From d99586363228edea2384501886231d7eb50c5a66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 14:07:44 +0200 Subject: [PATCH 0059/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 244d4fd1..cc324858 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Original script by FiveDev => https://github.com/FiveDev-FR/esx_phone-by-FiveDev [INSTALLATION] -1) CD in your resources folder +1) CD in your resources/[ESX] folder 2) Clone the repository ``` git clone https://github.com/FXServer-ESX/fxserver-esx_phone esx_phone From 08b64603b581abac8c1a4bbedd29ad7c62c57115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 14:08:07 +0200 Subject: [PATCH 0060/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4fd1f966..9603612e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ FXServer ESX Skin [INSTALLATION] -1) CD in your resources folder +1) CD in your resources/[esx] folder 2) Clone the repository ``` git clone https://github.com/FXServer-ESX/fxserver-esx_skin esx_skin From 18d6452f79c4bc55487dc6e055fe631e99efea52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 14:09:00 +0200 Subject: [PATCH 0061/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f7b2b790..caae750b 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ESX AddonAccount [INSTALLATION] -1) CD in your resources/[ESX] folder +1) CD in your resources/[esx] folder 2) Clone the repository ``` git clone https://github.com/FXServer-ESX/fxserver-esx_addonaccount esx_addonaccount From 9df7e8e72f228ba9fd6c51bce990b5be97dab141 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 14:09:18 +0200 Subject: [PATCH 0062/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 141fe098..c47d91a8 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ESX AddonInventory [INSTALLATION] -1) CD in your resources/[ESX] folder +1) CD in your resources/[esx] folder 2) Clone the repository ``` git clone https://github.com/FXServer-ESX/fxserver-esx_addoninventory esx_addoninventory From 8a2715535aa9841c205e256b494697c80cd2451c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 14:09:34 +0200 Subject: [PATCH 0063/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9757fde1..46ad022a 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ FXServer ESX DataStore [INSTALLATION] -1) CD in your resources/[ESX] folder +1) CD in your resources/[esx] folder 2) Clone the repository ``` git clone https://github.com/FXServer-ESX/fxserver-esx_datastore esx_datastore From d216b4d05cf178816881c76439f7de99fd5af929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 14:09:48 +0200 Subject: [PATCH 0064/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cc324858..9a42a9c6 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Original script by FiveDev => https://github.com/FiveDev-FR/esx_phone-by-FiveDev [INSTALLATION] -1) CD in your resources/[ESX] folder +1) CD in your resources/[esx] folder 2) Clone the repository ``` git clone https://github.com/FXServer-ESX/fxserver-esx_phone esx_phone From d9a340918183bd63e8fd5c1652661822eedafc28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 14:12:55 +0200 Subject: [PATCH 0065/3224] Update README.md --- README.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/README.md b/README.md index d0892968..989f4efb 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,40 @@ # fxserver-cron FXServer CRON + +# fxserver-esx_addonaccount +ESX AddonAccount + +[INSTALLATION] + +1) CD in your resources folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-cron cron +``` +3) Add this in your server.cfg : + +``` +start cron +``` + +[USAGE] + +``` + +-- Execute task every 5:10 +function CronTask(d, h, m) + print('Task done') +end + +TriggerEvent('cron:runAt', 5, 10, CronTask) + +-- Execute task every monday at 18:30 +function CronTask(d, h, m) + if d == 1 then + print('Task done') + end +end + +TriggerEvent('cron:runAt', 18, 30, CronTask) + +``` From b167997977742fe2b3af655b9282d26588879937 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 14:13:51 +0200 Subject: [PATCH 0066/3224] Add files --- __resource.lua | 1 + server/main.lua | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 __resource.lua create mode 100644 server/main.lua diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..bb6f3d67 --- /dev/null +++ b/__resource.lua @@ -0,0 +1 @@ +server_script "server/main.lua" diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..e075105c --- /dev/null +++ b/server/main.lua @@ -0,0 +1,55 @@ +local Jobs = {} +local LastTime = nil + +function RunAt(h, m, cb) + + table.insert(Jobs, { + h = h, + m = m, + cb = cb + }) + +end + +function GetTime() + + local timestamp = os.time() + local d = os.date('*t', timestamp).wday + local h = tonumber(os.date('%H', timestamp)) + local m = tonumber(os.date('%M', timestamp)) + + return {d = d, h = h, m = m} + +end + +function OnTime(d, h, m) + + for i=1, #Jobs, 1 do + if Jobs[i].h == h and Jobs[i].m == m then + Jobs[i].cb(d, h, m) + end + end + +end + +function Tick() + + local time = GetTime() + + if time.h ~= LastTime.h or time.m ~= LastTime.m then + OnTime(time.d, time.h, time.m) + LastTime = time + end + + SetTimeout(1000, Tick) +end + +LastTime = GetTime() + +Tick() + +AddEventHandler('cron:runAt', function(h, m, cb) + RunAt(h, m, cb) +end) + +print('CRON STARTED [' .. os.date('%H:%M', os.time()) .. ']') From 9b7ccc617ed4e5b708a13688cf00e9930525d496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 14:15:15 +0200 Subject: [PATCH 0067/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..af8a195d --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-instance +FXServer Instance From 06d2a0bc5af9d2b4ca49b1d49f5a32cc3b5afaf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 14:16:23 +0200 Subject: [PATCH 0068/3224] Update README.md --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index af8a195d..1d59060d 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,15 @@ # fxserver-instance FXServer Instance + +[INSTALLATION] + +1) CD in your resources folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-instance instance +``` +3) Add this in your server.cfg : + +``` +start instance +``` From ded115ae9efbe3d961aa43894e464d910847438e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 14:17:02 +0200 Subject: [PATCH 0069/3224] Add files --- __resource.lua | 6 ++ client/main.lua | 212 ++++++++++++++++++++++++++++++++++++++++++++++++ server/main.lua | 128 +++++++++++++++++++++++++++++ 3 files changed, 346 insertions(+) create mode 100644 __resource.lua create mode 100644 client/main.lua create mode 100644 server/main.lua diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..4b1f559e --- /dev/null +++ b/__resource.lua @@ -0,0 +1,6 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'Instance' + +server_script 'server/main.lua' +client_script 'client/main.lua' diff --git a/client/main.lua b/client/main.lua new file mode 100644 index 00000000..0d446792 --- /dev/null +++ b/client/main.lua @@ -0,0 +1,212 @@ +local Keys = { + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, + ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, + ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, + ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, + ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 +} + +local GUI = {} +GUI.Time = 0 +local Instance = {} +local InstanceInvite = nil +local InstancedPlayers = {} + +function ShowNotification(msg) + SetNotificationTextEntry('STRING') + AddTextComponentString(msg) + DrawNotification(0,1) +end + +function GetInstance() + return Instance +end + +function CreateInstance() + TriggerServerEvent('instance:create') +end + +function EnterInstance(instance) + TriggerServerEvent('instance:enter', InstanceInvite.host) +end + +function LeaveInstance() + + if Instance.host ~= nil then + + if #Instance.players > 1 then + TriggerEvent('esx:showNotification', 'Vous avez quitté l\'instance') + end + + TriggerServerEvent('instance:leave', Instance.host) + end + +end + +function InviteToInstance(player, pos) + TriggerServerEvent('instance:invite', Instance.host, player, pos) +end + +AddEventHandler('instance:get', function(cb) + cb(GetInstance()) +end) + +AddEventHandler('instance:create', function() + CreateInstance() +end) + +AddEventHandler('instance:enter', function(instance) + EnterInstance(instance) +end) + +AddEventHandler('instance:leave', function() + LeaveInstance() +end) + +AddEventHandler('instance:invite', function(player, pos) + InviteToInstance(player, pos) +end) + +RegisterNetEvent('instance:onData') +AddEventHandler('instance:onData', function(instance) + Instance = instance +end) + +RegisterNetEvent('instance:onInstancedPlayersData') +AddEventHandler('instance:onInstancedPlayersData', function(instancedPlayers) + InstancedPlayers = instancedPlayers +end) + +RegisterNetEvent('instance:onInvite') +AddEventHandler('instance:onInvite', function(instance, pos) + + InstanceInvite = { + host = instance, + pos = pos + } + + Citizen.CreateThread(function() + + Citizen.Wait(10000) + + if InstanceInvite ~= nil then + ShowNotification('Invitation expirée') + InstanceInvite = nil + end + + end) + +end) + +-- Input invites +Citizen.CreateThread(function() + while true do + + Wait(0) + + if InstanceInvite ~= nil then + SetTextComponentFormat('STRING') + AddTextComponentString('Appuyez sur ~INPUT_CONTEXT~ pour entrer dans l\'instance') + DisplayHelpTextFromStringLabel(0, 0, 1, -1) + end + + end +end) + +-- Controls +Citizen.CreateThread(function() + while true do + + Wait(0) + + if InstanceInvite ~= nil and IsControlPressed(0, Keys['E']) and (GetGameTimer() - GUI.Time) > 150 then + + local playerPed = GetPlayerPed(-1) + + EnterInstance(InstanceInvite.host) + + SetEntityCoords(playerPed, InstanceInvite.pos.x, InstanceInvite.pos.y, InstanceInvite.pos.z) + + ShowNotification('Vous êtes entré dans l\'instance') + + InstanceInvite = nil + GUI.Time = GetGameTimer() + + end + + end + +end) + +-- Instance players +Citizen.CreateThread(function() + + while true do + + Wait(0) + + if Instance.host ~= nil then + + local playerPed = GetPlayerPed(-1) + + for i=0, 32, 1 do + + local found = false + + for j=1, #Instance.players, 1 do + + instancePlayer = GetPlayerFromServerId(Instance.players[j]) + + if i == instancePlayer then + found = true + end + + end + + if not found then + + local otherPlayerPed = GetPlayerPed(i) + + SetEntityLocallyInvisible(otherPlayerPed) + SetEntityNoCollisionEntity(playerPed, otherPlayerPed, true) + end + + end + + else + + local playerPed = GetPlayerPed(-1) + + for i=0, 32, 1 do + + local found = false + + for j=1, #InstancedPlayers, 1 do + + instancePlayer = GetPlayerFromServerId(InstancedPlayers[j]) + + if i == instancePlayer then + found = true + end + + end + + if found then + + local otherPlayerPed = GetPlayerPed(i) + + SetEntityLocallyInvisible(otherPlayerPed) + SetEntityNoCollisionEntity(playerPed, otherPlayerPed, true) + end + + end + + end + + end + +end) \ No newline at end of file diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..9b08a315 --- /dev/null +++ b/server/main.lua @@ -0,0 +1,128 @@ +local Instances = {} + +function GetInstancedPlayers() + + local players = {} + + for k,v in pairs(Instances) do + for i=1, #v.players, 1 do + table.insert(players, v.players[i]) + end + end + + return players + +end + +function CreateInstance(player) + + Instances[player] = { + host = player, + players = {player} + } + + TriggerClientEvent('instance:onData', player, Instances[player]) + TriggerClientEvent('instance:onInstancedPlayersData', -1, GetInstancedPlayers()) + +end + +function CloseInstance(instance) + + for i=1, #Instances[instance].players, 1 do + TriggerClientEvent('instance:onData', Instances[instance].players[i], {}) + end + + Instances[instance] = nil + + TriggerClientEvent('instance:onInstancedPlayersData', -1, GetInstancedPlayers()) + +end + +function AddPlayerToInstance(instance, player) + + local found = false + + for i=1, #Instances[instance].players, 1 do + if Instances[instance].players[i] == player then + found = true + break + end + end + + if not found then + table.insert(Instances[instance].players, player) + end + + for i=1, #Instances[instance].players, 1 do + TriggerClientEvent('instance:onData', Instances[instance].players[i], Instances[instance]) + end + + TriggerClientEvent('instance:onInstancedPlayersData', -1, GetInstancedPlayers()) + +end + +function RemovePlayerFromInstance(instance, player) + + if Instances[instance].host == player then + + CloseInstance(instance) + + else + + for i=1, #Instances[instance].players, 1 do + if Instances[instance].players[i] == player then + Instances[instance].players[i] = nil + end + end + + TriggerClientEvent('instance:onData', player, {}) + + for i=1, #Instances[instance].players, 1 do + TriggerClientEvent('instance:onData', Instances[instance].players[i], Instances[instance]) + end + + TriggerClientEvent('instance:onInstancedPlayersData', -1, GetInstancedPlayers()) + + end + +end + +function InvitePlayerToInstance(instance, player, pos) + TriggerClientEvent('instance:onInvite', player, instance, pos) +end + +RegisterServerEvent('instance:create') +AddEventHandler('instance:create', function() + CreateInstance(source) +end) + +RegisterServerEvent('instance:enter') +AddEventHandler('instance:enter', function(instance) + AddPlayerToInstance(instance, source) +end) + +RegisterServerEvent('instance:leave') +AddEventHandler('instance:leave', function(instance) + RemovePlayerFromInstance(instance, source) +end) + +RegisterServerEvent('instance:invite') +AddEventHandler('instance:invite', function(instance, player, pos) + InvitePlayerToInstance(instance, player, pos) +end) + +TriggerEvent('es:addCommand', 'instance_create', function(source, args, user) + CreateInstance(source) +end) + +TriggerEvent('es:addCommand', 'instance_invite', function(source, args, user) + InvitePlayerToInstance(tonumber(args[2]), tonumber(args[3]), { + x = tonumber(args[4]), + y = tonumber(args[5]), + z = tonumber(args[6]), + }) +end) + +TriggerEvent('es:addCommand', 'instance_enter', function(source, args, user) + AddPlayerToInstance(source, tonumber(args[2])) +end) From 4c1c74b58250e37eec3ba1585b3fe8ef037256f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 14:29:55 +0200 Subject: [PATCH 0070/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..529a923a --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_property +FXServer ESX Property From cedd80f21752a2eee4a7111ef4d33a549a029f47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 14:33:45 +0200 Subject: [PATCH 0071/3224] Update README.md --- README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/README.md b/README.md index 529a923a..591c5977 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,25 @@ # fxserver-esx_property FXServer ESX Property + +[REQUIREMENTS] + +- instance => https://github.com/FXServer-ESX/fxserver-instance +- cron => https://github.com/FXServer-ESX/fxserver-cron +- esx_addonaccount => https://github.com/FXServer-ESX/fxserver-esx_addonaccount +- esx_addoninventory => https://github.com/FXServer-ESX/fxserver-esx_addoninventory +- esx_datastore => https://github.com/FXServer-ESX/fxserver-esx_datastore + +[INSTALLATION] + +1) CD in your resources/[esx] folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-esx_property esx_property +``` +3) Import esx_property.sql in your database +4) Add this in your server.cfg : + +``` +start esx_property +``` + From 32575d64f83108e41e473e849fea754432a0a85a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 14:43:08 +0200 Subject: [PATCH 0072/3224] Add files --- __resource.lua | 14 + client/main.lua | 1024 ++++++++++++++++++++++++++++++++++++++++++++++ config.lua | 9 + esx_property.sql | 76 ++++ server/main.lua | 560 +++++++++++++++++++++++++ 5 files changed, 1683 insertions(+) create mode 100644 __resource.lua create mode 100644 client/main.lua create mode 100644 config.lua create mode 100644 esx_property.sql create mode 100644 server/main.lua diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..5660501e --- /dev/null +++ b/__resource.lua @@ -0,0 +1,14 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'ESX Property' + +server_scripts { + '@mysql-async/lib/MySQL.lua', + 'config.lua', + 'server/main.lua' +} + +client_scripts { + 'config.lua', + 'client/main.lua' +} diff --git a/client/main.lua b/client/main.lua new file mode 100644 index 00000000..1be6f35f --- /dev/null +++ b/client/main.lua @@ -0,0 +1,1024 @@ +local Keys = { + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, + ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, + ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, + ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, + ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 +} + +ESX = nil +local GUI = {} +GUI.Time = 0 +local OwnedProperties = {} +local Blips = {} +local CurrentProperty = nil +local LastProperty = nil +local LastPart = nil +local HasAlreadyEnteredMarker = false +local CurrentAction = nil +local CurrentActionMsg = '' +local CurrentActionData = {} + +function DrawSub(text, time) + ClearPrints() + SetTextEntry_2('STRING') + AddTextComponentString(text) + DrawSubtitleTimed(time, 1) +end + +function CreateBlips() + + for i=1, #Config.Properties, 1 do + + local property = Config.Properties[i] + + if property.entering ~= nil then + + Blips[property.name] = AddBlipForCoord(property.entering.x, property.entering.y, property.entering.z) + + SetBlipSprite (Blips[property.name], 369) + SetBlipDisplay(Blips[property.name], 4) + SetBlipScale (Blips[property.name], 1.0) + SetBlipAsShortRange(Blips[property.name], true) + + BeginTextCommandSetBlipName("STRING") + AddTextComponentString("Propriété libre") + EndTextCommandSetBlipName(Blips[property.name]) + + end + end + +end + +function GetProperties() + return Config.Properties +end + +function GetProperty(name) + + for i=1, #Config.Properties, 1 do + if Config.Properties[i].name == name then + return Config.Properties[i] + end + end + +end + +function GetGateway(property) + + for i=1, #Config.Properties, 1 do + + local property2 = Config.Properties[i] + + if property2.isGateway and property2.name == property.gateway then + return property2 + end + + end + +end + +function GetGatewayProperties(property) + + local properties = {} + + for i=1, #Config.Properties, 1 do + if Config.Properties[i].gateway == property.name then + table.insert(properties, Config.Properties[i]) + end + end + + return properties + +end + +function EnterProperty(name) + + local property = GetProperty(name) + local playerPed = GetPlayerPed(-1) + CurrentProperty = property + + for i=1, #Config.Properties, 1 do + if Config.Properties[i].name ~= name then + Config.Properties[i].disabled = true + end + end + + TriggerServerEvent('esx_property:saveLastProperty', name) + + TriggerEvent('instance:get', function(instance) + if instance.host == nil then + TriggerEvent('instance:create') + end + end) + + Citizen.CreateThread(function() + + DoScreenFadeOut(800) + + while not IsScreenFadedOut() do + Citizen.Wait(0) + end + + for i=1, #property.ipls, 1 do + + RequestIpl(property.ipls[i]) + + while not IsIplActive(property.ipls[i]) do + Citizen.Wait(0) + end + + end + + SetEntityCoords(playerPed, property.inside.x, property.inside.y, property.inside.z) + + DoScreenFadeIn(800) + + DrawSub(property.label, 5000) + end) + +end + +function ExitProperty(name) + + local property = GetProperty(name) + local playerPed = GetPlayerPed(-1) + local outside = nil + CurrentProperty = nil + + if property.isSingle then + outside = property.outside + else + outside = GetGateway(property).outside + end + + TriggerServerEvent('esx_property:deleteLastProperty') + + Citizen.CreateThread(function() + + DoScreenFadeOut(800) + + while not IsScreenFadedOut() do + Citizen.Wait(0) + end + + SetEntityCoords(playerPed, outside.x, outside.y, outside.z) + + TriggerEvent('instance:get', function(instance) + if instance.host ~= nil then + TriggerEvent('instance:leave') + end + end) + + for i=1, #property.ipls, 1 do + RemoveIpl(property.ipls[i]) + end + + for i=1, #Config.Properties, 1 do + Config.Properties[i].disabled = false + end + + DoScreenFadeIn(800) + + end) + +end + +function SetPropertyOwned(name, owned) + + local property = GetProperty(name) + local entering = nil + local enteringName = nil + + if property.isSingle then + entering = property.entering + enteringName = property.name + else + local gateway = GetGateway(property) + entering = gateway.entering + enteringName = gateway.name + end + + if owned then + + OwnedProperties[name] = true + + RemoveBlip(Blips[enteringName]) + + Blips[enteringName] = AddBlipForCoord(entering.x, entering.y, entering.z) + + SetBlipSprite(Blips[enteringName], 357) + SetBlipAsShortRange(Blips[enteringName], true) + + BeginTextCommandSetBlipName("STRING") + AddTextComponentString("Propriété") + EndTextCommandSetBlipName(Blips[enteringName]) + + else + + OwnedProperties[name] = nil + + local found = false + + for k,v in pairs(OwnedProperties) do + + local _property = GetProperty(k) + local _gateway = GetGateway(_property) + + if _gateway ~= nil then + + if _gateway.name == enteringName then + found = true + break + end + end + + end + + if not found then + + RemoveBlip(Blips[enteringName]) + + Blips[enteringName] = AddBlipForCoord(entering.x, entering.y, entering.z) + + SetBlipSprite(Blips[enteringName], 369) + SetBlipAsShortRange(Blips[enteringName], true) + + BeginTextCommandSetBlipName("STRING") + AddTextComponentString("Propriété libre") + EndTextCommandSetBlipName(Blips[enteringName]) + + end + + end + +end + +function PropertyIsOwned(property) + return OwnedProperties[property.name] == true +end + +function OpenPropertyMenu(property) + + local elements = {} + + if PropertyIsOwned(property) then + + table.insert(elements, {label = 'Entrer', value = 'enter'}) + + if not Config.EnablePlayerManagement then + table.insert(elements, {label = 'Rendre', value = 'leave'}) + end + + else + + if not Config.EnablePlayerManagement then + table.insert(elements, {label = 'Acheter', value = 'buy'}) + table.insert(elements, {label = 'Louer', value = 'rent'}) + end + + table.insert(elements, {label = 'Visiter', value = 'visit'}) + + end + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'property', + { + title = property.label, + align = 'top-left', + elements = elements, + }, + function(data2, menu) + + menu.close() + + if data2.current.value == 'enter' then + EnterProperty(property.name) + end + + if data2.current.value == 'leave' then + TriggerServerEvent('esx_property:removeOwnedProperty', property.name) + end + + if data2.current.value == 'buy' then + TriggerServerEvent('esx_property:buyProperty', property.name) + end + + if data2.current.value == 'rent' then + TriggerServerEvent('esx_property:rentProperty', property.name) + end + + if data2.current.value == 'visit' then + EnterProperty(property.name) + end + + end, + function(data, menu) + + menu.close() + + CurrentAction = 'property_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {property = property} + end + ) + +end + +function OpenGatewayMenu(property) + + if Config.EnablePlayerManagement then + OpenGatewayOwnedPropertiesMenu(gatewayProperties) + else + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'gateway', + { + title = property.name, + align = 'top-left', + elements = { + {label = 'Propriétés acquises', value = 'owned_properties'}, + {label = 'Propriétés disponibles', value = 'available_properties'}, + } + }, + function(data, menu) + + if data.current.value == 'owned_properties' then + OpenGatewayOwnedPropertiesMenu(property) + end + + if data.current.value == 'available_properties' then + OpenGatewayAvailablePropertiesMenu(property) + end + + end, + function(data, menu) + + menu.close() + + CurrentAction = 'gateway_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {property = property} + + end + ) + + end + +end + +function OpenGatewayOwnedPropertiesMenu(property) + + local gatewayProperties = GetGatewayProperties(property) + local elements = {} + + for i=1, #gatewayProperties, 1 do + + if PropertyIsOwned(gatewayProperties[i]) then + table.insert(elements, { + label = gatewayProperties[i].label, + value = gatewayProperties[i].name + }) + end + + end + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'gateway_owned_properties', + { + title = property.name .. ' - Propriétés Acquises', + align = 'top-left', + elements = elements, + }, + function(data, menu) + + menu.close() + + local elements = { + {label = 'Entrer', value = 'enter'} + } + + if not Config.EnablePlayerManagement then + table.insert(elements, {label = 'Rendre', value = 'leave'}) + end + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'gateway_owned_properties_actions', + { + title = data.current.label, + align = 'top-left', + elements = elements, + }, + function(data2, menu) + + menu.close() + + if data2.current.value == 'enter' then + EnterProperty(data.current.value) + end + + if data2.current.value == 'leave' then + TriggerServerEvent('esx_property:removeOwnedProperty', data.current.value) + end + + end, + function(data, menu) + menu.close() + end + ) + + end, + function(data, menu) + menu.close() + end + ) + +end + +function OpenGatewayAvailablePropertiesMenu(property) + + local gatewayProperties = GetGatewayProperties(property) + local elements = {} + + for i=1, #gatewayProperties, 1 do + + if not PropertyIsOwned(gatewayProperties[i]) then + table.insert(elements, { + label = gatewayProperties[i].label .. ' $' .. gatewayProperties[i].price, + value = gatewayProperties[i].name, + price = gatewayProperties[i].price + }) + end + + end + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'gateway_available_properties', + { + title = property.name.. ' - Propriétés Disponbibles', + align = 'top-left', + elements = elements, + }, + function(data, menu) + + menu.close() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'gateway_available_properties_actions', + { + title = property.name, + align = 'top-left', + elements = { + {label = 'Acheter', value = 'buy'}, + {label = 'Louer', value = 'rent'}, + {label = 'Visiter', value = 'visit'}, + }, + }, + function(data2, menu) + menu.close() + + if data2.current.value == 'buy' then + TriggerServerEvent('esx_property:buyProperty', data.current.value) + end + + if data2.current.value == 'rent' then + TriggerServerEvent('esx_property:rentProperty', data.current.value) + end + + if data2.current.value == 'visit' then + EnterProperty(data.current.value) + end + + end, + function(data, menu) + menu.close() + end + ) + + end, + function(data, menu) + menu.close() + end + ) + +end + +function OpenRoomMenu(property) + + local entering = nil + + if property.isSingle then + entering = property.entering + else + entering = GetGateway(property).entering + end + + ESX.UI.Menu.CloseAll() + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'room', + { + title = property.label, + align = 'top-left', + elements = { + {label = 'Inviter un joueur', value = 'invite_player'}, + {label = 'Dressing', value = 'player_dressing'}, + {label = 'Retirer objet', value = 'room_inventory'}, + {label = 'Déposer objet', value = 'player_inventory'}, + }, + }, + function(data, menu) + + if data.current.value == 'invite_player' then + + local playersInArea = ESX.Game.GetPlayersInArea(entering, 10.0) + local elements = {} + + for i=1, #playersInArea, 1 do + if playersInArea[i] ~= PlayerId() then + table.insert(elements, {label = GetPlayerName(playersInArea[i]), value = playersInArea[i]}) + end + end + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'room_invite', + { + title = property.label .. ' - Invite', + align = 'top-left', + elements = elements, + }, + function(data, menu) + TriggerEvent('instance:invite', GetPlayerServerId(data.current.value), property.inside) + end, + function(data, menu) + menu.close() + end + ) + + end + + if data.current.value == 'player_dressing' then + + ESX.TriggerServerCallback('esx_property:getPlayerDressing', function(dressing) + + local elements = {} + + for i=1, #dressing, 1 do + table.insert(elements, {label = dressing[i].label, value = dressing[i].skin}) + end + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'player_dressing', + { + title = property.label .. ' - Dressing', + align = 'top-left', + elements = elements, + }, + function(data, menu) + + TriggerEvent('skinchanger:getSkin', function(skin) + + TriggerEvent('skinchanger:loadClothes', skin, data.current.value) + + TriggerEvent('skinchanger:getSkin', function(skin) + TriggerServerEvent('esx_skin:save', skin) + end) + + end) + + end, + function(data, menu) + menu.close() + end + ) + + end) + + end + + if data.current.value == 'room_inventory' then + OpenRoomInventoryMenu(property) + end + + if data.current.value == 'player_inventory' then + OpenPlayerInventoryMenu(property) + end + + end, + function(data, menu) + + menu.close() + + CurrentAction = 'room_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {property = property} + end + ) + +end + +function OpenRoomInventoryMenu(property) + + ESX.TriggerServerCallback('esx_property:getPropertyInventory', function(inventory) + + local elements = {} + + table.insert(elements, {label = 'Argent sale $' .. inventory.blackMoney, type = 'item_account', value = 'black_money'}) + + for i=1, #inventory.items, 1 do + + local item = inventory.items[i] + + if item.count > 0 then + table.insert(elements, {label = item.label .. ' x' .. item.count, type = 'item_standard', value = item.name}) + end + + end + + for i=1, #inventory.weapons, 1 do + local weapon = inventory.weapons[i] + table.insert(elements, {label = ESX.GetWeaponLabel(weapon.name) .. ' [' .. weapon.ammo .. ']', type = 'item_weapon', value = weapon.name, ammo = weapon.ammo}) + end + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'room_inventory', + { + title = property.label .. ' - Inventaire', + align = 'top-left', + elements = elements, + }, + function(data, menu) + + if data.current.type == 'item_weapon' then + + menu.close() + + TriggerServerEvent('esx_property:getItem', data.current.type, data.current.value, data.current.ammo) + + ESX.SetTimeout(300, function() + OpenRoomInventoryMenu(property) + end) + + else + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'get_item_count', + { + title = 'Quantité ?', + }, + function(data2, menu) + + local quantity = tonumber(data2.value) + + if quantity == nil then + ESX.ShowNotification('Montant invalide') + else + + menu.close() + + TriggerServerEvent('esx_property:getItem', data.current.type, data.current.value, quantity) + + ESX.SetTimeout(300, function() + OpenRoomInventoryMenu(property) + end) + + end + + end, + function(data2,menu) + menu.close() + end + ) + + end + + end, + function(data, menu) + menu.close() + end + ) + + end) + +end + +function OpenPlayerInventoryMenu(property) + + ESX.TriggerServerCallback('esx_property:getPlayerInventory', function(inventory) + + local elements = {} + + table.insert(elements, {label = 'Argent sale $' .. inventory.blackMoney, type = 'item_account', value = 'black_money'}) + + for i=1, #inventory.items, 1 do + + local item = inventory.items[i] + + if item.count > 0 then + table.insert(elements, {label = item.label .. ' x' .. item.count, type = 'item_standard', value = item.name}) + end + + end + + local playerPed = GetPlayerPed(-1) + local weaponList = ESX.GetWeaponList() + + for i=1, #weaponList, 1 do + + local weaponHash = GetHashKey(weaponList[i].name) + + if HasPedGotWeapon(playerPed, weaponHash, false) and weaponList[i].name ~= 'WEAPON_UNARMED' then + local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) + table.insert(elements, {label = weaponList[i].label .. ' [' .. ammo .. ']', type = 'item_weapon', value = weaponList[i].name, ammo = ammo}) + end + + end + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'player_inventory', + { + title = property.label .. ' - Inventaire', + align = 'top-left', + elements = elements, + }, + function(data, menu) + + if data.current.type == 'item_weapon' then + + menu.close() + + TriggerServerEvent('esx_property:putItem', data.current.type, data.current.value, data.current.ammo) + + ESX.SetTimeout(300, function() + OpenPlayerInventoryMenu(property) + end) + + else + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'put_item_count', + { + title = 'Quantité ?', + }, + function(data2, menu) + + menu.close() + + TriggerServerEvent('esx_property:putItem', data.current.type, data.current.value, tonumber(data2.value)) + + ESX.SetTimeout(300, function() + OpenPlayerInventoryMenu(property) + end) + + end, + function(data2,menu) + menu.close() + end + ) + + end + + end, + function(data, menu) + menu.close() + end + ) + + end) + +end + +local FirstSpawn = true + +AddEventHandler('playerSpawned', function() + + if FirstSpawn then + + ESX.TriggerServerCallback('esx_property:getLastProperty', function(propertyName) + if propertyName ~= nil then + EnterProperty(propertyName) + end + end) + + FirstSpawn = false + end + +end) + +AddEventHandler('esx_property:getProperties', function(cb) + cb(GetProperties()) +end) + +AddEventHandler('esx_property:getProperty', function(name, cb) + cb(GetProperty(name)) +end) + +AddEventHandler('esx_property:getGateway', function(property, cb) + cb(GetGateway(property)) +end) + +RegisterNetEvent('esx_property:setPropertyOwned') +AddEventHandler('esx_property:setPropertyOwned', function(name, owned) + SetPropertyOwned(name, owned) +end) + +RegisterNetEvent('esx:playerLoaded') +AddEventHandler('esx:playerLoaded', function(xPlayer) + + ESX.TriggerServerCallback('esx_property:getOwnedProperties', function(ownedProperties) + for i=1, #ownedProperties, 1 do + SetPropertyOwned(ownedProperties[i], true) + end + end) + +end) + +AddEventHandler('esx_property:hasEnteredMarker', function(name, part) + + local property = GetProperty(name) + + if part == 'entering' then + + if property.isSingle then + CurrentAction = 'property_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {property = property} + else + CurrentAction = 'gateway_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {property = property} + end + + end + + if part == 'exit' then + ExitProperty(name) + end + + if part == 'roomMenu' then + CurrentAction = 'room_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {property = property} + end + +end) + +AddEventHandler('esx_property:hasExitedMarker', function(name, part) + ESX.UI.Menu.CloseAll() + CurrentAction = nil +end) + +-- Init +Citizen.CreateThread(function() + + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end + + ESX.TriggerServerCallback('esx_property:getProperties', function(properties) + Config.Properties = properties + CreateBlips() + end) + +end) + +-- Display markers +Citizen.CreateThread(function() + while true do + + Wait(0) + + local coords = GetEntityCoords(GetPlayerPed(-1)) + + for i=1, #Config.Properties, 1 do + + local property = Config.Properties[i] + + if(property.entering ~= nil and not property.disabled and GetDistanceBetweenCoords(coords, property.entering.x, property.entering.y, property.entering.z, true) < Config.DrawDistance) then + DrawMarker(Config.MarkerType, property.entering.x, property.entering.y, property.entering.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.MarkerSize.x, Config.MarkerSize.y, Config.MarkerSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) + end + + if(property.exit ~= nil and not property.disabled and GetDistanceBetweenCoords(coords, property.exit.x, property.exit.y, property.exit.z, true) < Config.DrawDistance) then + DrawMarker(Config.MarkerType, property.exit.x, property.exit.y, property.exit.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.MarkerSize.x, Config.MarkerSize.y, Config.MarkerSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) + end + + if(property.roomMenu ~= nil and PropertyIsOwned(property) and not property.disabled and GetDistanceBetweenCoords(coords, property.roomMenu.x, property.roomMenu.y, property.roomMenu.z, true) < Config.DrawDistance) then + DrawMarker(Config.MarkerType, property.roomMenu.x, property.roomMenu.y, property.roomMenu.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.MarkerSize.x, Config.MarkerSize.y, Config.MarkerSize.z, Config.RoomMenuMarkerColor.r, Config.RoomMenuMarkerColor.g, Config.RoomMenuMarkerColor.b, 100, false, true, 2, false, false, false, false) + end + + end + + end +end) + +-- Enter / Exit marker events +Citizen.CreateThread(function() + while true do + + Wait(0) + + local coords = GetEntityCoords(GetPlayerPed(-1)) + local isInMarker = false + local currentProperty = nil + local currentPart = nil + + for i=1, #Config.Properties, 1 do + + local property = Config.Properties[i] + + if(property.entering ~= nil and not property.disabled and GetDistanceBetweenCoords(coords, property.entering.x, property.entering.y, property.entering.z, true) < Config.MarkerSize.x) then + isInMarker = true + currentProperty = property.name + currentPart = 'entering' + end + + if(property.exit ~= nil and not property.disabled and GetDistanceBetweenCoords(coords, property.exit.x, property.exit.y, property.exit.z, true) < Config.MarkerSize.x) then + isInMarker = true + currentProperty = property.name + currentPart = 'exit' + end + + if(property.inside ~= nil and not property.disabled and GetDistanceBetweenCoords(coords, property.inside.x, property.inside.y, property.inside.z, true) < Config.MarkerSize.x) then + isInMarker = true + currentProperty = property.name + currentPart = 'inside' + end + + if(property.outside ~= nil and not property.disabled and GetDistanceBetweenCoords(coords, property.outside.x, property.outside.y, property.outside.z, true) < Config.MarkerSize.x) then + isInMarker = true + currentProperty = property.name + currentPart = 'outside' + end + + if(property.roomMenu ~= nil and PropertyIsOwned(property) and not property.disabled and GetDistanceBetweenCoords(coords, property.roomMenu.x, property.roomMenu.y, property.roomMenu.z, true) < Config.MarkerSize.x) then + isInMarker = true + currentProperty = property.name + currentPart = 'roomMenu' + end + + end + + if isInMarker and not HasAlreadyEnteredMarker or (isInMarker and (LastProperty ~= currentProperty or LastPart ~= currentPart) ) then + + HasAlreadyEnteredMarker = true + LastProperty = currentProperty + LastPart = currentPart + + TriggerEvent('esx_property:hasEnteredMarker', currentProperty, currentPart) + end + + if not isInMarker and HasAlreadyEnteredMarker then + + HasAlreadyEnteredMarker = false + + TriggerEvent('esx_property:hasExitedMarker', LastProperty, LastPart) + end + + end +end) + +-- Key controls +Citizen.CreateThread(function() + while true do + + Citizen.Wait(0) + + if CurrentAction ~= nil then + + SetTextComponentFormat('STRING') + AddTextComponentString(CurrentActionMsg) + DisplayHelpTextFromStringLabel(0, 0, 1, -1) + + if IsControlPressed(0, Keys['E']) and (GetGameTimer() - GUI.Time) > 300 then + + if CurrentAction == 'property_menu' then + OpenPropertyMenu(CurrentActionData.property) + end + + if CurrentAction == 'gateway_menu' then + + if Config.EnablePlayerManagement then + OpenGatewayOwnedPropertiesMenu(CurrentActionData.property) + else + OpenGatewayMenu(CurrentActionData.property) + end + + end + + if CurrentAction == 'room_menu' then + OpenRoomMenu(CurrentActionData.property) + end + + CurrentAction = nil + GUI.Time = GetGameTimer() + + end + + end + + end +end) \ No newline at end of file diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..25c717f8 --- /dev/null +++ b/config.lua @@ -0,0 +1,9 @@ +Config = {} +Config.DrawDistance = 100 +Config.MarkerSize = {x = 1.5, y = 1.5, z = 1.0} +Config.MarkerColor = {r = 102, g = 102, b = 204} +Config.RoomMenuMarkerColor = {r = 102, g = 204, b = 102} +Config.MarkerType = 1 +Config.Zones = {} +Config.Properties = {} +Config.EnablePlayerManagement = false -- If set to true you need esx_realestateagentjob diff --git a/esx_property.sql b/esx_property.sql new file mode 100644 index 00000000..82419c5b --- /dev/null +++ b/esx_property.sql @@ -0,0 +1,76 @@ +CREATE TABLE `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`) +); + +CREATE TABLE `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`) +); + +INSERT INTO `properties` VALUES + (1,'WhispymoundDrive','2677 Whispymound Drive','{\"y\":564.89,\"z\":182.959,\"x\":119.384}','{\"y\":558.667,\"z\":183.297,\"x\":116.392}','{\"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','Milla House','{\"y\":834.47540283203,\"z\":234.92024230957,\"x\":-86.692153930664}','{\"y\":422.84088134766,\"z\":144.90005493164,\"x\":372.70159912109}','{\"y\":420.07595825195,\"z\":145.90487670898,\"x\":373.16149902344}','{\"y\":835.64111328125,\"z\":234.7230072021,\"x\":-90.789779663086}','[]',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}','{\"y\":444.374,\"z\":145.037,\"x\":-212.15144348145}','[]',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}','{\"y\":448.07,\"z\":96.894,\"x\":-1290.834}','{\"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','{\"y\":696.314,\"z\":147.784,\"x\":-853.282}','{\"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\":211.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 Pèrcant 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 Pèrcant 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 Pèrcant 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) +; + diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..cff86548 --- /dev/null +++ b/server/main.lua @@ -0,0 +1,560 @@ +ESX = nil + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +function GetProperty(name) + + for i=1, #Config.Properties, 1 do + if Config.Properties[i].name == name then + return Config.Properties[i] + end + end + +end + +function SetPropertyOwned(name, price, rented, owner) + + MySQL.Async.execute( + 'INSERT INTO owned_properties (name, price, rented, owner) VALUES (@name, @price, @rented, @owner)', + { + ['@name'] = name, + ['@price'] = price, + ['@rented'] = (rented and 1 or 0), + ['@owner'] = owner + }, + function(rowsChanged) + + local xPlayers = ESX.GetPlayers() + + for k,v in pairs(xPlayers) do + if v.identifier == owner then + + TriggerClientEvent('esx_property:setPropertyOwned', v.source, name, true) + + if rented then + TriggerClientEvent('esx:showNotification', v.source, 'Vous avez loué une propriété pour $' .. price) + else + TriggerClientEvent('esx:showNotification', v.source, 'Vous avez acheté une propriété pour $' .. price) + end + + break + end + end + + end + ) + +end + +function RemoveOwnedProperty(name, owner) + + MySQL.Async.execute( + 'DELETE FROM owned_properties WHERE name = @name AND owner = @owner', + { + ['@name'] = name, + ['@owner'] = owner + }, + function(rowsChanged) + + local xPlayers = ESX.GetPlayers() + + for k,v in pairs(xPlayers) do + if v.identifier == owner then + TriggerClientEvent('esx_property:setPropertyOwned', v.source, name, false) + TriggerClientEvent('esx:showNotification', v.source, 'Vous avez rendu une propriété') + break + end + end + + end + ) + +end + +AddEventHandler('onMySQLReady', function () + + MySQL.Async.fetchAll('SELECT * FROM properties', {}, function(properties) + + for i=1, #properties, 1 do + + local entering = nil + local exit = nil + local inside = nil + local outside = nil + local isSingle = nil + local isRoom = nil + local isGateway = nil + local roomMenu = nil + + if properties[i].entering ~= nil then + entering = json.decode(properties[i].entering) + end + + if properties[i].exit ~= nil then + exit = json.decode(properties[i].exit) + end + + if properties[i].inside ~= nil then + inside = json.decode(properties[i].inside) + end + + if properties[i].outside ~= nil then + outside = json.decode(properties[i].outside) + end + + if properties[i].is_single == 0 then + isSingle = false + else + isSingle = true + end + + if properties[i].is_room == 0 then + isRoom = false + else + isRoom = true + end + + if properties[i].is_gateway == 0 then + isGateway = false + else + isGateway = true + end + + if properties[i].room_menu ~= nil then + roomMenu = json.decode(properties[i].room_menu) + end + + table.insert(Config.Properties, { + name = properties[i].name, + label = properties[i].label, + entering = entering, + exit = exit, + inside = inside, + outside = outside, + ipls = json.decode(properties[i].ipls), + gateway = properties[i].gateway, + isSingle = isSingle, + isRoom = isRoom, + isGateway = isGateway, + roomMenu = roomMenu, + price = properties[i].price + }) + + end + + end) + +end) + +AddEventHandler('esx_ownedproperty:getOwnedProperties', function(cb) + + MySQL.Async.fetchAll( + 'SELECT * FROM owned_properties', + {}, + function(result) + + local properties = {} + + for i=1, #result, 1 do + + table.insert(properties, { + id = result[i].id, + name = result[i].name, + price = result[i].price, + rented = (rented == 1 and true or false), + owner = result[i].owner, + }) + end + + cb(properties) + + end + ) + +end) + +AddEventHandler('esx_property:setPropertyOwned', function(name, price, rented, owner) + SetPropertyOwned(name, price, rented, owner) +end) + +AddEventHandler('esx_property:removeOwnedProperty', function(name, owner) + RemoveOwnedProperty(name, owner) +end) + +RegisterServerEvent('esx_property:rentProperty') +AddEventHandler('esx_property:rentProperty', function(propertyName) + + local xPlayer = ESX.GetPlayerFromId(source) + local property = GetProperty(propertyName) + + SetPropertyOwned(propertyName, property.price / 200, true, xPlayer.identifier) + +end) + +RegisterServerEvent('esx_property:buyProperty') +AddEventHandler('esx_property:buyProperty', function(propertyName) + + local xPlayer = ESX.GetPlayerFromId(source) + local property = GetProperty(propertyName) + + if property.price <= xPlayer.get('money') then + + xPlayer.removeMoney(property.price) + SetPropertyOwned(propertyName, property.price, false, xPlayer.identifier) + + else + TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez pas assez d\'argent') + end + +end) + +RegisterServerEvent('esx_property:removeOwnedProperty') +AddEventHandler('esx_property:removeOwnedProperty', function(propertyName) + + local xPlayer = ESX.GetPlayerFromId(source) + + RemoveOwnedProperty(propertyName, xPlayer.identifier) + +end) + +AddEventHandler('esx_property:removeOwnedPropertyIdentifier', function(propertyName, identifier) + RemoveOwnedProperty(propertyName, identifier) +end) + +RegisterServerEvent('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', + { + ['@last_property'] = property, + ['@identifier'] = xPlayer.identifier + } + ) + +end) + +RegisterServerEvent('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', + { + ['@identifier'] = xPlayer.identifier + } + ) +end) + +RegisterServerEvent('esx_property:getItem') +AddEventHandler('esx_property:getItem', function(type, item, count) + + local xPlayer = ESX.GetPlayerFromId(source) + + if type == 'item_standard' then + + TriggerEvent('esx_addoninventory:getInventory', 'property', xPlayer.identifier, function(inventory) + + local roomItemCount = inventory.getItem(item).count + + if roomItemCount >= count then + inventory.removeItem(item, count) + xPlayer.addInventoryItem(item, count) + else + TriggerClientEvent('esx:showNotification', source, 'Quantité invalide') + end + + end) + + end + + if type == 'item_account' then + + TriggerEvent('esx_addonaccount:getAccount', 'property_' .. item, xPlayer.identifier, function(account) + + local roomAccountMoney = account.money + + if roomAccountMoney >= count then + account.removeMoney(count) + xPlayer.addAccountMoney(item, count) + else + TriggerClientEvent('esx:showNotification', source, 'Montant invalide') + end + + end) + + end + + if type == 'item_weapon' then + + TriggerEvent('esx_datastore:getDataStore', 'property', xPlayer.identifier, function(store) + + local storeWeapons = store.get('weapons') + + if storeWeapons == nil then + storeWeapons = {} + end + + local weaponName = nil + local ammo = nil + + for i=1, #storeWeapons, 1 do + if storeWeapons[i].name == item then + + weaponName = storeWeapons[i].name + ammo = storeWeapons[i].ammo + + table.remove(storeWeapons, i) + + break + end + end + + store.set('weapons', storeWeapons) + + xPlayer.addWeapon(weaponName, ammo) + + end) + + end + +end) + +RegisterServerEvent('esx_property:putItem') +AddEventHandler('esx_property:putItem', function(type, item, count) + + local xPlayer = ESX.GetPlayerFromId(source) + + if type == 'item_standard' then + + local playerItemCount = xPlayer.getInventoryItem(item).count + + if playerItemCount >= count then + + xPlayer.removeInventoryItem(item, count) + + TriggerEvent('esx_addoninventory:getInventory', 'property', xPlayer.identifier, function(inventory) + inventory.addItem(item, count) + end) + + else + TriggerClientEvent('esx:showNotification', source, 'Quantité invalide') + end + + end + + if type == 'item_account' then + + local playerAccountMoney = xPlayer.getAccount(item).money + + if playerAccountMoney >= count then + + xPlayer.removeAccountMoney(item, count) + + TriggerEvent('esx_addonaccount:getAccount', 'property_' .. item, xPlayer.identifier, function(account) + account.addMoney(count) + end) + + else + TriggerClientEvent('esx:showNotification', source, 'Montant invalide') + end + + end + + if type == 'item_weapon' then + + TriggerEvent('esx_datastore:getDataStore', 'property', xPlayer.identifier, function(store) + + local storeWeapons = store.get('weapons') + + if storeWeapons == nil then + storeWeapons = {} + end + + table.insert(storeWeapons, { + name = item, + ammo = count + }) + + store.set('weapons', storeWeapons) + + xPlayer.removeWeapon(item) + + end) + + end + +end) + +ESX.RegisterServerCallback('esx_property:getProperties', function(source, cb) + cb(Config.Properties) +end) + +ESX.RegisterServerCallback('esx_property:getOwnedProperties', function(source, cb) + + local xPlayer = ESX.GetPlayerFromId(source) + + MySQL.Async.fetchAll( + 'SELECT * FROM owned_properties WHERE owner = @owner', + { + ['@owner'] = xPlayer.identifier + }, + function(ownedProperties) + + local properties = {} + + for i=1, #ownedProperties, 1 do + table.insert(properties, ownedProperties[i].name) + end + + cb(properties) + end + ) + +end) + +ESX.RegisterServerCallback('esx_property:getLastProperty', function(source, cb) + + local xPlayer = ESX.GetPlayerFromId(source) + + MySQL.Async.fetchAll( + 'SELECT * FROM users WHERE identifier = @identifier', + { + ['@identifier'] = xPlayer.identifier + }, + function(users) + cb(users[1].last_property) + end + ) + +end) + +ESX.RegisterServerCallback('esx_property:getPropertyInventory', function(source, cb) + + local xPlayer = ESX.GetPlayerFromId(source) + local blackMoney = 0 + local items = {} + local weapons = {} + + TriggerEvent('esx_addonaccount:getAccount', 'property_black_money', xPlayer.identifier, function(account) + blackMoney = account.money + end) + + TriggerEvent('esx_addoninventory:getInventory', 'property', xPlayer.identifier, function(inventory) + items = inventory.items + end) + + TriggerEvent('esx_datastore:getDataStore', 'property', xPlayer.identifier, function(store) + + local storeWeapons = store.get('weapons') + + if storeWeapons ~= nil then + weapons = storeWeapons + end + + end) + + cb({ + blackMoney = blackMoney, + items = items, + weapons = weapons + }) + +end) + +ESX.RegisterServerCallback('esx_property:getPlayerInventory', function(source, cb) + + local xPlayer = ESX.GetPlayerFromId(source) + local blackMoney = xPlayer.getAccount('black_money').money + local items = xPlayer.inventory + + cb({ + blackMoney = blackMoney, + items = items + }) + +end) + +ESX.RegisterServerCallback('esx_property:getPlayerDressing', function(source, cb) + + local xPlayer = ESX.GetPlayerFromId(source) + local dressing = {} + + TriggerEvent('esx_datastore:getDataStore', 'property', xPlayer.identifier, function(store) + + local storeDressing = store.get('dressing') + + if storeDressing ~= nil then + dressing = storeDressing + end + + end) + + cb(dressing) + +end) + +function PayRent(d, h, m) + + MySQL.Async.fetchAll( + 'SELECT * FROM owned_properties WHERE rented = 1', + {}, + function(result) + + local xPlayers = ESX.GetPlayers() + + for i=1, #result, 1 do + + local foundPlayer = false + local xPlayer = nil + + for k,v in pairs(xPlayers) do + if v.identifier == result[i].owner then + foundPlayer = true + xPlayer = v + end + end + + if foundPlayer then + + xPlayer.removeMoney(result[i].price) + TriggerClientEvent('esx:showNotification', xPlayer.source, 'Vous avez ~g~payé~s~ votre loyer : ~g~$' .. result[i].price) + + else + + MySQL.Async.fetchAll( + 'SELECT * FROM users WHERE identifier = @identifier', + { + ['@identifier'] = result[i].owner + }, + function(result2) + + local money = result2[1].money + money = money - result[i].price + + MySQL.Async.execute( + 'UPDATE users SET money = @money WHERE identifier = @identifier', + { + ['@money'] = money, + ['@identifier'] = result[i].owner + } + ) + end + ) + + end + + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_realestateagent', function(account) + account.addMoney(result[i].price) + end) + + end + + end + ) + +end + +TriggerEvent('cron:runAt', 22, 0, PayRent) \ No newline at end of file From 6ae4d3e88b6810c2d0462c71fd9451ec37be4a4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 14:45:13 +0200 Subject: [PATCH 0073/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 78358e1f..5f1baa98 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ # fxserver-esx_boilerplate -FXSServer ESX Boilerplate +FXServer ESX Boilerplate This a sample script for es_extended From c3b34569cdae585f09a2d11494c510b5d474f697 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 14:54:16 +0200 Subject: [PATCH 0074/3224] Update SQL --- esx_property.sql | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/esx_property.sql b/esx_property.sql index 82419c5b..877f3498 100644 --- a/esx_property.sql +++ b/esx_property.sql @@ -1,3 +1,17 @@ +USE `gta5_gamemode_essential` + +INSERT INTO `addon_account` (name, label, shared) VALUES + ('property_black_money','Argent Sale Propriété',0) +; + +INSERT INTO `addon_inventory` (name, label, shared) VALUES + ('property','Propriété',0) +; + +INSERT INTO `datastore` (name, label, shared) VALUES + (1,'property','Propriété',0) +; + CREATE TABLE `owned_properties` ( `id` int(11) NOT NULL AUTO_INCREMENT, From 7ddccc8c273868db42e22c258db64522481b1b1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 14:54:59 +0200 Subject: [PATCH 0075/3224] Update SQL --- esx_property.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_property.sql b/esx_property.sql index 877f3498..ae820607 100644 --- a/esx_property.sql +++ b/esx_property.sql @@ -9,7 +9,7 @@ INSERT INTO `addon_inventory` (name, label, shared) VALUES ; INSERT INTO `datastore` (name, label, shared) VALUES - (1,'property','Propriété',0) + ('property','Propriété',0) ; CREATE TABLE `owned_properties` ( From 3c3be8c6ce8bf02124cd855d06e1ce952c73f907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 15:42:54 +0200 Subject: [PATCH 0076/3224] Update SQL --- esx_property.sql | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/esx_property.sql b/esx_property.sql index ae820607..19c20782 100644 --- a/esx_property.sql +++ b/esx_property.sql @@ -1,4 +1,8 @@ -USE `gta5_gamemode_essential` +USE `gta5_gamemode_essential`; + +ALTER TABLE `users` + ADD COLUMN `last_property` VARCHAR(255) NULL +; INSERT INTO `addon_account` (name, label, shared) VALUES ('property_black_money','Argent Sale Propriété',0) From cc68bf49e5f6b00d806d9155fbe21bafbe9c6b34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 16:35:27 +0200 Subject: [PATCH 0077/3224] Update SQL --- esx_phone.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_phone.sql b/esx_phone.sql index 19d3b255..8896abdf 100644 --- a/esx_phone.sql +++ b/esx_phone.sql @@ -1,5 +1,5 @@ CREATE TABLE `user_contacts` ( - `id` int(11) NOT NULL, + `id` int(11) NOT NULL AUTO_INCREMENT, `identifier` varchar(255) NOT NULL, `name` varchar(255) NOT NULL, `number` int(11) NOT NULL From 5404250e9ecc0f54fd9e9f3d88bc3fa5a28b7479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 16:58:40 +0200 Subject: [PATCH 0078/3224] Update SQL --- esx_phone.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_phone.sql b/esx_phone.sql index 8896abdf..0517238e 100644 --- a/esx_phone.sql +++ b/esx_phone.sql @@ -8,4 +8,4 @@ CREATE TABLE `user_contacts` ( ALTER TABLE `user_contacts` ADD PRIMARY KEY (`id`); ALTER TABLE `users` -ADD COLUMN `phone_number` INT NULL AFTER `position`; +ADD COLUMN `phone_number` INT NULL; From b1029ad75f82516b39ea8a5be1372ced3347f7c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 17:03:36 +0200 Subject: [PATCH 0079/3224] xPlayer.set('contacts', contacts) --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 14d1afdb..5681607a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -157,7 +157,7 @@ AddEventHandler('esx_phone:reload', function(phoneNumber) end - xPlayer['contacts'] = contacts + xPlayer.set('contacts', contacts) TriggerClientEvent('esx_phone:loaded', source, phoneNumber, contacts) From fc1ef9dae2e25a3396eb4d42eba4ebffeae02650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 17:31:17 +0200 Subject: [PATCH 0080/3224] fix contact click bug --- html/scripts/app.js | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/html/scripts/app.js b/html/scripts/app.js index 160d91d1..4934837c 100644 --- a/html/scripts/app.js +++ b/html/scripts/app.js @@ -361,6 +361,35 @@ showAddContact(); }); + $('.phone-icon').click(function(event) { + + let id = $(this).attr('id'); + + switch(id) { + + case 'phone-icon-rep' : { + showRepertoire(); + break; + } + + case 'phone-icon-msg' : { + showMessages(); + break; + } + + default : { + + let number = $(this).data('number'); + let name = $(this).data('name'); + + showNewMessage(number, name); + + break; + } + } + + }); + window.onData = function(data){ if(data.scroll === true){ @@ -395,7 +424,7 @@ if(data.addSpecialContact === true){ addSpecialContact(data.name, data.number, data.base64Icon); - renderSpecialContacts() + renderSpecialContacts(); } if(data.move && isPhoneShowed){ From de2e4b3c1717a355799e466c0a8c60b862787e66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 00:29:02 +0200 Subject: [PATCH 0081/3224] Add skinchanger.net.dll source --- skinchanger_dll/.vs/skinchanger/v15/.suo | Bin 0 -> 43520 bytes skinchanger_dll/skinchanger.sln | 22 +++++++ .../skinchanger/Properties/AssemblyInfo.cs | 36 +++++++++++ .../obj/Debug/CoreCompileInputs.cache | 1 + ...gnTimeResolveAssemblyReferencesInput.cache | Bin 0 -> 6820 bytes ...le_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs | 0 ...le_5937a670-0e60-4077-877b-f7221da3dda1.cs | 0 ...le_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs | 0 skinchanger_dll/skinchanger/skinchanger.cs | 58 ++++++++++++++++++ .../skinchanger/skinchanger.csproj | 51 +++++++++++++++ .../skinchanger/skinchanger.csproj.user | 6 ++ 11 files changed, 174 insertions(+) create mode 100644 skinchanger_dll/.vs/skinchanger/v15/.suo create mode 100644 skinchanger_dll/skinchanger.sln create mode 100644 skinchanger_dll/skinchanger/Properties/AssemblyInfo.cs create mode 100644 skinchanger_dll/skinchanger/obj/Debug/CoreCompileInputs.cache create mode 100644 skinchanger_dll/skinchanger/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache create mode 100644 skinchanger_dll/skinchanger/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs create mode 100644 skinchanger_dll/skinchanger/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs create mode 100644 skinchanger_dll/skinchanger/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs create mode 100644 skinchanger_dll/skinchanger/skinchanger.cs create mode 100644 skinchanger_dll/skinchanger/skinchanger.csproj create mode 100644 skinchanger_dll/skinchanger/skinchanger.csproj.user diff --git a/skinchanger_dll/.vs/skinchanger/v15/.suo b/skinchanger_dll/.vs/skinchanger/v15/.suo new file mode 100644 index 0000000000000000000000000000000000000000..267f914db4066b1f4ab1b64aa492387b57a627d2 GIT binary patch literal 43520 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 UrB58~-p+O2@7{#juae>ZA3D9w2mk;8 literal 0 HcmV?d00001 diff --git a/skinchanger_dll/skinchanger.sln b/skinchanger_dll/skinchanger.sln new file mode 100644 index 00000000..edb4061d --- /dev/null +++ b/skinchanger_dll/skinchanger.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26403.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "skinchanger", "skinchanger\skinchanger.csproj", "{0B36C12C-4C7A-4C24-B204-161034340C8A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0B36C12C-4C7A-4C24-B204-161034340C8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0B36C12C-4C7A-4C24-B204-161034340C8A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0B36C12C-4C7A-4C24-B204-161034340C8A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0B36C12C-4C7A-4C24-B204-161034340C8A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/skinchanger_dll/skinchanger/Properties/AssemblyInfo.cs b/skinchanger_dll/skinchanger/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..29ce8cfb --- /dev/null +++ b/skinchanger_dll/skinchanger/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Les informations générales relatives à un assembly dépendent de +// l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations +// associées à un assembly. +[assembly: AssemblyTitle("es_skinchanger")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("es_skinchanger")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly +// aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de +// COM, affectez la valeur true à l'attribut ComVisible sur ce type. +[assembly: ComVisible(false)] + +// Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM +[assembly: Guid("0b36c12c-4c7a-4c24-b204-161034340c8a")] + +// Les informations de version pour un assembly se composent des quatre valeurs suivantes : +// +// Version principale +// Version secondaire +// Numéro de build +// Révision +// +// Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut +// en utilisant '*', comme indiqué ci-dessous : +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/skinchanger_dll/skinchanger/obj/Debug/CoreCompileInputs.cache b/skinchanger_dll/skinchanger/obj/Debug/CoreCompileInputs.cache new file mode 100644 index 00000000..172d913a --- /dev/null +++ b/skinchanger_dll/skinchanger/obj/Debug/CoreCompileInputs.cache @@ -0,0 +1 @@ +001bf808026bfc7fe5228d45535464d5f6b2318e diff --git a/skinchanger_dll/skinchanger/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache b/skinchanger_dll/skinchanger/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache new file mode 100644 index 0000000000000000000000000000000000000000..f2235478b7f3ddf9a107c8e98745a9015695e83e GIT binary patch literal 6820 zcmeHMZByGu5Vms-}KxVK;gXMwiHU# zwE3Q^fVpKII9!-{;d#PeFRW!V??Eaq{FRw`Ge>{fOg?aRAYsLaKuhLkGn+xx<@T>| zR1tgNuT*ohwfWjYZDz)q&#_rHOez;Yqv@A`yAJ7F_cch-{2*Dg3DPVvx$ZXut?uIB zyUcaP0XVBlfmd~p)($oJG%GcRz4OAa@p_TFFkv&_;SST#=}EO}x)!)@Q8Et>gxu>i zRah0<#?Q1Bh3lZb52&)jWF2%gtQ=Go=nVu>k9ge|5(-db=!$h;X`J8b>{`H2zuc(> z*XnwQUk-8qLVfqBjEiWbw+3!XVS`da zuHx*uMw>9?+C#u81-|AUw1=EWYI#Xb1`0}00|`Dt6{YYH^b;c8l%3kpEyjQ`Xc&pa zAj*McGHKukWn$pZ;qsBv;9+>;`r4WT&U^_zNN$_2(ODm7wzt2~1$V@I<_56IxcvA$ z>RQ&4`}J(bQ?`&Uub%F)x&OVz78cmNJ^x~6X?6~Bi%UD%FU{kMPPG?)*ooJzR~#;x z?1yMCqA1!;y#T-BF%|O$>IY~qVyGXWalJTqlEi~kgD6H*LsT3lfpj2|x`qP3Mo6Sc zjFPyHV$`^SGGUCNC>)pC%xSrdMEZb9up+W+nHy`Bh(l)g=gfKYdA37A+jMj7@Wi-@ zNQZ@Gs{s4p3Z%du_}VJ+eRyNlPD{)u4`2AqlM@ zQ7VBF?ta9IPg#*^GrIw)ugI8NDDIt|Z-@N1=53_0$2j%KL?&fIi;UX@(C+m$mWMpW zU1JvvU6+WWx-l)HVaHM>$R|%+xAoFEfa49md!Q)1ANPN<#P)umW8(&Vc}G*e5<9n zg``eGsBa3ve~Se?T6QyEZZO#l;inOvAv}`LI^IDt;guxw_;B&X6DwMXOgkiyws!?j ze2el|hTi@1+_@ngONZSRbX zq`t>fuk)mdUQ$-nc!c6zPhJ>lVy~f&AFwb~#EfQ=m~2RIyC;(*YI~tJO}vYqH1S=+ zGJZrcd7QsA#d=~q#@4l1-WkRdgt~qFiu;=KbCkGS$9;HWJjME{0ZT>lq?4cX8D literal 0 HcmV?d00001 diff --git a/skinchanger_dll/skinchanger/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs b/skinchanger_dll/skinchanger/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs new file mode 100644 index 00000000..e69de29b diff --git a/skinchanger_dll/skinchanger/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs b/skinchanger_dll/skinchanger/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs new file mode 100644 index 00000000..e69de29b diff --git a/skinchanger_dll/skinchanger/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs b/skinchanger_dll/skinchanger/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs new file mode 100644 index 00000000..e69de29b diff --git a/skinchanger_dll/skinchanger/skinchanger.cs b/skinchanger_dll/skinchanger/skinchanger.cs new file mode 100644 index 00000000..1276ba24 --- /dev/null +++ b/skinchanger_dll/skinchanger/skinchanger.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using CitizenFX.Core; +using CitizenFX.Core.UI; +using CitizenFX.Core.Native; + +namespace skinchanger +{ + public class Main : BaseScript + { + public Main() + { + Tick += OnTick; + + EventHandlers["skinchanger:LoadDefaultModel"] += new Action(async (dynamic LoadMale) => + { + await LoadDefaultModel((bool) LoadMale); + + TriggerEvent("skinchanger:modelLoaded"); + }); + + } + + public async Task LoadDefaultModel(bool LoadMale) + { + + PedHash CharacterModel; + + if (LoadMale) + CharacterModel = PedHash.FreemodeMale01; + else + CharacterModel = PedHash.FreemodeFemale01; + + Model characterModel = new Model(CharacterModel); + + characterModel.Request(500); + + if (characterModel.IsInCdImage && characterModel.IsValid) + { + while (!characterModel.IsLoaded) + await BaseScript.Delay(0); + + Function.Call(Hash.SET_PLAYER_MODEL, Game.Player, characterModel.Hash); + Function.Call(Hash.SET_PED_DEFAULT_COMPONENT_VARIATION, Game.Player.Character.Handle); + } + + characterModel.MarkAsNoLongerNeeded(); + } + + public async Task OnTick() + { + + } + } +} diff --git a/skinchanger_dll/skinchanger/skinchanger.csproj b/skinchanger_dll/skinchanger/skinchanger.csproj new file mode 100644 index 00000000..d2c9d418 --- /dev/null +++ b/skinchanger_dll/skinchanger/skinchanger.csproj @@ -0,0 +1,51 @@ + + + + + Debug + AnyCPU + {0B36C12C-4C7A-4C24-B204-161034340C8A} + Library + Properties + skinchanger + skinchanger.net + v4.5.2 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + copy /y "$(TargetPath)" "C:\Users\NGD\Desktop\cfx-server\resources\skinchanger" + + \ No newline at end of file diff --git a/skinchanger_dll/skinchanger/skinchanger.csproj.user b/skinchanger_dll/skinchanger/skinchanger.csproj.user new file mode 100644 index 00000000..e997092b --- /dev/null +++ b/skinchanger_dll/skinchanger/skinchanger.csproj.user @@ -0,0 +1,6 @@ + + + + C:\Users\NGD\AppData\Local\FiveM\FiveM.app\citizen\clr2\lib\mono\4.5\ + + \ No newline at end of file From eb2e22349f5a33ea8377a324eebeb400196b2ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 00:29:41 +0200 Subject: [PATCH 0082/3224] Delete obj folder --- .../obj/Debug/CoreCompileInputs.cache | 1 - ...esignTimeResolveAssemblyReferencesInput.cache | Bin 6820 -> 0 bytes ...dFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs | 0 ...dFile_5937a670-0e60-4077-877b-f7221da3dda1.cs | 0 ...dFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs | 0 5 files changed, 1 deletion(-) delete mode 100644 skinchanger_dll/skinchanger/obj/Debug/CoreCompileInputs.cache delete mode 100644 skinchanger_dll/skinchanger/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache delete mode 100644 skinchanger_dll/skinchanger/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs delete mode 100644 skinchanger_dll/skinchanger/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs delete mode 100644 skinchanger_dll/skinchanger/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs diff --git a/skinchanger_dll/skinchanger/obj/Debug/CoreCompileInputs.cache b/skinchanger_dll/skinchanger/obj/Debug/CoreCompileInputs.cache deleted file mode 100644 index 172d913a..00000000 --- a/skinchanger_dll/skinchanger/obj/Debug/CoreCompileInputs.cache +++ /dev/null @@ -1 +0,0 @@ -001bf808026bfc7fe5228d45535464d5f6b2318e diff --git a/skinchanger_dll/skinchanger/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache b/skinchanger_dll/skinchanger/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache deleted file mode 100644 index f2235478b7f3ddf9a107c8e98745a9015695e83e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6820 zcmeHMZByGu5Vms-}KxVK;gXMwiHU# zwE3Q^fVpKII9!-{;d#PeFRW!V??Eaq{FRw`Ge>{fOg?aRAYsLaKuhLkGn+xx<@T>| zR1tgNuT*ohwfWjYZDz)q&#_rHOez;Yqv@A`yAJ7F_cch-{2*Dg3DPVvx$ZXut?uIB zyUcaP0XVBlfmd~p)($oJG%GcRz4OAa@p_TFFkv&_;SST#=}EO}x)!)@Q8Et>gxu>i zRah0<#?Q1Bh3lZb52&)jWF2%gtQ=Go=nVu>k9ge|5(-db=!$h;X`J8b>{`H2zuc(> z*XnwQUk-8qLVfqBjEiWbw+3!XVS`da zuHx*uMw>9?+C#u81-|AUw1=EWYI#Xb1`0}00|`Dt6{YYH^b;c8l%3kpEyjQ`Xc&pa zAj*McGHKukWn$pZ;qsBv;9+>;`r4WT&U^_zNN$_2(ODm7wzt2~1$V@I<_56IxcvA$ z>RQ&4`}J(bQ?`&Uub%F)x&OVz78cmNJ^x~6X?6~Bi%UD%FU{kMPPG?)*ooJzR~#;x z?1yMCqA1!;y#T-BF%|O$>IY~qVyGXWalJTqlEi~kgD6H*LsT3lfpj2|x`qP3Mo6Sc zjFPyHV$`^SGGUCNC>)pC%xSrdMEZb9up+W+nHy`Bh(l)g=gfKYdA37A+jMj7@Wi-@ zNQZ@Gs{s4p3Z%du_}VJ+eRyNlPD{)u4`2AqlM@ zQ7VBF?ta9IPg#*^GrIw)ugI8NDDIt|Z-@N1=53_0$2j%KL?&fIi;UX@(C+m$mWMpW zU1JvvU6+WWx-l)HVaHM>$R|%+xAoFEfa49md!Q)1ANPN<#P)umW8(&Vc}G*e5<9n zg``eGsBa3ve~Se?T6QyEZZO#l;inOvAv}`LI^IDt;guxw_;B&X6DwMXOgkiyws!?j ze2el|hTi@1+_@ngONZSRbX zq`t>fuk)mdUQ$-nc!c6zPhJ>lVy~f&AFwb~#EfQ=m~2RIyC;(*YI~tJO}vYqH1S=+ zGJZrcd7QsA#d=~q#@4l1-WkRdgt~qFiu;=KbCkGS$9;HWJjME{0ZT>lq?4cX8D diff --git a/skinchanger_dll/skinchanger/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs b/skinchanger_dll/skinchanger/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs deleted file mode 100644 index e69de29b..00000000 diff --git a/skinchanger_dll/skinchanger/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs b/skinchanger_dll/skinchanger/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs deleted file mode 100644 index e69de29b..00000000 diff --git a/skinchanger_dll/skinchanger/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs b/skinchanger_dll/skinchanger/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs deleted file mode 100644 index e69de29b..00000000 From d96661fa924aa305d406164af74322704c0c79b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 10:40:47 +0200 Subject: [PATCH 0083/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..8c228b9f --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_billing +FXServer ESX Billing From 9dfece1d66de537ad09874cda31a328bee83759f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 10:44:25 +0200 Subject: [PATCH 0084/3224] Update README.md --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index 8c228b9f..f6a555e3 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,31 @@ # fxserver-esx_billing FXServer ESX Billing + +[INSTALLATION] + +1) CD in your resources/[esx] folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-esx_billing esx_billing +``` +3) Import esx_billing.sql in your database +4) Add this in your server.cfg : + +``` +start esx_billing +``` + +[USAGE] + +Press [F7] To show billing menu + +``` +local amount = 100 +local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + +if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification('Aucun joueur à proximité') +else + TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_taxi', 'Taxi', amount) +end +``` From 5534bedaa4daee267df3607d4bf9133a606ba98b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 10:49:26 +0200 Subject: [PATCH 0085/3224] Add files --- __resource.lua | 12 +++ client/main.lua | 72 ++++++++++++++++++ esx_billing.sql | 12 +++ server/main.lua | 189 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 285 insertions(+) create mode 100644 __resource.lua create mode 100644 client/main.lua create mode 100644 esx_billing.sql create mode 100644 server/main.lua diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..479a2226 --- /dev/null +++ b/__resource.lua @@ -0,0 +1,12 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'ESX Billing' + +server_scripts { + '@mysql-async/lib/MySQL.lua', + 'server/main.lua' +} + +client_scripts { + 'client/main.lua' +} diff --git a/client/main.lua b/client/main.lua new file mode 100644 index 00000000..99e7a4e4 --- /dev/null +++ b/client/main.lua @@ -0,0 +1,72 @@ +local Keys = { + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, + ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, + ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, + ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, + ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 +} + +ESX = nil +local GUI = {} +GUI.Time = 0 + +Citizen.CreateThread(function() + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end +end) + +function ShowBillsMenu() + + ESX.TriggerServerCallback('esx_billing:getBills', function(bills) + + ESX.UI.Menu.CloseAll() + + local elements = {} + + for i=1, #bills, 1 do + table.insert(elements, {label = bills[i].label .. ' $' .. bills[i].amount, value = bills[i].id}) + end + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'billing', + { + title = 'Factures', + elements = elements + }, + function(data, menu) + + local billId = data.current.value + + ESX.TriggerServerCallback('esx_billing:payBill', function() + ShowBillsMenu() + end, billId) + + end, + function(data, menu) + menu.close() + end + ) + + end) + +end + +-- Key controls +Citizen.CreateThread(function() + while true do + + Wait(0) + + if IsControlPressed(0, Keys["F7"]) and not ESX.UI.Menu.IsOpen('default', GetCurrentResourceName(), 'billing') and (GetGameTimer() - GUI.Time) > 150 then + ShowBillsMenu() + GUI.Time = GetGameTimer() + end + + end +end) \ No newline at end of file diff --git a/esx_billing.sql b/esx_billing.sql new file mode 100644 index 00000000..78a71771 --- /dev/null +++ b/esx_billing.sql @@ -0,0 +1,12 @@ +CREATE TABLE `billing` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `identifier` varchar(255) NOT NULL, + `sender` varchar(255) NOT NULL, + `target_type` varchar(50) NOT NULL, + `target` varchar(255) NOT NULL, + `label` varchar(255) NOT NULL, + `amount` int(11) NOT NULL, + + PRIMARY KEY (`id`) +); \ No newline at end of file diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..75c5a788 --- /dev/null +++ b/server/main.lua @@ -0,0 +1,189 @@ +ESX = nil + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +RegisterServerEvent('esx_billing:sendBill') +AddEventHandler('esx_billing:sendBill', function(playerId, sharedAccountName, label, amount) + + local xPlayer = ESX.GetPlayerFromId(source) + local xPlayers = ESX.GetPlayers() + + TriggerEvent('esx_addonaccount:getSharedAccount', sharedAccountName, function(account) + + if account == nil then + + for k, v in pairs(xPlayers) do + if v.source == playerId then + + MySQL.Async.execute( + 'INSERT INTO billing (identifier, sender, target_type, target, label, amount) VALUES (@identifier, @sender, @target_type, @target, @label, @amount)', + { + ['@identifier'] = v.identifier, + ['@sender'] = xPlayer.identifier, + ['@target_type'] = 'player', + ['@target'] = xPlayer.identifier, + ['@label'] = label, + ['@amount'] = amount + }, + function(rowsChanged) + TriggerClientEvent('esx:showNotification', v.source, 'Vous avez ~r~reçu~s~ une facture') + end + ) + + break + end + end + + else + + for k, v in pairs(xPlayers) do + + if v.source == playerId then + + MySQL.Async.execute( + 'INSERT INTO billing (identifier, sender, target_type, target, label, amount) VALUES (@identifier, @sender, @target_type, @target, @label, @amount)', + { + ['@identifier'] = v.identifier, + ['@sender'] = xPlayer.identifier, + ['@target_type'] = 'society', + ['@target'] = sharedAccountName, + ['@label'] = label, + ['@amount'] = amount + }, + function(rowsChanged) + TriggerClientEvent('esx:showNotification', v.source, 'Vous avez ~r~reçu~s~ une facture') + end + ) + + break + end + end + + end + + end) + +end) + +ESX.RegisterServerCallback('esx_billing:getBills', function(source, cb) + + local xPlayer = ESX.GetPlayerFromId(source) + + MySQL.Async.fetchAll( + 'SELECT * FROM billing WHERE identifier = @identifier', + { + ['@identifier'] = xPlayer.identifier + }, + function(result) + + local bills = {} + + for i=1, #result, 1 do + table.insert(bills, { + id = result[i].id, + identifier = result[i].identifier, + sender = result[i].sender, + targetType = result[i].target_type, + target = result[i].target, + label = result[i].label, + amount = result[i].amount + }) + end + + cb(bills) + + end + ) + +end) + + +ESX.RegisterServerCallback('esx_billing:payBill', function(source, cb, id) + + local xPlayer = ESX.GetPlayerFromId(source) + + MySQL.Async.fetchAll( + 'SELECT * FROM billing WHERE id = @id', + { + ['@id'] = id + }, + function(result) + + local sender = result[1].sender + local targetType = result[1].target_type + local target = result[1].target + local amount = result[1].amount + local xPlayers = ESX.GetPlayers() + local foundPlayer = nil + + for k,v in pairs(xPlayers) do + if v.identifier == sender then + foundPlayer = v + break + end + end + + if targetType == 'player' then + + if foundPlayer ~= nil then + + if xPlayer.get('money') >= amount then + + MySQL.Async.execute( + 'DELETE from billing WHERE id = @id', + { + ['@id'] = id + }, + function(rowsChanged) + + xPlayer.removeMoney(amount) + foundPlayer.addMoney(amount) + + TriggerClientEvent('esx:showNotification', xPlayer.source, 'Vous avez ~g~payé~s~ une facture de ~r~$' .. amount) + TriggerClientEvent('esx:showNotification', foundPlayer.source, 'Vous avez ~g~reçu~s~ un paiement de ~g~$' .. amount) + + cb() + + end + ) + + else + TriggerClientEvent('esx:showNotification', _source, 'Le joueur n\'est pas connecté') + cb() + end + + end + + else + + TriggerEvent('esx_addonaccount:getSharedAccount', target, function(account) + + MySQL.Async.execute( + 'DELETE from billing WHERE id = @id', + { + ['@id'] = id + }, + function(rowsChanged) + + xPlayer.removeMoney(amount) + account.addMoney(amount) + + TriggerClientEvent('esx:showNotification', xPlayer.source, 'Vous avez ~g~payé~s~ une facture de ~r~$' .. amount) + + if foundPlayer ~= nil then + TriggerClientEvent('esx:showNotification', foundPlayer.source, 'Vous avez ~g~reçu~s~ un paiement de ~g~$' .. amount) + end + + cb() + + end + ) + + end) + + end + + end + ) + +end) \ No newline at end of file From a4de590c4b959194398b042636d49df4f0df5009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 10:56:51 +0200 Subject: [PATCH 0086/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..f0d91ed6 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_clotheshop +FXServer ESX ClotheShop From 679a484c9efc34395d48bc8106c395da66603dc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 10:57:57 +0200 Subject: [PATCH 0087/3224] Update README.md --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index f0d91ed6..3dbf7b6d 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,15 @@ # fxserver-esx_clotheshop FXServer ESX ClotheShop + +[INSTALLATION] + +1) CD in your resources/[esx] folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-clotheshop clotheshop +``` +3) Add this in your server.cfg : + +``` +start clotheshop +``` From 6c44faa1ab049d5a60901806a4d804e6adeb2fec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 10:58:39 +0200 Subject: [PATCH 0088/3224] Add files --- __resource.lua | 14 +++ client/main.lua | 262 ++++++++++++++++++++++++++++++++++++++++++++++++ config.lua | 38 +++++++ server/main.lua | 63 ++++++++++++ 4 files changed, 377 insertions(+) create mode 100644 __resource.lua create mode 100644 client/main.lua create mode 100644 config.lua create mode 100644 server/main.lua diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..f3483a9e --- /dev/null +++ b/__resource.lua @@ -0,0 +1,14 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'ESX ClotheShop' + +server_scripts { + '@mysql-async/lib/MySQL.lua', + 'config.lua', + 'server/main.lua' +} + +client_scripts { + 'config.lua', + 'client/main.lua' +} diff --git a/client/main.lua b/client/main.lua new file mode 100644 index 00000000..f72efb78 --- /dev/null +++ b/client/main.lua @@ -0,0 +1,262 @@ +local Keys = { + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, + ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, + ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, + ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, + ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 +} + +ESX = nil +local GUI = {} +GUI.Time = 0 +local HasAlreadyEnteredMarker = false +local LastZone = nil +local CurrentAction = nil +local CurrentActionMsg = '' +local CurrentActionData = {} + +Citizen.CreateThread(function() + + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end + +end) + +function OpenShopMenu() + + TriggerEvent('esx_skin:openRestrictedMenu', function(data, menu) + + menu.close() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'shop_confirm', + { + title = 'Valider cet achat ?', + align = 'top-left', + elements = { + {label = 'Oui', value = 'yes'}, + {label = 'Non', value = 'no'}, + } + }, + function(data, menu) + + menu.close() + + if data.current.value == 'yes' then + + ESX.TriggerServerCallback('esx_clotheshop:checkMoney', function(hasEnoughMoney) + + if hasEnoughMoney then + + TriggerEvent('skinchanger:getSkin', function(skin) + TriggerServerEvent('esx_skin:save', skin) + end) + + TriggerServerEvent('esx_clotheshop:pay') + + ESX.TriggerServerCallback('esx_clotheshop:checkPropertyDataStore', function(foundStore) + + if foundStore then + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'outfit_name', + { + title = 'Nom de la tenue ?', + }, + function(data, menu) + + menu.close() + + TriggerEvent('skinchanger:getSkin', function(skin) + TriggerServerEvent('esx_clotheshop:saveOutfit', data.value, skin) + end) + + end, + function(data2,menu) + menu.close() + end + ) + + end + + end) + + else + + TriggerEvent('esx_skin:getLastSkin', function(skin) + TriggerEvent('skinchanger:loadSkin', skin) + end) + + ESX.ShowNotification('Vous n\'avez pas assez d\'argent') + + end + + end) + + end + + if data.current.value == 'no' then + + TriggerEvent('esx_skin:getLastSkin', function(skin) + TriggerEvent('skinchanger:loadSkin', skin) + end) + + end + + CurrentAction = 'shop_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {} + + end, + function(data, menu) + + menu.close() + + CurrentAction = 'shop_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {} + + end + ) + + end, function(data, menu) + + menu.close() + + CurrentAction = 'shop_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {} + + end, { + 'tshirt_1', + 'tshirt_2', + 'torso_1', + 'torso_2', + 'decals_1', + 'decals_2', + 'arms', + 'pants_1', + 'pants_2', + 'shoes_1', + 'shoes_2', + 'chain_1', + 'chain_2', + 'helmet_1', + 'helmet_2', + 'glasses_1', + 'glasses_2', + }) + +end + +AddEventHandler('esx_clotheshop:hasEnteredMarker', function(zone) + CurrentAction = 'shop_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {} +end) + +AddEventHandler('esx_clotheshop:hasExitedMarker', function(zone) + CurrentAction = nil +end) + +-- Create Blips +Citizen.CreateThread(function() + + for i=1, #Config.Shops, 1 do + + local blip = AddBlipForCoord(Config.Shops[i].x, Config.Shops[i].y, Config.Shops[i].z) + + SetBlipSprite (blip, 73) + SetBlipDisplay(blip, 4) + SetBlipScale (blip, 1.0) + SetBlipColour (blip, 47) + SetBlipAsShortRange(blip, true) + + BeginTextCommandSetBlipName("STRING") + AddTextComponentString("Vêtements") + EndTextCommandSetBlipName(blip) + end + +end) + +-- Display markers +Citizen.CreateThread(function() + while true do + + Wait(0) + + local coords = GetEntityCoords(GetPlayerPed(-1)) + + for k,v in pairs(Config.Zones) do + if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) + end + end + + end +end) + +-- Enter / Exit marker events +Citizen.CreateThread(function() + while true do + + Wait(0) + + local coords = GetEntityCoords(GetPlayerPed(-1)) + local isInMarker = false + local currentZone = nil + + for k,v in pairs(Config.Zones) do + if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then + isInMarker = true + currentZone = k + end + end + + if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then + HasAlreadyEnteredMarker = true + LastZone = currentZone + TriggerEvent('esx_clotheshop:hasEnteredMarker', currentZone) + end + + if not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent('esx_clotheshop:hasExitedMarker', LastZone) + end + + end +end) + +-- Key controls +Citizen.CreateThread(function() + while true do + + Citizen.Wait(0) + + if CurrentAction ~= nil then + + SetTextComponentFormat('STRING') + AddTextComponentString(CurrentActionMsg) + DisplayHelpTextFromStringLabel(0, 0, 1, -1) + + if IsControlPressed(0, Keys['E']) and (GetGameTimer() - GUI.Time) > 300 then + + if CurrentAction == 'shop_menu' then + OpenShopMenu() + end + + CurrentAction = nil + GUI.Time = GetGameTimer() + + end + + end + + end +end) \ No newline at end of file diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..71e4491f --- /dev/null +++ b/config.lua @@ -0,0 +1,38 @@ +Config = {} + +Config.Price = 250 + +Config.DrawDistance = 100.0 +Config.MarkerSize = {x = 1.5, y = 1.5, z = 1.0} +Config.MarkerColor = {r = 102, g = 102, b = 204} +Config.MarkerType = 1 + +Config.Zones = {} + +Config.Shops = { + {x=72.254, y=-1399.102, z=28.376}, + {x=-703.776, y=-152.258, z=36.415}, + {x=-167.863, y=-298.969, z=38.733}, + {x=428.694, y=-800.106, z=28.491}, + {x=-829.413, y=-1073.710, z=10.328}, + {x=-1447.797, y=-242.461, z=48.820}, + {x=11.632, y=6514.224, z=30.877}, + {x=123.646, y=-219.440, z=53.557}, + {x=1696.291, y=4829.312, z=41.063}, + {x=618.093, y=2759.629, z=41.088}, + {x=1190.550, y=2713.441, z=37.222}, + {x=-1193.429, y=-772.262, z=16.324}, + {x=-3172.496, y=1048.133, z=19.863}, + {x=-1108.441, y=2708.923, z=18.107}, +} + +for i=1, #Config.Shops, 1 do + + Config.Zones['Shop_' .. i] = { + Pos = Config.Shops[i], + Size = Config.MarkerSize, + Color = Config.MarkerColor, + Type = Config.MarkerType + } + +end \ No newline at end of file diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..1c338a51 --- /dev/null +++ b/server/main.lua @@ -0,0 +1,63 @@ +ESX = nil + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +RegisterServerEvent('esx_clotheshop:pay') +AddEventHandler('esx_clotheshop:pay', function() + + local xPlayer = ESX.GetPlayerFromId(source) + + xPlayer.removeMoney(Config.Price) + + TriggerClientEvent('esx:showNotification', source, 'Vous avez payé $' .. Config.Price) + +end) + +RegisterServerEvent('esx_clotheshop:saveOutfit') +AddEventHandler('esx_clotheshop:saveOutfit', function(label, skin) + + local xPlayer = ESX.GetPlayerFromId(source) + + TriggerEvent('esx_datastore:getDataStore', 'property', xPlayer.identifier, function(store) + + local dressing = store.get('dressing') + + if dressing == nil then + dressing = {} + end + + table.insert(dressing, { + label = label, + skin = skin + }) + + store.set('dressing', dressing) + + end) + +end) + +ESX.RegisterServerCallback('esx_clotheshop:checkMoney', function(source, cb) + + local xPlayer = ESX.GetPlayerFromId(source) + + if xPlayer.get('money') >= Config.Price then + cb(true) + else + cb(false) + end + +end) + +ESX.RegisterServerCallback('esx_clotheshop:checkPropertyDataStore', function(source, cb) + + local xPlayer = ESX.GetPlayerFromId(source) + local foundStore = false + + TriggerEvent('esx_datastore:getDataStore', 'property', xPlayer.identifier, function(store) + foundStore = true + end) + + cb(foundStore) + +end) \ No newline at end of file From 53756690f9733bfce18ea07922de69dda02bbbe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 11:00:05 +0200 Subject: [PATCH 0089/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..77fea26d --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_society +FXServer ESX Society From 6d7bfa56d332e9eadf58dcd360311d387d5f9861 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 11:05:57 +0200 Subject: [PATCH 0090/3224] Update README.md --- README.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/README.md b/README.md index 77fea26d..bf16a874 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,35 @@ # fxserver-esx_society FXServer ESX Society + +[REQUIREMENTS] + +- cron => https://github.com/FXServer-ESX/fxserver-cron +- esx_addonaccount => https://github.com/FXServer-ESX/fxserver-esx_addonaccount + +[INSTALLATION] + +1) CD in your resources/[esx] folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-esx_society esx_society +``` +3) Import esx_society.sql in your database +4) Add this in your server.cfg : + +``` +start esx_society +``` +[EXPLANATION] + +ESX Society works with addon accounts named 'society_xxx' like 'society_taxi' or 'society_realestateagnt'. +If you job grade is 'boss', you will see the society_xxx money of your job showed in the HUD. + +[USAGE] +``` +local society = 'taxi' +local amount = 100 + +TriggerServerEvent('esx_society:withdrawMoney', society, amount) +TriggerServerEvent('esx_society:depositMoney', society, amount) +TriggerServerEvent('esx_society:washMoney', society, amount) +``` From 4992d2e458162335bed30408af97e2c09f726906 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 11:06:58 +0200 Subject: [PATCH 0091/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bf16a874..46c786af 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ start esx_society ``` [EXPLANATION] -ESX Society works with addon accounts named 'society_xxx' like 'society_taxi' or 'society_realestateagnt'. +ESX Society works with addon accounts named 'society_xxx' like 'society_taxi' or 'society_realestateagent'. If you job grade is 'boss', you will see the society_xxx money of your job showed in the HUD. [USAGE] From 7abb2575872074b5151c852603c1f64c560a9f1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 11:08:21 +0200 Subject: [PATCH 0092/3224] Add files --- __resource.lua | 12 +++++ client/main.lua | 79 ++++++++++++++++++++++++++++++ esx_society.sql | 9 ++++ server/main.lua | 124 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 224 insertions(+) create mode 100644 __resource.lua create mode 100644 client/main.lua create mode 100644 esx_society.sql create mode 100644 server/main.lua diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..9287ed13 --- /dev/null +++ b/__resource.lua @@ -0,0 +1,12 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'ESX Society' + +server_scripts { + '@mysql-async/lib/MySQL.lua', + 'server/main.lua' +} + +client_scripts { + 'client/main.lua' +} diff --git a/client/main.lua b/client/main.lua new file mode 100644 index 00000000..8ac18b75 --- /dev/null +++ b/client/main.lua @@ -0,0 +1,79 @@ +ESX = nil +local PlayerData = {} +local base64MoneyIcon = 'data:image/png;base64,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/GMzLdsAADhgaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjUtYzAxNCA3OS4xNTE0ODEsIDIwMTMvMDMvMTMtMTI6MDk6MTUgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgICAgICAgICB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8eG1wOkNyZWF0b3JUb29sPkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cyk8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMTUtMTAtMDlUMjA6MTM6MTYrMDI6MDA8L3htcDpDcmVhdGVEYXRlPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxNS0xMC0wOVQyMDoxNDo0NyswMjowMDwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6TWV0YWRhdGFEYXRlPjIwMTUtMTAtMDlUMjA6MTQ6NDcrMDI6MDA8L3htcDpNZXRhZGF0YURhdGU+CiAgICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2UvcG5nPC9kYzpmb3JtYXQ+CiAgICAgICAgIDxwaG90b3Nob3A6Q29sb3JNb2RlPjM8L3Bob3Rvc2hvcDpDb2xvck1vZGU+CiAgICAgICAgIDxwaG90b3Nob3A6SUNDUHJvZmlsZT5zUkdCIElFQzYxOTY2LTIuMTwvcGhvdG9zaG9wOklDQ1Byb2ZpbGU+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6NmZkNGVlNjgtOWU3Mi1jYTQxLTg5NjMtMWRjMmI2M2EzYWExPC94bXBNTTpJbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD54bXAuZGlkOjZmZDRlZTY4LTllNzItY2E0MS04OTYzLTFkYzJiNjNhM2FhMTwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD54bXAuZGlkOjZmZDRlZTY4LTllNzItY2E0MS04OTYzLTFkYzJiNjNhM2FhMTwveG1wTU06T3JpZ2luYWxEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06SGlzdG9yeT4KICAgICAgICAgICAgPHJkZjpTZXE+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmNyZWF0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDo2ZmQ0ZWU2OC05ZTcyLWNhNDEtODk2My0xZGMyYjYzYTNhYTE8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTUtMTAtMDlUMjA6MTM6MTYrMDI6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpTZXE+CiAgICAgICAgIDwveG1wTU06SGlzdG9yeT4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WFJlc29sdXRpb24+OTYwMDAwLzEwMDAwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj45NjAwMDAvMTAwMDA8L3RpZmY6WVJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U+MTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+MTgwPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjE4MDwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAg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' + +Citizen.CreateThread(function() + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end +end) + +function EnableSocietyMoneyHUDElement() + + local societyMoneyHUDElementTpl = '
 {{money}}
' + + ESX.UI.HUD.RegisterElement('society_money', 3, 0, societyMoneyHUDElementTpl, { + money = 0 + }) + +end + +function DisableSocietyMoneyHUDElement() + ESX.UI.HUD.RemoveElement('society_money') +end + +function UpdateSocietyMoneyHUDElement(money) + + ESX.UI.HUD.UpdateElement('society_money', { + money = money + }) + +end + +RegisterNetEvent('esx:playerLoaded') +AddEventHandler('esx:playerLoaded', function(xPlayer) + + PlayerData = xPlayer + + DisableSocietyMoneyHUDElement() + + if PlayerData.job.grade_name == 'boss' then + + EnableSocietyMoneyHUDElement() + + ESX.TriggerServerCallback('esx_society:getAccountMoney', function(money) + UpdateSocietyMoneyHUDElement(money) + end, 'society_' .. PlayerData.job.name) + + end + +end) + +RegisterNetEvent('esx:setJob') +AddEventHandler('esx:setJob', function(job) + + PlayerData.job = job + + DisableSocietyMoneyHUDElement() + + if PlayerData.job.grade_name == 'boss' then + + EnableSocietyMoneyHUDElement() + + ESX.TriggerServerCallback('esx_society:getAccountMoney', function(money) + UpdateSocietyMoneyHUDElement(money) + end, 'society_' .. PlayerData.job.name) + + end + +end) + +RegisterNetEvent('esx_addonAccount:setMoney') +AddEventHandler('esx_addonAccount:setMoney', function(name, money) + + if PlayerData.job ~= nil and PlayerData.job.grade_name == 'boss' and 'society_' .. PlayerData.job.name == name then + UpdateSocietyMoneyHUDElement(money) + end + +end) \ No newline at end of file diff --git a/esx_society.sql b/esx_society.sql new file mode 100644 index 00000000..cb097561 --- /dev/null +++ b/esx_society.sql @@ -0,0 +1,9 @@ +CREATE TABLE `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`) +); \ No newline at end of file diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..0e30cf2e --- /dev/null +++ b/server/main.lua @@ -0,0 +1,124 @@ +ESX = nil + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +RegisterServerEvent('esx_society:withdrawMoney') +AddEventHandler('esx_society:withdrawMoney', function(society, amount) + + local xPlayer = ESX.GetPlayerFromId(source) + + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_' .. society, function(account) + + if amount > 0 and account.money >= amount then + + account.removeMoney(amount) + xPlayer.addMoney(amount) + + TriggerClientEvent('esx:showNotification', xPlayer.source, 'Vous avez retiré ~g~$' .. amount) + + else + TriggerClientEvent('esx:showNotification', xPlayer.source, 'Montant invalide') + end + + end) + +end) + +RegisterServerEvent('esx_society:depositMoney') +AddEventHandler('esx_society:depositMoney', function(society, amount) + + local xPlayer = ESX.GetPlayerFromId(source) + + if amount > 0 and xPlayer.get('money') >= amount then + + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_' .. society, function(account) + xPlayer.removeMoney(amount) + account.addMoney(amount) + end) + + TriggerClientEvent('esx:showNotification', xPlayer.source, 'Vous avez déposé ~r~$' .. amount) + + else + TriggerClientEvent('esx:showNotification', xPlayer.source, 'Montant invalide') + end + +end) + +RegisterServerEvent('esx_society:washMoney') +AddEventHandler('esx_society:washMoney', function(society, amount) + + local xPlayer = ESX.GetPlayerFromId(source) + local account = xPlayer.getAccount('black_money') + + if 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) + TriggerClientEvent('esx:showNotification', xPlayer.source, 'Vous avez ~g~$' .. amount .. '~s~ en attente de ~r~blanchiement~s~ (24h)') + end + ) + + else + TriggerClientEvent('esx:showNotification', xPlayer.source, 'Montant invalide') + end + +end) + +ESX.RegisterServerCallback('esx_society:getAccountMoney', function(source, cb, account) + TriggerEvent('esx_addonaccount:getSharedAccount', account, function(account) + cb(account.money) + end) +end) + +function WashMoneyCRON(d, h, m) + + MySQL.Async.fetchAll( + 'SELECT * FROM society_moneywash', + {}, + function(result) + + local xPlayers = ESX.GetPlayers() + + for i=1, #result, 1 do + + local foundPlayer = false + local xPlayer = nil + + for k,v in pairs(xPlayers) do + if v.identifier == result[i].identifier then + foundPlayer = true + xPlayer = v + end + end + + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_' .. result[i].society, function(account) + account.addMoney(result[i].amount) + end) + + if foundPlayer then + TriggerClientEvent('esx:showNotification', xPlayer.source, 'Vous avez ~r~blanchi~s~ votre argent : ~g~$' .. result[i].amount) + end + + MySQL.Async.execute( + 'DELETE FROM society_moneywash WHERE id = @id', + { + ['@id'] = result[i].id + } + ) + + end + + end + ) + +end + +TriggerEvent('cron:runAt', 3, 0, WashMoneyCRON) \ No newline at end of file From 84f1934cfc86c008053d56c81352885c1fe2b764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 11:15:47 +0200 Subject: [PATCH 0093/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..4532a5d4 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_realestateagentjob +FXServer ESX RealestateAgent Job From 66e42f29daf7b70879939899dca5881231b5ef44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 11:17:56 +0200 Subject: [PATCH 0094/3224] Update README.md --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index 4532a5d4..bfc4e863 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,20 @@ # fxserver-esx_realestateagentjob FXServer ESX RealestateAgent Job + +[REQUIREMENTS] + +- esx_property => https://github.com/FXServer-ESX/fxserver-esx_property + +[INSTALLATION] + +1) CD in your resources/[esx] folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-esx_realestateagentjob esx_realestateagentjob +``` +3) Add this in your server.cfg : + +``` +start esx_realestateagentjob +``` +4) Set Config.EnablePlayerManagement to true in esx_property/config.lua From 521fdd5a2a1cd4e133ae466158811a29b6dc8f23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 11:21:56 +0200 Subject: [PATCH 0095/3224] Update README.md --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bfc4e863..72f35038 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,11 @@ FXServer ESX RealestateAgent Job [REQUIREMENTS] +- esx_addonaccount => https://github.com/FXServer-ESX/fxserver-esx_society - esx_property => https://github.com/FXServer-ESX/fxserver-esx_property +- (optionnal) esx_society => https://github.com/FXServer-ESX/fxserver-esx_society + +If you add esx_society you will see the realestateagent account money in the HUD if your grade is 'boss' [INSTALLATION] @@ -12,9 +16,10 @@ FXServer ESX RealestateAgent Job ``` git clone https://github.com/FXServer-ESX/fxserver-esx_realestateagentjob esx_realestateagentjob ``` -3) Add this in your server.cfg : +3) Import esx_realestateagentjob.sql in your database +4) Add this in your server.cfg : ``` start esx_realestateagentjob ``` -4) Set Config.EnablePlayerManagement to true in esx_property/config.lua +5) Set Config.EnablePlayerManagement to true in esx_property/config.lua From 43698d9d13dfc513161d5b7562ddd165b683f577 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 11:33:48 +0200 Subject: [PATCH 0096/3224] Add files --- __resource.lua | 14 ++ client/main.lua | 499 +++++++++++++++++++++++++++++++++++++ config.lua | 36 +++ esx_realestateagentjob.sql | 16 ++ server/main.lua | 95 +++++++ 5 files changed, 660 insertions(+) create mode 100644 __resource.lua create mode 100644 client/main.lua create mode 100644 config.lua create mode 100644 esx_realestateagentjob.sql create mode 100644 server/main.lua diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..9d54ef92 --- /dev/null +++ b/__resource.lua @@ -0,0 +1,14 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'ESX RealestateAgentJob' + +server_scripts { + '@mysql-async/lib/MySQL.lua', + 'config.lua', + 'server/main.lua' +} + +client_scripts { + 'config.lua', + 'client/main.lua' +} \ No newline at end of file diff --git a/client/main.lua b/client/main.lua new file mode 100644 index 00000000..c5c126b1 --- /dev/null +++ b/client/main.lua @@ -0,0 +1,499 @@ +local Keys = { + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, + ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, + ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, + ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, + ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 +} + +ESX = nil +local GUI = {} +GUI.Time = 0 +local PlayerData = {} +local HasAlreadyEnteredMarker = false +local LastZone = nil +local CurrentAction = nil +local CurrentActionMsg = '' +local CurrentActionData = {} + +Citizen.CreateThread(function() + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end +end) + +function OpenRealestateAgentMenu() + + local elements = { + {label = 'Propriétés', value = 'properties'}, + {label = 'Clients', value = 'customers'}, + } + + if PlayerData.job ~= nil and PlayerData.job.name == 'realestateagent' and PlayerData.job.grade_name == 'boss' then + table.insert(elements, {label = 'Retirer argent société', value = 'withdraw_society_money'}) + table.insert(elements, {label = 'Déposer argent ', value = 'deposit_money'}) + table.insert(elements, {label = 'Blanchir argent', value = 'wash_money'}) + end + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'realestateagent', + { + title = 'Agent Immobilier', + elements = elements + }, + function(data, menu) + + if data.current.value == 'properties' then + OpenPropertyMenu() + end + + if data.current.value == 'customers' then + OpenCustomersMenu() + end + + if data.current.value == 'withdraw_society_money' then + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'withdraw_society_money_amount', + { + title = 'Montant du retrait' + }, + function(data, menu) + + local amount = tonumber(data.value) + + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + menu.close() + TriggerServerEvent('esx_society:withdrawMoney', 'realestateagent', amount) + end + + end, + function(data, menu) + menu.close() + end + ) + + end + + if data.current.value == 'deposit_money' then + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'deposit_money_amount', + { + title = 'Montant du dépôt' + }, + function(data, menu) + + local amount = tonumber(data.value) + + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + menu.close() + TriggerServerEvent('esx_society:depositMoney', 'realestateagent', amount) + end + + end, + function(data, menu) + menu.close() + end + ) + + end + + if data.current.value == 'wash_money' then + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'wash_money_amount', + { + title = 'Montant à blanchir' + }, + function(data, menu) + + local amount = tonumber(data.value) + + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + menu.close() + TriggerServerEvent('esx_society:washMoney', 'realestateagent', amount) + end + + end, + function(data, menu) + menu.close() + end + ) + + end + + end, + function(data, menu) + + menu.close() + + CurrentAction = 'realestateagent_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {} + + end + ) + +end + +function OpenPropertyMenu() + + TriggerEvent('esx_property:getProperties', function(properties) + + local elements = { + head = {'Propriété', 'Actions'}, + rows = {} + } + + for i=1, #properties, 1 do + table.insert(elements.rows, { + data = properties[i], + cols = { + properties[i].label, + '{{Assigner [vente]|sell}} {{Assigner [Location]|rent}} {{GPS|gps}}' + } + }) + end + + ESX.UI.Menu.Open( + 'list', GetCurrentResourceName(), 'properties', + elements, + function(data, menu) + + if data.value == 'sell' then + + menu.close() + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'sell_property_amount', + { + title = 'Montant' + }, + function(data2, menu) + + local amount = tonumber(data2.value) + + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + + menu.close() + + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification('Aucun joueur à proximité') + else + TriggerServerEvent('esx_realestateagentjob:sell', GetPlayerServerId(closestPlayer), data.data.name, amount) + end + + OpenPropertyMenu() + + end + + end, + function(data2, menu) + menu.close() + end + ) + + end + + if data.value == 'rent' then + + menu.close() + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'rent_property_amount', + { + title = 'Montant' + }, + function(data2, menu) + + local amount = tonumber(data2.value) + + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + + menu.close() + + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification('Aucun joueur à proximité') + else + TriggerServerEvent('esx_realestateagentjob:rent', GetPlayerServerId(closestPlayer), data.data.name, amount) + end + + OpenPropertyMenu() + + end + + end, + function(data2, menu) + menu.close() + end + ) + + end + + if data.value == 'gps' then + + TriggerEvent('esx_property:getProperty', data.data.name, function(property) + + if property.isSingle then + SetNewWaypoint(property.entering.x, property.entering.y) + else + TriggerEvent('esx_property:getGateway', property, function(gateway) + SetNewWaypoint(gateway.entering.x, gateway.entering.y) + end) + end + + end) + + end + + end, + function(data, menu) + menu.close() + end + ) + + end) + +end + +function OpenCustomersMenu() + + ESX.TriggerServerCallback('esx_realestateagentjob:getCustomers', function(customers) + + local elements = { + head = {'Client', 'Propriété', 'Type', 'Actions'}, + rows = {} + } + + for i=1, #customers, 1 do + table.insert(elements.rows, { + data = customers[i], + cols = { + customers[i].name, + customers[i].propertyName, + (customers[i].rented and 'Location' or 'Vente'), + '{{Révoquer contrat|revoke}} {{GPS|gps}}' + } + }) + end + + ESX.UI.Menu.Open( + 'list', GetCurrentResourceName(), 'customers', + elements, + function(data, menu) + + if data.value == 'revoke' then + TriggerServerEvent('esx_realestateagentjob:revoke', data.data.propertyName, data.data.propertyOwner) + OpenCustomersMenu() + end + + if data.value == 'gps' then + + TriggerEvent('esx_property:getProperty', data.data.propertyName, function(property) + + if property.isSingle then + SetNewWaypoint(property.entering.x, property.entering.y) + else + TriggerEvent('esx_property:getGateway', property, function(gateway) + SetNewWaypoint(gateway.entering.x, gateway.entering.y) + end) + end + + end) + + end + + end, + function(data, menu) + menu.close() + end + ) + + end) + +end + +RegisterNetEvent('esx:playerLoaded') +AddEventHandler('esx:playerLoaded', function(xPlayer) + + PlayerData = xPlayer + + if PlayerData.job.name == 'realestateagent' then + Config.Zones.OfficeActions.Type = 1 + else + Config.Zones.OfficeActions.Type = -1 + end + +end) + +RegisterNetEvent('esx:setJob') +AddEventHandler('esx:setJob', function(job) + + PlayerData.job = job + + if PlayerData.job.name == 'realestateagent' then + Config.Zones.OfficeActions.Type = 1 + else + Config.Zones.OfficeActions.Type = -1 + end + +end) + +AddEventHandler('esx_realestateagentjob:hasEnteredMarker', function(zone) + + if zone == 'OfficeEnter' then + local playerPed = GetPlayerPed(-1) + SetEntityCoords(playerPed, Config.Zones.OfficeInside.Pos.x, Config.Zones.OfficeInside.Pos.y, Config.Zones.OfficeInside.Pos.z) + end + + if zone == 'OfficeExit' then + local playerPed = GetPlayerPed(-1) + SetEntityCoords(playerPed, Config.Zones.OfficeOutside.Pos.x, Config.Zones.OfficeOutside.Pos.y, Config.Zones.OfficeOutside.Pos.z) + end + + if zone == 'OfficeActions' and PlayerData.job ~= nil and PlayerData.job.name == 'realestateagent' then + CurrentAction = 'realestateagent_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {} + end + +end) + +AddEventHandler('esx_realestateagentjob:hasExitedMarker', function(zone) + CurrentAction = nil +end) + +RegisterNetEvent('esx_phone:loaded') +AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) + + local specialContact = { + name = 'Agent immobilier', + number = 'realestateagent', + base64Icon = 'data:image/png;base64,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' + } + + TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) + +end) + +-- Create Blips +Citizen.CreateThread(function() + + local blip = AddBlipForCoord(Config.Zones.OfficeEnter.Pos.x, Config.Zones.OfficeEnter.Pos.y, Config.Zones.OfficeEnter.Pos.z) + + SetBlipSprite (blip, 357) + SetBlipDisplay(blip, 4) + SetBlipScale (blip, 1.0) + SetBlipColour (blip, 59) + SetBlipAsShortRange(blip, true) + + BeginTextCommandSetBlipName("STRING") + AddTextComponentString("Agents Immobilier") + EndTextCommandSetBlipName(blip) + +end) + +-- Display markers +Citizen.CreateThread(function() + while true do + + Wait(0) + + local coords = GetEntityCoords(GetPlayerPed(-1)) + + for k,v in pairs(Config.Zones) do + if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) + end + end + + end +end) + +-- Enter / Exit marker events +Citizen.CreateThread(function() + while true do + + Wait(0) + + local coords = GetEntityCoords(GetPlayerPed(-1)) + local isInMarker = false + local currentZone = nil + + for k,v in pairs(Config.Zones) do + if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then + isInMarker = true + currentZone = k + end + end + + if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then + HasAlreadyEnteredMarker = true + LastZone = currentZone + TriggerEvent('esx_realestateagentjob:hasEnteredMarker', currentZone) + end + + if not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent('esx_realestateagentjob:hasExitedMarker', LastZone) + end + + end +end) + +-- Key controls +Citizen.CreateThread(function() + while true do + + Citizen.Wait(0) + + if CurrentAction ~= nil then + + SetTextComponentFormat('STRING') + AddTextComponentString(CurrentActionMsg) + DisplayHelpTextFromStringLabel(0, 0, 1, -1) + + if IsControlPressed(0, Keys['E']) and (GetGameTimer() - GUI.Time) > 300 then + + if CurrentAction == 'realestateagent_menu' then + OpenRealestateAgentMenu() + end + + CurrentAction = nil + GUI.Time = GetGameTimer() + + end + + end + + end +end) + +-- Load IPLS +Citizen.CreateThread(function() + LoadMpDlcMaps() + EnableMpDlcMaps(true) + RequestIpl('ex_dt1_02_office_02c') +end) \ No newline at end of file diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..bb654350 --- /dev/null +++ b/config.lua @@ -0,0 +1,36 @@ +Config = {} +Config.DrawDistance = 100.0 +Config.MarkerColor = {r = 120, g = 120, b = 240} + +Config.Zones = { + + OfficeEnter = { + Pos = {x = -199.151, y = -575.000, z = 39.489}, + Size = {x = 1.5, y = 1.5, z = 1.0}, + Type = 1 + }, + + OfficeExit = { + Pos = {x = -141.226, y = -614.166, z = 167.820}, + Size = {x = 1.5, y = 1.5, z = 1.0}, + Type = 1 + }, + + OfficeInside = { + Pos = {x = -140.969, y = -616.785, z = 167.820}, + Size = {x = 1.5, y = 1.5, z = 1.0}, + Type = -1 + }, + + OfficeOutside = { + Pos = {x = -202.238, y = -578.193, z = 39.500}, + Size = {x = 1.5, y = 1.5, z = 1.0}, + Type = -1 + }, + + OfficeActions = { + Pos = {x = -124.786, y = -641.486, z = 167.820}, + Size = {x = 1.5, y = 1.5, z = 1.0}, + Type = -1 + }, +} diff --git a/esx_realestateagentjob.sql b/esx_realestateagentjob.sql new file mode 100644 index 00000000..c15aa369 --- /dev/null +++ b/esx_realestateagentjob.sql @@ -0,0 +1,16 @@ +USE `gta5_gamemode_essential`; + +INSERT INTO `addon_account` (name, label, shared) VALUES + ('society_realestateagent','Agent Immobilier',1) +; + +INSERT INTO `jobs` (name, label) VALUES + ('realestateagent','Agent immobilier') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('realestateagent',0,'location','Location',10,'{}','{}'), + ('realestateagent',1,'vendeur','Vendeur',25,'{}','{}'), + ('realestateagent',2,'gestion','Gestion',40,'{}','{}'), + ('realestateagent',3,'boss','Patron',0,'{}','{}') +; diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..415d3044 --- /dev/null +++ b/server/main.lua @@ -0,0 +1,95 @@ +ESX = nil + +TriggerEvent('esx:getSharedObject', function(obj) + ESX = obj +end) + +RegisterServerEvent('esx_realestateagentjob:revoke') +AddEventHandler('esx_realestateagentjob:revoke', function(property, owner) + TriggerEvent('esx_property:removeOwnedPropertyIdentifier', property, owner) +end) + +AddEventHandler('esx_phone:ready', function() + + TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) + + local xPlayer = ESX.GetPlayerFromId(source) + local xPlayers = ESX.GetPlayers() + local job = 'Client immobilier' + + if phoneNumber == "realestateagent" then + + for k, v in pairs(xPlayers) do + if v.job.name == 'realestateagent' then + TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, job) + end + end + + end + + end) + +end) + +RegisterServerEvent('esx_realestateagentjob:sell') +AddEventHandler('esx_realestateagentjob:sell', function(target, property, price) + + local xPlayer = ESX.GetPlayerFromId(target) + + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_realestateagent', function(account) + account.addMoney(price) + end) + + TriggerEvent('esx_property:setPropertyOwned', property, price, false, xPlayer.identifier) +end) + +RegisterServerEvent('esx_realestateagentjob:rent') +AddEventHandler('esx_realestateagentjob:rent', function(target, property, price) + + local xPlayer = ESX.GetPlayerFromId(target) + + TriggerEvent('esx_property:setPropertyOwned', property, price, true, xPlayer.identifier) +end) + +TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) + + local xPlayer = ESX.GetPlayerFromId(source) + local xPlayers = ESX.GetPlayers() + + if phoneNumber == 'realestateagent' then + for k, v in pairs(xPlayers) do + if v.job.name == 'realestateagent' then + TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'player') + end + end + end + +end) + +ESX.RegisterServerCallback('esx_realestateagentjob:getCustomers', function(source, cb) + + TriggerEvent('esx_ownedproperty:getOwnedProperties', function(properties) + + local xPlayers = ESX.GetPlayers() + local customers = {} + + for i=1, #properties, 1 do + for k,v in pairs(xPlayers) do + if v.identifier == properties[i].owner then + table.insert(customers, { + name = v.name, + propertyOwner = properties[i].owner, + propertyRented = properties[i].rented, + propertyId = properties[i].id, + propertyPrice = properties[i].price, + propertyName = properties[i].name + }) + end + end + end + + cb(customers) + + end) + +end) \ No newline at end of file From 0dd0d64e015c1914aa2a436688c9475541b850f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 11:38:47 +0200 Subject: [PATCH 0097/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..641e8bad --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_service +FXServer ESX Service From 3a5b26d18dbbbd593b7bc38c1364538836be66cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 11:42:06 +0200 Subject: [PATCH 0098/3224] Update README.md --- README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/README.md b/README.md index 641e8bad..96ed585e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,32 @@ # fxserver-esx_service FXServer ESX Service + +[INSTALLATION] + +1) CD in your resources/[esx] folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-esx_service esx_service +``` +3) Add this in your server.cfg : + +``` +start esx_service +``` + +[USAGE] +``` +-- Enable service +ESX.TriggerServerCallback('esx_service:enableService', function(canTakeService, maxInService, inServiceCount) + + if canTakeService then + ESX.ShowNotification('Vous avez pris votre service') + else + ESX.ShowNotification('Service complet : ' .. inServiceCount .. '/' .. maxInService) + end + +end, 'taxi') + +-- Disable service +TriggerServerEvent('esx_service:disableService', 'taxi') +``` From b0f878f5bb194b02207e5c257967b608ef19f645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 11:43:22 +0200 Subject: [PATCH 0099/3224] Add files --- __resource.lua | 7 +++++++ server/main.lua | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 __resource.lua create mode 100644 server/main.lua diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..d8e5a91c --- /dev/null +++ b/__resource.lua @@ -0,0 +1,7 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'ESX Service' + +server_scripts { + 'server/main.lua' +} \ No newline at end of file diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..a30b38dc --- /dev/null +++ b/server/main.lua @@ -0,0 +1,43 @@ +ESX = nil +local InService = {} +local MaxInService = {} + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +function GetInServiceCount(name) + + local count = 0 + + for k,v in pairs(InService[name]) do + if v == true then + count = count + 1 + end + end + + return count + +end + +AddEventHandler('esx_service:activateService', function(name, max) + InService[name] = {} + MaxInService[name] = max +end) + +AddEventHandler('esx_service:disableService', function(name) + InService[name][source] = nil +end) + +ESX.RegisterServerCallback('esx_service:enableService', function(source, cb, name) + + local inServiceCount = GetInServiceCount(name) + + if inServiceCount >= MaxInService[name] then + cb(false, MaxInService[name], inServiceCount) + else + InService[name][source] = enable + cb(true, MaxInService[name], inServiceCount) + end + +end) + + From c4888631050e90a3f1789be15f5b77b9b793025b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 11:45:30 +0200 Subject: [PATCH 0100/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..61175955 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_taxijob +FXServer ESX Taxi Job From 5c1ef492f9310cf7e2007382433dea9030778dd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 11:46:00 +0200 Subject: [PATCH 0101/3224] Update README.md --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 61175955..b44a8792 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,15 @@ # fxserver-esx_taxijob FXServer ESX Taxi Job + +[INSTALLATION] + +1) CD in your resources/[esx] folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-esx_taxijob esx_taxijob +``` +3) Add this in your server.cfg : + +``` +start esx_taxijob +``` From 4f9a6e887d5cc530d324173c58893a1a514aba9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 12:05:23 +0200 Subject: [PATCH 0102/3224] Update README.md --- README.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b44a8792..d6f7b23a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,15 @@ # fxserver-esx_taxijob FXServer ESX Taxi Job +[REQUIREMENTS] + +* Auto mode +No need to download another resource + +* Player management (billing and boss actions) +- esx_society => https://github.com/FXServer-ESX/fxserver-esx_society +- esx_billing => https://github.com/FXServer-ESX/fxserver-esx_billing + [INSTALLATION] 1) CD in your resources/[esx] folder @@ -8,8 +17,12 @@ FXServer ESX Taxi Job ``` git clone https://github.com/FXServer-ESX/fxserver-esx_taxijob esx_taxijob ``` -3) Add this in your server.cfg : +3) - Auto mode : Import esx_taxijob_minimal.sql in your database + - Player management : Import esx_taxijob_full.sql in your database + +4) Add this in your server.cfg : ``` start esx_taxijob ``` +5) If you want player management you have to set Config.EnablePlayerManagement to true in config.lua From 0993140e86474e13d57de763a3a0673ce840f2bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 12:05:49 +0200 Subject: [PATCH 0103/3224] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d6f7b23a..b1aeec46 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,8 @@ No need to download another resource ``` git clone https://github.com/FXServer-ESX/fxserver-esx_taxijob esx_taxijob ``` -3) - Auto mode : Import esx_taxijob_minimal.sql in your database - - Player management : Import esx_taxijob_full.sql in your database +3) * Auto mode : Import esx_taxijob_minimal.sql in your database + * Player management : Import esx_taxijob_full.sql in your database 4) Add this in your server.cfg : From 47b662aab181103e61bff4a90996d5bf79e57080 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 12:06:24 +0200 Subject: [PATCH 0104/3224] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b1aeec46..577f6681 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,11 @@ FXServer ESX Taxi Job [REQUIREMENTS] * Auto mode -No need to download another resource + * No need to download another resource * Player management (billing and boss actions) -- esx_society => https://github.com/FXServer-ESX/fxserver-esx_society -- esx_billing => https://github.com/FXServer-ESX/fxserver-esx_billing + * esx_society => https://github.com/FXServer-ESX/fxserver-esx_society + * esx_billing => https://github.com/FXServer-ESX/fxserver-esx_billing [INSTALLATION] From dcf8df0df8f3ff6e48b0e14fd109afcd286c5a59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 12:11:31 +0200 Subject: [PATCH 0105/3224] Add files --- __resource.lua | 13 + client/main.lua | 756 ++++++++++++++++++++++++++++++++++++++++ config.lua | 124 +++++++ esx_taxijob_full.sql | 15 + esx_taxijob_minimal.sql | 11 + server/main.lua | 57 +++ 6 files changed, 976 insertions(+) create mode 100644 __resource.lua create mode 100644 client/main.lua create mode 100644 config.lua create mode 100644 esx_taxijob_full.sql create mode 100644 esx_taxijob_minimal.sql create mode 100644 server/main.lua diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..d8e5a59d --- /dev/null +++ b/__resource.lua @@ -0,0 +1,13 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'ESX Taxi Job' + +client_scripts { + 'config.lua', + 'client/main.lua' +} + +server_scripts { + 'config.lua', + 'server/main.lua' +} \ No newline at end of file diff --git a/client/main.lua b/client/main.lua new file mode 100644 index 00000000..d2cfdb00 --- /dev/null +++ b/client/main.lua @@ -0,0 +1,756 @@ +local Keys = { + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, + ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, + ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, + ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, + ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 +} + +ESX = nil +local PlayerData = {} +local GUI = {} +GUI.Time = 0 +local HasAlreadyEnteredMarker = false +local LastZone = nil +local CurrentAction = nil +local CurrentActionMsg = '' +local CurrentActionData = {} +local OnJob = false +local CurrentCustomer = nil +local CurrentCustomerBlip = nil +local DestinationBlip = nil +local IsNearCustomer = false +local CustomerIsEnteringVehicle = false +local CustomerEnteredVehicle = false +local TargetCoords = nil + +Citizen.CreateThread(function() + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end +end) + +function DrawSub(msg, time) + ClearPrints() + SetTextEntry_2("STRING") + AddTextComponentString(msg) + DrawSubtitleTimed(time, 1) +end + +function ShowLoadingPromt(msg, time, type) + Citizen.CreateThread(function() + Citizen.Wait(0) + N_0xaba17d7ce615adbf("STRING") + AddTextComponentString(msg) + N_0xbd12f8228410d9b4(type) + Citizen.Wait(time) + N_0x10d373323e5b9c0d() + end) +end + +function GetRandomPed() + + local peds = {} + local handle, ped = FindFirstPed() + local success = nil + + repeat + table.insert(peds, ped) + success, ped = FindNextPed(handle) + until not success + + EndFindPed(handle) + + if #peds > 0 then + return peds[GetRandomIntInRange(1, #peds)] + end + +end + +function ClearCurrentMission() + + if DoesBlipExist(CurrentCustomerBlip) then + RemoveBlip(CurrentCustomerBlip) + end + + if DoesBlipExist(DestinationBlip) then + RemoveBlip(DestinationBlip) + end + + CurrentCustomer = nil + CurrentCustomerBlip = nil + DestinationBlip = nil + IsNearCustomer = false + CustomerIsEnteringVehicle = false + CustomerEnteredVehicle = false + TargetCoords = nil + +end + +function StartTaxiJob() + + ShowLoadingPromt('Prise de service : Taxi/Uber', 5000, 3) + ClearCurrentMission() + + OnJob = true + +end + +function StopTaxiJob() + + local playerPed = GetPlayerPed(-1) + + if IsPedInAnyVehicle(playerPed, false) and CurrentCustomer ~= nil then + local vehicle = GetVehiclePedIsIn(playerPed, false) + TaskLeaveVehicle(CurrentCustomer, vehicle, 0) + + if CustomerEnteredVehicle then + TaskGoStraightToCoord(CurrentCustomer, TargetCoords.x, TargetCoords.y, TargetCoords.z, 1.0, -1, 0.0, 0.0) + end + + end + + ClearCurrentMission() + + OnJob = false + + DrawSub('Mission terminée', 5000) + +end + +function OpenTaxiActionsMenu() + + local elements = { + {label = 'Sortir Véhicule', value = 'spawn_vehicle'} + } + + if Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.grade_name == 'boss' then + table.insert(elements, {label = 'Retirer argent société', value = 'withdraw_society_money'}) + table.insert(elements, {label = 'Déposer argent ', value = 'deposit_money'}) + table.insert(elements, {label = 'Blanchir argent', value = 'wash_money'}) + end + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'taxi_actions', + { + title = 'Taxi', + elements = elements + }, + function(data, menu) + + if data.current.value == 'spawn_vehicle' then + + menu.close() + + if Config.MaxInService == -1 then + + local playerPed = GetPlayerPed(-1) + local coords = Config.Zones.VehicleSpawnPoint.Pos + + ESX.Game.SpawnVehicle('taxi', coords, 225.0, function(vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + end) + + else + + ESX.TriggerServerCallback('esx_service:enableService', function(canTakeService, maxInService, inServiceCount) + + if canTakeService then + + local playerPed = GetPlayerPed(-1) + local coords = Config.Zones.VehicleSpawnPoint.Pos + + ESX.Game.SpawnVehicle('taxi', coords, 225.0, function(vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + end) + + else + + ESX.ShowNotification('Service complet : ' .. inServiceCount .. '/' .. maxInService) + + end + + end, 'taxi') + + end + + end + + if data.current.value == 'withdraw_society_money' then + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'withdraw_society_money_amount', + { + title = 'Montant du retrait' + }, + function(data, menu) + + local amount = tonumber(data.value) + + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + menu.close() + TriggerServerEvent('esx_society:withdrawMoney', 'taxi', amount) + end + + end, + function(data, menu) + menu.close() + end + ) + + end + + if data.current.value == 'deposit_money' then + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'deposit_money_amount', + { + title = 'Montant du dépôt' + }, + function(data, menu) + + local amount = tonumber(data.value) + + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + menu.close() + TriggerServerEvent('esx_society:depositMoney', 'taxi', amount) + end + + end, + function(data, menu) + menu.close() + end + ) + + end + + if data.current.value == 'wash_money' then + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'wash_money_amount', + { + title = 'Montant à blanchir' + }, + function(data, menu) + + local amount = tonumber(data.value) + + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + menu.close() + TriggerServerEvent('esx_society:washMoney', 'taxi', amount) + end + + end, + function(data, menu) + menu.close() + end + ) + + end + + end, + function(data, menu) + + menu.close() + + CurrentAction = 'taxi_actions_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {} + + end + ) + +end + +function OpenMobileTaxiActionsMenu() + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'mobile_taxi_actions', + { + title = 'Taxi', + elements = { + {label = 'Facuration', value = 'billing'} + } + }, + function(data, menu) + + if data.current.value == 'billing' then + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'billing', + { + title = 'Montant de la facture' + }, + function(data, menu) + + local amount = tonumber(data.value) + + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + + menu.close() + + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification('Aucun joueur à proximité') + else + TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_taxi', 'Taxi', amount) + end + + end + + end, + function(data, menu) + menu.close() + end + ) + + end + + end, + function(data, menu) + menu.close() + end + ) + +end + +RegisterNetEvent('esx:playerLoaded') +AddEventHandler('esx:playerLoaded', function(xPlayer) + PlayerData = xPlayer +end) + +RegisterNetEvent('esx:setJob') +AddEventHandler('esx:setJob', function(job) + PlayerData.job = job +end) + +AddEventHandler('esx_taxijob:hasEnteredMarker', function(zone) + + if zone == 'TaxiActions' then + CurrentAction = 'taxi_actions_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {} + end + + if zone == 'VehicleDeleter' then + + local playerPed = GetPlayerPed(-1) + + if IsPedInAnyVehicle(playerPed, false) then + CurrentAction = 'delete_vehicle' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour ranger le véhicule' + CurrentActionData = {} + end + + end + +end) + +AddEventHandler('esx_taxijob:hasExitedMarker', function(zone) + CurrentAction = nil +end) + +RegisterNetEvent('esx_phone:loaded') +AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) + + local specialContact = { + name = 'Taxi', + number = 'taxi', + base64Icon = 'data:image/png;base64,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', + } + + TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) + +end) + +-- Create Blips +Citizen.CreateThread(function() + + local blip = AddBlipForCoord(Config.Zones.TaxiActions.Pos.x, Config.Zones.TaxiActions.Pos.y, Config.Zones.TaxiActions.Pos.z) + + SetBlipSprite (blip, 198) + SetBlipDisplay(blip, 4) + SetBlipScale (blip, 1.0) + SetBlipColour (blip, 5) + SetBlipAsShortRange(blip, true) + + BeginTextCommandSetBlipName("STRING") + AddTextComponentString("Taxi") + EndTextCommandSetBlipName(blip) + +end) + +-- Display markers +Citizen.CreateThread(function() + while true do + + Wait(0) + + if PlayerData.job ~= nil and PlayerData.job.name == 'taxi' then + + local coords = GetEntityCoords(GetPlayerPed(-1)) + + for k,v in pairs(Config.Zones) do + if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) + end + end + + end + + end +end) + +-- Enter / Exit marker events +Citizen.CreateThread(function() + while true do + + Wait(0) + + if PlayerData.job ~= nil and PlayerData.job.name == 'taxi' then + + local coords = GetEntityCoords(GetPlayerPed(-1)) + local isInMarker = false + local currentZone = nil + + for k,v in pairs(Config.Zones) do + if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then + isInMarker = true + currentZone = k + end + end + + if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then + HasAlreadyEnteredMarker = true + LastZone = currentZone + TriggerEvent('esx_taxijob:hasEnteredMarker', currentZone) + end + + if not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent('esx_taxijob:hasExitedMarker', LastZone) + end + + end + + end +end) + +-- Taxi Job +Citizen.CreateThread(function() + + while true do + + Citizen.Wait(0) + + local playerPed = GetPlayerPed(-1) + + if OnJob then + + if CurrentCustomer == nil then + + DrawSub('Conduisez à la recherche de ~y~passagers', 5000) + + if IsPedInAnyVehicle(playerPed, false) and GetEntitySpeed(playerPed) > 0 then + + local waitUntil = GetGameTimer() + GetRandomIntInRange(1000, 120000) + + while OnJob and waitUntil > GetGameTimer() do + Citizen.Wait(0) + end + + if OnJob and IsPedInAnyVehicle(playerPed, false) and GetEntitySpeed(playerPed) > 0 then + + while CurrentCustomer == nil do + + local ped = GetRandomPed() + + if IsPedHuman(ped) and IsPedWalking(ped) then + CurrentCustomer = ped + end + + end + + CurrentCustomerBlip = AddBlipForEntity(CurrentCustomer) + + SetBlipAsFriendly(CurrentCustomerBlip, 1) + SetBlipColour(CurrentCustomerBlip, 2) + SetBlipCategory(CurrentCustomerBlip, 3) + SetBlipRoute(CurrentCustomerBlip, true) + + SetEntityAsMissionEntity(CurrentCustomer, true) + ClearPedTasksImmediately(CurrentCustomer) + SetBlockingOfNonTemporaryEvents(CurrentCustomer, 1) + + local standTime = GetRandomIntInRange(60000, 180000) + + TaskStandStill(CurrentCustomer, standTime) + + ESX.ShowNotification('Vous avez ~g~trouvé~s~ un client, conduisez jusqu\'à ce dernier') + + end + + end + + else + + if IsPedFatallyInjured(CurrentCustomer) then + + ESX.ShowNotification('Votre client est ~r~inconscient~w~. Cherchez-en un autre.') + + if DoesBlipExist(CurrentCustomerBlip) then + RemoveBlip(CurrentCustomerBlip) + end + + if DoesBlipExist(DestinationBlip) then + RemoveBlip(DestinationBlip) + end + + SetEntityAsMissionEntity(CurrentCustomer, false) + + CurrentCustomer = nil + CurrentCustomerBlip = nil + DestinationBlip = nil + IsNearCustomer = false + CustomerIsEnteringVehicle = false + CustomerEnteredVehicle = false + TargetCoords = nil + + end + + if IsPedInAnyVehicle(playerPed, false) then + + local vehicle = GetVehiclePedIsIn(playerPed, false) + local playerCoords = GetEntityCoords(playerPed) + local customerCoords = GetEntityCoords(CurrentCustomer) + local customerDistance = GetDistanceBetweenCoords(playerCoords.x, playerCoords.y, playerCoords.z, customerCoords.x, customerCoords.y, customerCoords.z) + + if IsPedSittingInVehicle(CurrentCustomer, vehicle) then + + if CustomerEnteredVehicle then + + local targetDistance = GetDistanceBetweenCoords(playerCoords.x, playerCoords.y, playerCoords.z, TargetCoords.x, TargetCoords.y, TargetCoords.z) + + if targetDistance <= 10.0 then + + TaskLeaveVehicle(CurrentCustomer, vehicle, 0) + + ESX.ShowNotification('Vous êtes ~g~arrivé~s~ à destination') + + TaskGoStraightToCoord(CurrentCustomer, TargetCoords.x, TargetCoords.y, TargetCoords.z, 1.0, -1, 0.0, 0.0) + SetEntityAsMissionEntity(CurrentCustomer, false) + + TriggerServerEvent('esx_taxijob:success') + + RemoveBlip(DestinationBlip) + + CurrentCustomer = nil + CurrentCustomerBlip = nil + DestinationBlip = nil + IsNearCustomer = false + CustomerIsEnteringVehicle = false + CustomerEnteredVehicle = false + TargetCoords = nil + + end + + DrawMarker(1, TargetCoords.x, TargetCoords.y, TargetCoords.z - 1.0, 0, 0, 0, 0, 0, 0, 4.0, 4.0, 2.0, 178, 236, 93, 155, 0, 0, 2, 0, 0, 0, 0) + + else + + RemoveBlip(CurrentCustomerBlip) + + CurrentCustomerBlip = nil + + TargetCoords = Config.JobLocations[GetRandomIntInRange(1, #Config.JobLocations)] + + local street = table.pack(GetStreetNameAtCoord(TargetCoords.x, TargetCoords.y, TargetCoords.z)) + local msg = nil + + if street[2] ~= 0 and street[2] ~= nil then + msg = string.format("~w~Emmenez-moi à~y~ %s~w~, près de~y~ %s", GetStreetNameFromHashKey(street[1]),GetStreetNameFromHashKey(street[2])) + else + msg = string.format("~w~Emmenez-moi à~y~ %s", GetStreetNameFromHashKey(street[1])) + end + + ESX.ShowNotification(msg) + + DestinationBlip = AddBlipForCoord(TargetCoords.x, TargetCoords.y, TargetCoords.z) + + BeginTextCommandSetBlipName("STRING") + AddTextComponentString("Destination") + EndTextCommandSetBlipName(blip) + + SetBlipRoute(DestinationBlip, true) + + CustomerEnteredVehicle = true + + end + + else + + if not CustomerIsEnteringVehicle then + DrawMarker(1, customerCoords.x, customerCoords.y, customerCoords.z - 1.0, 0, 0, 0, 0, 0, 0, 4.0, 4.0, 2.0, 178, 236, 93, 155, 0, 0, 2, 0, 0, 0, 0) + end + + if not CustomerEnteredVehicle then + + if customerDistance <= 30.0 then + + if not IsNearCustomer then + ESX.ShowNotification('Vous êtes à proximité du client, approchez-vous de lui') + IsNearCustomer = true + end + + end + + if customerDistance <= 10.0 then + + if not CustomerIsEnteringVehicle then + + ClearPedTasksImmediately(CurrentCustomer) + + local seat = 0 + + for i=4, 0, 1 do + if IsVehicleSeatFree(vehicle, seat) then + seat = i + break + end + end + + TaskEnterVehicle(CurrentCustomer, vehicle, -1, seat, 2.0, 1) + + CustomerIsEnteringVehicle = true + + end + + end + + end + + end + + else + + DrawSub('Veuillez remonter dans votre véhicule pour continuer la mission', 5000) + + end + + end + + end + + end +end) + +-- Key Controls +Citizen.CreateThread(function() + while true do + + Citizen.Wait(0) + + if CurrentAction ~= nil then + + SetTextComponentFormat('STRING') + AddTextComponentString(CurrentActionMsg) + DisplayHelpTextFromStringLabel(0, 0, 1, -1) + + if IsControlPressed(0, Keys['E']) and PlayerData.job ~= nil and PlayerData.job.name == 'taxi' and (GetGameTimer() - GUI.Time) > 300 then + + if CurrentAction == 'taxi_actions_menu' then + OpenTaxiActionsMenu() + end + + if CurrentAction == 'delete_vehicle' then + + local playerPed = GetPlayerPed(-1) + local vehicle = GetVehiclePedIsIn(playerPed, false) + + if GetEntityModel(vehicle) == GetHashKey('taxi') then + + if Config.MaxInService ~= -1 then + TriggerServerEvent('esx_service:disableService', 'taxi') + end + + DeleteVehicle(vehicle) + else + ESX.ShowNotification('Vous ne pouvez ranger que les taxi') + end + + end + + CurrentAction = nil + GUI.Time = GetGameTimer() + + end + + end + + if IsControlPressed(0, Keys['F6']) and Config.EnablePlayerManagement and (GetGameTimer() - GUI.Time) > 150 then + OpenMobileTaxiActionsMenu() + GUI.Time = GetGameTimer() + end + + if IsControlPressed(0, Keys['DELETE']) and (GetGameTimer() - GUI.Time) > 150 then + + if OnJob then + StopTaxiJob() + else + + if PlayerData.job ~= nil and PlayerData.job.name == 'taxi' then + + local playerPed = GetPlayerPed(-1) + + if IsPedInAnyVehicle(playerPed, false) then + + local vehicle = GetVehiclePedIsIn(playerPed, false) + + if PlayerData.job.grade >= 3 then + StartTaxiJob() + else + if GetEntityModel(vehicle) == GetHashKey('taxi') then + StartTaxiJob() + else + ESX.ShowNotification('Vous devez être dans un taxi pour commencer la mission') + end + end + + else + + if PlayerData.job.grade >= 3 then + ESX.ShowNotification('Vous devez être dans un véhicule pour commencer la mission') + else + ESX.ShowNotification('Vous devez être dans un taxi pour commencer la mission') + end + + end + + end + + end + + GUI.Time = GetGameTimer() + + end + + end +end) \ No newline at end of file diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..2f19dd8b --- /dev/null +++ b/config.lua @@ -0,0 +1,124 @@ +Config = {} +Config.DrawDistance = 100.0 +Config.NPCJobEarnings = {min = 15, max = 40} +Config.MaxInService = 2 +Config.EnablePlayerManagement = false + +Config.Zones = { + + TaxiActions = { + Pos = {x = 915.039, y = -162.187, z = 73.684}, + Size = {x = 1.5, y = 1.5, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Type = 1 + }, + + VehicleSpawnPoint = { + Pos = {x = 911.108, y = -177.867, z = 74.283}, + Size = {x = 1.5, y = 1.5, z = 1.0}, + Type = -1 + }, + + VehicleDeleter = { + Pos = {x = 908.317, y = -183.070, z = 73.201}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Type = 1 + } + +} + +Config.JobLocations = { + {x = 293.476, y = -590.163, z = 42.7371}, + {x = 253.404, y = -375.86, z = 44.0819}, + {x = 120.808, y = -300.416, z = 45.1399}, + {x = -38.4132, y = -381.576, z = 38.3456}, + {x = -107.442, y = -614.377, z = 35.6703}, + {x = -252.292, y = -856.474, z = 30.5626}, + {x = -236.138, y = -988.382, z = 28.7749}, + {x = -276.989, y = -1061.18, z = 25.6853}, + {x = -576.451, y = -998.989, z = 21.785}, + {x = -602.798, y = -952.63, z = 21.6353}, + {x = -790.653, y = -961.855, z = 14.8932}, + {x = -912.588, y = -864.756, z = 15.0057}, + {x = -1069.77, y = -792.513, z = 18.8075}, + {x = -1306.94, y = -854.085, z = 15.0959}, + {x = -1468.51, y = -681.363, z = 26.178}, + {x = -1380.89, y = -452.7, z = 34.0843}, + {x = -1326.35, y = -394.81, z = 36.0632}, + {x = -1383.68, y = -269.985, z = 42.4878}, + {x = -1679.61, y = -457.339, z = 39.4048}, + {x = -1812.45, y = -416.917, z = 43.6734}, + {x = -2043.64, y = -268.291, z = 22.9927}, + {x = -2186.45, y = -421.595, z = 12.6776}, + {x = -1862.08, y = -586.528, z = 11.1747}, + {x = -1859.5, y = -617.563, z = 10.8788}, + {x = -1634.95, y = -988.302, z = 12.6241}, + {x = -1283.99, y = -1154.16, z = 5.30998}, + {x = -1126.47, y = -1338.08, z = 4.63434}, + {x = -867.907, y = -1159.67, z = 5.00795}, + {x = -847.55, y = -1141.38, z = 6.27591}, + {x = -722.625, y = -1144.6, z = 10.2176}, + {x = -575.503, y = -318.446, z = 34.5273}, + {x = -592.309, y = -224.853, z = 36.1209}, + {x = -559.594, y = -162.873, z = 37.7547}, + {x = -534.992, y = -65.6695, z = 40.634}, + {x = -758.234, y = -36.6906, z = 37.2911}, + {x = -1375.88, y = 20.9516, z = 53.2255}, + {x = -1320.25, y = -128.018, z = 48.097}, + {x = -1285.71, y = 294.287, z = 64.4619}, + {x = -1245.67, y = 386.533, z = 75.0908}, + {x = -760.355, y = 285.015, z = 85.0667}, + {x = -626.786, y = 254.146, z = 81.0964}, + {x = -563.609, y = 267.962, z = 82.5116}, + {x = -486.806, y = 271.977, z = 82.8187}, + {x = 88.295, y = 250.867, z = 108.188}, + {x = 234.087, y = 344.678, z = 105.018}, + {x = 434.963, y = 96.707, z = 99.1713}, + {x = 482.617, y = -142.533, z = 58.1936}, + {x = 762.651, y = -786.55, z = 25.8915}, + {x = 809.06, y = -1290.8, z = 25.7946}, + {x = 490.819, y = -1751.37, z = 28.0987}, + {x = 432.351, y = -1856.11, z = 27.0352}, + {x = 164.348, y = -1734.54, z = 28.8982}, + {x = -57.6909, y = -1501.4, z = 31.1084}, + {x = 52.2241, y = -1566.65, z = 29.006}, + {x = 310.222, y = -1376.76, z = 31.4442}, + {x = 181.967, y = -1332.79, z = 28.8773}, + {x = -74.6091, y = -1100.64, z = 25.738}, + {x = -887.045, y = -2187.46, z = 8.13248}, + {x = -749.584, y = -2296.59, z = 12.4627}, + {x = -1064.83, y = -2560.66, z = 19.6811}, + {x = -1033.44, y = -2730.24, z = 19.6868}, + {x = -1018.67, y = -2732, z = 13.2687}, + {x = 797.354, y = -174.423, z = 72.708}, + {x = 508.156, y = -117.908, z = 60.78}, + {x = 159.458, y = -27.555, z = 67.38}, + {x = -36.382, y = -106.912, z = 56.982}, + {x = -355.801, y = -270.404, z = 33.011}, + {x = -831.196, y = -76.871, z = 37.323}, + {x = -1038.707, y = -214.593, z = 37}, + {x = 1918.448, y = 3691.41, z = 32.261}, + {x = 1820.217, y = 3697.115, z = 33.493}, + {x = 1619.323, y = 3827.162, z = 34.482}, + {x = 1418.628, y = 3602.243, z = 34.511}, + {x = 1944.858, y = 3856.252, z = 31.741}, + {x = 2285.278, y = 3839.444, z = 34.023}, + {x = 2760.945, y = 3387.813, z = 55.659}, + {x = 1952.819, y = 2627.731, z = 45.368}, + {x = 1051.414, y = 474.833, z = 93.653}, + {x = 866.393, y = 17.635, z = 78.654}, + {x = 318.985, y = 167.41, z = 103.335}, + {x = 88.836, y = 254.054, z = 108.236}, + {x = -44.852, y = 70.414, z = 72.437}, + {x = -115.496, y = 84.333, z = 70.792}, + {x = -384.806, y = 226.868, z = 83.548}, + {x = -578.669, y = 139.085, z = 61.337}, + {x = -651.334, y = -584.879, z = 34.116}, + {x = -571.847, y = -1195.648, z = 17.869}, + {x = -1513.271, y = -670.039, z = 28.362}, + {x = -1297.484, y = -654.913, z = 26.123}, + {x = -1645.546, y = 144.571, z = 61.664}, + {x = -1160.618, y = 744.418, z = 154.571}, + {x = -798.09, y = 831.699, z = 204.351}, +} \ No newline at end of file diff --git a/esx_taxijob_full.sql b/esx_taxijob_full.sql new file mode 100644 index 00000000..4294b763 --- /dev/null +++ b/esx_taxijob_full.sql @@ -0,0 +1,15 @@ +INSERT INTO `addon_account` VALUES (name, label, shared) + ('society_taxi','Taxi',1) +; + +INSERT INTO `jobs` (name, label) VALUES + ('taxi','Taxi') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('taxi',0,'recrue','Recrue',12,'{}','{}'), + ('taxi',1,'novice','Novice',24,'{}','{}'), + ('taxi',2,'experimente','Experimente',36,'{}','{}'), + ('taxi',3,'uber','Uber',48,'{}','{}'), + ('taxi',4,'boss','Patron',0,'{}','{}') +; diff --git a/esx_taxijob_minimal.sql b/esx_taxijob_minimal.sql new file mode 100644 index 00000000..074330de --- /dev/null +++ b/esx_taxijob_minimal.sql @@ -0,0 +1,11 @@ +INSERT INTO `jobs` (name, label) VALUES + ('taxi','Taxi') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('taxi',0,'recrue','Recrue',12,'{}','{}'), + ('taxi',1,'novice','Novice',24,'{}','{}'), + ('taxi',2,'experimente','Experimente',36,'{}','{}'), + ('taxi',3,'uber','Uber',48,'{}','{}'), + ('taxi',4,'boss','Patron',0,'{}','{}') +; diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..3d46a5f2 --- /dev/null +++ b/server/main.lua @@ -0,0 +1,57 @@ +ESX = nil + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +if Config.MaxInService ~= -1 then + TriggerEvent('esx_service:activateService', 'taxi', Config.MaxInService) +end + +RegisterServerEvent('esx_taxijob:success') +AddEventHandler('esx_taxijob:success', function() + + local xPlayer = ESX.GetPlayerFromId(source) + local total = math.random(Config.NPCJobEarnings.min, Config.NPCJobEarnings.max); + local societyAccount = nil + + if xPlayer.job.grade >= 3 then + total = total * 2 + end + + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_taxi', function(account) + societyAccount = account + end) + + if societyAccount ~= nil then + + local playerMoney = math.floor(total / 100 * 30) + local societyMoney = math.floor(total / 100 * 70) + + xPlayer.addMoney(playerMoney) + societyAccount.addMoney(societyMoney) + + TriggerClientEvent('esx:showNotification', xPlayer.source, 'Vous avez gagné ~g~$'.. playerMoney) + TriggerClientEvent('esx:showNotification', xPlayer.source, 'Votre société a gagné ~g~$'.. societyMoney) + + else + + xPlayer.addMoney(total) + TriggerClientEvent('esx:showNotification', xPlayer.source, 'Vous avez gagné ~g~$'.. total) + + end + +end) + +TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) + + local xPlayer = ESX.GetPlayerFromId(source) + local xPlayers = ESX.GetPlayers() + + if phoneNumber == 'taxi' then + for k, v in pairs(xPlayers) do + if v.job.name == 'taxi' then + TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'Appel Taxi') + end + end + end + +end) \ No newline at end of file From 73e272ef0f62c4550e84ba771dcdf6ac6083b97f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 12:16:45 +0200 Subject: [PATCH 0106/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..cab8f7d7 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_vehicleshop +FXServer ESX Vehicle Shop From 2bc94af8f42f1ddcf2232285606a3d7814e9a2c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 12:18:11 +0200 Subject: [PATCH 0107/3224] Update README.md --- README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/README.md b/README.md index cab8f7d7..9da6f543 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,28 @@ # fxserver-esx_vehicleshop FXServer ESX Vehicle Shop + +[REQUIREMENTS] + +* Auto mode + * No need to download another resource + +* Player management (billing and boss actions) + * esx_society => https://github.com/FXServer-ESX/fxserver-esx_society + * esx_billing => https://github.com/FXServer-ESX/fxserver-esx_billing + +[INSTALLATION] + +1) CD in your resources/[esx] folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-esx_vehicleshop esx_vehicleshop +``` +3) * Auto mode : Import esx_vehicleshop_minimal.sql in your database + * Player management : Import esx_vehicleshop_full.sql in your database + +4) Add this in your server.cfg : + +``` +start esx_vehicleshop +``` +5) If you want player management you have to set Config.EnablePlayerManagement to true in config.lua From dcc1f850064694b6d89e013df9c826436b800f16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 12:24:19 +0200 Subject: [PATCH 0108/3224] Add files --- __resource.lua | 14 + client/main.lua | 936 ++++++++++++++++++++++++++++++++++++ config.lua | 46 ++ esx_vehicleshop_full.sql | 14 + esx_vehicleshop_minimal.sql | 10 + server/main.lua | 419 ++++++++++++++++ stream/v_15_shrm_glass1.ydr | Bin 0 -> 878 bytes stream/v_carshowroom.ybn | Bin 0 -> 35063 bytes stream/v_int_15.ytyp | Bin 0 -> 11886 bytes 9 files changed, 1439 insertions(+) create mode 100644 __resource.lua create mode 100644 client/main.lua create mode 100644 config.lua create mode 100644 esx_vehicleshop_full.sql create mode 100644 esx_vehicleshop_minimal.sql create mode 100644 server/main.lua create mode 100644 stream/v_15_shrm_glass1.ydr create mode 100644 stream/v_carshowroom.ybn create mode 100644 stream/v_int_15.ytyp diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..a74c4022 --- /dev/null +++ b/__resource.lua @@ -0,0 +1,14 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'ESX Vehicle Shop' + +server_scripts { + '@mysql-async/lib/MySQL.lua', + 'config.lua', + 'server/main.lua' +} + +client_scripts { + 'config.lua', + 'client/main.lua' +} diff --git a/client/main.lua b/client/main.lua new file mode 100644 index 00000000..c1b8c621 --- /dev/null +++ b/client/main.lua @@ -0,0 +1,936 @@ +local Keys = { + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, + ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, + ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, + ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, + ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 +} + +ESX = nil +local GUI = {} +GUI.Time = 0 +local HasAlreadyEnteredMarker = false +local LastZone = nil +local PlayerData = {} +local CurrentAction = nil +local CurrentActionMsg = '' +local CurrentActionData = {} +local Categories = {} +local Vehicles = {} +local CurrentVehicle = nil +local CurrentVehicleData = nil + +Citizen.CreateThread(function() + + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end + + ESX.TriggerServerCallback('esx_vehicleshop:getCategories', function(categories) + Categories = categories + end) + + ESX.TriggerServerCallback('esx_vehicleshop:getVehicles', function(vehicles) + Vehicles = vehicles + end) + +end) + +function OpenShopMenu() + + ESX.UI.Menu.CloseAll() + + local playerPed = GetPlayerPed(-1) + + FreezeEntityPosition(playerPed, true) + SetEntityVisible(playerPed, false) + SetEntityCoords(playerPed, Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z) + + local vehiclesByCategory = {} + local elements = {} + local firstVehicleData = nil + + for i=1, #Categories, 1 do + vehiclesByCategory[Categories[i].name] = {} + end + + for i=1, #Vehicles, 1 do + table.insert(vehiclesByCategory[Vehicles[i].category], Vehicles[i]) + end + + for i=1, #Categories, 1 do + + local category = Categories[i] + local categoryVehicles = vehiclesByCategory[category.name] + local options = {} + + for j=1, #categoryVehicles, 1 do + + local vehicle = categoryVehicles[j] + + if i == 1 and j == 1 then + firstVehicleData = vehicle + end + + table.insert(options, vehicle.name .. ' $' .. vehicle.price) + end + + table.insert(elements, { + name = category.name, + label = category.label, + value = 0, + type = 'slider', + max = #Categories[i], + options = options + }) + + end + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'vehicle_shop', + { + title = 'Concessionnaire', + align = 'top-left', + elements = elements + }, + function(data, menu) + + local vehicleData = vehiclesByCategory[data.current.name][data.current.value + 1] + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'shop_confirm', + { + title = 'Acheter ' .. vehicleData.name .. ' pour $' .. vehicleData.price .. ' ?', + align = 'top-left', + elements = { + {label = 'Oui', value = 'yes'}, + {label = 'Non', value = 'no'}, + } + }, + function(data2, menu2) + + menu2.close() + + if data2.current.value == 'yes' then + + if Config.EnablePlayerManagement then + + ESX.TriggerServerCallback('esx_vehicleshop:buyVehicleSociety', function(hasEnoughMoney) + + if hasEnoughMoney then + ESX.ShowNotification('Vous avez acheté un véhicule') + else + ESX.ShowNotification('Vous n\'avez pas assez d\'argent sur votre compte société') + end + + end, vehicleData.model) + + else + + menu2.close() + menu.close() + + ESX.TriggerServerCallback('esx_vehicleshop:buyVehicle', function(hasEnoughMoney) + + if hasEnoughMoney then + + if CurrentVehicle ~= nil then + DeleteVehicle(CurrentVehicle) + CurrentVehicle = nil + end + + ESX.Game.SpawnVehicle(vehicleData.model, { + x = Config.Zones.ShopOutside.Pos.x, + y = Config.Zones.ShopOutside.Pos.y, + z = Config.Zones.ShopOutside.Pos.z + }, -20.0, function(vehicle) + + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + + local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) + + TriggerServerEvent('esx_vehicleshop:setVehicleOwned', vehicleProps) + + end) + + FreezeEntityPosition(playerPed, false) + SetEntityVisible(playerPed, true) + + else + ESX.ShowNotification('Vous n\'avez pas assez d\'argent') + end + + end, vehicleData.model) + + end + + end + + if data2.current.value == 'no' then + + end + + end, + function(data, menu) + + end + ) + + end, + function(data, menu) + + menu.close() + + local playerPed = GetPlayerPed(-1) + + menu.close() + + if CurrentVehicle ~= nil then + DeleteVehicle(CurrentVehicle) + CurrentVehicle = nil + end + + CurrentAction = 'shop_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {} + + FreezeEntityPosition(playerPed, false) + SetEntityVisible(playerPed, true) + + if Config.EnablePlayerManagement then + SetEntityCoords(playerPed, Config.Zones.BossActions.Pos.x, Config.Zones.BossActions.Pos.y, Config.Zones.BossActions.Pos.z) + else + SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos.x, Config.Zones.ShopEntering.Pos.y, Config.Zones.ShopEntering.Pos.z) + end + + end, + function(data, menu) + + local vehicleData = vehiclesByCategory[data.current.name][data.current.value + 1] + local playerPed = GetPlayerPed(-1) + + if CurrentVehicle ~= nil then + DeleteVehicle(CurrentVehicle) + CurrentVehicle = nil + end + + ESX.Game.SpawnLocalVehicle(vehicleData.model, { + x = Config.Zones.ShopInside.Pos.x, + y = Config.Zones.ShopInside.Pos.y, + z = Config.Zones.ShopInside.Pos.z + }, 90.0, function(vehicle) + CurrentVehicle = vehicle + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + FreezeEntityPosition(vehicle, true) + end) + + end + ) + + if CurrentVehicle ~= nil then + DeleteVehicle(CurrentVehicle) + CurrentVehicle = nil + end + + ESX.Game.SpawnLocalVehicle(firstVehicleData.model, { + x = Config.Zones.ShopInside.Pos.x, + y = Config.Zones.ShopInside.Pos.y, + z = Config.Zones.ShopInside.Pos.z + }, 90.0, function(vehicle) + CurrentVehicle = vehicle + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + FreezeEntityPosition(vehicle, true) + end) + +end + +function OpenResellerMenu() + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'reseller', + { + title = 'Concessionnaire', + align = 'top-left', + elements = { + {label = 'Sortir véhicule', value = 'pop_vehicle'}, + {label = 'Rentrer véhicule', value = 'depop_vehicle'}, + {label = 'Créer facture', value = 'create_bill'}, + {label = 'Véhicules en location', value = 'get_rented_vehicles'}, + {label = 'Attribuer véhicule [Vente]', value = 'set_vehicle_owner_sell'}, + {label = 'Attribuer véhicule [Location]', value = 'set_vehicle_owner_rent'}, + } + }, + function(data, menu) + + if data.current.value == 'pop_vehicle' then + OpenPopVehicleMenu() + end + + if data.current.value == 'depop_vehicle' then + + if CurrentVehicle ~= nil then + DeleteVehicle(CurrentVehicle) + end + + end + + if data.current.value == 'create_bill' then + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'set_vehicle_owner_sell_amount', + { + title = 'Montant de la facture' + }, + function(data2, menu) + + local amount = tonumber(data2.value) + + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + + menu.close() + + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification('Aucun joueur à proximité') + else + TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_realestateagent', 'Concessionnaire', tonumber(data2.value)) + end + + end + + end, + function(data2, menu) + menu.close() + end + ) + + end + + if data.current.value == 'get_rented_vehicles' then + OpenRentedVehiclesMenu() + end + + if data.current.value == 'set_vehicle_owner_sell' then + + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification('Aucun joueur à proximité') + else + + local vehicleProps = ESX.Game.GetVehicleProperties(CurrentVehicle) + local model = CurrentVehicleData.model + + TriggerServerEvent('esx_vehicleshop:sellVehicle', model) + TriggerServerEvent('esx_vehicleshop:setVehicleOwnedPlayerId', GetPlayerServerId(closestPlayer), vehicleProps) + end + + end + + if data.current.value == 'set_vehicle_owner_rent' then + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'set_vehicle_owner_rent_amount', + { + title = 'Montant de la location' + }, + function(data2, menu) + + local amount = tonumber(data2.value) + + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + + menu.close() + + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification('Aucun joueur à proximité') + else + + SetVehicleNumberPlateText(CurrentVehicle, 'LOC ' .. ESX.GetRandomString(5)) + + local vehicleProps = ESX.Game.GetVehicleProperties(CurrentVehicle) + local model = CurrentVehicleData.model + + TriggerServerEvent('esx_vehicleshop:rentVehicle', model, vehicleProps.plate, GetPlayerName(closestPlayer), CurrentVehicleData.price, amount, GetPlayerServerId(closestPlayer)) + TriggerServerEvent('esx_vehicleshop:setVehicleOwnedPlayerId', GetPlayerServerId(closestPlayer), vehicleProps) + TriggerServerEvent('esx_vehicleshop:setVehicleForAllPlayers', vehicleProps, Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 5.0) + end + + end + + end, + function(data2, menu) + menu.close() + end + ) + + end + + end, + function(data, menu) + + menu.close() + + CurrentAction = 'reseller_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {} + + end + ) + +end + +function OpenPersonnalVehicleMenu() + + ESX.UI.Menu.CloseAll() + + ESX.TriggerServerCallback('esx_vehicleshop:getPersonnalVehicles', function(vehicles) + + local elements = {} + + for i=1, #vehicles, 1 do + for j=1, #Vehicles, 1 do + if vehicles[i].model == GetHashKey(Vehicles[j].model) then + vehicles[i].name = Vehicles[j].name + end + end + end + + for i=1, #vehicles, 1 do + table.insert(elements, {label = vehicles[i].name .. ' [' .. vehicles[i].plate .. ']', value = vehicles[i]}) + end + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'personnal_vehicle', + { + title = 'Véhicule personnel', + align = 'top-left', + elements = elements + }, + function(data, menu) + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + local heading = GetEntityHeading(playerPed) + local vehicleData = data.current.value + + menu.close() + + ESX.Game.SpawnLocalVehicle(vehicleData.model, { + x = coords.x, + y = coords.y, + z = coords.z + }, heading, function(vehicle) + ESX.Game.SetVehicleProperties(vehicle, vehicleData) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + end) + end, + function(data, menu) + menu.close() + end + ) + + end) + +end + +function OpenPopVehicleMenu() + + ESX.TriggerServerCallback('esx_vehicleshop:getCommercialVehicles', function(vehicles) + + local elements = {} + + for i=1, #vehicles, 1 do + table.insert(elements, {label = vehicles[i].name .. ' $' .. vehicles[i].price, value = vehicles[i].name}) + end + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'commercial_vehicles', + { + title = 'Concessionnaire - Véhicules', + align = 'top-left', + elements = elements + }, + function(data, menu) + + local model = data.current.value + + if CurrentVehicle ~= nil then + DeleteVehicle(CurrentVehicle) + end + + ESX.Game.SpawnLocalVehicle(model, { + x = Config.Zones.ShopInside.Pos.x, + y = Config.Zones.ShopInside.Pos.y, + z = Config.Zones.ShopInside.Pos.z + }, 90.0, function(vehicle) + + CurrentVehicle = vehicle + + for i=1, #Vehicles, 1 do + if model == Vehicles[i].model then + CurrentVehicleData = Vehicles[i] + end + end + + end) + + end, + function(data, menu) + menu.close() + end + ) + + end) + +end + +function OpenRentedVehiclesMenu() + + ESX.TriggerServerCallback('esx_vehicleshop:getRentedVehicles', function(vehicles) + + local elements = {} + + for i=1, #vehicles, 1 do + table.insert(elements, {label = vehicles[i].playerName .. ' : ' .. vehicles[i].name .. ' - ' .. vehicles[i].plate, value = vehicles[i].name}) + end + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'rented_vehicles', + { + title = 'Concessionnaire - Véhicules en location', + align = 'top-left', + elements = elements + }, + nil, + function(data, menu) + menu.close() + end + ) + + end) + +end + +function OpenBossActionsMenu() + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'reseller', + { + title = 'Concessionnaire - Patron', + align = 'top-left', + elements = { + {label = 'Acheter véhicule', value = 'buy_vehicle'}, + {label = 'Retirer argent société', value = 'withdraw_society_money'}, + {label = 'Déposer argent ', value = 'deposit_money'}, + {label = 'Blanchir argent', value = 'wash_money'} + } + }, + function(data, menu) + + if data.current.value == 'buy_vehicle' then + OpenShopMenu() + end + + if data.current.value == 'withdraw_society_money' then + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'withdraw_society_money_amount', + { + title = 'Montant du retrait' + }, + function(data, menu) + + local amount = tonumber(data.value) + + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + menu.close() + TriggerServerEvent('esx_society:withdrawMoney', 'cardealer', amount) + end + + end, + function(data, menu) + menu.close() + end + ) + + end + + if data.current.value == 'deposit_money' then + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'deposit_money_amount', + { + title = 'Montant du dépôt' + }, + function(data, menu) + + local amount = tonumber(data.value) + + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + menu.close() + TriggerServerEvent('esx_society:depositMoney', 'cardealer', amount) + end + + end, + function(data, menu) + menu.close() + end + ) + + end + + if data.current.value == 'wash_money' then + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'wash_money_amount', + { + title = 'Montant à blanchir' + }, + function(data, menu) + + local amount = tonumber(data.value) + + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + menu.close() + TriggerServerEvent('esx_society:washMoney', 'cardealer', amount) + end + + end, + function(data, menu) + menu.close() + end + ) + + end + + end, + function(data, menu) + + menu.close() + + CurrentAction = 'boss_actions_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {} + + end + ) + +end + +RegisterNetEvent('esx:playerLoaded') +AddEventHandler('esx:playerLoaded', function(xPlayer) + + PlayerData = xPlayer + + if Config.EnablePlayerManagement then + + if PlayerData.job.name == 'cardealer' then + + Config.Zones.ShopEntering.Type = 1 + + if PlayerData.job.grade_name == 'boss' then + Config.Zones.BossActions.Type = 1 + end + + else + Config.Zones.ShopEntering.Type = -1 + Config.Zones.BossActions.Type = -1 + end + + end + +end) + +RegisterNetEvent('esx:setJob') +AddEventHandler('esx:setJob', function(job) + + PlayerData.job = job + + if Config.EnablePlayerManagement then + + if PlayerData.job.name == 'cardealer' then + + Config.Zones.ShopEntering.Type = 1 + + if PlayerData.job.grade_name == 'boss' then + Config.Zones.BossActions.Type = 1 + end + + else + Config.Zones.ShopEntering.Type = -1 + Config.Zones.BossActions.Type = -1 + end + + end + +end) + +RegisterNetEvent('esx_vehicleshop:openPersonnalVehicleMenu') +AddEventHandler('esx_vehicleshop:openPersonnalVehicleMenu', function() + OpenPersonnalVehicleMenu() +end) + +AddEventHandler('esx_vehicleshop:hasEnteredMarker', function(zone) + + if zone == 'ShopEntering' then + + if Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.name == 'cardealer' then + + CurrentAction = 'reseller_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {} + + else + + CurrentAction = 'shop_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {} + + end + + end + + if zone == 'GiveBackVehicle' and Config.EnablePlayerManagement then + + local playerPed = GetPlayerPed(-1) + + if IsPedInAnyVehicle(playerPed, false) then + + local vehicle = GetVehiclePedIsIn(playerPed, false) + + CurrentAction = 'give_back_vehicle' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour rendre votre véhicule' + + CurrentActionData = { + vehicle = vehicle + } + + end + + end + + if zone == 'ResellVehicle' then + + local playerPed = GetPlayerPed(-1) + + if IsPedInAnyVehicle(playerPed, false) then + + local vehicle = GetVehiclePedIsIn(playerPed, false) + local vehicleData = nil + + for i=1, #Vehicles, 1 do + if GetHashKey(Vehicles[i].model) == GetEntityModel(vehicle) then + vehicleData = Vehicles[i] + break + end + end + + local resellPrice = math.floor(vehicleData.price / 100 * Config.ResellPercentage) + + CurrentAction = 'resell_vehicle' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour vendre ' .. vehicleData.name .. ' au prix de $' .. resellPrice + + CurrentActionData = { + vehicle = vehicle, + price = resellPrice + } + + end + + end + + if zone == 'BossActions' and PlayerData.job ~= nil and PlayerData.job.name == 'cardealer' and PlayerData.job.grade_name == 'boss' then + + CurrentAction = 'boss_actions_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {} + + end + +end) + +AddEventHandler('esx_vehicleshop:hasExitedMarker', function(zone) + CurrentAction = nil +end) + +if Config.EnablePlayerManagement then + + RegisterNetEvent('esx_phone:loaded') + AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) + + local specialContact = { + name = 'Concession', + number = 'cardealer', + base64Icon = 'data:image/x-icon;base64,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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroMD5K6G8+SuinPkro2z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87Rt3/Mzy+/zI7u+AyPLysMju7cjI7vDUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SuhcPkropz5K6O8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTW/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uvEyPLysMju7YDI7uxYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroDD5K6GQ+Sui7Pkro+z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zZBy/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/DI7vMEyO7tnMju7DgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroOD5K6J8+Suj3Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zxI4/80PsP/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r4Mjy9ozI7vD0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugEPkroXD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87Rt3/Mzy+/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u9MyO7tgMju8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugIPkrobz5K6N8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTW/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7vfMjy9dDI7vAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugEPkroYD5K6N8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zZBy/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju73zI8vWQyO7wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroPD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zxI4/80PsT/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u9MyO7tAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroFD5K6KM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R97/Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yPL2oMju7FgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6GA+SujvPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTW/zI7u/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7rxMjy9ZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SuivPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzf8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy9sDI7uxYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhEPkro4z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zxI4/80PsX/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju65jI8vUgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkrodz5K6Ps+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R97/Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/DI7vH0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroDD5K6Kc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTW/zI7u/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI8vawyO7sOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Bg+SujLPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzf8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u84yO7sbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugoPkro3z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zxI4/80PsX/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uuIyO7orAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6Oc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R97/Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uuoyO7orAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Dw+SujzPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTW/zI7u/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uvUzPL8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugoPkro8z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzf8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uvEyO7orAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6Oc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1I5P80PsX/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uuoyO7orAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Bg+SujfPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R9//Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uuIyO7sbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugMPkroyz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTX/zI7vP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u84yO7sOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Kc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI8vawAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+Suh3Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1I5P81P8X/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7vH0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroRD5K6Ps+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R9//Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/DI8vUgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTX/zI7vP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju65jI7uxYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkrorz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy9swAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6GA+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1I5P81P8X/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy9ZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugUPkro7z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R9//Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7rxMju7FgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6KM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTX/zI7vP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yPL2oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+Sug8Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7tAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroBD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1J5f81P8X/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u9MyO7wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhgPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R+D/Mz3A/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI8vWQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroCD5K6N8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OkXY/zI7vP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju73zI7vAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhvPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdC0P8yO7r/Mju6/zI7uv8yO7r/Mju6/zI6uP8yOqn/Mjqp/zI6q/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI6qf8yOqn/Mjqp/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/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Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/MjVa/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8yNVj/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7vD0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6J8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1J5f81P8b/Mju6/zI7uv8yO7r/Mju6/zI7uv8yN37/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjmY/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI4jf8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8yN4n/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy9owAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugMPkro9z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R+D/Mz3A/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zMzQf8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8yNVv/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/MjRO/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zI0Tv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r4Mju7DgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6GQ+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OkXY/zI7vP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yOZ7/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzN/8yOrP/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI6rf8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zI6qf8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7tn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MjVl/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zI3fv8yO7r/IILV/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/H4fW/zI7uv8yNnD/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjZt/zI7uv8oY8n/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8nZcr/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI8vTUAAAAAAAAAAD5K6G8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/xyi6/8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Ho3Z/zI7uv8yOqn/MzM5/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zNEP/Mjq1/zI7uv8XqOP/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Vr+b/Mju6/zI6sf8zMz3/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzPf8yOq//Mju6/x+H1v8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yJ60v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy+cgAAAAAAAAAAPkropz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Kn7q/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Tuen/MEO9/zI7uv8yN4n/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzM5/zI5nv8yO7r/K1TD/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8pXcb/Mju6/zI4lv8zMzX/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzX/MjiU/zI7uv8xP7v/E7fp/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8RwOz/Lkm//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv81P8epAAAAAAAAAAA+SujbPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P86U+j/EcDt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8hgNT/Mju6/zI7uv8yN4f/MzM3/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzP/8yOJr/Mju6/zI7uv8anN7/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xii4f8yO7r/Mju6/zI4kv8zMzv/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzM5/zI4kv8yO7r/Mju6/yJ60v8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xuY3f8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/N0LP/z1J59sAAAAAPkroDD5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8fnOv/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHA7P8rVsT/Mju6/zI7uv8yOaX/MjVd/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzN/8yNmf/Mjqv/zI7uv8yO7r/JW/O/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yN20P8yO7r/Mju6/zI6qf8yNWX/MzM1/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzM1/zI1Yf8yOqn/Mju6/zI7uv8rVMP/Er7r/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/KV/H/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju8/zpF2P8+Suj/Pkro/zlF2Qw+Sug0Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/y9v6f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xS16P8sUML/Mju6/zI7uv8yO7r/Mjqr/zI3hf8yNnL/MjZl/zI2dP8yOIv/Mjqv/zI7uv8yO7r/Mju6/yhhyP8RwOz/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcDs/ydny/8yO7r/Mju6/zI7uv8yOq//MjiJ/zI2dP8yNmX/MjZ0/zI4if8yOq//Mju6/zI7uv8yO7r/LFDC/xS16P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xar5P8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zM9wf88R+D/Pkro/z5K6P8+Suj/PEfhND5K6Fw+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUzo/xS47P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xO36f8oYcj/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8kdM//EcDs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcDs/yN20P8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/ylcx/8Utej/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/JHTP/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv81P8j/PUnl/z5K6P8+Suj/Pkro/z5K6P88SONcPkrogz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/JI3r/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8ckdr/LFLC/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8pX8f/GKLh/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xik4v8oYcj/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yxQwv8dj9r/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xO56f8wQbz/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/OELR/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1J5oM+SuifPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P81YOn/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Fqvk/x+H1v8jdtD/JW7N/yN40f8ejdn/FLPn/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Us+f/HY/Z/yN40f8lbs3/JHTP/x+H1v8XqOP/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/H4fW/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy9/zpG2/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkronz5K6L8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8Yrez/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8sUML/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zQ+w/88SOL/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Sui/Pkro1z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/ymA6v8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Gpze/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv82QMv/PUnm/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Nc+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OVXo/xHA7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8oY8n/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/OUTW/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro4z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Hp7r/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/FbHm/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mzy//ztH3v8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8vcen/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8jeNH/Mju6/zI7uv8yO7r/Mju6/zQ+xf88SOP/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zxN6P8UuOz/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Er7r/zBDvf8yO7r/Mju6/zI7uv83Qc7/PUnn/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/ySP6/8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8ei9j/Mju6/zI7uv8yO7z/OUTY/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/LnPp/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yZpy/8yO7r/Mz3A/ztH4P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P85Vej/Er7s/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/F6jj/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/GKLh/xHC7f8Rwu3/EcLt/xyV3P8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/xat5f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Svuv/L0e+/zU/x/89SeX/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8td+r/EcDt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8ejdn/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8lbs3/EcLt/xHC7f8Rwu3/LkzA/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/G5jd/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcDt/yVuzv84QtH/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P81YOn/Jojq/yKV6/8ilev/IpXr/yKV6/8ilev/IpXr/yKV6/8ilev/HaLr/xHC7f8Rwu3/EcLt/x2P2v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yVuzf8Rwu3/EcLt/xHC7f8uTMD/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8WreX/EcLt/xHC7f8Vr+X/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/H5Hg/yKV6/8ilev/IpXr/yaK6v81Xeb/OkXa/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8yaOn/EcLt/xHC7f8Rwu3/HY/a/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/JW7N/xHC7f8Rwu3/EcLt/y5MwP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/MEG8/xHC7f8Rwu3/EcLt/yJ60v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zU/x/89SeX/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro4z5K6Nc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zJo6f8Rwu3/EcLt/xHC7f8dj9r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8lbs3/EcLt/xHC7f8Rwu3/LkzA/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8pXcb/EcLt/xHC7f8Rwu3/KV/H/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv83Qs7/PUnn/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujXPkrovz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/M2bp/xHC7f8Rwu3/EcLt/xqa3v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yVuzf8Rwu3/EcLt/xHC7f8uTMD/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yF+0/8Rwu3/EcLt/xK76v8xP7v/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/OUPV/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6L8+SuifPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P84Wej/EcLt/xHC7f8Rwu3/GaDg/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/JW7N/xHC7f8Rwu3/EcLt/y5MwP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Fqvk/xHC7f8Rwu3/HZHa/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju8/zpF2v8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkronz5K6IM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/ztR6P8Rwu3/EcLt/xHC7f8ZoOD/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8lbs3/EcLt/xHC7f8Rwu3/LkzA/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/ydnyv8Rwu3/EcLt/xHC7f8pXMb/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zM8v/87R+D/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuiDPkroXD5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/xO87P8Rwu3/EcLt/xWv5f8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yVuzf8Rwu3/EcLt/xHC7f8uTMD/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8xPbr/Fa/m/xHC7f8Rwu3/F6nj/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv80PsP/PEjj/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Fw+Sug0Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/GK3s/xHC7f8Rwu3/FbHm/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/JW7N/xHC7f8Rwu3/EcLt/y5MwP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yVtzf8Rwu3/EcLt/xHC7f8ma8z/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/NUDI/z1J5f8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroND5K6Aw+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8fnOv/EcLt/xHC7f8Rwu3/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8lbs3/EcLt/xHC7f8Rwu3/LkzA/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8xPbr/Fa/m/xHC7f8Rwu3/Fa/m/zE9uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zdCz/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SugMAAAAAD5K6Ns+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/yaI6v8Rwu3/EcLt/xHC7f8wQ73/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/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Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/ymA6v8TvOz/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHA7f8fnOv/N1vo/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6M8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroXD5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zlV6P8kjer/FLjs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xmr7P8nhur/OFno/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugEPkro4z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P88Tej/MWzp/yaK6v8cpOv/Fbbs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Svuz/FrPs/xum7P8gmOv/J4bq/y9v6f85Vej/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6N8+SugEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhvPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zhZ6P84Wej/OFno/zhZ6P84Wej/OFno/zhZ6P84Wej/OFno/zhZ6P88Tej/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkrobwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Ag+SujfPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6N8+SugIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6GA+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroBD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6M8+SugEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroPD5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkrooz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6KMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugUPkro7z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujvPkroFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhgPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuivPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuivAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro4z5K6BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6EQ+Suj7Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Ps+SuhEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Hc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkrodwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Kc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6KcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroDD5K6Ms+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujLPkroDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroGD5K6N8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro3z5K6BgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6Oc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Oc+SugoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6PM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujzPkroKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroPD5K6PM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro8z5K6DwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6Oc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Oc+SugoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6N8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujfPkroKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroGD5K6Ms+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkroyz5K6BgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroDD5K6Ks+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Kc+SugMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Hc+Suj7Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Ps+Suh3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6EQ+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujjPkroRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SuivPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkrorz5K6BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhgPkro7z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro7z5K6GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugUPkrooz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6KM+SugUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroPD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6M8+Sug8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroBD5K6GA+SujfPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6N8+SuhgPkroBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Ag+SuhvPkro3z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6N8+SuhvPkroCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugEPkroXD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6M8+SuhcPkroBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Dg+SuifPkro9z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro9z5K6J8+Sug4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugMPkroZD5K6Ls+Suj7Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj7Pkrouz5K6GQ+SugMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SuhcPkropz5K6O8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6O8+SuinPkroXD5K6BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6DA+SuhvPkropz5K6Ns+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujbPkropz5K6G8+SugwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Aw+Sug0PkroXD5K6IM+SuifPkrovz5K6Nc+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujjPkro1z5K6L8+SuifPkrogz5K6Fw+Sug0PkroDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD////////wAAAP////////////////AAAAAP//////////////8AAAAAAP/////////////4AAAAAAAf////////////4AAAAAAAB////////////wAAAAAAAAD///////////wAAAAAAAAAP//////////wAAAAAAAAAA//////////4AAAAAAAAAAH/////////4AAAAAAAAAAAf////////8AAAAAAAAAAAD////////8AAAAAAAAAAAAP///////+AAAAAAAAAAAAB////////AAAAAAAAAAAAAP///////AAAAAAAAAAAAAA///////gAAAAAAAAAAAAAH//////wAAAAAAAAAAAAAA//////4AAAAAAAAAAAAAAH/////8AAAAAAAAAAAAAAA/////+AAAAAAAAAAAAAAAH/////AAAAAAAAAAAAAAAA/////gAAAAAAAAAAAAAAAH////wAAAAAAAAAAAAAAAA////8AAAAAAAAAAAAAAAAP///+AAAAAAAAAAAAAAAAB////AAAAAAAAAAAAAAAAAP///gAAAAAAAAAAAAAAAAB///4AAAAAAAAAAAAAAAAAf//8AAAAAAAAAAAAAAAAAD//+AAAAAAAAAAAAAAAAAAf//gAAAAAAAAAAAAAAAAAH//wAAAAAAAAAAAAAAAAAA//4AAAAAAAAAAAAAAAAAAH/+AAAAAAAAAAAAAAAAAAB//AAAAAAAAAAAAAAAAAAAP/wAAAAAAAAAAAAAAAAAAD/4AAAAAAAAAAAAAAAAAAAf+AAAAAAAAAAAAAAAAAAAH/gAAAAAAAAAAAAAAAAAAB/wAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAD+AAAAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAAAAAAH4AAAAAAAAAAAAAAAAAAAB8AAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAPgAAAAAAAAAAAAAAAAAAAH4AAAAAAAAAAAAAAAAAAAB+AAAAAAAAAAAAAAAAAAAAfwAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAD/gAAAAAAAAAAAAAAAAAAB/4AAAAAAAAAAAAAAAAAAAf+AAAAAAAAAAAAAAAAAAAH/wAAAAAAAAAAAAAAAAAAD/8AAAAAAAAAAAAAAAAAAA//gAAAAAAAAAAAAAAAAAAf/4AAAAAAAAAAAAAAAAAAH//AAAAAAAAAAAAAAAAAAD//4AAAAAAAAAAAAAAAAAB//+AAAAAAAAAAAAAAAAAAf//wAAAAAAAAAAAAAAAAAP//+AAAAAAAAAAAAAAAAAH///gAAAAAAAAAAAAAAAAB///8AAAAAAAAAAAAAAAAA////gAAAAAAAAAAAAAAAAf///8AAAAAAAAAAAAAAAAP////AAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAB/////AAAAAAAAAAAAAAAA/////4AAAAAAAAAAAAAAAf/////AAAAAAAAAAAAAAAP/////4AAAAAAAAAAAAAAH//////AAAAAAAAAAAAAAD//////4AAAAAAAAAAAAAB///////AAAAAAAAAAAAAA///////8AAAAAAAAAAAAA////////gAAAAAAAAAAAAf///////8AAAAAAAAAAAAP////////wAAAAAAAAAAAP////////+AAAAAAAAAAAH/////////4AAAAAAAAAAH//////////AAAAAAAAAAD//////////8AAAAAAAAAD///////////wAAAAAAAAD////////////gAAAAAAAH////////////+AAAAAAAH/////////////8AAAAAAP//////////////8AAAAA////////////////8AAAD////////ygAAABgAAAAwAAAAAEAIAAAAAAAgJQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroCD5K6Ck9SedOPkrodz5K6Js9See9Pkro1j5K6Ok9Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89SefpPkro1j5K6L08SOSbO0fgdzdC0U4zPcEsMjy9CQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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Mju6/zE6uf4yO7r/Mju6/zI6sP4zMzb/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjL+MzMz/zMzM/8yNWL+Mjq5/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mjq5/zI1Wv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIzOv4yOrX/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uv0yO7srAAAAAAAAAAAAAAAAAAAAAD1J54A+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/O0fg/zQ9wv4yO7r/Mju6/zE6uf4yO7r/Mju6/zI4lf4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjL+MzMz/zMzM/8yNEj+Mjq0/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mjqx/zIzQ/4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4yOZ3/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7uDAAAAAAAAAAAAAAAAPUnnCD1J5809Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/46Rdn+Mjy9/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jI3h/4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yM0P+Mjqx/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+Mjqt/jIzO/4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yOJP+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4yO7rPMju6CQAAAAAAAAAAPkroKD1J5/g+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Suf+NGPp/yWI5/4ei9n/HovY/x6L2P4ei9j/HovY/x6L2P4ei9j/JmrM/zI4kv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjL+MzMz/zMzM/8yNEf+MD+1/yCB1P8ei9j+HovY/x6L2P8ei9j+HovY/x6L2P8ei9j+HovY/x6L2P8ei9j+HovY/x6L2P8ei9j+HovY/x6L2P8ei9j+HovY/x6L2P4fhdb/MEGz/zIzQf4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4yOZz/KGPJ/x6L2P4ei9j/HovY/x6L2P4ei9j/HovY/x6L2P4eitj/JHLO/zBDvf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r5Mju6KgAAAAAAAAAAPkroaT1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P8xa+n+E7vs/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/HY3Z/zI6rv4zMzX/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjL+MzMz/zMzM/8yNV7+L0a9/xO26P8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Suur/Lke9/zI0V/4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIzOP4yOrT/H4jX/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xmg4P4xPLr/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6awAAAAAAAAAAPUnnrD1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1K5/4couv+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+GKPh/jE7uv4yNWL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyM/4yOJf+K1TD/hHB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+KlfE/jI4jf4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jI2af4xOrn+GKHg/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4oX8f+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+Mju7sAAAAAA+SugIPkro4D1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P8enuv+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/Errq/y1Pwf4yOaX/MjNA/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjL+MzMz/zI1Yf8xOrn+IX3T/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/IIPV/zE6uP4yNVr/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MjNE/zI5qv4tTMD/E7np/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xHB7P4qWcX/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju84DQ+xgg+SugpPkro8z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P8udOn+EcHt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/x+H1v4yO7r/MjiW/zIzQP4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjP+MjVc/zI6sf8vRr7+FLLm/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/FLTo/y5Iv/4yOq3/MjRW/zIyM/4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4yM0P/Mjmd/zE6uf4ggtT/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xap4/4xO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7z/OUTW8zhD1Ck9SedOPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/46Uuj+FbXs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hHA7P4pX8f+MTq5/jI6rv4yNmv+MjND/jIzM/4yMjL+MjM3/jI0Tv4yN4f+MTq4/jE8uv4cktv+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/huW3P4xPbr+Mjq2/jI3hP4yNEz+MjM2/jIyMv4yMzT+MjRF/jI2b/4yOrD+MTq5/ildx/4Rv+z+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EcHs/iVvzf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jM9wP47R9/+PUnn/jtG3k0+Suh3Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+I5Hq/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Ttuj/KGHI/zE7uv4yOrn/Mjqx/zI5p/4yOZ7/Mjqq/zI6tf8xOrn+MEG8/x+G1v8Rwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xHB7P4eitj/MEG8/zE6uf4yOrX/Mjqq/zI5nv4yOaj/Mjqy/zE6uf4xO7r/KV/H/xO26P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/FLPn/y9Evf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/NT/I/zxI4/4+Suj/Pkro/zxI43c+SuibPkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+M2Xp/xHB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/Er3r/x+G1v4uSL7/Mju6/zE6uf4yO7r/Mju6/zI7uv8pX8f+GKLh/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/GKPh/yhgyP4yO7r/Mju6/zE6uf4yO7r/Mju6/y9Gvv4fhdb/Erzq/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/H4XW/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE7uv43QtD/PUnm/z1J5/4+Suj/Pkro/z1J5ps9See9PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PE7o/hmr6/4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Rv+z+GKLh/h6K1/4gg9X+HJLb/hWx5v4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Useb+HJLb/iCD1f4eidf+GaHg/hG/7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4SvOr+LFDB/jE6uf4xOrn+MTq5/jE6uf4xOrn+Mzy+/jpF2f49Sef+PUnn/j1J5/49Sef+PUnn/j1J570+SujWPkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/yiD6v4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4bmN3/MTy6/zE6uf4yO7r/Mju6/zE6uf40PsP/O0fg/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J59Y+SujpPkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/zhY6P4Rwe3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4oYcj/Mju6/zE6uf4yO7r/Mju6/zZAyf49SeX/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5+k9Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/4doev+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hWt5f4xOrn+MTq5/jE6uf4yO7v+OEPT/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4tden/EcHt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcHs/yN1z/4yO7r/Mju6/zM8v/46Rtv/PUnn/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/46U+j/Fbbs/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/E7bo/y5Hvv4yO7r/ND7E/zxH4f4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+HaHr/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+GZ3f/jE7uv43Qc7+PUnm/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/L3Hp/xK/7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/JmrM/ypYxf4qWMX/KljF/ypYxf8qWMX+KljF/ypYxf8qWMX+KljF/ypYxf8qWMX+KljF/yN20P8Qwez+EcLt/yJ80v8qWMX+KljF/ypYxf8qWMX+KljF/ypYxf8qWMX+KljF/ypYxf8qWMX+KljF/ypYxf4qWMX/KljF/ypYxf4qWMX/KljF/x6K2P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rvuz/J2jO/zlE1f49Sef/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUvo/zBu6f4gmOv/HaDr/x2g6/4doOv/HaDr/x2g6/4doOv/FLjs/xDB7P4Rwu3/KljF/zE6uf4yO7r/Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/x2O2f4Rwu3/Eb7r/xme3/4anN7/Gpze/xqc3v4anN7/Gpze/xqc3v4anN7/Gpze/xud4v4doOv/HaDr/yCa6/4ua+L/Okfe/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/49SefpPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+Hpzr/hDB7P4Qwez+KljF/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/ihhyP4Qwez+EMHs/iZpy/4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MT27/hel4v4Qwez+Fqrk/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+ND7E/jxI4v49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5+k+SujWPkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/H5zr/xDB7P4Rwu3/KlvG/zE6uf4yO7r/Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Lki//xO56f4Rwu3/HovY/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE7uv41QMn/PUjk/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J59Y+Sui9Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/IpPr/xDB7P4Rwu3/J2XK/zE6uf4yO7r/Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/J2bK/xDB7P4Rwu3/KGDI/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zZBzf49Seb/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5709SeebPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+JYrq/hDB7P4Qwez+JmfK/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/ihhyP4Qwez+EMHs/iZpy/4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4wP7v+GKXi/hDB7P4Wq+T+MEG8/jE6uf4xOrn+MTq5/jE6uf4yO7v+OEPU/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J55s+Suh3Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/K3zq/xDB7P4Rwu3/JHHO/zE6uf4yO7r/Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mju6/zE6uf4masz/EcDs/xDB7P4jdtD/Mju6/zE6uf4yO7r/Mju6/zI8vf46Rdr/PUnn/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J53c9SedOPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+MWzp/hDB7P4Qwez+InvS/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/ihhyP4Qwez+EMHs/iZpy/4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE8uv4WquT+EMHs/hO36P4wQrz+MTq5/jE6uf4xOrn+MzzA/jtG3v49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+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Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj4PkroKAAAAAAAAAAAPUnnCD1J5809Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/4kjOr+EMHs/hem4v4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/ihhyP4Qwez+EMHs/iZpy/4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/iRxzv4Qwez+EMHs/h2N2P4zPcD+O0fe/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49SefNPUnnCAAAAAAAAAAAAAAAAD1J538+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/44WOj/FLfs/xDB7P4nZ8v/Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+JmrL/xK96/4Rwu3/GKTh/zJGyP48SOP/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suh/AAAAAAAAAAAAAAAAAAAAAD1J5yg+Suj9Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Kn3q/xHA7P4Vsuf/LVHF/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE+u/8iedH+Erzq/xDB7P4WrOX/MVPR/z1J5f4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/0+SugoAAAAAAAAAAAAAAAAAAAAAAAAAAA9SefGPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PEzo/iKT6v4Qwez+FbHo/ihmzf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/ihhyP4Qwez+EMHs/iZpy/4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xPbr+KGLJ/hmf4P4Qwez+EMHs/hes6P4zVNj+PUnm/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J58YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhdPkro/j1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1L5/4jkev/EcDt/xHC7f8UtOj+GZ7f/xqc3v8anN7+Gpze/xqc3v8anN7+Gpze/xem4v8Qwez+EcLt/xep4/8anN7+HJLa/x2P2f8fiNf+HY7Z/xqb3v8Tt+n+EcLt/xHC7f8Svuz+IpLr/zpS6P4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/j1J510AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugQPkro3z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/49TOj/L3Hp/xms7P8RwOz+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Rwez+Fbfs/yGW6/80Y+n+PUvo/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro3z1J5w8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnnfj1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/jxO6P4xa+n+JYzq/hqo6/4Tu+z+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EcHs/hS47P4Zq+z+H5zr/iaH6v4wben+OlTo/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnnewAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroGD1J5+g+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+O0/o/zlV6P85Vej+OVXo/zlV6P85Vej+OVXo/zlV6P89TOj+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+SujoPkroGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J53g+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suh4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J5w49SefkPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5+Q9SecOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhaPkro+z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro+z1J51oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugFPkrouD1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/PkrouD1J5wUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnnLj1J5/A9Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49SefwPUnnLgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J52o+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+SuhqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J5wM+SuixPkro/j5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/j1J57A+SugDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SecaPUnn2j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn2j1J5xoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroND5K6Ow9Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+SujsPkroNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6FM9Sef5Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/k+SuhTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SedxPUnn+j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn+j1J53EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkrodz1J5/w+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj8PkrodwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroBD1J53c+Suj6Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/o+Suh3PkroBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SedxPUnn+T1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn+T1J53EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroUz1J5+0+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+SujsPkroUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J5zU+SujaPkro/j1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/j1J59o+Sug0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SecaPUnnsT1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnnsD1J5xoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroAz1J52o+SujwPkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/A+SuhqPkroAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuguPkrouD1J5/s+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj7PkrouD1J5y4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnnBj1J51o9SefkPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5+Q9SedaPUnnBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugOPkroeD1J5+g+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+SujoPkroeD1J5w4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J5xg+Suh8Pkro3z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj+Pkro3z1J53s+SugYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnnDz1J5109SefGPUnn/T1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/T1J58Y9SeddPUnnDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6IA9SefNPkro+D5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro+D1J580+Suh/PkroKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SecIPkroKD5K6Gk9SeesPkro4D5K6PM9Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+SujzPkro4D1J56w+SuhpPkroKD1J5wgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnnBz1J5yk9SedNPUnndz1J55s9See9PUnn1j1J5+k9Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49SefpPUnn1j1J5709SeebPUnndz1J5009SecpPUnnBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////+AAAH///////////gAAAAf/////////+AAAAAH/////////wAAAAAA/////////AAAAAAAP///////8AAAAAAAD///////wAAAAAAAA///////gAAAAAAAAf/////+AAAAAAAAAH/////8AAAAAAAAAD/////4AAAAAAAAAB/////wAAAAAAAAAA/////gAAAAAAAAAAf///+AAAAAAAAAAAH///+AAAAAAAAAAAH///8AAAAAAAAAAAD///4AAAAAAAAAAAB///wAAAAAAAAAAAA///gAAAAAAAAAAAAf//AAAAAAAAAAAAAP//AAAAAAAAAAAAAP/+AAAAAAAAAAAAAH/8AAAAAAAAAAAAAD/8AAAAAAAAAAAAAD/4AAAAAAAAAAAAAB/4AAAAAAAAAAAAAB/wAAAAAAAAAAAAAA/wAAAAAAAAAAAAAA/gAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAfAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAPgAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAfwAAAAAAAAAAAAAA/wAAAAAAAAAAAAAA/4AAAAAAAAAAAAAB/4AAAAAAAAAAAAAB/8AAAAAAAAAAAAAD/8AAAAAAAAAAAAAD/+AAAAAAAAAAAAAH//AAAAAAAAAAAAAP//AAAAAAAAAAAAAP//gAAAAAAAAAAAAf//wAAAAAAAAAAAA///4AAAAAAAAAAAB///8AAAAAAAAAAAD///+AAAAAAAAAAAH///+AAAAAAAAAAAH////gAAAAAAAAAAf////wAAAAAAAAAA/////4AAAAAAAAAB/////8AAAAAAAAAD/////+AAAAAAAAAH//////gAAAAAAAAf//////wAAAAAAAA///////8AAAAAAAD////////AAAAAAAP////////wAAAAAA/////////+AAAAAH//////////gAAAAf//////////+AAAH/////8oAAAASAAAAJAAAAABACAAAAAAAGBUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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Pkro/z5K6P8+Suj/Pkro/zlV6P8wW9X/K1XE/ytVxP8rVcT/K1XE/yxSw/8yOZf/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjVb/y9Hvv8rVcT/K1XE/ytVxP8rVcT/K1XE/ytVxP8rVcT/K1XE/ytVxP8rVcT/K1XE/ytVxP8rVcT/K1XE/y5Iv/8yNFP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Mjmf/yxSwv8rVcT/K1XE/ytVxP8rVcT/K1XE/yxPwf8xPbr/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uoAAAAAAAAAAAD5K6MU+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/LnHp/xO77P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xO26P8wQK//MzM0/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjZw/yF90v8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yCC1P8yNmr/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzb/MT20/xSz5/8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHA7P8bl9z/MTu6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uscAAAAAPkroFz5K6PE9Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Suj/Gavs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hG+6/8tTsH/MjVf/jMzM/8yMjL+MzMz/zIyMv4zMzP/MjIy/jMzM/8zMzX/Mjml/huW3P8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hqZ3f8yOZ/+MzM0/zMzM/8yMjL+MzMz/zIyMv4zMzP/MjIy/jMzM/8yNWX+LUzA/xG96/8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Qwez+KljF/zI7uv8xOrn+Mju6/zE6uf4yO7r/MTq5/jI7uvIzPL8YPkroQz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/IJjr/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8hfNL/Mjmq/zI0Rf8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzNP8yN37/Lki+/xO56f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xK66v8uS8D/MjZ3/zMzNP8zMzP/MzMz/zMzM/8zMzP/MzMz/zI0Sf8yOq3/InnR/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8SvOr/L0O9/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI8vf82Qc1DPkrodD5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/MWvp/hHB7P8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Suur/LU/B/jI6rf8yNmb+MjM8/zIyMv4zMzX/MjRN/jI4kP8xO7r/HJLa/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8clNv+MTy6/zI4jP8yNEz+MzM1/zIyMv4yMz7/MjZp/jI6sP8tTsH+E7np/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8ei9j+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/ND7D/jxH4f87R990PkronT5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PE7o/xex7P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Fa/l/ytWxP8xO7n/Mjqy/zI5p/8yOq3/Mjq3/zBBvP8fiNf/EcHs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwez/HorY/zBBvP8yOrf/Mjqt/zI5p/8yOrP/MTu6/ytUw/8Vr+X/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xG/7P8rVcP/Mju6/zI7uv8yO7r/Mju6/zI7uv82QMv/PUnl/z5K6P89SeWdPkrowT5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/iaI6v8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hK96/8djdn+KGPJ/yxSwv4qWcX/I3fQ/hWt5f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Qwez+EcLt/xWu5f8iedH+KlnF/yxSwv4oYsn/HY3Z/hK86/8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hmf3/8xO7r+Mju6/zI7uv8xOrn+Mju7/zhD1P49Sef/PUnn/j5K6P89SefBPkro3j5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zZd6P8Rwez/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHA7P8Rwez/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcHs/xHA7P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/ydnyv8yO7r/Mju6/zI7uv8zPL//O0bc/z1J5/8+Suj/Pkro/z5K6P8+SujePkro8j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j1K6P8bp+v+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/FbHm/jE+u/8xOrn+Mju6/zQ+xf88SOL+Pkro/z1J5/4+Suj/PUnn/j5K6P89SefyPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8reur/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/InvS/zI7uv8yO7r/N0HO/z1J5v8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P85VOj/E7vs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Su+r/Lkm//zI7vP85RNb/PUnn/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+G6Tr/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+FLPn/xSy5/4Usuf/FLLn/hSy5/8Usuf/FLLn/hSy5/8Usuf+FLLn/xK96/4Rwu3/E7bo/hSy5/8Usuf/FLLn/hSy5/8Usuf+FLLn/xSy5/4Usuf/FLLn/hSy5/8Usuf+FLLn/xSz5/8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4YoeD/Mz3A/jtH3/89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/M2Xp/xaz7P8Sv+z/Er/s/xK/7P8Sv+z/Eb/s/xHB7f8Rwu3/LFPD/zE/u/8xP7v/MT+7/zE/u/8xP7v/MT+7/zE/u/8xP7v/MT+7/xqc3v8Rwu3/KGDI/zE/u/8xP7v/MT+7/zE/u/8xP7v/MT+7/zE/u/8xP7v/MT+7/zE/u/8xP7v/MT+7/yxTw/8Rwu3/EcHs/xG+6/8Rvuv/Eb7r/xG+6/8Rvuv/Eb7r/xG+6/8Sv+z/Er/s/xay7P8uXtT/PEjk/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro8j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1K5/47Uej/O1Ho/jtR6P87Uej/N1ro/hO77P8Qwez+LFHC/zE6uf4yO7r/MTq5/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/xqb3v4Rwu3/KV3H/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/zE6uf4yO7r/MTq5/jI7uv8xOrn+Mju6/ydnyv8Qwez+HJTb/y9Dvf4wQ73/L0O9/jBDvf8vQ73+MEO9/zVJ0P87Uef+O1Ho/z1L5/49Sef/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89SefyPkro3j5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OlLo/xO67P8Rwu3/K1XD/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/xqb3v8Rwu3/KV3H/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/x+G1v8Rwu3/JHLO/zI7uv8yO7r/Mju6/zI7uv8yO7r/OEPU/z1J5/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujePkrowT5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PE3o/hW17P8Qwez+KlrG/zE6uf4yO7r/MTq5/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/xqb3v4Rwu3/KV3H/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/zE6uf4yO7r/MTq5/jI7uv8xOrn+MEG8/xWw5v8Su+r+Lkm//zE6uf4yO7r/MTq5/jI8vf86Rdn+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89SefBPkronT5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/xit7P8Rwu3/KGPJ/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/xqb3v8Rwu3/KV3H/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/I3fQ/xHB7f8dkNr/MTu6/zI7uv8yO7r/Mzy//ztH3/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuidPkrodD5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/h6d6/8Qwez+JmvM/zE6uf4yO7r/MTq5/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/xqb3v4Rwu3/KV3H/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/zE6uf4yO7r/MTq5/jI7uv8wQLz+FLTo/xG/7P8rU8P+Mju6/zE6uf40PsP/PEji/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sed0PkroQz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/yeG6v8Rwu3/InnR/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/xqb3v8Rwu3/KV3H/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8ieNH/EcLt/xyU2/8xO7r/Mju6/zU/yP89SeX/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/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PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J54YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6A4+SujfPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro3z5K6A4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhVPkro/T5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj9PkroVQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugCPUnnpD5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89SeekPkroAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroEz5K6Nw+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Nw+SugTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Dc+SujxPUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro8T5K6DcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhYPkro+z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj7PkroWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnncz5K6Pw9Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6Pw9SedzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6H8+Suj8Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/D5K6H8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SedzPkro+z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj7PUnncwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroWD5K6PI+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6PE+SuhYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Dc+SujcPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro3D5K6DcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugTPUnnpD5K6P0+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/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AAAAAAAAAAAAAAAA////4AAH////AAAA///+AAAAf///AAAA///4AAAAH///AAAA///gAAAAB///AAAA//+AAAAAAf//AAAA//4AAAAAAH//AAAA//wAAAAAAD//AAAA//gAAAAAAB//AAAA//AAAAAAAA//AAAA/+AAAAAAAAf/AAAA/8AAAAAAAAP/AAAA/4AAAAAAAAH/AAAA/wAAAAAAAAD/AAAA/gAAAAAAAAB/AAAA/AAAAAAAAAA/AAAA+AAAAAAAAAAfAAAA+AAAAAAAAAAfAAAA8AAAAAAAAAAPAAAA8AAAAAAAAAAPAAAA4AAAAAAAAAAHAAAA4AAAAAAAAAAHAAAAwAAAAAAAAAADAAAAwAAAAAAAAAADAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAwAAAAAAAAAADAAAAwAAAAAAAAAADAAAA4AAAAAAAAAAHAAAA4AAAAAAAAAAHAAAA8AAAAAAAAAAPAAAA8AAAAAAAAAAPAAAA+AAAAAAAAAAfAAAA+AAAAAAAAAAfAAAA/AAAAAAAAAA/AAAA/gAAAAAAAAB/AAAA/wAAAAAAAAD/AAAA/4AAAAAAAAH/AAAA/8AAAAAAAAP/AAAA/+AAAAAAAAf/AAAA//AAAAAAAA//AAAA//gAAAAAAB//AAAA//wAAAAAAD//AAAA//4AAAAAAH//AAAA//+AAAAAAf//AAAA///gAAAAB///AAAA///4AAAAH///AAAA///+AAAAf///AAAA////4AAH////AAAAKAAAAEAAAACAAAAAAQAgAAAAAAAAQgAA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Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6vTI7ugYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6J8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P88R+H/ND3B/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7uiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6G0+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P86Rdr/Mjy8/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6DA+Suj4Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1J5/84QtH/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r4Mju7MgAAAAAAAAAAAAAAAAAAAAAAAAAA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EcLt/xHC7f8Rwu3/Fa7l/zI5pf8zMzX/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjVj/ypYxf8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/K1XE/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zM8vyk+SuhgPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/yGV6/8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8dkNr/Mjqt/zI0Sf8zMzP/MzMz/zMzM/8zMzP/MzM2/zI4i/8qWcX/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8pXcf/MjeF/zMzNf8zMzP/MzMz/zMzM/8zMzP/MjRM/zI6sP8ejNj/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/E7fo/zE+u/8yO7r/Mju6/zI7uv8yO7r/Mju6/zM8v/84QtJhPkrojz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8yaOn/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcHs/ydlyv8yOrT/Mjd9/zI1V/8yNFD/MjZp/zI5ov8vRL3/Fqzl/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Fa7l/y9Gvv8yOaD/MjZo/zI0UP8yNVj/Mjd//zI6tf8nZcn/EcHs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yCB1P8yO7r/Mju6/zI7uv8yO7r/Mju6/zU+xv89SOT/PEjijz5K6Lc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUro/xay7P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rv+z/InvS/zBAvP8yO7r/Mju6/zI7uv8pXcf/Fa7l/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8VruX/KV/H/zI7uv8yO7r/Mju6/zBAvP8ietL/Eb7r/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xG/7P8uSsD/Mju6/zI7uv8yO7r/Mju6/zdBzv89Sef/Pkro/z1J5rc+SujXPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8nhur/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8SvOr/GaDg/xqa3v8Vseb/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Vseb/Gpre/xmf4P8Su+r/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8bltz/Mju6/zI7uv8yO7r/Mju8/zpF2P8+Suj/Pkro/z5K6P8+SujXPkro7j5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/N1ro/xHB7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/KV3H/zI7uv8yO7r/Mz3B/zxH4P8+Suj/Pkro/z5K6P8+Suj/Pkro7j5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8bpev/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Fqvk/zI7uv8yO7r/NT/I/z1J5f8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/LHjp/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yRxzv8yO7r/OELS/z1J5/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zlX6P8Rwez/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Ervq/xeo4/8XqOP/F6jj/xeo4/8XqOP/F6jj/xeo4/8XqOP/Fq3l/xHC7f8Ttuj/F6jj/xeo4/8XqOP/F6jj/xeo4/8XqOP/F6jj/xeo4/8XqOP/F6jj/xeo4/8VsOb/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHB7P8vS8L/Okbb/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/LHjq/xqo6/8Zq+z/Gavs/xmr7P8Yruz/EcLt/xeo4/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/ytUw/8Rwu3/H4fW/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/JW7N/xHC7f8VsOb/F6jj/xeo4/8XqOP/F6jj/xeo4/8XqeX/Gavs/xqo6/8pdN//PEji/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujuPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OFno/xHC7f8XqOP/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8rVMP/EcLt/x+H1v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/x+I1/8Rwu3/K1PD/zI7uv8yO7r/Mju6/zI7uv8zPL//O0ff/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujuPkro1z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zlU6P8Rwu3/Fa/m/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/K1TD/xHC7f8fh9b/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8Wq+T/FLTn/zE8uv8yO7r/Mju6/zI7uv80PcL/PEjj/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro1z5K6Lc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P89S+j/EcDs/xS06P8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/ytUw/8Rwu3/H4fW/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8oY8n/EcLt/yGA1P8yO7r/Mju6/zI7uv81P8f/PUnm/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Lc+SuiPPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/xaz7P8Svev/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8rVMP/EcLt/x+H1v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8xO7r/F6jj/xK96/8uR77/Mju6/zI7uv83Qc7/PUnn/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuiPPkroYD5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8enuv/EcLt/zBCvP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/K1TD/xHC7f8fh9b/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/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Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Pc+SugYAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuiVPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/O1Ho/ztR6P87Uej/O1Ho/ztR6P89Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuiVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroGT5K6PM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujzPkroGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+Suh3Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkrodwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroBT5K6NM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro0z5K6AUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugwPkro+D5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro+D5K6DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6G0+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6G0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkronz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6J8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6AY+Sui7Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Ls+SugGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroCj5K6Mg+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Mg+SugKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugKPkrouz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Ls+SugKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6AY+SuigPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6J8+SugGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6G0+Suj4Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro+D5K6G0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroMD5K6NM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro0z5K6DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugFPkrodz5K6PM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujzPkrodz5K6AUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugZPkrolT5K6Pc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Pc+SuiVPkroGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugYPkrogT5K6OU+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro5T5K6IE+SugYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugDPkroRz5K6Jo+SujlPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6OU+SuiaPkroRz5K6AMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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EMHs/hDB7P4Rwu3/EMHs/huV3P4yOZ3/MjRN/jMzM/8yMzj+MjVl/i9Dtv8Vseb+EMHs/hHC7f8Qwez+EMHs/hen4v8xO7r+MTq5/jI7uv8xOrn+NT7F/jpG3Jo+SujEPUnn/j1J5/4+Suj/PUnn/j1J5/40Yun/EcHs/hDB7P4Rwu3/EMHs/hHC7f8XpeL+LFHC/jI6s/4yOq//L0O8/h6L2P4Rwez/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hHB7P4ejNj/L0S8/jI6r/8yOrP+LFDC/hil4v8Qwez+EMHs/hHC7f8Qwez+EMHs/iVuzf8xOrn+MTq5/jI7uv83Qc7+PUnm/j1J5sQ+SujkPkro/z5K6P8+Suj/Pkro/z5K6P89S+j/GKzs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcHs/xas5P8XpuL/Er3r/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Eb7r/xem4v8Wq+T/EcHs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/E7bo/zBAvP8yO7r/Mju8/zlE2P8+Suj/Pkro/z5K6OQ+Suj5PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/KYHq/hDB7P4Rwu3/EMHs/hHC7f8Qwez+EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hHC7f8Qwez+EMHs/hHC7f8Qwez+EMHs/hHC7f8Qwez+IILV/jI7uv8zPcD+O0ff/j5K6P89Sef+PUnn/j1J5/k+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/OVfo/hK/7P4Rwu3/EMHs/hHC7f8Qwez+EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hHC7f8Qwez+EMHs/hHC7f8Qwez+EMHs/hHC7f8Rv+v+LUzA/jU/x/89SOT+PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/xul6/8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xyR2v8djdn/HY3Z/x2N2f8djdn/HY3Z/xyU2/8Rwu3/G5bc/x2N2f8djdn/HY3Z/x2N2f8djdn/HY3Z/x2N2f8djdn/FLTn/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8ZoeH/OELR/z1J5/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj5PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/jpT6P4uc+n/LXXp/i116f8jj+r+EMHs/i5Jv/4yO7r/MTq5/jE6uf4yO7r/MTq5/i1Owf4Rwu3/LFLC/jE6uf4yO7r/MTq5/jE6uf4yO7r/MTq5/jE6uf4xO7r/Fa7l/h2Q2v8ma8z+JmvM/iZrzP8mbM7+LHPl/i5z6f85UeT+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j1J5/k+SujkPUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P8vcOn+EMHs/i1Nwf4yO7r/MTq5/jE6uf4yO7r/MTq5/i1Owf4Rwu3/LFLC/jE6uf4yO7r/MTq5/jE6uf4yO7r/MTq5/jE6uf4uSb//Eb/s/ipYxf8xOrn+MTq5/jM8vv87R9/+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j1J5+Q+SujEPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8zZun/EcLt/ytTw/8yO7r/Mju6/zI7uv8yO7r/Mju6/y1Owf8Rwu3/LFLC/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8ghNX/F6nj/zE8uv8yO7r/ND7D/zxI4/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6MQ+SuiaPUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P85Vuj+EcHs/ildx/4yO7r/MTq5/jE6uf4yO7r/MTq5/i1Owf4Rwu3/LFLC/jE6uf4yO7r/MTq5/jE6uf4yO7r/MTq5/i5Hvv4SvOr/JmvM/jI7uv81P8j+PUnl/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j1J55o+SuhlPUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89S+j+FrLs/iVtzf4yO7r/MTq5/jE6uf4yO7r/MTq5/i1Owf4Rwu3/LFLC/jE6uf4yO7r/MTq5/jE6uf4yO7r/MTq5/h+I1/4WquT/MT27/jdBzv89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j1J52U+SugkPkro/T5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/I4/q/x2O2f8yO7r/Mju6/zI7uv8yO7r/Mju6/y1Owf8Rwu3/LFLC/zI7uv8yO7r/Mju6/zI7uv8yO7r/K1XD/xG+6/8oYsn/OUPV/z5J6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/T5K6CQ+SugCPUnn0j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+Nl7o/hO46v4vRr7/MTq5/jE6uf4yO7r/MTq5/i1Owf4Rwu3/LFLC/jE6uf4yO7r/MTq5/jE6uf4vRr7/Fqzk/h6O3P46Rdr/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn0j1J5wIAAAAAPkroez5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/yaH6v8aneD/L0a+/zI7uv8yO7r/Mju6/y1Owf8Rwu3/LFLC/zI7uv8yO7r/MTu6/ylfx/8VruX/HJvk/zpL4f8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroewAAAAAAAAAAPUnnGz1J5/Y+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1K5/4og+r/E7jr/hWv5v4Vr+X/Fa/l/hWx5v4Rwu3/FLLn/hep4/4XpuL/FLXo/ha07P4pf+r/PUzo/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef2PUnnGwAAAAAAAAAAAAAAAD1J558+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/OlPo/i5y6f4nher/JYvq/iWL6v4li+r/Jonq/iiD6v4tdun/NGLp/j1M6P4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89SeeeAAAAAAAAAAAAAAAAAAAAAD5K6CE+Suj4Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Pg+SughAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuiFPUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6IUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugLPUnn1j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn1j5K6AsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroMz5K6PU+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj1PkroMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J510+Suj9PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P09SeddAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+Suh4PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6HgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugBPkroeD5K6P0+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj9PkroeD5K6AEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J510+Suj1PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6PU9SeddAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuiTAAAAAAAAAAAAAAAAAAAAAD5K6Aw+SujYPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro2D5K6AwAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Ck+SujuPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6O4+SugpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Dc+SujuPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujuPkroNwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Ck+SujYPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro2D5K6CkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Aw+SuiTPkro/D5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/D5K6JM+SugMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugrPkrooz5K6Pg+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro+D5K6KM+SugrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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' + } + + TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) + + end) + +end + +-- Create Blips +Citizen.CreateThread(function() + + local blip = AddBlipForCoord(Config.Zones.ShopEntering.Pos.x, Config.Zones.ShopEntering.Pos.y, Config.Zones.ShopEntering.Pos.z) + + SetBlipSprite (blip, 326) + SetBlipDisplay(blip, 4) + SetBlipScale (blip, 1.0) + SetBlipAsShortRange(blip, true) + + BeginTextCommandSetBlipName("STRING") + AddTextComponentString("Concessionnaire") + EndTextCommandSetBlipName(blip) + +end) + +-- Display markers +Citizen.CreateThread(function() + while true do + + Wait(0) + + local coords = GetEntityCoords(GetPlayerPed(-1)) + + for k,v in pairs(Config.Zones) do + if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) + end + end + + end +end) + +-- Enter / Exit marker events +Citizen.CreateThread(function() + while true do + + Wait(0) + + local coords = GetEntityCoords(GetPlayerPed(-1)) + local isInMarker = false + local currentZone = nil + + for k,v in pairs(Config.Zones) do + if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then + isInMarker = true + currentZone = k + end + end + + if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then + HasAlreadyEnteredMarker = true + LastZone = currentZone + TriggerEvent('esx_vehicleshop:hasEnteredMarker', currentZone) + end + + if not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent('esx_vehicleshop:hasExitedMarker', LastZone) + end + + end +end) + +-- Key controls +Citizen.CreateThread(function() + while true do + + Citizen.Wait(0) + + if CurrentAction ~= nil then + + SetTextComponentFormat('STRING') + AddTextComponentString(CurrentActionMsg) + DisplayHelpTextFromStringLabel(0, 0, 1, -1) + + if IsControlPressed(0, Keys['E']) and (GetGameTimer() - GUI.Time) > 300 then + + if CurrentAction == 'shop_menu' then + OpenShopMenu() + end + + if CurrentAction == 'reseller_menu' then + OpenResellerMenu() + end + + if CurrentAction == 'give_back_vehicle' then + + ESX.TriggerServerCallback('esx_vehicleshop:giveBackVehicle', function(isRentedVehicle) + + if isRentedVehicle then + DeleteVehicle(CurrentActionData.vehicle) + ESX.ShowNotification('Véhicule ~g~rendu~s~ au concessionnaire') + else + ESX.ShowNotification('Ce n\'est pas un ~r~véhicule de location~s~') + end + + end, GetVehicleNumberPlateText(CurrentActionData.vehicle)) + + end + + if CurrentAction == 'resell_vehicle' then + + ESX.TriggerServerCallback('esx_vehicleshop:resellVehicle', function(isOwnedVehicle) + + if isOwnedVehicle then + DeleteVehicle(CurrentActionData.vehicle) + ESX.ShowNotification('Véhicule ~g~vendu~s~') + else + ESX.ShowNotification('Ce véhicule ne vous appartient pas') + end + + end, GetVehicleNumberPlateText(CurrentActionData.vehicle), CurrentActionData.price) + + end + + if CurrentAction == 'boss_actions_menu' then + OpenBossActionsMenu() + end + + CurrentAction = nil + GUI.Time = GetGameTimer() + + end + + end + + end +end) + +-- Load IPLS +Citizen.CreateThread(function() + RemoveIpl('v_carshowroom') + RemoveIpl('shutter_open') + RemoveIpl('shutter_closed') + RemoveIpl('shr_int') + RemoveIpl('csr_inMission') + RequestIpl('v_carshowroom') + RequestIpl('shr_int') + RequestIpl('shutter_closed') +end) \ No newline at end of file diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..5c6f2113 --- /dev/null +++ b/config.lua @@ -0,0 +1,46 @@ +Config = {} +Config.DrawDistance = 100.0 +Config.MarkerColor = {r = 120, g = 120, b = 240} +Config.EnablePlayerManagement = false -- If set to true, you need esx_billing and esx_society +Config.EnablePvCommand = true +Config.ResellPercentage = 50 + +Config.Zones = { + + ShopEntering = { + Pos = {x = -33.777, y = -1102.021, z = 25.422}, + Size = {x = 1.5, y = 1.5, z = 1.0}, + Type = 1 + }, + + ShopInside = { + Pos = {x = -47.570, y = -1097.221, z = 25.422}, + Size = {x = 1.5, y = 1.5, z = 1.0}, + Type = -1 + }, + + ShopOutside = { + Pos = {x = -28.637, y = -1085.691, z = 25.565}, + Size = {x = 1.5, y = 1.5, z = 1.0}, + Type = -1 + }, + + BossActions = { + Pos = {x = -32.106, y = -1110.377, z = 25.422}, + Size = {x = 1.5, y = 1.5, z = 1.0}, + Type = -1 + }, + + GiveBackVehicle = { + Pos = {x = -18.227, y = -1078.558, z = 25.675}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Type = (Config.EnablePlayerManagement and 1 or -1) + }, + + ResellVehicle = { + Pos = {x = -44.630, y = -1080.738, z = 25.683}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Type = 1 + }, + +} \ No newline at end of file diff --git a/esx_vehicleshop_full.sql b/esx_vehicleshop_full.sql new file mode 100644 index 00000000..6a4422a0 --- /dev/null +++ b/esx_vehicleshop_full.sql @@ -0,0 +1,14 @@ +INSERT INTO `addon_account` VALUES (name, label, shared) + ('society_cardealer','Concessionnaire',1) +; + +INSERT INTO `jobs` (name, label) VALUES + ('cardealer','Concessionnaire') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('cardealer',0,'recruit','Recrue',10,'{}','{}'), + ('cardealer',1,'novice','Novice',25,'{}','{}'), + ('cardealer',2,'experienced','Experimente',40,'{}','{}'), + ('cardealer',3,'boss','Patron',0,'{}','{}') +; diff --git a/esx_vehicleshop_minimal.sql b/esx_vehicleshop_minimal.sql new file mode 100644 index 00000000..be0b0691 --- /dev/null +++ b/esx_vehicleshop_minimal.sql @@ -0,0 +1,10 @@ +INSERT INTO `jobs` (name, label) VALUES + ('cardealer','Concessionnaire') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('cardealer',0,'recruit','Recrue',10,'{}','{}'), + ('cardealer',1,'novice','Novice',25,'{}','{}'), + ('cardealer',2,'experienced','Experimente',40,'{}','{}'), + ('cardealer',3,'boss','Patron',0,'{}','{}') +; diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..2c31860c --- /dev/null +++ b/server/main.lua @@ -0,0 +1,419 @@ +ESX = nil +local Categories = {} +local Vehicles = {} + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +function RemoveOwnedVehicle(plate) + + MySQL.Async.fetchAll( + 'SELECT * FROM owned_vehicles', + {}, + function(result) + + for i=1, #result, 1 do + + local vehicleProps = json.decode(result[i].vehicle) + + if vehicleProps.plate == plate then + + MySQL.Async.execute( + 'DELETE FROM owned_vehicles WHERE id = @id', + { + ['@id'] = result[i].id + } + ) + + end + + end + + end + ) + +end + +AddEventHandler('onMySQLReady', function() + + Categories = MySQL.Sync.fetchAll('SELECT * FROM vehicle_categories') + local vehicles = MySQL.Sync.fetchAll('SELECT * FROM vehicles') + + for i=1, #vehicles, 1 do + + local vehicle = vehicles[i] + + for j=1, #Categories, 1 do + if Categories[j].name == vehicle.category then + vehicle.categoryLabel = Categories[j].label + end + end + + table.insert(Vehicles, vehicle) + + end + +end) + +RegisterServerEvent('esx_vehicleshop:setVehicleOwned') +AddEventHandler('esx_vehicleshop:setVehicleOwned', function(vehicleProps) + + local _source = source + local xPlayer = ESX.GetPlayerFromId(source) + + MySQL.Async.execute( + 'INSERT INTO owned_vehicles (vehicle, owner) VALUES (@vehicle, @owner)', + { + ['@vehicle'] = json.encode(vehicleProps), + ['@owner'] = xPlayer.identifier + }, + function(rowsChanged) + TriggerClientEvent('esx:showNotification', _source, 'Le véhicule ' .. vehicleProps.plate .. ' vous appartient désormais') + end + ) + +end) + +RegisterServerEvent('esx_vehicleshop:setVehicleOwnedPlayerId') +AddEventHandler('esx_vehicleshop:setVehicleOwnedPlayerId', function(playerId, vehicleProps) + + local xPlayer = ESX.GetPlayerFromId(playerId) + + MySQL.Async.execute( + 'INSERT INTO owned_vehicles (vehicle, owner) VALUES (@vehicle, @owner)', + { + ['@vehicle'] = json.encode(vehicleProps), + ['@owner'] = xPlayer.identifier + }, + function(rowsChanged) + TriggerClientEvent('esx:showNotification', playerId, 'Le véhicule ' .. vehicleProps.plate .. ' vous appartient désormais') + end + ) + +end) + +RegisterServerEvent('esx_vehicleshop:sellVehicle') +AddEventHandler('esx_vehicleshop:sellVehicle', function(vehicle) + + MySQL.Async.fetchAll( + 'SELECT * FROM cardealer_vehicles WHERE vehicle = @vehicle LIMIT 1', + { + ['@vehicle'] = vehicle + }, + function(result) + + local id = result[1].id + local price = result[1].price + + MySQL.Async.execute( + 'DELETE FROM cardealer_vehicles WHERE id = @id', + { + ['@id'] = id + } + ) + + end + ) + +end) + +RegisterServerEvent('esx_vehicleshop:rentVehicle') +AddEventHandler('esx_vehicleshop:rentVehicle', function(vehicle, plate, playerName, basePrice, rentPrice, target) + + local xPlayer = ESX.GetPlayerFromId(target) + + MySQL.Async.fetchAll( + 'SELECT * FROM cardealer_vehicles WHERE vehicle = @vehicle LIMIT 1', + { + ['@vehicle'] = vehicle + }, + function(result) + + local id = result[1].id + local price = result[1].price + local owner = xPlayer.identifier + + MySQL.Async.execute( + 'DELETE FROM cardealer_vehicles WHERE id = @id', + { + ['@id'] = id + } + ) + + 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'] = playerName, + ['@base_price'] = basePrice, + ['@rent_price'] = rentPrice, + ['@owner'] = owner + } + ) + + end + ) + +end) + +RegisterServerEvent('esx_vehicleshop:setVehicleForAllPlayers') +AddEventHandler('esx_vehicleshop:setVehicleForAllPlayers', function(props, x, y, z, radius) + TriggerClientEvent('esx_vehicleshop:setVehicle', -1, props, x, y, z, radius) +end) + +ESX.RegisterServerCallback('esx_vehicleshop:getCategories', function(source, cb) + cb(Categories) +end) + +ESX.RegisterServerCallback('esx_vehicleshop:getVehicles', function(source, cb) + cb(Vehicles) +end) + +ESX.RegisterServerCallback('esx_vehicleshop:buyVehicle', function(source, cb, vehicleModel) + + local xPlayer = ESX.GetPlayerFromId(source) + local vehicleData = nil + + for i=1, #Vehicles, 1 do + if Vehicles[i].model == vehicleModel then + vehicleData = Vehicles[i] + break + end + end + + if xPlayer.get('money') >= vehicleData.price then + xPlayer.removeMoney(vehicleData.price) + cb(true) + else + cb(false) + end + +end) + +ESX.RegisterServerCallback('esx_vehicleshop:buyVehicleSociety', function(source, cb, vehicleModel) + + local vehicleData = nil + + for i=1, #Vehicles, 1 do + if Vehicles[i].model == vehicleModel then + vehicleData = Vehicles[i] + break + end + end + + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_cardealer', function(account) + + if account.money >= vehicleData.price then + + account.removeMoney(vehicleData.price) + + MySQL.Async.execute( + 'INSERT INTO cardealer_vehicles (vehicle, price) VALUES (@vehicle, @price)', + { + ['@vehicle'] = vehicleData.model, + ['@price'] = vehicleData.price + } + ) + + cb(true) + else + cb(false) + end + + end) + +end) + +ESX.RegisterServerCallback('esx_vehicleshop:getPersonnalVehicles', function(source, cb) + + local xPlayer = ESX.GetPlayerFromId(source) + + MySQL.Async.fetchAll( + 'SELECT * FROM owned_vehicles WHERE owner = @owner', + { + ['@owner'] = xPlayer.identifier + }, + function(result) + + local vehicles = {} + + for i=1, #result, 1 do + local vehicleData = json.decode(result[i].vehicle) + table.insert(vehicles, vehicleData) + end + + cb(vehicles) + + end + ) + +end) + +ESX.RegisterServerCallback('esx_vehicleshop:getCommercialVehicles', function(source, cb) + + MySQL.Async.fetchAll( + 'SELECT * FROM cardealer_vehicles ORDER BY vehicle ASC', + {}, + function(result) + + local vehicles = {} + + for i=1, #result, 1 do + table.insert(vehicles, { + name = result[i].vehicle, + price = result[i].price + }) + end + + cb(vehicles) + + end + ) + +end) + +ESX.RegisterServerCallback('esx_vehicleshop:getRentedVehicles', function(source, cb) + + MySQL.Async.fetchAll( + '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 + }) + end + + cb(vehicles) + + end + ) + +end) + +ESX.RegisterServerCallback('esx_vehicleshop:giveBackVehicle', function(source, cb, plate) + + MySQL.Async.fetchAll( + 'SELECT * FROM rented_vehicles WHERE plate = @plate LIMIT 1', + { + ['@plate'] = plate + }, + function(result) + + if #result > 0 then + + local id = result[1].id + local vehicle = result[1].vehicle + local plate = result[1].plate + local basePrice = result[1].base_price + + MySQL.Async.execute( + 'INSERT INTO cardealer_vehicles (vehicle, price) VALUES (@vehicle, @price)', + { + ['@vehicle'] = vehicle, + ['@price'] = basePrice + } + ) + + MySQL.Async.execute( + 'DELETE FROM rented_vehicles WHERE id = @id', + { + ['@id'] = id + } + ) + + RemoveOwnedVehicle(plate) + + cb(true) + + else + cb(false) + end + + end + ) + +end) + +ESX.RegisterServerCallback('esx_vehicleshop:resellVehicle', function(source, cb, plate, price) + + MySQL.Async.fetchAll( + 'SELECT * FROM rented_vehicles WHERE plate = @plate LIMIT 1', + { + ['@plate'] = plate + }, + function(result) + + if #result > 0 then + cb(false) + else + + local xPlayer = ESX.GetPlayerFromId(source) + + MySQL.Async.fetchAll( + 'SELECT * FROM owned_vehicles WHERE owner = @owner', + { + ['@owner'] = xPlayer.identifier + }, + function(result) + + local found = false + + for i=1, #result, 1 do + + local vehicleProps = json.decode(result[i].vehicle) + + if vehicleProps.plate == plate then + found = true + break + end + + end + + if found then + + xPlayer.addMoney(price) + RemoveOwnedVehicle(plate) + + cb(true) + + else + cb(false) + end + + end + ) + + end + end + ) + +end) + +TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) + + local xPlayer = ESX.GetPlayerFromId(source) + local xPlayers = ESX.GetPlayers() + + if phoneNumber == 'cardealer' then + for k, v in pairs(xPlayers) do + if v.job.name == 'cardealer' then + TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'player') + end + end + end + +end) + +if Config.EnablePvCommand then + + TriggerEvent('es:addCommand', 'pv', function(source, args, user) + TriggerClientEvent('esx_vehicleshop:openPersonnalVehicleMenu', source) + end, {help = 'Sortir un véhicule personnel'}) + +end \ No newline at end of file diff --git a/stream/v_15_shrm_glass1.ydr b/stream/v_15_shrm_glass1.ydr new file mode 100644 index 0000000000000000000000000000000000000000..506aeed9e4904dc54441a5227d6e8d0aa5bc9dfd GIT binary patch literal 878 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%0A$<{Y6Ed^Kjs2^yn4*|7OiK#dZr`Ve+m!2s5E$F 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 I4#*V#158wB$N&HU literal 0 HcmV?d00001 diff --git a/stream/v_int_15.ytyp b/stream/v_int_15.ytyp new file mode 100644 index 0000000000000000000000000000000000000000..a78a172b6b1a1974725f9d3101abd0f86b762096 GIT binary patch literal 11886 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%0A_3vgv zh_|nuBcM;_PCjCj%Q9X8ye)5%CV$Pa7m`%gPP%0`cqbZQr-}u30)?7NhHG(BQ&)=_ zHCumbu_!pBT9A?L#M<{ba0p8?ss$qy{L2e}qx+XsoL0j(y!H1piGzU2LGNMY;4#>S zw*{t_s33(Q9m-*}cKZT>@lLms-KLK`rgV9;LGu}(HcJqD@J>I(enA}ft=Bc2Ckaed zA-_o;Hk06B_Lbo{!t2 zW@bKmLg9tjO5*of?%AG(GZXD9N?i#L%y072Y)lZ}Uw1tmG{KwP=Z$x8{g*ODmsMSD*tePnKR7b{1PUciQ<#f zw|@h9O9!i5DUU*tA_IA9E}ch^esF@Y`@Wl`{J>1OS683%rzLkY_=#8_w~LjRc#p5( zf1vAEb~96V$T_V@R(YGDEoI=4#dp3r^Z9gS z#EVsNz-rz_q2~tn5G$;euDw_Ery8eV70PszqeQ=b|I^in=Tm2(CRH*BRgL+yPwXWW z?pP1L_-YP!YmkF(c2}N>>8jA*j>TiJ8(qc2ej1c}wB7;r^k$pF`5;X7=iCr;g*a68 z2|ZtHWA@2_R}FrQKa`ypae-C{?FXv4Jz;S49Fu93w{TCQojem^}A zB6(6EL)_9{v&eDe^zD^-!vTpTY5143J?AY(6fXW+VYFR@f~woA-~-GlH1pU|+H^Wf zDbWqV1Vv4A&-MNBEPha9mr~(=lK3v7@TzOh1&CUFzs}OkY?J_O^%Q3S`}f!-G~x@J z_0z#mxh}aj<=;3AxVoPfv}4%9eY$i?a|GyrUH^)aSy>i+EYjel|4r6*ATh*`=@Nr^Vc?NjRb3!*3bD xnZ4Act##5uSx^$40zYX`a7=Y!)f!|mt%1X8`MzzejJH^M$N%jIKrR5({|nrXd~E;# literal 0 HcmV?d00001 From 219e4e62f0d002e1b64069746d5edd3f41353d9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 12:34:33 +0200 Subject: [PATCH 0109/3224] Update SQL files --- esx_vehicleshop_full.sql | 276 ++++++++++++++++++++++++++++++++++++ esx_vehicleshop_minimal.sql | 276 ++++++++++++++++++++++++++++++++++++ 2 files changed, 552 insertions(+) diff --git a/esx_vehicleshop_full.sql b/esx_vehicleshop_full.sql index 6a4422a0..8a53c449 100644 --- a/esx_vehicleshop_full.sql +++ b/esx_vehicleshop_full.sql @@ -12,3 +12,279 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ('cardealer',2,'experienced','Experimente',40,'{}','{}'), ('cardealer',3,'boss','Patron',0,'{}','{}') ; + +CREATE TABLE `cardealer_vehicles` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `vehicle` varchar(255) NOT NULL, + `price` int(11) NOT NULL, + PRIMARY KEY (`id`) +); + +CREATE TABLE `owned_vehicles` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `vehicle` longtext NOT NULL, + `owner` varchar(60) NOT NULL, + + PRIMARY KEY (`id`) +); + +CREATE TABLE `rented_vehicles` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `vehicle` varchar(60) NOT NULL, + `plate` varchar(10) NOT NULL, + `player_name` varchar(255) NOT NULL, + `base_price` int(11) NOT NULL, + `rent_price` int(11) NOT NULL, + `owner` varchar(255) NOT NULL, + + PRIMARY KEY (`id`) +); + +CREATE TABLE `vehicle_categories` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(60) NOT NULL, + `label` varchar(60) NOT NULL, + + PRIMARY KEY (`id`) +); + +INSERT INTO `vehicle_categories` VALUES + (1,'compacts','Compacts'), + (2,'coupes','Coupés'), + (3,'sedans','Sedans'), + (4,'sports','Sports'), + (5,'sportsclassics','Sports Classics'), + (6,'super','Super'), + (7,'muscle','Muscle'), + (8,'offroad','Off Road'), + (9,'suvs','SUVs'), + (10,'vans','Vans'), + (11,'sedans','Sedans'), + (12,'motorcycles','Motos') +; + +CREATE TABLE `vehicles` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(60) NOT NULL, + `model` varchar(60) NOT NULL, + `price` int(11) NOT NULL, + `category` varchar(60) DEFAULT NULL, + PRIMARY KEY (`id`) +); + +INSERT INTO `vehicles` (name, model, price, category) VALUES + ('Blade','blade',15000,'muscle'), + ('Buccaneer','buccaneer',18000,'muscle'), + ('Buccaneer Rider','buccaneer2',24000,'muscle'), + ('Chino','chino',15000,'muscle'), + ('Chino Luxe','chino2',19000,'muscle'), + ('Coquette BlackFin','coquette3',55000,'muscle'), + ('Dominator','dominator',35000,'muscle'), + ('Dukes','dukes',28000,'muscle'), + ('Gauntlet','gauntlet',30000,'muscle'), + ('Hotknife','hotknife',125000,'muscle'), + ('Faction','faction',20000,'muscle'), + ('Faction Rider','faction2',30000,'muscle'), + ('Faction XL','faction3',40000,'muscle'), + ('Nightshade','nightshade',65000,'muscle'), + ('Phoenix','phoenix',12500,'muscle'), + ('Picador','picador',18000,'muscle'), + ('Sabre Turbo','sabregt',20000,'muscle'), + ('Sabre GT','sabregt2',25000,'muscle'), + ('Slam Van','slamvan3',11500,'muscle'), + ('Tampa','tampa',16000,'muscle'), + ('Virgo','virgo',14000,'muscle'), + ('Vigero','vigero',12500,'muscle'), + ('Voodoo','voodoo',7200,'muscle'), + ('Blista','blista',8000,'compacts'), + ('Brioso R/A','brioso',18000,'compacts'), + ('Issi','issi2',10000,'compacts'), + ('Panto','panto',10000,'compacts'), + ('Prairie','prairie',12000,'compacts'), + ('Bison','bison',45000,'vans'), + ('Bobcat XL','bobcatxl',32000,'vans'), + ('Burrito','burrito3',19000,'vans'), + ('Burrito','gburrito2',29000,'vans'), + ('Camper','camper',42000,'vans'), + ('Gang Burrito','gburrito',45000,'vans'), + ('Journey','journey',6500,'vans'), + ('Minivan','minivan',13000,'vans'), + ('Moonbeam','moonbeam',18000,'vans'), + ('Moonbeam Rider','moonbeam2',35000,'vans'), + ('Paradise','paradise',19000,'vans'), + ('Rumpo','rumpo',15000,'vans'), + ('Rumpo Trail','rumpo3',19500,'vans'), + ('Surfer','surfer',12000,'vans'), + ('Youga','youga',10800,'vans'), + ('Youga Luxuary','youga2',14500,'vans'), + ('Asea','asea',5500,'sedans'), + ('Cognoscenti','cognoscenti',55000,'sedans'), + ('Emperor','emperor',8500,'sedans'), + ('Fugitive','fugitive',12000,'sedans'), + ('Glendale','glendale',6500,'sedans'), + ('Intruder','intruder',7500,'sedans'), + ('Premier','premier',8000,'sedans'), + ('Primo Custom','primo2',14000,'sedans'), + ('Regina','regina',5000,'sedans'), + ('Schafter','schafter2',25000,'sedans'), + ('Stretch','stretch',90000,'sedans'), + ('Super Diamond','superd',130000,'sedans'), + ('Tailgater','tailgater',30000,'sedans'), + ('Warrener','warrener',4000,'sedans'), + ('Washington','washington',9000,'sedans'), + ('Baller','baller2',40000,'suvs'), + ('Baller Sport','baller3',60000,'suvs'), + ('Cavalcade','cavalcade2',55000,'suvs'), + ('Contender','contender',70000,'suvs'), + ('Dubsta','dubsta',45000,'suvs'), + ('Dubsta Luxuary','dubsta2',60000,'suvs'), + ('Fhantom','fq2',17000,'suvs'), + ('Grabger','granger',50000,'suvs'), + ('Gresley','gresley',47500,'suvs'), + ('Huntley S','huntley',40000,'suvs'), + ('Landstalker','landstalker',35000,'suvs'), + ('Mesa','mesa',16000,'suvs'), + ('Mesa Trail','mesa3',40000,'suvs'), + ('Patriot','patriot',55000,'suvs'), + ('Radius','radi',29000,'suvs'), + ('Rocoto','rocoto',45000,'suvs'), + ('Seminole','seminole',25000,'suvs'), + ('XLS','xls',32000,'suvs'), + ('Btype','btype',62000,'sportsclassics'), + ('Btype Luxe','btype3',85000,'sportsclassics'), + ('Btype Hotroad','btype2',155000,'sportsclassics'), + ('Casco','casco',30000,'sportsclassics'), + ('Coquette Classic','coquette2',40000,'sportsclassics'), + ('Manana','manana',12800,'sportsclassics'), + ('Monroe','monroe',55000,'sportsclassics'), + ('Pigalle','pigalle',20000,'sportsclassics'), + ('Stinger','stinger',80000,'sportsclassics'), + ('Stinger GT','stingergt',75000,'sportsclassics'), + ('Stirling GT','feltzer3',65000,'sportsclassics'), + ('Z-Type','ztype',220000,'sportsclassics'), + ('Bifta','bifta',12000,'offroad'), + ('Bf Injection','bfinjection',16000,'offroad'), + ('Blazer','blazer',6500,'offroad'), + ('Blazer Sport','blazer4',8500,'offroad'), + ('Brawler','brawler',45000,'offroad'), + ('Bubsta 6x6','dubsta3',120000,'offroad'), + ('Dune Buggy','dune',8000,'offroad'), + ('Guardian','guardian',45000,'offroad'), + ('Rebel','rebel2',35000,'offroad'), + ('Sandking','sandking',55000,'offroad'), + ('The Liberator','monster',210000,'offroad'), + ('Trophy Truck','trophytruck',60000,'offroad'), + ('Trophy Truck Limited','trophytruck2',80000,'offroad'), + ('Cognoscenti Cabrio','cogcabrio',55000,'coupes'), + ('Exemplar','exemplar',32000,'coupes'), + ('F620','f620',40000,'coupes'), + ('Felon','felon',42000,'coupes'), + ('Felon GT','felon2',55000,'coupes'), + ('Jackal','jackal',38000,'coupes'), + ('Oracle XS','oracle2',35000,'coupes'), + ('Sentinel','sentinel',32000,'coupes'), + ('Sentinel XS','sentinel2',40000,'coupes'), + ('Windsor','windsor',95000,'coupes'), + ('Windsor Drop','windsor2',125000,'coupes'), + ('Zion','zion',36000,'coupes'), + ('Zion Cabrio','zion2',45000,'coupes'), + ('9F','ninef',65000,'sports'), + ('9F Cabrio','ninef2',80000,'sports'), + ('Alpha','alpha',60000,'sports'), + ('Banshee','banshee',70000,'sports'), + ('Bestia GTS','bestiagts',55000,'sports'), + ('Buffalo','buffalo',12000,'sports'), + ('Buffalo S','buffalo2',20000,'sports'), + ('Carbonizzare','carbonizzare',75000,'sports'), + ('Comet','comet2',65000,'sports'), + ('Coquette','coquette',65000,'sports'), + ('Drift Tampa','tampa2',80000,'sports'), + ('Elegy','elegy2',38500,'sports'), + ('Feltzer','feltzer2',55000,'sports'), + ('Furore GT','furoregt',45000,'sports'), + ('Fusilade','fusilade',40000,'sports'), + ('Jester','jester',65000,'sports'), + ('Jester(Racecar)','jester2',135000,'sports'), + ('Khamelion','khamelion',38000,'sports'), + ('Kuruma','kuruma',30000,'sports'), + ('Lynx','lynx',40000,'sports'), + ('Mamba','mamba',70000,'sports'), + ('Massacro','massacro',65000,'sports'), + ('Massacro(Racecar)','massacro2',130000,'sports'), + ('Omnis','omnis',35000,'sports'), + ('Penumbra','penumbra',28000,'sports'), + ('Rapid GT','rapidgt',35000,'sports'), + ('Rapid GT Convertible','rapidgt2',45000,'sports'), + ('Schafter V12','schafter3',50000,'sports'), + ('Seven 70','seven70',39500,'sports'), + ('Sultan','sultan',15000,'sports'), + ('Surano','surano',50000,'sports'), + ('Tropos','tropos',40000,'sports'), + ('Verlierer','verlierer2',70000,'sports'), + ('Adder','adder',900000,'super'), + ('Banshee 900R','banshee2',255000,'super'), + ('Bullet','bullet',90000,'super'), + ('Cheetah','cheetah',375000,'super'), + ('Entity XF','entityxf',425000,'super'), + ('ETR1','sheava',220000,'super'), + ('FMJ','fmj',185000,'super'), + ('Infernus','infernus',180000,'super'), + ('Osiris','osiris',160000,'super'), + ('Pfister','pfister811',85000,'super'), + ('RE-7B','le7b',325000,'super'), + ('Reaper','reaper',150000,'super'), + ('Sultan RS','sultanrs',65000,'super'), + ('T20','t20',300000,'super'), + ('Turismo R','turismor',350000,'super'), + ('Tyrus','tyrus',600000,'super'), + ('Vacca','vacca',120000,'super'), + ('Voltic','voltic',90000,'super'), + ('X80 Proto','prototipo',2500000,'super'), + ('Zentorno','zentorno',1500000,'super'), + ('Akuma','AKUMA',7500,'motorcycles'), + ('Avarus','avarus',18000,'motorcycles'), + ('Bagger','bagger',13500,'motorcycles'), + ('Bati 801','bati',12000,'motorcycles'), + ('Bati 801RR','bati2',19000,'motorcycles'), + ('BF400','bf400',6500,'motorcycles'), + ('BMX (velo)','bmx',160,'motorcycles'), + ('Carbon RS','carbonrs',18000,'motorcycles'), + ('Chimera','chimera',38000,'motorcycles'), + ('Cliffhanger','cliffhanger',9500,'motorcycles'), + ('Cruiser (velo)','cruiser',510,'motorcycles'), + ('Daemon','daemon',11500,'motorcycles'), + ('Daemon High','daemon2',13500,'motorcycles'), + ('Defiler','defiler',9800,'motorcycles'), + ('Double T','double',28000,'motorcycles'), + ('Enduro','enduro',5500,'motorcycles'), + ('Esskey','esskey',4200,'motorcycles'), + ('Faggio','faggio',1900,'motorcycles'), + ('Vespa','faggio2',2800,'motorcycles'), + ('Fixter (velo)','fixter',225,'motorcycles'), + ('Gargoyle','gargoyle',16500,'motorcycles'), + ('Hakuchou','hakuchou',31000,'motorcycles'), + ('Hakuchou Sport','hakuchou2',55000,'motorcycles'), + ('Hexer','hexer',12000,'motorcycles'), + ('Innovation','innovation',23500,'motorcycles'), + ('Manchez','manchez',5300,'motorcycles'), + ('Nemesis','nemesis',5800,'motorcycles'), + ('Nightblade','nightblade',35000,'motorcycles'), + ('PCJ-600','pcj',6200,'motorcycles'), + ('Ruffian','ruffian',6800,'motorcycles'), + ('Sanchez','sanchez',5300,'motorcycles'), + ('Sanchez Sport','sanchez2',5300,'motorcycles'), + ('Sanctus','sanctus',25000,'motorcycles'), + ('Scorcher (velo)','scorcher',280,'motorcycles'), + ('Sovereign','sovereign',22000,'motorcycles'), + ('Shotaro Concept','shotaro',320000,'motorcycles'), + ('Thrust','thrust',24000,'motorcycles'), + ('Tri bike (velo)','tribike3',520,'motorcycles'), + ('Vader','vader',7200,'motorcycles'), + ('Vortex','vortex',9800,'motorcycles'), + ('Woflsbane','wolfsbane',9000,'motorcycles'), + ('Zombie','zombiea',9500,'motorcycles'), + ('Zombie Luxuary','zombieb',12000,'motorcycles') +; \ No newline at end of file diff --git a/esx_vehicleshop_minimal.sql b/esx_vehicleshop_minimal.sql index be0b0691..f6d189a0 100644 --- a/esx_vehicleshop_minimal.sql +++ b/esx_vehicleshop_minimal.sql @@ -8,3 +8,279 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ('cardealer',2,'experienced','Experimente',40,'{}','{}'), ('cardealer',3,'boss','Patron',0,'{}','{}') ; + +CREATE TABLE `cardealer_vehicles` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `vehicle` varchar(255) NOT NULL, + `price` int(11) NOT NULL, + PRIMARY KEY (`id`) +); + +CREATE TABLE `owned_vehicles` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `vehicle` longtext NOT NULL, + `owner` varchar(60) NOT NULL, + + PRIMARY KEY (`id`) +); + +CREATE TABLE `rented_vehicles` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `vehicle` varchar(60) NOT NULL, + `plate` varchar(10) NOT NULL, + `player_name` varchar(255) NOT NULL, + `base_price` int(11) NOT NULL, + `rent_price` int(11) NOT NULL, + `owner` varchar(255) NOT NULL, + + PRIMARY KEY (`id`) +); + +CREATE TABLE `vehicle_categories` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(60) NOT NULL, + `label` varchar(60) NOT NULL, + + PRIMARY KEY (`id`) +); + +INSERT INTO `vehicle_categories` VALUES + (1,'compacts','Compacts'), + (2,'coupes','Coupés'), + (3,'sedans','Sedans'), + (4,'sports','Sports'), + (5,'sportsclassics','Sports Classics'), + (6,'super','Super'), + (7,'muscle','Muscle'), + (8,'offroad','Off Road'), + (9,'suvs','SUVs'), + (10,'vans','Vans'), + (11,'sedans','Sedans'), + (12,'motorcycles','Motos') +; + +CREATE TABLE `vehicles` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(60) NOT NULL, + `model` varchar(60) NOT NULL, + `price` int(11) NOT NULL, + `category` varchar(60) DEFAULT NULL, + PRIMARY KEY (`id`) +); + +INSERT INTO `vehicles` (name, model, price, category) VALUES + ('Blade','blade',15000,'muscle'), + ('Buccaneer','buccaneer',18000,'muscle'), + ('Buccaneer Rider','buccaneer2',24000,'muscle'), + ('Chino','chino',15000,'muscle'), + ('Chino Luxe','chino2',19000,'muscle'), + ('Coquette BlackFin','coquette3',55000,'muscle'), + ('Dominator','dominator',35000,'muscle'), + ('Dukes','dukes',28000,'muscle'), + ('Gauntlet','gauntlet',30000,'muscle'), + ('Hotknife','hotknife',125000,'muscle'), + ('Faction','faction',20000,'muscle'), + ('Faction Rider','faction2',30000,'muscle'), + ('Faction XL','faction3',40000,'muscle'), + ('Nightshade','nightshade',65000,'muscle'), + ('Phoenix','phoenix',12500,'muscle'), + ('Picador','picador',18000,'muscle'), + ('Sabre Turbo','sabregt',20000,'muscle'), + ('Sabre GT','sabregt2',25000,'muscle'), + ('Slam Van','slamvan3',11500,'muscle'), + ('Tampa','tampa',16000,'muscle'), + ('Virgo','virgo',14000,'muscle'), + ('Vigero','vigero',12500,'muscle'), + ('Voodoo','voodoo',7200,'muscle'), + ('Blista','blista',8000,'compacts'), + ('Brioso R/A','brioso',18000,'compacts'), + ('Issi','issi2',10000,'compacts'), + ('Panto','panto',10000,'compacts'), + ('Prairie','prairie',12000,'compacts'), + ('Bison','bison',45000,'vans'), + ('Bobcat XL','bobcatxl',32000,'vans'), + ('Burrito','burrito3',19000,'vans'), + ('Burrito','gburrito2',29000,'vans'), + ('Camper','camper',42000,'vans'), + ('Gang Burrito','gburrito',45000,'vans'), + ('Journey','journey',6500,'vans'), + ('Minivan','minivan',13000,'vans'), + ('Moonbeam','moonbeam',18000,'vans'), + ('Moonbeam Rider','moonbeam2',35000,'vans'), + ('Paradise','paradise',19000,'vans'), + ('Rumpo','rumpo',15000,'vans'), + ('Rumpo Trail','rumpo3',19500,'vans'), + ('Surfer','surfer',12000,'vans'), + ('Youga','youga',10800,'vans'), + ('Youga Luxuary','youga2',14500,'vans'), + ('Asea','asea',5500,'sedans'), + ('Cognoscenti','cognoscenti',55000,'sedans'), + ('Emperor','emperor',8500,'sedans'), + ('Fugitive','fugitive',12000,'sedans'), + ('Glendale','glendale',6500,'sedans'), + ('Intruder','intruder',7500,'sedans'), + ('Premier','premier',8000,'sedans'), + ('Primo Custom','primo2',14000,'sedans'), + ('Regina','regina',5000,'sedans'), + ('Schafter','schafter2',25000,'sedans'), + ('Stretch','stretch',90000,'sedans'), + ('Super Diamond','superd',130000,'sedans'), + ('Tailgater','tailgater',30000,'sedans'), + ('Warrener','warrener',4000,'sedans'), + ('Washington','washington',9000,'sedans'), + ('Baller','baller2',40000,'suvs'), + ('Baller Sport','baller3',60000,'suvs'), + ('Cavalcade','cavalcade2',55000,'suvs'), + ('Contender','contender',70000,'suvs'), + ('Dubsta','dubsta',45000,'suvs'), + ('Dubsta Luxuary','dubsta2',60000,'suvs'), + ('Fhantom','fq2',17000,'suvs'), + ('Grabger','granger',50000,'suvs'), + ('Gresley','gresley',47500,'suvs'), + ('Huntley S','huntley',40000,'suvs'), + ('Landstalker','landstalker',35000,'suvs'), + ('Mesa','mesa',16000,'suvs'), + ('Mesa Trail','mesa3',40000,'suvs'), + ('Patriot','patriot',55000,'suvs'), + ('Radius','radi',29000,'suvs'), + ('Rocoto','rocoto',45000,'suvs'), + ('Seminole','seminole',25000,'suvs'), + ('XLS','xls',32000,'suvs'), + ('Btype','btype',62000,'sportsclassics'), + ('Btype Luxe','btype3',85000,'sportsclassics'), + ('Btype Hotroad','btype2',155000,'sportsclassics'), + ('Casco','casco',30000,'sportsclassics'), + ('Coquette Classic','coquette2',40000,'sportsclassics'), + ('Manana','manana',12800,'sportsclassics'), + ('Monroe','monroe',55000,'sportsclassics'), + ('Pigalle','pigalle',20000,'sportsclassics'), + ('Stinger','stinger',80000,'sportsclassics'), + ('Stinger GT','stingergt',75000,'sportsclassics'), + ('Stirling GT','feltzer3',65000,'sportsclassics'), + ('Z-Type','ztype',220000,'sportsclassics'), + ('Bifta','bifta',12000,'offroad'), + ('Bf Injection','bfinjection',16000,'offroad'), + ('Blazer','blazer',6500,'offroad'), + ('Blazer Sport','blazer4',8500,'offroad'), + ('Brawler','brawler',45000,'offroad'), + ('Bubsta 6x6','dubsta3',120000,'offroad'), + ('Dune Buggy','dune',8000,'offroad'), + ('Guardian','guardian',45000,'offroad'), + ('Rebel','rebel2',35000,'offroad'), + ('Sandking','sandking',55000,'offroad'), + ('The Liberator','monster',210000,'offroad'), + ('Trophy Truck','trophytruck',60000,'offroad'), + ('Trophy Truck Limited','trophytruck2',80000,'offroad'), + ('Cognoscenti Cabrio','cogcabrio',55000,'coupes'), + ('Exemplar','exemplar',32000,'coupes'), + ('F620','f620',40000,'coupes'), + ('Felon','felon',42000,'coupes'), + ('Felon GT','felon2',55000,'coupes'), + ('Jackal','jackal',38000,'coupes'), + ('Oracle XS','oracle2',35000,'coupes'), + ('Sentinel','sentinel',32000,'coupes'), + ('Sentinel XS','sentinel2',40000,'coupes'), + ('Windsor','windsor',95000,'coupes'), + ('Windsor Drop','windsor2',125000,'coupes'), + ('Zion','zion',36000,'coupes'), + ('Zion Cabrio','zion2',45000,'coupes'), + ('9F','ninef',65000,'sports'), + ('9F Cabrio','ninef2',80000,'sports'), + ('Alpha','alpha',60000,'sports'), + ('Banshee','banshee',70000,'sports'), + ('Bestia GTS','bestiagts',55000,'sports'), + ('Buffalo','buffalo',12000,'sports'), + ('Buffalo S','buffalo2',20000,'sports'), + ('Carbonizzare','carbonizzare',75000,'sports'), + ('Comet','comet2',65000,'sports'), + ('Coquette','coquette',65000,'sports'), + ('Drift Tampa','tampa2',80000,'sports'), + ('Elegy','elegy2',38500,'sports'), + ('Feltzer','feltzer2',55000,'sports'), + ('Furore GT','furoregt',45000,'sports'), + ('Fusilade','fusilade',40000,'sports'), + ('Jester','jester',65000,'sports'), + ('Jester(Racecar)','jester2',135000,'sports'), + ('Khamelion','khamelion',38000,'sports'), + ('Kuruma','kuruma',30000,'sports'), + ('Lynx','lynx',40000,'sports'), + ('Mamba','mamba',70000,'sports'), + ('Massacro','massacro',65000,'sports'), + ('Massacro(Racecar)','massacro2',130000,'sports'), + ('Omnis','omnis',35000,'sports'), + ('Penumbra','penumbra',28000,'sports'), + ('Rapid GT','rapidgt',35000,'sports'), + ('Rapid GT Convertible','rapidgt2',45000,'sports'), + ('Schafter V12','schafter3',50000,'sports'), + ('Seven 70','seven70',39500,'sports'), + ('Sultan','sultan',15000,'sports'), + ('Surano','surano',50000,'sports'), + ('Tropos','tropos',40000,'sports'), + ('Verlierer','verlierer2',70000,'sports'), + ('Adder','adder',900000,'super'), + ('Banshee 900R','banshee2',255000,'super'), + ('Bullet','bullet',90000,'super'), + ('Cheetah','cheetah',375000,'super'), + ('Entity XF','entityxf',425000,'super'), + ('ETR1','sheava',220000,'super'), + ('FMJ','fmj',185000,'super'), + ('Infernus','infernus',180000,'super'), + ('Osiris','osiris',160000,'super'), + ('Pfister','pfister811',85000,'super'), + ('RE-7B','le7b',325000,'super'), + ('Reaper','reaper',150000,'super'), + ('Sultan RS','sultanrs',65000,'super'), + ('T20','t20',300000,'super'), + ('Turismo R','turismor',350000,'super'), + ('Tyrus','tyrus',600000,'super'), + ('Vacca','vacca',120000,'super'), + ('Voltic','voltic',90000,'super'), + ('X80 Proto','prototipo',2500000,'super'), + ('Zentorno','zentorno',1500000,'super'), + ('Akuma','AKUMA',7500,'motorcycles'), + ('Avarus','avarus',18000,'motorcycles'), + ('Bagger','bagger',13500,'motorcycles'), + ('Bati 801','bati',12000,'motorcycles'), + ('Bati 801RR','bati2',19000,'motorcycles'), + ('BF400','bf400',6500,'motorcycles'), + ('BMX (velo)','bmx',160,'motorcycles'), + ('Carbon RS','carbonrs',18000,'motorcycles'), + ('Chimera','chimera',38000,'motorcycles'), + ('Cliffhanger','cliffhanger',9500,'motorcycles'), + ('Cruiser (velo)','cruiser',510,'motorcycles'), + ('Daemon','daemon',11500,'motorcycles'), + ('Daemon High','daemon2',13500,'motorcycles'), + ('Defiler','defiler',9800,'motorcycles'), + ('Double T','double',28000,'motorcycles'), + ('Enduro','enduro',5500,'motorcycles'), + ('Esskey','esskey',4200,'motorcycles'), + ('Faggio','faggio',1900,'motorcycles'), + ('Vespa','faggio2',2800,'motorcycles'), + ('Fixter (velo)','fixter',225,'motorcycles'), + ('Gargoyle','gargoyle',16500,'motorcycles'), + ('Hakuchou','hakuchou',31000,'motorcycles'), + ('Hakuchou Sport','hakuchou2',55000,'motorcycles'), + ('Hexer','hexer',12000,'motorcycles'), + ('Innovation','innovation',23500,'motorcycles'), + ('Manchez','manchez',5300,'motorcycles'), + ('Nemesis','nemesis',5800,'motorcycles'), + ('Nightblade','nightblade',35000,'motorcycles'), + ('PCJ-600','pcj',6200,'motorcycles'), + ('Ruffian','ruffian',6800,'motorcycles'), + ('Sanchez','sanchez',5300,'motorcycles'), + ('Sanchez Sport','sanchez2',5300,'motorcycles'), + ('Sanctus','sanctus',25000,'motorcycles'), + ('Scorcher (velo)','scorcher',280,'motorcycles'), + ('Sovereign','sovereign',22000,'motorcycles'), + ('Shotaro Concept','shotaro',320000,'motorcycles'), + ('Thrust','thrust',24000,'motorcycles'), + ('Tri bike (velo)','tribike3',520,'motorcycles'), + ('Vader','vader',7200,'motorcycles'), + ('Vortex','vortex',9800,'motorcycles'), + ('Woflsbane','wolfsbane',9000,'motorcycles'), + ('Zombie','zombiea',9500,'motorcycles'), + ('Zombie Luxuary','zombieb',12000,'motorcycles') +; \ No newline at end of file From 70c98e5cfce916f12edc48e91bad1ff232a7f646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 12:36:20 +0200 Subject: [PATCH 0110/3224] Update SQL files --- esx_vehicleshop_full.sql | 26 +++++++++++++------------- esx_vehicleshop_minimal.sql | 26 +++++++++++++------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/esx_vehicleshop_full.sql b/esx_vehicleshop_full.sql index 8a53c449..829ca82f 100644 --- a/esx_vehicleshop_full.sql +++ b/esx_vehicleshop_full.sql @@ -51,19 +51,19 @@ CREATE TABLE `vehicle_categories` ( PRIMARY KEY (`id`) ); -INSERT INTO `vehicle_categories` VALUES - (1,'compacts','Compacts'), - (2,'coupes','Coupés'), - (3,'sedans','Sedans'), - (4,'sports','Sports'), - (5,'sportsclassics','Sports Classics'), - (6,'super','Super'), - (7,'muscle','Muscle'), - (8,'offroad','Off Road'), - (9,'suvs','SUVs'), - (10,'vans','Vans'), - (11,'sedans','Sedans'), - (12,'motorcycles','Motos') +INSERT INTO `vehicle_categories` (name, label) VALUES + ('compacts','Compacts'), + ('coupes','Coupés'), + ('sedans','Sedans'), + ('sports','Sports'), + ('sportsclassics','Sports Classics'), + ('super','Super'), + ('muscle','Muscle'), + ('offroad','Off Road'), + ('suvs','SUVs'), + ('vans','Vans'), + ('sedans','Sedans'), + ('motorcycles','Motos') ; CREATE TABLE `vehicles` ( diff --git a/esx_vehicleshop_minimal.sql b/esx_vehicleshop_minimal.sql index f6d189a0..5f8cdde5 100644 --- a/esx_vehicleshop_minimal.sql +++ b/esx_vehicleshop_minimal.sql @@ -47,19 +47,19 @@ CREATE TABLE `vehicle_categories` ( PRIMARY KEY (`id`) ); -INSERT INTO `vehicle_categories` VALUES - (1,'compacts','Compacts'), - (2,'coupes','Coupés'), - (3,'sedans','Sedans'), - (4,'sports','Sports'), - (5,'sportsclassics','Sports Classics'), - (6,'super','Super'), - (7,'muscle','Muscle'), - (8,'offroad','Off Road'), - (9,'suvs','SUVs'), - (10,'vans','Vans'), - (11,'sedans','Sedans'), - (12,'motorcycles','Motos') +INSERT INTO `vehicle_categories` (name, label) VALUES + ('compacts','Compacts'), + ('coupes','Coupés'), + ('sedans','Sedans'), + ('sports','Sports'), + ('sportsclassics','Sports Classics'), + ('super','Super'), + ('muscle','Muscle'), + ('offroad','Off Road'), + ('suvs','SUVs'), + ('vans','Vans'), + ('sedans','Sedans'), + ('motorcycles','Motos') ; CREATE TABLE `vehicles` ( From 978ffe74f7841b018d43ede00d8aa033d42c5d5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 14:10:31 +0200 Subject: [PATCH 0111/3224] Fix triggerservercallback too early --- client/main.lua | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/client/main.lua b/client/main.lua index 1be6f35f..0da41a9e 100644 --- a/client/main.lua +++ b/client/main.lua @@ -22,6 +22,8 @@ local HasAlreadyEnteredMarker = false local CurrentAction = nil local CurrentActionMsg = '' local CurrentActionData = {} +local FirstSpawn = true +local PlayerLoaded = false function DrawSub(text, time) ClearPrints() @@ -791,16 +793,22 @@ function OpenPlayerInventoryMenu(property) end -local FirstSpawn = true - AddEventHandler('playerSpawned', function() if FirstSpawn then - ESX.TriggerServerCallback('esx_property:getLastProperty', function(propertyName) - if propertyName ~= nil then - EnterProperty(propertyName) + Citizen.CreateThread(function() + + while not PlayerLoaded do + Citizen.Wait(0) end + + ESX.TriggerServerCallback('esx_property:getLastProperty', function(propertyName) + if propertyName ~= nil then + EnterProperty(propertyName) + end + end) + end) FirstSpawn = false @@ -808,6 +816,11 @@ AddEventHandler('playerSpawned', function() end) +RegisterNetEvent('esx:playerLoaded') +AddEventHandler('esx:playerLoaded', function(xPlayer) + PlayerLoaded = true +end) + AddEventHandler('esx_property:getProperties', function(cb) cb(GetProperties()) end) From 7a669782120913f3ca976308c831bcd8ec55eed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 14:20:17 +0200 Subject: [PATCH 0112/3224] Update esx_property.sql --- esx_property.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_property.sql b/esx_property.sql index 19c20782..3902765c 100644 --- a/esx_property.sql +++ b/esx_property.sql @@ -49,7 +49,7 @@ CREATE TABLE `properties` ( INSERT INTO `properties` VALUES (1,'WhispymoundDrive','2677 Whispymound Drive','{\"y\":564.89,\"z\":182.959,\"x\":119.384}','{\"y\":558.667,\"z\":183.297,\"x\":116.392}','{\"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','Milla House','{\"y\":834.47540283203,\"z\":234.92024230957,\"x\":-86.692153930664}','{\"y\":422.84088134766,\"z\":144.90005493164,\"x\":372.70159912109}','{\"y\":420.07595825195,\"z\":145.90487670898,\"x\":373.16149902344}','{\"y\":835.64111328125,\"z\":234.7230072021,\"x\":-90.789779663086}','[]',NULL,1,1,0,'{\"x\":377.349,\"y\":429.422,\"z\":137.3}',1500000), + (2,'NorthConkerAvenue2045','2045 North Conker Avenue','{\"y\":834.47540283203,\"z\":234.92024230957,\"x\":-86.692153930664}','{\"y\":422.84088134766,\"z\":144.90005493164,\"x\":372.70159912109}','{\"y\":420.07595825195,\"z\":145.90487670898,\"x\":373.16149902344}','{\"y\":835.64111328125,\"z\":234.7230072021,\"x\":-90.789779663086}','[]',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}','{\"y\":444.374,\"z\":145.037,\"x\":-212.15144348145}','[]',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), From ec92041090ada3783229c4da42abea00e0de7398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 15:00:25 +0200 Subject: [PATCH 0113/3224] Update esx_property.sql --- esx_property.sql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/esx_property.sql b/esx_property.sql index 3902765c..ed5ff2c5 100644 --- a/esx_property.sql +++ b/esx_property.sql @@ -66,12 +66,12 @@ INSERT INTO `properties` VALUES (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\":211.396}',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 Pèrcant 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 Pèrcant 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 Pèrcant 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), + (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), From b5d70e320109349b27ee53686570a06fc6a0353d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 15:07:15 +0200 Subject: [PATCH 0114/3224] Update esx_property.sql --- esx_property.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_property.sql b/esx_property.sql index ed5ff2c5..5972de29 100644 --- a/esx_property.sql +++ b/esx_property.sql @@ -55,7 +55,7 @@ INSERT INTO `properties` VALUES (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}','{\"y\":448.07,\"z\":96.894,\"x\":-1290.834}','{\"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), + (8,'MadWayneThunder','2113 Mad Wayne Thunder','{\"y\":449.541,\"z\":96.902,\"x\":-1289.917}','{\"y\":448.07,\"z\":96.894,\"x\":-1290.834}','{\"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','{\"y\":696.314,\"z\":147.784,\"x\":-853.282}','{\"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), From 0ed8071194a4ca4a87ab0023f4273b2c056e583b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 15:12:43 +0200 Subject: [PATCH 0115/3224] Update esx_property.sql --- esx_property.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_property.sql b/esx_property.sql index 5972de29..ccb7af03 100644 --- a/esx_property.sql +++ b/esx_property.sql @@ -55,7 +55,7 @@ INSERT INTO `properties` VALUES (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\":449.541,\"z\":96.902,\"x\":-1289.917}','{\"y\":448.07,\"z\":96.894,\"x\":-1290.834}','{\"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), + (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','{\"y\":696.314,\"z\":147.784,\"x\":-853.282}','{\"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), From ec90b859810dbab95aa43ffef423599cda4f9c49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 15:15:31 +0200 Subject: [PATCH 0116/3224] Update esx_property.sql --- esx_property.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_property.sql b/esx_property.sql index ccb7af03..c7ad2df0 100644 --- a/esx_property.sql +++ b/esx_property.sql @@ -48,7 +48,7 @@ CREATE TABLE `properties` ( ); INSERT INTO `properties` VALUES - (1,'WhispymoundDrive','2677 Whispymound Drive','{\"y\":564.89,\"z\":182.959,\"x\":119.384}','{\"y\":558.667,\"z\":183.297,\"x\":116.392}','{\"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), + (1,'WhispymoundDrive','2677 Whispymound Drive','{\"y\":564.89,\"z\":182.959,\"x\":119.384}','{\"y\":558.667,\"z\":182.297,\"x\":116.392}','{\"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','{\"y\":834.47540283203,\"z\":234.92024230957,\"x\":-86.692153930664}','{\"y\":422.84088134766,\"z\":144.90005493164,\"x\":372.70159912109}','{\"y\":420.07595825195,\"z\":145.90487670898,\"x\":373.16149902344}','{\"y\":835.64111328125,\"z\":234.7230072021,\"x\":-90.789779663086}','[]',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}','{\"y\":444.374,\"z\":145.037,\"x\":-212.15144348145}','[]',NULL,1,1,0,'{\"x\":337.726,\"y\":436.985,\"z\":140.77}',1500000), From 06f20b3a81bf768bd8d8e68d09306e3668edc3e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 15:31:44 +0200 Subject: [PATCH 0117/3224] Update esx_property.sql --- esx_property.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_property.sql b/esx_property.sql index c7ad2df0..78dc23a4 100644 --- a/esx_property.sql +++ b/esx_property.sql @@ -56,7 +56,7 @@ INSERT INTO `properties` VALUES (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','{\"y\":696.314,\"z\":147.784,\"x\":-853.282}','{\"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), + (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), From e935b41c4ba20089e7b37a09217afc2625adaa3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 15:37:58 +0200 Subject: [PATCH 0118/3224] Update esx_property.sql --- esx_property.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_property.sql b/esx_property.sql index 78dc23a4..54cc6d33 100644 --- a/esx_property.sql +++ b/esx_property.sql @@ -48,7 +48,7 @@ CREATE TABLE `properties` ( ); INSERT INTO `properties` VALUES - (1,'WhispymoundDrive','2677 Whispymound Drive','{\"y\":564.89,\"z\":182.959,\"x\":119.384}','{\"y\":558.667,\"z\":182.297,\"x\":116.392}','{\"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), + (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','{\"y\":834.47540283203,\"z\":234.92024230957,\"x\":-86.692153930664}','{\"y\":422.84088134766,\"z\":144.90005493164,\"x\":372.70159912109}','{\"y\":420.07595825195,\"z\":145.90487670898,\"x\":373.16149902344}','{\"y\":835.64111328125,\"z\":234.7230072021,\"x\":-90.789779663086}','[]',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}','{\"y\":444.374,\"z\":145.037,\"x\":-212.15144348145}','[]',NULL,1,1,0,'{\"x\":337.726,\"y\":436.985,\"z\":140.77}',1500000), From 020bbd1796505c7224a66e338eaea2f0e77c2dbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 15:43:40 +0200 Subject: [PATCH 0119/3224] Update esx_property.sql --- esx_property.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_property.sql b/esx_property.sql index 54cc6d33..7aaaff3e 100644 --- a/esx_property.sql +++ b/esx_property.sql @@ -51,7 +51,7 @@ INSERT INTO `properties` 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','{\"y\":834.47540283203,\"z\":234.92024230957,\"x\":-86.692153930664}','{\"y\":422.84088134766,\"z\":144.90005493164,\"x\":372.70159912109}','{\"y\":420.07595825195,\"z\":145.90487670898,\"x\":373.16149902344}','{\"y\":835.64111328125,\"z\":234.7230072021,\"x\":-90.789779663086}','[]',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}','{\"y\":444.374,\"z\":145.037,\"x\":-212.15144348145}','[]',NULL,1,1,0,'{\"x\":337.726,\"y\":436.985,\"z\":140.77}',1500000), + (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), From bf8618fee150e8f96a7f4c9941c92f27c4235ba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 15:50:05 +0200 Subject: [PATCH 0120/3224] Update esx_property.sql --- esx_property.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_property.sql b/esx_property.sql index 7aaaff3e..fe7479c1 100644 --- a/esx_property.sql +++ b/esx_property.sql @@ -49,7 +49,7 @@ CREATE TABLE `properties` ( INSERT INTO `properties` 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','{\"y\":834.47540283203,\"z\":234.92024230957,\"x\":-86.692153930664}','{\"y\":422.84088134766,\"z\":144.90005493164,\"x\":372.70159912109}','{\"y\":420.07595825195,\"z\":145.90487670898,\"x\":373.16149902344}','{\"y\":835.64111328125,\"z\":234.7230072021,\"x\":-90.789779663086}','[]',NULL,1,1,0,'{\"x\":377.349,\"y\":429.422,\"z\":137.3}',1500000), + (2,'NorthConkerAvenue2045','2045 North Conker Avenue','{\"x\":372.796,\"y\":428.327,\"z\":144.685}','{\"y\":422.84088134766,\"z\":144.90005493164,\"x\":372.70159912109}','{\"y\":420.07595825195,\"z\":145.90487670898,\"x\":373.16149902344}','{\"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), From 85b4fef217d6f827dcd2f7d818f95536b3be1fc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 15:55:17 +0200 Subject: [PATCH 0121/3224] Update esx_property.sql --- esx_property.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_property.sql b/esx_property.sql index fe7479c1..d6e8ae83 100644 --- a/esx_property.sql +++ b/esx_property.sql @@ -49,7 +49,7 @@ CREATE TABLE `properties` ( INSERT INTO `properties` 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}','{\"y\":422.84088134766,\"z\":144.90005493164,\"x\":372.70159912109}','{\"y\":420.07595825195,\"z\":145.90487670898,\"x\":373.16149902344}','{\"x\":372.454,\"y\":432.886,\"z\":143.443}','[]',NULL,1,1,0,'{\"x\":377.349,\"y\":429.422,\"z\":137.3}',1500000), + (2,'NorthConkerAvenue2045','2045 North Conker Avenue','{\"x\":372.796,\"y\":428.327,\"z\":144.685}','{\"y\":422.84088134766,\"z\":144.90005493164,\"x\":372.70159912109}','{\"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), From 863ad88ecce100e53d3b7dd0c15b87c4d7cc8deb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 15:58:24 +0200 Subject: [PATCH 0122/3224] Update esx_property.sql --- esx_property.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_property.sql b/esx_property.sql index d6e8ae83..ebd5fb05 100644 --- a/esx_property.sql +++ b/esx_property.sql @@ -49,7 +49,7 @@ CREATE TABLE `properties` ( INSERT INTO `properties` 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}','{\"y\":422.84088134766,\"z\":144.90005493164,\"x\":372.70159912109}','{\"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), + (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), From 8e4b6052ccfdbe393d678ca9f84ccf4bf4869b7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 2 Aug 2017 16:03:27 +0200 Subject: [PATCH 0123/3224] Press [E] to exit property --- client/main.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 0da41a9e..cd7194dd 100644 --- a/client/main.lua +++ b/client/main.lua @@ -868,7 +868,9 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part) end if part == 'exit' then - ExitProperty(name) + CurrentAction = 'room_exit' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour sortir de la propriété' + CurrentActionData = {propertyName = name} end if part == 'roomMenu' then @@ -1026,6 +1028,10 @@ Citizen.CreateThread(function() OpenRoomMenu(CurrentActionData.property) end + if CurrentAction == 'room_exit' then + ExitProperty(CurrentActionData.propertyName) + end + CurrentAction = nil GUI.Time = GetGameTimer() From 2fcb0b36e043ebea782503660567cf22e0b34c9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 3 Aug 2017 13:10:38 +0200 Subject: [PATCH 0124/3224] Add vehicle functions --- .../es_extended/client/functions.lua | 83 +++++++++++++++---- 1 file changed, 69 insertions(+), 14 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 38ea9a91..63806af8 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -1,8 +1,8 @@ -local charset = {} +local Charset = {} -for i = 48, 57 do table.insert(charset, string.char(i)) end -for i = 65, 90 do table.insert(charset, string.char(i)) end -for i = 97, 122 do table.insert(charset, string.char(i)) end +for i = 48, 57 do table.insert(Charset, string.char(i)) end +for i = 65, 90 do table.insert(Charset, string.char(i)) end +for i = 97, 122 do table.insert(Charset, string.char(i)) end ESX = {} ESX.CurrentRequestId = 0 @@ -21,7 +21,7 @@ ESX.GetRandomString = function(length) math.randomseed(GetGameTimer()) if length > 0 then - return ESX.GetRandomString(length - 1) .. charset[math.random(1, #charset)] + return ESX.GetRandomString(length - 1) .. Charset[math.random(1, #Charset)] else return '' end @@ -267,8 +267,7 @@ end ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) - local playerPed = GetPlayerPed(-1) - local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) + local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) Citizen.CreateThread(function() @@ -279,9 +278,10 @@ ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) end local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, true, false) - + local id = NetworkGetNetworkIdFromEntity(vehicle) + SetNetworkIdCanMigrate(id, true) - SetEntityAsMissionEntity(vehicle, true, true) + SetEntityAsMissionEntity(vehicle, true, false) SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetModelAsNoLongerNeeded(model) @@ -292,8 +292,6 @@ ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) Citizen.Wait(0) end - local id = NetworkGetNetworkIdFromEntity(vehicle) - if cb ~= nil then cb(vehicle) end @@ -304,8 +302,7 @@ end ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) - local playerPed = GetPlayerPed(-1) - local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) + local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) Citizen.CreateThread(function() @@ -319,7 +316,7 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) local id = NetworkGetNetworkIdFromEntity(vehicle) SetNetworkIdCanMigrate(id, true) - SetEntityAsMissionEntity(vehicle, true, true) + SetEntityAsMissionEntity(vehicle, true, false) SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetModelAsNoLongerNeeded(model) @@ -387,6 +384,64 @@ ESX.Game.GetPlayersInArea = function(coords, area) return playersInArea end +ESX.Game.GetVehicles = function() + + local vehicles = {} + local handle, vehicle = FindFirstVehicle() + local success = nil + + repeat + table.insert(vehicles, vehicle) + success, vehicle = FindNextVehicle(handle) + until not success + + EndFindVehicle(handle) + + return vehicles + +end + +ESX.Game.GetClosestVehicle = function(coords) + + local vehicles = ESX.Game.GetVehicles() + local closestDistance = -1 + local closestPlayer = -1 + + for i=1, #vehicles, 1 do + + local vehicleCoords = GetEntityCoords(vehicles[i]) + local distance = GetDistanceBetweenCoords(vehicleCoords.x, vehicleCoords.y, vehicleCoords.z, coords.x, coords.y, coords.z, true) + + if closestDistance == -1 or closestDistance > distance then + closestVehicle = vehicles[i] + closestDistance = distance + end + + end + + return closestVehicle, closestDistance + +end + +ESX.Game.GetVehiclesInArea = function(coords, area) + + local vehicles = ESX.Game.GetVehicles() + local vehiclesInArea = {} + + for i=1, #vehicles, 1 do + + local vehicleCoords = GetEntityCoords(vehicles[i]) + local distance = GetDistanceBetweenCoords(vehicleCoords.x, vehicleCoords.y, vehicleCoords.z, coords.x, coords.y, coords.z, true) + + if distance <= area then + table.insert(vehiclesInArea, vehicles[i]) + end + + end + + return vehiclesInArea +end + ESX.Game.GetVehicleProperties = function(vehicle) local colour1, colour2 = GetVehicleColours(vehicle) From 1174b6f095bfc53cd32b3c2f875e6be0bced5116 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 3 Aug 2017 13:11:49 +0200 Subject: [PATCH 0125/3224] Fix vehicles not deleted --- client/main.lua | 110 ++++++++++++++++++++++++++++++------------------ 1 file changed, 70 insertions(+), 40 deletions(-) diff --git a/client/main.lua b/client/main.lua index c1b8c621..850ebb67 100644 --- a/client/main.lua +++ b/client/main.lua @@ -139,9 +139,16 @@ function OpenShopMenu() if hasEnoughMoney then - if CurrentVehicle ~= nil then - DeleteVehicle(CurrentVehicle) - CurrentVehicle = nil + if IsAnyVehicleNearPoint(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 3.0) then + + local vehicle = ESX.Game.GetClosestVehicle({ + x = Config.Zones.ShopInside.Pos.x, + y = Config.Zones.ShopInside.Pos.y, + z = Config.Zones.ShopInside.Pos.z + }) + + DeleteVehicle(vehicle) + end ESX.Game.SpawnVehicle(vehicleData.model, { @@ -176,8 +183,8 @@ function OpenShopMenu() end end, - function(data, menu) - + function(data2, menu2) + menu2.close() end ) @@ -188,17 +195,22 @@ function OpenShopMenu() local playerPed = GetPlayerPed(-1) - menu.close() - - if CurrentVehicle ~= nil then - DeleteVehicle(CurrentVehicle) - CurrentVehicle = nil - end - CurrentAction = 'shop_menu' CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' CurrentActionData = {} + if IsAnyVehicleNearPoint(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 3.0) then + + local vehicle = ESX.Game.GetClosestVehicle({ + x = Config.Zones.ShopInside.Pos.x, + y = Config.Zones.ShopInside.Pos.y, + z = Config.Zones.ShopInside.Pos.z + }) + + DeleteVehicle(vehicle) + + end + FreezeEntityPosition(playerPed, false) SetEntityVisible(playerPed, true) @@ -214,9 +226,16 @@ function OpenShopMenu() local vehicleData = vehiclesByCategory[data.current.name][data.current.value + 1] local playerPed = GetPlayerPed(-1) - if CurrentVehicle ~= nil then - DeleteVehicle(CurrentVehicle) - CurrentVehicle = nil + if IsAnyVehicleNearPoint(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 3.0) then + + local vehicle = ESX.Game.GetClosestVehicle({ + x = Config.Zones.ShopInside.Pos.x, + y = Config.Zones.ShopInside.Pos.y, + z = Config.Zones.ShopInside.Pos.z + }) + + DeleteVehicle(vehicle) + end ESX.Game.SpawnLocalVehicle(vehicleData.model, { @@ -232,9 +251,16 @@ function OpenShopMenu() end ) - if CurrentVehicle ~= nil then - DeleteVehicle(CurrentVehicle) - CurrentVehicle = nil + if IsAnyVehicleNearPoint(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 3.0) then + + local vehicle = ESX.Game.GetClosestVehicle({ + x = Config.Zones.ShopInside.Pos.x, + y = Config.Zones.ShopInside.Pos.y, + z = Config.Zones.ShopInside.Pos.z + }) + + DeleteVehicle(vehicle) + end ESX.Game.SpawnLocalVehicle(firstVehicleData.model, { @@ -259,11 +285,11 @@ function OpenResellerMenu() title = 'Concessionnaire', align = 'top-left', elements = { - {label = 'Sortir véhicule', value = 'pop_vehicle'}, - {label = 'Rentrer véhicule', value = 'depop_vehicle'}, - {label = 'Créer facture', value = 'create_bill'}, - {label = 'Véhicules en location', value = 'get_rented_vehicles'}, - {label = 'Attribuer véhicule [Vente]', value = 'set_vehicle_owner_sell'}, + {label = 'Sortir véhicule', value = 'pop_vehicle'}, + {label = 'Rentrer véhicule', value = 'depop_vehicle'}, + {label = 'Créer facture', value = 'create_bill'}, + {label = 'Véhicules en location', value = 'get_rented_vehicles'}, + {label = 'Attribuer véhicule [Vente]', value = 'set_vehicle_owner_sell'}, {label = 'Attribuer véhicule [Location]', value = 'set_vehicle_owner_rent'}, } }, @@ -275,8 +301,9 @@ function OpenResellerMenu() if data.current.value == 'depop_vehicle' then - if CurrentVehicle ~= nil then - DeleteVehicle(CurrentVehicle) + if IsAnyVehicleNearPoint(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 3.0) then + local vehicle = GetClosestVehicle(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 3.0, 0, 71) + DeleteVehicle(vehicle) end end @@ -436,7 +463,7 @@ function OpenPersonnalVehicleMenu() z = coords.z }, heading, function(vehicle) ESX.Game.SetVehicleProperties(vehicle, vehicleData) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) end) end, function(data, menu) @@ -469,8 +496,9 @@ function OpenPopVehicleMenu() local model = data.current.value - if CurrentVehicle ~= nil then - DeleteVehicle(CurrentVehicle) + if IsAnyVehicleNearPoint(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 3.0) then + local vehicle = GetClosestVehicle(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 3.0, 0, 71) + DeleteVehicle(vehicle) end ESX.Game.SpawnLocalVehicle(model, { @@ -536,10 +564,10 @@ function OpenBossActionsMenu() title = 'Concessionnaire - Patron', align = 'top-left', elements = { - {label = 'Acheter véhicule', value = 'buy_vehicle'}, + {label = 'Acheter véhicule', value = 'buy_vehicle'}, {label = 'Retirer argent société', value = 'withdraw_society_money'}, - {label = 'Déposer argent ', value = 'deposit_money'}, - {label = 'Blanchir argent', value = 'wash_money'} + {label = 'Déposer argent ', value = 'deposit_money'}, + {label = 'Blanchir argent', value = 'wash_money'} } }, function(data, menu) @@ -697,11 +725,13 @@ AddEventHandler('esx_vehicleshop:hasEnteredMarker', function(zone) if zone == 'ShopEntering' then - if Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.name == 'cardealer' then + if Config.EnablePlayerManagement then - CurrentAction = 'reseller_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' - CurrentActionData = {} + if PlayerData.job ~= nil and PlayerData.job.name == 'cardealer' then + CurrentAction = 'reseller_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {} + end else @@ -717,9 +747,9 @@ AddEventHandler('esx_vehicleshop:hasEnteredMarker', function(zone) local playerPed = GetPlayerPed(-1) - if IsPedInAnyVehicle(playerPed, false) then + if IsPedInAnyVehicle(playerPed, false) then - local vehicle = GetVehiclePedIsIn(playerPed, false) + local vehicle = GetVehiclePedIsIn(playerPed, false) CurrentAction = 'give_back_vehicle' CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour rendre votre véhicule' @@ -736,9 +766,9 @@ AddEventHandler('esx_vehicleshop:hasEnteredMarker', function(zone) local playerPed = GetPlayerPed(-1) - if IsPedInAnyVehicle(playerPed, false) then + if IsPedInAnyVehicle(playerPed, false) then - local vehicle = GetVehiclePedIsIn(playerPed, false) + local vehicle = GetVehiclePedIsIn(playerPed, false) local vehicleData = nil for i=1, #Vehicles, 1 do @@ -869,7 +899,7 @@ Citizen.CreateThread(function() AddTextComponentString(CurrentActionMsg) DisplayHelpTextFromStringLabel(0, 0, 1, -1) - if IsControlPressed(0, Keys['E']) and (GetGameTimer() - GUI.Time) > 300 then + if IsControlPressed(0, Keys['E']) and (GetGameTimer() - GUI.Time) > 300 then if CurrentAction == 'shop_menu' then OpenShopMenu() From 5855010643f7ab0c8571cea3d6b5b1cbde4c72d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 3 Aug 2017 13:17:17 +0200 Subject: [PATCH 0126/3224] Add distance check --- client/main.lua | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/client/main.lua b/client/main.lua index 850ebb67..ca18a59a 100644 --- a/client/main.lua +++ b/client/main.lua @@ -141,13 +141,15 @@ function OpenShopMenu() if IsAnyVehicleNearPoint(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 3.0) then - local vehicle = ESX.Game.GetClosestVehicle({ + local vehicle, distance = ESX.Game.GetClosestVehicle({ x = Config.Zones.ShopInside.Pos.x, y = Config.Zones.ShopInside.Pos.y, z = Config.Zones.ShopInside.Pos.z }) - - DeleteVehicle(vehicle) + + if distance <= 3.0 then + DeleteVehicle(vehicle) + end end @@ -201,13 +203,15 @@ function OpenShopMenu() if IsAnyVehicleNearPoint(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 3.0) then - local vehicle = ESX.Game.GetClosestVehicle({ + local vehicle, distance = ESX.Game.GetClosestVehicle({ x = Config.Zones.ShopInside.Pos.x, y = Config.Zones.ShopInside.Pos.y, z = Config.Zones.ShopInside.Pos.z }) - - DeleteVehicle(vehicle) + + if distance <= 3.0 then + DeleteVehicle(vehicle) + end end @@ -228,13 +232,15 @@ function OpenShopMenu() if IsAnyVehicleNearPoint(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 3.0) then - local vehicle = ESX.Game.GetClosestVehicle({ + local vehicle, distance = ESX.Game.GetClosestVehicle({ x = Config.Zones.ShopInside.Pos.x, y = Config.Zones.ShopInside.Pos.y, z = Config.Zones.ShopInside.Pos.z }) - - DeleteVehicle(vehicle) + + if distance <= 3.0 then + DeleteVehicle(vehicle) + end end @@ -253,13 +259,15 @@ function OpenShopMenu() if IsAnyVehicleNearPoint(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 3.0) then - local vehicle = ESX.Game.GetClosestVehicle({ + local vehicle, distance = ESX.Game.GetClosestVehicle({ x = Config.Zones.ShopInside.Pos.x, y = Config.Zones.ShopInside.Pos.y, z = Config.Zones.ShopInside.Pos.z }) - - DeleteVehicle(vehicle) + + if distance <= 3.0 then + DeleteVehicle(vehicle) + end end From 08fa16c7504d07c9053c57c38eb71cba11c1e3a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 3 Aug 2017 13:34:00 +0200 Subject: [PATCH 0127/3224] Optionnal coords --- .../es_extended/client/functions.lua | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 63806af8..f1b3f265 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -335,22 +335,28 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) end -ESX.Game.GetClosestPlayer = function() +ESX.Game.GetClosestPlayer = function(coords) local players = ESX.Game.GetPlayers() local closestDistance = -1 local closestPlayer = -1 - local playerPed = GetPlayerPed(-1) - local playerCoords = GetEntityCoords(playerPed) - + local coords = coords + local usePlayerPed = false + + if coords == nil then + usePlayerPed = true + local playerPed = GetPlayerPed(-1) + coords = GetEntityCoords(playerPed) + end + for i=1, #players, 1 do local target = GetPlayerPed(players[i]) - if target ~= playerPed then + if not usePlayerPed or (usePlayerPed and target ~= playerPed) then local targetCoords = GetEntityCoords(target) - local distance = GetDistanceBetweenCoords(targetCoords.x, targetCoords.y, targetCoords.z, playerCoords.x, playerCoords.y, playerCoords.z, true) + local distance = GetDistanceBetweenCoords(targetCoords.x, targetCoords.y, targetCoords.z, coords.x, coords.y, coords.z, true) if closestDistance == -1 or closestDistance > distance then closestPlayer = players[i] @@ -403,10 +409,16 @@ end ESX.Game.GetClosestVehicle = function(coords) - local vehicles = ESX.Game.GetVehicles() + local vehicles = ESX.Game.GetVehicles() local closestDistance = -1 local closestPlayer = -1 - + local coords = coords + + if coords == nil then + local playerPed = GetPlayerPed(-1) + coords = GetEntityCoords(playerPed) + end + for i=1, #vehicles, 1 do local vehicleCoords = GetEntityCoords(vehicles[i]) From afebc0e23eff5adab5ac86c845667dbadbcd793c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 3 Aug 2017 13:42:08 +0200 Subject: [PATCH 0128/3224] Remove wrong code --- resources/[essential]/es_extended/client/functions.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index f1b3f265..945fa6a8 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -313,9 +313,7 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) end local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, false, false) - local id = NetworkGetNetworkIdFromEntity(vehicle) - SetNetworkIdCanMigrate(id, true) SetEntityAsMissionEntity(vehicle, true, false) SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetModelAsNoLongerNeeded(model) From 700355cf55710b39de7733aa41c9b19dd0dee66d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 3 Aug 2017 15:44:01 +0200 Subject: [PATCH 0129/3224] Add ESX.Game.Teleport --- .../es_extended/client/functions.lua | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 945fa6a8..f70fe539 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -247,6 +247,23 @@ ESX.GetWeaponLabel = function(name) end +ESX.Game.Teleport = function(entity, coords, cb) + + RequestCollisionAtCoord(coords.x, coords.y, coords.z) + + while not HasCollisionLoadedAroundEntity(entity) do + RequestCollisionAtCoord(coords.x, coords.x, coords.x) + Citizen.Wait(0) + end + + SetEntityCoords(entity, coords.x, coords.y, coords.z) + + if cb ~= nil then + cb() + end + +end + ESX.Game.GetPlayers = function() local maxPlayers = Config.MaxPlayers From a4be86055589adf2fbe04b8695ed30ecde9a6769 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 3 Aug 2017 15:45:09 +0200 Subject: [PATCH 0130/3224] Add CloseInstance and instance:close event --- client/main.lua | 8 ++++++++ server/main.lua | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/client/main.lua b/client/main.lua index 0d446792..d61a7d0a 100644 --- a/client/main.lua +++ b/client/main.lua @@ -30,6 +30,10 @@ function CreateInstance() TriggerServerEvent('instance:create') end +function CloseInstance() + TriggerServerEvent('instance:close') +end + function EnterInstance(instance) TriggerServerEvent('instance:enter', InstanceInvite.host) end @@ -59,6 +63,10 @@ AddEventHandler('instance:create', function() CreateInstance() end) +AddEventHandler('instance:close', function() + CloseInstance() +end) + AddEventHandler('instance:enter', function(instance) EnterInstance(instance) end) diff --git a/server/main.lua b/server/main.lua index 9b08a315..d8309566 100644 --- a/server/main.lua +++ b/server/main.lua @@ -96,6 +96,11 @@ AddEventHandler('instance:create', function() CreateInstance(source) end) +RegisterServerEvent('instance:close') +AddEventHandler('instance:close', function() + CloseInstance(source) +end) + RegisterServerEvent('instance:enter') AddEventHandler('instance:enter', function(instance) AddPlayerToInstance(instance, source) From 392a1e72aa39846c636787abb623ff900a021fed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 3 Aug 2017 16:29:06 +0200 Subject: [PATCH 0131/3224] Update main.lua --- client/main.lua | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 67d50eaa..7d3114e2 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,4 +1,5 @@ -ESX = nil +ESX = nil +local PlayerData = {} Citizen.CreateThread(function() while ESX == nil do @@ -7,3 +8,12 @@ Citizen.CreateThread(function() end end) +RegisterNetEvent('esx:playerLoaded') +AddEventHandler('esx:playerLoaded', function(xPlayer) + PlayerData = xPlayer +end) + +RegisterNetEvent('esx:setJob') +AddEventHandler('esx:setJob', function(job) + PlayerData.job = job +end) From e8f64ce38d6c251d80880a43ffd315f3375091f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 3 Aug 2017 16:29:51 +0200 Subject: [PATCH 0132/3224] Fix spaces --- client/main.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index 7d3114e2..c7f146b4 100644 --- a/client/main.lua +++ b/client/main.lua @@ -10,10 +10,10 @@ end) RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) - PlayerData = xPlayer + PlayerData = xPlayer end) RegisterNetEvent('esx:setJob') AddEventHandler('esx:setJob', function(job) - PlayerData.job = job + PlayerData.job = job end) From 57564af25010c7563b684370bde6c0cc34f0c49e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 4 Aug 2017 11:44:48 +0200 Subject: [PATCH 0133/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..df5f258b --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_garage +FXServer ESX Garage From deebe151660b9e441b7658972652686902edd040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 4 Aug 2017 11:45:24 +0200 Subject: [PATCH 0134/3224] Update README.md --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index df5f258b..27ce05e4 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,15 @@ # fxserver-esx_garage FXServer ESX Garage + +[INSTALLATION] + +1) CD in your resources/[esx] folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-esx_garage esx_garage +``` +3) Add this in your server.cfg : + +``` +start esx_garage +``` From 6d40d7d6a4517f5d1443db60404c4e9bf9123189 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 4 Aug 2017 11:46:39 +0200 Subject: [PATCH 0135/3224] Add files --- __resource.lua | 14 ++ client/main.lua | 369 ++++++++++++++++++++++++++++++++++++++++++++++++ config.lua | 80 +++++++++++ server/main.lua | 67 +++++++++ 4 files changed, 530 insertions(+) create mode 100644 __resource.lua create mode 100644 client/main.lua create mode 100644 config.lua create mode 100644 server/main.lua diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..40b44860 --- /dev/null +++ b/__resource.lua @@ -0,0 +1,14 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'ESX Garage' + +server_scripts { + '@mysql-async/lib/MySQL.lua', + 'config.lua', + 'server/main.lua' +} + +client_scripts { + 'config.lua', + 'client/main.lua' +} diff --git a/client/main.lua b/client/main.lua new file mode 100644 index 00000000..84625a50 --- /dev/null +++ b/client/main.lua @@ -0,0 +1,369 @@ +ESX = nil +local LastGarage = nil +local LastPart = nil +local LastParking = nil + +Citizen.CreateThread(function() + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end +end) + +AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) + + if part == 'ExteriorEntryPoint' then + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + local garage = Config.Garages[name] + + if IsPedInAnyVehicle(playerPed, false) then + + local vehicle, distance = ESX.Game.GetClosestVehicle({ + x = coords.x, + y = coords.y, + z = coords.z + }) + + if distance <= 2.0 then + + local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) + + local spawnCoords = { + x = garage.InteriorSpawnPoint.Pos.x, + y = garage.InteriorSpawnPoint.Pos.y, + z = garage.InteriorSpawnPoint.Pos.z + } + + DeleteVehicle(vehicle) + + ESX.Game.Teleport(playerPed, spawnCoords, function() + + TriggerEvent('instance:create') + + ESX.Game.SpawnLocalVehicle(vehicleProps.model, spawnCoords, garage.InteriorSpawnPoint.Heading, function(vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + ESX.Game.SetVehicleProperties(vehicle, vehicleProps) + end) + + ESX.TriggerServerCallback('esx_vehicleshop:getVehiclesInGarage', function(vehicles) + + Citizen.CreateThread(function() + + for i=1, #garage.Parkings, 1 do + for j=1, #vehicles, 1 do + + if i == vehicles[j].zone then + + local vehicleLoaded = false + + ESX.Game.SpawnLocalVehicle(vehicles[j].vehicle.model, { + x = garage.Parkings[i].Pos.x, + y = garage.Parkings[i].Pos.y, + z = garage.Parkings[i].Pos.z + }, garage.Parkings[i].Heading, function(vehicle) + ESX.Game.SetVehicleProperties(vehicle, vehicles[j].vehicle) + vehicleLoaded = true + end) + + while not vehicleLoaded do + Citizen.Wait(0) + end + + end + + end + end + + end) + + end, name) + + end) + + end + + else + + ESX.Game.Teleport(playerPed, { + x = garage.InteriorSpawnPoint.Pos.x, + y = garage.InteriorSpawnPoint.Pos.y, + z = garage.InteriorSpawnPoint.Pos.z + }, function() + + TriggerEvent('instance:create') + + ESX.TriggerServerCallback('esx_vehicleshop:getVehiclesInGarage', function(vehicles) + + Citizen.CreateThread(function() + + for i=1, #garage.Parkings, 1 do + for j=1, #vehicles, 1 do + + if i == vehicles[j].zone then + + local vehicleLoaded = false + + ESX.Game.SpawnLocalVehicle(vehicles[j].vehicle.model, { + x = garage.Parkings[i].Pos.x, + y = garage.Parkings[i].Pos.y, + z = garage.Parkings[i].Pos.z + }, garage.Parkings[i].Heading, function(vehicle) + ESX.Game.SetVehicleProperties(vehicle, vehicles[j].vehicle) + vehicleLoaded = true + end) + + while not vehicleLoaded do + Citizen.Wait(0) + end + + end + + end + end + + end) + + end, name) + + end) + + end + + end + + if part == 'InteriorExitPoint' then + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + local garage = Config.Garages[name] + + if IsPedInAnyVehicle(playerPed, false) then + + local vehicle, distance = ESX.Game.GetClosestVehicle({ + x = coords.x, + y = coords.y, + z = coords.z + }) + + if distance <= 2.0 then + + local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) + + local spawnCoords = { + x = garage.ExteriorSpawnPoint.Pos.x, + y = garage.ExteriorSpawnPoint.Pos.y, + z = garage.ExteriorSpawnPoint.Pos.z + } + + DeleteVehicle(vehicle) + + ESX.Game.Teleport(playerPed, spawnCoords, function() + + TriggerEvent('instance:close') + + ESX.Game.SpawnVehicle(vehicleProps.model, spawnCoords, garage.ExteriorSpawnPoint.Heading, function(vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + ESX.Game.SetVehicleProperties(vehicle, vehicleProps) + end) + + end) + + end + + else + + ESX.Game.Teleport(playerPed, { + x = garage.ExteriorSpawnPoint.Pos.x, + y = garage.ExteriorSpawnPoint.Pos.y, + z = garage.ExteriorSpawnPoint.Pos.z + }, function() + TriggerEvent('instance:close') + end) + + end + + for i=1, #garage.Parkings, 1 do + + local vehicle, distance = ESX.Game.GetClosestVehicle({ + x = garage.Parkings[i].Pos.x, + y = garage.Parkings[i].Pos.y, + z = garage.Parkings[i].Pos.z + }) + + if distance <= 2.0 then + DeleteVehicle(vehicle) + end + + end + + end + + if part == 'Parking' then + + local playerPed = GetPlayerPed(-1) + local garage = Config.Garages[name] + + if IsPedInAnyVehicle(playerPed, false) then + + local vehicle, distance = ESX.Game.GetClosestVehicle() + local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) + + if distance <= 2.0 then + TriggerServerEvent('esx_garage:setParking', name, parking, vehicleProps) + end + + end + + end + +end) + +AddEventHandler('esx_property:hasExitedMarker', function(name, part, parking) + + if part == 'Parking' then + + local playerPed = GetPlayerPed(-1) + local garage = Config.Garages[name] + + if IsPedInAnyVehicle(playerPed, false) then + TriggerServerEvent('esx_garage:setParking', name, parking, false) + end + + end + +end) + +-- Create Blips +Citizen.CreateThread(function() + + for k,v in pairs(Config.Garages) do + + if v.IsClosed then + + local blip = AddBlipForCoord(v.ExteriorEntryPoint.Pos.x, v.ExteriorEntryPoint.Pos.y, v.ExteriorEntryPoint.Pos.z) + + SetBlipSprite (blip, 357) + SetBlipDisplay(blip, 4) + SetBlipScale (blip, 1.2) + SetBlipColour (blip, 3) + SetBlipAsShortRange(blip, true) + + BeginTextCommandSetBlipName("STRING") + AddTextComponentString("Garage") + EndTextCommandSetBlipName(blip) + + end + + end + +end) + +-- Display markers +Citizen.CreateThread(function() + while true do + + Wait(0) + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + for k,v in pairs(Config.Garages) do + + if v.IsClosed then + + if(GetDistanceBetweenCoords(coords, v.ExteriorEntryPoint.Pos.x, v.ExteriorEntryPoint.Pos.y, v.ExteriorEntryPoint.Pos.z, true) < Config.DrawDistance) then + DrawMarker(Config.MarkerType, v.ExteriorEntryPoint.Pos.x, v.ExteriorEntryPoint.Pos.y, v.ExteriorEntryPoint.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.MarkerSize.x, Config.MarkerSize.y, Config.MarkerSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) + end + + if(GetDistanceBetweenCoords(coords, v.InteriorExitPoint.Pos.x, v.InteriorExitPoint.Pos.y, v.InteriorExitPoint.Pos.z, true) < Config.DrawDistance) then + DrawMarker(Config.MarkerType, v.InteriorExitPoint.Pos.x, v.InteriorExitPoint.Pos.y, v.InteriorExitPoint.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.MarkerSize.x, Config.MarkerSize.y, Config.MarkerSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) + end + + end + + if IsPedInAnyVehicle(playerPed, false) then + + for i=1, #v.Parkings, 1 do + + local parking = v.Parkings[i] + + if(GetDistanceBetweenCoords(coords, parking.Pos.x, parking.Pos.y, parking.Pos.z, true) < Config.DrawDistance) then + DrawMarker(Config.MarkerType, parking.Pos.x, parking.Pos.y, parking.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.ParkingMarkerSize.x, Config.ParkingMarkerSize.y, Config.ParkingMarkerSize.z, Config.ParkingMarkerColor.r, Config.ParkingMarkerColor.g, Config.ParkingMarkerColor.b, 100, false, true, 2, false, false, false, false) + end + + end + + end + + end + + end +end) + +-- Enter / Exit marker events +Citizen.CreateThread(function() + while true do + + Wait(0) + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + local isInMarker = false + local currentGarage = nil + local currentPart = nil + local currentParking = nil + + for k,v in pairs(Config.Garages) do + + if v.IsClosed then + + if GetDistanceBetweenCoords(coords, v.ExteriorEntryPoint.Pos.x, v.ExteriorEntryPoint.Pos.y, v.ExteriorEntryPoint.Pos.z, true) < Config.MarkerSize.x then + isInMarker = true + currentGarage = k + currentPart = 'ExteriorEntryPoint' + end + + if GetDistanceBetweenCoords(coords, v.InteriorExitPoint.Pos.x, v.InteriorExitPoint.Pos.y, v.InteriorExitPoint.Pos.z, true) < Config.MarkerSize.x then + isInMarker = true + currentGarage = k + currentPart = 'InteriorExitPoint' + end + + for i=1, #v.Parkings, 1 do + + local parking = v.Parkings[i] + + if GetDistanceBetweenCoords(coords, parking.Pos.x, parking.Pos.y, parking.Pos.z, true) < Config.ParkingMarkerSize.x then + isInMarker = true + currentGarage = k + currentPart = 'Parking' + currentParking = i + end + + end + + end + + end + + if isInMarker and not HasAlreadyEnteredMarker or (isInMarker and (LastGarage ~= currentGarage or LastPart ~= currentPart) ) then + + HasAlreadyEnteredMarker = true + LastGarage = currentGarage + LastPart = currentPart + LastParking = currentParking + + TriggerEvent('esx_property:hasEnteredMarker', currentGarage, currentPart, currentParking) + end + + if not isInMarker and HasAlreadyEnteredMarker then + + HasAlreadyEnteredMarker = false + + TriggerEvent('esx_property:hasExitedMarker', LastGarage, LastPart, LastParking) + end + + end +end) \ No newline at end of file diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..234498f1 --- /dev/null +++ b/config.lua @@ -0,0 +1,80 @@ +Config = {} +Config.DrawDistance = 100.0 +Config.MarkerType = 1 +Config.MarkerSize = {x = 2.0, y = 2.0, z = 1.0} +Config.MarkerColor = {r = 204, g = 204, b = 0} +Config.ParkingMarkerSize = {x = 3.0, y = 3.0, z = 2.0} +Config.ParkingMarkerColor = {r = 102, g = 102, b = 204} + +Config.Zones = {} + +Config.Garages = { + + MiltonDrive = { + + IsClosed = true, + + ExteriorEntryPoint = { + Pos = {x= -796.542, y = 318.137, z = 84.673}, + }, + + ExteriorSpawnPoint = { + Pos = {x = -796.501, y = 302.271, z = 85.000}, + Heading = 180.0 + }, + + InteriorSpawnPoint = { + Pos = {x = 228.930, y = -1000.698, z = -100.000}, + Heading = 0.0 + }, + + InteriorExitPoint = { + Pos = {x = 224.613, y = -1004.769, z = -100.000}, + }, + + Parkings = { + { + Pos = {x = 224.500, y = -998.695, z = -100.000}, + Heading = 225.0 + }, + { + Pos = {x = 224.500, y = -994.630, z = -100.000}, + Heading = 225.0 + }, + { + Pos = {x = 224.500, y = -990.255, z = -100.000}, + Heading = 225.0 + }, + { + Pos = {x = 224.500, y = -986.628, z = -100.000}, + Heading = 225.0 + }, + { + Pos = {x = 224.500, y = -982.496, z = -100.000}, + Heading = 225.0 + }, + { + Pos = {x = 232.500, y = -982.496, z = -100.000}, + Heading = 135.0 + }, + { + Pos = {x = 232.500, y = -986.628, z = -100.000}, + Heading = 135.0 + }, + { + Pos = {x = 232.500, y = -990.255, z = -100.000}, + Heading = 135.0 + }, + { + Pos = {x = 232.500, y = -994.630, z = -100.000}, + Heading = 135.0 + }, + { + Pos = {x = 232.500, y = -998.695, z = -100.000}, + Heading = 135.0 + }, + } + + } + +} diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..b4d1f90c --- /dev/null +++ b/server/main.lua @@ -0,0 +1,67 @@ +ESX = nil + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +RegisterServerEvent('esx_garage:setParking') +AddEventHandler('esx_garage:setParking', function(garage, zone, vehicleProps) + + local xPlayer = ESX.GetPlayerFromId(source) + + if vehicleProps == false then + + MySQL.Async.execute( + 'DELETE FROM `user_parkings` WHERE `identifier` = @identifier AND `garage` = @garage AND zone = @zone', + { + ['@identifier'] = xPlayer.identifier, + ['@garage'] = garage; + ['@zone'] = zone + }, function(rowsChanged) + TriggerClientEvent('esx:showNotification', xPlayer.source, 'Véhicule ~g~sorti') + end + ) + + else + + MySQL.Async.execute( + 'INSERT INTO `user_parkings` (`identifier`, `garage`, `zone`, `vehicle`) VALUES (@identifier, @garage, @zone, @vehicle)', + { + ['@identifier'] = xPlayer.identifier, + ['@garage'] = garage; + ['@zone'] = zone, + ['vehicle'] = json.encode(vehicleProps) + }, function(rowsChanged) + TriggerClientEvent('esx:showNotification', xPlayer.source, 'Véhicule ~g~rangé') + end + ) + + end + +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', + { + ['@identifier'] = xPlayer.identifier, + ['@garage'] = garage + }, + function(result) + + local vehicles = {} + + for i=1, #result, 1 do + table.insert(vehicles, { + zone = result[i].zone, + vehicle = json.decode(result[i].vehicle) + }) + end + + cb(vehicles) + + end + ) + +end) \ No newline at end of file From 74c3ac01a1b5731a9a29877f5dc99703369f7cdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 4 Aug 2017 11:47:11 +0200 Subject: [PATCH 0136/3224] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 27ce05e4..f8841adc 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,8 @@ FXServer ESX Garage ``` git clone https://github.com/FXServer-ESX/fxserver-esx_garage esx_garage ``` -3) Add this in your server.cfg : +3) Import esx_garage.sql in your database +4) Add this in your server.cfg : ``` start esx_garage From bf6ced37b1d3958727a37a68212b7542a834b450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 4 Aug 2017 11:49:21 +0200 Subject: [PATCH 0137/3224] Add SQL --- esx_garage.sql | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 esx_garage.sql diff --git a/esx_garage.sql b/esx_garage.sql new file mode 100644 index 00000000..7c21f651 --- /dev/null +++ b/esx_garage.sql @@ -0,0 +1,12 @@ +USE `gta5_gamemode_essential`; + +CREATE TABLE `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, + + PRIMARY KEY (`id`) +); \ No newline at end of file From d6659dc9afaac0e4e39bdee618e62e2102dd585e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 4 Aug 2017 11:54:00 +0200 Subject: [PATCH 0138/3224] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 325054d4..20106bde 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ # fxserver-es_extended [WIP] FXServer ES Extended +[REQUIREMENTS] + +- essentialmode-mysql : https://github.com/FXServer-ESX/fxserver-essentialmode-mysql + [INSTALLATION] ``` @@ -31,4 +35,4 @@ TriggerEvent('es:setDefaultSettings', { nativeMoneySystem = false, }); -``` \ No newline at end of file +``` From 304a67aa197a71db1af55699381db19d11b91b20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 4 Aug 2017 12:00:05 +0200 Subject: [PATCH 0139/3224] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 3dbf7b6d..e808c500 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ # fxserver-esx_clotheshop FXServer ESX ClotheShop +[REQUIREMENTS] + +- esx_skin => https://github.com/FXServer-ESX/fxserver-esx_skin + [INSTALLATION] 1) CD in your resources/[esx] folder From 42e463eab625357a4b6bc5a8c4a997321c3c72cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 4 Aug 2017 12:06:22 +0200 Subject: [PATCH 0140/3224] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index f8841adc..01104f79 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ # fxserver-esx_garage FXServer ESX Garage +[REQUIREMENTS] + +- instance => https://github.com/FXServer-ESX/fxserver-instance + [INSTALLATION] 1) CD in your resources/[esx] folder From 7339db977c670af457d028ef03b6b310918e082a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 4 Aug 2017 14:02:34 +0200 Subject: [PATCH 0141/3224] Fix playerPed issue --- resources/[essential]/es_extended/client/functions.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index f70fe539..d9c6be2a 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -357,11 +357,12 @@ ESX.Game.GetClosestPlayer = function(coords) local closestPlayer = -1 local coords = coords local usePlayerPed = false + local playerPed = nil if coords == nil then - usePlayerPed = true - local playerPed = GetPlayerPed(-1) - coords = GetEntityCoords(playerPed) + usePlayerPed = true + playerPed = GetPlayerPed(-1) + coords = GetEntityCoords(playerPed) end for i=1, #players, 1 do From 7eff2640c6ef61be02aaf45f9b0691cfc6508aec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 4 Aug 2017 14:46:25 +0200 Subject: [PATCH 0142/3224] Add job check for taxi menu --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index d2cfdb00..5d5df427 100644 --- a/client/main.lua +++ b/client/main.lua @@ -705,7 +705,7 @@ Citizen.CreateThread(function() end - if IsControlPressed(0, Keys['F6']) and Config.EnablePlayerManagement and (GetGameTimer() - GUI.Time) > 150 then + if IsControlPressed(0, Keys['F6']) and Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.name == 'taxi' and (GetGameTimer() - GUI.Time) > 150 then OpenMobileTaxiActionsMenu() GUI.Time = GetGameTimer() end From 533e3f99814b34fd81e595ca77e6cd5ebe7d7e51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 4 Aug 2017 15:34:10 +0200 Subject: [PATCH 0143/3224] Better garage vehicle spawning logic --- client/main.lua | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/client/main.lua b/client/main.lua index 84625a50..01ee5d8a 100644 --- a/client/main.lua +++ b/client/main.lua @@ -96,34 +96,29 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) ESX.TriggerServerCallback('esx_vehicleshop:getVehiclesInGarage', function(vehicles) - Citizen.CreateThread(function() + for i=1, #garage.Parkings, 1 do + for j=1, #vehicles, 1 do - for i=1, #garage.Parkings, 1 do - for j=1, #vehicles, 1 do - - if i == vehicles[j].zone then + if i == vehicles[j].zone then - local vehicleLoaded = false + local spawn = function(j) - ESX.Game.SpawnLocalVehicle(vehicles[j].vehicle.model, { - x = garage.Parkings[i].Pos.x, - y = garage.Parkings[i].Pos.y, - z = garage.Parkings[i].Pos.z - }, garage.Parkings[i].Heading, function(vehicle) - ESX.Game.SetVehicleProperties(vehicle, vehicles[j].vehicle) - vehicleLoaded = true - end) - - while not vehicleLoaded do - Citizen.Wait(0) - end + ESX.Game.SpawnLocalVehicle(vehicles[j].vehicle.model, { + x = garage.Parkings[i].Pos.x, + y = garage.Parkings[i].Pos.y, + z = garage.Parkings[i].Pos.z + }, garage.Parkings[i].Heading, function(vehicle) + ESX.Game.SetVehicleProperties(vehicle, vehicles[j].vehicle) + end) end - end - end + spawn(j) - end) + end + + end + end end, name) From f54fd1b7ffa7b2728c4f08cc143e9ed7503bd5a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 4 Aug 2017 16:32:31 +0200 Subject: [PATCH 0144/3224] Update esx_taxijob_full.sql --- esx_taxijob_full.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_taxijob_full.sql b/esx_taxijob_full.sql index 4294b763..2d3c1eec 100644 --- a/esx_taxijob_full.sql +++ b/esx_taxijob_full.sql @@ -1,4 +1,4 @@ -INSERT INTO `addon_account` VALUES (name, label, shared) +INSERT INTO `addon_account` (name, label, shared) VALUES ('society_taxi','Taxi',1) ; From e1498d234092f5d47281e0a3f6e22080144678eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 4 Aug 2017 19:26:40 +0200 Subject: [PATCH 0145/3224] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 20106bde..094f170f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ # fxserver-es_extended [WIP] FXServer ES Extended +[DISCORD] + +https://discord.gg/8P7zjMF + [REQUIREMENTS] - essentialmode-mysql : https://github.com/FXServer-ESX/fxserver-essentialmode-mysql From e73f677ccce1b0b9e7690ed5eb24131ef9cc355d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 4 Aug 2017 22:10:07 +0200 Subject: [PATCH 0146/3224] Fix garage spawn + add missing event --- client/main.lua | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/client/main.lua b/client/main.lua index 01ee5d8a..ce83c27f 100644 --- a/client/main.lua +++ b/client/main.lua @@ -49,14 +49,12 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) ESX.TriggerServerCallback('esx_vehicleshop:getVehiclesInGarage', function(vehicles) - Citizen.CreateThread(function() + for i=1, #garage.Parkings, 1 do + for j=1, #vehicles, 1 do - for i=1, #garage.Parkings, 1 do - for j=1, #vehicles, 1 do - - if i == vehicles[j].zone then + if i == vehicles[j].zone then - local vehicleLoaded = false + local spawn = function(j) ESX.Game.SpawnLocalVehicle(vehicles[j].vehicle.model, { x = garage.Parkings[i].Pos.x, @@ -64,19 +62,16 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) z = garage.Parkings[i].Pos.z }, garage.Parkings[i].Heading, function(vehicle) ESX.Game.SetVehicleProperties(vehicle, vehicles[j].vehicle) - vehicleLoaded = true end) - while not vehicleLoaded do - Citizen.Wait(0) - end - end - end - end + spawn(j) - end) + end + + end + end end, name) @@ -220,7 +215,6 @@ AddEventHandler('esx_property:hasExitedMarker', function(name, part, parking) if part == 'Parking' then local playerPed = GetPlayerPed(-1) - local garage = Config.Garages[name] if IsPedInAnyVehicle(playerPed, false) then TriggerServerEvent('esx_garage:setParking', name, parking, false) @@ -274,7 +268,7 @@ Citizen.CreateThread(function() if(GetDistanceBetweenCoords(coords, v.InteriorExitPoint.Pos.x, v.InteriorExitPoint.Pos.y, v.InteriorExitPoint.Pos.z, true) < Config.DrawDistance) then DrawMarker(Config.MarkerType, v.InteriorExitPoint.Pos.x, v.InteriorExitPoint.Pos.y, v.InteriorExitPoint.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.MarkerSize.x, Config.MarkerSize.y, Config.MarkerSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) - end + end end @@ -299,8 +293,9 @@ end) -- Enter / Exit marker events Citizen.CreateThread(function() + while true do - + Wait(0) local playerPed = GetPlayerPed(-1) @@ -345,6 +340,10 @@ Citizen.CreateThread(function() if isInMarker and not HasAlreadyEnteredMarker or (isInMarker and (LastGarage ~= currentGarage or LastPart ~= currentPart) ) then + if LastGarage ~= currentGarage or LastPart ~= currentPart then + TriggerEvent('esx_property:hasExitedMarker', LastGarage, LastPart, LastParking) + end + HasAlreadyEnteredMarker = true LastGarage = currentGarage LastPart = currentPart From f827f62dd498f79affa43d65b1a156055b4ee1ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 08:55:02 +0200 Subject: [PATCH 0147/3224] Edit discord link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 094f170f..244da74e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ FXServer ES Extended [DISCORD] -https://discord.gg/8P7zjMF +https://discord.me/fivem_esx [REQUIREMENTS] From 448fdaa9fae1544a9644129de8e76d69e9a84c56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 11:34:03 +0200 Subject: [PATCH 0148/3224] Add ESX.Game.Utils.DrawText3D --- .../es_extended/client/functions.lua | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index d9c6be2a..195c4d71 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -15,6 +15,7 @@ ESX.UI.Menu = {} ESX.UI.Menu.RegisteredTypes = {} ESX.UI.Menu.Opened = {} ESX.Game = {} +ESX.Game.Utils = {} ESX.GetRandomString = function(length) @@ -649,6 +650,42 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) end +ESX.Game.Utils.DrawText3D = function(coords, text, size) + + local onScreen, x, y = World3dToScreen2d(coords.x, coords.y, coords.z) + local camCoords = GetGameplayCamCoords() + local dist = GetDistanceBetweenCoords(camCoords.x, camCoords.y, camCoords.z, coords.x, coords.y, coords.z, 1) + local size = size + + if size == nil then + size = 1 + end + + local scale = (size / dist) * 2 + local fov = (1 / GetGameplayCamFov()) * 100 + local scale = scale * fov + + if onScreen then + + SetTextScale(0.0 * scale, 0.55 * scale) + SetTextFont(0) + SetTextProportional(1) + -- SetTextScale(0.0, 0.55) + SetTextColour(255, 255, 255, 255) + SetTextDropshadow(0, 0, 0, 0, 255) + SetTextEdge(2, 0, 0, 0, 150) + SetTextDropShadow() + SetTextOutline() + SetTextEntry('STRING') + SetTextCentre(1) + + AddTextComponentString(text) + + DrawText(x, y) + end + +end + ESX.ShowInventory = function() ESX.TriggerServerCallback('esx:getPlayerData', function(data) From 3f438c01b005e68cdf5096f149b49c9185c48438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 11:43:40 +0200 Subject: [PATCH 0149/3224] Add ESX.Game.DeleteVehicle --- resources/[essential]/es_extended/client/functions.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 195c4d71..bcdbd663 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -283,6 +283,11 @@ ESX.Game.GetPlayers = function() end +ESX.Game.DeleteVehicle = function(vehicle) + SetEntityAsMissionEntity(vehicle, false, true) + DeleteVehicle(vehicle) +end + ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) @@ -670,7 +675,6 @@ ESX.Game.Utils.DrawText3D = function(coords, text, size) SetTextScale(0.0 * scale, 0.55 * scale) SetTextFont(0) SetTextProportional(1) - -- SetTextScale(0.0, 0.55) SetTextColour(255, 255, 255, 255) SetTextDropshadow(0, 0, 0, 0, 255) SetTextEdge(2, 0, 0, 0, 150) From 97e0735320d0722467403713d45fa9be3f1b6263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 11:46:38 +0200 Subject: [PATCH 0150/3224] Update ESX.Game.DeleteVehicle --- resources/[essential]/es_extended/client/functions.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index bcdbd663..6a31c79e 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -285,6 +285,7 @@ end ESX.Game.DeleteVehicle = function(vehicle) SetEntityAsMissionEntity(vehicle, false, true) + SetEntityAsNoLongerNeeded(vehicle) DeleteVehicle(vehicle) end From 6d943080d3640c78a363eef49a74e0321358b0ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 12:56:56 +0200 Subject: [PATCH 0151/3224] ESX.Game.DalateVehicle + SQL DELETE statement --- client/main.lua | 6 +++--- server/main.lua | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/main.lua b/client/main.lua index ce83c27f..d27e9808 100644 --- a/client/main.lua +++ b/client/main.lua @@ -36,7 +36,7 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) z = garage.InteriorSpawnPoint.Pos.z } - DeleteVehicle(vehicle) + ESX.Game.DeleteVehicle(vehicle) ESX.Game.Teleport(playerPed, spawnCoords, function() @@ -147,7 +147,7 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) z = garage.ExteriorSpawnPoint.Pos.z } - DeleteVehicle(vehicle) + ESX.Game.DeleteVehicle(vehicle) ESX.Game.Teleport(playerPed, spawnCoords, function() @@ -183,7 +183,7 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) }) if distance <= 2.0 then - DeleteVehicle(vehicle) + ESX.Game.DeleteVehicle(vehicle) end end diff --git a/server/main.lua b/server/main.lua index b4d1f90c..ba07b928 100644 --- a/server/main.lua +++ b/server/main.lua @@ -23,7 +23,7 @@ AddEventHandler('esx_garage:setParking', function(garage, zone, vehicleProps) else MySQL.Async.execute( - 'INSERT INTO `user_parkings` (`identifier`, `garage`, `zone`, `vehicle`) VALUES (@identifier, @garage, @zone, @vehicle)', + 'DELETE FROM `user_parkings` WHERE `identifier` = @identifier AND `garage` = @garage AND zone = @zone; INSERT INTO `user_parkings` (`identifier`, `garage`, `zone`, `vehicle`) VALUES (@identifier, @garage, @zone, @vehicle)', { ['@identifier'] = xPlayer.identifier, ['@garage'] = garage; From 922b7e2434180483210670d94a5fbe9a20690633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 13:00:13 +0200 Subject: [PATCH 0152/3224] Add dispatch --- server/main.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 3d46a5f2..335362cc 100644 --- a/server/main.lua +++ b/server/main.lua @@ -49,7 +49,9 @@ TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message if phoneNumber == 'taxi' then for k, v in pairs(xPlayers) do if v.job.name == 'taxi' then - TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'Appel Taxi') + TriggerEvent('esx_phone:getDistpatchRequestId', function(requestId) + TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'Appel Taxi', requestId) + end) end end end From f769e84a677b69f68b9f7013296e40b981dc0071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 14:22:51 +0200 Subject: [PATCH 0153/3224] Better zone detection --- client/main.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index d27e9808..c348aefd 100644 --- a/client/main.lua +++ b/client/main.lua @@ -338,9 +338,9 @@ Citizen.CreateThread(function() end - if isInMarker and not HasAlreadyEnteredMarker or (isInMarker and (LastGarage ~= currentGarage or LastPart ~= currentPart) ) then + if isInMarker and not HasAlreadyEnteredMarker or (isInMarker and (LastGarage ~= currentGarage or LastPart ~= currentPart or LastParking ~= currentParking) ) then - if LastGarage ~= currentGarage or LastPart ~= currentPart then + if LastGarage ~= currentGarage or LastPart ~= currentPart or LastParking ~= currentParking then TriggerEvent('esx_property:hasExitedMarker', LastGarage, LastPart, LastParking) end From 55ba8521ab8436ce1528709f098e214d7160f1c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 15:26:00 +0200 Subject: [PATCH 0154/3224] Update ESX.Game.DeleteVehicle --- resources/[essential]/es_extended/client/functions.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 6a31c79e..c023905f 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -284,9 +284,8 @@ ESX.Game.GetPlayers = function() end ESX.Game.DeleteVehicle = function(vehicle) - SetEntityAsMissionEntity(vehicle, false, true) - SetEntityAsNoLongerNeeded(vehicle) - DeleteVehicle(vehicle) + SetEntityAsMissionEntity(CurrentActionData.vehicle, false, true) + DeleteVehicle(CurrentActionData.vehicle) end ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) From b650b76b2ab578bf08976f87e6bfc5e075783498 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 15:26:49 +0200 Subject: [PATCH 0155/3224] Update ESX.Game.DeleteVehicle --- resources/[essential]/es_extended/client/functions.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index c023905f..bcdbd663 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -284,8 +284,8 @@ ESX.Game.GetPlayers = function() end ESX.Game.DeleteVehicle = function(vehicle) - SetEntityAsMissionEntity(CurrentActionData.vehicle, false, true) - DeleteVehicle(CurrentActionData.vehicle) + SetEntityAsMissionEntity(vehicle, false, true) + DeleteVehicle(vehicle) end ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) From d0125d99e1c53066bd695639deae9fb01470437c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 17:51:48 +0200 Subject: [PATCH 0156/3224] Remove DLL, everything is in lua now --- __resource.lua | 3 +- client/main.lua | 45 ++++++++++++-- skinchanger.net.dll | Bin 8192 -> 0 bytes skinchanger_dll/.vs/skinchanger/v15/.suo | Bin 43520 -> 0 bytes skinchanger_dll/skinchanger.sln | 22 ------- .../skinchanger/Properties/AssemblyInfo.cs | 36 ----------- skinchanger_dll/skinchanger/skinchanger.cs | 58 ------------------ .../skinchanger/skinchanger.csproj | 51 --------------- .../skinchanger/skinchanger.csproj.user | 6 -- 9 files changed, 42 insertions(+), 179 deletions(-) delete mode 100644 skinchanger.net.dll delete mode 100644 skinchanger_dll/.vs/skinchanger/v15/.suo delete mode 100644 skinchanger_dll/skinchanger.sln delete mode 100644 skinchanger_dll/skinchanger/Properties/AssemblyInfo.cs delete mode 100644 skinchanger_dll/skinchanger/skinchanger.cs delete mode 100644 skinchanger_dll/skinchanger/skinchanger.csproj delete mode 100644 skinchanger_dll/skinchanger/skinchanger.csproj.user diff --git a/__resource.lua b/__resource.lua index 430df89c..80a13e52 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,7 +2,6 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'SkinChanger' -client_scripts { - 'skinchanger.net.dll', +client_scripts {, 'client/main.lua' } \ No newline at end of file diff --git a/client/main.lua b/client/main.lua index 314858e0..33713191 100644 --- a/client/main.lua +++ b/client/main.lua @@ -42,6 +42,39 @@ for i=1, #Components, 1 do Character[Components[i].name] = Components[i].value end +function LoadDefaultModel(loadMale) + + local playerPed = GetPlayerPed(-1) + local characterModel + + if loadMale then + characterModel = GetHashKey('mp_m_freemode_01') + else + characterModel = GetHashKey('mp_f_freemode_01'); + end + + RequestModel(characterModel) + + Citizen.CreateThread(function() + + while not HasModelLoaded(characterModel) do + RequestModel(characterModel) + Citizen.Wait(0) + end + + if IsModelInCdimage(characterModel) and IsModelValid(characterModel) then + SetPlayerModel(PlayerId(), characterModel) + SetPedDefaultComponentVariation(playerPed) + end + + SetModelAsNoLongerNeeded(characterModel) + + TriggerEvent('skinchanger:modelLoaded') + + end) + +end + function GetMaxVals() local playerPed = GetPlayerPed(-1) @@ -134,6 +167,10 @@ function ApplySkin(skin, clothes) end +AddEventHandler('skinchanger:loadDefaultModel', function(loadMale) + LoadDefaultModel(loadMale) +end) + AddEventHandler('skinchanger:getData', function(cb) local components = json.decode(json.encode(Components)) @@ -189,9 +226,9 @@ AddEventHandler('skinchanger:loadSkin', function(skin) LoadSkin = skin if skin['sex'] == 0 then - TriggerEvent('skinchanger:LoadDefaultModel', true) + LoadDefaultModel(true) else - TriggerEvent('skinchanger:LoadDefaultModel', false) + LoadDefaultModel(false) end LastSex = skin['sex'] @@ -207,9 +244,9 @@ AddEventHandler('skinchanger:loadClothes', function(playerSkin, clothesSkin) } if playerSkin['sex'] == 0 then - TriggerEvent('skinchanger:LoadDefaultModel', true) + LoadDefaultModel(true) else - TriggerEvent('skinchanger:LoadDefaultModel', false) + LoadDefaultModel(false) end LastSex = skin['sex'] diff --git a/skinchanger.net.dll b/skinchanger.net.dll deleted file mode 100644 index 315d79e572ca46eba6b42ac480c88da7ca77d449..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 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 diff --git a/skinchanger_dll/.vs/skinchanger/v15/.suo b/skinchanger_dll/.vs/skinchanger/v15/.suo deleted file mode 100644 index 267f914db4066b1f4ab1b64aa492387b57a627d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43520 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 UrB58~-p+O2@7{#juae>ZA3D9w2mk;8 diff --git a/skinchanger_dll/skinchanger.sln b/skinchanger_dll/skinchanger.sln deleted file mode 100644 index edb4061d..00000000 --- a/skinchanger_dll/skinchanger.sln +++ /dev/null @@ -1,22 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26403.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "skinchanger", "skinchanger\skinchanger.csproj", "{0B36C12C-4C7A-4C24-B204-161034340C8A}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0B36C12C-4C7A-4C24-B204-161034340C8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0B36C12C-4C7A-4C24-B204-161034340C8A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0B36C12C-4C7A-4C24-B204-161034340C8A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0B36C12C-4C7A-4C24-B204-161034340C8A}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/skinchanger_dll/skinchanger/Properties/AssemblyInfo.cs b/skinchanger_dll/skinchanger/Properties/AssemblyInfo.cs deleted file mode 100644 index 29ce8cfb..00000000 --- a/skinchanger_dll/skinchanger/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// Les informations générales relatives à un assembly dépendent de -// l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations -// associées à un assembly. -[assembly: AssemblyTitle("es_skinchanger")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("es_skinchanger")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly -// aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de -// COM, affectez la valeur true à l'attribut ComVisible sur ce type. -[assembly: ComVisible(false)] - -// Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM -[assembly: Guid("0b36c12c-4c7a-4c24-b204-161034340c8a")] - -// Les informations de version pour un assembly se composent des quatre valeurs suivantes : -// -// Version principale -// Version secondaire -// Numéro de build -// Révision -// -// Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut -// en utilisant '*', comme indiqué ci-dessous : -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/skinchanger_dll/skinchanger/skinchanger.cs b/skinchanger_dll/skinchanger/skinchanger.cs deleted file mode 100644 index 1276ba24..00000000 --- a/skinchanger_dll/skinchanger/skinchanger.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using CitizenFX.Core; -using CitizenFX.Core.UI; -using CitizenFX.Core.Native; - -namespace skinchanger -{ - public class Main : BaseScript - { - public Main() - { - Tick += OnTick; - - EventHandlers["skinchanger:LoadDefaultModel"] += new Action(async (dynamic LoadMale) => - { - await LoadDefaultModel((bool) LoadMale); - - TriggerEvent("skinchanger:modelLoaded"); - }); - - } - - public async Task LoadDefaultModel(bool LoadMale) - { - - PedHash CharacterModel; - - if (LoadMale) - CharacterModel = PedHash.FreemodeMale01; - else - CharacterModel = PedHash.FreemodeFemale01; - - Model characterModel = new Model(CharacterModel); - - characterModel.Request(500); - - if (characterModel.IsInCdImage && characterModel.IsValid) - { - while (!characterModel.IsLoaded) - await BaseScript.Delay(0); - - Function.Call(Hash.SET_PLAYER_MODEL, Game.Player, characterModel.Hash); - Function.Call(Hash.SET_PED_DEFAULT_COMPONENT_VARIATION, Game.Player.Character.Handle); - } - - characterModel.MarkAsNoLongerNeeded(); - } - - public async Task OnTick() - { - - } - } -} diff --git a/skinchanger_dll/skinchanger/skinchanger.csproj b/skinchanger_dll/skinchanger/skinchanger.csproj deleted file mode 100644 index d2c9d418..00000000 --- a/skinchanger_dll/skinchanger/skinchanger.csproj +++ /dev/null @@ -1,51 +0,0 @@ - - - - - Debug - AnyCPU - {0B36C12C-4C7A-4C24-B204-161034340C8A} - Library - Properties - skinchanger - skinchanger.net - v4.5.2 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - copy /y "$(TargetPath)" "C:\Users\NGD\Desktop\cfx-server\resources\skinchanger" - - \ No newline at end of file diff --git a/skinchanger_dll/skinchanger/skinchanger.csproj.user b/skinchanger_dll/skinchanger/skinchanger.csproj.user deleted file mode 100644 index e997092b..00000000 --- a/skinchanger_dll/skinchanger/skinchanger.csproj.user +++ /dev/null @@ -1,6 +0,0 @@ - - - - C:\Users\NGD\AppData\Local\FiveM\FiveM.app\citizen\clr2\lib\mono\4.5\ - - \ No newline at end of file From 4d54c8f83e7b01b75e3d74f088a9bd504b07eb69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 17:52:41 +0200 Subject: [PATCH 0157/3224] change LoadDefaultModel to loadDefaultModel --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 8f65df36..30d4452e 100644 --- a/client/main.lua +++ b/client/main.lua @@ -145,7 +145,7 @@ function OpenSaveableMenu(submitCb, cancelCb, restrict) end AddEventHandler('playerSpawned', function() - TriggerEvent('skinchanger:LoadDefaultModel', true) + TriggerEvent('skinchanger:loadDefaultModel', true) end) AddEventHandler('esx_skin:getLastSkin', function(cb) From c9180284f12281f832625af2f62c0e5e6a675529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 18:10:11 +0200 Subject: [PATCH 0158/3224] Update __resource.lua --- __resource.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/__resource.lua b/__resource.lua index 80a13e52..9ebdaa11 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,6 +2,6 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'SkinChanger' -client_scripts {, +client_scripts { 'client/main.lua' -} \ No newline at end of file +} From ab98a36f273cbc1cde87de327fd8a6eb2b561fdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 19:00:56 +0200 Subject: [PATCH 0159/3224] Add removable helmet - need new version of esx_menu_default --- client/main.lua | 74 ++++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/client/main.lua b/client/main.lua index 33713191..f6409523 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,36 +1,36 @@ -local Components = { - {label = 'Sexe', name = 'sex', value = 0}, - {label = 'Visage', name = 'face', value = 0}, - {label = 'Peau', name = 'skin', value = 0}, - {label = 'Type Barbe', name = 'beard_1', value = 0}, - {label = 'Taille barbe', name = 'beard_2', value = 0}, - {label = 'Couleur barbe 1', name = 'beard_3', value = 0}, - {label = 'Couleur barbe 2', name = 'beard_4', value = 0}, - {label = 'Cheveux 1', name = 'hair_1', value = 0}, - {label = 'Cheveux 2', name = 'hair_2', value = 0}, - {label = 'Couleur cheveux 1', name = 'hair_color_1', value = 0}, - {label = 'Couleur cheveux 2', name = 'hair_color_2', value = 0}, - {label = 'T-Shirt 1', name = 'tshirt_1', value = 0}, - {label = 'T-Shirt 2', name = 'tshirt_2', value = 0, textureof = 'tshirt_1'}, - {label = 'Torse 1', name = 'torso_1', value = 0}, - {label = 'Torse 2', name = 'torso_2', value = 0, textureof = 'torso_1'}, - {label = 'Calques 1', name = 'decals_1', value = 0}, - {label = 'Calques 2', name = 'decals_2', value = 0, textureof = 'decals_1'}, - {label = 'Bras', name = 'arms', value = 0}, - {label = 'Jambes 1', name = 'pants_1', value = 0}, - {label = 'Jambes 2', name = 'pants_2', value = 0, textureof = 'pants_1'}, - {label = 'Chaussures 1', name = 'shoes_1', value = 0}, - {label = 'Chaussures 2', name = 'shoes_2', value = 0, textureof = 'shoes_1'}, - {label = 'Masque 1', name = 'mask_1', value = 0}, - {label = 'Masque 2', name = 'mask_2', value = 0, textureof = 'mask_1'}, - {label = 'Gilet pare-balle 1', name = 'bproof_1', value = 0}, - {label = 'Gilet pare-balle 2', name = 'bproof_2', value = 0, textureof = 'bproof_1'}, - {label = 'Chaine 1', name = 'chain_1', value = 0}, - {label = 'Chaine 2', name = 'chain_2', value = 0, textureof = 'chain_1'}, - {label = 'Casque 1', name = 'helmet_1', value = 0}, - {label = 'Casque 2', name = 'helmet_2', value = 0, textureof = 'helmet_1'}, - {label = 'Lunettes 1', name = 'glasses_1', value = 0}, - {label = 'Lunettes 2', name = 'glasses_2', value = 0, textureof = 'glasses_1'}, +local Components = { + {label = 'Sexe', name = 'sex', value = 0, min = 0 }, + {label = 'Visage', name = 'face', value = 0, min = 0 }, + {label = 'Peau', name = 'skin', value = 0, min = 0 }, + {label = 'Type Barbe', name = 'beard_1', value = 0, min = 0 }, + {label = 'Taille barbe', name = 'beard_2', value = 0, min = 0 }, + {label = 'Couleur barbe 1', name = 'beard_3', value = 0, min = 0 }, + {label = 'Couleur barbe 2', name = 'beard_4', value = 0, min = 0 }, + {label = 'Cheveux 1', name = 'hair_1', value = 0, min = 0 }, + {label = 'Cheveux 2', name = 'hair_2', value = 0, min = 0 }, + {label = 'Couleur cheveux 1', name = 'hair_color_1', value = 0, min = 0 }, + {label = 'Couleur cheveux 2', name = 'hair_color_2', value = 0, min = 0 }, + {label = 'T-Shirt 1', name = 'tshirt_1', value = 0, min = 0 }, + {label = 'T-Shirt 2', name = 'tshirt_2', value = 0, min = 0 , textureof = 'tshirt_1'}, + {label = 'Torse 1', name = 'torso_1', value = 0, min = 0 }, + {label = 'Torse 2', name = 'torso_2', value = 0, min = 0 , textureof = 'torso_1'}, + {label = 'Calques 1', name = 'decals_1', value = 0, min = 0 }, + {label = 'Calques 2', name = 'decals_2', value = 0, min = 0 , textureof = 'decals_1'}, + {label = 'Bras', name = 'arms', value = 0, min = 0 }, + {label = 'Jambes 1', name = 'pants_1', value = 0, min = 0 }, + {label = 'Jambes 2', name = 'pants_2', value = 0, min = 0 , textureof = 'pants_1'}, + {label = 'Chaussures 1', name = 'shoes_1', value = 0, min = 0 }, + {label = 'Chaussures 2', name = 'shoes_2', value = 0, min = 0 , textureof = 'shoes_1'}, + {label = 'Masque 1', name = 'mask_1', value = 0, min = 0 }, + {label = 'Masque 2', name = 'mask_2', value = 0, min = 0 , textureof = 'mask_1'}, + {label = 'Gilet pare-balle 1', name = 'bproof_1', value = 0, min = 0 }, + {label = 'Gilet pare-balle 2', name = 'bproof_2', value = 0, min = 0 , textureof = 'bproof_1'}, + {label = 'Chaine 1', name = 'chain_1', value = 0, min = 0 }, + {label = 'Chaine 2', name = 'chain_2', value = 0, min = 0 , textureof = 'chain_1'}, + {label = 'Casque 1', name = 'helmet_1', value = -1, min = -1, componentId = 0}, + {label = 'Casque 2', name = 'helmet_2', value = 0, min = 0 , textureof = 'helmet_1'}, + {label = 'Lunettes 1', name = 'glasses_1', value = 0, min = 0 }, + {label = 'Lunettes 2', name = 'glasses_2', value = 0, min = 0 , textureof = 'glasses_1'}, } local LastSex = 0 @@ -162,7 +162,13 @@ function ApplySkin(skin, clothes) SetPedComponentVariation(playerPed, 1, Character['mask_1'], Character['mask_2'], 2) -- mask SetPedComponentVariation(playerPed, 9, Character['bproof_1'], Character['bproof_2'], 2) -- bulletproof SetPedComponentVariation(playerPed, 7, Character['chain_1'], Character['chain_2'], 2) -- chain - SetPedPropIndex(playerPed, 0, Character['helmet_1'], Character['helmet_2'], 2) -- Helmet + + if Character['helmet_1'] == -1 then + ClearPedProp(playerPed, 0) + else + SetPedPropIndex(playerPed, 0, Character['helmet_1'], Character['helmet_2'], 2) -- Helmet + end + SetPedPropIndex(playerPed, 1, Character['glasses_1'], Character['glasses_2'], 2) -- Glasses end From 4c3b885c63a7d391bb1c644cb573ad3fccc89f31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 19:02:47 +0200 Subject: [PATCH 0160/3224] Add playerloaded event and min value + get comonent value --- client/main.lua | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/client/main.lua b/client/main.lua index 30d4452e..5016c327 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,6 +1,7 @@ ESX = nil local HasLoadedModel = false local LastSkin = nil +local PlayerLoaded = false Citizen.CreateThread(function() while ESX == nil do @@ -11,6 +12,8 @@ end) function OpenMenu(submitCb, cancelCb, restrict) + local playerPed = GetPlayerPed(-1) + TriggerEvent('skinchanger:getSkin', function(skin) LastSkin = skin end) @@ -45,11 +48,18 @@ function OpenMenu(submitCb, cancelCb, restrict) -- Insert elements for i=1, #_components, 1 do - + + local value = _components[i].value + + if _components[i].componentId ~= nil then + value = GetPedPropIndex(playerPed, _components[i].componentId) + end + local data = { label = _components[i].label, - name = _components[i].name, - value = _components[i].value, + name = _components[i].name, + value = value, + min = _components[i].min, textureof = _components[i].textureof, type = 'slider' } @@ -148,6 +158,11 @@ AddEventHandler('playerSpawned', function() TriggerEvent('skinchanger:loadDefaultModel', true) end) +RegisterNetEvent('esx:playerLoaded') +AddEventHandler('esx:playerLoaded', function(xPlayer) + PlayerLoaded = true +end) + AddEventHandler('esx_skin:getLastSkin', function(cb) cb(LastSkin) end) @@ -176,16 +191,24 @@ AddEventHandler('skinchanger:modelLoaded', function() if not HasLoadedModel then - ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) + Citizen.CreateThread(function() - HasLoadedModel = true - - if skin == nil then - OpenSaveableMenu(nil, nil, nil) - else - TriggerEvent('skinchanger:loadSkin', skin) + while not PlayerLoaded do + Citizen.Wait(0) end + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) + + HasLoadedModel = true + + if skin == nil then + OpenSaveableMenu(nil, nil, nil) + else + TriggerEvent('skinchanger:loadSkin', skin) + end + + end) + end) end From 4b9cdd83b8acad0127b5599c7c75f47975667eb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 19:03:51 +0200 Subject: [PATCH 0161/3224] Component id check --- client/main.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/main.lua b/client/main.lua index 5016c327..2f232bc3 100644 --- a/client/main.lua +++ b/client/main.lua @@ -49,9 +49,10 @@ function OpenMenu(submitCb, cancelCb, restrict) -- Insert elements for i=1, #_components, 1 do - local value = _components[i].value - - if _components[i].componentId ~= nil then + local value = _components[i].value + local componentId = _components[i].componentId + + if componentId == 0 then value = GetPedPropIndex(playerPed, _components[i].componentId) end From e29177a94331bdbda828cb8b08b3615f73728e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 19:04:28 +0200 Subject: [PATCH 0162/3224] Add min value --- html/js/app.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/html/js/app.js b/html/js/app.js index 2ad1336c..213c0d59 100644 --- a/html/js/app.js +++ b/html/js/app.js @@ -268,7 +268,9 @@ case 'slider' : { - if(elem.value > 0){ + let min = (typeof elem.min == 'undefined') ? 0 : elem.min; + + if(elem.value > min){ elem.value--; ESX_MENU.change(focused.namespace, focused.name, elem) } From d65849ab97404afb51f890701cc002910f940c4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 22:58:47 +0200 Subject: [PATCH 0163/3224] LastSex fix for loadClothes --- __resource.lua | 2 +- client/main.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/__resource.lua b/__resource.lua index 9ebdaa11..5afa8772 100644 --- a/__resource.lua +++ b/__resource.lua @@ -4,4 +4,4 @@ description 'SkinChanger' client_scripts { 'client/main.lua' -} +} \ No newline at end of file diff --git a/client/main.lua b/client/main.lua index f6409523..aa9fa324 100644 --- a/client/main.lua +++ b/client/main.lua @@ -255,6 +255,6 @@ AddEventHandler('skinchanger:loadClothes', function(playerSkin, clothesSkin) LoadDefaultModel(false) end - LastSex = skin['sex'] + LastSex = playerSkin['sex'] end) \ No newline at end of file From 8bc3fad9d499d1fe55815cff25c8817f976204d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 23:55:17 +0200 Subject: [PATCH 0164/3224] Add weapon types --- resources/[essential]/es_extended/config.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua index 22f1c7c9..5a166b37 100644 --- a/resources/[essential]/es_extended/config.lua +++ b/resources/[essential]/es_extended/config.lua @@ -84,6 +84,8 @@ Config.Weapons = { {name = 'WEAPON_PIPEBOMB', label = 'Bombe tuyau'}, {name = 'WEAPON_POOLCUE', label = 'Queue de billard'}, {name = 'WEAPON_WRENCH', label = 'Clé'}, + {name = 'WEAPON_FLASHLIGHT', label = 'Lampe torche'}, + {name = 'WEAPON_FIREEXTINGUISHER', label = 'Extincteur'}, {name = 'GADGET_NIGHTVISION', label = 'Vision nocturne'}, {name = 'GADGET_PARACHUTE', label = 'Parachute'}, } \ No newline at end of file From 921a2962b19eb15674a348cbce1bacf38441f648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 6 Aug 2017 10:14:43 +0200 Subject: [PATCH 0165/3224] Fix missing weapon labels --- resources/[essential]/es_extended/config.lua | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua index 5a166b37..2c891417 100644 --- a/resources/[essential]/es_extended/config.lua +++ b/resources/[essential]/es_extended/config.lua @@ -42,12 +42,12 @@ Config.Weapons = { {name = 'WEAPON_GRENADE', label = 'Grenade'}, {name = 'WEAPON_STICKYBOMB', label = 'Bombe collante'}, {name = 'WEAPON_SMOKEGRENADE', label = 'Grenade fumigène'}, - {name = 'WEAPON_BZGAS', 'Grenade à gaz BZ'}, - {name = 'WEAPON_MOLOTOV', 'Cocktail molotov'}, - {name = 'WEAPON_FIREEXTINGUISHER', 'Extincteur'}, - {name = 'WEAPON_PETROLCAN', 'Jerrican d\'essence'}, - {name = 'WEAPON_DIGISCANNER', 'Digiscanner'}, - {name = 'WEAPON_BALL', 'Balle'}, + {name = 'WEAPON_BZGAS', label = 'Grenade à gaz BZ'}, + {name = 'WEAPON_MOLOTOV', label = 'Cocktail molotov'}, + {name = 'WEAPON_FIREEXTINGUISHER', label = 'Extincteur'}, + {name = 'WEAPON_PETROLCAN', label = 'Jerrican d\'essence'}, + {name = 'WEAPON_DIGISCANNER', label = 'Digiscanner'}, + {name = 'WEAPON_BALL', label = 'Balle'}, {name = 'WEAPON_SNSPISTOL', label = 'Pistolet SNS'}, {name = 'WEAPON_BOTTLE', label = 'Bouteille'}, {name = 'WEAPON_GUSENBERG', label = 'Balayeuse Gusenberg'}, @@ -85,7 +85,6 @@ Config.Weapons = { {name = 'WEAPON_POOLCUE', label = 'Queue de billard'}, {name = 'WEAPON_WRENCH', label = 'Clé'}, {name = 'WEAPON_FLASHLIGHT', label = 'Lampe torche'}, - {name = 'WEAPON_FIREEXTINGUISHER', label = 'Extincteur'}, {name = 'GADGET_NIGHTVISION', label = 'Vision nocturne'}, {name = 'GADGET_PARACHUTE', label = 'Parachute'}, } \ No newline at end of file From 1f0fe4b6a9f94b0233110e0f3b7bf7cd053315de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 6 Aug 2017 11:50:35 +0200 Subject: [PATCH 0166/3224] Fix loadDefaultModel --- resources/[essential]/es_extended/client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index a2e1adb1..5e6e8591 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -85,7 +85,7 @@ AddEventHandler('playerSpawned', function() end) -AddEventHandler('skinchanger:LoadDefaultModel', function() +AddEventHandler('skinchanger:loadDefaultModel', function() LoadoutLoaded = false end) From 5e4fdf51fade9f693cdf630a901c5536b8dca8b1 Mon Sep 17 00:00:00 2001 From: renaiku Date: Sun, 6 Aug 2017 12:34:43 +0200 Subject: [PATCH 0167/3224] Add camera movements, eyebrows, ageing, makeup, bags, lipstick --- client/main.lua | 109 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/client/main.lua b/client/main.lua index 2f232bc3..be153b0a 100644 --- a/client/main.lua +++ b/client/main.lua @@ -2,6 +2,11 @@ ESX = nil local HasLoadedModel = false local LastSkin = nil local PlayerLoaded = false +local cam = nil +local isCameraActive = false +local zoomOffset = 0.0 +local camOffset = 0.0 +local heading = 90.0 Citizen.CreateThread(function() while ESX == nil do @@ -62,6 +67,8 @@ function OpenMenu(submitCb, cancelCb, restrict) value = value, min = _components[i].min, textureof = _components[i].textureof, + zoomOffset= _components[i].zoomOffset, + camOffset = _components[i].camOffset, type = 'slider' } @@ -75,6 +82,10 @@ function OpenMenu(submitCb, cancelCb, restrict) end + CreateSkinCam() + zoomOffset = _components[1].zoomOffset + camOffset = _components[1].camOffset + ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'skin', { @@ -87,6 +98,8 @@ function OpenMenu(submitCb, cancelCb, restrict) menu.close() + DeleteSkinCam() + TriggerEvent('skinchanger:loadSkin', LastSkin) if cancelCb ~= nil then @@ -97,6 +110,9 @@ function OpenMenu(submitCb, cancelCb, restrict) function(data, menu) TriggerEvent('skinchanger:getSkin', function(skin) + + zoomOffset = data.current.zoomOffset + camOffset = data.current.camOffset if skin[data.current.name] ~= data.current.value then @@ -131,6 +147,97 @@ function OpenMenu(submitCb, cancelCb, restrict) end +function CreateSkinCam() + if not DoesCamExist(cam) then + cam = CreateCam('DEFAULT_SCRIPTED_CAMERA', true) + end + SetCamActive(cam, true) + RenderScriptCams(true, true, 500, true, true) + isCameraActive = true + SetCamRot(cam, 0.0, 0.0, 270.0, true) + SetEntityHeading(playerPed, 90.0) +end + +function DeleteSkinCam() + isCameraActive = false + SetCamActive(cam, false) + RenderScriptCams(false, true, 500, true, true) + cam = nil +end + +Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + if isCameraActive then + DisableControlAction(2, 30, true) + DisableControlAction(2, 31, true) + DisableControlAction(2, 32, true) + DisableControlAction(2, 33, true) + DisableControlAction(2, 34, true) + DisableControlAction(2, 35, true) + + DisableControlAction(0, 25, true) -- Input Aim + DisableControlAction(0, 24, true) -- Input Attack + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + local angle = heading * math.pi / 180.0 + local theta = { + x = math.cos(angle), + y = math.sin(angle) + } + local pos = { + x = coords.x + (zoomOffset * theta.x), + y = coords.y + (zoomOffset * theta.y), + } + + local angleToLook = heading - 140.0 + if angleToLook > 360 then + angleToLook = angleToLook - 360 + elseif angleToLook < 0 then + angleToLook = angleToLook + 360 + end + angleToLook = angleToLook * math.pi / 180.0 + local thetaToLook = { + x = math.cos(angleToLook), + y = math.sin(angleToLook) + } + local posToLook = { + x = coords.x + (zoomOffset * thetaToLook.x), + y = coords.y + (zoomOffset * thetaToLook.y), + } + + SetCamCoord(cam, pos.x, pos.y, coords.z + camOffset) + PointCamAtCoord(cam, posToLook.x, posToLook.y, coords.z + camOffset) + + SetTextComponentFormat("STRING") + AddTextComponentString("Utilisez ~INPUT_VEH_FLY_ROLL_LEFT_ONLY~ et ~INPUT_VEH_FLY_ROLL_RIGHT_ONLY~ pour tourner la vue.") + DisplayHelpTextFromStringLabel(0, 0, 0, -1) + end + end +end) + +Citizen.CreateThread(function() + local angle = 90 + while true do + Citizen.Wait(0) + if isCameraActive then + if IsControlPressed(0, 108) then + angle = angle - 1 + elseif IsControlPressed(0, 109) then + angle = angle + 1 + end + if angle > 360 then + angle = angle - 360 + elseif angle < 0 then + angle = angle + 360 + end + heading = angle + 0.0 + end + end +end) + function OpenSaveableMenu(submitCb, cancelCb, restrict) TriggerEvent('skinchanger:getSkin', function(skin) @@ -141,6 +248,8 @@ function OpenSaveableMenu(submitCb, cancelCb, restrict) menu.close() + DeleteSkinCam() + TriggerEvent('skinchanger:getSkin', function(skin) TriggerServerEvent('esx_skin:save', skin) From 434a4cabfe2d58fbb877e70707a20ba56a8a02b9 Mon Sep 17 00:00:00 2001 From: renaiku Date: Sun, 6 Aug 2017 12:47:09 +0200 Subject: [PATCH 0168/3224] Add bags, makeup, ageing, eyebrows ... --- client/main.lua | 210 +++++++++++++++++++++++++++++++----------------- 1 file changed, 136 insertions(+), 74 deletions(-) diff --git a/client/main.lua b/client/main.lua index aa9fa324..8bf6469b 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,36 +1,54 @@ -local Components = { - {label = 'Sexe', name = 'sex', value = 0, min = 0 }, - {label = 'Visage', name = 'face', value = 0, min = 0 }, - {label = 'Peau', name = 'skin', value = 0, min = 0 }, - {label = 'Type Barbe', name = 'beard_1', value = 0, min = 0 }, - {label = 'Taille barbe', name = 'beard_2', value = 0, min = 0 }, - {label = 'Couleur barbe 1', name = 'beard_3', value = 0, min = 0 }, - {label = 'Couleur barbe 2', name = 'beard_4', value = 0, min = 0 }, - {label = 'Cheveux 1', name = 'hair_1', value = 0, min = 0 }, - {label = 'Cheveux 2', name = 'hair_2', value = 0, min = 0 }, - {label = 'Couleur cheveux 1', name = 'hair_color_1', value = 0, min = 0 }, - {label = 'Couleur cheveux 2', name = 'hair_color_2', value = 0, min = 0 }, - {label = 'T-Shirt 1', name = 'tshirt_1', value = 0, min = 0 }, - {label = 'T-Shirt 2', name = 'tshirt_2', value = 0, min = 0 , textureof = 'tshirt_1'}, - {label = 'Torse 1', name = 'torso_1', value = 0, min = 0 }, - {label = 'Torse 2', name = 'torso_2', value = 0, min = 0 , textureof = 'torso_1'}, - {label = 'Calques 1', name = 'decals_1', value = 0, min = 0 }, - {label = 'Calques 2', name = 'decals_2', value = 0, min = 0 , textureof = 'decals_1'}, - {label = 'Bras', name = 'arms', value = 0, min = 0 }, - {label = 'Jambes 1', name = 'pants_1', value = 0, min = 0 }, - {label = 'Jambes 2', name = 'pants_2', value = 0, min = 0 , textureof = 'pants_1'}, - {label = 'Chaussures 1', name = 'shoes_1', value = 0, min = 0 }, - {label = 'Chaussures 2', name = 'shoes_2', value = 0, min = 0 , textureof = 'shoes_1'}, - {label = 'Masque 1', name = 'mask_1', value = 0, min = 0 }, - {label = 'Masque 2', name = 'mask_2', value = 0, min = 0 , textureof = 'mask_1'}, - {label = 'Gilet pare-balle 1', name = 'bproof_1', value = 0, min = 0 }, - {label = 'Gilet pare-balle 2', name = 'bproof_2', value = 0, min = 0 , textureof = 'bproof_1'}, - {label = 'Chaine 1', name = 'chain_1', value = 0, min = 0 }, - {label = 'Chaine 2', name = 'chain_2', value = 0, min = 0 , textureof = 'chain_1'}, - {label = 'Casque 1', name = 'helmet_1', value = -1, min = -1, componentId = 0}, - {label = 'Casque 2', name = 'helmet_2', value = 0, min = 0 , textureof = 'helmet_1'}, - {label = 'Lunettes 1', name = 'glasses_1', value = 0, min = 0 }, - {label = 'Lunettes 2', name = 'glasses_2', value = 0, min = 0 , textureof = 'glasses_1'}, +local Components = { + {label = 'Sexe', name = 'sex', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = 'Visage', name = 'face', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = 'Peau', name = 'skin', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = 'Rides', name = 'age_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = 'Epaisseur rides', name = 'age_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = 'Type Barbe', name = 'beard_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = 'Taille barbe', name = 'beard_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = 'Couleur barbe 1', name = 'beard_3', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = 'Couleur barbe 2', name = 'beard_4', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = 'Cheveux 1', name = 'hair_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = 'Cheveux 2', name = 'hair_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = 'Couleur cheveux 1', name = 'hair_color_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = 'Couleur cheveux 2', name = 'hair_color_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = 'Type Sourcils', name = 'eyebrows_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = 'Taille Sourcils', name = 'eyebrows_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = 'Couleur Sourcils 1', name = 'eyebrows_3', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = 'Couleur Sourcils 2', name = 'eyebrows_4', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = 'Type Maquillage', name = 'makeup_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = 'Epaisseur Maquillage', name = 'makeup_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = 'Couleur Maquillage 1', name = 'makeup_3', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = 'Couleur Maquillage 2', name = 'makeup_4', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = 'Type Lipstick', name = 'lipstick_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = 'Epaisseur Lipstick', name = 'lipstick_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = 'Couleur Lipstick 1', name = 'lipstick_3', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = 'Couleur Lipstick 2', name = 'lipstick_4', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = 'Accessoire Oreilles',name = 'ears_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = 'Couleur Accessoire', name = 'ears_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65, textureof = 'ears_1'}, -- + {label = 'T-Shirt 1', name = 'tshirt_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- + {label = 'T-Shirt 2', name = 'tshirt_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'tshirt_1'}, -- + {label = 'Torse 1', name = 'torso_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- + {label = 'Torse 2', name = 'torso_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'torso_1'}, -- + {label = 'Calques 1', name = 'decals_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- + {label = 'Calques 2', name = 'decals_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'decals_1'}, -- + {label = 'Bras', name = 'arms', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- + {label = 'Jambes 1', name = 'pants_1', value = 0, min = 0, zoomOffset = 0.8, camOffset = -0.5}, -- + {label = 'Jambes 2', name = 'pants_2', value = 0, min = 0, zoomOffset = 0.8, camOffset = -0.5, textureof = 'pants_1'}, -- + {label = 'Chaussures 1', name = 'shoes_1', value = 0, min = 0, zoomOffset = 0.8, camOffset = -0.8}, + {label = 'Chaussures 2', name = 'shoes_2', value = 0, min = 0, zoomOffset = 0.8, camOffset = -0.8, textureof = 'shoes_1'}, + {label = 'Masque 1', name = 'mask_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = 'Masque 2', name = 'mask_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65, textureof = 'mask_1'}, -- + {label = 'Gilet pare-balle 1', name = 'bproof_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- + {label = 'Gilet pare-balle 2', name = 'bproof_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'bproof_1'}, -- + {label = 'Chaine 1', name = 'chain_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = 'Chaine 2', name = 'chain_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65, textureof = 'chain_1'}, -- + {label = 'Casque 1', name = 'helmet_1', value = -1, min = -1, componentId = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = 'Casque 2', name = 'helmet_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65, textureof = 'helmet_1'}, -- + {label = 'Lunettes 1', name = 'glasses_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = 'Lunettes 2', name = 'glasses_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65, textureof = 'glasses_1'}, -- + {label = 'Sac', name = 'bags_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, + {label = 'Couleur Sac', name = 'bags_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'bags_1'} } local LastSex = 0 @@ -43,35 +61,35 @@ for i=1, #Components, 1 do end function LoadDefaultModel(loadMale) - + local playerPed = GetPlayerPed(-1) - local characterModel + local characterModel - if loadMale then - characterModel = GetHashKey('mp_m_freemode_01') - else - characterModel = GetHashKey('mp_f_freemode_01'); - end + if loadMale then + characterModel = GetHashKey('mp_m_freemode_01') + else + characterModel = GetHashKey('mp_f_freemode_01'); + end - RequestModel(characterModel) + RequestModel(characterModel) - Citizen.CreateThread(function() - - while not HasModelLoaded(characterModel) do - RequestModel(characterModel) - Citizen.Wait(0) - end + Citizen.CreateThread(function() - if IsModelInCdimage(characterModel) and IsModelValid(characterModel) then - SetPlayerModel(PlayerId(), characterModel) - SetPedDefaultComponentVariation(playerPed) - end + while not HasModelLoaded(characterModel) do + RequestModel(characterModel) + Citizen.Wait(0) + end - SetModelAsNoLongerNeeded(characterModel) + if IsModelInCdimage(characterModel) and IsModelValid(characterModel) then + SetPlayerModel(PlayerId(), characterModel) + SetPedDefaultComponentVariation(playerPed) + end - TriggerEvent('skinchanger:modelLoaded') + SetModelAsNoLongerNeeded(characterModel) - end) + TriggerEvent('skinchanger:modelLoaded') + + end) end @@ -83,14 +101,30 @@ function GetMaxVals() sex = 1, face = 45, skin = 45, - beard_1 = GetNumHeadOverlayValues(1), + age_1 = GetNumHeadOverlayValues(3)-1, + age_2 = 10, + beard_1 = GetNumHeadOverlayValues(1)-1, beard_2 = 10, - beard_3 = 63, - beard_4 = 63, + beard_3 = GetNumHairColors()-1, + beard_4 = GetNumHairColors()-1, hair_1 = GetNumberOfPedDrawableVariations(playerPed, 2) - 1, hair_2 = GetNumberOfPedTextureVariations(playerPed, 2, Character['hair_1']) - 1, - hair_color_1 = 22, - hair_color_2 = 4, + hair_color_1 = GetNumHairColors()-1, + hair_color_2 = GetNumHairColors()-1, + eyebrows_1 = GetNumHeadOverlayValues(2)-1, + eyebrows_2 = 10, + eyebrows_3 = GetNumHairColors()-1, + eyebrows_4 = GetNumHairColors()-1, + makeup_1 = GetNumHeadOverlayValues(4)-1, + makeup_2 = 10, + makeup_3 = 74, + makeup_4 = 74, + lipstick_1 = GetNumHeadOverlayValues(8)-1, + lipstick_2 = 10, + lipstick_3 = 9, + lipstick_4 = 9, + ears_1 = GetNumberOfPedPropDrawableVariations(playerPed, 1) - 1, + ears_2 = GetNumberOfPedPropTextureVariations(playerPed, 1, Character['ears_1'] - 1), tshirt_1 = GetNumberOfPedDrawableVariations(playerPed, 8) - 1, tshirt_2 = GetNumberOfPedTextureVariations(playerPed, 8, Character['tshirt_1']) - 1, torso_1 = GetNumberOfPedDrawableVariations(playerPed, 11) - 1, @@ -102,12 +136,14 @@ function GetMaxVals() pants_2 = GetNumberOfPedTextureVariations(playerPed, 4, Character['pants_1']) - 1, shoes_1 = GetNumberOfPedDrawableVariations(playerPed, 6) - 1, shoes_2 = GetNumberOfPedTextureVariations(playerPed, 6, Character['shoes_1']) - 1, - mask_1 = GetNumberOfPedDrawableVariations(playerPed, 1) - 1, - mask_2 = GetNumberOfPedTextureVariations(playerPed, 1, Character['mask_1']) - 1, - bproof_1 = GetNumberOfPedDrawableVariations(playerPed, 9) - 1, - bproof_2 = GetNumberOfPedTextureVariations(playerPed, 9, Character['bproof_1']) - 1, - chain_1 = GetNumberOfPedDrawableVariations(playerPed, 7) - 1, - chain_2 = GetNumberOfPedTextureVariations(playerPed, 7, Character['chain_1']) - 1, + mask_1 = GetNumberOfPedDrawableVariations(playerPed, 1) - 1, + mask_2 = GetNumberOfPedTextureVariations(playerPed, 1, Character['mask_1']) - 1, + bproof_1 = GetNumberOfPedDrawableVariations(playerPed, 9) - 1, + bproof_2 = GetNumberOfPedTextureVariations(playerPed, 9, Character['bproof_1']) - 1, + chain_1 = GetNumberOfPedDrawableVariations(playerPed, 7) - 1, + chain_2 = GetNumberOfPedTextureVariations(playerPed, 7, Character['chain_1']) - 1, + bags_1 = GetNumberOfPedDrawableVariations(playerPed, 5) - 1, + bags_2 = GetNumberOfPedTextureVariations(playerPed, 5, Character['bags_1']) - 1, helmet_1 = GetNumberOfPedPropDrawableVariations(playerPed, 0) - 1, helmet_2 = GetNumberOfPedTextureVariations(playerPed, 0, Character['helmet_1']) - 1, glasses_1 = GetNumberOfPedPropDrawableVariations(playerPed, 1) - 1, @@ -133,6 +169,8 @@ function ApplySkin(skin, clothes) k ~= 'sex' and k ~= 'face' and k ~= 'skin' and + k ~= 'age_1' and + k ~= 'age_2' and k ~= 'beard_1' and k ~= 'beard_2' and k ~= 'beard_3' and @@ -140,7 +178,19 @@ function ApplySkin(skin, clothes) k ~= 'hair_1' and k ~= 'hair_2' and k ~= 'hair_color_1' and - k ~= 'hair_color_2' + k ~= 'hair_color_2' and + k ~= 'eyebrows_1' and + k ~= 'eyebrows_2' and + k ~= 'eyebrows_3' and + k ~= 'eyebrows_4' and + k ~= 'makeup_1' and + k ~= 'makeup_2' and + k ~= 'makeup_3' and + k ~= 'makeup_4' and + k ~= 'lipstick_1' and + k ~= 'lipstick_2' and + k ~= 'lipstick_3' and + k ~= 'lipstick_4' then Character[k] = v end @@ -149,26 +199,34 @@ function ApplySkin(skin, clothes) end SetPedHeadBlendData(playerPed, Character['face'], Character['face'], Character['face'], Character['skin'], Character['skin'], Character['skin'], 1.0, 1.0, 1.0, true) - SetPedHeadOverlay(playerPed, 1, Character['beard_1'], (Character['beard_2'] / 10) + 0.0) -- Beard - SetPedHeadOverlayColor(playerPed, 1, 1, Character['beard_3'], Character['beard_4']) -- Beard Color + + SetPedHeadOverlay(playerPed, 3, Character['age_1'], (Character['age_2'] / 10) + 0.0) -- Age + opacity + SetPedHeadOverlay(playerPed, 1, Character['beard_1'], (Character['beard_2'] / 10) + 0.0) -- Beard + opacity + SetPedHeadOverlayColor(playerPed, 1, 1, Character['beard_3'], Character['beard_4']) -- Beard Color + SetPedHeadOverlay(playerPed, 2, Character['eyebrows_1'], (Character['eyebrows_2'] / 10) + 0.0) -- Eyebrows + opacity + SetPedHeadOverlayColor(playerPed, 1, 1, Character['eyebrows_3'], Character['eyebrows_4']) -- Eyebrows Color + SetPedHeadOverlay(playerPed, 4, Character['makeup_1'], (Character['makeup_2'] / 10) + 0.0) -- Makeup + opacity + SetPedHeadOverlayColor(playerPed, 1, 1, Character['makeup_3'], Character['makeup_4']) -- Makeup Color + SetPedHeadOverlay(playerPed, 8, Character['lipstick_1'], (Character['lipstick_2'] / 10) + 0.0) -- Lipstick + opacity + SetPedHeadOverlayColor(playerPed, 2, 1, Character['lipstick_3'], Character['lipstick_4']) -- Lipstick Color SetPedComponentVariation(playerPed, 2, Character['hair_1'], Character['hair_2'], 2) -- Hair - SetPedHairColor(playerPed, Character['hair_color_1'], Character['hair_color_2']) -- Hair Color + SetPedHairColor(playerPed, Character['hair_color_1'], Character['hair_color_2']) -- Hair Color + SetPedPropIndex(playerPed, 2, Character['ears_1'], Character['ears_2'], 2) -- Ears Accessories SetPedComponentVariation(playerPed, 8, Character['tshirt_1'],Character['tshirt_2'], 2) -- Tshirt SetPedComponentVariation(playerPed, 11, Character['torso_1'], Character['torso_2'], 2) -- torso parts SetPedComponentVariation(playerPed, 3, Character['arms'], 0, 2) -- torso SetPedComponentVariation(playerPed, 10, Character['decals_1'], Character['decals_2'], 2) -- decals SetPedComponentVariation(playerPed, 4, Character['pants_1'], Character['pants_2'], 2) -- pants SetPedComponentVariation(playerPed, 6, Character['shoes_1'], Character['shoes_2'], 2) -- shoes - SetPedComponentVariation(playerPed, 1, Character['mask_1'], Character['mask_2'], 2) -- mask - SetPedComponentVariation(playerPed, 9, Character['bproof_1'], Character['bproof_2'], 2) -- bulletproof + SetPedComponentVariation(playerPed, 1, Character['mask_1'], Character['mask_2'], 2) -- mask + SetPedComponentVariation(playerPed, 9, Character['bproof_1'], Character['bproof_2'], 2) -- bulletproof SetPedComponentVariation(playerPed, 7, Character['chain_1'], Character['chain_2'], 2) -- chain - + SetPedComponentVariation(playerPed, 5, Character['bags_1'], Character['bags_2'], 2) -- Bag if Character['helmet_1'] == -1 then ClearPedProp(playerPed, 0) else SetPedPropIndex(playerPed, 0, Character['helmet_1'], Character['helmet_2'], 2) -- Helmet end - SetPedPropIndex(playerPed, 1, Character['glasses_1'], Character['glasses_2'], 2) -- Glasses end @@ -185,6 +243,8 @@ AddEventHandler('skinchanger:getData', function(cb) for i=1, #components, 1 do if k == components[i].name then components[i].value = v + --components[i].zoomOffset = Components[i].zoomOffset + --components[i].camOffset = Components[i].camOffset end end end @@ -210,6 +270,8 @@ end) AddEventHandler('skinchanger:modelLoaded', function() + ClearPedProp(GetPlayerPed(-1), 0) + if LoadSkin ~= nil then ApplySkin(LoadSkin) @@ -236,7 +298,7 @@ AddEventHandler('skinchanger:loadSkin', function(skin) else LoadDefaultModel(false) end - + LastSex = skin['sex'] end) From fbb16673ba35d7145daeb3d83efe513dfab92442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 6 Aug 2017 14:25:31 +0200 Subject: [PATCH 0169/3224] Remove DELETE FROM --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index ba07b928..b4d1f90c 100644 --- a/server/main.lua +++ b/server/main.lua @@ -23,7 +23,7 @@ AddEventHandler('esx_garage:setParking', function(garage, zone, vehicleProps) else MySQL.Async.execute( - 'DELETE FROM `user_parkings` WHERE `identifier` = @identifier AND `garage` = @garage AND zone = @zone; INSERT INTO `user_parkings` (`identifier`, `garage`, `zone`, `vehicle`) VALUES (@identifier, @garage, @zone, @vehicle)', + 'INSERT INTO `user_parkings` (`identifier`, `garage`, `zone`, `vehicle`) VALUES (@identifier, @garage, @zone, @vehicle)', { ['@identifier'] = xPlayer.identifier, ['@garage'] = garage; From be7dc860f522b98a40af93cc5e63819614e5424c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 6 Aug 2017 14:35:43 +0200 Subject: [PATCH 0170/3224] Add seat check --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index c348aefd..55822d69 100644 --- a/client/main.lua +++ b/client/main.lua @@ -18,7 +18,7 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) local coords = GetEntityCoords(playerPed) local garage = Config.Garages[name] - if IsPedInAnyVehicle(playerPed, false) then + if IsPedInAnyVehicle(playerPed, false) and GetPedInVehicleSeat(vehicle, -1) == playerPed then local vehicle, distance = ESX.Game.GetClosestVehicle({ x = coords.x, From d9938db145e4747260ba08aada1e853a6320a4c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 6 Aug 2017 14:38:05 +0200 Subject: [PATCH 0171/3224] Seat check fix --- client/main.lua | 108 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 76 insertions(+), 32 deletions(-) diff --git a/client/main.lua b/client/main.lua index 55822d69..5d861352 100644 --- a/client/main.lua +++ b/client/main.lua @@ -18,7 +18,7 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) local coords = GetEntityCoords(playerPed) local garage = Config.Garages[name] - if IsPedInAnyVehicle(playerPed, false) and GetPedInVehicleSeat(vehicle, -1) == playerPed then + if IsPedInAnyVehicle(playerPed, false) then local vehicle, distance = ESX.Game.GetClosestVehicle({ x = coords.x, @@ -28,54 +28,98 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) if distance <= 2.0 then - local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) + if GetPedInVehicleSeat(vehicle, -1) == playerPed then - local spawnCoords = { - x = garage.InteriorSpawnPoint.Pos.x, - y = garage.InteriorSpawnPoint.Pos.y, - z = garage.InteriorSpawnPoint.Pos.z - } + local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) - ESX.Game.DeleteVehicle(vehicle) + local spawnCoords = { + x = garage.InteriorSpawnPoint.Pos.x, + y = garage.InteriorSpawnPoint.Pos.y, + z = garage.InteriorSpawnPoint.Pos.z + } - ESX.Game.Teleport(playerPed, spawnCoords, function() + ESX.Game.DeleteVehicle(vehicle) - TriggerEvent('instance:create') + ESX.Game.Teleport(playerPed, spawnCoords, function() - ESX.Game.SpawnLocalVehicle(vehicleProps.model, spawnCoords, garage.InteriorSpawnPoint.Heading, function(vehicle) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - ESX.Game.SetVehicleProperties(vehicle, vehicleProps) - end) + TriggerEvent('instance:create') - ESX.TriggerServerCallback('esx_vehicleshop:getVehiclesInGarage', function(vehicles) + ESX.Game.SpawnLocalVehicle(vehicleProps.model, spawnCoords, garage.InteriorSpawnPoint.Heading, function(vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + ESX.Game.SetVehicleProperties(vehicle, vehicleProps) + end) - for i=1, #garage.Parkings, 1 do - for j=1, #vehicles, 1 do + ESX.TriggerServerCallback('esx_vehicleshop:getVehiclesInGarage', function(vehicles) - if i == vehicles[j].zone then - - local spawn = function(j) + for i=1, #garage.Parkings, 1 do + for j=1, #vehicles, 1 do - ESX.Game.SpawnLocalVehicle(vehicles[j].vehicle.model, { - x = garage.Parkings[i].Pos.x, - y = garage.Parkings[i].Pos.y, - z = garage.Parkings[i].Pos.z - }, garage.Parkings[i].Heading, function(vehicle) - ESX.Game.SetVehicleProperties(vehicle, vehicles[j].vehicle) - end) + if i == vehicles[j].zone then + + local spawn = function(j) + + ESX.Game.SpawnLocalVehicle(vehicles[j].vehicle.model, { + x = garage.Parkings[i].Pos.x, + y = garage.Parkings[i].Pos.y, + z = garage.Parkings[i].Pos.z + }, garage.Parkings[i].Heading, function(vehicle) + ESX.Game.SetVehicleProperties(vehicle, vehicles[j].vehicle) + end) + + end + + spawn(j) end - spawn(j) + end + end + + end, name) + + end) + + else + + ESX.Game.Teleport(playerPed, { + x = garage.InteriorSpawnPoint.Pos.x, + y = garage.InteriorSpawnPoint.Pos.y, + z = garage.InteriorSpawnPoint.Pos.z + }, function() + + TriggerEvent('instance:create') + + ESX.TriggerServerCallback('esx_vehicleshop:getVehiclesInGarage', function(vehicles) + + for i=1, #garage.Parkings, 1 do + for j=1, #vehicles, 1 do + + if i == vehicles[j].zone then + + local spawn = function(j) + + ESX.Game.SpawnLocalVehicle(vehicles[j].vehicle.model, { + x = garage.Parkings[i].Pos.x, + y = garage.Parkings[i].Pos.y, + z = garage.Parkings[i].Pos.z + }, garage.Parkings[i].Heading, function(vehicle) + ESX.Game.SetVehicleProperties(vehicle, vehicles[j].vehicle) + end) + + end + + spawn(j) + + end end - end - end - end, name) + end, name) - end) + end) + + end end From d6b50975fca18026e43ec980ec6416db4c59254f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 6 Aug 2017 18:08:54 +0200 Subject: [PATCH 0172/3224] bring back skinchanger:loadDefaultModel event --- client/main.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/main.lua b/client/main.lua index 8bf6469b..69edcafa 100644 --- a/client/main.lua +++ b/client/main.lua @@ -294,9 +294,9 @@ AddEventHandler('skinchanger:loadSkin', function(skin) LoadSkin = skin if skin['sex'] == 0 then - LoadDefaultModel(true) + TriggerEvent('skinchanger:loadDefaultModel', true) else - LoadDefaultModel(false) + TriggerEvent('skinchanger:loadDefaultModel', false) end LastSex = skin['sex'] @@ -312,9 +312,9 @@ AddEventHandler('skinchanger:loadClothes', function(playerSkin, clothesSkin) } if playerSkin['sex'] == 0 then - LoadDefaultModel(true) + TriggerEvent('skinchanger:loadDefaultModel', true) else - LoadDefaultModel(false) + TriggerEvent('skinchanger:loadDefaultModel', false) end LastSex = playerSkin['sex'] From c6aababf26344cc77314176c97b73e3dc993e63f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 6 Aug 2017 18:12:36 +0200 Subject: [PATCH 0173/3224] Update essentialmode download link --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 244da74e..286e7a95 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,8 @@ https://discord.me/fivem_esx [REQUIREMENTS] -- essentialmode-mysql : https://github.com/FXServer-ESX/fxserver-essentialmode-mysql +- essentialmode => https://forum.fivem.net/t/release-essentialmode-base/3665 +- esplugin_mysql => https://forum.fivem.net/t/release-essentialmode-base/3665/1181 [INSTALLATION] From 53a5ed6017911d2f4ecbfd9ddb04e3117d058483 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 6 Aug 2017 19:50:04 +0200 Subject: [PATCH 0174/3224] Add screenshot + description --- README.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 286e7a95..320dd401 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,25 @@ FXServer ES Extended https://discord.me/fivem_esx +[SCREENSHOT] + +![screenshot](http://i.imgur.com/aPFdJl3.jpg) + +[DESCRIPTION] + +Add support for accounts (bank / black money) you can also add others accounts + +Add support for inventory (press F5 ingame) => Players can now remove items from inventory + +Add support for jobs + +Loadouts are saved in database and restored on spawn + +Positions are saved in database and restored on spawn + [REQUIREMENTS] -- essentialmode => https://forum.fivem.net/t/release-essentialmode-base/3665 +- essentialmode + es_admin => https://forum.fivem.net/t/release-essentialmode-base/3665 - esplugin_mysql => https://forum.fivem.net/t/release-essentialmode-base/3665/1181 [INSTALLATION] From 4d2b430781e01aa2d3fefeef58ac9f12d19a2fac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 6 Aug 2017 20:01:00 +0200 Subject: [PATCH 0175/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 320dd401..fa8471cb 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ https://discord.me/fivem_esx Add support for accounts (bank / black money) you can also add others accounts -Add support for inventory (press F5 ingame) => Players can now remove items from inventory +Add support for inventory (press F2 ingame) => Players can now remove items from inventory Add support for jobs From 16209570a2c1763f04a88791581ae04164228e8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 7 Aug 2017 12:08:57 +0200 Subject: [PATCH 0176/3224] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 9603612e..7b3b678d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ # fxserver-esx_skin FXServer ESX Skin +[REQUIREMENTS] + +- skinchanger => https://github.com/FXServer-ESX/fxserver-skinchanger + [INSTALLATION] 1) CD in your resources/[esx] folder From e2e223d7de2716280f39cc1dddadf0b01cf70ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 7 Aug 2017 12:17:27 +0200 Subject: [PATCH 0177/3224] Update es_extended.sql --- es_extended.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/es_extended.sql b/es_extended.sql index 411e682b..834a229c 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -1,4 +1,4 @@ -USE `gta5_gamemode_essential`; +USE `essentialmode`; ALTER TABLE `users` ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, @@ -63,4 +63,4 @@ CREATE TABLE `user_inventory` ( `count` int(11) NOT NULL, PRIMARY KEY (`id`) -); \ No newline at end of file +); From 928810827f5cf857273d61106f2aa409fe7d8a65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 7 Aug 2017 12:17:43 +0200 Subject: [PATCH 0178/3224] Update esx_garage.sql --- esx_garage.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esx_garage.sql b/esx_garage.sql index 7c21f651..85334297 100644 --- a/esx_garage.sql +++ b/esx_garage.sql @@ -1,4 +1,4 @@ -USE `gta5_gamemode_essential`; +USE `essentialmode`; CREATE TABLE `user_parkings` ( @@ -9,4 +9,4 @@ CREATE TABLE `user_parkings` ( `vehicle` longtext, PRIMARY KEY (`id`) -); \ No newline at end of file +); From ede43a0fa5288d151cdf8de252c5e82b4dad8843 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 7 Aug 2017 12:18:24 +0200 Subject: [PATCH 0179/3224] Update esx_taxijob_full.sql --- esx_taxijob_full.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esx_taxijob_full.sql b/esx_taxijob_full.sql index 2d3c1eec..1faa40d0 100644 --- a/esx_taxijob_full.sql +++ b/esx_taxijob_full.sql @@ -1,3 +1,5 @@ +USE `essentialmode`; + INSERT INTO `addon_account` (name, label, shared) VALUES ('society_taxi','Taxi',1) ; From c886d83322fca6ef0ceea5b7e9caaf8dc08a5341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 7 Aug 2017 12:18:37 +0200 Subject: [PATCH 0180/3224] Update esx_taxijob_minimal.sql --- esx_taxijob_minimal.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esx_taxijob_minimal.sql b/esx_taxijob_minimal.sql index 074330de..9dd20e82 100644 --- a/esx_taxijob_minimal.sql +++ b/esx_taxijob_minimal.sql @@ -1,3 +1,5 @@ +USE `essentialmode`; + INSERT INTO `jobs` (name, label) VALUES ('taxi','Taxi') ; From 16c2a3c3d1e5e18bf993ddf42b6e44c303da662a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 7 Aug 2017 12:18:58 +0200 Subject: [PATCH 0181/3224] Update esx_vehicleshop_full.sql --- esx_vehicleshop_full.sql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/esx_vehicleshop_full.sql b/esx_vehicleshop_full.sql index 829ca82f..ec68181a 100644 --- a/esx_vehicleshop_full.sql +++ b/esx_vehicleshop_full.sql @@ -1,3 +1,5 @@ +USE `essentialmode`; + INSERT INTO `addon_account` VALUES (name, label, shared) ('society_cardealer','Concessionnaire',1) ; @@ -287,4 +289,4 @@ INSERT INTO `vehicles` (name, model, price, category) VALUES ('Woflsbane','wolfsbane',9000,'motorcycles'), ('Zombie','zombiea',9500,'motorcycles'), ('Zombie Luxuary','zombieb',12000,'motorcycles') -; \ No newline at end of file +; From b1c821da32fd7dd10e6109f85975e34e5beb6db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 7 Aug 2017 12:19:11 +0200 Subject: [PATCH 0182/3224] Update esx_vehicleshop_minimal.sql --- esx_vehicleshop_minimal.sql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/esx_vehicleshop_minimal.sql b/esx_vehicleshop_minimal.sql index 5f8cdde5..868530e9 100644 --- a/esx_vehicleshop_minimal.sql +++ b/esx_vehicleshop_minimal.sql @@ -1,3 +1,5 @@ +USE `essentialmode`; + INSERT INTO `jobs` (name, label) VALUES ('cardealer','Concessionnaire') ; @@ -283,4 +285,4 @@ INSERT INTO `vehicles` (name, model, price, category) VALUES ('Woflsbane','wolfsbane',9000,'motorcycles'), ('Zombie','zombiea',9500,'motorcycles'), ('Zombie Luxuary','zombieb',12000,'motorcycles') -; \ No newline at end of file +; From 6dcc5f9ef13ee7615dd576c0ee5498f65cfd5edb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 7 Aug 2017 12:19:30 +0200 Subject: [PATCH 0183/3224] Update esx_property.sql --- esx_property.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_property.sql b/esx_property.sql index ebd5fb05..a532e62f 100644 --- a/esx_property.sql +++ b/esx_property.sql @@ -1,4 +1,4 @@ -USE `gta5_gamemode_essential`; +USE `essentialmode`; ALTER TABLE `users` ADD COLUMN `last_property` VARCHAR(255) NULL From cc1329470efb7248340119f979e355e03574e73f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 7 Aug 2017 12:19:53 +0200 Subject: [PATCH 0184/3224] Update esx_society.sql --- esx_society.sql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/esx_society.sql b/esx_society.sql index cb097561..6f2594d9 100644 --- a/esx_society.sql +++ b/esx_society.sql @@ -1,3 +1,5 @@ +USE `essentialmode`; + CREATE TABLE `society_moneywash` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -6,4 +8,4 @@ CREATE TABLE `society_moneywash` ( `amount` int(11) NOT NULL, PRIMARY KEY (`id`) -); \ No newline at end of file +); From ce6be364f0975f70655073c87d8169a408208706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 7 Aug 2017 12:20:47 +0200 Subject: [PATCH 0185/3224] Update esx_billing.sql --- esx_billing.sql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/esx_billing.sql b/esx_billing.sql index 78a71771..f7571215 100644 --- a/esx_billing.sql +++ b/esx_billing.sql @@ -1,3 +1,5 @@ +USE `essentialmode`; + CREATE TABLE `billing` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -9,4 +11,4 @@ CREATE TABLE `billing` ( `amount` int(11) NOT NULL, PRIMARY KEY (`id`) -); \ No newline at end of file +); From 0d2f61a3a6f7d0a655d4461896132ade9194a355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 7 Aug 2017 12:21:06 +0200 Subject: [PATCH 0186/3224] Update esx_datastore.sql --- esx_datastore.sql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/esx_datastore.sql b/esx_datastore.sql index d9bc4fd5..a8d46654 100644 --- a/esx_datastore.sql +++ b/esx_datastore.sql @@ -1,3 +1,5 @@ +USE `essentialmode`; + CREATE TABLE `datastore` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, @@ -12,4 +14,4 @@ CREATE TABLE `datastore_data` ( `owner` varchar(255) NOT NULL, `data` longtext, PRIMARY KEY (`id`) -); \ No newline at end of file +); From afc58f5e75bca2d41dca4fb9e76076cc85fa8007 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 7 Aug 2017 12:21:24 +0200 Subject: [PATCH 0187/3224] Update esx_addoninventory.sql --- esx_addoninventory.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esx_addoninventory.sql b/esx_addoninventory.sql index a02c5700..5ae70805 100644 --- a/esx_addoninventory.sql +++ b/esx_addoninventory.sql @@ -1,3 +1,5 @@ +USE `essentialmode`; + CREATE TABLE `addon_inventory` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, From 7b222336bdf05de6e987faf0875a099ed30f823a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 7 Aug 2017 12:21:40 +0200 Subject: [PATCH 0188/3224] Update esx_addonaccount.sql --- esx_addonaccount.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esx_addonaccount.sql b/esx_addonaccount.sql index fa0fb335..95e9e703 100644 --- a/esx_addonaccount.sql +++ b/esx_addonaccount.sql @@ -1,3 +1,5 @@ +USE `essentialmode`; + CREATE TABLE `addon_account` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, From 0f3687f992908d91f5fa0cdfe63a18a1bc962b52 Mon Sep 17 00:00:00 2001 From: renaiku Date: Mon, 7 Aug 2017 14:35:43 +0200 Subject: [PATCH 0189/3224] Initial commit --- README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..7c8b1e8b --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# fxserver-esx_atm \ No newline at end of file From ec2ce72a5153a0852b4fb951c32a5d5dfd4bc4d7 Mon Sep 17 00:00:00 2001 From: renaiku Date: Mon, 7 Aug 2017 14:38:04 +0200 Subject: [PATCH 0190/3224] Adding files --- README.md | 16 +++++- __resource.lua | 18 ++++++ client/esx_atm_cl.lua | 129 ++++++++++++++++++++++++++++++++++++++++++ config.lua | 53 +++++++++++++++++ html/css/app.css | 49 ++++++++++++++++ html/img/cursor.png | Bin 0 -> 272 bytes html/pdown.ttf | Bin 0 -> 151512 bytes html/scripts/app.js | 78 +++++++++++++++++++++++++ html/ui.html | 28 +++++++++ server/esx_atm_sv.lua | 35 ++++++++++++ 10 files changed, 405 insertions(+), 1 deletion(-) create mode 100644 __resource.lua create mode 100644 client/esx_atm_cl.lua create mode 100644 config.lua create mode 100644 html/css/app.css create mode 100644 html/img/cursor.png create mode 100644 html/pdown.ttf create mode 100644 html/scripts/app.js create mode 100644 html/ui.html create mode 100644 server/esx_atm_sv.lua diff --git a/README.md b/README.md index 7c8b1e8b..3f67c05e 100644 --- a/README.md +++ b/README.md @@ -1 +1,15 @@ -# fxserver-esx_atm \ No newline at end of file +# fxserver-esx_atm +FXServer ESX ATM + +[INSTALLATION] + +1) CD in your resources/[esx] folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-esx_atm esx_atm +``` +3) Add this in your server.cfg : + +``` +start esx_atm +``` diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..10f49234 --- /dev/null +++ b/__resource.lua @@ -0,0 +1,18 @@ +description 'ESX ATM' + +server_script 'server/esx_atm_sv.lua' + +client_script { + 'config.lua', + 'client/esx_atm_cl.lua' +} + +ui_page 'html/ui.html' + +files { + 'html/ui.html', + 'html/pdown.ttf', + 'html/img/cursor.png', + 'html/css/app.css', + 'html/scripts/app.js' +} \ No newline at end of file diff --git a/client/esx_atm_cl.lua b/client/esx_atm_cl.lua new file mode 100644 index 00000000..89cb175d --- /dev/null +++ b/client/esx_atm_cl.lua @@ -0,0 +1,129 @@ +local GUI = {} +local hasAlreadyEnteredMarker = false +GUI.MenuIsShowed = false + +ESX = nil + +Citizen.CreateThread(function() + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end +end) + +TriggerEvent('es:setDefaultSettings', { + nativeMoneySystem = false, +}) + +RegisterNetEvent('esx_atm:closeATM') +AddEventHandler('esx_atm:closeATM', function() + SetNuiFocus(false) + GUI.MenuIsShowed = false + SendNUIMessage({ + hideAll = true + }) +end) + +RegisterNUICallback('escape', function(data, cb) + TriggerEvent('esx_atm:closeATM') + cb('ok') +end) + +RegisterNUICallback('deposit', function(data, cb) + TriggerServerEvent('esx_atm:deposit', data.amount) + cb('ok') +end) + +RegisterNUICallback('withdraw', function(data, cb) + TriggerServerEvent('esx_atm:withdraw', data.amount) + cb('ok') +end) + +-- Create blips +Citizen.CreateThread(function() + for i=1, #Config.ATMS, 1 do + local blip = AddBlipForCoord(Config.ATMS[i].x, Config.ATMS[i].y, Config.ATMS[i].z - Config.ZDiff) + SetBlipSprite (blip, Config.BlipSprite) + SetBlipDisplay(blip, 4) + SetBlipScale (blip, 0.9) + SetBlipColour (blip, 2) + SetBlipAsShortRange(blip, true) + BeginTextCommandSetBlipName("STRING") + AddTextComponentString("ATM") + EndTextCommandSetBlipName(blip) + end +end) + +-- Render markers +Citizen.CreateThread(function() + while true do + Wait(0) + local coords = GetEntityCoords(GetPlayerPed(-1)) + for i=1, #Config.ATMS, 1 do + if(GetDistanceBetweenCoords(coords, Config.ATMS[i].x, Config.ATMS[i].y, Config.ATMS[i].z, true) < Config.DrawDistance) then + DrawMarker(Config.MarkerType, Config.ATMS[i].x, Config.ATMS[i].y, Config.ATMS[i].z - Config.ZDiff, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.ZoneSize.x, Config.ZoneSize.y, Config.ZoneSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) + end + end + end +end) + +-- Activate menu when player is inside marker +Citizen.CreateThread(function() + while true do + Wait(0) + local coords = GetEntityCoords(GetPlayerPed(-1)) + local isInMarker = false + for i=1, #Config.ATMS, 1 do + if(GetDistanceBetweenCoords(coords, Config.ATMS[i].x, Config.ATMS[i].y, Config.ATMS[i].z, true) < Config.ZoneSize.x / 2) then + isInMarker = true + SetTextComponentFormat('STRING') + AddTextComponentString('Appuyez sur ~INPUT_PICKUP~ pour déposer ou retirer du ~g~cash~s~.') + DisplayHelpTextFromStringLabel(0, 0, 1, -1) + end + end + if isInMarker and not hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = true + --TriggerEvent('esx_atm:hasEnteredMarker') + end + if not isInMarker and hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = false + SetNuiFocus(false) + GUI.MenuIsShowed = false + SendNUIMessage({ + hideAll = true + }) + end + end +end) + +-- Menu interactions +Citizen.CreateThread(function() + while true do + Wait(0) + if GUI.MenuIsShowed then + DisableControlAction(0, 1, true) -- LookLeftRight + DisableControlAction(0, 2, true) -- LookUpDown + DisableControlAction(0, 142, true) -- MeleeAttackAlternate + DisableControlAction(0, 106, true) -- VehicleMouseControlOverride + if IsDisabledControlJustReleased(0, 142) then -- MeleeAttackAlternate + SendNUIMessage({ + click = true + }) + end + else + if IsControlJustReleased(0, 38) then + GUI.MenuIsShowed = true + ESX.TriggerServerCallback('esx:getPlayerData', function(data) + SendNUIMessage({ + showMenu = true, + player = { + money = data.money, + accounts = data.accounts + } + }) + end) + SetNuiFocus(true) + end + end + end +end) diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..a57596af --- /dev/null +++ b/config.lua @@ -0,0 +1,53 @@ +Config = {} +Config.MarkerType = 1 +Config.DrawDistance = 100.0 +Config.ZoneSize = {x = 3.0, y = 3.0, z = 0.3} +Config.MarkerColor = {r = 100, g = 100, b = 204} +Config.ZDiff = 2.0 +Config.BlipSprite = 431 + + Config.ATMS = { + { ['x'] = -386.733, ['y'] = 6045.953, ['z'] = 31.501}, + { ['x'] = -110.753, ['y'] = 6467.703, ['z'] = 31.784}, + { ['x'] = 155.4300, ['y'] = 6641.991, ['z'] = 31.784}, + { ['x'] = 174.6720, ['y'] = 6637.218, ['z'] = 31.784}, + { ['x'] = 1703.138, ['y'] = 6426.783, ['z'] = 32.730}, + { ['x'] = 1735.114, ['y'] = 6411.035, ['z'] = 35.164}, + { ['x'] = 1702.842, ['y'] = 4933.593, ['z'] = 42.051}, + { ['x'] = 1967.333, ['y'] = 3744.293, ['z'] = 32.272}, + { ['x'] = 1174.532, ['y'] = 2705.278, ['z'] = 38.027}, + { ['x'] = 2564.399, ['y'] = 2585.100, ['z'] = 38.016}, + { ['x'] = 2558.683, ['y'] = 349.6010, ['z'] = 108.050}, + { ['x'] = 2558.051, ['y'] = 389.4817, ['z'] = 108.660}, + { ['x'] = 1077.692, ['y'] = -775.796, ['z'] = 58.218}, + { ['x'] = 1139.018, ['y'] = -469.886, ['z'] = 66.789}, + { ['x'] = 1168.975, ['y'] = -457.241, ['z'] = 66.641}, + { ['x'] = 1153.884, ['y'] = -326.540, ['z'] = 69.245}, + { ['x'] = 236.4638, ['y'] = 217.4718, ['z'] = 106.840}, + { ['x'] = 265.0043, ['y'] = 212.1717, ['z'] = 106.780}, + { ['x'] = -164.568, ['y'] = 233.5066, ['z'] = 94.919}, + { ['x'] = -1827.04, ['y'] = 785.5159, ['z'] = 138.020}, + { ['x'] = -1409.39, ['y'] = -99.2603, ['z'] = 52.473}, + { ['x'] = -1215.64, ['y'] = -332.231, ['z'] = 37.881}, + { ['x'] = -2072.41, ['y'] = -316.959, ['z'] = 13.345}, + { ['x'] = -2975.72, ['y'] = 379.7737, ['z'] = 14.992}, + { ['x'] = -2962.60, ['y'] = 482.1914, ['z'] = 15.762}, + { ['x'] = -3144.13, ['y'] = 1127.415, ['z'] = 20.868}, + { ['x'] = -1305.40, ['y'] = -706.240, ['z'] = 25.352}, + { ['x'] = -717.614, ['y'] = -915.880, ['z'] = 19.268}, + { ['x'] = -526.566, ['y'] = -1222.90, ['z'] = 18.434}, + { ['x'] = 149.4551, ['y'] = -1038.95, ['z'] = 29.366}, + { ['x'] = -846.304, ['y'] = -340.402, ['z'] = 38.687}, + { ['x'] = -1216.27, ['y'] = -331.461, ['z'] = 37.773}, + { ['x'] = -56.1935, ['y'] = -1752.53, ['z'] = 29.452}, + { ['x'] = -273.001, ['y'] = -2025.60, ['z'] = 30.197}, + { ['x'] = 314.187, ['y'] = -278.621, ['z'] = 54.170}, + { ['x'] = -351.534, ['y'] = -49.529, ['z'] = 49.042}, + { ['x'] = -1570.197, ['y'] = -546.651, ['z'] = 34.955}, + { ['x'] = 33.232, ['y'] = -1347.849, ['z'] = 29.497}, + { ['x'] = 129.216, ['y'] = -1292.347, ['z'] = 29.269}, + { ['x'] = 289.012, ['y'] = -1256.545, ['z'] = 29.440}, + { ['x'] = 1686.753, ['y'] = 4815.809, ['z'] = 42.008}, + { ['x'] = -302.408, ['y'] = -829.945, ['z'] = 32.417}, + { ['x'] = 5.134, ['y'] = -919.949, ['z'] = 29.557} +} \ No newline at end of file diff --git a/html/css/app.css b/html/css/app.css new file mode 100644 index 00000000..af32745a --- /dev/null +++ b/html/css/app.css @@ -0,0 +1,49 @@ +@font-face { + font-family: pcdown; + src: url('pdown.ttf'); +} +body { + font-family: roboto; +} +#cursor { + position: absolute; + z-index: 999999; + display: none; +} +#menu { + position: absolute; + top: 50%; + left: 50%; +} +#menu { + display : flex; + flex-direction: column; + width : 500px; + height : 150px; + margin-top : -75px; + margin-left: -250px; +} +#menu div { + display: flex; + flex-direction: row; +} +#deposit_btn { + width : 250px; + height: 50px; + font-size: 2em; +} +#deposit_amount { + width : 250px; + height : 50px; + font-size: 2em; +} +#withdraw_btn { + width : 250px; + height: 50px; + font-size: 2em; +} +#withdraw_amount { + width : 250px; + height : 50px; + font-size: 2em; +} \ No newline at end of file diff --git a/html/img/cursor.png b/html/img/cursor.png new file mode 100644 index 0000000000000000000000000000000000000000..39536f953d701b36a90dc56084bafd988371a2fb GIT binary patch literal 272 zcmeAS@N?(olHy`uVBq!ia0vp^q9Dw{1|(OCFP#RYSkfJR9T^xl_H+M9WCij$3p^r= z85sBufiR<}hF1enP_o1|q9iy!t)x7$D3zfgF*C13FE6!3!9>qM&(L5k7uNxxqFzrI z#}Etut!FreS`>I(0^ikVp5f1PInc0ibrsXWO3z8Ee_BE>W<&%Ean9H1Y|@_Ma)5tI zP3vrppG@U}o4EJ`H!a-_TKCSz%v`zHX&3lrYRgJzbSuAt9 z@6PvoS_%Jm+&BGp_A+yZ?Fo&SwU@JtJ?kA`YTb#E`^&mC!8qZZWp1Mjt5em&H79@$ OWAJqKb6Mw<&;$S!<6)ox literal 0 HcmV?d00001 diff --git a/html/pdown.ttf b/html/pdown.ttf new file mode 100644 index 0000000000000000000000000000000000000000..69c76cf3f2a6bbc93f570124554fec06d7bbac25 GIT binary patch literal 151512 zcmeFa2Y_5hefU2!Z~N|*-Mziu_V)UnPFHnSv9wn2cS7Bki)>jsV;dXW*a8#FHYU_i zf&o*4L=Dw3#T18{KpaRDA%$NE*akuj0SpNc0_g7l`ObT9cdto;*d%|#*_zvX`=)(o z=G*7{Raz;PqzI_WO_LM5-@E03T}tUjrGm|ycJE#LgZDlCuu`E_O4aV1*u8Z4s=xZt z_mygXDYdS+>iWYsKI?~NxAOOQd4Ka&x8BkkxIg|zWj4H%?+1?Fcu$K}aNwOU-l8OrqDL;cog9KQbQ`@gaBPx$+7%<20#-f;6R&6ic*sLas4N>#;fyy@y2 z2d4hDTA2yy|6V1qiK%AQuk>|?Z+V7_0408AX6!dw`sW$ovi}0g@Y_)dJ)o~pT7TWX zol}!)pE{(jR8#61>K64Jb*K7W^-}fw>OS=*^)~fx^?>@Y`ndWN_2=rZ)!(UqQje-{ zsqdPmJkICj%xi7=`UT6<_ubFQnT6l{A9}817D8Gj zR8*DE+@>n|*FW=s+CKAu-ad1ip5WhZ{=InS0n@;9qrN6J^asr2)CjW@6F|J=XXeu- zf2f(eXYQT(>lxOTHy@h$m*RIbzgPUsceDQD?;p*4l=ok0>#?)kpP8(DW1qP#X_Zsu z?B;4!r?RSB4Xe$1yPnXy^$YY%_1pCW`h)sQ`Wq%>!X{>_O_Nz-#?5lG$?Px_=5q6N zbG>=Fd7XJ9tEXv0vqJ&`2~|O>(&7>|K&uz1VP_^u450qQT-cxIwA&^+R^cf2bd+AFH3}4&AA{bdS#Ki}YH(POsM+^hUi|Z_!)zHpaI@@3dpwtM_^1 ze2;!FV|_oP{iuvrPwN>w=7@QLxz8Yap0oE#NSFD`bg_vIj=cbbXLdWzG6{wg96P+?%O zU4;Y=e4fw~eBP~hQvwm*d5?Y%XZOAOy|np$4XyzyA5}qtiZTY6Py!PbG{a_CX<#zK zlMBoRl&j5Zo^LT*_`K6Fa-g$^Cs&)RdGn|_%9Cr&wUjrRn|OY&0mlHXSM%ic=Jk|s z24+EK++d;RSg1L`teklY)Qp9i1|#(YJJ}fl3$LKs&VL~bsepx)v5+zrQb7xyfQ3%b zLMLdU6R^+;TId)H9mhgPTj)3zI@&@U$QOH}BU-Nzowv@lW?|uJMrE84p0Y-Q0ztdmSkF&e` z&1z@R+3H*uxIg&Oa9enNcxU*E$h#w-jeIK_iPlF~MK?w#qgO`niM}R!D)yY%y|Me_ zk0<`U{80HF<*%str-~m{R##p?`!SVL^{P!hoso8^xR&3;Dh|eX)F{8@?+yI!eKKf) zZqwb+m{GlgRouvmy$vWivR755{vc&mLxWXLzlpM4pQP;2auz%FTPeHr+bO&CJ1Kkh zyD0ngyD9tG`9>{~ov#M;`zV*{`zZ(YA5jiz!N0@$1C%5BLzJWXLCP`xVajFtBb4L% zW0b4(A5gBh{cg~w_`FfSg>sXA2jv$1hm>1wzuRoT+ikx)Y>yMR$4T4cF5Al<+sj_t z%Rbx7e$Jy&m)O1zvBm-YDf!!e`mFsV>mhi#Q9sPz-L~AUKhNha`fujE@g@6)l$-V6 z+czGwZy5GkLVv@4`!DuMvs%qA-TJH1bNzGLa0Gj(N)w~Z>K{<%G`Nd(`59%GK110j zct#Bv+4)P2Lpf*!BMg}^<*-Rmj+%1HF;hvo%%mvC^%Ioq^uJSX&_AZ!sQ-&{lWlXG zZF8q>bHcVcY1`aoTiat>+iP3fXItA3eiMi~VA^s8{^zf5TW&TreBNSryoIo7vfoL$ z*|bn@HEooafEAv`NxMuPVej9lZdK1!cdHkwm%&xNUY%0!Q14YAP#;yFRG(E}P^Z;D zsDD;pSC2!_ex!Z|8VKoxPU%|RtlM?39@NY9D$`H9j^J4!xSTR;+9`9Uld|1(QFfRf z%1+Zq*=3eccAEjp9y3VUYlbNMz}oC`!P-E1lya#VqZ~BLD2L2A<*->nIcio?j+s@I z%glw880Fc``v7o@_DQ6ahvUNhwX8v?Qz2PIB9#_ zW&7G=``T;!+GqRP4+roo?>3)%G#eR(W1vL9Y=Sat@{~EVma^TfqwFvnD7(xi%5Jln zvQOw2u-Qtv)NG?1G}|eM%nr(7Gf6pWc2SO*r%^65yD7(^bOM_-l zZ?f%gw(W1T?eDbhPuTV+ZTq`y%X@6gdu_}6Y|H!M5dPcz^E{mSG<`r{rjMA*7@Z?D z83zWLa@br)IbxncIcjd895XjkE;G-h9EUFuDBeuD%Iu|FXZBOBwJGA*lx$L!;WF69m9kj!=xR^h_e%s@r zl5_nm+U+*arCe#`^Ja4^R zi`6UCYv4lOqTZ?QS07RjsZXmvQ-7)cR(%<6{+sGM@UK5nztBcUbh)n5^|}=fwqFnH z3-oHe-n@+V9pQ~wAE9bl^ShKe^FqpY^CHR)^AgHV^LvzC=H-;#<`tAZ=JzRk&8sN; z;Iw3AUQIb*UPHOmyq0p%+($WNUPn1>-at8G{(y4S2<;p*Cn=X1p<&~en_X$1&*ydK z1(fS;?;FgE`MlA*lyZ~peY1HbpSRk6x7mJo*nW4~ekW|dleXVowy!<5uf4XfeYUUt z1-fO>;a%`LKQC-Po;F$rICLw-|N4&-xb^WTmJ6WQf}6NXWw|#zEPyB zoAtlgCqlu$Yd(f$fF)!n5m##W|EZS`g@e?^nXxp)c;Aj$+ou5wzku@Hep+vw5{#3?d-Ab?6vLe zv+e9RY3iPhlKM1OC}_8(rkgzq+V!h(8b0p#H3vTCTa+J80y50V+)}jeWq9YJ$ zcfI$W?1*ypJKh^Nl)Q0c$>(SKpF=OzJCq6iu8Qdca91~}oAp6`vA#qf(wA!Z*wC$L zv0k8GgqG%|QX)p(qMB45p6t2kn16~y)vu508}(cCcg-^MLi4vyqqEO>h4XIbv(DE7 zt%2ddk-(b*?+koB*dM$j_~-O%PwjWYOKjEhc@G*t zD<7g0=|)#Gs{hQs_XWzO`Y$L4^#jmdE2gL6>HpzeyZOz$}`hU*=t%U2Thi8)PA0{ zpZB2OE4+`s$Z|jC7F+K&TkqMFOU-jA2hHu2qvkl}RwK_R?DI+ceBqXUhqrR(4$5A0 zC*@Le7v-S2n{w2gpxkPoPuS;^_W2%mGMW>A-PqxI_V{-57T(U8w^R0-Kcrl0-bp!V z-bFcT-bT5_yn}M9{dU5BJ88dNcx>IM(vXc`()BSDegWQUrq}zK5EP2H|}XFJxBf- z{G6@xm$r_S3!RhG_MLyCT&n+>a!`Mba#a5#*Hn5$Ry zf%%rGah|W@zbds(ZBrR+FT23NyVZW)JH&tTZcwH9KBH=|RT=(HVWkk=e28!Rut#jB z=61e`g1LM6rjK?*Y6!d*Rb%uJx0Z@>df0*`V;g-`)5|Ve+e<(7)NssaoqOmf0G;aR zZ{_~x^RW6^q{75w$ZRH}19vKQ17FKL?9ZNqlM~>nn#a~Ttuq&>KX)Eif8MIp^W;l& z0!*jC$quFW&pE}o<)@J+d_rCfaWWKh`?mLu{n{(gKtS=t`VfXX2?XORp~|4$VyR04 z2^TWe)URbe^+2W(%G<13=r;>4%>k1Rs6rR8>akGo2RZ|4DHKj1G=i023|cpCZ8|G} z)GBo$vhW&ab&*;N%+_N+*r+xEKG=(GVLv+8gV6g+ShGvf zzFw}bU=Ghi5A(ZdUtghKt=@q4^`v^UdMg^4x1oo9r}{(nF09b+Rqs*nLqqcbdfE4@ z52^>z)qD&M?L+F1^&}eHtI*_5>8Gh@VYPmSdb++ATlO{jIqLc9wfZ*oOntk4E_xrO zZ_>BuoAnxfTwSZ4P2X=S5W{(UT451X$# z_d4%#KHdEM=KpA|YOQZ=Zf$GrY#nS}(Yn6%#@1)IzNq!R*_v!yc2D-QHq%zomTIeS zYi{dn+uU|V+tqD<*71eM*5M%_d#M#z-_ML<=&?J|V=vRond4>jQ)~XreA(;g&gOq_ zO}EyzHnz6fewN#QZfU*K>t}cN65CI*q@N?w&!c!E%zS6&>ocF3`Si@EW`aNnz5#99bcmyM@DoPJRae(^ZC4lQ9sH`)55e&c*tsv?9n_8^mI}i-80C(D))E;XpVP z93eGaD$(d&tQxw?T81%f6`!2 zz7so|*08%wQ11vj0f)aY3I??fMuL%W2&bJuDpcDiV@p%)vtw&f8}sYpQ4>ytAf92h zw=8IMdB6x{_QrH15?@nUVH_vnFw{UxpryH~v7x@Mwx&8$l}_59RI)Oe>C?H)NM%GY!_H zmg3(STTZRWk27i&js(I7AaIU}I0ux8MVX<|`&BS#LCIoLFQ?i@vdLslig>24!;T|6 ze4&;lqg<)&Sh8(RT9%J8r&r(p9<7ae-PF{&+ut`mV?T9wcb_!vX5XLe>gqaWI?SFw zodouEGha5pj|9-F7qN-Up$K(jIfa9HZ6WQh*(W%F$9yI9Fb=O4~{bb0Pp@~oS#6tZa-?i(?q%lu3_wGCSV}8j# zlQZ;9&Xc2>@^E=_bXXC+!|+L8B#Xm&bjteDT_fRv`qOo$><2%PdUwq%*RORpz+-jf z+veerN|o1&p@%~ORiP_DAT=%m$>dzjk@@!2)cxy?S^w~abKR~}=FB)27HPMUc86`d zZF!L>+)eK9kxD1eTNSE2o680(`fA2ThQUjH>}rdd8l}bir=}i0Y0T%%sa?Og7Z)@Q z$M<9XPS);Pby@zBG98VDquUZX<}k&W-XBOAg~5GWvNGfZ`DAuilt-L!I6k4`{4kND zN3J@2`K5<0-n)Bp=f?G`R*a7g4lL>G>FR86X{xWSEN7C}>TA;p)}w1c=h{M#T@^z*vT&`(>XXDF8 zhMSEvL<^ZJp2*kbMo*<$E30DBSXC;ueS0cpKUTJ;%4$-vfvTEhS68y8Y9N-XDLc>i zbpKd=Lo8TX+t^Um(o)sXSX&v4HPnw)H)rEbflMaQ6wfwSpU*o2?@oBU&*8Ta7mN>* z!s`lHLvn%|KG>Mxju6j+vb*9cZn0-L**ET^OSbdJUiGTu_uhNMy~pLZ-52#UF9ge+ zq(U~|46)#NJGUknPnyn?4|CukdQa#I{ql3} z_wli8CZU}tPMxAbf)a-Dq=hkHMr84gvpnexfp6>I4BrO z>Wh^29rii(>!rRtc1Igugz4wj0xN>#kkj-(_}o zKTM0vznbFP%)eXx@q;<-Sd8w1As7zH{Dqgmo*w{v2b}$i$xlK%pgdrXiHL{XeK3^P zK^!}KCBVS@;b7>9+sU~q0ETLtA1&XBlvSV48Hv6A&JJr)?PLG@(8~cF%tLZQ4CDUIz^?{Oo*PuS+ z?>oq6FjN3|7=VWXcrX~)sRDsT08X7iDChz35d7uYDgp3W?*s6&R&W7c1A7N!CsbGf z-k|H}0z8*ZLVw5L?kqQTmj~k+{iV|*Z*<$2+&#(O16t5D|D4yTth(Oa zJ{=6+We_+Puo8mVT>gMvrzXPQUdxLct>FO4{yNKx2lG{0wKg@>rIQtjSQIwCMps8X zHr}2VpM7wL-31M`TWIXgDLFN=Q5gM{8REl)eq@)O$Igi#PW-1ifMp%x&IWmmy%AFF z`79el>($K7V&nK4nF}b22O$+oCIjVtBbuF&and?C{S*DA|J0A1x_25h3U>6)Uun8)l|M#2Al zhwObON;xHm!vBBb;{)N)z(c!sdFOz$aw$u(%E0H= z#Sa9W9ncReJwa0{0_BM~yV4c*A~2UUNwXj>muSVeK2Hn zJ1j#-rc7r#^~vdP>zXsi-+TAfhwo+vjHy%Ir9X#%rOa<2-&Zm}aJS3iB6})*(R|TU zNWbQvG<#T|yzBUJ9XNiRJzv^C^OOFU=&>L#*3kdS{dXU}`tJ80cl)mbj{nN}a3Ea| zxma$ApnS**a!>#%*wPh*mc1o(MSvf1`3jG`S~}rZ3K+){mb28#FZBtF?dIGyKy-CM z#P5dM>I^$B76}Jhg3XNENyc0;e4IlAy6_2%`CT?O2^*5=0gnyM6|0)sW_CX0MI$L`MO zWOE7-Y2^TL5)gzOPY4O(py*?V|z)X5*m_3?+ z1#B
I4Hlt^kjdD17dxcNj!Pl%JKoqGbmWAv} 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 literal 0 HcmV?d00001 diff --git a/html/scripts/app.js b/html/scripts/app.js new file mode 100644 index 00000000..46261858 --- /dev/null +++ b/html/scripts/app.js @@ -0,0 +1,78 @@ +var documentWidth = document.documentElement.clientWidth; +var documentHeight = document.documentElement.clientHeight; + +var cursor = document.getElementById("cursor"); +var cursorX = documentWidth / 2; +var cursorY = documentHeight / 2; + +function UpdateCursorPos() { + cursor.style.left = cursorX; + cursor.style.top = cursorY; +} + +function Click(x, y) { + var element = $(document.elementFromPoint(x, y)); + element.focus().click(); +} + +$(document).mousemove(function(event) { + cursorX = event.pageX; + cursorY = event.pageY; + UpdateCursorPos(); +}); + +window.onload = function(e){ + // NUI Callback + window.addEventListener('message', function(event){ + let data = event.data; + if(data.showControls){ + $('#container').show(); + $('#menu' ).hide(); + $(cursor ).hide(); + } + if(data.showMenu){ + $('#container' ).show(); + $('#menu' ).show(); + $(cursor ).show(); + $('#deposit_amount').val(data.player.money) + let bankAmount = 0; + for(let i=0; i= 10000) + $('#withdraw_amount').val(10000) + else + $('#withdraw_amount').val(bankAmount) + } + + if(data.hideAll){ + $('#container').hide(); + $(cursor ).hide(); + } + if (data.click) { + // Avoid clicking the cursor itself, click 1px to the top/left; + Click(cursorX - 1, cursorY - 1); + } + + }) +} + +document.onkeyup = function (data) { + if (data.which == 27) { + $.post('http://esx_atm/escape', '{}'); + } +}; + +$('#container').hide() + +$('#deposit_btn').click(() => { + $.post('http://esx_atm/deposit', JSON.stringify({ + amount: $('#deposit_amount').val() + })); +}) + +$('#withdraw_btn').click(() => { + $.post('http://esx_atm/withdraw', JSON.stringify({ + amount: $('#withdraw_amount').val() + })); +}) \ No newline at end of file diff --git a/html/ui.html b/html/ui.html new file mode 100644 index 00000000..112567b7 --- /dev/null +++ b/html/ui.html @@ -0,0 +1,28 @@ + + + + + + + + +
+ +
+ + + + + + + \ No newline at end of file diff --git a/server/esx_atm_sv.lua b/server/esx_atm_sv.lua new file mode 100644 index 00000000..ca05e499 --- /dev/null +++ b/server/esx_atm_sv.lua @@ -0,0 +1,35 @@ +ESX = nil +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +RegisterServerEvent('esx_atm:deposit') +AddEventHandler('esx_atm:deposit', function(amount) + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) + amount = tonumber(amount) + if amount == nil or amount <= 0 or amount > xPlayer.getMoney() then + TriggerClientEvent('esx:showNotification', _source, '~r~Montant invalide') + else + xPlayer.removeMoney(amount) + xPlayer.addAccountMoney('bank', amount) + TriggerClientEvent('esx:showNotification', _source, 'Vous avez déposé ~g~' .. amount .. '$~s~.') + TriggerClientEvent('esx_atm:closeATM', _source) + end +end) + + +RegisterServerEvent('esx_atm:withdraw') +AddEventHandler('esx_atm:withdraw', function(amount) + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) + amount = tonumber(amount) + local accountMoney = 0 + accountMoney = xPlayer.getAccount('bank').money + if amount == nil or amount <= 0 or amount > accountMoney then + TriggerClientEvent('esx:showNotification', _source, '~r~Montant invalide') + else + xPlayer.removeAccountMoney('bank', amount) + xPlayer.addMoney(amount) + TriggerClientEvent('esx:showNotification', _source, 'Vous avez retiré ~g~' .. amount .. '$~s~.') + TriggerClientEvent('esx_atm:closeATM', _source) + end +end) \ No newline at end of file From f59425ebcc225fc7067dec6386c77860c33caaca Mon Sep 17 00:00:00 2001 From: renaiku Date: Mon, 7 Aug 2017 14:43:33 +0200 Subject: [PATCH 0191/3224] Deleting a line on the wrong file. --- client/esx_atm_cl.lua | 4 ---- 1 file changed, 4 deletions(-) diff --git a/client/esx_atm_cl.lua b/client/esx_atm_cl.lua index 89cb175d..89e9eabb 100644 --- a/client/esx_atm_cl.lua +++ b/client/esx_atm_cl.lua @@ -11,10 +11,6 @@ Citizen.CreateThread(function() end end) -TriggerEvent('es:setDefaultSettings', { - nativeMoneySystem = false, -}) - RegisterNetEvent('esx_atm:closeATM') AddEventHandler('esx_atm:closeATM', function() SetNuiFocus(false) From 732ca2385b7fd9d7ad259c99826909e3c68dbcbd Mon Sep 17 00:00:00 2001 From: renaiku Date: Mon, 7 Aug 2017 23:36:23 +0200 Subject: [PATCH 0192/3224] ATM opening in every marker zone bug correction. --- client/esx_atm_cl.lua | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/client/esx_atm_cl.lua b/client/esx_atm_cl.lua index 89e9eabb..e096e28a 100644 --- a/client/esx_atm_cl.lua +++ b/client/esx_atm_cl.lua @@ -1,6 +1,7 @@ local GUI = {} local hasAlreadyEnteredMarker = false -GUI.MenuIsShowed = false +local isInATMMarker = false +local menuIsShowed = false ESX = nil @@ -11,10 +12,14 @@ Citizen.CreateThread(function() end end) +TriggerEvent('es:setDefaultSettings', { + nativeMoneySystem = false, +}) + RegisterNetEvent('esx_atm:closeATM') AddEventHandler('esx_atm:closeATM', function() SetNuiFocus(false) - GUI.MenuIsShowed = false + menuIsShowed = false SendNUIMessage({ hideAll = true }) @@ -67,24 +72,23 @@ end) Citizen.CreateThread(function() while true do Wait(0) - local coords = GetEntityCoords(GetPlayerPed(-1)) - local isInMarker = false + local coords = GetEntityCoords(GetPlayerPed(-1)) + isInATMMarker = false for i=1, #Config.ATMS, 1 do if(GetDistanceBetweenCoords(coords, Config.ATMS[i].x, Config.ATMS[i].y, Config.ATMS[i].z, true) < Config.ZoneSize.x / 2) then - isInMarker = true + isInATMMarker = true SetTextComponentFormat('STRING') AddTextComponentString('Appuyez sur ~INPUT_PICKUP~ pour déposer ou retirer du ~g~cash~s~.') DisplayHelpTextFromStringLabel(0, 0, 1, -1) end end - if isInMarker and not hasAlreadyEnteredMarker then + if isInATMMarker and not hasAlreadyEnteredMarker then hasAlreadyEnteredMarker = true - --TriggerEvent('esx_atm:hasEnteredMarker') end - if not isInMarker and hasAlreadyEnteredMarker then + if not isInATMMarker and hasAlreadyEnteredMarker then hasAlreadyEnteredMarker = false SetNuiFocus(false) - GUI.MenuIsShowed = false + menuIsShowed = false SendNUIMessage({ hideAll = true }) @@ -96,7 +100,7 @@ end) Citizen.CreateThread(function() while true do Wait(0) - if GUI.MenuIsShowed then + if menuIsShowed then DisableControlAction(0, 1, true) -- LookLeftRight DisableControlAction(0, 2, true) -- LookUpDown DisableControlAction(0, 142, true) -- MeleeAttackAlternate @@ -107,8 +111,8 @@ Citizen.CreateThread(function() }) end else - if IsControlJustReleased(0, 38) then - GUI.MenuIsShowed = true + if IsControlJustReleased(0, 38) and isInATMMarker then + menuIsShowed = true ESX.TriggerServerCallback('esx:getPlayerData', function(data) SendNUIMessage({ showMenu = true, @@ -122,4 +126,4 @@ Citizen.CreateThread(function() end end end -end) +end) \ No newline at end of file From cc43d95ca6fdbf447559efefb96161844f9c96ed Mon Sep 17 00:00:00 2001 From: renaiku Date: Tue, 8 Aug 2017 17:24:05 +0200 Subject: [PATCH 0193/3224] Deleting a line on the wrong file --- client/esx_atm_cl.lua | 4 ---- 1 file changed, 4 deletions(-) diff --git a/client/esx_atm_cl.lua b/client/esx_atm_cl.lua index e096e28a..b0fa1854 100644 --- a/client/esx_atm_cl.lua +++ b/client/esx_atm_cl.lua @@ -12,10 +12,6 @@ Citizen.CreateThread(function() end end) -TriggerEvent('es:setDefaultSettings', { - nativeMoneySystem = false, -}) - RegisterNetEvent('esx_atm:closeATM') AddEventHandler('esx_atm:closeATM', function() SetNuiFocus(false) From d2a10ee4bfff4cf7419ee9d08f18637f53266e13 Mon Sep 17 00:00:00 2001 From: renaiku Date: Tue, 8 Aug 2017 18:15:17 +0200 Subject: [PATCH 0194/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..59cfc3e6 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_jobs +[KNOWN BUGS] From 592612497b21eaec4f443fa80e01749789f52a11 Mon Sep 17 00:00:00 2001 From: renaiku Date: Tue, 8 Aug 2017 18:22:35 +0200 Subject: [PATCH 0195/3224] Adding files --- README.md | 12 + __resource.lua | 29 ++ client/esx_jobs_cl.lua | 561 +++++++++++++++++++++++++++++++++++ config.lua | 44 +++ html/bankgothic.ttf | Bin 0 -> 36272 bytes html/css/app.css | 61 ++++ html/img/keys/enter.png | Bin 0 -> 941 bytes html/img/keys/return.png | Bin 0 -> 376 bytes html/pdown.ttf | Bin 0 -> 151512 bytes html/scripts/app.js | 168 +++++++++++ html/scripts/mustache.min.js | 1 + html/ui.html | 15 + jobs/fisherman.lua | 167 +++++++++++ jobs/fuel.lua | 168 +++++++++++ jobs/lumberjack.lua | 161 ++++++++++ jobs/miner.lua | 267 +++++++++++++++++ jobs/reporter.lua | 54 ++++ jobs/slaughterer.lua | 161 ++++++++++ jobs/textil.lua | 168 +++++++++++ server/esx_jobs_sv.lua | 128 ++++++++ 20 files changed, 2165 insertions(+) create mode 100644 __resource.lua create mode 100644 client/esx_jobs_cl.lua create mode 100644 config.lua create mode 100644 html/bankgothic.ttf create mode 100644 html/css/app.css create mode 100644 html/img/keys/enter.png create mode 100644 html/img/keys/return.png create mode 100644 html/pdown.ttf create mode 100644 html/scripts/app.js create mode 100644 html/scripts/mustache.min.js create mode 100644 html/ui.html create mode 100644 jobs/fisherman.lua create mode 100644 jobs/fuel.lua create mode 100644 jobs/lumberjack.lua create mode 100644 jobs/miner.lua create mode 100644 jobs/reporter.lua create mode 100644 jobs/slaughterer.lua create mode 100644 jobs/textil.lua create mode 100644 server/esx_jobs_sv.lua diff --git a/README.md b/README.md index 59cfc3e6..6c94f3a2 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,14 @@ # fxserver-esx_jobs [KNOWN BUGS] + +The bail is not given back when the player disconnect or timeout. + +[FEATURES] +- Bails +- Easy system to create jobs (samples in jobs folder) +- Item farming jobs +- On Duty system + +This addon is an easy way to have farming jobs on your server. +There is no player management. +Just take exemple on the files in the jobs folder. \ No newline at end of file diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..a13546f2 --- /dev/null +++ b/__resource.lua @@ -0,0 +1,29 @@ +server_scripts { + '@mysql-async/lib/MySQL.lua', + 'server/esx_jobs_sv.lua' +} + +client_scripts { + 'config.lua', + 'jobs/fisherman.lua', + 'jobs/fuel.lua', + 'jobs/lumberjack.lua', + 'jobs/miner.lua', + 'jobs/reporter.lua', + 'jobs/slaughterer.lua', + 'jobs/textil.lua', + 'client/esx_jobs_cl.lua' +} + +ui_page 'html/ui.html' + +files { + 'html/ui.html', + 'html/bankgothic.ttf', + 'html/pdown.ttf', + 'html/css/app.css', + 'html/scripts/mustache.min.js', + 'html/scripts/app.js', + 'html/img/keys/enter.png', + 'html/img/keys/return.png' +} \ No newline at end of file diff --git a/client/esx_jobs_cl.lua b/client/esx_jobs_cl.lua new file mode 100644 index 00000000..0f787a9c --- /dev/null +++ b/client/esx_jobs_cl.lua @@ -0,0 +1,561 @@ +local Keys = { + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, + ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, + ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, + ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, + ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 +} + +local PlayerData = {} +local menuIsShowed = false +local hintIsShowed = false + + +local hasAlreadyEnteredMarker = false +local Blips = {} +local JobBlips = {} + +local collectedItem = nil +local collectedQtty = 0 +local collectedQttyUpToDate = false +local previousCollectedItem = nil +local previousCollectedQtty = 0 +local isInMarker = false +local isInPublicMarker = false + +local newTask = false +local hintToDisplay = "no hint to display" +local jobDone = false +local onDuty = false +local moneyInBank = 0 + +local spawner = 0 +local myPlate = {} + +local isJobVehicleDestroyed = false + +local cautionVehicleInCaseofDrop = 0 +local maxCautionVehicleInCaseofDrop = 0 +local vehicleObjInCaseofDrop = nil +local vehicleInCaseofDrop = nil +local vehicleHashInCaseofDrop = nil +local vehicleMaxHealthInCaseofDrop = nil +local vehicleOldHealthInCaseofDrop = nil + +ESX = nil + +Citizen.CreateThread(function() + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end +end) + +RegisterNetEvent('esx:playerLoaded') +AddEventHandler('esx:playerLoaded', function(xPlayer) + PlayerData = xPlayer + TriggerServerEvent('esx_jobs:giveBackCautionInCaseOfDrop') + refreshBlips() +end) + +AddEventHandler('esx_jobs:publicTeleports', function(position) + SetEntityCoords(GetPlayerPed(-1), position.x, position.y, position.z) +end) + +AddEventHandler('esx_jobs:action', function(job, zone) + menuIsShowed = true + if zone.Type == "cloakroom" then + SendNUIMessage({ + showMenu = true, + menu = 'cloakroom' + }) + elseif zone.Type == "work" then + hintToDisplay = "no hint to display" + hintIsShowed = false + local playerPed = GetPlayerPed(-1) + if IsPedInAnyVehicle(playerPed, 0) then + TriggerEvent('esx:showNotification', 'Vous devez être à pied pour pouvoir travailler.') + else + TriggerServerEvent('esx_jobs:startWork', zone.Item) + end + elseif zone.Type == "vehspawner" then + TriggerServerEvent('esx_jobs:requestPlayerData', 'refresh_bank_account') + local spawnpt = nil + local deliverypt = nil + local vehicle = nil + + for k,v in pairs(Config.Jobs) do + if PlayerData.job.name == k then + for l,w in pairs(v.Zones) do + if (w.Type == "vehspawnpt") and (w.Spawner == zone.Spawner) then + spawnpt = w + spawner = w.Spawner + end + end + for m,x in pairs(v.Vehicles) do + if (x.Spawner == zone.Spawner) then + vehicle = x + end + end + end + end + + local caution = zone.Caution + + if deliverypt == nil then + deliverypt = 0 + end + + TriggerServerEvent('esx_jobs:setCautionInCaseOfDrop', caution) + cautionVehicleInCaseofDrop = caution + maxCautionVehicleInCaseofDrop = cautionVehicleInCaseofDrop + + spawncar(spawnpt, vehicle) + + elseif zone.Type == "vehdelete" then + local looping = true + for k,v in pairs(Config.Jobs) do + if PlayerData.job.name == k then + for l,w in pairs(v.Zones) do + if (w.Type == "vehdelete") and (w.Spawner == zone.Spawner) then + local playerPed = GetPlayerPed(-1) + if IsPedInAnyVehicle(playerPed, 0) then + local vehicle = GetVehiclePedIsIn(playerPed, 0) + local plate = GetVehicleNumberPlateText(vehicle) + plate = string.gsub(plate, " ", "") + local driverPed = GetPedInVehicleSeat(vehicle, -1) + for i=1, #myPlate, 1 do + if (myPlate[i] == plate) and (playerPed == driverPed) then + TriggerServerEvent('esx_jobs:caution', "give_back", cautionVehicleInCaseofDrop, 0, 0) + DeleteVehicle(GetVehiclePedIsIn(playerPed, 0)) + + if w.Teleport ~= 0 then + SetEntityCoords(GetPlayerPed(-1), w.Teleport.x, w.Teleport.y, w.Teleport.z) + end + + TriggerEvent('esx_vehiclelock:updatePlayerCars', "remove", myPlate[i]) + table.remove(myPlate, i) + + if vehicleObjInCaseofDrop.HasCaution then + cautionVehicleInCaseofDrop = 0 + maxCautionVehicleInCaseofDrop = 0 + vehicleInCaseofDrop = nil + vehicleHashInCaseofDrop = nil + vehicleMaxHealthInCaseofDrop = nil + vehicleOldHealthInCaseofDrop = nil + vehicleObjInCaseofDrop = nil + TriggerServerEvent('esx_jobs:setCautionInCaseOfDrop', 0) + end + + break + end + end + end + looping = false + break + end + if looping == false then + break + end + end + end + if looping == false then + break + end + end + elseif zone.Type == "delivery" then + if Blips['delivery'] ~= nil then + RemoveBlip(Blips['delivery']) + Blips['delivery'] = nil + end + hintToDisplay = "no hint to display" + hintIsShowed = false + TriggerServerEvent('esx_jobs:startWork', zone.Item) + end + --nextStep(zone.GPS) +end) + +function nextStep(gps) + if gps ~= 0 then + if Blips['delivery'] ~= nil then + RemoveBlip(Blips['delivery']) + Blips['delivery'] = nil + end + Blips['delivery'] = AddBlipForCoord(gps.x, gps.y, gps.z) + SetBlipRoute(Blips['delivery'], true) + TriggerEvent('esx:showNotification', 'Rendez-vous à la prochaine étape après avoir complété celle-ci.') + end +end + +-- ######################### +AddEventHandler('esx_jobs:hasExitedMarker', function(zone) + TriggerServerEvent('esx_jobs:stopWork') + hintToDisplay = "no hint to display" + menuIsShowed = false + hintIsShowed = false + isInMarker = false + SendNUIMessage({ + showControls = false, + showMenu = false, + }) +end) + +RegisterNetEvent('esx:setJob') +AddEventHandler('esx:setJob', function(job) + PlayerData.job = job + onDuty = false + myPlate = {} -- loosing vehicle caution in case player changes job. + isJobVehicleDestroyed = false + spawner = 0 + --deleteBlips() + --refreshBlips() +end) + +function deleteBlips() + if JobBlips[1] ~= nil then + for i=1, #JobBlips, 1 do + RemoveBlip(JobBlips[i]) + table.remove(JobBlips, i) + end + end +end + +function refreshBlips() + local zones = {} + local blipInfo = {} + if PlayerData.job ~= nil then + for jobKey,jobValues in pairs(Config.Jobs) do + for zoneKey,zoneValues in pairs(jobValues.Zones) do + if zoneValues.Blip then + local blip = AddBlipForCoord(zoneValues.Pos.x, zoneValues.Pos.y, zoneValues.Pos.z) + SetBlipSprite (blip, jobValues.BlipInfos.Sprite) + SetBlipDisplay(blip, 4) + SetBlipScale (blip, 1.2) + SetBlipColour (blip, jobValues.BlipInfos.Color) + SetBlipAsShortRange(blip, true) + BeginTextCommandSetBlipName("STRING") + AddTextComponentString(zoneValues.Name) + EndTextCommandSetBlipName(blip) + table.insert(JobBlips, blip) + end + end + end + end +end + +-- ######################### +RegisterNUICallback('select', function(data, cb) + if data.menu == 'cloakroom' then + if data.val == 'citizen_wear' then + onDuty = false + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin) + TriggerEvent('skinchanger:loadSkin', skin) + end) + end + if data.val == 'job_wear' then + onDuty = true + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) + if skin.sex == 0 then + TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_male) + else + TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_female) + end + end) + end + end + cb('ok') +end) + +function spawncar(spawnPoint, vehicle) + hintToDisplay = "no hint to display" + hintIsShowed = false + TriggerServerEvent('esx_jobs:caution', "take", cautionVehicleInCaseofDrop, spawnPoint, vehicle) +end + +RegisterNetEvent('esx_jobs:spawnJobVehicle') +AddEventHandler('esx_jobs:spawnJobVehicle', function(spawnPoint, vehicle) + local playerPed = GetPlayerPed(-1) + local coords = spawnPoint.Pos + local vehicleModel = GetHashKey(vehicle.Hash) + + RequestModel(vehicleModel) + while not HasModelLoaded(vehicleModel) do + Citizen.Wait(0) + end + + local plate = math.random(100, 900) + if not IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + local veh = CreateVehicle(vehicleModel, coords.x, coords.y, coords.z, spawnPoint.Heading, true, false) + + if vehicle.Trailer ~= "none" then + RequestModel(vehicle.Trailer) + + while not HasModelLoaded(vehicle.Trailer) do + Citizen.Wait(0) + end + + local trailer = CreateVehicle(vehicle.Trailer, coords.x, coords.y, coords.z, spawnPoint.Heading, true, false) + AttachVehicleToTrailer(veh, trailer, 1.1) + end + + SetVehicleHasBeenOwnedByPlayer(veh, true) + SetEntityAsMissionEntity(veh, true, true) + local id = NetworkGetNetworkIdFromEntity(veh) + SetNetworkIdCanMigrate(id, true) + + local platePrefix = "WORK" + for k,v in pairs(Config.Plates) do + if PlayerData.job.name == k then + platePrefix = v + end + end + + plate = platePrefix .. plate + SetVehicleNumberPlateText(veh, plate) + table.insert(myPlate, plate) + plate = string.gsub(plate, " ", "") + TriggerEvent('esx_vehiclelock:updatePlayerCars', "add", plate) + SetVehRadioStation(veh, "OFF") + TaskWarpPedIntoVehicle(playerPed, veh, -1) + isJobVehicleDestroyed = false + + if vehicle.HasCaution then + vehicleInCaseofDrop = veh + vehicleHashInCaseofDrop = vehicle.Hash + vehicleObjInCaseofDrop = vehicle + vehicleMaxHealthInCaseofDrop = GetEntityMaxHealth(veh) + vehicleOldHealthInCaseofDrop = vehicleMaxHealthInCaseofDrop + end + end +end) + +-- Show top left hint +Citizen.CreateThread(function() + while true do + Wait(0) + if hintIsShowed == true then + SetTextComponentFormat("STRING") + AddTextComponentString(hintToDisplay) + DisplayHelpTextFromStringLabel(0, 0, 1, -1) + end + end +end) + +-- Display markers (only if on duty and the player's job ones) +Citizen.CreateThread(function() + while true do + Wait(0) + local zones = {} + if PlayerData.job ~= nil then + for k,v in pairs(Config.Jobs) do + if PlayerData.job.name == k then + zones = v.Zones + end + end + + local coords = GetEntityCoords(GetPlayerPed(-1)) + for k,v in pairs(zones) do + if onDuty or v.Type == "cloakroom" or PlayerData.job.name == "reporter" then + if(v.Marker ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then + DrawMarker(v.Marker, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) + end + end + end + end + end +end) + +-- Display public markers +Citizen.CreateThread(function() + while true do + Wait(0) + local coords = GetEntityCoords(GetPlayerPed(-1)) + for k,v in pairs(Config.PublicZones) do + if(v.Marker ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then + DrawMarker(v.Marker, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) + end + end + end +end) + +-- Activate public marker +Citizen.CreateThread(function() + while true do + Wait(0) + local coords = GetEntityCoords(GetPlayerPed(-1)) + local position = nil + local zone = nil + + for k,v in pairs(Config.PublicZones) do + if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then + isInPublicMarker = true + position = v.Teleport + zone = v + break + else + isInPublicMarker = false + end + end + + if IsControlJustReleased(0, Keys["E"]) and isInPublicMarker then + TriggerEvent('esx_jobs:publicTeleports', position) + end + + -- hide or show top left zone hints + if isInPublicMarker then + hintToDisplay = zone.Hint + hintIsShowed = true + else + if not isInMarker then + hintToDisplay = "no hint to display" + hintIsShowed = false + end + end + end +end) + +-- Activate menu when player is inside marker +Citizen.CreateThread(function() + while true do + Wait(0) + + if PlayerData.job ~= nil and PlayerData.job.name ~= 'unemployed' then + local zones = nil + local job = nil + + for k,v in pairs(Config.Jobs) do + if PlayerData.job.name == k then + job = v + zones = v.Zones + end + end + + local coords = GetEntityCoords(GetPlayerPed(-1)) + local currentZone = nil + local zone = nil + local lastZone = nil + + for k,v in pairs(zones) do + if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then + isInMarker = true + currentZone = k + zone = v + break + else + isInMarker = false + end + end + + if IsControlJustReleased(0, Keys["E"]) and not menuIsShowed and isInMarker then + if onDuty or zone.Type == "cloakroom" or PlayerData.job.name == "reporter" then + TriggerEvent('esx_jobs:action', job, zone) + end + end + + -- hide or show top left zone hints + if isInMarker and not menuIsShowed then + hintIsShowed = true + if (onDuty or zone.Type == "cloakroom" or PlayerData.job.name == "reporter") and zone.Type ~= "vehdelete" then + hintToDisplay = zone.Hint + hintIsShowed = true + elseif zone.Type == "vehdelete" and (onDuty or PlayerData.job.name == "reporter") then + local playerPed = GetPlayerPed(-1) + if IsPedInAnyVehicle(playerPed, 0) then + local vehicle = GetVehiclePedIsIn(playerPed) + local driverPed = GetPedInVehicleSeat(vehicle, -1) + local isVehicleOwner = false + local plate = GetVehicleNumberPlateText(vehicle) + plate = string.gsub(plate, " ", "") + for i=1, #myPlate, 1 do + Citizen.Trace(myPlate[i]) + if (myPlate[i] == plate) and (playerPed == driverPed) then + hintToDisplay = zone.Hint .. "\n" .. "La caution rendue sera de ~g~" .. cautionVehicleInCaseofDrop .. "$~s~." + isVehicleOwner = true + break + end + end + if not isVehicleOwner then + hintToDisplay = "Ce n'est pas votre véhicule ou vous devez être conducteur." + end + else + hintToDisplay = "Vous devez être dans un véhicule." + end + hintIsShowed = true + elseif onDuty and zone.Spawner ~= spawner then + hintToDisplay = "Vous n'êtes pas au bon point de livraison." + hintIsShowed = true + else + if not isInPublicMarker then + hintToDisplay = "no hint to display" + hintIsShowed = false + end + end + end + + if isInMarker and not hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = true + end + + if not isInMarker and hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = false + TriggerEvent('esx_jobs:hasExitedMarker', zone) + end + + end + end +end) + +-- VEHICLE CAUTION +Citizen.CreateThread(function() + while true do + Wait(0) + if vehicleInCaseofDrop ~= nil then + if onDuty and IsVehicleModel(vehicleInCaseofDrop, vehicleHashInCaseofDrop) then + local vehicleHealth = GetEntityHealth(vehicleInCaseofDrop) + if vehicleOldHealthInCaseofDrop ~= vehicleHealth then + local cautionValue = 0 + vehicleOldHealthInCaseofDrop = vehicleHealth + if vehicleHealth == vehicleMaxHealthInCaseofDrop then + cautionValue = maxCautionVehicleInCaseofDrop + cautionVehicleInCaseofDrop = cautionValue + else + local healthPct = (vehicleHealth * 100) / vehicleMaxHealthInCaseofDrop + local damagePct = 100 - healthPct + cautionValue = math.ceil(cautionVehicleInCaseofDrop - cautionVehicleInCaseofDrop * damagePct * 2.5 / 100) + if cautionValue < 0 then + cautionValue = 0 + elseif cautionValue >= cautionVehicleInCaseofDrop then + cautionValue = cautionVehicleInCaseofDrop + end + cautionVehicleInCaseofDrop = cautionValue + end + TriggerServerEvent('esx_jobs:setCautionInCaseOfDrop', cautionValue) + end + end + end + end +end) + +-- Menu Controls +Citizen.CreateThread(function() + while true do + Wait(0) + if IsControlJustReleased(0, Keys['ENTER']) or IsControlJustReleased(0, Keys['E']) then + SendNUIMessage({ enterPressed = true }) + elseif IsControlJustReleased(0, Keys['BACKSPACE']) then + SendNUIMessage({ backspacePressed = true }) + elseif IsControlJustReleased(0, Keys['LEFT']) then + SendNUIMessage({ move = 'LEFT' }) + elseif IsControlJustReleased(0, Keys['RIGHT']) then + SendNUIMessage({ move = 'RIGHT' }) + elseif IsControlJustReleased(0, Keys['TOP']) then + SendNUIMessage({ move = 'UP' }) + elseif IsControlJustReleased(0, Keys['DOWN']) then + SendNUIMessage({ move = 'DOWN' }) + end + end +end) \ No newline at end of file diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..fe37a95a --- /dev/null +++ b/config.lua @@ -0,0 +1,44 @@ +Config = {} +Config.DrawDistance = 1000.0 + +Config.Plates = { + taxi = "TAXI", + fisherman = "FISH", + cop = "LSPD", + ambulance = "EMS", + depanneur = "MECA", + fuel = "FUEL", + lumberjack = "BUCH", + miner = "MINE", + reporter = "JOUR", + slaughterer = "ABAT", + textil = "COUT" +} + +Config.Jobs = {} + +Config.PublicZones = { + EnterBuilding = { + Pos = { x = -118.21381378174, y = -607.14227294922, z = 35.280723571777 }, + Size = {x = 3.0, y = 3.0, z = 0.2}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = false, + Name = "Le Maclerait Libéré", + Type = "teleport", + Hint = "Appuyez sur ~INPUT_PICKUP~ pour entrer dans l'immeuble.", + Teleport = { x = -139.09838867188, y = -620.74865722656, z = 167.82052612305 } + }, + + ExitBuilding = { + Pos = { x = -139.45831298828, y = -617.32312011719, z = 167.82052612305 }, + Size = {x = 3.0, y = 3.0, z = 0.2}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = false, + Name = "Le Maclerait Libéré", + Type = "teleport", + Hint = "Appuyez sur ~INPUT_PICKUP~ pour aller à l'entrée de l'immeuble.", + Teleport = { x = -113.07, y = -604.93, z = 35.28 }, + }, +} \ No newline at end of file diff --git a/html/bankgothic.ttf b/html/bankgothic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f3d8049b052a1f9cfd27557eb3675bc85ce4b9fc GIT binary patch literal 36272 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
D;NyGoM}BX%_3nO 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 D`#l06 literal 0 HcmV?d00001 diff --git a/html/css/app.css b/html/css/app.css new file mode 100644 index 00000000..f5b568b8 --- /dev/null +++ b/html/css/app.css @@ -0,0 +1,61 @@ +@font-face { + font-family: bankgothic; + src: url('../bankgothic.ttf'); +} + +@font-face { + font-family: pcdown; + src: url('../pdown.ttf'); +} + +#controls { + font-family : pcdown; + font-size : 3em; + color : #FFF; + position : absolute; + bottom : 40; + right : 40; + + text-shadow: + -1px -1px 0 #000, + 1px -1px 0 #000, + -1px 1px 0 #000, + 1px 1px 0 #000 + ; +} + +.controls { + display: none; +} + +.menu { + font-family : bankgothic; + min-width : 350px; + background-color: #506be6; + color : #fff; + box-shadow : 0px 0px 50px 0px #000; + position : absolute; + left : 40; + top : 40; +} + +.menu .head { + text-align : center; + height : 40px; + line-height : 40px; +} + +.menu .menu-items .menu-item { + height : 40px; + display : block; + background-color: #f1f1f1; + box-shadow : inset 1px 0px 0px 1px #b8b8b8; + height : 32px; + line-height : 32px; + color : #3A3A3A; + text-align : center; +} + +.menu .menu-items .menu-item.selected { + background-color: #d0d0d0; +} \ No newline at end of file diff --git a/html/img/keys/enter.png b/html/img/keys/enter.png new file mode 100644 index 0000000000000000000000000000000000000000..3eb9a1f69f58c651517329c92d28cdb1c605f165 GIT binary patch literal 941 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 literal 0 HcmV?d00001 diff --git a/html/scripts/app.js b/html/scripts/app.js new file mode 100644 index 00000000..6f0e1a3c --- /dev/null +++ b/html/scripts/app.js @@ -0,0 +1,168 @@ +(function(){ + + let DefaultTpl = + '
{{title}}
' + + ''+ + '' + ; + + let DefaultWithTypeAndCountTpl = + '
{{title}}
' + + ''+ + '' + ; + + let menus = { + + cloakroom : { + title : 'Vestiaire', + visible : false, + current : 0, + hasControl: true, + template : DefaultTpl, + + items: [ + {label: 'Tenue civile', value: 'citizen_wear'}, + {label: 'Tenue de travail', value: 'job_wear'} + ] + }, + } + + let renderMenus = function(){ + for(let k in menus){ + + let elem = $('#menu_' + k); + + elem.html(Mustache.render(menus[k].template, menus[k])); + + if(menus[k].visible) + elem.show(); + else + elem.hide(); + + } + } + + let showMenu = function(menu){ + + currentMenu = menu; + + for(let k in menus) + menus[k].visible = false; + + menus[menu].visible = true; + + renderMenus(); + + if(menus[currentMenu].items.length > 0){ + + $('#menu_' + currentMenu + ' .menu-item').removeClass('selected'); + $('#menu_' + currentMenu + ' .menu-item:eq(0)').addClass('selected'); + + menus[currentMenu].current = 0; + currentVal = menus[currentMenu].items[menus[currentMenu].current].value; + currentType = $('#menu_' + currentMenu + ' .menu-item:eq(0)').data('type'); + currentCount = $('#menu_' + currentMenu + ' .menu-item:eq(0)').data('count'); + } + + isMenuOpen = true + } + + let hideMenus = function(){ + + for(let k in menus) + menus[k].visible = false; + + renderMenus(); + isMenuOpen = false; + } + + let isMenuOpen = false + let currentMenu = null; + let currentControl = null; + let currentVal = null; + let currentType = null; + let currentCount = null; + + renderMenus(); + + window.onData = function(data){ + + if(data.showMenu === true){ + showMenu(data.menu); + } + + if(data.showMenu === false){ + hideMenus(); + } + + if(data.move && isMenuOpen){ + + if(data.move == 'UP'){ + if(menus[currentMenu].current > 0) + menus[currentMenu].current--; + } + + if(data.move == 'DOWN'){ + + let max = $('#menu_' + currentMenu + ' .menu-item').length; + + if(menus[currentMenu].current < max - 1) + menus[currentMenu].current++; + } + + $('#menu_' + currentMenu + ' .menu-item').removeClass('selected'); + $('#menu_' + currentMenu + ' .menu-item:eq(' + menus[currentMenu].current + ')').addClass('selected'); + + currentVal = menus[currentMenu].items[menus[currentMenu].current].value; + currentType = $('#menu_' + currentMenu + ' .menu-item:eq(' + menus[currentMenu].current + ')').data('type'); + currentCount = $('#menu_' + currentMenu + ' .menu-item:eq(' + menus[currentMenu].current + ')').data('count'); + } + + if(data.enterPressed){ + + if(isMenuOpen) { + + $.post('http://esx_jobs/select', JSON.stringify({ + menu : currentMenu, + val : currentVal, + type : currentType, + count: currentCount + })) + + let elem = $('#menu_' + currentMenu + ' .menu-item.selected') + + if(elem.data('remove-on-select') == true){ + + elem.remove(); + + menus[currentMenu].items.splice(menus[currentMenu].current, 1) + menus[currentMenu].current = 0; + + $('#menu_' + currentMenu + ' .menu-item').removeClass('selected'); + $('#menu_' + currentMenu + ' .menu-item:eq(0)').addClass('selected'); + + currentVal = menus[currentMenu].items[0].value; + currentType = $('#menu_' + currentMenu + ' .menu-item:eq(0)').data('type'); + currentCount = $('#menu_' + currentMenu + ' .menu-item:eq(0)').data('count'); + } + + } + + } + + if(data.backspacePressed){ + if(isMenuOpen && currentMenu == 'cloakroom'){ + hideMenus(); + } + } + + } + + window.onload = function(e){ window.addEventListener('message', function(event){ onData(event.data) }); } + +})() \ No newline at end of file diff --git a/html/scripts/mustache.min.js b/html/scripts/mustache.min.js new file mode 100644 index 00000000..520cfcb9 --- /dev/null +++ b/html/scripts/mustache.min.js @@ -0,0 +1 @@ +(function defineMustache(global,factory){if(typeof exports==="object"&&exports&&typeof exports.nodeName!=="string"){factory(exports)}else if(typeof define==="function"&&define.amd){define(["exports"],factory)}else{global.Mustache={};factory(global.Mustache)}})(this,function mustacheFactory(mustache){var objectToString=Object.prototype.toString;var isArray=Array.isArray||function isArrayPolyfill(object){return objectToString.call(object)==="[object Array]"};function isFunction(object){return typeof object==="function"}function typeStr(obj){return isArray(obj)?"array":typeof obj}function escapeRegExp(string){return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}function hasProperty(obj,propName){return obj!=null&&typeof obj==="object"&&propName in obj}var regExpTest=RegExp.prototype.test;function testRegExp(re,string){return regExpTest.call(re,string)}var nonSpaceRe=/\S/;function isWhitespace(string){return!testRegExp(nonSpaceRe,string)}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(string){return String(string).replace(/[&<>"'`=\/]/g,function fromEntityMap(s){return entityMap[s]})}var whiteRe=/\s*/;var spaceRe=/\s+/;var equalsRe=/\s*=/;var curlyRe=/\s*\}/;var tagRe=/#|\^|\/|>|\{|&|=|!/;function parseTemplate(template,tags){if(!template)return[];var sections=[];var tokens=[];var spaces=[];var hasTag=false;var nonSpace=false;function stripSpace(){if(hasTag&&!nonSpace){while(spaces.length)delete tokens[spaces.pop()]}else{spaces=[]}hasTag=false;nonSpace=false}var openingTagRe,closingTagRe,closingCurlyRe;function compileTags(tagsToCompile){if(typeof tagsToCompile==="string")tagsToCompile=tagsToCompile.split(spaceRe,2);if(!isArray(tagsToCompile)||tagsToCompile.length!==2)throw new Error("Invalid tags: "+tagsToCompile);openingTagRe=new RegExp(escapeRegExp(tagsToCompile[0])+"\\s*");closingTagRe=new RegExp("\\s*"+escapeRegExp(tagsToCompile[1]));closingCurlyRe=new RegExp("\\s*"+escapeRegExp("}"+tagsToCompile[1]))}compileTags(tags||mustache.tags);var scanner=new Scanner(template);var start,type,value,chr,token,openSection;while(!scanner.eos()){start=scanner.pos;value=scanner.scanUntil(openingTagRe);if(value){for(var i=0,valueLength=value.length;i0?sections[sections.length-1][4]:nestedTokens;break;default:collector.push(token)}}return nestedTokens}function Scanner(string){this.string=string;this.tail=string;this.pos=0}Scanner.prototype.eos=function eos(){return this.tail===""};Scanner.prototype.scan=function scan(re){var match=this.tail.match(re);if(!match||match.index!==0)return"";var string=match[0];this.tail=this.tail.substring(string.length);this.pos+=string.length;return string};Scanner.prototype.scanUntil=function scanUntil(re){var index=this.tail.search(re),match;switch(index){case-1:match=this.tail;this.tail="";break;case 0:match="";break;default:match=this.tail.substring(0,index);this.tail=this.tail.substring(index)}this.pos+=match.length;return match};function Context(view,parentContext){this.view=view;this.cache={".":this.view};this.parent=parentContext}Context.prototype.push=function push(view){return new Context(view,this)};Context.prototype.lookup=function lookup(name){var cache=this.cache;var value;if(cache.hasOwnProperty(name)){value=cache[name]}else{var context=this,names,index,lookupHit=false;while(context){if(name.indexOf(".")>0){value=context.view;names=name.split(".");index=0;while(value!=null&&index")value=this.renderPartial(token,context,partials,originalTemplate);else if(symbol==="&")value=this.unescapedValue(token,context);else if(symbol==="name")value=this.escapedValue(token,context);else if(symbol==="text")value=this.rawValue(token);if(value!==undefined)buffer+=value}return buffer};Writer.prototype.renderSection=function renderSection(token,context,partials,originalTemplate){var self=this;var buffer="";var value=context.lookup(token[1]);function subRender(template){return self.render(template,context,partials)}if(!value)return;if(isArray(value)){for(var j=0,valueLength=value.length;j + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jobs/fisherman.lua b/jobs/fisherman.lua new file mode 100644 index 00000000..e8af59c0 --- /dev/null +++ b/jobs/fisherman.lua @@ -0,0 +1,167 @@ +Config.Jobs.fisherman = { + BlipInfos = { + Sprite = 68, + Color = 38 + }, + Vehicles = { + Truck = { + Spawner = 1, + Hash = "benson", + Trailer = "none", + HasCaution = true + }, + Boat = { + Spawner = 2, + Hash = "tug", + Trailer = "none", + HasCaution = false + } + }, + Zones = { + CloakRoom = { + Pos = {x = 868.39929199219, y = -1639.7556152344, z = 29.339252471924}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = true, + Name = "Vestiaire", + Type = "cloakroom", + Hint = "Appuyez sur ~INPUT_PICKUP~ pour vous changer.", + GPS = {x = 880.74462890625, y = -1663.9635009766, z = 29.370491027832} + }, + + FishingSpot = { + Pos = {x = 4435.21, y = 4829.6, z = 0.3439}, + Color = {r = 204, g = 204, b = 0}, + Size = {x = 110.0, y = 110.0, z = 10.0}, + Marker= 1, + Blip = true, + Name = "Zone de pêche", + Type = "work", + Item = { + { + name = "Poisson", + db_name= "fish", + time = 2000, + max = 100, + add = 1, + remove = 1, + requires = "nothing", + requires_name = "Nothing", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour pêcher.", + GPS = {x = 3859.43, y = 4448.83, z = 0.39994} + }, + + BoatSpawner = { + Pos = {x = 3867.44, y = 4463.62, z = 1.72386}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = true, + Name = "Spawner bateau", + Type = "vehspawner", + Spawner = 2, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour appeler le bateau.", + Caution = 0, + GPS = {x = 4435.21, y = 4829.6, z = 0.3439} + }, + + BoatSpawnPoint = { + Pos = {x = 3888.3, y = 4468.09, z = 0.0}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Marker= -1, + Blip = false, + Name = "Bateau", + Type = "vehspawnpt", + Spawner = 2, + GPS = 0, + Heading = 270.1 + }, + + BoatDeletePoint = { + Pos = {x = 3859.43, y = 4448.83, z = 0.39994}, + Size = {x = 10.0, y = 10.0, z = 1.0}, + Color = {r = 255, g = 0, b = 0}, + Marker= 1, + Blip = false, + Name = "Supression du bateau", + Type = "vehdelete", + Hint = "Appuyez sur ~INPUT_PICKUP~ pour rendre le bateau.", + Spawner = 2, + Caution = 0, + GPS = {x = -1012.64758300781, y = -1354.62634277344, z = 5.54292726516724}, + Teleport = {x = 3867.44, y = 4463.62, z = 1.72386} + }, + + + VehicleSpawner = { + Pos = {x = 880.74462890625, y = -1663.9635009766, z = 29.370491027832}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = false, + Name = "Spawner véhicule de fonction", + Type = "vehspawner", + Spawner = 1, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour appeler le véhicule de livraison.", + Caution = 2000, + GPS = {x = 3867.44, y = 4463.62, z = 1.72386} + }, + + VehicleSpawnPoint = { + Pos = {x = 859.354, y = -1656.21, z = 29.5697}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Marker= -1, + Blip = false, + Name = "Véhicule de fonction", + Type = "vehspawnpt", + Spawner = 1, + GPS = 0, + Heading = 70.1 + }, + + VehicleDeletePoint = { + Pos = {x = 863.23254394531, y = -1718.2849121094, z = 28.631998062134}, + Size = {x = 5.0, y = 5.0, z = 1.0}, + Color = {r = 255, g = 0, b = 0}, + Marker= 1, + Blip = false, + Name = "Supression du véhicule", + Type = "vehdelete", + Hint = "Appuyez sur ~INPUT_PICKUP~ pour rendre le véhicule.", + Spawner = 1, + Caution = 2000, + GPS = 0, + Teleport = 0 + }, + + Delivery = { + Pos = {x = -1012.64758300781, y = -1354.62634277344, z = 5.54292726516724}, + 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 = "Point de livraison", + Type = "delivery", + Spawner = 2, + Item = { + { + name = "Livraison", + time = 500, + remove = 1, + max = 100, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua + price = 11, + requires = "fish", + requires_name = "Poisson", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour livrer le poisson.", + GPS = {x = 3867.44, y = 4463.62, z = 1.72386} + } + } +} \ No newline at end of file diff --git a/jobs/fuel.lua b/jobs/fuel.lua new file mode 100644 index 00000000..653906b0 --- /dev/null +++ b/jobs/fuel.lua @@ -0,0 +1,168 @@ +Config.Jobs.fuel = { + BlipInfos = { + Sprite = 436, + Color = 5 + }, + Vehicles = { + Truck = { + Spawner = 1, + Hash = "phantom", + Trailer = "tanker", + HasCaution = true + } + }, + Zones = { + CloakRoom = { -- 1 + Pos = {x = 557.933, y = -2327.9, z = 4.82896}, + Size = {x = 3.0, y = 3.0, z = 2.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = true, + Name = "Vestiaire", + Type = "cloakroom", + Hint = "Appuyez sur ~INPUT_PICKUP~ pour vous changer.", + GPS = {x = 554.597, y = -2314.43, z = 4.86293} + }, + + ChampPetrol = { -- 4 -- 8 + Pos = {x = 609.589, y = 2856.74, z = 39.4958}, + Size = {x = 20.0, y = 20.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = true, + Name = "Pétrol", + Type = "work", + Item = { + { + name = "Pétrol", + db_name= "petrol", + time = 5000, + max = 24, + add = 1, + remove = 1, + requires = "nothing", + requires_name = "Nothing", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour forer.", + GPS = {x = 2736.94, y = 1417.99, z = 23.4888} + }, + + Raffinerie = { -- 5 + Pos = {x = 2736.94, y = 1417.99, z = 23.4888}, + Size = {x = 10.0, y = 10.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = true, + Name = "Pétrol raffiné", + Type = "work", + Item = { + { + name = "Pétrol raffiné", + db_name= "petrol_raffin", + time = 5000, + max = 20, + add = 1, + remove = 2, + requires = "petrol", + requires_name = "Pétrol", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour raffiner.", + GPS = {x = 265.752, y = -3013.39, z = 4.73275} + }, + + Melange = { -- 6 + Pos = {x = 265.752, y = -3013.39, z = 4.73275}, + Size = {x = 10.0, y = 10.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = true, + Name = "Mélange", + Type = "work", + Item = { + { + name = "Essence", + db_name= "essence", + time = 5000, + max = 20, + add = 2, + remove = 1, + requires = "petrol_raffin", + requires_name = "Pétrol raffiné", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour mélanger.", + GPS = {x = 491.406, y = -2163.37, z = 4.91827} + }, + + VehicleSpawner = { -- 2 + Pos = {x = 554.597, y = -2314.43, z = 4.86293}, + Size = {x = 3.0, y = 3.0, z = 2.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = false, + Name = "Spawner véhicule de fonction", + Type = "vehspawner", + Spawner = 1, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour appeler le camion.", + Caution = 2000, + GPS = {x = 602.254, y = 2926.62, z = 39.6898} + }, + + VehicleSpawnPoint = { + Pos = {x = 580.541, y = -2309.7, z = 4.90915}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Marker= -1, + Blip = false, + Name = "Véhicule de fonction", + Type = "vehspawnpt", + Spawner = 1, + GPS = 0, + Heading = 0 + }, + + VehicleDeletePoint = { + Pos = {x = 520.684, y = -2124.21, z = 4.98635}, + Size = {x = 5.0, y = 5.0, z = 1.0}, + Color = {r = 255, g = 0, b = 0}, + Marker= 1, + Blip = false, + Name = "Supression du véhicule", + Type = "vehdelete", + Hint = "Appuyez sur ~INPUT_PICKUP~ pour rendre le véhicule.", + Spawner = 1, + Caution = 2000, + GPS = 0, + Teleport = 0 + }, + + Delivery = { -- 7 + Pos = {x = 491.406, y = -2163.37, z = 4.91827}, + Color = {r = 204, g = 204, b = 0}, + Size = {x = 10.0, y = 10.0, z = 1.0}, + Marker= 1, + Blip = true, + Name = "Point de livraison", + Type = "delivery", + Spawner = 1, + Item = { + { + name = "Livraison", + time = 500, + remove = 1, + max = 100, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua + price = 61, + requires = "essence", + requires_name = "Essence", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour livrer l'essence.", + GPS = {x = 609.589, y = 2856.74, z = 39.4958} + } + } +} \ No newline at end of file diff --git a/jobs/lumberjack.lua b/jobs/lumberjack.lua new file mode 100644 index 00000000..07a0f96d --- /dev/null +++ b/jobs/lumberjack.lua @@ -0,0 +1,161 @@ +Config.Jobs.lumberjack = { + BlipInfos = { + Sprite = 237, + Color = 4 + }, + Vehicles = { + Truck = { + Spawner = 1, + Hash = "phantom", + Trailer = "trailers", + HasCaution = true + } + }, + Zones = { + CloakRoom = { + Pos = {x = 1200.63, y = -1276.875, z = 34.38}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = true, + Name = "Vestiaire", + Type = "cloakroom", + Hint = "Appuyez sur ~INPUT_PICKUP~ pour vous changer." + }, + + Wood = { + Pos = {x = -534.323669433594, y = 5373.794921875, z = 69.503059387207}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = true, + Name = "Tas de bois", + Type = "work", + Item = { + { + name = "Bois", + db_name= "wood", + time = 3000, + max = 20, + add = 1, + remove = 1, + requires = "nothing", + requires_name = "Nothing", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour récupérer du bois." + }, + + CuttedWood = { + Pos = {x = -552.214660644531, y = 5326.90966796875, z = 72.5996017456055}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = false, + Name = "Découpe du bois", + Type = "work", + Item = { + { + name = "Bois coupé", + db_name= "cutted_wood", + time = 5000, + max = 20, + add = 1, + remove = 1, + requires = "wood", + requires_name = "Bois", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour couper du bois." + }, + + Planks = { + Pos = {x = -501.386596679688, y = 5280.53076171875, z = 79.6187744140625}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = false, + Name = "Planches", + Type = "work", + Item = { + { + name = "Paquet de planche", + db_name= "packaged_plank", + time = 4000, + max = 100, + add = 5, + remove = 1, + requires = "cutted_wood", + requires_name = "Bois coupé", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour récupérer des planches." + }, + + VehicleSpawner = { + Pos = {x = 1191.9681396484, y = -1261.7775878906, z = 34.170627593994}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = false, + Name = "Spawner véhicule de fonction", + Type = "vehspawner", + Spawner = 1, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour appeler le véhicule de livraison.", + Caution = 2000 + }, + + VehicleSpawnPoint = { + Pos = {x = 1194.6257324219, y = -1286.955078125, z = 34.121524810791}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Marker= -1, + Blip = false, + Name = "Véhicule de fonction", + Type = "vehspawnpt", + Spawner = 1, + Heading = 285.1 + }, + + VehicleDeletePoint = { + Pos = {x = 1216.8983154297, y = -1229.2396240234, z = 34.403507232666}, + Size = {x = 5.0, y = 5.0, z = 1.0}, + Color = {r = 255, g = 0, b = 0}, + Marker= 1, + Blip = false, + Name = "Supression du véhicule", + Type = "vehdelete", + Hint = "Appuyez sur ~INPUT_PICKUP~ pour rendre le véhicule.", + Spawner = 1, + Caution = 2000, + GPS = 0, + Teleport = 0 + }, + + Delivery = { + Pos = {x = 1201.3558349609, y = -1327.5159912109, z = 34.226093292236}, + Color = {r = 204, g = 204, b = 0}, + Size = {x = 5.0, y = 5.0, z = 3.0}, + Marker= 1, + Blip = true, + Name = "Point de livraison", + Type = "delivery", + Spawner = 1, + Item = { + { + name = "Livraison", + time = 500, + remove = 1, + max = 100, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua + price = 13, + requires = "packaged_plank", + requires_name = "Paquet de planche", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour livrer les planches." + } + } +} \ No newline at end of file diff --git a/jobs/miner.lua b/jobs/miner.lua new file mode 100644 index 00000000..52fde249 --- /dev/null +++ b/jobs/miner.lua @@ -0,0 +1,267 @@ +Config.Jobs.miner = { + BlipInfos = { + Sprite = 318, + Color = 5 + }, + Vehicles = { + Truck = { + Spawner = 1, + Hash = "rubble", + Trailer = "none", + HasCaution = true + } + }, + Zones = { + CloakRoom = { + Pos = {x = 892.35333251953, y = -2172.7705078125, z = 31.286273956299}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = true, + Name = "Vestiaire", + Type = "cloakroom", + Hint = "Appuyez sur ~INPUT_PICKUP~ pour vous changer.", + GPS = {x = 884.86889648438, y = -2176.5102539063, z = 29.519346237183} + }, + + Mine = { + Pos = {x = 2962.4, y = 2746.2, z = 42.398}, + Size = {x = 5.0, y = 5.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = true, + Name = "Rocher", + Type = "work", + Item = { + { + name = "Rocher", + db_name= "stone", + time = 3000, + max = 7, + add = 1, + remove = 1, + requires = "nothing", + requires_name = "Nothing", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour récupérer des rochers.", + GPS = {x = 289.244, y = 2862.9, z = 42.6424} + }, + + StoneWash = { + Pos = {x = 289.244, y = 2862.9, z = 42.6424}, + Size = {x = 5.0, y = 5.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = true, + Name = "Roche lavé", + Type = "work", + Item = { + { + name = "Roche lavé", + db_name= "washed_stone", + time = 5000, + max = 7, + add = 1, + remove = 1, + requires = "stone", + requires_name = "Rocher", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour laver les roches.", + GPS = {x = 1109.14, y = -2007.87, z = 30.0188} + }, + + Foundry = { + Pos = {x = 1109.14, y = -2007.87, z = 30.0188}, + Size = {x = 5.0, y = 5.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = true, + Name = "Fonderie", + Type = "work", + Item = { + { + name = "Cuivre", + db_name= "copper", + time = 4000, + max = 56, + add = 8, + remove = 1, + requires = "washed_stone", + requires_name = "Roche lavé", + drop = 100 + }, + { + name = "Fer", + db_name= "iron", + max = 42, + add = 6, + drop = 100 + }, + { + name = "Or", + db_name= "gold", + max = 21, + add = 3, + drop = 100 + }, + { + name = "Diamant", + db_name= "diamond", + max = 50, + add = 1, + drop = 5 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour fondre les roches.", + GPS = {x = -169.481, y = -2659.16, z = 5.00103} + }, + + VehicleSpawner = { + Pos = {x = 884.86889648438, y = -2176.5102539063, z = 29.519346237183}, + Size = {x = 5.0, y = 5.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = false, + Name = "Spawner véhicule de fonction", + Type = "vehspawner", + Spawner = 1, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour appeler le véhicule de livraison.", + Caution = 2000, + GPS = {x = 2962.4, y = 2746.2, z = 42.398} + }, + + VehicleSpawnPoint = { + Pos = {x = 879.55700683594, y = -2189.7995605469, z = 29.519348144531}, + Size = {x = 5.0, y = 5.0, z = 1.0}, + Marker= -1, + Blip = false, + Name = "Véhicule de fonction", + Type = "vehspawnpt", + Spawner = 1, + Heading = 90.1, + GPS = 0 + }, + + VehicleDeletePoint = { + Pos = {x = 881.93725585938, y = -2198.0151367188, z = 29.519351959229}, + Size = {x = 5.0, y = 5.0, z = 1.0}, + Color = {r = 255, g = 0, b = 0}, + Marker= 1, + Blip = false, + Name = "Supression du véhicule", + Type = "vehdelete", + Hint = "Appuyez sur ~INPUT_PICKUP~ pour rendre le véhicule.", + Spawner = 1, + Caution = 2000, + GPS = 0, + Teleport = 0 + }, + + CopperDelivery = { + Pos = {x = -169.481, y = -2659.16, z = 5.00103}, + Color = {r = 204, g = 204, b = 0}, + Size = {x = 5.0, y = 5.0, z = 3.0}, + Marker= 1, + Blip = true, + Name = "Revente de cuivre", + Type = "delivery", + Spawner = 1, + Item = { + { + name = "Livraison", + time = 500, + remove = 1, + max = 56, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua + price = 5, + requires = "copper", + requires_name = "Cuivre", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour livrer le cuivre.", + GPS = {x = -148.782, y = -1040.38, z = 26.2736} + }, + + IronDelivery = { + Pos = {x = -148.782, y = -1040.38, z = 26.2736}, + 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 = "Revente de fer", + Type = "delivery", + Spawner = 1, + Item = { + { + name = "Livraison", + time = 500, + remove = 1, + max = 42, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua + price = 9, + requires = "iron", + requires_name = "Fer", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour livrer le fer.", + GPS = {x = 261.487, y = 207.354, z = 109.287} + }, + + GoldDelivery = { + Pos = {x = 261.487, y = 207.354, z = 109.287}, + 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 = "Revente d'or", + Type = "delivery", + Spawner = 1, + Item = { + { + name = "Livraison", + time = 500, + remove = 1, + max = 21, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua + price = 25, + requires = "gold", + requires_name = "Or", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour livrer l'or'.", + GPS = {x = -621.046, y = -228.532, z = 37.0571} + }, + + DiamondDelivery = { + Pos = {x = -621.046, y = -228.532, z = 37.0571}, + 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 = "Revente de diamants", + Type = "delivery", + Spawner = 1, + Item = { + { + name = "Livraison", + time = 500, + remove = 1, + max = 50, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua + price = 250, + requires = "diamond", + requires_name = "Diamant", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour livrer les diamants.", + GPS = {x = 2962.4, y = 2746.2, z = 42.398} + } + } +} \ No newline at end of file diff --git a/jobs/reporter.lua b/jobs/reporter.lua new file mode 100644 index 00000000..a2750f36 --- /dev/null +++ b/jobs/reporter.lua @@ -0,0 +1,54 @@ +Config.Jobs.reporter = { + BlipInfos = { + Sprite = 184, + Color = 1 + }, + Vehicles = { + Truck = { + Spawner = 1, + Hash = "rumpo", + Trailer = "none", + HasCaution = true + } + }, + Zones = { + VehicleSpawner = { + Pos = { x = -141.41, y = -620.80, z = 167.82 }, + Size = {x = 2.0, y = 2.0, z = 0.2}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = true, + Name = "Le Maclerait Libéré", + Type = "vehspawner", + Spawner = 1, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour descendre au garage.", + Caution = 2000 + }, + + VehicleSpawnPoint = { + Pos = { x = -149.32023620605, y = -592.17163085938, z = 31.42448425293 }, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Marker= -1, + Blip = false, + Name = "Véhicule de fonction", + Type = "vehspawnpt", + Spawner = 1, + Heading = 200.1 + }, + + VehicleDeletePoint = { + Pos = { x = -144.2229309082, y = -577.02972412109, z = 31.42448425293 }, + Size = {x = 5.0, y = 5.0, z = 0.2}, + Color = {r = 255, g = 0, b = 0}, + Marker= 1, + Blip = false, + Name = "Supression du véhicule", + Type = "vehdelete", + Hint = "Appuyez sur ~INPUT_PICKUP~ pour rendre le véhicule.", + Spawner = 1, + Caution = 2000, + GPS = 0, + Teleport = { x = -139.09838867188, y = -620.74865722656, z = 167.82052612305 } + } + } +} \ No newline at end of file diff --git a/jobs/slaughterer.lua b/jobs/slaughterer.lua new file mode 100644 index 00000000..7b923303 --- /dev/null +++ b/jobs/slaughterer.lua @@ -0,0 +1,161 @@ +Config.Jobs.slaughterer = { + BlipInfos = { + Sprite = 256, + Color = 5 + }, + Vehicles = { + Truck = { + Spawner = 1, + Hash = "benson", + Trailer = "none", + HasCaution = true + } + }, + Zones = { + CloakRoom = { + Pos = {x = -1071.1319580078, y = -2003.7891845703, z = 14.78551197052}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = true, + Name = "Vestiaire", + Type = "cloakroom", + Hint = "Appuyez sur ~INPUT_PICKUP~ pour vous changer." + }, + + AliveChicken = { + Pos = {x = -62.9018, y = 6241.46, z = 30.0901}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = true, + Name = "Poulailler", + Type = "work", + Item = { + { + name = "Poulet vivant", + db_name= "alive_chicken", + time = 3000, + max = 20, + add = 1, + remove = 1, + requires = "nothing", + requires_name = "Nothing", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour attrapper des poulets vivants." + }, + + SlaughterHouse = { + Pos = {x = -77.991, y = 6229.063, z = 30.091}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = false, + Name = "Abattoir", + Type = "work", + Item = { + { + name = "Poulet à conditionner", + db_name= "slaughtered_chicken", + time = 5000, + max = 20, + add = 1, + remove = 1, + requires = "alive_chicken", + requires_name = "Poulet vivant", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour dépecer les poulets." + }, + + Packaging = { + Pos = {x = -101.978, y = 6208.799, z = 30.025}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = false, + Name = "Emballage", + Type = "work", + Item = { + { + name = "Poulet en barquette", + db_name= "packaged_chicken", + time = 4000, + max = 100, + add = 5, + remove = 1, + requires = "slaughtered_chicken", + requires_name = "Poulet à conditionner", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour conditionner le poulet en barquette." + }, + + VehicleSpawner = { + Pos = {x = -1042.9444580078, y = -2023.2551269531, z = 12.161581993103}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = false, + Name = "Spawner véhicule de fonction", + Type = "vehspawner", + Spawner = 1, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour appeler le véhicule de livraison.", + Caution = 2000 + }, + + VehicleSpawnPoint = { + Pos = {x = -1048.8568115234, y = -2025.322265625, z = 12.161581993103}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Marker= -1, + Blip = false, + Name = "Véhicule de fonction", + Type = "vehspawnpt", + Spawner = 1, + Heading = 130.1 + }, + + VehicleDeletePoint = { + Pos = {x = -1061.5164794922, y = -2008.3552246094, z = 12.161584854126}, + Size = {x = 5.0, y = 5.0, z = 1.0}, + Color = {r = 255, g = 0, b = 0}, + Marker= 1, + Blip = false, + Name = "Supression du véhicule", + Type = "vehdelete", + Hint = "Appuyez sur ~INPUT_PICKUP~ pour rendre le véhicule.", + Spawner = 1, + Caution = 2000, + GPS = 0, + Teleport = 0 + }, + + Delivery = { + Pos = {x = -596.158, y = -889.324, z = 24.5073}, + Color = {r = 204, g = 204, b = 0}, + Size = {x = 5.0, y = 5.0, z = 1.0}, + Marker= 1, + Blip = true, + Name = "Point de livraison", + Type = "delivery", + Spawner = 1, + Item = { + { + name = "Livraison", + time = 500, + remove = 1, + max = 100, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua + price = 11, + requires = "packaged_chicken", + requires_name = "Poulet en barquette", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour livrer les barquettes de poulet." + } + } +} \ No newline at end of file diff --git a/jobs/textil.lua b/jobs/textil.lua new file mode 100644 index 00000000..affcae2b --- /dev/null +++ b/jobs/textil.lua @@ -0,0 +1,168 @@ +Config.Jobs.textil = { + BlipInfos = { + Sprite = 366, + Color = 4 + }, + Vehicles = { + Truck = { + Spawner = 1, + Hash = "youga2", + Trailer = "none", + HasCaution = true + } + }, + Zones = { + CloakRoom = { + Pos = {x = 706.735412597656, y = -960.902893066406, z = 29.3953247070313}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = true, + Name = "Vestiaire", + Type = "cloakroom", + Hint = "Appuyez sur ~INPUT_PICKUP~ pour vous changer.", + GPS = {x = 740.808776855469, y = -970.066650390625, z = 23.4693908691406} + }, + + Whool = { + Pos = {x = 1978.92407226563, y = 5171.70166015625, z = 46.6391181945801}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = true, + Name = "Laine", + Type = "work", + Item = { + { + name = "Laine", + db_name= "whool", + time = 3000, + max = 40, + add = 1, + remove = 1, + requires = "nothing", + requires_name = "Nothing", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour récupérer de la laine.", + GPS = {x = 715.954650878906, y = -959.639587402344, z = 29.3953247070313} + }, + + Fabric = { + Pos = {x = 715.954650878906, y = -959.639587402344, z = 29.3953247070313}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = false, + Name = "Tissu", + Type = "work", + Item = { + { + name = "Tissu", + db_name= "fabric", + time = 5000, + max = 80, + add = 2, + remove = 1, + requires = "whool", + requires_name = "Laine", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour fabriquer du tissu.", + GPS = {x = 712.928283691406, y = -970.5869140625, z = 29.3953247070313} + }, + + Clothe = { + Pos = {x = 712.928283691406, y = -970.5869140625, z = 29.3953247070313}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = false, + Name = "Vêtement", + Type = "work", + Item = { + { + name = "Vêtement", + db_name= "clothe", + time = 4000, + max = 40, + add = 1, + remove = 2, + requires = "fabric", + requires_name = "Tissu", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour récupérer des vêtements.", + GPS = {x = 429.595855712891, y = -807.341613769531, z = 28.4911441802979} + }, + + VehicleSpawner = { + Pos = {x = 740.808776855469, y = -970.066650390625, z = 23.4693908691406}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = false, + Name = "Spawner véhicule de fonction", + Type = "vehspawner", + Spawner = 1, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour appeler le véhicule de livraison.", + Caution = 2000, + GPS = {x = 1978.92407226563, y = 5171.70166015625, z = 46.6391181945801} + }, + + VehicleSpawnPoint = { + Pos = {x = 747.31396484375, y = -966.235778808594, z = 23.705005645752}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Marker= -1, + Blip = false, + Name = "Véhicule de fonction", + Type = "vehspawnpt", + Spawner = 1, + Heading = 270.1, + GPS = 0 + }, + + VehicleDeletePoint = { + Pos = {x = 693.796325683594, y = -963.010498046875, z = 22.8247337341309}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 255, g = 0, b = 0}, + Marker= 1, + Blip = false, + Name = "Supression du véhicule", + Type = "vehdelete", + Hint = "Appuyez sur ~INPUT_PICKUP~ pour rendre le véhicule.", + Spawner = 1, + Caution = 2000, + GPS = 0, + Teleport = 0 + }, + + Delivery = { + Pos = {x = 429.595855712891, y = -807.341613769531, z = 28.4911441802979}, + Color = {r = 204, g = 204, b = 0}, + Size = {x = 5.0, y = 5.0, z = 3.0}, + Marker= 1, + Blip = true, + Name = "Point de livraison", + Type = "delivery", + Spawner = 1, + Item = { + { + name = "Livraison", + time = 500, + remove = 1, + max = 100, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua + price = 40, + requires = "clothe", + requires_name = "Vêtement", + drop = 100 + } + }, + Hint = "Appuyez sur ~INPUT_PICKUP~ pour livrer les vêtements.", + GPS = {x = 1978.92407226563, y = 5171.70166015625, z = 46.6391181945801} + } + } +} \ No newline at end of file diff --git a/server/esx_jobs_sv.lua b/server/esx_jobs_sv.lua new file mode 100644 index 00000000..5c1f7ce7 --- /dev/null +++ b/server/esx_jobs_sv.lua @@ -0,0 +1,128 @@ +local PlayersWorking = {} +local Players = {} + +ESX = nil +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +AddEventHandler('esx:playerDropped', function(source) + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) + local caution = xPlayer.get('caution') + TriggerEvent('esx_addonaccount:getAccount', 'caution', xPlayer.identifier, function(account) + account.addMoney(caution) + end) +end) + +RegisterServerEvent('esx_jobs:setCautionInCaseOfDrop') +AddEventHandler('esx_jobs:setCautionInCaseOfDrop', function(caution) + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) + xPlayer.set('caution', caution) +end) + +RegisterServerEvent('esx_jobs:giveBackCautionInCaseOfDrop') +AddEventHandler('esx_jobs:giveBackCautionInCaseOfDrop', function() + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) + + local caution = 0 + TriggerEvent('esx_addonaccount:getAccount', 'caution', xPlayer.identifier, function(account) + caution = account.money + account.removeMoney(caution) + end) + + if caution > 0 then + xPlayer.addAccountMoney('bank', value) + TriggerClientEvent('esx:showNotification', _source, 'Une caution de ~g~'.. value .. '$ ~s~vous a été rendue suite à votre évanouissment.') + else + TriggerClientEvent('esx:showNotification', _source, "Vous n'aviez pas de caution") + end +end) + +RegisterServerEvent('esx_jobs:setCaution') +AddEventHandler('esx_jobs:setCaution', function() + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) + xPlayer.set('caution', 0) +end) + +local function Work(source, item) + SetTimeout(item[1].time, function() + + if PlayersWorking[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + + for i=1, #item, 1 do + local itemQtty = 0 + if item[i].name ~= "Livraison" then + itemQtty = xPlayer.getInventoryItem(item[i].db_name).count + end + + local requiredItemQtty = 0 + if item[1].requires ~= "nothing" then + requiredItemQtty = xPlayer.getInventoryItem(item[1].requires).count + end + + if item[i].name ~= "Livraison" and itemQtty >= item[i].max then + TriggerClientEvent('esx:showNotification', source, 'Vous avez le maximum de: ' .. item[i].name) + elseif item[i].requires ~= "nothing" and requiredItemQtty <= 0 then + TriggerClientEvent('esx:showNotification', source, "Vous n'avez plus assez de " .. item[1].requires_name .. " pour continuer cette tâche.") + else + if item[i].name ~= "Livraison" then + -- Chances to drop the item + if item[i].drop == 100 then + xPlayer.addInventoryItem(item[i].db_name, item[i].add) + else + local chanceToDrop = math.random(100) + if chanceToDrop <= item[i].drop then + xPlayer.addInventoryItem(item[i].db_name, item[i].add) + end + end + else + xPlayer.addMoney(item[i].price) + end + + end + end + + if item[1].requires ~= "nothing" then + local itemToRemoveQtty = xPlayer.getInventoryItem(item[1].requires).count + if itemToRemoveQtty > 0 then + xPlayer.removeInventoryItem(item[1].requires, item[1].remove) + end + end + Work(source, item) + + end + end) +end + +RegisterServerEvent('esx_jobs:startWork') +AddEventHandler('esx_jobs:startWork', function(item) + local source = source + PlayersWorking[source] = true + Work(source, item) +end) + +RegisterServerEvent('esx_jobs:stopWork') +AddEventHandler('esx_jobs:stopWork', function() + local source = source + PlayersWorking[source] = false +end) + +RegisterServerEvent('esx_jobs:caution') +AddEventHandler('esx_jobs:caution', function(cautionType, cautionAmount, spawnPoint, vehicle) + local source = source + local xPlayer = ESX.GetPlayerFromId(source) + if cautionType == "take" then + xPlayer.removeAccountMoney('bank', cautionAmount) + xPlayer.set('caution', cautionAmount) + TriggerClientEvent('esx:showNotification', source, 'Une caution de ~r~'.. cautionAmount .. '$ ~s~vous a été prélevée.') + TriggerClientEvent('esx_jobs:spawnJobVehicle', source, spawnPoint, vehicle) + elseif cautionType == "give_back" then + xPlayer.addAccountMoney('bank', cautionAmount) + xPlayer.set('caution', 0) + TriggerClientEvent('esx:showNotification', source, 'Une caution de ~g~'.. cautionAmount .. '$ ~s~vous a été rendue.') + end +end) \ No newline at end of file From e0d895623837a47de3ea5a99172a4ee4539dab31 Mon Sep 17 00:00:00 2001 From: renaiku Date: Tue, 8 Aug 2017 18:23:25 +0200 Subject: [PATCH 0196/3224] readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6c94f3a2..89ca5a5f 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ The bail is not given back when the player disconnect or timeout. [FEATURES] +- Jobs: Slaughterer, Miner, Fisherman, Journalist, etc... - Bails - Easy system to create jobs (samples in jobs folder) - Item farming jobs From a599d6981a46068c20076d8ff356be1beb7b27d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 8 Aug 2017 19:11:33 +0200 Subject: [PATCH 0197/3224] Add functions --- .../es_extended/client/functions.lua | 114 ++++++++++++++++-- .../es_extended/server/functions.lua | 17 +++ 2 files changed, 121 insertions(+), 10 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index bcdbd663..509211cb 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -265,21 +265,25 @@ ESX.Game.Teleport = function(entity, coords, cb) end -ESX.Game.GetPlayers = function() - - local maxPlayers = Config.MaxPlayers - local players = {} +ESX.Game.SpawnObject = function(model, coords, radius, cb) - for i=0, maxPlayers, 1 do + local model = (type(model) == 'number' and model or GetHashKey(model)) - local ped = GetPlayerPed(i) + Citizen.CreateThread(function() - if DoesEntityExist(ped) then - table.insert(players, i) + RequestModel(model) + + while not HasModelLoaded(model) do + Citizen.Wait(0) end - end - return players + local obj = CreateObject(model, coords.x, coords.y, coords.z, true, true, true) + + if cb ~= nil then + cb(obj) + end + + end) end @@ -356,6 +360,96 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) end +ESX.Game.GetObjects = function() + + local objects = {} + local handle, object = FindFirstObject() + local success = nil + + repeat + table.insert(objects, object) + success, object = FindNextObject(handle) + until not success + + EndFindObject(handle) + + return objects + +end + +ESX.Game.GetClosestObject = function(filter, coords) + + local objects = ESX.Game.GetObjects() + local closestDistance = -1 + local closestPlayer = -1 + local filter = filter + local coords = coords + + if type(filter) == 'string' then + if filter ~= '' then + filter = {filter} + end + end + + if coords == nil then + local playerPed = GetPlayerPed(-1) + coords = GetEntityCoords(playerPed) + end + + for i=1, #objects, 1 do + + local foundObject = false + + if filter == nil or (type(filter) == 'table' and #filter == 0) then + foundObject = true + else + + local objectModel = GetEntityModel(objects[i]) + + for j=1, #filter, 1 do + if objectModel == GetHashKey(filter[j]) then + foundObject = true + end + end + + end + + if foundObject then + + local objectCoords = GetEntityCoords(objects[i]) + local distance = GetDistanceBetweenCoords(objectCoords.x, objectCoords.y, objectCoords.z, coords.x, coords.y, coords.z, true) + + if closestDistance == -1 or closestDistance > distance then + closestObject = objects[i] + closestDistance = distance + end + + end + + end + + return closestObject, closestDistance + +end + +ESX.Game.GetPlayers = function() + + local maxPlayers = Config.MaxPlayers + local players = {} + + for i=0, maxPlayers, 1 do + + local ped = GetPlayerPed(i) + + if DoesEntityExist(ped) then + table.insert(players, i) + end + end + + return players + +end + ESX.Game.GetClosestPlayer = function(coords) local players = ESX.Game.GetPlayers() diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index cb042b02..b1001dba 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -174,6 +174,23 @@ ESX.UseItem = function(source, item) ESX.UsableItemsCallbacks[item](source) end +ESX.GetWeaponList = function() + return Config.Weapons +end + +ESX.GetWeaponLabel = function(name) + + name = string.upper(name) + local weapons = ESX.GetWeaponList() + + for i=1, #weapons, 1 do + if weapons[i].name == name then + return weapons[i].label + end + end + +end + RegisterServerEvent('esx:clientLog') AddEventHandler('esx:clientLog', function(msg) RconPrint(msg .. "\n") From 5459372a3691b57fcf12a5a077e81d0823ceed8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 8 Aug 2017 19:12:38 +0200 Subject: [PATCH 0198/3224] fix Inservice bug + add playerDropped event --- server/main.lua | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index a30b38dc..1828d4a1 100644 --- a/server/main.lua +++ b/server/main.lua @@ -34,10 +34,18 @@ ESX.RegisterServerCallback('esx_service:enableService', function(source, cb, nam if inServiceCount >= MaxInService[name] then cb(false, MaxInService[name], inServiceCount) else - InService[name][source] = enable + InService[name][source] = true cb(true, MaxInService[name], inServiceCount) end end) +AddEventHandler('playerDropped', function(source) + for k,v in pairs(InService) do + if v[source] == true then + v[source] = nil + end + end + +end) \ No newline at end of file From 4e9b529b4c748085542797bb23ee72a280150a16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 8 Aug 2017 19:13:58 +0200 Subject: [PATCH 0199/3224] Fix shared DataStore bug --- esx_datastore.sql | 2 +- server/main.lua | 24 ++++++++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/esx_datastore.sql b/esx_datastore.sql index d9bc4fd5..9a0632a9 100644 --- a/esx_datastore.sql +++ b/esx_datastore.sql @@ -9,7 +9,7 @@ CREATE TABLE `datastore` ( CREATE TABLE `datastore_data` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, - `owner` varchar(255) NOT NULL, + `owner` varchar(255), `data` longtext, PRIMARY KEY (`id`) ); \ No newline at end of file diff --git a/server/main.lua b/server/main.lua index f5f1e7d3..a89d8b21 100644 --- a/server/main.lua +++ b/server/main.lua @@ -2,7 +2,7 @@ ESX = nil Items = {} local DataStoresIndex = {} local DataStores = {} -local SharedDatastores = {} +local SharedDataStores = {} TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) @@ -44,13 +44,25 @@ AddEventHandler('onMySQLReady', function() else - local items = {} + local data = nil - local storeName = result2[1].name - local storeData = (result2[1].data == nil and {} or json.decode(result2[1].data)) + if #result2 == 0 then - local dataStore = CreateDataStore(storeName, nil, storeData) - SharedDatastores[name] = dataStore + MySQL.Sync.execute( + 'INSERT INTO datastore_data (name, owner, data) VALUES (@name, NULL, \'{}\')', + { + ['@name'] = name, + } + ) + + data = {} + + else + data = json.decode(result2[1].data) + end + + local dataStore = CreateDataStore(name, nil, data) + SharedDataStores[name] = dataStore end From 77e93ecee77edb1de20658cc001f702775e489f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 8 Aug 2017 19:17:10 +0200 Subject: [PATCH 0200/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..e5f1f919 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_policejob +FXServer ESX Police Job From e065a26e46e75008bd1907657a0436fd531a04dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 8 Aug 2017 19:43:48 +0200 Subject: [PATCH 0201/3224] Fix GetClosestObject and GetClosestVehicle bugs --- resources/[essential]/es_extended/client/functions.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 509211cb..64323e53 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -381,7 +381,7 @@ ESX.Game.GetClosestObject = function(filter, coords) local objects = ESX.Game.GetObjects() local closestDistance = -1 - local closestPlayer = -1 + local closestObject = -1 local filter = filter local coords = coords @@ -527,7 +527,7 @@ ESX.Game.GetClosestVehicle = function(coords) local vehicles = ESX.Game.GetVehicles() local closestDistance = -1 - local closestPlayer = -1 + local closestVehicle = -1 local coords = coords if coords == nil then From e756b1a60fa3dc9585d62fac15f962096e95b815 Mon Sep 17 00:00:00 2001 From: renaiku Date: Tue, 8 Aug 2017 19:56:18 +0200 Subject: [PATCH 0202/3224] requires + sql --- README.md | 7 +++++++ items.sql | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 items.sql diff --git a/README.md b/README.md index 89ca5a5f..80d46548 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,11 @@ # fxserver-esx_jobs +[REQUIRES] +- fxserver-esx_addonaccount: https://github.com/FXServer-ESX/fxserver-esx_addonaccount +- in the addin_account table add a field like this: + name: caution + label: Caution + shared: 0 + [KNOWN BUGS] The bail is not given back when the player disconnect or timeout. diff --git a/items.sql b/items.sql new file mode 100644 index 00000000..8cd41514 --- /dev/null +++ b/items.sql @@ -0,0 +1,20 @@ +INSERT INTO `items` (`name`, `label`) VALUES +('alive_chicken', 'Poulet vivant'), +('slaughtered_chicken', 'Poulet abattu'), +('packaged_chicken', 'Poulet en barquette'), +('fish', 'Poisson'), +('stone', 'Pierre'), +('washed_stone', 'Pierre Lavée'), +('copper', 'Cuivre'), +('iron', 'Fer'), +('gold', 'Or'), +('diamond', 'Diamant'), +('wood', 'Bois'), +('cutted_wood', 'Bois coupé'), +('packaged_plank', 'Paquet de planches'), +('petrol', 'Pétrole'), +('petrol_raffin', 'Pétrole Raffiné'), +('essence', 'Essence'), +('whool', 'Laine'), +('fabric', 'Tissu'), +('clothe', 'Vêtement'); \ No newline at end of file From 7015139b3399fb5c0b1a4ef21c893df8e5ce0583 Mon Sep 17 00:00:00 2001 From: renaiku Date: Tue, 8 Aug 2017 20:04:58 +0200 Subject: [PATCH 0203/3224] sql --- job_grades.sql | 9 +++++++++ jobs.sql | 9 +++++++++ 2 files changed, 18 insertions(+) create mode 100644 job_grades.sql create mode 100644 jobs.sql diff --git a/job_grades.sql b/job_grades.sql new file mode 100644 index 00000000..687b543b --- /dev/null +++ b/job_grades.sql @@ -0,0 +1,9 @@ +INSERT INTO `job_grades` (`job_name`, `grade`, `name`, `label`, `salary`, `skin_male`, `skin_female`) VALUES +('unemployed', 0, 'rsa', 'RSA', 0, '{}', '{}'), +('lumberjack', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), +('fisherman', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), +('fuel', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), +('reporter', 0, 'employee', 'Intérimaire', 0, '{}', '{}'), +('textil', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), +('miner', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), +('slaughterer', 0, 'interim', 'Intérimaire', 0, , '{}', '{}'); \ No newline at end of file diff --git a/jobs.sql b/jobs.sql new file mode 100644 index 00000000..3f846ee6 --- /dev/null +++ b/jobs.sql @@ -0,0 +1,9 @@ +INSERT INTO `jobs` (`name`, `label`) VALUES +('unemployed', 'Chômeur'), +('slaughterer', 'Abatteur'), +('fisherman', 'Pêcheur'), +('miner', 'Mineur'), +('lumberjack', 'Bûcheron'), +('fuel', 'Raffineur'), +('reporter', 'Journaliste'), +('textil', 'Couturier'), \ No newline at end of file From 57d8abed3d40cace143a77a70731c56330f4fdc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 8 Aug 2017 20:16:19 +0200 Subject: [PATCH 0204/3224] Add files --- README.md | 28 + __resource.lua | 14 + client/main.lua | 1430 +++++++++++++++++++++++++++++++++++++ config.lua | 77 ++ esx_policejob_full.sql | 18 + esx_policejob_minimal.sql | 10 + server/main.lua | 263 +++++++ 7 files changed, 1840 insertions(+) create mode 100644 __resource.lua create mode 100644 client/main.lua create mode 100644 config.lua create mode 100644 esx_policejob_full.sql create mode 100644 esx_policejob_minimal.sql create mode 100644 server/main.lua diff --git a/README.md b/README.md index e5f1f919..0c536d16 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,30 @@ # fxserver-esx_policejob FXServer ESX Police Job + +[REQUIREMENTS] + +* Auto mode + * esx_billing => https://github.com/FXServer-ESX/fxserver-esx_billing + +* Player management (boss actions and armory with buyable weapons) + * esx_society => https://github.com/FXServer-ESX/fxserver-esx_society + * esx_datastore => https://github.com/FXServer-ESX/fxserver-esx_datastore + +[INSTALLATION] + +1) CD in your resources/[esx] folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-esx_taxijob esx_taxijob +``` +3) * Auto mode : Import esx_policejob_minimal.sql in your database + * Player / Armory management : Import esx_policejob_full.sql in your database + +4) Add this in your server.cfg : + +``` +start esx_policejob +``` +5) * If you want player management you have to set Config.EnablePlayerManagement to true in config.lua + * If you want armory management you have to set Config.EnableArmoryManagement to true in config.lua + diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..d486b6f5 --- /dev/null +++ b/__resource.lua @@ -0,0 +1,14 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'ESX Police Job' + +server_scripts { + '@mysql-async/lib/MySQL.lua', + 'config.lua', + 'server/main.lua' +} + +client_scripts { + 'config.lua', + 'client/main.lua' +} diff --git a/client/main.lua b/client/main.lua new file mode 100644 index 00000000..618fd401 --- /dev/null +++ b/client/main.lua @@ -0,0 +1,1430 @@ +local Keys = { + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, + ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, + ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, + ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, + ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 +} + +ESX = nil +local PlayerData = {} +local GUI = {} +GUI.Time = 0 +local HasAlreadyEnteredMarker = false +local LastStation = nil +local LastPart = nil +local LastPartNum = nil +local LastEntity = nil +local CurrentAction = nil +local CurrentActionMsg = '' +local CurrentActionData = {} +local IsHandcuffed = false + +Citizen.CreateThread(function() + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end +end) + +function SetVehicleMaxMods(vehicle) + + local props = { + modEngine = 2, + modBrakes = 2, + modTransmission = 2, + modSuspension = 3, + modTurbo = true, + } + + ESX.Game.SetVehicleProperties(vehicle, props) + +end + +function OpenCloakroomMenu() + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'cloakroom', + { + title = 'Vestiaire', + align = 'top-left', + elements = { + {label = 'Tenue Civil', value = 'citizen_wear'}, + {label = 'Tenue Policier', value = 'police_wear'}, + }, + }, + function(data, menu) + + menu.close() + + if data.current.value == 'citizen_wear' then + + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) + TriggerEvent('skinchanger:loadSkin', skin) + end) + + end + + if data.current.value == 'police_wear' then + + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) + + if skin.sex == 0 then + TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_male) + else + TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_female) + end + + end) + + end + + CurrentAction = 'menu_cloakroom' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour vous changer' + CurrentActionData = {} + + end, + function(data, menu) + + menu.close() + + CurrentAction = 'menu_cloakroom' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour vous changer' + CurrentActionData = {} + end + ) + +end + +function OpenArmoryMenu(station) + + if Config.EnableArmoryManagement then + + local elements = { + {label = 'Prendre Arme', value = 'get_weapon'}, + {label = 'Déposer Arme', value = 'put_weapon'} + } + + if PlayerData.job.grade_name == 'boss' then + table.insert(elements, {label = 'Acheter Armes', value = 'buy_weapons'}) + end + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'armory', + { + title = 'Armurerie', + align = 'top-left', + elements = elements, + }, + function(data, menu) + + if data.current.value == 'get_weapon' then + OpenGetWeaponMenu() + end + + if data.current.value == 'put_weapon' then + OpenPutWeaponMenu() + end + + if data.current.value == 'buy_weapons' then + OpenBuyWeaponsMenu(station) + end + + end, + function(data, menu) + + menu.close() + + CurrentAction = 'menu_armory' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder à l\'armurerie' + CurrentActionData = {station = station} + end + ) + + else + + local elements = {} + + for i=1, #Config.PoliceStations[station].AuthorizedWeapons, 1 do + local weapon = Config.PoliceStations[station].AuthorizedWeapons[i] + table.insert(elements, {label = ESX.GetWeaponLabel(weapon.name), value = weapon.name}) + end + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'armory', + { + title = 'Armurerie', + align = 'top-left', + elements = elements, + }, + function(data, menu) + local weapon = data.current.value + TriggerServerEvent('esx_policejob:giveWeapon', weapon, 1000) + end, + function(data, menu) + + menu.close() + + CurrentAction = 'menu_armory' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder à l\'armurerie' + CurrentActionData = {station = station} + + end + ) + + end + +end + +function OpenVehicleSpawnerMenu(station, partNum) + + local elements = {} + local vehicles = Config.PoliceStations[station].Vehicles + + for i=1, #Config.PoliceStations[station].AuthorizedVehicles, 1 do + local vehicle = Config.PoliceStations[station].AuthorizedVehicles[i] + table.insert(elements, {label = vehicle.label, value = vehicle.name}) + end + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'vehicle_spawner', + { + title = 'Véhicule', + align = 'top-left', + elements = elements, + }, + function(data, menu) + + menu.close() + + local model = data.current.value + + local vehicle, distance = ESX.Game.GetClosestVehicle({ + x = vehicles[partNum].SpawnPoint.x, + y = vehicles[partNum].SpawnPoint.y, + z = vehicles[partNum].SpawnPoint.z + }) + + if distance > 3.0 then + + local playerPed = GetPlayerPed(-1) + + if Config.MaxInService == -1 then + + ESX.Game.SpawnVehicle(model, { + x = vehicles[partNum].SpawnPoint.x, + y = vehicles[partNum].SpawnPoint.y, + z = vehicles[partNum].SpawnPoint.z + }, vehicles[partNum].Heading, function(vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + SetVehicleMaxMods(vehicle) + end) + + else + + ESX.TriggerServerCallback('esx_service:enableService', function(canTakeService, maxInService, inServiceCount) + + if canTakeService then + + ESX.Game.SpawnVehicle(model, { + x = vehicles[partNum].SpawnPoint.x, + y = vehicles[partNum].SpawnPoint.y, + z = vehicles[partNum].SpawnPoint.z + }, vehicles[partNum].Heading, function(vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + SetVehicleMaxMods(vehicle) + end) + + else + ESX.ShowNotification('Service complet : ' .. inServiceCount .. '/' .. maxInService) + end + + end, 'police') + + end + + else + ESX.ShowNotification('Il y a déja un véhicule de sorti') + end + + end, + function(data, menu) + + menu.close() + + CurrentAction = 'menu_vehicle_spawner' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour sortir un véhicule' + CurrentActionData = {station = station, partNum = partNum} + + end + ) + +end + +function OpenPoliceActionsMenu() + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'police_actions', + { + title = 'Police', + align = 'top-left', + elements = { + {label = 'Interaction citoyen', value = 'citizen_interaction'}, + {label = 'Interaction véhicule', value = 'vehicle_interaction'}, + {label = 'Placer objets', value = 'object_spawner'}, + }, + }, + function(data, menu) + + if data.current.value == 'citizen_interaction' then + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'citizen_interaction', + { + title = 'Interaction Csitoyen', + align = 'top-left', + elements = { + {label = 'Carte d\'identité', value = 'identity_card'}, + {label = 'Fouiller', value = 'body_search'}, + {label = 'Menotter / Démenotter', value = 'handcuff'}, + {label = 'Mettre dans véhicule', value = 'put_in_vehicle'}, + {label = 'Amende', value = 'fine'} + }, + }, + function(data2, menu2) + + local player, distance = ESX.Game.GetClosestPlayer() + + if distance ~= -1 and distance <= 3.0 then + + if data2.current.value == 'identity_card' then + OpenIdentityCardMenu(player) + end + + if data2.current.value == 'body_search' then + OpenBodySearchMenu(player) + end + + if data2.current.value == 'handcuff' then + TriggerServerEvent('esx_policejob:handcuff', GetPlayerServerId(player)) + end + + if data2.current.value == 'put_in_vehicle' then + TriggerServerEvent('esx_policejob:putInVehicle', GetPlayerServerId(player)) + end + + if data2.current.value == 'fine' then + OpenFineMenu(player) + end + + else + ESX.ShowNotification('Aucun joueur à proximité') + end + + end, + function(data2, menu2) + menu2.close() + end + ) + + end + + if data.current.value == 'vehicle_interaction' then + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'vehicle_interaction', + { + title = 'Interaction Csitoyen', + align = 'top-left', + elements = { + {label = 'Infos véhicule', value = 'vehicle_infos'}, + {label = 'Crocheter véhicule', value = 'hijack_vehicle'}, + }, + }, + function(data2, menu2) + + local vehicle, distance = ESX.Game.GetClosestVehicle() + + if distance ~= -1 and distance <= 3.0 then + + local vehicleData = ESX.Game.GetVehicleProperties(vehicle) + + if data2.current.value == 'vehicle_infos' then + OpenVehicleInfosMenu(vehicleData) + end + + if data2.current.value == 'hijack_vehicle' then + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + + local vehicle, distance = ESX.Game.GetClosestVehicle({ + x = coords.x, + y = coords.y, + z = coords.z + }) + + if DoesEntityExist(vehicle) then + + Citizen.CreateThread(function() + + TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_WELDING", 0, true) + + Wait(20000) + + ClearPedTasksImmediately(playerPed) + + SetVehicleDoorsLocked(vehicle, 1) + SetVehicleDoorsLockedForAllPlayers(vehicle, false) + + TriggerEvent('esx:showNotification', 'Véhicule ~g~déverouillé~s~') + + end) + + end + + end + + end + + else + ESX.ShowNotification('Aucun véhicule à proximité') + end + + end, + function(data2, menu2) + menu2.close() + end + ) + + end + + if data.current.value == 'object_spawner' then + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'citizen_interaction', + { + title = 'Interaction Csitoyen', + align = 'top-left', + elements = { + {label = 'Plot', value = 'prop_roadcone02a'}, + {label = 'Barrière', value = 'prop_barrier_work06a'}, + {label = 'Herse', value = 'p_ld_stinger_s'}, + {label = 'Caisse', value = 'prop_boxpile_07d'}, + {label = 'Caisse', value = 'hei_prop_cash_crate_half_full'} + }, + }, + function(data2, menu2) + + + local model = data2.current.value + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + local forward = GetEntityForwardVector(playerPed) + local x, y, z = table.unpack(coords + forward * 1.0) + + if model == 'prop_roadcone02a' then + z = z - 2.0 + end + + ESX.Game.SpawnObject(model, { + x = x, + y = y, + z = z + }, 3.0, function(obj) + SetEntityHeading(obj, GetEntityHeading(playerPed)) + PlaceObjectOnGroundProperly(obj) + end) + + end, + function(data2, menu2) + menu2.close() + end + ) + + end + + end, + function(data, menu) + + menu.close() + + end + ) + +end + +function OpenIdentityCardMenu(player) + + ESX.TriggerServerCallback('esx_policejob:getOtherPlayerData', function(data) + + local jobLabel = nil + + if data.job.grade_label ~= nil and data.job.grade_label ~= '' then + jobLabel = 'Job : ' .. data.job.label .. ' - ' .. data.job.grade_label + else + jobLabel = 'Job : ' .. data.job.label + end + + local elements = { + {label = 'Nom : ' .. data.name, value = nil}, + {label = jobLabel, value = nil}, + } + + if data.drunk ~= nil then + table.insert(elements, {label = 'Alcoolémie : ' .. data.drunk .. '%', value = nil}) + end + + if data.licenses ~= nil then + + table.insert(elements, {label = '--- Licenses ---', value = nil}) + + for i=1, #data.licenses, 1 do + table.insert(elements, {label = data.licenses[i].label, value = nil}) + end + + end + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'citizen_interaction', + { + title = 'Interaction Citoyen', + align = 'top-left', + elements = elements, + }, + function(data, menu) + + end, + function(data, menu) + menu.close() + end + ) + + end, GetPlayerServerId(player)) + +end + +function OpenBodySearchMenu(player) + + ESX.TriggerServerCallback('esx_policejob:getOtherPlayerData', function(data) + + local elements = {} + + local blackMoney = 0 + + for i=1, #data.accounts, 1 do + if data.accounts[i].name == 'black_money' then + blackMoney = data.accounts[i].money + end + end + + table.insert(elements, { + label = 'Confisquer argent sale : $' .. blackMoney, + value = 'black_money', + itemType = 'item_account', + amount = blackMoney + }) + + table.insert(elements, {label = '--- Armes ---', value = nil}) + + for i=1, #data.weapons, 1 do + table.insert(elements, { + label = 'Confisquer ' .. ESX.GetWeaponLabel(data.weapons[i].name), + value = data.weapons[i].name, + itemType = 'item_weapon', + amount = data.ammo, + }) + end + + table.insert(elements, {label = '--- Inventaire ---', value = nil}) + + for i=1, #data.inventory, 1 do + if data.inventory[i].count > 0 then + table.insert(elements, { + label = 'Confisquer x' .. data.inventory[i].count .. ' ' .. data.inventory[i].label, + value = data.inventory[i].name, + itemType = 'item_standard', + amount = data.inventory[i].count, + }) + end + end + + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'body_search', + { + title = 'Fouille', + align = 'top-left', + elements = elements, + }, + function(data, menu) + + local itemType = data.current.itemType + local itemName = data.current.value + local amount = data.current.amount + + if data.current.value ~= nil then + + TriggerServerEvent('esx_policejob:confiscatePlayerItem', GetPlayerServerId(player), itemType, itemName, amount) + + OpenBodySearchMenu(player) + + end + + end, + function(data, menu) + menu.close() + end + ) + + end, GetPlayerServerId(player)) + +end + +function OpenFineMenu(player) + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'fine', + { + title = 'Amende', + align = 'top-left', + elements = { + {label = 'Code de la route', value = 0}, + {label = 'Délit mineur', value = 1}, + {label = 'Délit moyen', value = 2}, + {label = 'Délit grave', value = 3} + }, + }, + function(data, menu) + + OpenFineCategoryMenu(player, data.current.value) + + end, + function(data, menu) + menu.close() + end + ) + +end + +function OpenFineCategoryMenu(player, category) + + ESX.TriggerServerCallback('esx_policejob:getFineList', function(fines) + + local elements = {} + + for i=1, #fines, 1 do + table.insert(elements, { + label = fines[i].label .. ' $' .. fines[i].amount, + value = fines[i].id, + amount = fines[i].amount, + fineLabel = fines[i].label + }) + end + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'fine_category', + { + title = 'Amende', + align = 'top-left', + elements = elements, + }, + function(data, menu) + + local label = data.current.fineLabel + local amount = data.current.amount + + menu.close() + + if Config.EnablePlayerManagement then + TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(player), 'society_police', 'Amende : ' .. label, amount) + else + TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(player), '', 'Amende : ' .. label, amount) + end + + ESX.SetTimeout(300, function() + OpenFineCategoryMenu(player, category) + end) + + end, + function(data, menu) + menu.close() + end + ) + + end, category) + +end + +function OpenVehicleInfosMenu(vehicleData) + + ESX.TriggerServerCallback('esx_policejob:getVehicleInfos', function(infos) + + local elements = {} + + table.insert(elements, {label = 'N°: ' .. infos.plate, value = nil}) + + if infos.owner == nil then + table.insert(elements, {label = 'Propriétaire : Inconnu', value = nil}) + else + table.insert(elements, {label = 'Propriétaire : ' .. infos.owner, value = nil}) + end + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'vehicle_infos', + { + title = 'Infos Véhicule', + align = 'top-left', + elements = elements, + }, + nil, + function(data, menu) + menu.close() + end + ) + + end, vehicleData.plate) + +end + +function OpenGetWeaponMenu() + + ESX.TriggerServerCallback('esx_policejob:getArmoryWeapons', function(weapons) + + local elements = {} + + for i=1, #weapons, 1 do + if weapons[i].count > 0 then + table.insert(elements, {label = 'x' .. weapons[i].count .. ' ' .. ESX.GetWeaponLabel(weapons[i].name), value = weapons[i].name}) + end + end + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'armory_get_weapon', + { + title = 'Armurerie - Prendre Arme', + align = 'top-left', + elements = elements, + }, + function(data, menu) + + menu.close() + + ESX.TriggerServerCallback('esx_policejob:removeArmoryWeapon', function() + OpenGetWeaponMenu() + end, data.current.value) + + end, + function(data, menu) + menu.close() + end + ) + + end) + +end + +function OpenPutWeaponMenu() + + local elements = {} + local playerPed = GetPlayerPed(-1) + local weaponList = ESX.GetWeaponList() + + for i=1, #weaponList, 1 do + + local weaponHash = GetHashKey(weaponList[i].name) + + if HasPedGotWeapon(playerPed, weaponHash, false) and weaponList[i].name ~= 'WEAPON_UNARMED' then + local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) + table.insert(elements, {label = weaponList[i].label, value = weaponList[i].name}) + end + + end + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'armory_put_weapon', + { + title = 'Armurerie - Déposer Arme', + align = 'top-left', + elements = elements, + }, + function(data, menu) + + menu.close() + + ESX.TriggerServerCallback('esx_policejob:addArmoryWeapon', function() + OpenPutWeaponMenu() + end, data.current.value) + + end, + function(data, menu) + menu.close() + end + ) + +end + +function OpenBuyWeaponsMenu(station) + + ESX.TriggerServerCallback('esx_policejob:getArmoryWeapons', function(weapons) + + local elements = {} + + for i=1, #Config.PoliceStations[station].AuthorizedWeapons, 1 do + + local weapon = Config.PoliceStations[station].AuthorizedWeapons[i] + local count = 0 + + for i=1, #weapons, 1 do + if weapons[i].name == weapon.name then + count = weapons[i].count + break + end + end + + table.insert(elements, {label = 'x' .. count .. ' ' .. ESX.GetWeaponLabel(weapon.name) .. ' $' .. weapon.price, value = weapon.name, price = weapon.price}) + + end + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'armory_buy_weapons', + { + title = 'Armurerie - Acheter Armes', + align = 'top-left', + elements = elements, + }, + function(data, menu) + + ESX.TriggerServerCallback('esx_policejob:buy', function(hasEnoughMoney) + + if hasEnoughMoney then + ESX.TriggerServerCallback('esx_policejob:addArmoryWeapon', function() + OpenBuyWeaponsMenu(station) + end, data.current.value) + else + ESX.ShowNotification('Vous n\'avez pas assez d\'argent') + end + + end, data.current.price) + + end, + function(data, menu) + menu.close() + end + ) + + end) + +end + +function OpenBossActionsMenu() + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'realestateagent', + { + title = PlayerData.job.grade_label, + elements = { + {label = 'Retirer argent société', value = 'withdraw_society_money'}, + {label = 'Déposer argent', value = 'deposit_money'}, + } + }, + function(data, menu) + + if data.current.value == 'withdraw_society_money' then + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'withdraw_society_money_amount', + { + title = 'Montant du retrait' + }, + function(data, menu) + + local amount = tonumber(data.value) + + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + menu.close() + TriggerServerEvent('esx_society:withdrawMoney', 'police', amount) + end + + end, + function(data, menu) + menu.close() + end + ) + + end + + if data.current.value == 'deposit_money' then + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'deposit_money_amount', + { + title = 'Montant du dépôt' + }, + function(data, menu) + + local amount = tonumber(data.value) + + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + menu.close() + TriggerServerEvent('esx_society:depositMoney', 'police', amount) + end + + end, + function(data, menu) + menu.close() + end + ) + + end + + end, + function(data, menu) + + menu.close() + + CurrentAction = 'menu_boss_actions' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour ouvrir le menu' + CurrentActionData = {} + + end + ) + +end + +RegisterNetEvent('esx:playerLoaded') +AddEventHandler('esx:playerLoaded', function(xPlayer) + PlayerData = xPlayer +end) + +RegisterNetEvent('esx:setJob') +AddEventHandler('esx:setJob', function(job) + PlayerData.job = job +end) + +AddEventHandler('esx_policejob:hasEnteredMarker', function(station, part, partNum) + + if part == 'Cloakroom' then + CurrentAction = 'menu_cloakroom' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour vous changer' + CurrentActionData = {} + end + + if part == 'Armory' then + CurrentAction = 'menu_armory' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder à l\'armurerie' + CurrentActionData = {station = station} + end + + if part == 'VehicleSpawner' then + CurrentAction = 'menu_vehicle_spawner' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour sortir un véhicule' + CurrentActionData = {station = station, partNum = partNum} + end + + if part == 'HelicopterSpawner' then + + local helicopters = Config.PoliceStations[station].Helicopters + + local vehicle, distance = ESX.Game.GetClosestVehicle({ + x = helicopters[partNum].SpawnPoint.x, + y = helicopters[partNum].SpawnPoint.y, + z = helicopters[partNum].SpawnPoint.z + }) + + if distance > 3.0 then + + ESX.Game.SpawnVehicle('polmav', { + x = helicopters[partNum].SpawnPoint.x, + y = helicopters[partNum].SpawnPoint.y, + z = helicopters[partNum].SpawnPoint.z + }, helicopters[partNum].Heading, function(vehicle) + SetVehicleModKit(vehicle, 0) + SetVehicleLivery(vehicle, 0) + end) + + end + + end + + if part == 'VehicleDeleter' then + + local playerPed = GetPlayerPed(-1) + + if IsPedInAnyVehicle(playerPed, false) then + + local vehicle, distance = ESX.Game.GetClosestVehicle() + + if distance <= 2.0 then + CurrentAction = 'delete_vehicle' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour ranger le véhicule' + CurrentActionData = {vehicle = vehicle} + end + + end + + end + + if part == 'BossActions' then + CurrentAction = 'menu_boss_actions' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour ouvrir le menu' + CurrentActionData = {} + end + +end) + +AddEventHandler('esx_policejob:hasExitedMarker', function(station, part, partNum) + CurrentAction = nil +end) + +AddEventHandler('esx_policejob:hasEnteredEntityZone', function(entity) + + local playerPed = GetPlayerPed(-1) + + if PlayerData.job ~= nil and PlayerData.job.name == 'police' and not IsPedInAnyVehicle(playerPed, false) then + CurrentAction = 'remove_entity' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour enlever l\'objet' + CurrentActionData = {entity = entity} + end + + if GetEntityModel(entity) == GetHashKey('p_ld_stinger_s') then + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + if IsPedInAnyVehicle(playerPed, false) then + + local vehicle, distance = ESX.Game.GetClosestVehicle({ + x = coords.x, + y = coords.y, + z = coords.z + }) + + if distance <= 1.0 then + + for i=0, 7, 1 do + SetVehicleTyreBurst(vehicle, i, true, 1000) + end + + end + + end + + end + +end) + +AddEventHandler('esx_policejob:hasExitedEntityZone', function(entity) + + if CurrentAction == 'remove_entity' then + CurrentAction = nil + end + +end) + +RegisterNetEvent('esx_policejob:handcuff') +AddEventHandler('esx_policejob:handcuff', function() + + IsHandcuffed = not IsHandcuffed; + local playerPed = GetPlayerPed(-1) + + Citizen.CreateThread(function() + + if IsHandcuffed then + + RequestAnimDict('mp_arresting') + + while not HasAnimDictLoaded('mp_arresting') do + Wait(100) + end + + TaskPlayAnim(playerPed, 'mp_arresting', 'idle', 8.0, -8, -1, 49, 0, 0, 0, 0) + SetEnableHandcuffs(playerPed, true) + SetPedCanPlayGestureAnims(playerPed, false) + FreezeEntityPosition(playerPed, true) + + else + + ClearPedSecondaryTask(playerPed) + SetEnableHandcuffs(playerPed, false) + SetPedCanPlayGestureAnims(playerPed, true) + FreezeEntityPosition(playerPed, false) + + end + + end) +end) + +RegisterNetEvent('esx_policejob:putInVehicle') +AddEventHandler('esx_policejob:putInVehicle', function() + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + + local vehicle, distance = ESX.Game.GetClosestVehicle({ + x = coords.x, + y = coords.y, + z = coords.z + }) + + if DoesEntityExist(vehicle) then + + local maxSeats = GetVehicleMaxNumberOfPassengers(vehicle) + local freeSeat = nil + + for i=maxSeats - 1, 0, -1 do + if IsVehicleSeatFree(vehicle, i) then + freeSeat = i + break + end + end + + if freeSeat ~= nil then + TaskWarpPedIntoVehicle(playerPed, vehicle, freeSeat) + end + + end + + end + +end) + +-- Handcuff +Citizen.CreateThread(function() + while true do + Wait(0) + if IsHandcuffed then + DisableControlAction(0, 142, true) -- MeleeAttackAlternate + DisableControlAction(0, 30, true) -- MoveLeftRight + DisableControlAction(0, 31, true) -- MoveUpDown + end + end +end) + +-- Create blips +Citizen.CreateThread(function() + + for k,v in pairs(Config.PoliceStations) do + + local blip = AddBlipForCoord(v.Blip.Pos.x, v.Blip.Pos.y, v.Blip.Pos.z) + + SetBlipSprite (blip, 60) + SetBlipDisplay(blip, 4) + SetBlipScale (blip, 1.2) + SetBlipColour (blip, v.Blip.Color) + SetBlipAsShortRange(blip, true) + + BeginTextCommandSetBlipName("STRING") + AddTextComponentString("Commissariat") + EndTextCommandSetBlipName(blip) + + end + +end) + +-- Display markers +Citizen.CreateThread(function() + while true do + + Wait(0) + + if PlayerData.job ~= nil and PlayerData.job.name == 'police' then + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + for k,v in pairs(Config.PoliceStations) do + + for i=1, #v.Cloakrooms, 1 do + if GetDistanceBetweenCoords(coords, v.Cloakrooms[i].x, v.Cloakrooms[i].y, v.Cloakrooms[i].z, true) < Config.DrawDistance then + DrawMarker(Config.MarkerType, v.Cloakrooms[i].x, v.Cloakrooms[i].y, v.Cloakrooms[i].z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.MarkerSize.x, Config.MarkerSize.y, Config.MarkerSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) + end + end + + for i=1, #v.Armories, 1 do + if GetDistanceBetweenCoords(coords, v.Armories[i].x, v.Armories[i].y, v.Armories[i].z, true) < Config.DrawDistance then + DrawMarker(Config.MarkerType, v.Armories[i].x, v.Armories[i].y, v.Armories[i].z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.MarkerSize.x, Config.MarkerSize.y, Config.MarkerSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) + end + end + + for i=1, #v.Vehicles, 1 do + if GetDistanceBetweenCoords(coords, v.Vehicles[i].Spawner.x, v.Vehicles[i].Spawner.y, v.Vehicles[i].Spawner.z, true) < Config.DrawDistance then + DrawMarker(Config.MarkerType, v.Vehicles[i].Spawner.x, v.Vehicles[i].Spawner.y, v.Vehicles[i].Spawner.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.MarkerSize.x, Config.MarkerSize.y, Config.MarkerSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) + end + end + + for i=1, #v.VehicleDeleters, 1 do + if GetDistanceBetweenCoords(coords, v.VehicleDeleters[i].x, v.VehicleDeleters[i].y, v.VehicleDeleters[i].z, true) < Config.DrawDistance then + DrawMarker(Config.MarkerType, v.VehicleDeleters[i].x, v.VehicleDeleters[i].y, v.VehicleDeleters[i].z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.MarkerSize.x, Config.MarkerSize.y, Config.MarkerSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) + end + end + + if Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.name == 'police' and PlayerData.job.grade_name == 'boss' then + + for i=1, #v.BossActions, 1 do + if not v.BossActions[i].disabled and GetDistanceBetweenCoords(coords, v.BossActions[i].x, v.BossActions[i].y, v.BossActions[i].z, true) < Config.DrawDistance then + DrawMarker(Config.MarkerType, v.BossActions[i].x, v.BossActions[i].y, v.BossActions[i].z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.MarkerSize.x, Config.MarkerSize.y, Config.MarkerSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) + end + end + + end + + end + + end + + end +end) + +-- Enter / Exit marker events +Citizen.CreateThread(function() + + while true do + + Wait(0) + + if PlayerData.job ~= nil and PlayerData.job.name == 'police' then + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + local isInMarker = false + local currentStation = nil + local currentPart = nil + local currentPartNum = nil + + for k,v in pairs(Config.PoliceStations) do + + for i=1, #v.Cloakrooms, 1 do + if GetDistanceBetweenCoords(coords, v.Cloakrooms[i].x, v.Cloakrooms[i].y, v.Cloakrooms[i].z, true) < Config.MarkerSize.x then + isInMarker = true + currentStation = k + currentPart = 'Cloakroom' + currentPartNum = i + end + end + + for i=1, #v.Armories, 1 do + if GetDistanceBetweenCoords(coords, v.Armories[i].x, v.Armories[i].y, v.Armories[i].z, true) < Config.MarkerSize.x then + isInMarker = true + currentStation = k + currentPart = 'Armory' + currentPartNum = i + end + end + + for i=1, #v.Vehicles, 1 do + + if GetDistanceBetweenCoords(coords, v.Vehicles[i].Spawner.x, v.Vehicles[i].Spawner.y, v.Vehicles[i].Spawner.z, true) < Config.MarkerSize.x then + isInMarker = true + currentStation = k + currentPart = 'VehicleSpawner' + currentPartNum = i + end + + if GetDistanceBetweenCoords(coords, v.Vehicles[i].SpawnPoint.x, v.Vehicles[i].SpawnPoint.y, v.Vehicles[i].SpawnPoint.z, true) < Config.MarkerSize.x then + isInMarker = true + currentStation = k + currentPart = 'VehicleSpawnPoint' + currentPartNum = i + end + + end + + for i=1, #v.Helicopters, 1 do + + if GetDistanceBetweenCoords(coords, v.Helicopters[i].Spawner.x, v.Helicopters[i].Spawner.y, v.Helicopters[i].Spawner.z, true) < Config.MarkerSize.x then + isInMarker = true + currentStation = k + currentPart = 'HelicopterSpawner' + currentPartNum = i + end + + if GetDistanceBetweenCoords(coords, v.Helicopters[i].SpawnPoint.x, v.Helicopters[i].SpawnPoint.y, v.Helicopters[i].SpawnPoint.z, true) < Config.MarkerSize.x then + isInMarker = true + currentStation = k + currentPart = 'HelicopterSpawnPoint' + currentPartNum = i + end + + end + + for i=1, #v.VehicleDeleters, 1 do + if GetDistanceBetweenCoords(coords, v.VehicleDeleters[i].x, v.VehicleDeleters[i].y, v.VehicleDeleters[i].z, true) < Config.MarkerSize.x then + isInMarker = true + currentStation = k + currentPart = 'VehicleDeleter' + currentPartNum = i + end + end + + if Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.name == 'police' and PlayerData.job.grade_name == 'boss' then + + for i=1, #v.BossActions, 1 do + if GetDistanceBetweenCoords(coords, v.BossActions[i].x, v.BossActions[i].y, v.BossActions[i].z, true) < Config.MarkerSize.x then + isInMarker = true + currentStation = k + currentPart = 'BossActions' + currentPartNum = i + end + end + + end + + end + + local hasExited = false + + if isInMarker and not HasAlreadyEnteredMarker or (isInMarker and (LastStation ~= currentStation or LastPart ~= currentPart or LastPartNum ~= currentPartNum) ) then + + if + (LastStation ~= nil and LastPart ~= nil and LastPartNum ~= nil) and + (LastStation ~= currentStation or LastPart ~= currentPart or LastPartNum ~= currentPartNum) + then + TriggerEvent('esx_policejob:hasExitedMarker', LastStation, LastPart, LastPartNum) + hasExited = true + end + + HasAlreadyEnteredMarker = true + LastStation = currentStation + LastPart = currentPart + LastPartNum = currentPartNum + + TriggerEvent('esx_policejob:hasEnteredMarker', currentStation, currentPart, currentPartNum) + end + + if not hasExited and not isInMarker and HasAlreadyEnteredMarker then + + HasAlreadyEnteredMarker = false + + TriggerEvent('esx_policejob:hasExitedMarker', LastStation, LastPart, LastPartNum) + end + + end + + end +end) + +-- Enter / Exit entity zone events +Citizen.CreateThread(function() + while true do + + Citizen.Wait(0) + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + local entity, distance = ESX.Game.GetClosestObject({ + 'prop_roadcone02a', + 'prop_barrier_work06a', + 'p_ld_stinger_s', + 'prop_boxpile_07d', + 'hei_prop_cash_crate_half_full' + }) + + if distance ~= -1 and distance <= 3.0 then + + if LastEntity ~= entity then + TriggerEvent('esx_policejob:hasEnteredEntityZone', entity) + LastEntity = entity + end + + else + + if LastEntity ~= nil then + TriggerEvent('esx_policejob:hasExitedEntityZone', LastEntity) + LastEntity = nil + end + + end + + end +end) + +-- Key Controls +Citizen.CreateThread(function() + while true do + + Citizen.Wait(0) + + if CurrentAction ~= nil then + + SetTextComponentFormat('STRING') + AddTextComponentString(CurrentActionMsg) + DisplayHelpTextFromStringLabel(0, 0, 1, -1) + + if IsControlPressed(0, Keys['E']) and PlayerData.job ~= nil and PlayerData.job.name == 'police' and (GetGameTimer() - GUI.Time) > 150 then + + if CurrentAction == 'menu_cloakroom' then + OpenCloakroomMenu() + end + + if CurrentAction == 'menu_armory' then + OpenArmoryMenu(CurrentActionData.station) + end + + if CurrentAction == 'menu_vehicle_spawner' then + OpenVehicleSpawnerMenu(CurrentActionData.station, CurrentActionData.partNum) + end + + if CurrentAction == 'delete_vehicle' then + + if + GetEntityModel(vehicle) == GetHashKey('police') or + GetEntityModel(vehicle) == GetHashKey('police2') or + GetEntityModel(vehicle) == GetHashKey('police3') or + GetEntityModel(vehicle) == GetHashKey('police4') or + GetEntityModel(vehicle) == GetHashKey('policeb') or + GetEntityModel(vehicle) == GetHashKey('policet') + then + TriggerServerEvent('esx_service:disableService', 'police') + end + + ESX.Game.DeleteVehicle(CurrentActionData.vehicle) + end + + if CurrentAction == 'menu_boss_actions' then + OpenBossActionsMenu() + end + + if CurrentAction == 'remove_entity' then + DeleteEntity(CurrentActionData.entity) + end + + CurrentAction = nil + GUI.Time = GetGameTimer() + + end + + end + + if IsControlPressed(0, Keys['F6']) and PlayerData.job ~= nil and PlayerData.job.name == 'police' and not ESX.UI.Menu.IsOpen('default', GetCurrentResourceName(), 'police_actions') and (GetGameTimer() - GUI.Time) > 150 then + OpenPoliceActionsMenu() + GUI.Time = GetGameTimer() + end + + end +end) diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..00e67176 --- /dev/null +++ b/config.lua @@ -0,0 +1,77 @@ +Config = {} +Config.DrawDistance = 100.0 +Config.MarkerType = 1 +Config.MarkerSize = {x = 1.5, y = 1.5, z = 1.0} +Config.MarkerColor = {r = 50, g = 50, b = 204} +Config.EnablePlayerManagement = false +Config.EnableArmoryManagement = false +Config.MaxInService = -1 + +Config.PoliceStations = { + + LSPD = { + + Blip = { + Pos = {x = 425.130, y = -979.558, z = 30.711}, + Color = 29 + }, + + AuthorizedWeapons = { + {name = 'WEAPON_NIGHTSTICK', price = 200}, + {name = 'WEAPON_COMBATPISTOL', price = 300}, + {name = 'WEAPON_ASSAULTSMG', price = 1250}, + {name = 'WEAPON_ASSAULTRIFLE', price = 1500}, + {name = 'WEAPON_PUMPSHOTGUN', price = 600}, + {name = 'WEAPON_STUNGUN', price = 500}, + {name = 'WEAPON_FLASHLIGHT', price = 80}, + {name = 'WEAPON_FIREEXTINGUISHER', price = 120}, + {name = 'WEAPON_FLAREGUN', price = 60}, + {name = 'WEAPON_STICKYBOMB', price = 250}, + {name = 'GADGET_PARACHUTE', price = 300}, + }, + + AuthorizedVehicles = { + {name = 'police' , label = 'Véhicule de patrouille 1'}, + {name = 'police2', label = 'Véhicule de patrouille 2'}, + {name = 'police3', label = 'Véhicule de patrouille 3'}, + {name = 'police4', label = 'Véhicule civil'}, + {name = 'policeb', label = 'Moto'}, + {name = 'policet', label = 'Van de transport'}, + }, + + Cloakrooms = { + {x = 452.600, y = -993.306, z = 29.750} + }, + + Armories = { + {x = 451.699, y = -980.356, z = 29.689} + }, + + Vehicles = { + { + Spawner = {x = 454.69, y = -1017.4, z = 27.430}, + SpawnPoint = {x = 438.42, y = -1018.3, z = 27.757}, + Heading = 90.0 + } + }, + + Helicopters = { + { + Spawner = {x = 466.477, y = -982.819, z = 42.691}, + SpawnPoint = {x = 450.04, y = -981.14, z = 42.691}, + Heading = 0.0 + } + }, + + VehicleDeleters = { + {x = 462.74, y = -1014.4, z = 27.065}, + {x = 462.40, y = -1019.7, z = 27.104} + }, + + BossActions = { + {x = 448.417, y = -973.208, z = 29.689} + } + + } + +} \ No newline at end of file diff --git a/esx_policejob_full.sql b/esx_policejob_full.sql new file mode 100644 index 00000000..543a5801 --- /dev/null +++ b/esx_policejob_full.sql @@ -0,0 +1,18 @@ +INSERT INTO `addon_account` (name, label, shared) VALUES + ('society_police','Police',1) +; + +INSERT INTO `datastore` (name, label, shared) VALUES + ('society_police','Police',1) +; + +INSERT INTO `jobs` (name, label) VALUES + ('police','LSPD') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('police',0,'recrue','Recrue',20,'{\"tshirt_1\":57,\"torso_1\":55,\"arms\":0,\"pants_1\":35,\"glasses\":0,\"decals_2\":0,\"hair_color_2\":0,\"helmet_2\":0,\"hair_color_1\":5,\"face\":19,\"glasses_2\":1,\"torso_2\":0,\"shoes\":24,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"pants_2\":0,\"hair_2\":0,\"decals_1\":0,\"tshirt_2\":0,\"helmet_1\":8}','{\"tshirt_1\":34,\"torso_1\":48,\"shoes\":24,\"pants_1\":34,\"torso_2\":0,\"decals_2\":0,\"hair_color_2\":0,\"glasses\":0,\"helmet_2\":0,\"hair_2\":3,\"face\":21,\"decals_1\":0,\"glasses_2\":1,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"pants_2\":0,\"arms\":14,\"hair_color_1\":10,\"tshirt_2\":0,\"helmet_1\":57}'), + ('police',1,'sergeant','Sergent',40,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":1,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"arms\":0,\"decals_1\":8,\"torso_2\":0,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"hair_color_1\":5,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":14,\"pants_1\":34,\"pants_2\":0,\"decals_2\":1,\"hair_color_2\":0,\"shoes\":24,\"helmet_2\":0,\"hair_2\":3,\"decals_1\":7,\"torso_2\":0,\"face\":21,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"glasses_2\":1,\"hair_color_1\":10,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}'), + ('police',2,'lieutenant','Lieutenant',65,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":2,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"glasses\":0,\"decals_1\":8,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"torso_2\":0,\"arms\":41,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"hair_2\":3,\"decals_2\":2,\"hair_color_2\":0,\"hair_color_1\":10,\"helmet_2\":0,\"face\":21,\"shoes\":24,\"torso_2\":0,\"glasses_2\":1,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"pants_2\":0,\"decals_1\":7,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}'), + ('police',3,'commandant','Commandant',80,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"arms\":41,\"torso_2\":0,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"decals_1\":8,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":21,\"helmet_2\":0,\"hair_2\":3,\"decals_1\":7,\"torso_2\":0,\"hair_color_1\":10,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"glasses_2\":1,\"shoes\":24,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}') +; diff --git a/esx_policejob_minimal.sql b/esx_policejob_minimal.sql new file mode 100644 index 00000000..fca6635c --- /dev/null +++ b/esx_policejob_minimal.sql @@ -0,0 +1,10 @@ +INSERT INTO `jobs` (name, label) VALUES + ('police','LSPD') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('police',0,'recrue','Recrue',20,'{\"tshirt_1\":57,\"torso_1\":55,\"arms\":0,\"pants_1\":35,\"glasses\":0,\"decals_2\":0,\"hair_color_2\":0,\"helmet_2\":0,\"hair_color_1\":5,\"face\":19,\"glasses_2\":1,\"torso_2\":0,\"shoes\":24,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"pants_2\":0,\"hair_2\":0,\"decals_1\":0,\"tshirt_2\":0,\"helmet_1\":8}','{\"tshirt_1\":34,\"torso_1\":48,\"shoes\":24,\"pants_1\":34,\"torso_2\":0,\"decals_2\":0,\"hair_color_2\":0,\"glasses\":0,\"helmet_2\":0,\"hair_2\":3,\"face\":21,\"decals_1\":0,\"glasses_2\":1,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"pants_2\":0,\"arms\":14,\"hair_color_1\":10,\"tshirt_2\":0,\"helmet_1\":57}'), + ('police',1,'sergeant','Sergent',40,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":1,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"arms\":0,\"decals_1\":8,\"torso_2\":0,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"hair_color_1\":5,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":14,\"pants_1\":34,\"pants_2\":0,\"decals_2\":1,\"hair_color_2\":0,\"shoes\":24,\"helmet_2\":0,\"hair_2\":3,\"decals_1\":7,\"torso_2\":0,\"face\":21,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"glasses_2\":1,\"hair_color_1\":10,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}'), + ('police',2,'lieutenant','Lieutenant',65,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":2,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"glasses\":0,\"decals_1\":8,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"torso_2\":0,\"arms\":41,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"hair_2\":3,\"decals_2\":2,\"hair_color_2\":0,\"hair_color_1\":10,\"helmet_2\":0,\"face\":21,\"shoes\":24,\"torso_2\":0,\"glasses_2\":1,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"pants_2\":0,\"decals_1\":7,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}'), + ('police',3,'commandant','Commandant',80,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"arms\":41,\"torso_2\":0,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"decals_1\":8,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":21,\"helmet_2\":0,\"hair_2\":3,\"decals_1\":7,\"torso_2\":0,\"hair_color_1\":10,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"glasses_2\":1,\"shoes\":24,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}') +; diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..11ace9c4 --- /dev/null +++ b/server/main.lua @@ -0,0 +1,263 @@ +ESX = nil + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +if Config.MaxInService ~= -1 then + TriggerEvent('esx_service:activateService', 'police', Config.MaxInService) +end + +RegisterServerEvent('esx_policejob:giveWeapon') +AddEventHandler('esx_policejob:giveWeapon', function(weapon, ammo) + local xPlayer = ESX.GetPlayerFromId(source) + xPlayer.addWeapon(weapon, ammo) +end) + +RegisterServerEvent('esx_policejob:confiscatePlayerItem') +AddEventHandler('esx_policejob:confiscatePlayerItem', function(target, itemType, itemName, amount) + + local sourceXPlayer = ESX.GetPlayerFromId(source) + local targetXPlayer = ESX.GetPlayerFromId(target) + + if itemType == 'item_standard' then + + local label = sourceXPlayer.getInventoryItem(itemName).label + + targetXPlayer.removeInventoryItem(itemName, amount) + sourceXPlayer.addInventoryItem(itemName, amount) + + TriggerClientEvent('esx:showNotification', sourceXPlayer.source, 'Vous avez confisqué ~y~x' .. amount .. ' ' .. label .. '~s~ à ~b~' .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', targetXPlayer.source, '~b~' .. targetXPlayer.name .. '~s~ vous a confisqué ~y~x' .. amount .. ' ' .. label ) + + end + + if itemType == 'item_account' then + + targetXPlayer.removeAccountMoney(itemName, amount) + sourceXPlayer.addAccountMoney(itemName, amount) + + TriggerClientEvent('esx:showNotification', sourceXPlayer.source, 'Vous avez confisqué ~y~$' .. amount .. '~s~ à ~b~' .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', targetXPlayer.source, '~b~' .. targetXPlayer.name .. '~s~ vous a confisqué ~y~$' .. amount) + + end + + if itemType == 'item_weapon' then + + targetXPlayer.removeWeapon(itemName) + sourceXPlayer.addWeapon(itemName, amount) + + TriggerClientEvent('esx:showNotification', sourceXPlayer.source, 'Vous avez confisqué ~y~x1 ' .. ESX.GetWeaponLabel(itemName) .. '~s~ à ~b~' .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', targetXPlayer.source, '~b~' .. targetXPlayer.name .. '~s~ vous a confisqué ~y~x1 ' .. ESX.GetWeaponLabel(itemName)) + + end + +end) + +RegisterServerEvent('esx_policejob:handcuff') +AddEventHandler('esx_policejob:handcuff', function(target) + TriggerClientEvent('esx_policejob:handcuff', target) +end) + +RegisterServerEvent('esx_policejob:putInVehicle') +AddEventHandler('esx_policejob:putInVehicle', function(target) + TriggerClientEvent('esx_policejob:putInVehicle', target) +end) + +ESX.RegisterServerCallback('esx_policejob:getOtherPlayerData', function(source, cb, target) + + local xPlayer = ESX.GetPlayerFromId(target) + + local data = { + name = GetPlayerName(source), + job = xPlayer.job, + inventory = xPlayer.inventory, + accounts = xPlayer.accounts, + weapons = xPlayer.loadout + } + + TriggerEvent('esx_status:getStatus', _source, 'drunk', function(status) + data.drunk = status:getPercent() + end) + + TriggerEvent('esx_license:getLicenses', _source, function(licenses) + data.licenses = licenses + end) + + cb(data) + +end) + +ESX.RegisterServerCallback('esx_policejob:getFineList', function(source, cb, category) + + MySQL.Async.fetchAll( + 'SELECT * FROM fine_types WHERE category = @category', + { + ['@category'] = category + }, + function(fines) + cb(fines) + end + ) + +end) + +ESX.RegisterServerCallback('esx_policejob:getVehicleInfos', function(source, cb, plate) + + MySQL.Async.fetchAll( + 'SELECT * FROM owned_vehicles', + {}, + function(result) + + local foundIdentifier = nil + + for i=1, #result, 1 do + + local vehicleData = json.decode(result[i].vehicle) + + if vehicleData.plate == plate then + foundIdentifier = result[i].owner + break + end + + end + + if foundIdentifier ~= nil then + + MySQL.Async.fetchAll( + 'SELECT * FROM users WHERE identifier = @identifier', + { + ['@identifier'] = foundIdentifier + }, + function(result) + + local infos = { + plate = plate, + owner = result[1].name + } + + cb(infos) + + end + ) + + else + + local infos = { + plate = plate + } + + cb(infos) + + end + + end + ) + +end) + +ESX.RegisterServerCallback('esx_policejob:getArmoryWeapons', function(source, cb) + + TriggerEvent('esx_datastore:getSharedDataStore', 'society_police', function(store) + + local weapons = store.get('weapons') + + if weapons == nil then + weapons = {} + end + + cb(weapons) + + end) + +end) + +ESX.RegisterServerCallback('esx_policejob:addArmoryWeapon', function(source, cb, weaponName) + + local xPlayer = ESX.GetPlayerFromId(source) + + xPlayer.removeWeapon(weaponName) + + TriggerEvent('esx_datastore:getSharedDataStore', 'society_police', function(store) + + local weapons = store.get('weapons') + + if weapons == nil then + weapons = {} + end + + local foundWeapon = false + + for i=1, #weapons, 1 do + if weapons[i].name == weaponName then + weapons[i].count = weapons[i].count + 1 + foundWeapon = true + end + end + + if not foundWeapon then + table.insert(weapons, { + name = weaponName, + count = 1 + }) + end + + store.set('weapons', weapons) + + cb() + + end) + +end) + +ESX.RegisterServerCallback('esx_policejob:removeArmoryWeapon', function(source, cb, weaponName) + + local xPlayer = ESX.GetPlayerFromId(source) + + xPlayer.addWeapon(weaponName, 1000) + + TriggerEvent('esx_datastore:getSharedDataStore', 'society_police', function(store) + + local weapons = store.get('weapons') + + if weapons == nil then + weapons = {} + end + + local foundWeapon = false + + for i=1, #weapons, 1 do + if weapons[i].name == weaponName then + weapons[i].count = (weapons[i].count > 0 and weapons[i].count - 1 or 0) + foundWeapon = true + end + end + + if not foundWeapon then + table.insert(weapons, { + name = weaponName, + count = 0 + }) + end + + store.set('weapons', weapons) + + cb() + + end) + +end) + + +ESX.RegisterServerCallback('esx_policejob:buy', function(source, cb, amount) + + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_police', function(account) + + if account.money >= amount then + account.removeMoney(amount) + cb(true) + else + cb(false) + end + + end) + +end) \ No newline at end of file From 816a498b05c637b28e7707eb66212f3526915055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 8 Aug 2017 20:17:40 +0200 Subject: [PATCH 0205/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0c536d16..8eca241e 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ FXServer ESX Police Job 1) CD in your resources/[esx] folder 2) Clone the repository ``` -git clone https://github.com/FXServer-ESX/fxserver-esx_taxijob esx_taxijob +git clone https://github.com/FXServer-ESX/fxserver-esx_policejob esx_policejob ``` 3) * Auto mode : Import esx_policejob_minimal.sql in your database * Player / Armory management : Import esx_policejob_full.sql in your database From a2ef3b0aa0383fdd05b69bbe50146062974d664a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 8 Aug 2017 21:35:51 +0200 Subject: [PATCH 0206/3224] Add usable items --- resources/[essential]/es_extended/client/functions.lua | 6 +++++- resources/[essential]/es_extended/server/main.lua | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 64323e53..7f3d273b 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -858,7 +858,7 @@ ESX.ShowInventory = function() local elements = {} if data.current.usable then - table.insert(elements, {label = 'Utiliser', action = 'use', type = data.current.type, value = data.current.value}) + table.insert(elements, {label = 'Utiliser', action = 'use', type = data.current.type, value = data.current.value}) end table.insert(elements, {label = 'Donner', action = 'give', type = data.current.type, value = data.current.value}) @@ -941,6 +941,10 @@ ESX.ShowInventory = function() end + elseif data.current.action == 'use' then + + TriggerServerEvent('esx:useItem', data.current.value) + elseif data.current.action == 'return' then ESX.UI.Menu.CloseAll() ESX.ShowInventory() diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index 9e617b1d..5f86cd94 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -490,6 +490,11 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) end) +RegisterServerEvent('esx:useItem') +AddEventHandler('esx:useItem', function(item) + ESX.UseItem(source, item) +end) + ESX.RegisterServerCallback('esx:getPlayerData', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) From a8e552f31964aa741c437d870c98dc29d65c02ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 00:02:15 +0200 Subject: [PATCH 0207/3224] Update esx_policejob_full.sql --- esx_policejob_full.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esx_policejob_full.sql b/esx_policejob_full.sql index 543a5801..e3e1254a 100644 --- a/esx_policejob_full.sql +++ b/esx_policejob_full.sql @@ -11,8 +11,8 @@ INSERT INTO `jobs` (name, label) VALUES ; INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES - ('police',0,'recrue','Recrue',20,'{\"tshirt_1\":57,\"torso_1\":55,\"arms\":0,\"pants_1\":35,\"glasses\":0,\"decals_2\":0,\"hair_color_2\":0,\"helmet_2\":0,\"hair_color_1\":5,\"face\":19,\"glasses_2\":1,\"torso_2\":0,\"shoes\":24,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"pants_2\":0,\"hair_2\":0,\"decals_1\":0,\"tshirt_2\":0,\"helmet_1\":8}','{\"tshirt_1\":34,\"torso_1\":48,\"shoes\":24,\"pants_1\":34,\"torso_2\":0,\"decals_2\":0,\"hair_color_2\":0,\"glasses\":0,\"helmet_2\":0,\"hair_2\":3,\"face\":21,\"decals_1\":0,\"glasses_2\":1,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"pants_2\":0,\"arms\":14,\"hair_color_1\":10,\"tshirt_2\":0,\"helmet_1\":57}'), + ('police',0,'recruit','Recrue',20,'{\"tshirt_1\":57,\"torso_1\":55,\"arms\":0,\"pants_1\":35,\"glasses\":0,\"decals_2\":0,\"hair_color_2\":0,\"helmet_2\":0,\"hair_color_1\":5,\"face\":19,\"glasses_2\":1,\"torso_2\":0,\"shoes\":24,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"pants_2\":0,\"hair_2\":0,\"decals_1\":0,\"tshirt_2\":0,\"helmet_1\":8}','{\"tshirt_1\":34,\"torso_1\":48,\"shoes\":24,\"pants_1\":34,\"torso_2\":0,\"decals_2\":0,\"hair_color_2\":0,\"glasses\":0,\"helmet_2\":0,\"hair_2\":3,\"face\":21,\"decals_1\":0,\"glasses_2\":1,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"pants_2\":0,\"arms\":14,\"hair_color_1\":10,\"tshirt_2\":0,\"helmet_1\":57}'), ('police',1,'sergeant','Sergent',40,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":1,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"arms\":0,\"decals_1\":8,\"torso_2\":0,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"hair_color_1\":5,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":14,\"pants_1\":34,\"pants_2\":0,\"decals_2\":1,\"hair_color_2\":0,\"shoes\":24,\"helmet_2\":0,\"hair_2\":3,\"decals_1\":7,\"torso_2\":0,\"face\":21,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"glasses_2\":1,\"hair_color_1\":10,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}'), ('police',2,'lieutenant','Lieutenant',65,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":2,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"glasses\":0,\"decals_1\":8,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"torso_2\":0,\"arms\":41,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"hair_2\":3,\"decals_2\":2,\"hair_color_2\":0,\"hair_color_1\":10,\"helmet_2\":0,\"face\":21,\"shoes\":24,\"torso_2\":0,\"glasses_2\":1,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"pants_2\":0,\"decals_1\":7,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}'), - ('police',3,'commandant','Commandant',80,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"arms\":41,\"torso_2\":0,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"decals_1\":8,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":21,\"helmet_2\":0,\"hair_2\":3,\"decals_1\":7,\"torso_2\":0,\"hair_color_1\":10,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"glasses_2\":1,\"shoes\":24,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}') + ('police',3,'boss','Commandant',80,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"arms\":41,\"torso_2\":0,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"decals_1\":8,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":21,\"helmet_2\":0,\"hair_2\":3,\"decals_1\":7,\"torso_2\":0,\"hair_color_1\":10,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"glasses_2\":1,\"shoes\":24,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}') ; From 2924875655019c51b5bab7d553b09b2b3c12e3d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 00:02:31 +0200 Subject: [PATCH 0208/3224] Update esx_policejob_minimal.sql --- esx_policejob_minimal.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esx_policejob_minimal.sql b/esx_policejob_minimal.sql index fca6635c..daf423d6 100644 --- a/esx_policejob_minimal.sql +++ b/esx_policejob_minimal.sql @@ -3,8 +3,8 @@ INSERT INTO `jobs` (name, label) VALUES ; INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES - ('police',0,'recrue','Recrue',20,'{\"tshirt_1\":57,\"torso_1\":55,\"arms\":0,\"pants_1\":35,\"glasses\":0,\"decals_2\":0,\"hair_color_2\":0,\"helmet_2\":0,\"hair_color_1\":5,\"face\":19,\"glasses_2\":1,\"torso_2\":0,\"shoes\":24,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"pants_2\":0,\"hair_2\":0,\"decals_1\":0,\"tshirt_2\":0,\"helmet_1\":8}','{\"tshirt_1\":34,\"torso_1\":48,\"shoes\":24,\"pants_1\":34,\"torso_2\":0,\"decals_2\":0,\"hair_color_2\":0,\"glasses\":0,\"helmet_2\":0,\"hair_2\":3,\"face\":21,\"decals_1\":0,\"glasses_2\":1,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"pants_2\":0,\"arms\":14,\"hair_color_1\":10,\"tshirt_2\":0,\"helmet_1\":57}'), + ('police',0,'recruit','Recrue',20,'{\"tshirt_1\":57,\"torso_1\":55,\"arms\":0,\"pants_1\":35,\"glasses\":0,\"decals_2\":0,\"hair_color_2\":0,\"helmet_2\":0,\"hair_color_1\":5,\"face\":19,\"glasses_2\":1,\"torso_2\":0,\"shoes\":24,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"pants_2\":0,\"hair_2\":0,\"decals_1\":0,\"tshirt_2\":0,\"helmet_1\":8}','{\"tshirt_1\":34,\"torso_1\":48,\"shoes\":24,\"pants_1\":34,\"torso_2\":0,\"decals_2\":0,\"hair_color_2\":0,\"glasses\":0,\"helmet_2\":0,\"hair_2\":3,\"face\":21,\"decals_1\":0,\"glasses_2\":1,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"pants_2\":0,\"arms\":14,\"hair_color_1\":10,\"tshirt_2\":0,\"helmet_1\":57}'), ('police',1,'sergeant','Sergent',40,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":1,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"arms\":0,\"decals_1\":8,\"torso_2\":0,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"hair_color_1\":5,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":14,\"pants_1\":34,\"pants_2\":0,\"decals_2\":1,\"hair_color_2\":0,\"shoes\":24,\"helmet_2\":0,\"hair_2\":3,\"decals_1\":7,\"torso_2\":0,\"face\":21,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"glasses_2\":1,\"hair_color_1\":10,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}'), ('police',2,'lieutenant','Lieutenant',65,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":2,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"glasses\":0,\"decals_1\":8,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"torso_2\":0,\"arms\":41,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"hair_2\":3,\"decals_2\":2,\"hair_color_2\":0,\"hair_color_1\":10,\"helmet_2\":0,\"face\":21,\"shoes\":24,\"torso_2\":0,\"glasses_2\":1,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"pants_2\":0,\"decals_1\":7,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}'), - ('police',3,'commandant','Commandant',80,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"arms\":41,\"torso_2\":0,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"decals_1\":8,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":21,\"helmet_2\":0,\"hair_2\":3,\"decals_1\":7,\"torso_2\":0,\"hair_color_1\":10,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"glasses_2\":1,\"shoes\":24,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}') + ('police',3,'boss','Commandant',80,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"arms\":41,\"torso_2\":0,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"decals_1\":8,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":21,\"helmet_2\":0,\"hair_2\":3,\"decals_1\":7,\"torso_2\":0,\"hair_color_1\":10,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"glasses_2\":1,\"shoes\":24,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}') ; From 046f9be25b8208595da30564d91cc4f218e45296 Mon Sep 17 00:00:00 2001 From: renaiku Date: Wed, 9 Aug 2017 00:29:59 +0200 Subject: [PATCH 0209/3224] Update SQL files --- esx_vehicleshop_full.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_vehicleshop_full.sql b/esx_vehicleshop_full.sql index ec68181a..4f683c03 100644 --- a/esx_vehicleshop_full.sql +++ b/esx_vehicleshop_full.sql @@ -1,6 +1,6 @@ USE `essentialmode`; -INSERT INTO `addon_account` VALUES (name, label, shared) +INSERT INTO `addon_account` (name, label, shared) VALUES ('society_cardealer','Concessionnaire',1) ; From de192f9601d5191d86900bba2c0d2b829613400d Mon Sep 17 00:00:00 2001 From: renaiku Date: Wed, 9 Aug 2017 00:39:41 +0200 Subject: [PATCH 0210/3224] Initial commit --- README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..69c5506c --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# fxserver-esx_joblisting \ No newline at end of file From b52e9a48d23e49c305ccac3095d087a1473b945f Mon Sep 17 00:00:00 2001 From: renaiku Date: Wed, 9 Aug 2017 00:42:51 +0200 Subject: [PATCH 0211/3224] Add files --- README.md | 3 +- __resource.lua | 9 +++ client/esx_joblisting_cl.lua | 115 +++++++++++++++++++++++++++++++++++ config.lua | 9 +++ server/esx_joblisting_sv.lua | 26 ++++++++ 5 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 __resource.lua create mode 100644 client/esx_joblisting_cl.lua create mode 100644 config.lua create mode 100644 server/esx_joblisting_sv.lua diff --git a/README.md b/README.md index 69c5506c..64d5b689 100644 --- a/README.md +++ b/README.md @@ -1 +1,2 @@ -# fxserver-esx_joblisting \ No newline at end of file +# fxserver-esx_joblisting +FR - Pôle Emploi \ No newline at end of file diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..7993f10f --- /dev/null +++ b/__resource.lua @@ -0,0 +1,9 @@ +server_scripts { + '@mysql-async/lib/MySQL.lua', + 'server/esx_joblisting_sv.lua' +} + +client_scripts { + 'config.lua', + 'client/esx_joblisting_cl.lua' +} \ No newline at end of file diff --git a/client/esx_joblisting_cl.lua b/client/esx_joblisting_cl.lua new file mode 100644 index 00000000..e782aa7e --- /dev/null +++ b/client/esx_joblisting_cl.lua @@ -0,0 +1,115 @@ +local Keys = { + ["ESC"] = 322, ["BACKSPACE"] = 177, ["E"] = 38, ["ENTER"] = 18, ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173 +} + +local menuIsShowed = false +local hasAlreadyEnteredMarker = false +local lastZone = nil +local isInJoblistingMarker = false + +ESX = nil + +Citizen.CreateThread(function() + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end +end) + +function ShowJobListingMenu(data) + ESX.TriggerServerCallback('esx_joblisting:getJobsList', function(data) + local elements = {} + for i = 1, #data, 1 do + table.insert( + elements, + {label = data[i].label, value = data[i].value} + ) + end + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'joblisting', + { + title = 'POLE EMPLOI', + elements = elements + }, + function(data, menu) + TriggerServerEvent('esx_joblisting:setJob', data.current.value) + ESX.ShowNotification('Vous avez un nouveau job !') + menu.close() + end, + function(data, menu) + menu.close() + end + ) + + end) +end + +AddEventHandler('esx_joblisting:hasExitedMarker', function(zone) + ESX.UI.Menu.CloseAll() +end) + +-- Display markers +Citizen.CreateThread(function() + while true do + Wait(0) + local coords = GetEntityCoords(GetPlayerPed(-1)) + for i=1, #Config.Zones, 1 do + if(GetDistanceBetweenCoords(coords, Config.Zones[i].x, Config.Zones[i].y, Config.Zones[i].z, true) < Config.DrawDistance) then + DrawMarker(Config.MarkerType, Config.Zones[i].x, Config.Zones[i].y, Config.Zones[i].z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.ZoneSize.x, Config.ZoneSize.y, Config.ZoneSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) + end + end + end +end) + +-- Activate menu when player is inside marker +Citizen.CreateThread(function() + while true do + Wait(0) + local coords = GetEntityCoords(GetPlayerPed(-1)) + isInJoblistingMarker = false + local currentZone = nil + for i=1, #Config.Zones, 1 do + if(GetDistanceBetweenCoords(coords, Config.Zones[i].x, Config.Zones[i].y, Config.Zones[i].z, true) < Config.ZoneSize.x / 2) then + isInJoblistingMarker = true + SetTextComponentFormat('STRING') + AddTextComponentString('Appuyez sur ~INPUT_PICKUP~ pour \naccéder au ~b~Pôle Emploi~s~.') + DisplayHelpTextFromStringLabel(0, 0, 1, -1) + end + end + if isInJoblistingMarker and not hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = true + end + if not isInJoblistingMarker and hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = false + TriggerEvent('esx_joblisting:hasExitedMarker') + end + end +end) + +-- Create blips +Citizen.CreateThread(function() + for i=1, #Config.Zones, 1 do + local blip = AddBlipForCoord(Config.Zones[i].x, Config.Zones[i].y, Config.Zones[i].z) + SetBlipSprite (blip, 407) + SetBlipDisplay(blip, 4) + SetBlipScale (blip, 1.2) + SetBlipColour (blip, 27) + SetBlipAsShortRange(blip, true) + BeginTextCommandSetBlipName("STRING") + AddTextComponentString("Pôle-Emploi") + EndTextCommandSetBlipName(blip) + end +end) + +-- Menu Controls +Citizen.CreateThread(function() + while true do + Wait(0) + if IsControlJustReleased(0, Keys['E']) and isInJoblistingMarker and not menuIsShowed then + ShowJobListingMenu() + end + end +end) \ No newline at end of file diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..876c8df9 --- /dev/null +++ b/config.lua @@ -0,0 +1,9 @@ +Config = {} +Config.DrawDistance = 100.0 +Config.ZoneSize = {x = 3.0, y = 3.0, z = 2.0} +Config.MarkerColor = {r = 100, g = 100, b = 204} +Config.MarkerType = 1 + +Config.Zones = { + {x = -265.036, y = -963.630, z = 30.223} +} diff --git a/server/esx_joblisting_sv.lua b/server/esx_joblisting_sv.lua new file mode 100644 index 00000000..79533e40 --- /dev/null +++ b/server/esx_joblisting_sv.lua @@ -0,0 +1,26 @@ +ESX = nil +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +ESX.RegisterServerCallback('esx_joblisting:getJobsList', function(source, cb) + MySQL.Async.fetchAll( + 'SELECT * FROM jobs', + {}, + function(result) + local data = {} + for i=1, #result, 1 do + table.insert(data, { + value = result[i].name, + label = result[i].label + }) + end + cb(data) + end + ) +end) + +RegisterServerEvent('esx_joblisting:setJob') +AddEventHandler('esx_joblisting:setJob', function(job) + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) + xPlayer.setJob(job, 0) +end) \ No newline at end of file From 3f1973348565e896eefe3db685674c31d723b8e2 Mon Sep 17 00:00:00 2001 From: ig0ne Date: Wed, 9 Aug 2017 00:45:48 +0200 Subject: [PATCH 0212/3224] Initial commit --- README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..06ba4b47 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# fxserver-esx_mecanojob \ No newline at end of file From 5150d2f3c81d7067cc8740b8b45593273eba7075 Mon Sep 17 00:00:00 2001 From: renaiku Date: Wed, 9 Aug 2017 00:56:59 +0200 Subject: [PATCH 0213/3224] Changing Csitoyen => Citoyen --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 618fd401..90b6f293 100644 --- a/client/main.lua +++ b/client/main.lua @@ -295,7 +295,7 @@ function OpenPoliceActionsMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'citizen_interaction', { - title = 'Interaction Csitoyen', + title = 'Interaction Citoyen', align = 'top-left', elements = { {label = 'Carte d\'identité', value = 'identity_card'}, From 26bc40f86b7f97492377a181312adde61bf3fa25 Mon Sep 17 00:00:00 2001 From: ig0ne Date: Wed, 9 Aug 2017 01:00:46 +0200 Subject: [PATCH 0214/3224] Add files via upload --- esx_mecanojob/__resource.lua | 11 + esx_mecanojob/client/main.lua | 863 ++++++++++++++++++++++++++++++++++ esx_mecanojob/config.lua | 42 ++ esx_mecanojob/server/main.lua | 268 +++++++++++ esx_mecanojob_full.sql | 26 + esx_mecanojob_minimal.sql | 22 + 6 files changed, 1232 insertions(+) create mode 100644 esx_mecanojob/__resource.lua create mode 100644 esx_mecanojob/client/main.lua create mode 100644 esx_mecanojob/config.lua create mode 100644 esx_mecanojob/server/main.lua create mode 100644 esx_mecanojob_full.sql create mode 100644 esx_mecanojob_minimal.sql diff --git a/esx_mecanojob/__resource.lua b/esx_mecanojob/__resource.lua new file mode 100644 index 00000000..6c475099 --- /dev/null +++ b/esx_mecanojob/__resource.lua @@ -0,0 +1,11 @@ +description 'ESX Mecano Job' + +client_scripts { + 'config.lua', + 'client/main.lua' +} + +server_scripts { + 'config.lua', + 'server/main.lua' +} \ No newline at end of file diff --git a/esx_mecanojob/client/main.lua b/esx_mecanojob/client/main.lua new file mode 100644 index 00000000..992fc71d --- /dev/null +++ b/esx_mecanojob/client/main.lua @@ -0,0 +1,863 @@ +ESX = nil +local PlayerData = {} +local GUI = {} +GUI.Time = 0 +local HasAlreadyEnteredMarker = false +local LastZone = nil +local CurrentAction = nil +local CurrentActionMsg = '' +local CurrentActionData = {} +local OnJob = false +local TargetCoords = nil + +Citizen.CreateThread(function() + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end +end) + +function OpenMecanoActionsMenu() + + local elements = { + {label = 'Sortir Véhicule', value = 'vehicle_list'}, + {label = 'Tenue de travail', value = 'cloakroom'}, + {label = 'Tenue civile', value = 'cloakroom2'} + } + if Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.grade_name == 'boss' then + table.insert(elements, {label = 'Retirer argent société', value = 'withdraw_society_money'}) + table.insert(elements, {label = 'Déposer argent ', value = 'deposit_money'}) + table.insert(elements, {label = 'Blanchir argent', value = 'wash_money'}) + end + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'mecano_actions', + { + title = 'Mecano', + elements = elements + }, + function(data, menu) + if data.current.value == 'vehicle_list' then + local elements = { + {label = 'Plateau', value = 'flatbed'}, + {label = 'Dépaneuse', value = 'towtruck2'} + } + + if Config.EnablePlayerManagement and PlayerData.job ~= nil and + (PlayerData.job.grade_name == 'boss' or PlayerData.job.grade_name == 'chef' or PlayerData.job.grade_name == 'experimente') then + table.insert(elements, {label = 'SlamVan', value = 'slamvan3'}) + end + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'spawn_vehicle', + { + title = 'Véhicule de service', + elements = elements + }, + function(data, menu) + for i=1, #elements, 1 do + if Config.MaxInService == -1 then + local playerPed = GetPlayerPed(-1) + local coords = Config.Zones.VehicleSpawnPoint.Pos + ESX.Game.SpawnVehicle(data.current.value, coords, 90.0, function(vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + end) + break + else + ESX.TriggerServerCallback('esx_service:enableService', function(canTakeService, maxInService, inServiceCount) + if canTakeService then + local playerPed = GetPlayerPed(-1) + local coords = Config.Zones.VehicleSpawnPoint.Pos + ESX.Game.SpawnVehicle(data.current.value, coords, 90.0, function(vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + end) + else + ESX.ShowNotification('Service complet : ' .. inServiceCount .. '/' .. maxInService) + end + end, 'mecano') + break + end + end + menu.close() + end, + function(data, menu) + menu.close() + OpenMecanoActionsMenu() + end + ) + end + + if data.current.value == 'cloakroom' then + menu.close() + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) + + if skin.sex == 0 then + TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_male) + else + TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_female) + end + + end) + end + + if data.current.value == 'cloakroom2' then + menu.close() + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) + + TriggerEvent('skinchanger:loadSkin', skin) + + end) + end + + if data.current.value == 'withdraw_society_money' then + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'withdraw_society_money_amount', + { + title = 'Montant du retrait' + }, + function(data, menu) + local amount = tonumber(data.value) + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + menu.close() + TriggerServerEvent('esx_society:withdrawMoney', 'mecano', amount) + end + end, + function(data, menu) + menu.close() + end + ) + end + + if data.current.value == 'deposit_money' then + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'deposit_money_amount', + { + title = 'Montant du dépôt' + }, + function(data, menu) + local amount = tonumber(data.value) + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + menu.close() + TriggerServerEvent('esx_society:depositMoney', 'mecano', amount) + end + end, + function(data, menu) + menu.close() + end + ) + end + + if data.current.value == 'wash_money' then + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'wash_money_amount', + { + title = 'Montant à blanchir' + }, + function(data, menu) + local amount = tonumber(data.value) + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + menu.close() + TriggerServerEvent('esx_society:washMoney', 'mecano', amount) + end + end, + function(data, menu) + menu.close() + end + ) + end + end, + function(data, menu) + menu.close() + CurrentAction = 'mecano_actions_menu' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au menu.' + CurrentActionData = {} + end + ) +end + +function OpenMecanoHarvestMenu() + + if Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.grade_name ~= 'recrue' then + local elements = { + {label = 'Bouteille de gaz', value = 'gaz_bottle'}, + {label = 'Outils réparation', value = 'fix_tool'}, + {label = 'Outils Carosserie', value = 'caro_tool'} + } + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'mecano_harvest', + { + title = 'Récolte', + elements = elements + }, + function(data, menu) + if data.current.value == 'gaz_bottle' then + menu.close() + TriggerServerEvent('esx_mecanojob:startHarvest') + end + + if data.current.value == 'fix_tool' then + menu.close() + TriggerServerEvent('esx_mecanojob:startHarvest2') + end + + if data.current.value == 'caro_tool' then + menu.close() + TriggerServerEvent('esx_mecanojob:startHarvest3') + end + + end, + function(data, menu) + menu.close() + CurrentAction = 'mecano_harvest_menu' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au menu de récolte.' + CurrentActionData = {} + end + ) + else + ESX.ShowNotification("Vous n'êtes ~r~pas assez expérimenté~s~ pour effectuer cette action.") + end +end + +function OpenMecanoCraftMenu() + if Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.grade_name ~= 'recrue' then + + local elements = { + {label = 'Chalumeaux', value = 'blow_pipe'}, + {label = 'Kit réparation', value = 'fix_kit'}, + {label = 'Outils Carosserie', value = 'caro_kit'} + } + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'mecano_craft', + { + title = 'Etabli', + elements = elements + }, + function(data, menu) + if data.current.value == 'blow_pipe' then + menu.close() + TriggerServerEvent('esx_mecanojob:startCraft') + end + + if data.current.value == 'fix_kit' then + menu.close() + TriggerServerEvent('esx_mecanojob:startCraft2') + end + + if data.current.value == 'caro_kit' then + menu.close() + TriggerServerEvent('esx_mecanojob:startCraft3') + end + + end, + function(data, menu) + menu.close() + CurrentAction = 'mecano_craft_menu' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au menu établi.' + CurrentActionData = {} + end + ) + else + ESX.ShowNotification("Vous n'êtes ~r~pas assez expérimenté~s~ pour effectuer cette action.") + end +end + +function OpenMobileMecanoActionsMenu() + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'mobile_mecano_actions', + { + title = 'Mécano', + elements = { + {label = 'Facuration', value = 'billing'}, + {label = 'Crocheter', value = 'hijack_vehicle'}, + {label = 'Réparer', value = 'fix_vehicle'}, + {label = 'Netoyer', value = 'clean_vehicle'}, + {label = 'Fourrière', value = 'del_vehicle'}, + {label = 'Plateau', value = 'dep_vehicle'}, + {label = 'Placer objets', value = 'object_spawner'} + } + }, + function(data, menu) + if data.current.value == 'billing' then + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'billing', + { + title = 'Montant de la facture' + }, + function(data, menu) + local amount = tonumber(data.value) + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + menu.close() + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification('Aucun joueur à proximité') + else + TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_mecano', 'Mecano', amount) + end + end + end, + function(data, menu) + menu.close() + end + ) + end + + if data.current.value == 'hijack_vehicle' then + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + + local vehicle = nil + + if IsPedInAnyVehicle(playerPed, false) then + vehicle = GetVehiclePedIsIn(playerPed, false) + else + vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) + end + + if DoesEntityExist(vehicle) then + TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_WELDING", 0, true) + Citizen.CreateThread(function() + Citizen.Wait(10000) + SetVehicleDoorsLocked(vehicle, 1) + SetVehicleDoorsLockedForAllPlayers(vehicle, false) + ClearPedTasksImmediately(playerPed) + TriggerEvent('esx:showNotification', 'Véhicule ~g~déverouillé') + end) + end + + end + + end + + if data.current.value == 'fix_vehicle' then + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + + local vehicle = nil + + if IsPedInAnyVehicle(playerPed, false) then + vehicle = GetVehiclePedIsIn(playerPed, false) + else + vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) + end + + if DoesEntityExist(vehicle) then + TaskStartScenarioInPlace(playerPed, "PROP_HUMAN_BUM_BIN", 0, true) + Citizen.CreateThread(function() + Citizen.Wait(20000) + SetVehicleFixed(vehicle) + SetVehicleDeformationFixed(vehicle) + SetVehicleUndriveable(vehicle, false) + ClearPedTasksImmediately(playerPed) + TriggerEvent('esx:showNotification', 'Véhicule ~g~réparé') + end) + end + end + end + + if data.current.value == 'clean_vehicle' then + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + + local vehicle = nil + + if IsPedInAnyVehicle(playerPed, false) then + vehicle = GetVehiclePedIsIn(playerPed, false) + else + vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) + end + + if DoesEntityExist(vehicle) then + TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_MAID_CLEAN", 0, true) + Citizen.CreateThread(function() + Citizen.Wait(10000) + SetVehicleDirtLevel(vehicle, 0) + ClearPedTasksImmediately(playerPed) + TriggerEvent('esx:showNotification', 'Véhicule ~g~néttoyé') + end) + end + end + end + + if data.current.value == 'del_vehicle' then + + local ped = GetPlayerPed( -1 ) + + if ( DoesEntityExist( ped ) and not IsEntityDead( ped ) ) then + local pos = GetEntityCoords( ped ) + + if ( IsPedSittingInAnyVehicle( ped ) ) then + local vehicle = GetVehiclePedIsIn( ped, false ) + + if ( GetPedInVehicleSeat( vehicle, -1 ) == ped ) then + TriggerEvent('esx:showNotification', 'Vehicule ~r~mis en fourrière') + SetEntityAsMissionEntity( vehicle, true, true ) + deleteCar( vehicle ) + else + TriggerEvent('esx:showNotification', 'Vous devez être assis du ~r~côté conducteur!') + end + else + local playerPos = GetEntityCoords( ped, 1 ) + local inFrontOfPlayer = GetOffsetFromEntityInWorldCoords( ped, 0.0, distanceToCheck, 0.0 ) + local vehicle = GetVehicleInDirection( playerPos, inFrontOfPlayer ) + + if ( DoesEntityExist( vehicle ) ) then + TriggerEvent('esx:showNotification', 'Vehicule ~r~mis en fourrière') + SetEntityAsMissionEntity( vehicle, true, true ) + deleteCar( vehicle ) + else + TriggerEvent('esx:showNotification', 'Vous devez être ~r~près d\'un véhicule~s~ pour le mettre en fourrière') + end + end + end + end + + if data.current.value == 'dep_vehicle' then + + local playerped = GetPlayerPed(-1) + local vehicle = GetVehiclePedIsIn(playerped, true) + + local towmodel = GetHashKey('flatbed') + local isVehicleTow = IsVehicleModel(vehicle, towmodel) + + if isVehicleTow then + + local coordA = GetEntityCoords(playerped, 1) + local coordB = GetOffsetFromEntityInWorldCoords(playerped, 0.0, 5.0, 0.0) + local targetVehicle = getVehicleInDirection(coordA, coordB) + + if currentlyTowedVehicle == nil then + if targetVehicle ~= 0 then + if not IsPedInAnyVehicle(playerped, true) then + if vehicle ~= targetVehicle then + AttachEntityToEntity(targetVehicle, vehicle, 20, -0.5, -5.0, 1.0, 0.0, 0.0, 0.0, false, false, false, false, 20, true) + currentlyTowedVehicle = targetVehicle + TriggerEvent('esx:showNotification', 'Vehicule ~b~attaché~s~ avec succès!') + else + TriggerEvent('esx:showNotification', '~r~Impossible~s~ d\'attacher votre propre dépanneuse') + end + end + else + TriggerEvent('esx:showNotification', 'Il n\'y a ~r~pas de véhicule~s~ à attacher') + end + else + AttachEntityToEntity(currentlyTowedVehicle, vehicle, 20, -0.5, -12.0, 1.0, 0.0, 0.0, 0.0, false, false, false, false, 20, true) + DetachEntity(currentlyTowedVehicle, true, true) + currentlyTowedVehicle = nil + TriggerEvent('esx:showNotification', 'Vehicule ~b~détattaché~s~ avec succès!') + end + else + TriggerEvent('esx:showNotification', '~r~Impossible! ~s~Vous devez avoir un ~b~Flatbed ~s~pour ça') + end + end + + if data.current.value == 'object_spawner' then + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'mobile_mecano_actions_spawn', + { + title = 'Objets', + align = 'top-left', + elements = { + {label = 'Plot', value = 'prop_roadcone02a'}, + {label = 'Boîte à outils', value = 'prop_toolchest_01'}, + }, + }, + function(data2, menu2) + + + local model = data2.current.value + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + local forward = GetEntityForwardVector(playerPed) + local x, y, z = table.unpack(coords + forward * 1.0) + + if model == 'prop_roadcone02a' then + z = z - 2.0 + elseif model == 'prop_toolchest_01' then + z = z - 3.0 + end + + ESX.Game.SpawnObject(model, { + x = x, + y = y, + z = z + }, 3.0, function(obj) + SetEntityHeading(obj, GetEntityHeading(playerPed)) + PlaceObjectOnGroundProperly(obj) + end) + + end, + function(data2, menu2) + menu2.close() + end + ) + + end + + end, + function(data, menu) + menu.close() + end + ) +end + +RegisterNetEvent('esx_mecanojob:onHijack') +AddEventHandler('esx_mecanojob:onHijack', function() + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + + local vehicle = nil + + if IsPedInAnyVehicle(playerPed, false) then + vehicle = GetVehiclePedIsIn(playerPed, false) + else + vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) + end + + local crochete = math.random(100) + local alarm = math.random(100) + + if DoesEntityExist(vehicle) then + if alarm <= 33 then + SetVehicleAlarm(vehicle, true) + StartVehicleAlarm(vehicle) + end + TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_WELDING", 0, true) + Citizen.CreateThread(function() + Citizen.Wait(10000) + if crochete <= 66 then + SetVehicleDoorsLocked(vehicle, 1) + SetVehicleDoorsLockedForAllPlayers(vehicle, false) + ClearPedTasksImmediately(playerPed) + TriggerEvent('esx:showNotification', '~g~Véhicule déverouillé') + else + TriggerEvent('esx:showNotification', '~r~Crochetage raté') + ClearPedTasksImmediately(playerPed) + end + end) + end + + end +end) + +RegisterNetEvent('esx_mecanojob:onCarokit') +AddEventHandler('esx_mecanojob:onCarokit', function() + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + + local vehicle = nil + + if IsPedInAnyVehicle(playerPed, false) then + vehicle = GetVehiclePedIsIn(playerPed, false) + else + vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) + end + + if DoesEntityExist(vehicle) then + TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_HAMMERING", 0, true) + Citizen.CreateThread(function() + Citizen.Wait(10000) + SetVehicleFixed(vehicle) + SetVehicleDeformationFixed(vehicle) + ClearPedTasksImmediately(playerPed) + TriggerEvent('esx:showNotification', '~g~Carosserie réparée') + end) + end + end +end) + +RegisterNetEvent('esx_mecanojob:onFixkit') +AddEventHandler('esx_mecanojob:onFixkit', function() + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + + local vehicle = nil + + if IsPedInAnyVehicle(playerPed, false) then + vehicle = GetVehiclePedIsIn(playerPed, false) + else + vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) + end + + if DoesEntityExist(vehicle) then + TaskStartScenarioInPlace(playerPed, "PROP_HUMAN_BUM_BIN", 0, true) + Citizen.CreateThread(function() + Citizen.Wait(20000) + SetVehicleFixed(vehicle) + SetVehicleDeformationFixed(vehicle) + SetVehicleUndriveable(vehicle, false) + ClearPedTasksImmediately(playerPed) + TriggerEvent('esx:showNotification', '~g~Véhicule réparé') + end) + end + end +end) + +function setEntityHeadingFromEntity ( vehicle, playerPed ) + local heading = GetEntityHeading(vehicle) + SetEntityHeading( playerPed, heading ) +end + +function getVehicleInDirection(coordFrom, coordTo) + local rayHandle = CastRayPointToPoint(coordFrom.x, coordFrom.y, coordFrom.z, coordTo.x, coordTo.y, coordTo.z, 10, GetPlayerPed(-1), 0) + local a, b, c, d, vehicle = GetRaycastResult(rayHandle) + return vehicle +end + +function deleteCar( entity ) + Citizen.InvokeNative( 0xEA386986E786A54F, Citizen.PointerValueIntInitialized( entity ) ) +end + +RegisterNetEvent('esx:playerLoaded') +AddEventHandler('esx:playerLoaded', function(xPlayer) + PlayerData = xPlayer +end) + +RegisterNetEvent('esx:setJob') +AddEventHandler('esx:setJob', function(job) + PlayerData.job = job +end) + +AddEventHandler('esx_mecanojob:hasEnteredMarker', function(zone) + if zone == 'MecanoActions' then + CurrentAction = 'mecano_actions_menu' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au menu.' + CurrentActionData = {} + end + if zone == 'Garage' then + CurrentAction = 'mecano_harvest_menu' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au menu de récolte.' + CurrentActionData = {} + end + if zone == 'Craft' then + CurrentAction = 'mecano_craft_menu' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au menu établi.' + CurrentActionData = {} + end + if zone == 'VehicleDeleter' then + local playerPed = GetPlayerPed(-1) + if IsPedInAnyVehicle(playerPed, false) then + CurrentAction = 'delete_vehicle' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour ranger le véhicule.' + CurrentActionData = {} + end + end +end) + +AddEventHandler('esx_mecanojob:hasExitedMarker', function(zone) + + if zone == 'Craft' then + TriggerServerEvent('esx_mecanojob:stopCraft') + TriggerServerEvent('esx_mecanojob:stopCraft2') + TriggerServerEvent('esx_mecanojob:stopCraft3') + end + + if zone == 'Garage' then + TriggerServerEvent('esx_mecanojob:stopHarvest') + TriggerServerEvent('esx_mecanojob:stopHarvest2') + TriggerServerEvent('esx_mecanojob:stopHarvest3') + end + + CurrentAction = nil + ESX.UI.Menu.CloseAll() +end) + +AddEventHandler('esx_mecanojob:hasEnteredEntityZone', function(entity) + + local playerPed = GetPlayerPed(-1) + + if PlayerData.job ~= nil and PlayerData.job.name == 'mecano' and not IsPedInAnyVehicle(playerPed, false) then + CurrentAction = 'remove_entity' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour enlever l\'objet' + CurrentActionData = {entity = entity} + end + +end) + +AddEventHandler('esx_mecanojob:hasExitedEntityZone', function(entity) + + if CurrentAction == 'remove_entity' then + CurrentAction = nil + end + +end) + +RegisterNetEvent('esx_phone:loaded') +AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) + local specialContact = { + name = 'Mecano', + number = 'mecano', + base64Icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAAA4BJREFUWIXtll9oU3cUx7/nJA02aSSlFouWMnXVB0ejU3wcRteHjv1puoc9rA978cUi2IqgRYWIZkMwrahUGfgkFMEZUdg6C+u21z1o3fbgqigVi7NzUtNcmsac40Npltz7S3rvUHzxQODec87vfD+/e0/O/QFv7Q0beV3QeXqmgV74/7H7fZJvuLwv8q/Xeux1gUrNBpN/nmtavdaqDqBK8VT2RDyV2VHmF1lvLERSBtCVynzYmcp+A9WqT9kcVKX4gHUehF0CEVY+1jYTTIwvt7YSIQnCTvsSUYz6gX5uDt7MP7KOKuQAgxmqQ+neUA+I1B1AiXi5X6ZAvKrabirmVYFwAMRT2RMg7F9SyKspvk73hfrtbkMPyIhA5FVqi0iBiEZMMQdAui/8E4GPv0oAJkpc6Q3+6goAAGpWBxNQmTLFmgL3jSJNgQdGv4pMts2EKm7ICJB/aG0xNdz74VEk13UYCx1/twPR8JjDT8wttyLZtkoAxSb8ZDCz0gdfKxWkFURf2v9qTYH7SK7rQIDn0P3nA0ehixvfwZwE0X9vBE/mW8piohhl1WH18UQBhYnre8N/L8b8xQvlx4ACbB4NnzaeRYDnKm0EALCMLXy84hwuTCXL/ExoB1E7qcK/8NCLIq5HcTT0i6u8TYbXUM1cAyyveVq8Xls7XhYrvY/4n3gC8C+dsmAzL1YUiyfWxvHzsy/w/dNd+KjhW2yvv/RfXr7x9QDcmo1he2RBiCCI1Q8jVj9szPNixVfgz+UiIGyDSrcoRu2J16d3I6e1VYvNSQjXpnucAcEPUOkGYZs/l4uUhowt/3kqu1UIv9n90fAY9jT3YBlbRvFTD4fw++wHjhiTRL/bG75t0jI2ITcHb5om4Xgmhv57xpGOg3d/NIqryOR7z+r+MC6qBJB/ZB2t9Om1D5lFm843G/3E3HI7Yh1xDRAfzLQr5EClBf/HBHK462TG2J0OABXeyWDPZ8VqxmBWYscpyghwtTd4EKpDTjCZdCNmzFM9k+4LHXIFACJN94Z6FiFEpKDQw9HndWsEuhnADVMhAUaYJBp9XrcGQKJ4qFE9k+6r2+MG3k5N8VQ22TVglbX2ZwOzX2VvNKr91zmY6S7N6zqZicVT2WNLyVSehESaBhxnOALfMeYX+K/S2yv7wmMAlvwyuR7FxQUyf0fgc/jztfkJr7XeGgC8BJJgWNV8ImT+AAAAAElFTkSuQmCC' + } + TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) +end) + +-- Create Blips +Citizen.CreateThread(function() + local blip = AddBlipForCoord(Config.Zones.MecanoActions.Pos.x, Config.Zones.MecanoActions.Pos.y, Config.Zones.MecanoActions.Pos.z) + SetBlipSprite (blip, 446) + SetBlipDisplay(blip, 4) + SetBlipScale (blip, 1.0) + SetBlipColour (blip, 5) + SetBlipAsShortRange(blip, true) + BeginTextCommandSetBlipName("STRING") + AddTextComponentString("Mecano") + EndTextCommandSetBlipName(blip) +end) + +-- Display markers +Citizen.CreateThread(function() + while true do + Wait(0) + if PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then + + local coords = GetEntityCoords(GetPlayerPed(-1)) + + for k,v in pairs(Config.Zones) do + if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) + end + end + end + end +end) + +-- Enter / Exit marker events +Citizen.CreateThread(function() + while true do + Wait(0) + if PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then + local coords = GetEntityCoords(GetPlayerPed(-1)) + local isInMarker = false + local currentZone = nil + for k,v in pairs(Config.Zones) do + if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then + isInMarker = true + currentZone = k + end + end + if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then + HasAlreadyEnteredMarker = true + LastZone = currentZone + TriggerEvent('esx_mecanojob:hasEnteredMarker', currentZone) + end + if not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent('esx_mecanojob:hasExitedMarker', LastZone) + end + end + end +end) + +Citizen.CreateThread(function() + while true do + + Citizen.Wait(0) + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + local entity, distance = ESX.Game.GetClosestObject({ + 'prop_roadcone02a', + 'prop_toolchest_01' + }) + + if distance ~= -1 and distance <= 3.0 then + + if LastEntity ~= entity then + TriggerEvent('esx_mecanojob:hasEnteredEntityZone', entity) + LastEntity = entity + end + + else + + if LastEntity ~= nil then + TriggerEvent('esx_mecanojob:hasExitedEntityZone', LastEntity) + LastEntity = nil + end + + end + + end +end) + + +-- Key Controls +Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + if CurrentAction ~= nil then + SetTextComponentFormat('STRING') + AddTextComponentString(CurrentActionMsg) + DisplayHelpTextFromStringLabel(0, 0, 1, -1) + if IsControlJustReleased(0, 38) and PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then + if CurrentAction == 'mecano_actions_menu' then + OpenMecanoActionsMenu() + end + if CurrentAction == 'mecano_harvest_menu' then + OpenMecanoHarvestMenu() + end + if CurrentAction == 'mecano_craft_menu' then + OpenMecanoCraftMenu() + end + if CurrentAction == 'delete_vehicle' then + local playerPed = GetPlayerPed(-1) + local vehicle = GetVehiclePedIsIn(playerPed, false) + local hash = GetEntityModel(vehicle) + if hash == GetHashKey('flatbed') or hash == GetHashKey('towtruck2') or hash == GetHashKey('slamvan3') then + if Config.MaxInService ~= -1 then + TriggerServerEvent('esx_service:disableService', 'mecano') + end + DeleteVehicle(vehicle) + else + ESX.ShowNotification('Vous ne pouvez ranger que des ~b~véhicules de Mécano~s~.') + end + end + if CurrentAction == 'remove_entity' then + DeleteEntity(CurrentActionData.entity) + end + CurrentAction = nil + end + end + + if IsControlJustReleased(0, 167) and PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then + OpenMobileMecanoActionsMenu() + end + end +end) \ No newline at end of file diff --git a/esx_mecanojob/config.lua b/esx_mecanojob/config.lua new file mode 100644 index 00000000..b413d582 --- /dev/null +++ b/esx_mecanojob/config.lua @@ -0,0 +1,42 @@ +Config = {} +Config.DrawDistance = 100.0 +Config.MaxInService = -1 +Config.EnablePlayerManagement = true + +Config.Zones = { + + MecanoActions = { + Pos = {x = -205.90548706055, y = -1327.7248535156, z = 29.89040184021}, + Size = {x = 1.5, y = 1.5, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Type = 1 + }, + + Garage = { + Pos = {x = -97.5797576904297, y = 6496.11376953125, z = 30.4909038543701}, + Size = {x = 1.5, y = 1.5, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Type = 1 + }, + + Craft = { + Pos = {x = -196.51593017578, y = -1318.4403076172, z = 30.089345932007}, + Size = {x = 1.5, y = 1.5, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Type = 1 + }, + + VehicleSpawnPoint = { + Pos = {x = -157.7899017334, y = -1305.8979492188, z = 30.348382949829}, + Size = {x = 1.5, y = 1.5, z = 1.0}, + Type = -1 + }, + + VehicleDeleter = { + Pos = {x = -182.78112792969, y = -1330.5368652344, z = 30.194892883301}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Type = 1 + } + +} diff --git a/esx_mecanojob/server/main.lua b/esx_mecanojob/server/main.lua new file mode 100644 index 00000000..fb6a325a --- /dev/null +++ b/esx_mecanojob/server/main.lua @@ -0,0 +1,268 @@ +ESX = nil +PlayersHarvesting = {} +PlayersHarvesting2 = {} +PlayersHarvesting3 = {} +PlayersCrafting = {} +PlayersCrafting2 = {} +PlayersCrafting3 = {} + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +if Config.MaxInService ~= -1 then + TriggerEvent('esx_service:activateService', 'mecano', Config.MaxInService) +end + +TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) + local xPlayers = ESX.GetPlayers() + + if phoneNumber == 'mecano' then + for k, v in pairs(xPlayers) do + if v.job.name == 'mecano' then + TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'Appel Mécano') + end + end + end +end) +-------------- Récupération bouteille de gaz ------------- +---- Sqlut je teste ------ +local function Harvest(source) + + SetTimeout(4000, function() + + if PlayersHarvesting[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + local GazBottleQuantity = xPlayer.getInventoryItem('gazbottle').count + + if GazBottleQuantity >= 5 then + TriggerClientEvent('esx:showNotification', source, '~r~Vous n\'avez plus de place') + else + xPlayer.addInventoryItem('gazbottle', 1) + + Harvest(source) + end + end + end) +end + +RegisterServerEvent('esx_mecanojob:startHarvest') +AddEventHandler('esx_mecanojob:startHarvest', function() + local _source = source + PlayersHarvesting[_source] = true + TriggerClientEvent('esx:showNotification', _source, 'Récupération de ~b~bouteille de gaz~s~...') + Harvest(source) +end) + +RegisterServerEvent('esx_mecanojob:stopHarvest') +AddEventHandler('esx_mecanojob:stopHarvest', function() + local _source = source + PlayersHarvesting[_source] = false +end) +------------ Récupération Outils Réparation -------------- +local function Harvest2(source) + + SetTimeout(4000, function() + + if PlayersHarvesting2[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + local FixToolQuantity = xPlayer.getInventoryItem('fixtool').count + if FixToolQuantity >= 5 then + TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez ~r~plus de place') + else + xPlayer.addInventoryItem('fixtool', 1) + + Harvest2(source) + end + end + end) +end + +RegisterServerEvent('esx_mecanojob:startHarvest2') +AddEventHandler('esx_mecanojob:startHarvest2', function() + local _source = source + PlayersHarvesting2[_source] = true + TriggerClientEvent('esx:showNotification', _source, 'Récupération d\'~b~Outils réparation~s~...') + Harvest2(_source) +end) + +RegisterServerEvent('esx_mecanojob:stopHarvest2') +AddEventHandler('esx_mecanojob:stopHarvest2', function() + local _source = source + PlayersHarvesting2[_source] = false +end) +----------------- Récupération Outils Carosserie ---------------- +local function Harvest3(source) + + SetTimeout(4000, function() + + if PlayersHarvesting3[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + local CaroToolQuantity = xPlayer.getInventoryItem('carotool').count + if CaroToolQuantity >= 5 then + TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez ~r~plus de place') + else + xPlayer.addInventoryItem('carotool', 1) + + Harvest3(source) + end + end + end) +end + +RegisterServerEvent('esx_mecanojob:startHarvest3') +AddEventHandler('esx_mecanojob:startHarvest3', function() + local _source = source + PlayersHarvesting3[_source] = true + TriggerClientEvent('esx:showNotification', _source, 'Récupération d\'~b~Outils carosserie~s~...') + Harvest3(_source) +end) + +RegisterServerEvent('esx_mecanojob:stopHarvest3') +AddEventHandler('esx_mecanojob:stopHarvest3', function() + local _source = source + PlayersHarvesting3[_source] = false +end) +------------ Craft Chalumeau ------------------- +local function Craft(source) + + SetTimeout(4000, function() + + if PlayersCrafting[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + local GazBottleQuantity = xPlayer.getInventoryItem('gazbottle').count + + if GazBottleQuantity <= 0 then + TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez ~r~pas assez~s~ de bouteille de gaz') + else + xPlayer.removeInventoryItem('gazbottle', 1) + xPlayer.addInventoryItem('blowpipe', 1) + + Craft(source) + end + end + end) +end + +RegisterServerEvent('esx_mecanojob:startCraft') +AddEventHandler('esx_mecanojob:startCraft', function() + local _source = source + PlayersCrafting[_source] = true + TriggerClientEvent('esx:showNotification', _source, 'Assemblage de ~b~Chalumeaux~s~...') + Craft(_source) +end) + +RegisterServerEvent('esx_mecanojob:stopCraft') +AddEventHandler('esx_mecanojob:stopCraft', function() + local _source = source + PlayersCrafting[_source] = false +end) +------------ Craft kit Réparation -------------- +local function Craft2(source) + + SetTimeout(4000, function() + + if PlayersCrafting2[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + local FixToolQuantity = xPlayer.getInventoryItem('fixtool').count + if FixToolQuantity <= 0 then + TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez ~r~pas assez~s~ d\'outils réparation') + else + xPlayer.removeInventoryItem('fixtool', 1) + xPlayer.addInventoryItem('fixkit', 1) + + Craft2(source) + end + end + end) +end + +RegisterServerEvent('esx_mecanojob:startCraft2') +AddEventHandler('esx_mecanojob:startCraft2', function() + local _source = source + PlayersCrafting2[_source] = true + TriggerClientEvent('esx:showNotification', _source, 'Assemblage de ~b~Kit réparation~s~...') + Craft2(_source) +end) + +RegisterServerEvent('esx_mecanojob:stopCraft2') +AddEventHandler('esx_mecanojob:stopCraft2', function() + local _source = source + PlayersCrafting2[_source] = false +end) +----------------- Craft kit Carosserie ---------------- +local function Craft3(source) + + SetTimeout(4000, function() + + if PlayersCrafting3[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + local CaroToolQuantity = xPlayer.getInventoryItem('carotool').count + if CaroToolQuantity <= 0 then + TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez ~r~pas assez~s~ d\'outils carosserie') + else + xPlayer.removeInventoryItem('carotool', 1) + xPlayer.addInventoryItem('carokit', 1) + + Craft3(source) + end + end + end) +end + +RegisterServerEvent('esx_mecanojob:startCraft3') +AddEventHandler('esx_mecanojob:startCraft3', function() + local _source = source + PlayersCrafting3[_source] = true + TriggerClientEvent('esx:showNotification', _source, 'Assemblage de ~b~kit carosserie~s~...') + Craft3(_source) +end) + +RegisterServerEvent('esx_mecanojob:stopCraft3') +AddEventHandler('esx_mecanojob:stopCraft3', function() + local _source = source + PlayersCrafting3[_source] = false +end) + +---------------------------- register usable item -------------------------------------------------- +ESX.RegisterUsableItem('blowpipe', function(source) + + local _source = source + local xPlayer = ESX.GetPlayerFromId(source) + + xPlayer.removeInventoryItem('blowpipe', 1) + + TriggerClientEvent('esx_mecanojob:onHijack', _source) + TriggerClientEvent('esx:showNotification', _source, 'Vous avez utilisé un ~b~Chalumeau') + +end) + +ESX.RegisterUsableItem('fixkit', function(source) + + local _source = source + local xPlayer = ESX.GetPlayerFromId(source) + + xPlayer.removeInventoryItem('fixkit', 1) + + TriggerClientEvent('esx_mecanojob:onFixkit', _source) + TriggerClientEvent('esx:showNotification', _source, 'Vous avez utilisé un ~b~Kit de réparation') + +end) + +ESX.RegisterUsableItem('carokit', function(source) + + local _source = source + local xPlayer = ESX.GetPlayerFromId(source) + + xPlayer.removeInventoryItem('carokit', 1) + + TriggerClientEvent('esx_mecanojob:onCarokit', _source) + TriggerClientEvent('esx:showNotification', _source, 'Vous avez utilisé un ~b~Kit de carosserie') + +end) \ No newline at end of file diff --git a/esx_mecanojob_full.sql b/esx_mecanojob_full.sql new file mode 100644 index 00000000..367ca698 --- /dev/null +++ b/esx_mecanojob_full.sql @@ -0,0 +1,26 @@ +USE `essentialmode`; + +INSERT INTO `addon_account` (name, label, shared) VALUES + ('society_mecano','Mécano',1) +; + +INSERT INTO `jobs` (name, label) VALUES + ('mecano','Mécano') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('mecano',0,'recrue','Recrue',12,'{}','{}'), + ('mecano',1,'novice','Novice',24,'{}','{}'), + ('mecano',2,'experimente','Experimente',36,'{}','{}'), + ('mecano',3,'chief','Chef d\'équipe',48,'{}','{}'), + ('mecano',4,'boss','Patron',0,'{}','{}') +; + +INSERT INTO `items` (name, label) VALUES + ('gazbottle', 'bouteille de gaz'), + ('fixtool', 'outils réparation'), + ('carotool', 'outils carosserie'), + ('blowpipe', 'Chalumeaux'), + ('fixkit', 'Kit réparation'), + ('carokit', 'Kit carosserie') +; \ No newline at end of file diff --git a/esx_mecanojob_minimal.sql b/esx_mecanojob_minimal.sql new file mode 100644 index 00000000..48dd963e --- /dev/null +++ b/esx_mecanojob_minimal.sql @@ -0,0 +1,22 @@ +USE `essentialmode`; + +INSERT INTO `jobs` (name, label) VALUES + ('mecano','Mécano') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('mecano',0,'recrue','Recrue',12,'{}','{}'), + ('mecano',1,'novice','Novice',24,'{}','{}'), + ('mecano',2,'experimente','Experimente',36,'{}','{}'), + ('mecano',3,'chief','Chef d\'équipe',48,'{}','{}'), + ('mecano',4,'boss','Patron',0,'{}','{}') +; + +INSERT INTO `items` (name, label) VALUES + ('gazbottle', 'bouteille de gaz'), + ('fixtool', 'outils réparation'), + ('carotool', 'outils carosserie'), + ('blowpipe', 'Chalumeaux'), + ('fixkit', 'Kit réparation'), + ('carokit', 'Kit carosserie') +; \ No newline at end of file From cd0635ab728a9036b1066b3798069b66ba88c184 Mon Sep 17 00:00:00 2001 From: renaiku Date: Wed, 9 Aug 2017 01:03:36 +0200 Subject: [PATCH 0215/3224] =?UTF-8?q?Renamming=20interactions=20menu=20(Cs?= =?UTF-8?q?itoyen=20=3D>=20v=C3=A9hicule=20&=20voirie)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/main.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index 90b6f293..f325c23a 100644 --- a/client/main.lua +++ b/client/main.lua @@ -348,7 +348,7 @@ function OpenPoliceActionsMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'vehicle_interaction', { - title = 'Interaction Csitoyen', + title = 'Interaction véhicule', align = 'top-left', elements = { {label = 'Infos véhicule', value = 'vehicle_infos'}, @@ -420,7 +420,7 @@ function OpenPoliceActionsMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'citizen_interaction', { - title = 'Interaction Csitoyen', + title = 'Interaction voirie', align = 'top-left', elements = { {label = 'Plot', value = 'prop_roadcone02a'}, From dcdfc2b9c9bac5213ac74246c1cb0a660ceaf805 Mon Sep 17 00:00:00 2001 From: ig0ne Date: Wed, 9 Aug 2017 01:04:08 +0200 Subject: [PATCH 0216/3224] Update README.md --- README.md | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 06ba4b47..0b8b09eb 100644 --- a/README.md +++ b/README.md @@ -1 +1,33 @@ -# fxserver-esx_mecanojob \ No newline at end of file +# fxserver-esx_mecanojob + +FXServer ESX Mecano Job + +[REQUIREMENTS] + +* Auto mode + * No need to download another resource + +* Player management (billing and boss actions) + * esx_society => https://github.com/FXServer-ESX/fxserver-esx_society + * esx_billing => https://github.com/FXServer-ESX/fxserver-esx_billing + +[INSTALLATION] + +1) CD in your resources/[esx] folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-esx_mecanojob esx_mecanojob +``` +3) * Auto mode : Import esx_mecanojob_minimal.sql in your database + * Player management : Import esx_mecanojob_full.sql in your database + +4) Add this in your server.cfg : + +``` +start esx_mecanojob +``` +5) If you want player management you have to set Config.EnablePlayerManagement to true in config.lua + +[KNOWN BUGS] + +* Props spawn don't work at all From 27146a2497645ff6adbc750bf8dc7483baa781a1 Mon Sep 17 00:00:00 2001 From: Aleweadan Date: Wed, 9 Aug 2017 01:42:56 +0200 Subject: [PATCH 0217/3224] Fix sql --- esx_phone.sql | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/esx_phone.sql b/esx_phone.sql index 0517238e..62842ccc 100644 --- a/esx_phone.sql +++ b/esx_phone.sql @@ -1,11 +1,13 @@ -CREATE TABLE `user_contacts` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `identifier` varchar(255) NOT NULL, - `name` varchar(255) NOT NULL, - `number` int(11) NOT NULL +CREATE TABLE user_contacts ( + id int(11) NOT NULL AUTO_INCREMENT, + identifier varchar(255) NOT NULL, + name varchar(255) NOT NULL, + number int(11) NOT NULL, + PRIMARY KEY (id) ); -ALTER TABLE `user_contacts` ADD PRIMARY KEY (`id`); - +ALTER TABLE `users` +ADD COLUMN `phone_number` INT NULL; + ALTER TABLE `users` ADD COLUMN `phone_number` INT NULL; From 3e38cb6f131d3e52284d4592414316b3caf5ecb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 09:55:59 +0200 Subject: [PATCH 0218/3224] DB fix + Remove unemployed --- jobs.sql | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/jobs.sql b/jobs.sql index 3f846ee6..df3eabf2 100644 --- a/jobs.sql +++ b/jobs.sql @@ -1,9 +1,9 @@ -INSERT INTO `jobs` (`name`, `label`) VALUES -('unemployed', 'Chômeur'), -('slaughterer', 'Abatteur'), -('fisherman', 'Pêcheur'), -('miner', 'Mineur'), -('lumberjack', 'Bûcheron'), -('fuel', 'Raffineur'), -('reporter', 'Journaliste'), -('textil', 'Couturier'), \ No newline at end of file +INSERT INTO `jobs` (name, label) VALUES + ('slaughterer', 'Abatteur'), + ('fisherman', 'Pêcheur'), + ('miner', 'Mineur'), + ('lumberjack', 'Bûcheron'), + ('fuel', 'Raffineur'), + ('reporter', 'Journaliste'), + ('textil', 'Couturier') +; From 49423c397bf434f53c414b5b17344572c4e180c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 09:56:48 +0200 Subject: [PATCH 0219/3224] DB Fix + Remove unemployed --- job_grades.sql | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/job_grades.sql b/job_grades.sql index 687b543b..2dd407ef 100644 --- a/job_grades.sql +++ b/job_grades.sql @@ -1,9 +1,9 @@ -INSERT INTO `job_grades` (`job_name`, `grade`, `name`, `label`, `salary`, `skin_male`, `skin_female`) VALUES -('unemployed', 0, 'rsa', 'RSA', 0, '{}', '{}'), -('lumberjack', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), -('fisherman', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), -('fuel', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), -('reporter', 0, 'employee', 'Intérimaire', 0, '{}', '{}'), -('textil', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), -('miner', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), -('slaughterer', 0, 'interim', 'Intérimaire', 0, , '{}', '{}'); \ No newline at end of file +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('lumberjack', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), + ('fisherman', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), + ('fuel', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), + ('reporter', 0, 'employee', 'Intérimaire', 0, '{}', '{}'), + ('textil', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), + ('miner', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), + ('slaughterer', 0, 'interim', 'Intérimaire', 0, '{}', '{}') +; From 455fe5cb6cb0dab8aec168f92b55074f1a6504ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 09:59:31 +0200 Subject: [PATCH 0220/3224] Fix xPlayer is nil --- server/main.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/main.lua b/server/main.lua index 5681607a..0a8d6403 100644 --- a/server/main.lua +++ b/server/main.lua @@ -181,6 +181,7 @@ end) RegisterServerEvent('esx_phone:addPlayerContact') AddEventHandler('esx_phone:addPlayerContact', function(phoneNumber, contactName) + local xPlayer = ESX.GetPlayerFromId(source) local xPlayers = ESX.GetPlayers() local foundNumber = false local foundPlayer = nil @@ -197,8 +198,6 @@ AddEventHandler('esx_phone:addPlayerContact', function(phoneNumber, contactName) end if foundNumber then - - local xPlayer = ESX.GetPlayerFromId(source) if phoneNumber == xPlayer.get('phoneNumber') then TriggerClientEvent('esx:showNotification', _source, 'Vous ne pouvez pas vous ajouter vous-même') From 6d6682a3248c8e27f79bda78ef981f72f59401a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 10:04:00 +0200 Subject: [PATCH 0221/3224] Add _source --- server/main.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 0a8d6403..d2986cc7 100644 --- a/server/main.lua +++ b/server/main.lua @@ -181,7 +181,8 @@ end) RegisterServerEvent('esx_phone:addPlayerContact') AddEventHandler('esx_phone:addPlayerContact', function(phoneNumber, contactName) - local xPlayer = ESX.GetPlayerFromId(source) + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) local xPlayers = ESX.GetPlayers() local foundNumber = false local foundPlayer = nil From b0ab7183a89115fea37b5936ed071ab20e57273f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 10:35:06 +0200 Subject: [PATCH 0222/3224] Fix source --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index d2986cc7..f6764d03 100644 --- a/server/main.lua +++ b/server/main.lua @@ -245,7 +245,7 @@ AddEventHandler('esx_phone:addPlayerContact', function(phoneNumber, contactName) end end - TriggerClientEvent('esx_phone:addContact', source, contactName, phoneNumber, isOnline) + TriggerClientEvent('esx_phone:addContact', _source, contactName, phoneNumber, isOnline) end ) From 1911495a4ebc4130860f222009ab38a46be69eb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:08:05 +0200 Subject: [PATCH 0223/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From 92b67862b9090828148fc6bec7ebedf1b5a312b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:08:30 +0200 Subject: [PATCH 0224/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From 9106a7db2b97d8d5bc73274dcb0d2ab9e58c0702 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:08:56 +0200 Subject: [PATCH 0225/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From 4d6cbb1fcd2b363a9e2956b8c4613a8303ea39c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:09:24 +0200 Subject: [PATCH 0226/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From 3ad30b0ef3da11922f40f485e1a60f1084bd2776 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:09:46 +0200 Subject: [PATCH 0227/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From 7f1a14be3dd9e7ed1d4022eb830f20f26a1306dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:10:08 +0200 Subject: [PATCH 0228/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From 44c043f11f62b2abdaa4209355dd33c9dc1e5659 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:10:27 +0200 Subject: [PATCH 0229/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From 837cb327789de64e5d33e75b33dc2d9b8073bc74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:11:06 +0200 Subject: [PATCH 0230/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From 109034e5762853b91c69a55b5607d47a1c4f2c48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:11:27 +0200 Subject: [PATCH 0231/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From 1a24c0e82bcbc663592e1cdd42c09a42e351bbbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:11:46 +0200 Subject: [PATCH 0232/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From 4d205600941ccd321de473f3e3b87933978e05fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:12:06 +0200 Subject: [PATCH 0233/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From 6c429f98d9b51dc0ef21a0de33c74f237969c63a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:12:26 +0200 Subject: [PATCH 0234/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From 41029caed19c7b9f27e90e0eac21ffe8ccd0d261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:12:44 +0200 Subject: [PATCH 0235/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From 4fb7e68837c497136bbf85e0d18b86b8f0b93aff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:13:02 +0200 Subject: [PATCH 0236/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From 934f2d4e74fb121017fbd8e5a100a35c9e4b52ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:13:20 +0200 Subject: [PATCH 0237/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From 816d01a80fd8b80e39a0d1dce41807ca295a2690 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:13:38 +0200 Subject: [PATCH 0238/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From d798033971a261d99934434e4f0bbff78443ee5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:14:06 +0200 Subject: [PATCH 0239/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From e1d2884d55e8c0aca5e562ff9c1b089eb26768d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:14:23 +0200 Subject: [PATCH 0240/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From f2bdb9320ae990d9d76868805626e7a656bd9e54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:14:40 +0200 Subject: [PATCH 0241/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From 53188ccb932c7ccc377e9bab7b5c4e1fbaa63f97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:14:55 +0200 Subject: [PATCH 0242/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From 33bad99d799881fecdebf6f8f02f20344173193b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:15:16 +0200 Subject: [PATCH 0243/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From dd5f4f64ab0ce9a9d3833df1b62461f0886a8e23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:15:33 +0200 Subject: [PATCH 0244/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From d258d1c5b96402d32aac8729fd185b4ac7f32694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:15:52 +0200 Subject: [PATCH 0245/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From 9dc89f4565c148742ea8e2835435c93b967fd210 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:16:11 +0200 Subject: [PATCH 0246/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From c5dcbc5cc78bd770507f89be0146ec39fd9277c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:16:28 +0200 Subject: [PATCH 0247/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From 9885e5dcb3538122df6ec02fca9391985ae8ab2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:16:44 +0200 Subject: [PATCH 0248/3224] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file From 949e69bbb4aa52eee5d321a24a098ba900607e3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:24:13 +0200 Subject: [PATCH 0249/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9e133a9b..baf78590 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ local skin = { } -- Load freemode model -TriggerEvent('skinchanger:LoadDefaultModel', isMale) +TriggerEvent('skinchanger:loadDefaultModel', isMale) -- Load skin TriggerEvent('skinchanger:loadSkin', skin) From c4d820e351c87bc088df2a74a252f332f9868481 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 15:38:14 +0200 Subject: [PATCH 0250/3224] Everything in one SQL file + fix caution account not added to database --- esx_jobs.sql | 47 +++++++++++++++++++++++++++++++++++++++++++++++ items.sql | 20 -------------------- job_grades.sql | 9 --------- jobs.sql | 9 --------- 4 files changed, 47 insertions(+), 38 deletions(-) create mode 100644 esx_jobs.sql delete mode 100644 items.sql delete mode 100644 job_grades.sql delete mode 100644 jobs.sql diff --git a/esx_jobs.sql b/esx_jobs.sql new file mode 100644 index 00000000..32633b41 --- /dev/null +++ b/esx_jobs.sql @@ -0,0 +1,47 @@ +USE `essentialmode`; + +INSERT INTO `addon_account` (name, label, shared) VALUES + ('caution','Caution',1) +; + +INSERT INTO `jobs` (name, label) VALUES + ('slaughterer', 'Abatteur'), + ('fisherman', 'Pêcheur'), + ('miner', 'Mineur'), + ('lumberjack', 'Bûcheron'), + ('fuel', 'Raffineur'), + ('reporter', 'Journaliste'), + ('textil', 'Couturier') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('lumberjack', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), + ('fisherman', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), + ('fuel', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), + ('reporter', 0, 'employee', 'Intérimaire', 0, '{}', '{}'), + ('textil', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), + ('miner', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), + ('slaughterer', 0, 'interim', 'Intérimaire', 0, '{}', '{}') +; + +INSERT INTO `items` (`name`, `label`) VALUES + ('alive_chicken', 'Poulet vivant'), + ('slaughtered_chicken', 'Poulet abattu'), + ('packaged_chicken', 'Poulet en barquette'), + ('fish', 'Poisson'), + ('stone', 'Pierre'), + ('washed_stone', 'Pierre Lavée'), + ('copper', 'Cuivre'), + ('iron', 'Fer'), + ('gold', 'Or'), + ('diamond', 'Diamant'), + ('wood', 'Bois'), + ('cutted_wood', 'Bois coupé'), + ('packaged_plank', 'Paquet de planches'), + ('petrol', 'Pétrole'), + ('petrol_raffin', 'Pétrole Raffiné'), + ('essence', 'Essence'), + ('whool', 'Laine'), + ('fabric', 'Tissu'), + ('clothe', 'Vêtement') +; \ No newline at end of file diff --git a/items.sql b/items.sql deleted file mode 100644 index 8cd41514..00000000 --- a/items.sql +++ /dev/null @@ -1,20 +0,0 @@ -INSERT INTO `items` (`name`, `label`) VALUES -('alive_chicken', 'Poulet vivant'), -('slaughtered_chicken', 'Poulet abattu'), -('packaged_chicken', 'Poulet en barquette'), -('fish', 'Poisson'), -('stone', 'Pierre'), -('washed_stone', 'Pierre Lavée'), -('copper', 'Cuivre'), -('iron', 'Fer'), -('gold', 'Or'), -('diamond', 'Diamant'), -('wood', 'Bois'), -('cutted_wood', 'Bois coupé'), -('packaged_plank', 'Paquet de planches'), -('petrol', 'Pétrole'), -('petrol_raffin', 'Pétrole Raffiné'), -('essence', 'Essence'), -('whool', 'Laine'), -('fabric', 'Tissu'), -('clothe', 'Vêtement'); \ No newline at end of file diff --git a/job_grades.sql b/job_grades.sql deleted file mode 100644 index 2dd407ef..00000000 --- a/job_grades.sql +++ /dev/null @@ -1,9 +0,0 @@ -INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES - ('lumberjack', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), - ('fisherman', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), - ('fuel', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), - ('reporter', 0, 'employee', 'Intérimaire', 0, '{}', '{}'), - ('textil', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), - ('miner', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), - ('slaughterer', 0, 'interim', 'Intérimaire', 0, '{}', '{}') -; diff --git a/jobs.sql b/jobs.sql deleted file mode 100644 index df3eabf2..00000000 --- a/jobs.sql +++ /dev/null @@ -1,9 +0,0 @@ -INSERT INTO `jobs` (name, label) VALUES - ('slaughterer', 'Abatteur'), - ('fisherman', 'Pêcheur'), - ('miner', 'Mineur'), - ('lumberjack', 'Bûcheron'), - ('fuel', 'Raffineur'), - ('reporter', 'Journaliste'), - ('textil', 'Couturier') -; From 1236a5751c5b67aad6ed014b387f11e5f0b661c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 15:40:37 +0200 Subject: [PATCH 0251/3224] Fix caution => Not shared --- esx_jobs.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_jobs.sql b/esx_jobs.sql index 32633b41..511ffd9d 100644 --- a/esx_jobs.sql +++ b/esx_jobs.sql @@ -1,7 +1,7 @@ USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES - ('caution','Caution',1) + ('caution', 'Caution', 0) ; INSERT INTO `jobs` (name, label) VALUES From 98ab0e461b3edbbe8284abdf5e670e566d22972b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 15:45:07 +0200 Subject: [PATCH 0252/3224] Update README.md --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 80d46548..403d87c3 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,6 @@ # fxserver-esx_jobs [REQUIRES] - fxserver-esx_addonaccount: https://github.com/FXServer-ESX/fxserver-esx_addonaccount -- in the addin_account table add a field like this: - name: caution - label: Caution - shared: 0 [KNOWN BUGS] From 78ac3497c4867878c2115fe882ed2a7629826511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 16:19:20 +0200 Subject: [PATCH 0253/3224] Move files outside folder --- .../__resource.lua => __resource.lua | 20 +- {esx_mecanojob/client => client}/main.lua | 1724 ++++++++--------- esx_mecanojob/config.lua => config.lua | 84 +- {esx_mecanojob/server => server}/main.lua | 534 ++--- 4 files changed, 1181 insertions(+), 1181 deletions(-) rename esx_mecanojob/__resource.lua => __resource.lua (93%) rename {esx_mecanojob/client => client}/main.lua (96%) rename esx_mecanojob/config.lua => config.lua (96%) rename {esx_mecanojob/server => server}/main.lua (96%) diff --git a/esx_mecanojob/__resource.lua b/__resource.lua similarity index 93% rename from esx_mecanojob/__resource.lua rename to __resource.lua index 6c475099..734f0377 100644 --- a/esx_mecanojob/__resource.lua +++ b/__resource.lua @@ -1,11 +1,11 @@ -description 'ESX Mecano Job' - -client_scripts { - 'config.lua', - 'client/main.lua' -} - -server_scripts { - 'config.lua', - 'server/main.lua' +description 'ESX Mecano Job' + +client_scripts { + 'config.lua', + 'client/main.lua' +} + +server_scripts { + 'config.lua', + 'server/main.lua' } \ No newline at end of file diff --git a/esx_mecanojob/client/main.lua b/client/main.lua similarity index 96% rename from esx_mecanojob/client/main.lua rename to client/main.lua index 992fc71d..a96d1225 100644 --- a/esx_mecanojob/client/main.lua +++ b/client/main.lua @@ -1,863 +1,863 @@ -ESX = nil -local PlayerData = {} -local GUI = {} -GUI.Time = 0 -local HasAlreadyEnteredMarker = false -local LastZone = nil -local CurrentAction = nil -local CurrentActionMsg = '' -local CurrentActionData = {} -local OnJob = false -local TargetCoords = nil - -Citizen.CreateThread(function() - while ESX == nil do - TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) - Citizen.Wait(0) - end -end) - -function OpenMecanoActionsMenu() - - local elements = { - {label = 'Sortir Véhicule', value = 'vehicle_list'}, - {label = 'Tenue de travail', value = 'cloakroom'}, - {label = 'Tenue civile', value = 'cloakroom2'} - } - if Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.grade_name == 'boss' then - table.insert(elements, {label = 'Retirer argent société', value = 'withdraw_society_money'}) - table.insert(elements, {label = 'Déposer argent ', value = 'deposit_money'}) - table.insert(elements, {label = 'Blanchir argent', value = 'wash_money'}) - end - - ESX.UI.Menu.CloseAll() - - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'mecano_actions', - { - title = 'Mecano', - elements = elements - }, - function(data, menu) - if data.current.value == 'vehicle_list' then - local elements = { - {label = 'Plateau', value = 'flatbed'}, - {label = 'Dépaneuse', value = 'towtruck2'} - } - - if Config.EnablePlayerManagement and PlayerData.job ~= nil and - (PlayerData.job.grade_name == 'boss' or PlayerData.job.grade_name == 'chef' or PlayerData.job.grade_name == 'experimente') then - table.insert(elements, {label = 'SlamVan', value = 'slamvan3'}) - end - - ESX.UI.Menu.CloseAll() - - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'spawn_vehicle', - { - title = 'Véhicule de service', - elements = elements - }, - function(data, menu) - for i=1, #elements, 1 do - if Config.MaxInService == -1 then - local playerPed = GetPlayerPed(-1) - local coords = Config.Zones.VehicleSpawnPoint.Pos - ESX.Game.SpawnVehicle(data.current.value, coords, 90.0, function(vehicle) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - end) - break - else - ESX.TriggerServerCallback('esx_service:enableService', function(canTakeService, maxInService, inServiceCount) - if canTakeService then - local playerPed = GetPlayerPed(-1) - local coords = Config.Zones.VehicleSpawnPoint.Pos - ESX.Game.SpawnVehicle(data.current.value, coords, 90.0, function(vehicle) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - end) - else - ESX.ShowNotification('Service complet : ' .. inServiceCount .. '/' .. maxInService) - end - end, 'mecano') - break - end - end - menu.close() - end, - function(data, menu) - menu.close() - OpenMecanoActionsMenu() - end - ) - end - - if data.current.value == 'cloakroom' then - menu.close() - ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) - - if skin.sex == 0 then - TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_male) - else - TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_female) - end - - end) - end - - if data.current.value == 'cloakroom2' then - menu.close() - ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) - - TriggerEvent('skinchanger:loadSkin', skin) - - end) - end - - if data.current.value == 'withdraw_society_money' then - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'withdraw_society_money_amount', - { - title = 'Montant du retrait' - }, - function(data, menu) - local amount = tonumber(data.value) - if amount == nil then - ESX.ShowNotification('Montant invalide') - else - menu.close() - TriggerServerEvent('esx_society:withdrawMoney', 'mecano', amount) - end - end, - function(data, menu) - menu.close() - end - ) - end - - if data.current.value == 'deposit_money' then - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'deposit_money_amount', - { - title = 'Montant du dépôt' - }, - function(data, menu) - local amount = tonumber(data.value) - if amount == nil then - ESX.ShowNotification('Montant invalide') - else - menu.close() - TriggerServerEvent('esx_society:depositMoney', 'mecano', amount) - end - end, - function(data, menu) - menu.close() - end - ) - end - - if data.current.value == 'wash_money' then - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'wash_money_amount', - { - title = 'Montant à blanchir' - }, - function(data, menu) - local amount = tonumber(data.value) - if amount == nil then - ESX.ShowNotification('Montant invalide') - else - menu.close() - TriggerServerEvent('esx_society:washMoney', 'mecano', amount) - end - end, - function(data, menu) - menu.close() - end - ) - end - end, - function(data, menu) - menu.close() - CurrentAction = 'mecano_actions_menu' - CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au menu.' - CurrentActionData = {} - end - ) -end - -function OpenMecanoHarvestMenu() - - if Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.grade_name ~= 'recrue' then - local elements = { - {label = 'Bouteille de gaz', value = 'gaz_bottle'}, - {label = 'Outils réparation', value = 'fix_tool'}, - {label = 'Outils Carosserie', value = 'caro_tool'} - } - - ESX.UI.Menu.CloseAll() - - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'mecano_harvest', - { - title = 'Récolte', - elements = elements - }, - function(data, menu) - if data.current.value == 'gaz_bottle' then - menu.close() - TriggerServerEvent('esx_mecanojob:startHarvest') - end - - if data.current.value == 'fix_tool' then - menu.close() - TriggerServerEvent('esx_mecanojob:startHarvest2') - end - - if data.current.value == 'caro_tool' then - menu.close() - TriggerServerEvent('esx_mecanojob:startHarvest3') - end - - end, - function(data, menu) - menu.close() - CurrentAction = 'mecano_harvest_menu' - CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au menu de récolte.' - CurrentActionData = {} - end - ) - else - ESX.ShowNotification("Vous n'êtes ~r~pas assez expérimenté~s~ pour effectuer cette action.") - end -end - -function OpenMecanoCraftMenu() - if Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.grade_name ~= 'recrue' then - - local elements = { - {label = 'Chalumeaux', value = 'blow_pipe'}, - {label = 'Kit réparation', value = 'fix_kit'}, - {label = 'Outils Carosserie', value = 'caro_kit'} - } - - ESX.UI.Menu.CloseAll() - - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'mecano_craft', - { - title = 'Etabli', - elements = elements - }, - function(data, menu) - if data.current.value == 'blow_pipe' then - menu.close() - TriggerServerEvent('esx_mecanojob:startCraft') - end - - if data.current.value == 'fix_kit' then - menu.close() - TriggerServerEvent('esx_mecanojob:startCraft2') - end - - if data.current.value == 'caro_kit' then - menu.close() - TriggerServerEvent('esx_mecanojob:startCraft3') - end - - end, - function(data, menu) - menu.close() - CurrentAction = 'mecano_craft_menu' - CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au menu établi.' - CurrentActionData = {} - end - ) - else - ESX.ShowNotification("Vous n'êtes ~r~pas assez expérimenté~s~ pour effectuer cette action.") - end -end - -function OpenMobileMecanoActionsMenu() - - ESX.UI.Menu.CloseAll() - - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'mobile_mecano_actions', - { - title = 'Mécano', - elements = { - {label = 'Facuration', value = 'billing'}, - {label = 'Crocheter', value = 'hijack_vehicle'}, - {label = 'Réparer', value = 'fix_vehicle'}, - {label = 'Netoyer', value = 'clean_vehicle'}, - {label = 'Fourrière', value = 'del_vehicle'}, - {label = 'Plateau', value = 'dep_vehicle'}, - {label = 'Placer objets', value = 'object_spawner'} - } - }, - function(data, menu) - if data.current.value == 'billing' then - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'billing', - { - title = 'Montant de la facture' - }, - function(data, menu) - local amount = tonumber(data.value) - if amount == nil then - ESX.ShowNotification('Montant invalide') - else - menu.close() - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification('Aucun joueur à proximité') - else - TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_mecano', 'Mecano', amount) - end - end - end, - function(data, menu) - menu.close() - end - ) - end - - if data.current.value == 'hijack_vehicle' then - - local playerPed = GetPlayerPed(-1) - local coords = GetEntityCoords(playerPed) - - if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then - - local vehicle = nil - - if IsPedInAnyVehicle(playerPed, false) then - vehicle = GetVehiclePedIsIn(playerPed, false) - else - vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) - end - - if DoesEntityExist(vehicle) then - TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_WELDING", 0, true) - Citizen.CreateThread(function() - Citizen.Wait(10000) - SetVehicleDoorsLocked(vehicle, 1) - SetVehicleDoorsLockedForAllPlayers(vehicle, false) - ClearPedTasksImmediately(playerPed) - TriggerEvent('esx:showNotification', 'Véhicule ~g~déverouillé') - end) - end - - end - - end - - if data.current.value == 'fix_vehicle' then - - local playerPed = GetPlayerPed(-1) - local coords = GetEntityCoords(playerPed) - - if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then - - local vehicle = nil - - if IsPedInAnyVehicle(playerPed, false) then - vehicle = GetVehiclePedIsIn(playerPed, false) - else - vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) - end - - if DoesEntityExist(vehicle) then - TaskStartScenarioInPlace(playerPed, "PROP_HUMAN_BUM_BIN", 0, true) - Citizen.CreateThread(function() - Citizen.Wait(20000) - SetVehicleFixed(vehicle) - SetVehicleDeformationFixed(vehicle) - SetVehicleUndriveable(vehicle, false) - ClearPedTasksImmediately(playerPed) - TriggerEvent('esx:showNotification', 'Véhicule ~g~réparé') - end) - end - end - end - - if data.current.value == 'clean_vehicle' then - - local playerPed = GetPlayerPed(-1) - local coords = GetEntityCoords(playerPed) - - if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then - - local vehicle = nil - - if IsPedInAnyVehicle(playerPed, false) then - vehicle = GetVehiclePedIsIn(playerPed, false) - else - vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) - end - - if DoesEntityExist(vehicle) then - TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_MAID_CLEAN", 0, true) - Citizen.CreateThread(function() - Citizen.Wait(10000) - SetVehicleDirtLevel(vehicle, 0) - ClearPedTasksImmediately(playerPed) - TriggerEvent('esx:showNotification', 'Véhicule ~g~néttoyé') - end) - end - end - end - - if data.current.value == 'del_vehicle' then - - local ped = GetPlayerPed( -1 ) - - if ( DoesEntityExist( ped ) and not IsEntityDead( ped ) ) then - local pos = GetEntityCoords( ped ) - - if ( IsPedSittingInAnyVehicle( ped ) ) then - local vehicle = GetVehiclePedIsIn( ped, false ) - - if ( GetPedInVehicleSeat( vehicle, -1 ) == ped ) then - TriggerEvent('esx:showNotification', 'Vehicule ~r~mis en fourrière') - SetEntityAsMissionEntity( vehicle, true, true ) - deleteCar( vehicle ) - else - TriggerEvent('esx:showNotification', 'Vous devez être assis du ~r~côté conducteur!') - end - else - local playerPos = GetEntityCoords( ped, 1 ) - local inFrontOfPlayer = GetOffsetFromEntityInWorldCoords( ped, 0.0, distanceToCheck, 0.0 ) - local vehicle = GetVehicleInDirection( playerPos, inFrontOfPlayer ) - - if ( DoesEntityExist( vehicle ) ) then - TriggerEvent('esx:showNotification', 'Vehicule ~r~mis en fourrière') - SetEntityAsMissionEntity( vehicle, true, true ) - deleteCar( vehicle ) - else - TriggerEvent('esx:showNotification', 'Vous devez être ~r~près d\'un véhicule~s~ pour le mettre en fourrière') - end - end - end - end - - if data.current.value == 'dep_vehicle' then - - local playerped = GetPlayerPed(-1) - local vehicle = GetVehiclePedIsIn(playerped, true) - - local towmodel = GetHashKey('flatbed') - local isVehicleTow = IsVehicleModel(vehicle, towmodel) - - if isVehicleTow then - - local coordA = GetEntityCoords(playerped, 1) - local coordB = GetOffsetFromEntityInWorldCoords(playerped, 0.0, 5.0, 0.0) - local targetVehicle = getVehicleInDirection(coordA, coordB) - - if currentlyTowedVehicle == nil then - if targetVehicle ~= 0 then - if not IsPedInAnyVehicle(playerped, true) then - if vehicle ~= targetVehicle then - AttachEntityToEntity(targetVehicle, vehicle, 20, -0.5, -5.0, 1.0, 0.0, 0.0, 0.0, false, false, false, false, 20, true) - currentlyTowedVehicle = targetVehicle - TriggerEvent('esx:showNotification', 'Vehicule ~b~attaché~s~ avec succès!') - else - TriggerEvent('esx:showNotification', '~r~Impossible~s~ d\'attacher votre propre dépanneuse') - end - end - else - TriggerEvent('esx:showNotification', 'Il n\'y a ~r~pas de véhicule~s~ à attacher') - end - else - AttachEntityToEntity(currentlyTowedVehicle, vehicle, 20, -0.5, -12.0, 1.0, 0.0, 0.0, 0.0, false, false, false, false, 20, true) - DetachEntity(currentlyTowedVehicle, true, true) - currentlyTowedVehicle = nil - TriggerEvent('esx:showNotification', 'Vehicule ~b~détattaché~s~ avec succès!') - end - else - TriggerEvent('esx:showNotification', '~r~Impossible! ~s~Vous devez avoir un ~b~Flatbed ~s~pour ça') - end - end - - if data.current.value == 'object_spawner' then - - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'mobile_mecano_actions_spawn', - { - title = 'Objets', - align = 'top-left', - elements = { - {label = 'Plot', value = 'prop_roadcone02a'}, - {label = 'Boîte à outils', value = 'prop_toolchest_01'}, - }, - }, - function(data2, menu2) - - - local model = data2.current.value - local playerPed = GetPlayerPed(-1) - local coords = GetEntityCoords(playerPed) - local forward = GetEntityForwardVector(playerPed) - local x, y, z = table.unpack(coords + forward * 1.0) - - if model == 'prop_roadcone02a' then - z = z - 2.0 - elseif model == 'prop_toolchest_01' then - z = z - 3.0 - end - - ESX.Game.SpawnObject(model, { - x = x, - y = y, - z = z - }, 3.0, function(obj) - SetEntityHeading(obj, GetEntityHeading(playerPed)) - PlaceObjectOnGroundProperly(obj) - end) - - end, - function(data2, menu2) - menu2.close() - end - ) - - end - - end, - function(data, menu) - menu.close() - end - ) -end - -RegisterNetEvent('esx_mecanojob:onHijack') -AddEventHandler('esx_mecanojob:onHijack', function() - local playerPed = GetPlayerPed(-1) - local coords = GetEntityCoords(playerPed) - - if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then - - local vehicle = nil - - if IsPedInAnyVehicle(playerPed, false) then - vehicle = GetVehiclePedIsIn(playerPed, false) - else - vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) - end - - local crochete = math.random(100) - local alarm = math.random(100) - - if DoesEntityExist(vehicle) then - if alarm <= 33 then - SetVehicleAlarm(vehicle, true) - StartVehicleAlarm(vehicle) - end - TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_WELDING", 0, true) - Citizen.CreateThread(function() - Citizen.Wait(10000) - if crochete <= 66 then - SetVehicleDoorsLocked(vehicle, 1) - SetVehicleDoorsLockedForAllPlayers(vehicle, false) - ClearPedTasksImmediately(playerPed) - TriggerEvent('esx:showNotification', '~g~Véhicule déverouillé') - else - TriggerEvent('esx:showNotification', '~r~Crochetage raté') - ClearPedTasksImmediately(playerPed) - end - end) - end - - end -end) - -RegisterNetEvent('esx_mecanojob:onCarokit') -AddEventHandler('esx_mecanojob:onCarokit', function() - local playerPed = GetPlayerPed(-1) - local coords = GetEntityCoords(playerPed) - - if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then - - local vehicle = nil - - if IsPedInAnyVehicle(playerPed, false) then - vehicle = GetVehiclePedIsIn(playerPed, false) - else - vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) - end - - if DoesEntityExist(vehicle) then - TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_HAMMERING", 0, true) - Citizen.CreateThread(function() - Citizen.Wait(10000) - SetVehicleFixed(vehicle) - SetVehicleDeformationFixed(vehicle) - ClearPedTasksImmediately(playerPed) - TriggerEvent('esx:showNotification', '~g~Carosserie réparée') - end) - end - end -end) - -RegisterNetEvent('esx_mecanojob:onFixkit') -AddEventHandler('esx_mecanojob:onFixkit', function() - local playerPed = GetPlayerPed(-1) - local coords = GetEntityCoords(playerPed) - - if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then - - local vehicle = nil - - if IsPedInAnyVehicle(playerPed, false) then - vehicle = GetVehiclePedIsIn(playerPed, false) - else - vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) - end - - if DoesEntityExist(vehicle) then - TaskStartScenarioInPlace(playerPed, "PROP_HUMAN_BUM_BIN", 0, true) - Citizen.CreateThread(function() - Citizen.Wait(20000) - SetVehicleFixed(vehicle) - SetVehicleDeformationFixed(vehicle) - SetVehicleUndriveable(vehicle, false) - ClearPedTasksImmediately(playerPed) - TriggerEvent('esx:showNotification', '~g~Véhicule réparé') - end) - end - end -end) - -function setEntityHeadingFromEntity ( vehicle, playerPed ) - local heading = GetEntityHeading(vehicle) - SetEntityHeading( playerPed, heading ) -end - -function getVehicleInDirection(coordFrom, coordTo) - local rayHandle = CastRayPointToPoint(coordFrom.x, coordFrom.y, coordFrom.z, coordTo.x, coordTo.y, coordTo.z, 10, GetPlayerPed(-1), 0) - local a, b, c, d, vehicle = GetRaycastResult(rayHandle) - return vehicle -end - -function deleteCar( entity ) - Citizen.InvokeNative( 0xEA386986E786A54F, Citizen.PointerValueIntInitialized( entity ) ) -end - -RegisterNetEvent('esx:playerLoaded') -AddEventHandler('esx:playerLoaded', function(xPlayer) - PlayerData = xPlayer -end) - -RegisterNetEvent('esx:setJob') -AddEventHandler('esx:setJob', function(job) - PlayerData.job = job -end) - -AddEventHandler('esx_mecanojob:hasEnteredMarker', function(zone) - if zone == 'MecanoActions' then - CurrentAction = 'mecano_actions_menu' - CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au menu.' - CurrentActionData = {} - end - if zone == 'Garage' then - CurrentAction = 'mecano_harvest_menu' - CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au menu de récolte.' - CurrentActionData = {} - end - if zone == 'Craft' then - CurrentAction = 'mecano_craft_menu' - CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au menu établi.' - CurrentActionData = {} - end - if zone == 'VehicleDeleter' then - local playerPed = GetPlayerPed(-1) - if IsPedInAnyVehicle(playerPed, false) then - CurrentAction = 'delete_vehicle' - CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour ranger le véhicule.' - CurrentActionData = {} - end - end -end) - -AddEventHandler('esx_mecanojob:hasExitedMarker', function(zone) - - if zone == 'Craft' then - TriggerServerEvent('esx_mecanojob:stopCraft') - TriggerServerEvent('esx_mecanojob:stopCraft2') - TriggerServerEvent('esx_mecanojob:stopCraft3') - end - - if zone == 'Garage' then - TriggerServerEvent('esx_mecanojob:stopHarvest') - TriggerServerEvent('esx_mecanojob:stopHarvest2') - TriggerServerEvent('esx_mecanojob:stopHarvest3') - end - - CurrentAction = nil - ESX.UI.Menu.CloseAll() -end) - -AddEventHandler('esx_mecanojob:hasEnteredEntityZone', function(entity) - - local playerPed = GetPlayerPed(-1) - - if PlayerData.job ~= nil and PlayerData.job.name == 'mecano' and not IsPedInAnyVehicle(playerPed, false) then - CurrentAction = 'remove_entity' - CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour enlever l\'objet' - CurrentActionData = {entity = entity} - end - -end) - -AddEventHandler('esx_mecanojob:hasExitedEntityZone', function(entity) - - if CurrentAction == 'remove_entity' then - CurrentAction = nil - end - -end) - -RegisterNetEvent('esx_phone:loaded') -AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) - local specialContact = { - name = 'Mecano', - number = 'mecano', - base64Icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAAA4BJREFUWIXtll9oU3cUx7/nJA02aSSlFouWMnXVB0ejU3wcRteHjv1puoc9rA978cUi2IqgRYWIZkMwrahUGfgkFMEZUdg6C+u21z1o3fbgqigVi7NzUtNcmsac40Npltz7S3rvUHzxQODec87vfD+/e0/O/QFv7Q0beV3QeXqmgV74/7H7fZJvuLwv8q/Xeux1gUrNBpN/nmtavdaqDqBK8VT2RDyV2VHmF1lvLERSBtCVynzYmcp+A9WqT9kcVKX4gHUehF0CEVY+1jYTTIwvt7YSIQnCTvsSUYz6gX5uDt7MP7KOKuQAgxmqQ+neUA+I1B1AiXi5X6ZAvKrabirmVYFwAMRT2RMg7F9SyKspvk73hfrtbkMPyIhA5FVqi0iBiEZMMQdAui/8E4GPv0oAJkpc6Q3+6goAAGpWBxNQmTLFmgL3jSJNgQdGv4pMts2EKm7ICJB/aG0xNdz74VEk13UYCx1/twPR8JjDT8wttyLZtkoAxSb8ZDCz0gdfKxWkFURf2v9qTYH7SK7rQIDn0P3nA0ehixvfwZwE0X9vBE/mW8piohhl1WH18UQBhYnre8N/L8b8xQvlx4ACbB4NnzaeRYDnKm0EALCMLXy84hwuTCXL/ExoB1E7qcK/8NCLIq5HcTT0i6u8TYbXUM1cAyyveVq8Xls7XhYrvY/4n3gC8C+dsmAzL1YUiyfWxvHzsy/w/dNd+KjhW2yvv/RfXr7x9QDcmo1he2RBiCCI1Q8jVj9szPNixVfgz+UiIGyDSrcoRu2J16d3I6e1VYvNSQjXpnucAcEPUOkGYZs/l4uUhowt/3kqu1UIv9n90fAY9jT3YBlbRvFTD4fw++wHjhiTRL/bG75t0jI2ITcHb5om4Xgmhv57xpGOg3d/NIqryOR7z+r+MC6qBJB/ZB2t9Om1D5lFm843G/3E3HI7Yh1xDRAfzLQr5EClBf/HBHK462TG2J0OABXeyWDPZ8VqxmBWYscpyghwtTd4EKpDTjCZdCNmzFM9k+4LHXIFACJN94Z6FiFEpKDQw9HndWsEuhnADVMhAUaYJBp9XrcGQKJ4qFE9k+6r2+MG3k5N8VQ22TVglbX2ZwOzX2VvNKr91zmY6S7N6zqZicVT2WNLyVSehESaBhxnOALfMeYX+K/S2yv7wmMAlvwyuR7FxQUyf0fgc/jztfkJr7XeGgC8BJJgWNV8ImT+AAAAAElFTkSuQmCC' - } - TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) -end) - --- Create Blips -Citizen.CreateThread(function() - local blip = AddBlipForCoord(Config.Zones.MecanoActions.Pos.x, Config.Zones.MecanoActions.Pos.y, Config.Zones.MecanoActions.Pos.z) - SetBlipSprite (blip, 446) - SetBlipDisplay(blip, 4) - SetBlipScale (blip, 1.0) - SetBlipColour (blip, 5) - SetBlipAsShortRange(blip, true) - BeginTextCommandSetBlipName("STRING") - AddTextComponentString("Mecano") - EndTextCommandSetBlipName(blip) -end) - --- Display markers -Citizen.CreateThread(function() - while true do - Wait(0) - if PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then - - local coords = GetEntityCoords(GetPlayerPed(-1)) - - for k,v in pairs(Config.Zones) do - if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then - DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) - end - end - end - end -end) - --- Enter / Exit marker events -Citizen.CreateThread(function() - while true do - Wait(0) - if PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then - local coords = GetEntityCoords(GetPlayerPed(-1)) - local isInMarker = false - local currentZone = nil - for k,v in pairs(Config.Zones) do - if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then - isInMarker = true - currentZone = k - end - end - if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then - HasAlreadyEnteredMarker = true - LastZone = currentZone - TriggerEvent('esx_mecanojob:hasEnteredMarker', currentZone) - end - if not isInMarker and HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = false - TriggerEvent('esx_mecanojob:hasExitedMarker', LastZone) - end - end - end -end) - -Citizen.CreateThread(function() - while true do - - Citizen.Wait(0) - - local playerPed = GetPlayerPed(-1) - local coords = GetEntityCoords(playerPed) - - local entity, distance = ESX.Game.GetClosestObject({ - 'prop_roadcone02a', - 'prop_toolchest_01' - }) - - if distance ~= -1 and distance <= 3.0 then - - if LastEntity ~= entity then - TriggerEvent('esx_mecanojob:hasEnteredEntityZone', entity) - LastEntity = entity - end - - else - - if LastEntity ~= nil then - TriggerEvent('esx_mecanojob:hasExitedEntityZone', LastEntity) - LastEntity = nil - end - - end - - end -end) - - --- Key Controls -Citizen.CreateThread(function() - while true do - Citizen.Wait(0) - if CurrentAction ~= nil then - SetTextComponentFormat('STRING') - AddTextComponentString(CurrentActionMsg) - DisplayHelpTextFromStringLabel(0, 0, 1, -1) - if IsControlJustReleased(0, 38) and PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then - if CurrentAction == 'mecano_actions_menu' then - OpenMecanoActionsMenu() - end - if CurrentAction == 'mecano_harvest_menu' then - OpenMecanoHarvestMenu() - end - if CurrentAction == 'mecano_craft_menu' then - OpenMecanoCraftMenu() - end - if CurrentAction == 'delete_vehicle' then - local playerPed = GetPlayerPed(-1) - local vehicle = GetVehiclePedIsIn(playerPed, false) - local hash = GetEntityModel(vehicle) - if hash == GetHashKey('flatbed') or hash == GetHashKey('towtruck2') or hash == GetHashKey('slamvan3') then - if Config.MaxInService ~= -1 then - TriggerServerEvent('esx_service:disableService', 'mecano') - end - DeleteVehicle(vehicle) - else - ESX.ShowNotification('Vous ne pouvez ranger que des ~b~véhicules de Mécano~s~.') - end - end - if CurrentAction == 'remove_entity' then - DeleteEntity(CurrentActionData.entity) - end - CurrentAction = nil - end - end - - if IsControlJustReleased(0, 167) and PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then - OpenMobileMecanoActionsMenu() - end - end +ESX = nil +local PlayerData = {} +local GUI = {} +GUI.Time = 0 +local HasAlreadyEnteredMarker = false +local LastZone = nil +local CurrentAction = nil +local CurrentActionMsg = '' +local CurrentActionData = {} +local OnJob = false +local TargetCoords = nil + +Citizen.CreateThread(function() + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end +end) + +function OpenMecanoActionsMenu() + + local elements = { + {label = 'Sortir Véhicule', value = 'vehicle_list'}, + {label = 'Tenue de travail', value = 'cloakroom'}, + {label = 'Tenue civile', value = 'cloakroom2'} + } + if Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.grade_name == 'boss' then + table.insert(elements, {label = 'Retirer argent société', value = 'withdraw_society_money'}) + table.insert(elements, {label = 'Déposer argent ', value = 'deposit_money'}) + table.insert(elements, {label = 'Blanchir argent', value = 'wash_money'}) + end + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'mecano_actions', + { + title = 'Mecano', + elements = elements + }, + function(data, menu) + if data.current.value == 'vehicle_list' then + local elements = { + {label = 'Plateau', value = 'flatbed'}, + {label = 'Dépaneuse', value = 'towtruck2'} + } + + if Config.EnablePlayerManagement and PlayerData.job ~= nil and + (PlayerData.job.grade_name == 'boss' or PlayerData.job.grade_name == 'chef' or PlayerData.job.grade_name == 'experimente') then + table.insert(elements, {label = 'SlamVan', value = 'slamvan3'}) + end + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'spawn_vehicle', + { + title = 'Véhicule de service', + elements = elements + }, + function(data, menu) + for i=1, #elements, 1 do + if Config.MaxInService == -1 then + local playerPed = GetPlayerPed(-1) + local coords = Config.Zones.VehicleSpawnPoint.Pos + ESX.Game.SpawnVehicle(data.current.value, coords, 90.0, function(vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + end) + break + else + ESX.TriggerServerCallback('esx_service:enableService', function(canTakeService, maxInService, inServiceCount) + if canTakeService then + local playerPed = GetPlayerPed(-1) + local coords = Config.Zones.VehicleSpawnPoint.Pos + ESX.Game.SpawnVehicle(data.current.value, coords, 90.0, function(vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + end) + else + ESX.ShowNotification('Service complet : ' .. inServiceCount .. '/' .. maxInService) + end + end, 'mecano') + break + end + end + menu.close() + end, + function(data, menu) + menu.close() + OpenMecanoActionsMenu() + end + ) + end + + if data.current.value == 'cloakroom' then + menu.close() + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) + + if skin.sex == 0 then + TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_male) + else + TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_female) + end + + end) + end + + if data.current.value == 'cloakroom2' then + menu.close() + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) + + TriggerEvent('skinchanger:loadSkin', skin) + + end) + end + + if data.current.value == 'withdraw_society_money' then + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'withdraw_society_money_amount', + { + title = 'Montant du retrait' + }, + function(data, menu) + local amount = tonumber(data.value) + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + menu.close() + TriggerServerEvent('esx_society:withdrawMoney', 'mecano', amount) + end + end, + function(data, menu) + menu.close() + end + ) + end + + if data.current.value == 'deposit_money' then + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'deposit_money_amount', + { + title = 'Montant du dépôt' + }, + function(data, menu) + local amount = tonumber(data.value) + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + menu.close() + TriggerServerEvent('esx_society:depositMoney', 'mecano', amount) + end + end, + function(data, menu) + menu.close() + end + ) + end + + if data.current.value == 'wash_money' then + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'wash_money_amount', + { + title = 'Montant à blanchir' + }, + function(data, menu) + local amount = tonumber(data.value) + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + menu.close() + TriggerServerEvent('esx_society:washMoney', 'mecano', amount) + end + end, + function(data, menu) + menu.close() + end + ) + end + end, + function(data, menu) + menu.close() + CurrentAction = 'mecano_actions_menu' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au menu.' + CurrentActionData = {} + end + ) +end + +function OpenMecanoHarvestMenu() + + if Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.grade_name ~= 'recrue' then + local elements = { + {label = 'Bouteille de gaz', value = 'gaz_bottle'}, + {label = 'Outils réparation', value = 'fix_tool'}, + {label = 'Outils Carosserie', value = 'caro_tool'} + } + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'mecano_harvest', + { + title = 'Récolte', + elements = elements + }, + function(data, menu) + if data.current.value == 'gaz_bottle' then + menu.close() + TriggerServerEvent('esx_mecanojob:startHarvest') + end + + if data.current.value == 'fix_tool' then + menu.close() + TriggerServerEvent('esx_mecanojob:startHarvest2') + end + + if data.current.value == 'caro_tool' then + menu.close() + TriggerServerEvent('esx_mecanojob:startHarvest3') + end + + end, + function(data, menu) + menu.close() + CurrentAction = 'mecano_harvest_menu' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au menu de récolte.' + CurrentActionData = {} + end + ) + else + ESX.ShowNotification("Vous n'êtes ~r~pas assez expérimenté~s~ pour effectuer cette action.") + end +end + +function OpenMecanoCraftMenu() + if Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.grade_name ~= 'recrue' then + + local elements = { + {label = 'Chalumeaux', value = 'blow_pipe'}, + {label = 'Kit réparation', value = 'fix_kit'}, + {label = 'Outils Carosserie', value = 'caro_kit'} + } + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'mecano_craft', + { + title = 'Etabli', + elements = elements + }, + function(data, menu) + if data.current.value == 'blow_pipe' then + menu.close() + TriggerServerEvent('esx_mecanojob:startCraft') + end + + if data.current.value == 'fix_kit' then + menu.close() + TriggerServerEvent('esx_mecanojob:startCraft2') + end + + if data.current.value == 'caro_kit' then + menu.close() + TriggerServerEvent('esx_mecanojob:startCraft3') + end + + end, + function(data, menu) + menu.close() + CurrentAction = 'mecano_craft_menu' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au menu établi.' + CurrentActionData = {} + end + ) + else + ESX.ShowNotification("Vous n'êtes ~r~pas assez expérimenté~s~ pour effectuer cette action.") + end +end + +function OpenMobileMecanoActionsMenu() + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'mobile_mecano_actions', + { + title = 'Mécano', + elements = { + {label = 'Facuration', value = 'billing'}, + {label = 'Crocheter', value = 'hijack_vehicle'}, + {label = 'Réparer', value = 'fix_vehicle'}, + {label = 'Netoyer', value = 'clean_vehicle'}, + {label = 'Fourrière', value = 'del_vehicle'}, + {label = 'Plateau', value = 'dep_vehicle'}, + {label = 'Placer objets', value = 'object_spawner'} + } + }, + function(data, menu) + if data.current.value == 'billing' then + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'billing', + { + title = 'Montant de la facture' + }, + function(data, menu) + local amount = tonumber(data.value) + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + menu.close() + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification('Aucun joueur à proximité') + else + TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_mecano', 'Mecano', amount) + end + end + end, + function(data, menu) + menu.close() + end + ) + end + + if data.current.value == 'hijack_vehicle' then + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + + local vehicle = nil + + if IsPedInAnyVehicle(playerPed, false) then + vehicle = GetVehiclePedIsIn(playerPed, false) + else + vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) + end + + if DoesEntityExist(vehicle) then + TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_WELDING", 0, true) + Citizen.CreateThread(function() + Citizen.Wait(10000) + SetVehicleDoorsLocked(vehicle, 1) + SetVehicleDoorsLockedForAllPlayers(vehicle, false) + ClearPedTasksImmediately(playerPed) + TriggerEvent('esx:showNotification', 'Véhicule ~g~déverouillé') + end) + end + + end + + end + + if data.current.value == 'fix_vehicle' then + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + + local vehicle = nil + + if IsPedInAnyVehicle(playerPed, false) then + vehicle = GetVehiclePedIsIn(playerPed, false) + else + vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) + end + + if DoesEntityExist(vehicle) then + TaskStartScenarioInPlace(playerPed, "PROP_HUMAN_BUM_BIN", 0, true) + Citizen.CreateThread(function() + Citizen.Wait(20000) + SetVehicleFixed(vehicle) + SetVehicleDeformationFixed(vehicle) + SetVehicleUndriveable(vehicle, false) + ClearPedTasksImmediately(playerPed) + TriggerEvent('esx:showNotification', 'Véhicule ~g~réparé') + end) + end + end + end + + if data.current.value == 'clean_vehicle' then + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + + local vehicle = nil + + if IsPedInAnyVehicle(playerPed, false) then + vehicle = GetVehiclePedIsIn(playerPed, false) + else + vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) + end + + if DoesEntityExist(vehicle) then + TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_MAID_CLEAN", 0, true) + Citizen.CreateThread(function() + Citizen.Wait(10000) + SetVehicleDirtLevel(vehicle, 0) + ClearPedTasksImmediately(playerPed) + TriggerEvent('esx:showNotification', 'Véhicule ~g~néttoyé') + end) + end + end + end + + if data.current.value == 'del_vehicle' then + + local ped = GetPlayerPed( -1 ) + + if ( DoesEntityExist( ped ) and not IsEntityDead( ped ) ) then + local pos = GetEntityCoords( ped ) + + if ( IsPedSittingInAnyVehicle( ped ) ) then + local vehicle = GetVehiclePedIsIn( ped, false ) + + if ( GetPedInVehicleSeat( vehicle, -1 ) == ped ) then + TriggerEvent('esx:showNotification', 'Vehicule ~r~mis en fourrière') + SetEntityAsMissionEntity( vehicle, true, true ) + deleteCar( vehicle ) + else + TriggerEvent('esx:showNotification', 'Vous devez être assis du ~r~côté conducteur!') + end + else + local playerPos = GetEntityCoords( ped, 1 ) + local inFrontOfPlayer = GetOffsetFromEntityInWorldCoords( ped, 0.0, distanceToCheck, 0.0 ) + local vehicle = GetVehicleInDirection( playerPos, inFrontOfPlayer ) + + if ( DoesEntityExist( vehicle ) ) then + TriggerEvent('esx:showNotification', 'Vehicule ~r~mis en fourrière') + SetEntityAsMissionEntity( vehicle, true, true ) + deleteCar( vehicle ) + else + TriggerEvent('esx:showNotification', 'Vous devez être ~r~près d\'un véhicule~s~ pour le mettre en fourrière') + end + end + end + end + + if data.current.value == 'dep_vehicle' then + + local playerped = GetPlayerPed(-1) + local vehicle = GetVehiclePedIsIn(playerped, true) + + local towmodel = GetHashKey('flatbed') + local isVehicleTow = IsVehicleModel(vehicle, towmodel) + + if isVehicleTow then + + local coordA = GetEntityCoords(playerped, 1) + local coordB = GetOffsetFromEntityInWorldCoords(playerped, 0.0, 5.0, 0.0) + local targetVehicle = getVehicleInDirection(coordA, coordB) + + if currentlyTowedVehicle == nil then + if targetVehicle ~= 0 then + if not IsPedInAnyVehicle(playerped, true) then + if vehicle ~= targetVehicle then + AttachEntityToEntity(targetVehicle, vehicle, 20, -0.5, -5.0, 1.0, 0.0, 0.0, 0.0, false, false, false, false, 20, true) + currentlyTowedVehicle = targetVehicle + TriggerEvent('esx:showNotification', 'Vehicule ~b~attaché~s~ avec succès!') + else + TriggerEvent('esx:showNotification', '~r~Impossible~s~ d\'attacher votre propre dépanneuse') + end + end + else + TriggerEvent('esx:showNotification', 'Il n\'y a ~r~pas de véhicule~s~ à attacher') + end + else + AttachEntityToEntity(currentlyTowedVehicle, vehicle, 20, -0.5, -12.0, 1.0, 0.0, 0.0, 0.0, false, false, false, false, 20, true) + DetachEntity(currentlyTowedVehicle, true, true) + currentlyTowedVehicle = nil + TriggerEvent('esx:showNotification', 'Vehicule ~b~détattaché~s~ avec succès!') + end + else + TriggerEvent('esx:showNotification', '~r~Impossible! ~s~Vous devez avoir un ~b~Flatbed ~s~pour ça') + end + end + + if data.current.value == 'object_spawner' then + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'mobile_mecano_actions_spawn', + { + title = 'Objets', + align = 'top-left', + elements = { + {label = 'Plot', value = 'prop_roadcone02a'}, + {label = 'Boîte à outils', value = 'prop_toolchest_01'}, + }, + }, + function(data2, menu2) + + + local model = data2.current.value + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + local forward = GetEntityForwardVector(playerPed) + local x, y, z = table.unpack(coords + forward * 1.0) + + if model == 'prop_roadcone02a' then + z = z - 2.0 + elseif model == 'prop_toolchest_01' then + z = z - 3.0 + end + + ESX.Game.SpawnObject(model, { + x = x, + y = y, + z = z + }, 3.0, function(obj) + SetEntityHeading(obj, GetEntityHeading(playerPed)) + PlaceObjectOnGroundProperly(obj) + end) + + end, + function(data2, menu2) + menu2.close() + end + ) + + end + + end, + function(data, menu) + menu.close() + end + ) +end + +RegisterNetEvent('esx_mecanojob:onHijack') +AddEventHandler('esx_mecanojob:onHijack', function() + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + + local vehicle = nil + + if IsPedInAnyVehicle(playerPed, false) then + vehicle = GetVehiclePedIsIn(playerPed, false) + else + vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) + end + + local crochete = math.random(100) + local alarm = math.random(100) + + if DoesEntityExist(vehicle) then + if alarm <= 33 then + SetVehicleAlarm(vehicle, true) + StartVehicleAlarm(vehicle) + end + TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_WELDING", 0, true) + Citizen.CreateThread(function() + Citizen.Wait(10000) + if crochete <= 66 then + SetVehicleDoorsLocked(vehicle, 1) + SetVehicleDoorsLockedForAllPlayers(vehicle, false) + ClearPedTasksImmediately(playerPed) + TriggerEvent('esx:showNotification', '~g~Véhicule déverouillé') + else + TriggerEvent('esx:showNotification', '~r~Crochetage raté') + ClearPedTasksImmediately(playerPed) + end + end) + end + + end +end) + +RegisterNetEvent('esx_mecanojob:onCarokit') +AddEventHandler('esx_mecanojob:onCarokit', function() + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + + local vehicle = nil + + if IsPedInAnyVehicle(playerPed, false) then + vehicle = GetVehiclePedIsIn(playerPed, false) + else + vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) + end + + if DoesEntityExist(vehicle) then + TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_HAMMERING", 0, true) + Citizen.CreateThread(function() + Citizen.Wait(10000) + SetVehicleFixed(vehicle) + SetVehicleDeformationFixed(vehicle) + ClearPedTasksImmediately(playerPed) + TriggerEvent('esx:showNotification', '~g~Carosserie réparée') + end) + end + end +end) + +RegisterNetEvent('esx_mecanojob:onFixkit') +AddEventHandler('esx_mecanojob:onFixkit', function() + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + + local vehicle = nil + + if IsPedInAnyVehicle(playerPed, false) then + vehicle = GetVehiclePedIsIn(playerPed, false) + else + vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) + end + + if DoesEntityExist(vehicle) then + TaskStartScenarioInPlace(playerPed, "PROP_HUMAN_BUM_BIN", 0, true) + Citizen.CreateThread(function() + Citizen.Wait(20000) + SetVehicleFixed(vehicle) + SetVehicleDeformationFixed(vehicle) + SetVehicleUndriveable(vehicle, false) + ClearPedTasksImmediately(playerPed) + TriggerEvent('esx:showNotification', '~g~Véhicule réparé') + end) + end + end +end) + +function setEntityHeadingFromEntity ( vehicle, playerPed ) + local heading = GetEntityHeading(vehicle) + SetEntityHeading( playerPed, heading ) +end + +function getVehicleInDirection(coordFrom, coordTo) + local rayHandle = CastRayPointToPoint(coordFrom.x, coordFrom.y, coordFrom.z, coordTo.x, coordTo.y, coordTo.z, 10, GetPlayerPed(-1), 0) + local a, b, c, d, vehicle = GetRaycastResult(rayHandle) + return vehicle +end + +function deleteCar( entity ) + Citizen.InvokeNative( 0xEA386986E786A54F, Citizen.PointerValueIntInitialized( entity ) ) +end + +RegisterNetEvent('esx:playerLoaded') +AddEventHandler('esx:playerLoaded', function(xPlayer) + PlayerData = xPlayer +end) + +RegisterNetEvent('esx:setJob') +AddEventHandler('esx:setJob', function(job) + PlayerData.job = job +end) + +AddEventHandler('esx_mecanojob:hasEnteredMarker', function(zone) + if zone == 'MecanoActions' then + CurrentAction = 'mecano_actions_menu' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au menu.' + CurrentActionData = {} + end + if zone == 'Garage' then + CurrentAction = 'mecano_harvest_menu' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au menu de récolte.' + CurrentActionData = {} + end + if zone == 'Craft' then + CurrentAction = 'mecano_craft_menu' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au menu établi.' + CurrentActionData = {} + end + if zone == 'VehicleDeleter' then + local playerPed = GetPlayerPed(-1) + if IsPedInAnyVehicle(playerPed, false) then + CurrentAction = 'delete_vehicle' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour ranger le véhicule.' + CurrentActionData = {} + end + end +end) + +AddEventHandler('esx_mecanojob:hasExitedMarker', function(zone) + + if zone == 'Craft' then + TriggerServerEvent('esx_mecanojob:stopCraft') + TriggerServerEvent('esx_mecanojob:stopCraft2') + TriggerServerEvent('esx_mecanojob:stopCraft3') + end + + if zone == 'Garage' then + TriggerServerEvent('esx_mecanojob:stopHarvest') + TriggerServerEvent('esx_mecanojob:stopHarvest2') + TriggerServerEvent('esx_mecanojob:stopHarvest3') + end + + CurrentAction = nil + ESX.UI.Menu.CloseAll() +end) + +AddEventHandler('esx_mecanojob:hasEnteredEntityZone', function(entity) + + local playerPed = GetPlayerPed(-1) + + if PlayerData.job ~= nil and PlayerData.job.name == 'mecano' and not IsPedInAnyVehicle(playerPed, false) then + CurrentAction = 'remove_entity' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour enlever l\'objet' + CurrentActionData = {entity = entity} + end + +end) + +AddEventHandler('esx_mecanojob:hasExitedEntityZone', function(entity) + + if CurrentAction == 'remove_entity' then + CurrentAction = nil + end + +end) + +RegisterNetEvent('esx_phone:loaded') +AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) + local specialContact = { + name = 'Mecano', + number = 'mecano', + base64Icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAAA4BJREFUWIXtll9oU3cUx7/nJA02aSSlFouWMnXVB0ejU3wcRteHjv1puoc9rA978cUi2IqgRYWIZkMwrahUGfgkFMEZUdg6C+u21z1o3fbgqigVi7NzUtNcmsac40Npltz7S3rvUHzxQODec87vfD+/e0/O/QFv7Q0beV3QeXqmgV74/7H7fZJvuLwv8q/Xeux1gUrNBpN/nmtavdaqDqBK8VT2RDyV2VHmF1lvLERSBtCVynzYmcp+A9WqT9kcVKX4gHUehF0CEVY+1jYTTIwvt7YSIQnCTvsSUYz6gX5uDt7MP7KOKuQAgxmqQ+neUA+I1B1AiXi5X6ZAvKrabirmVYFwAMRT2RMg7F9SyKspvk73hfrtbkMPyIhA5FVqi0iBiEZMMQdAui/8E4GPv0oAJkpc6Q3+6goAAGpWBxNQmTLFmgL3jSJNgQdGv4pMts2EKm7ICJB/aG0xNdz74VEk13UYCx1/twPR8JjDT8wttyLZtkoAxSb8ZDCz0gdfKxWkFURf2v9qTYH7SK7rQIDn0P3nA0ehixvfwZwE0X9vBE/mW8piohhl1WH18UQBhYnre8N/L8b8xQvlx4ACbB4NnzaeRYDnKm0EALCMLXy84hwuTCXL/ExoB1E7qcK/8NCLIq5HcTT0i6u8TYbXUM1cAyyveVq8Xls7XhYrvY/4n3gC8C+dsmAzL1YUiyfWxvHzsy/w/dNd+KjhW2yvv/RfXr7x9QDcmo1he2RBiCCI1Q8jVj9szPNixVfgz+UiIGyDSrcoRu2J16d3I6e1VYvNSQjXpnucAcEPUOkGYZs/l4uUhowt/3kqu1UIv9n90fAY9jT3YBlbRvFTD4fw++wHjhiTRL/bG75t0jI2ITcHb5om4Xgmhv57xpGOg3d/NIqryOR7z+r+MC6qBJB/ZB2t9Om1D5lFm843G/3E3HI7Yh1xDRAfzLQr5EClBf/HBHK462TG2J0OABXeyWDPZ8VqxmBWYscpyghwtTd4EKpDTjCZdCNmzFM9k+4LHXIFACJN94Z6FiFEpKDQw9HndWsEuhnADVMhAUaYJBp9XrcGQKJ4qFE9k+6r2+MG3k5N8VQ22TVglbX2ZwOzX2VvNKr91zmY6S7N6zqZicVT2WNLyVSehESaBhxnOALfMeYX+K/S2yv7wmMAlvwyuR7FxQUyf0fgc/jztfkJr7XeGgC8BJJgWNV8ImT+AAAAAElFTkSuQmCC' + } + TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) +end) + +-- Create Blips +Citizen.CreateThread(function() + local blip = AddBlipForCoord(Config.Zones.MecanoActions.Pos.x, Config.Zones.MecanoActions.Pos.y, Config.Zones.MecanoActions.Pos.z) + SetBlipSprite (blip, 446) + SetBlipDisplay(blip, 4) + SetBlipScale (blip, 1.0) + SetBlipColour (blip, 5) + SetBlipAsShortRange(blip, true) + BeginTextCommandSetBlipName("STRING") + AddTextComponentString("Mecano") + EndTextCommandSetBlipName(blip) +end) + +-- Display markers +Citizen.CreateThread(function() + while true do + Wait(0) + if PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then + + local coords = GetEntityCoords(GetPlayerPed(-1)) + + for k,v in pairs(Config.Zones) do + if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) + end + end + end + end +end) + +-- Enter / Exit marker events +Citizen.CreateThread(function() + while true do + Wait(0) + if PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then + local coords = GetEntityCoords(GetPlayerPed(-1)) + local isInMarker = false + local currentZone = nil + for k,v in pairs(Config.Zones) do + if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then + isInMarker = true + currentZone = k + end + end + if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then + HasAlreadyEnteredMarker = true + LastZone = currentZone + TriggerEvent('esx_mecanojob:hasEnteredMarker', currentZone) + end + if not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent('esx_mecanojob:hasExitedMarker', LastZone) + end + end + end +end) + +Citizen.CreateThread(function() + while true do + + Citizen.Wait(0) + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + local entity, distance = ESX.Game.GetClosestObject({ + 'prop_roadcone02a', + 'prop_toolchest_01' + }) + + if distance ~= -1 and distance <= 3.0 then + + if LastEntity ~= entity then + TriggerEvent('esx_mecanojob:hasEnteredEntityZone', entity) + LastEntity = entity + end + + else + + if LastEntity ~= nil then + TriggerEvent('esx_mecanojob:hasExitedEntityZone', LastEntity) + LastEntity = nil + end + + end + + end +end) + + +-- Key Controls +Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + if CurrentAction ~= nil then + SetTextComponentFormat('STRING') + AddTextComponentString(CurrentActionMsg) + DisplayHelpTextFromStringLabel(0, 0, 1, -1) + if IsControlJustReleased(0, 38) and PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then + if CurrentAction == 'mecano_actions_menu' then + OpenMecanoActionsMenu() + end + if CurrentAction == 'mecano_harvest_menu' then + OpenMecanoHarvestMenu() + end + if CurrentAction == 'mecano_craft_menu' then + OpenMecanoCraftMenu() + end + if CurrentAction == 'delete_vehicle' then + local playerPed = GetPlayerPed(-1) + local vehicle = GetVehiclePedIsIn(playerPed, false) + local hash = GetEntityModel(vehicle) + if hash == GetHashKey('flatbed') or hash == GetHashKey('towtruck2') or hash == GetHashKey('slamvan3') then + if Config.MaxInService ~= -1 then + TriggerServerEvent('esx_service:disableService', 'mecano') + end + DeleteVehicle(vehicle) + else + ESX.ShowNotification('Vous ne pouvez ranger que des ~b~véhicules de Mécano~s~.') + end + end + if CurrentAction == 'remove_entity' then + DeleteEntity(CurrentActionData.entity) + end + CurrentAction = nil + end + end + + if IsControlJustReleased(0, 167) and PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then + OpenMobileMecanoActionsMenu() + end + end end) \ No newline at end of file diff --git a/esx_mecanojob/config.lua b/config.lua similarity index 96% rename from esx_mecanojob/config.lua rename to config.lua index b413d582..ffb65d2b 100644 --- a/esx_mecanojob/config.lua +++ b/config.lua @@ -1,42 +1,42 @@ -Config = {} -Config.DrawDistance = 100.0 -Config.MaxInService = -1 -Config.EnablePlayerManagement = true - -Config.Zones = { - - MecanoActions = { - Pos = {x = -205.90548706055, y = -1327.7248535156, z = 29.89040184021}, - Size = {x = 1.5, y = 1.5, z = 1.0}, - Color = {r = 204, g = 204, b = 0}, - Type = 1 - }, - - Garage = { - Pos = {x = -97.5797576904297, y = 6496.11376953125, z = 30.4909038543701}, - Size = {x = 1.5, y = 1.5, z = 1.0}, - Color = {r = 204, g = 204, b = 0}, - Type = 1 - }, - - Craft = { - Pos = {x = -196.51593017578, y = -1318.4403076172, z = 30.089345932007}, - Size = {x = 1.5, y = 1.5, z = 1.0}, - Color = {r = 204, g = 204, b = 0}, - Type = 1 - }, - - VehicleSpawnPoint = { - Pos = {x = -157.7899017334, y = -1305.8979492188, z = 30.348382949829}, - Size = {x = 1.5, y = 1.5, z = 1.0}, - Type = -1 - }, - - VehicleDeleter = { - Pos = {x = -182.78112792969, y = -1330.5368652344, z = 30.194892883301}, - Size = {x = 3.0, y = 3.0, z = 1.0}, - Color = {r = 204, g = 204, b = 0}, - Type = 1 - } - -} +Config = {} +Config.DrawDistance = 100.0 +Config.MaxInService = -1 +Config.EnablePlayerManagement = true + +Config.Zones = { + + MecanoActions = { + Pos = {x = -205.90548706055, y = -1327.7248535156, z = 29.89040184021}, + Size = {x = 1.5, y = 1.5, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Type = 1 + }, + + Garage = { + Pos = {x = -97.5797576904297, y = 6496.11376953125, z = 30.4909038543701}, + Size = {x = 1.5, y = 1.5, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Type = 1 + }, + + Craft = { + Pos = {x = -196.51593017578, y = -1318.4403076172, z = 30.089345932007}, + Size = {x = 1.5, y = 1.5, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Type = 1 + }, + + VehicleSpawnPoint = { + Pos = {x = -157.7899017334, y = -1305.8979492188, z = 30.348382949829}, + Size = {x = 1.5, y = 1.5, z = 1.0}, + Type = -1 + }, + + VehicleDeleter = { + Pos = {x = -182.78112792969, y = -1330.5368652344, z = 30.194892883301}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Type = 1 + } + +} diff --git a/esx_mecanojob/server/main.lua b/server/main.lua similarity index 96% rename from esx_mecanojob/server/main.lua rename to server/main.lua index fb6a325a..522ae568 100644 --- a/esx_mecanojob/server/main.lua +++ b/server/main.lua @@ -1,268 +1,268 @@ -ESX = nil -PlayersHarvesting = {} -PlayersHarvesting2 = {} -PlayersHarvesting3 = {} -PlayersCrafting = {} -PlayersCrafting2 = {} -PlayersCrafting3 = {} - -TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) - -if Config.MaxInService ~= -1 then - TriggerEvent('esx_service:activateService', 'mecano', Config.MaxInService) -end - -TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) - local xPlayers = ESX.GetPlayers() - - if phoneNumber == 'mecano' then - for k, v in pairs(xPlayers) do - if v.job.name == 'mecano' then - TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'Appel Mécano') - end - end - end -end) --------------- Récupération bouteille de gaz ------------- ----- Sqlut je teste ------ -local function Harvest(source) - - SetTimeout(4000, function() - - if PlayersHarvesting[source] == true then - - local xPlayer = ESX.GetPlayerFromId(source) - local GazBottleQuantity = xPlayer.getInventoryItem('gazbottle').count - - if GazBottleQuantity >= 5 then - TriggerClientEvent('esx:showNotification', source, '~r~Vous n\'avez plus de place') - else - xPlayer.addInventoryItem('gazbottle', 1) - - Harvest(source) - end - end - end) -end - -RegisterServerEvent('esx_mecanojob:startHarvest') -AddEventHandler('esx_mecanojob:startHarvest', function() - local _source = source - PlayersHarvesting[_source] = true - TriggerClientEvent('esx:showNotification', _source, 'Récupération de ~b~bouteille de gaz~s~...') - Harvest(source) -end) - -RegisterServerEvent('esx_mecanojob:stopHarvest') -AddEventHandler('esx_mecanojob:stopHarvest', function() - local _source = source - PlayersHarvesting[_source] = false -end) ------------- Récupération Outils Réparation -------------- -local function Harvest2(source) - - SetTimeout(4000, function() - - if PlayersHarvesting2[source] == true then - - local xPlayer = ESX.GetPlayerFromId(source) - local FixToolQuantity = xPlayer.getInventoryItem('fixtool').count - if FixToolQuantity >= 5 then - TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez ~r~plus de place') - else - xPlayer.addInventoryItem('fixtool', 1) - - Harvest2(source) - end - end - end) -end - -RegisterServerEvent('esx_mecanojob:startHarvest2') -AddEventHandler('esx_mecanojob:startHarvest2', function() - local _source = source - PlayersHarvesting2[_source] = true - TriggerClientEvent('esx:showNotification', _source, 'Récupération d\'~b~Outils réparation~s~...') - Harvest2(_source) -end) - -RegisterServerEvent('esx_mecanojob:stopHarvest2') -AddEventHandler('esx_mecanojob:stopHarvest2', function() - local _source = source - PlayersHarvesting2[_source] = false -end) ------------------ Récupération Outils Carosserie ---------------- -local function Harvest3(source) - - SetTimeout(4000, function() - - if PlayersHarvesting3[source] == true then - - local xPlayer = ESX.GetPlayerFromId(source) - local CaroToolQuantity = xPlayer.getInventoryItem('carotool').count - if CaroToolQuantity >= 5 then - TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez ~r~plus de place') - else - xPlayer.addInventoryItem('carotool', 1) - - Harvest3(source) - end - end - end) -end - -RegisterServerEvent('esx_mecanojob:startHarvest3') -AddEventHandler('esx_mecanojob:startHarvest3', function() - local _source = source - PlayersHarvesting3[_source] = true - TriggerClientEvent('esx:showNotification', _source, 'Récupération d\'~b~Outils carosserie~s~...') - Harvest3(_source) -end) - -RegisterServerEvent('esx_mecanojob:stopHarvest3') -AddEventHandler('esx_mecanojob:stopHarvest3', function() - local _source = source - PlayersHarvesting3[_source] = false -end) ------------- Craft Chalumeau ------------------- -local function Craft(source) - - SetTimeout(4000, function() - - if PlayersCrafting[source] == true then - - local xPlayer = ESX.GetPlayerFromId(source) - local GazBottleQuantity = xPlayer.getInventoryItem('gazbottle').count - - if GazBottleQuantity <= 0 then - TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez ~r~pas assez~s~ de bouteille de gaz') - else - xPlayer.removeInventoryItem('gazbottle', 1) - xPlayer.addInventoryItem('blowpipe', 1) - - Craft(source) - end - end - end) -end - -RegisterServerEvent('esx_mecanojob:startCraft') -AddEventHandler('esx_mecanojob:startCraft', function() - local _source = source - PlayersCrafting[_source] = true - TriggerClientEvent('esx:showNotification', _source, 'Assemblage de ~b~Chalumeaux~s~...') - Craft(_source) -end) - -RegisterServerEvent('esx_mecanojob:stopCraft') -AddEventHandler('esx_mecanojob:stopCraft', function() - local _source = source - PlayersCrafting[_source] = false -end) ------------- Craft kit Réparation -------------- -local function Craft2(source) - - SetTimeout(4000, function() - - if PlayersCrafting2[source] == true then - - local xPlayer = ESX.GetPlayerFromId(source) - local FixToolQuantity = xPlayer.getInventoryItem('fixtool').count - if FixToolQuantity <= 0 then - TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez ~r~pas assez~s~ d\'outils réparation') - else - xPlayer.removeInventoryItem('fixtool', 1) - xPlayer.addInventoryItem('fixkit', 1) - - Craft2(source) - end - end - end) -end - -RegisterServerEvent('esx_mecanojob:startCraft2') -AddEventHandler('esx_mecanojob:startCraft2', function() - local _source = source - PlayersCrafting2[_source] = true - TriggerClientEvent('esx:showNotification', _source, 'Assemblage de ~b~Kit réparation~s~...') - Craft2(_source) -end) - -RegisterServerEvent('esx_mecanojob:stopCraft2') -AddEventHandler('esx_mecanojob:stopCraft2', function() - local _source = source - PlayersCrafting2[_source] = false -end) ------------------ Craft kit Carosserie ---------------- -local function Craft3(source) - - SetTimeout(4000, function() - - if PlayersCrafting3[source] == true then - - local xPlayer = ESX.GetPlayerFromId(source) - local CaroToolQuantity = xPlayer.getInventoryItem('carotool').count - if CaroToolQuantity <= 0 then - TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez ~r~pas assez~s~ d\'outils carosserie') - else - xPlayer.removeInventoryItem('carotool', 1) - xPlayer.addInventoryItem('carokit', 1) - - Craft3(source) - end - end - end) -end - -RegisterServerEvent('esx_mecanojob:startCraft3') -AddEventHandler('esx_mecanojob:startCraft3', function() - local _source = source - PlayersCrafting3[_source] = true - TriggerClientEvent('esx:showNotification', _source, 'Assemblage de ~b~kit carosserie~s~...') - Craft3(_source) -end) - -RegisterServerEvent('esx_mecanojob:stopCraft3') -AddEventHandler('esx_mecanojob:stopCraft3', function() - local _source = source - PlayersCrafting3[_source] = false -end) - ----------------------------- register usable item -------------------------------------------------- -ESX.RegisterUsableItem('blowpipe', function(source) - - local _source = source - local xPlayer = ESX.GetPlayerFromId(source) - - xPlayer.removeInventoryItem('blowpipe', 1) - - TriggerClientEvent('esx_mecanojob:onHijack', _source) - TriggerClientEvent('esx:showNotification', _source, 'Vous avez utilisé un ~b~Chalumeau') - -end) - -ESX.RegisterUsableItem('fixkit', function(source) - - local _source = source - local xPlayer = ESX.GetPlayerFromId(source) - - xPlayer.removeInventoryItem('fixkit', 1) - - TriggerClientEvent('esx_mecanojob:onFixkit', _source) - TriggerClientEvent('esx:showNotification', _source, 'Vous avez utilisé un ~b~Kit de réparation') - -end) - -ESX.RegisterUsableItem('carokit', function(source) - - local _source = source - local xPlayer = ESX.GetPlayerFromId(source) - - xPlayer.removeInventoryItem('carokit', 1) - - TriggerClientEvent('esx_mecanojob:onCarokit', _source) - TriggerClientEvent('esx:showNotification', _source, 'Vous avez utilisé un ~b~Kit de carosserie') - +ESX = nil +PlayersHarvesting = {} +PlayersHarvesting2 = {} +PlayersHarvesting3 = {} +PlayersCrafting = {} +PlayersCrafting2 = {} +PlayersCrafting3 = {} + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +if Config.MaxInService ~= -1 then + TriggerEvent('esx_service:activateService', 'mecano', Config.MaxInService) +end + +TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) + local xPlayers = ESX.GetPlayers() + + if phoneNumber == 'mecano' then + for k, v in pairs(xPlayers) do + if v.job.name == 'mecano' then + TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'Appel Mécano') + end + end + end +end) +-------------- Récupération bouteille de gaz ------------- +---- Sqlut je teste ------ +local function Harvest(source) + + SetTimeout(4000, function() + + if PlayersHarvesting[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + local GazBottleQuantity = xPlayer.getInventoryItem('gazbottle').count + + if GazBottleQuantity >= 5 then + TriggerClientEvent('esx:showNotification', source, '~r~Vous n\'avez plus de place') + else + xPlayer.addInventoryItem('gazbottle', 1) + + Harvest(source) + end + end + end) +end + +RegisterServerEvent('esx_mecanojob:startHarvest') +AddEventHandler('esx_mecanojob:startHarvest', function() + local _source = source + PlayersHarvesting[_source] = true + TriggerClientEvent('esx:showNotification', _source, 'Récupération de ~b~bouteille de gaz~s~...') + Harvest(source) +end) + +RegisterServerEvent('esx_mecanojob:stopHarvest') +AddEventHandler('esx_mecanojob:stopHarvest', function() + local _source = source + PlayersHarvesting[_source] = false +end) +------------ Récupération Outils Réparation -------------- +local function Harvest2(source) + + SetTimeout(4000, function() + + if PlayersHarvesting2[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + local FixToolQuantity = xPlayer.getInventoryItem('fixtool').count + if FixToolQuantity >= 5 then + TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez ~r~plus de place') + else + xPlayer.addInventoryItem('fixtool', 1) + + Harvest2(source) + end + end + end) +end + +RegisterServerEvent('esx_mecanojob:startHarvest2') +AddEventHandler('esx_mecanojob:startHarvest2', function() + local _source = source + PlayersHarvesting2[_source] = true + TriggerClientEvent('esx:showNotification', _source, 'Récupération d\'~b~Outils réparation~s~...') + Harvest2(_source) +end) + +RegisterServerEvent('esx_mecanojob:stopHarvest2') +AddEventHandler('esx_mecanojob:stopHarvest2', function() + local _source = source + PlayersHarvesting2[_source] = false +end) +----------------- Récupération Outils Carosserie ---------------- +local function Harvest3(source) + + SetTimeout(4000, function() + + if PlayersHarvesting3[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + local CaroToolQuantity = xPlayer.getInventoryItem('carotool').count + if CaroToolQuantity >= 5 then + TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez ~r~plus de place') + else + xPlayer.addInventoryItem('carotool', 1) + + Harvest3(source) + end + end + end) +end + +RegisterServerEvent('esx_mecanojob:startHarvest3') +AddEventHandler('esx_mecanojob:startHarvest3', function() + local _source = source + PlayersHarvesting3[_source] = true + TriggerClientEvent('esx:showNotification', _source, 'Récupération d\'~b~Outils carosserie~s~...') + Harvest3(_source) +end) + +RegisterServerEvent('esx_mecanojob:stopHarvest3') +AddEventHandler('esx_mecanojob:stopHarvest3', function() + local _source = source + PlayersHarvesting3[_source] = false +end) +------------ Craft Chalumeau ------------------- +local function Craft(source) + + SetTimeout(4000, function() + + if PlayersCrafting[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + local GazBottleQuantity = xPlayer.getInventoryItem('gazbottle').count + + if GazBottleQuantity <= 0 then + TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez ~r~pas assez~s~ de bouteille de gaz') + else + xPlayer.removeInventoryItem('gazbottle', 1) + xPlayer.addInventoryItem('blowpipe', 1) + + Craft(source) + end + end + end) +end + +RegisterServerEvent('esx_mecanojob:startCraft') +AddEventHandler('esx_mecanojob:startCraft', function() + local _source = source + PlayersCrafting[_source] = true + TriggerClientEvent('esx:showNotification', _source, 'Assemblage de ~b~Chalumeaux~s~...') + Craft(_source) +end) + +RegisterServerEvent('esx_mecanojob:stopCraft') +AddEventHandler('esx_mecanojob:stopCraft', function() + local _source = source + PlayersCrafting[_source] = false +end) +------------ Craft kit Réparation -------------- +local function Craft2(source) + + SetTimeout(4000, function() + + if PlayersCrafting2[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + local FixToolQuantity = xPlayer.getInventoryItem('fixtool').count + if FixToolQuantity <= 0 then + TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez ~r~pas assez~s~ d\'outils réparation') + else + xPlayer.removeInventoryItem('fixtool', 1) + xPlayer.addInventoryItem('fixkit', 1) + + Craft2(source) + end + end + end) +end + +RegisterServerEvent('esx_mecanojob:startCraft2') +AddEventHandler('esx_mecanojob:startCraft2', function() + local _source = source + PlayersCrafting2[_source] = true + TriggerClientEvent('esx:showNotification', _source, 'Assemblage de ~b~Kit réparation~s~...') + Craft2(_source) +end) + +RegisterServerEvent('esx_mecanojob:stopCraft2') +AddEventHandler('esx_mecanojob:stopCraft2', function() + local _source = source + PlayersCrafting2[_source] = false +end) +----------------- Craft kit Carosserie ---------------- +local function Craft3(source) + + SetTimeout(4000, function() + + if PlayersCrafting3[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + local CaroToolQuantity = xPlayer.getInventoryItem('carotool').count + if CaroToolQuantity <= 0 then + TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez ~r~pas assez~s~ d\'outils carosserie') + else + xPlayer.removeInventoryItem('carotool', 1) + xPlayer.addInventoryItem('carokit', 1) + + Craft3(source) + end + end + end) +end + +RegisterServerEvent('esx_mecanojob:startCraft3') +AddEventHandler('esx_mecanojob:startCraft3', function() + local _source = source + PlayersCrafting3[_source] = true + TriggerClientEvent('esx:showNotification', _source, 'Assemblage de ~b~kit carosserie~s~...') + Craft3(_source) +end) + +RegisterServerEvent('esx_mecanojob:stopCraft3') +AddEventHandler('esx_mecanojob:stopCraft3', function() + local _source = source + PlayersCrafting3[_source] = false +end) + +---------------------------- register usable item -------------------------------------------------- +ESX.RegisterUsableItem('blowpipe', function(source) + + local _source = source + local xPlayer = ESX.GetPlayerFromId(source) + + xPlayer.removeInventoryItem('blowpipe', 1) + + TriggerClientEvent('esx_mecanojob:onHijack', _source) + TriggerClientEvent('esx:showNotification', _source, 'Vous avez utilisé un ~b~Chalumeau') + +end) + +ESX.RegisterUsableItem('fixkit', function(source) + + local _source = source + local xPlayer = ESX.GetPlayerFromId(source) + + xPlayer.removeInventoryItem('fixkit', 1) + + TriggerClientEvent('esx_mecanojob:onFixkit', _source) + TriggerClientEvent('esx:showNotification', _source, 'Vous avez utilisé un ~b~Kit de réparation') + +end) + +ESX.RegisterUsableItem('carokit', function(source) + + local _source = source + local xPlayer = ESX.GetPlayerFromId(source) + + xPlayer.removeInventoryItem('carokit', 1) + + TriggerClientEvent('esx_mecanojob:onCarokit', _source) + TriggerClientEvent('esx:showNotification', _source, 'Vous avez utilisé un ~b~Kit de carosserie') + end) \ No newline at end of file From 05ea4d2de6dfe25ed41a58707a40eeadcfe6f486 Mon Sep 17 00:00:00 2001 From: ig0ne Date: Thu, 10 Aug 2017 02:44:44 +0200 Subject: [PATCH 0254/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..2967f0af --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver_esx_holdup +FXserver ESX Hold Up From 64969144c9f84eb0c7fa8f313f4deb05e6061e92 Mon Sep 17 00:00:00 2001 From: ig0ne Date: Thu, 10 Aug 2017 02:45:41 +0200 Subject: [PATCH 0255/3224] Add files via upload --- esx_holdup/__resource.lua | 11 +++ esx_holdup/client/esx_holdup_cl.lua | 142 ++++++++++++++++++++++++++++ esx_holdup/config.lua | 50 ++++++++++ esx_holdup/server/esx_holdup_sv.lua | 102 ++++++++++++++++++++ 4 files changed, 305 insertions(+) create mode 100644 esx_holdup/__resource.lua create mode 100644 esx_holdup/client/esx_holdup_cl.lua create mode 100644 esx_holdup/config.lua create mode 100644 esx_holdup/server/esx_holdup_sv.lua diff --git a/esx_holdup/__resource.lua b/esx_holdup/__resource.lua new file mode 100644 index 00000000..6bc532a3 --- /dev/null +++ b/esx_holdup/__resource.lua @@ -0,0 +1,11 @@ +dependency 'essentialmode' + +client_script { + 'config.lua', + 'client/esx_holdup_cl.lua' +} + +server_script { + 'config.lua', + 'server/esx_holdup_sv.lua' +} diff --git a/esx_holdup/client/esx_holdup_cl.lua b/esx_holdup/client/esx_holdup_cl.lua new file mode 100644 index 00000000..684625bd --- /dev/null +++ b/esx_holdup/client/esx_holdup_cl.lua @@ -0,0 +1,142 @@ +local holdingup = false +local store = "" +local secondsRemaining = 0 +local blipRobbery = nil +ESX = nil + +Citizen.CreateThread(function() + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end +end) + +function DisplayHelpText(str) + SetTextComponentFormat("STRING") + AddTextComponentString(str) + DisplayHelpTextFromStringLabel(0, 0, 1, -1) +end + +function drawTxt(x,y ,width,height,scale, text, r,g,b,a, outline) + SetTextFont(0) + SetTextProportional(0) + SetTextScale(scale, scale) + SetTextColour(r, g, b, a) + SetTextDropShadow(0, 0, 0, 0,255) + SetTextEdge(1, 0, 0, 0, 255) + SetTextDropShadow() + if(outline)then + SetTextOutline() + end + SetTextEntry("STRING") + AddTextComponentString(text) + DrawText(x - width/2, y - height/2 + 0.005) +end + +RegisterNetEvent('esx_holdup:currentlyrobbing') +AddEventHandler('esx_holdup:currentlyrobbing', function(robb) + holdingup = true + store = robb + secondsRemaining = 300 +end) + +RegisterNetEvent('esx_holdup:killblip') +AddEventHandler('esx_holdup:killblip', function() + RemoveBlip(blipRobbery) +end) + +RegisterNetEvent('esx_holdup:setblip') +AddEventHandler('esx_holdup:setblip', function(position) + blipRobbery = AddBlipForCoord(position.x, position.y, position.z) + SetBlipSprite(blipRobbery , 161) + SetBlipScale(blipRobbery , 2.0) + SetBlipColour(blipRobbery, 3) + PulseBlip(blipRobbery) +end) + +RegisterNetEvent('esx_holdup:toofarlocal') +AddEventHandler('esx_holdup:toofarlocal', function(robb) + holdingup = false + ESX.ShowNotification('Le braquage vas être annulé, vous ne gagnerez rien!') + robbingName = "" + secondsRemaining = 0 + incircle = false +end) + + +RegisterNetEvent('esx_holdup:robberycomplete') +AddEventHandler('esx_holdup:robberycomplete', function(robb) + holdingup = false + ESX.ShowNotification('Braquage réussi vous avez gagné ~g~$' .. Stores[store].reward) + store = "" + secondsRemaining = 0 + incircle = false +end) + +Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + if holdingup then + Citizen.Wait(1000) + if(secondsRemaining > 0)then + secondsRemaining = secondsRemaining - 1 + end + end + end +end) + +Citizen.CreateThread(function() + for k,v in pairs(Stores)do + local ve = v.position + + local blip = AddBlipForCoord(ve.x, ve.y, ve.z) + SetBlipSprite(blip, 156) + SetBlipScale(blip, 0.8) + SetBlipAsShortRange(blip, true) + BeginTextCommandSetBlipName("STRING") + AddTextComponentString("Braquage magasin") + EndTextCommandSetBlipName(blip) + end +end) +incircle = false + +Citizen.CreateThread(function() + while true do + local pos = GetEntityCoords(GetPlayerPed(-1), true) + + for k,v in pairs(Stores)do + local pos2 = v.position + + if(Vdist(pos.x, pos.y, pos.z, pos2.x, pos2.y, pos2.z) < 15.0)then + if not holdingup then + DrawMarker(1, v.position.x, v.position.y, v.position.z - 1, 0, 0, 0, 0, 0, 0, 1.0001, 1.0001, 1.5001, 1555, 0, 0,255, 0, 0, 0,0) + + if(Vdist(pos.x, pos.y, pos.z, pos2.x, pos2.y, pos2.z) < 1.0)then + if (incircle == false) then + DisplayHelpText("Appuyer sur ~INPUT_CONTEXT~ pour braquer ~b~" .. v.nameofstore) + end + incircle = true + if IsControlJustReleased(1, 51) then + TriggerServerEvent('esx_holdup:rob', k) + end + elseif(Vdist(pos.x, pos.y, pos.z, pos2.x, pos2.y, pos2.z) > 1.0)then + incircle = false + end + end + end + end + + if holdingup then + + drawTxt(0.66, 1.44, 1.0,1.0,0.4, "Braquage de magasin: ~r~" .. secondsRemaining .. "~w~ secondes restantes", 255, 255, 255, 255) + + local pos2 = Stores[store].position + + if(Vdist(pos.x, pos.y, pos.z, pos2.x, pos2.y, pos2.z) > 7.5)then + TriggerServerEvent('esx_holdup:toofar', store) + end + end + + Citizen.Wait(0) + end +end) diff --git a/esx_holdup/config.lua b/esx_holdup/config.lua new file mode 100644 index 00000000..a740c8ba --- /dev/null +++ b/esx_holdup/config.lua @@ -0,0 +1,50 @@ +Stores = { + --[["paleto_twentyfourseven"] = { + position = { ['x'] = 1736.32092285156, ['y'] = 6419.4970703125, ['z'] = 35.037223815918 }, + reward = math.random(100,1000), + nameofstore = "24/7. (Paleto Bay)", + lastrobbed = 0 + },]] + ["sandyshores_twentyfoursever"] = { + position = { ['x'] = 1961.24682617188, ['y'] = 3749.46069335938, ['z'] = 32.3437461853027 }, + reward = math.random(500,5000), + nameofstore = "24/7. (Sandy Shores)", + lastrobbed = 0 + }, + ["bar_one"] = { + position = { ['x'] = 1986.1240234375, ['y'] = 3053.8747558594, ['z'] = 47.215171813965 }, + reward = math.random(500,5000), + nameofstore = "Yellow Jack. (Sandy Shores)", + lastrobbed = 0 + }, + ["ocean_liquor"] = { + position = { ['x'] = -2959.33715820313, ['y'] = 388.214172363281, ['z'] = 14.0432071685791 }, + reward = math.random(1000,10000), + nameofstore = "Robs Liquor. (Great Ocean Higway)", + lastrobbed = 0 + }, + ["sanandreas_liquor"] = { + position = { ['x'] = -1219.85607910156, ['y'] = -916.276550292969, ['z'] = 11.3262157440186 }, + reward = math.random(1000,10000), + nameofstore = "Robs Liquor. (San andreas Avenue)", + lastrobbed = 0 + }, + ["grove_ltd"] = { + position = { ['x'] = -43.4035377502441, ['y'] = -1749.20922851563, ['z'] = 29.421012878418 }, + reward = math.random(1000,10000), + nameofstore = "LTD Gasoline. (Grove Street)", + lastrobbed = 0 + }, + ["mirror_ltd"] = { + position = { ['x'] = 1160.67578125, ['y'] = -314.400451660156, ['z'] = 69.2050552368164 }, + reward = math.random(1000,10000), + nameofstore = "LTD Gasoline. (Mirror Park Boulevard)", + lastrobbed = 0 + }, + ["littleseoul_twentyfourseven"] = { + position = { ['x'] = -709.17022705078, ['y'] = -904.21722412109, ['z'] = 19.215591430664 }, + reward = math.random(1000,10000), + nameofstore = "24/7. (Little Seoul)", + lastrobbed = 0 + } +} \ No newline at end of file diff --git a/esx_holdup/server/esx_holdup_sv.lua b/esx_holdup/server/esx_holdup_sv.lua new file mode 100644 index 00000000..b81ff260 --- /dev/null +++ b/esx_holdup/server/esx_holdup_sv.lua @@ -0,0 +1,102 @@ +local rob = false +local robbers = {} +ESX = nil + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +function get3DDistance(x1, y1, z1, x2, y2, z2) + return math.sqrt(math.pow(x1 - x2, 2) + math.pow(y1 - y2, 2) + math.pow(z1 - z2, 2)) +end + +RegisterServerEvent('esx_holdup:toofar') +AddEventHandler('esx_holdup:toofar', function(robb) + local source = source + local xPlayers = ESX.GetPlayers() + rob = false + for k, v in pairs(xPlayers) do + if v.job.name == 'police' then + TriggerClientEvent('esx:showNotification', k, '~r~ Braquage annulé à: ~b~' .. Stores[robb].nameofstore) + TriggerClientEvent('esx_holdup:killblip', k) + end + end + if(robbers[source])then + TriggerClientEvent('esx_holdup:toofarlocal', source) + robbers[source] = nil + TriggerClientEvent('esx:showNotification', source, '~r~ Le braquage à été annulé: ~b~' .. Stores[robb].nameofstore) + end +end) + +RegisterServerEvent('esx_holdup:rob') +AddEventHandler('esx_holdup:rob', function(robb) + + local source = source + local xPlayer = ESX.GetPlayerFromId(source) + local xPlayers = ESX.GetPlayers() + + if Stores[robb] then + + local store = Stores[robb] + + if (os.time() - store.lastrobbed) < 600 and store.lastrobbed ~= 0 then + + + TriggerClientEvent('esx:showNotification', source, 'Ce magasin a déjà été braqué. Veuillez attendre: ' .. (1800 - (os.time() - store.lastrobbed)) .. "secondes.") + return + end + + + local cops = 0 + for k, v in pairs(xPlayers) do + if v.job.name == 'police' then + cops = cops + 1 + end + end + + + if rob == false then + + if(cops > 1)then + + rob = true + for k, v in pairs(xPlayers) do + if v.job.name == 'police' then + TriggerClientEvent('esx:showNotification', k, '~r~ Braquage en cours à: ~b~' .. store.nameofstore) + TriggerClientEvent('esx_holdup:setblip', k, Stores[robb].position) + end + end + + TriggerClientEvent('esx:showNotification', source, 'Vous avez commencé à braquer ' .. store.nameofstore .. ', ne vous éloignez pas!') + TriggerClientEvent('esx:showNotification', source, 'L\'alarme à été déclenché ') + TriggerClientEvent('esx:showNotification', source, 'Tenez la position pendant 5min et l\'argent est à vous! ') + TriggerClientEvent('esx_holdup:currentlyrobbing', source, robb) + Stores[robb].lastrobbed = os.time() + robbers[source] = robb + local savedSource = source + SetTimeout(300000, function() + + if(robbers[savedSource])then + + rob = false + TriggerClientEvent('esx_holdup:robberycomplete', savedSource, job) + if(xPlayer)then + + xPlayer.addAccountMoney('black_money', store.reward) + TriggerClientEvent('esx:showNotification', source, '~r~ Braquage terminé.~s~ ~h~ Fuie!') + for k, v in pairs(xPlayers) do + if v.job.name == 'police' then + TriggerClientEvent('esx:showNotification', k, '~r~ Braquage terminé à: ~b~' .. store.nameofstore) + TriggerClientEvent('esx_holdup:killblip', k) + end + end + + end + end + end) + else + TriggerClientEvent('esx:showNotification', source, 'Il faut minimum ~b~2 policiers~s~ en ville pour braquer.') + end + else + TriggerClientEvent('esx:showNotification', source, '~r~Un braquage est déjà en cours.') + end + end +end) \ No newline at end of file From 4b2699cdf8e5aae94f2b4e59afc0bfd1c7446825 Mon Sep 17 00:00:00 2001 From: ig0ne Date: Thu, 10 Aug 2017 02:49:42 +0200 Subject: [PATCH 0256/3224] Update README.md --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index 2967f0af..631b0713 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,20 @@ # fxserver_esx_holdup FXserver ESX Hold Up + +[REQUIREMENTS] + + * esx_policejob => https://github.com/FXServer-ESX/fxserver-esx_policejob + +[INSTALLATION] + +1) CD in your resources/[esx] folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver_esx_holdup esx_holdup +``` + +3) Add this in your server.cfg : + +``` +start esx_holdup +``` From 48b57a1494c5cad96943782c4afde30c835c2c77 Mon Sep 17 00:00:00 2001 From: ig0ne Date: Thu, 10 Aug 2017 07:27:33 +0200 Subject: [PATCH 0257/3224] Rename esx_holdup/config.lua to config.lua --- esx_holdup/config.lua => config.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename esx_holdup/config.lua => config.lua (97%) diff --git a/esx_holdup/config.lua b/config.lua similarity index 97% rename from esx_holdup/config.lua rename to config.lua index a740c8ba..36d3e732 100644 --- a/esx_holdup/config.lua +++ b/config.lua @@ -47,4 +47,4 @@ Stores = { nameofstore = "24/7. (Little Seoul)", lastrobbed = 0 } -} \ No newline at end of file +} From f423afe14d557c3a39f5adcac567a6981ce33202 Mon Sep 17 00:00:00 2001 From: ig0ne Date: Thu, 10 Aug 2017 07:28:16 +0200 Subject: [PATCH 0258/3224] Rename esx_holdup/__resource.lua to __resource.lua --- esx_holdup/__resource.lua => __resource.lua | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename esx_holdup/__resource.lua => __resource.lua (100%) diff --git a/esx_holdup/__resource.lua b/__resource.lua similarity index 100% rename from esx_holdup/__resource.lua rename to __resource.lua From f8798a8c2ecf373145eb52c2d26072c0e6128405 Mon Sep 17 00:00:00 2001 From: ig0ne Date: Thu, 10 Aug 2017 07:28:46 +0200 Subject: [PATCH 0259/3224] Rename esx_holdup/client/esx_holdup_cl.lua to client/esx_holdup_cl.lua --- {esx_holdup/client => client}/esx_holdup_cl.lua | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {esx_holdup/client => client}/esx_holdup_cl.lua (100%) diff --git a/esx_holdup/client/esx_holdup_cl.lua b/client/esx_holdup_cl.lua similarity index 100% rename from esx_holdup/client/esx_holdup_cl.lua rename to client/esx_holdup_cl.lua From eb7bcf36eba7da758c6508e8db23b2f296fd4123 Mon Sep 17 00:00:00 2001 From: ig0ne Date: Thu, 10 Aug 2017 07:29:11 +0200 Subject: [PATCH 0260/3224] Rename esx_holdup/server/esx_holdup_sv.lua to server/esx_holdup_sv.lua --- {esx_holdup/server => server}/esx_holdup_sv.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename {esx_holdup/server => server}/esx_holdup_sv.lua (96%) diff --git a/esx_holdup/server/esx_holdup_sv.lua b/server/esx_holdup_sv.lua similarity index 96% rename from esx_holdup/server/esx_holdup_sv.lua rename to server/esx_holdup_sv.lua index b81ff260..f58e3f49 100644 --- a/esx_holdup/server/esx_holdup_sv.lua +++ b/server/esx_holdup_sv.lua @@ -99,4 +99,4 @@ AddEventHandler('esx_holdup:rob', function(robb) TriggerClientEvent('esx:showNotification', source, '~r~Un braquage est déjà en cours.') end end -end) \ No newline at end of file +end) From eba26ffd18407da30e1f223fcefe2f3c88df2059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 10 Aug 2017 09:38:35 +0200 Subject: [PATCH 0261/3224] Remove money when buying property --- server/main.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/main.lua b/server/main.lua index 415d3044..2f586956 100644 --- a/server/main.lua +++ b/server/main.lua @@ -36,6 +36,8 @@ AddEventHandler('esx_realestateagentjob:sell', function(target, property, price) local xPlayer = ESX.GetPlayerFromId(target) + xPlayer.removeMoney(price) + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_realestateagent', function(account) account.addMoney(price) end) From 5b97605431b06c31396d162383127e8d49d8bfdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 10 Aug 2017 18:15:32 +0200 Subject: [PATCH 0262/3224] Add exports, Config.Locale and some functions --- .../[essential]/es_extended/__resource.lua | 13 ++++++++ .../[essential]/es_extended/client/common.lua | 7 +++++ .../es_extended/client/functions.lua | 31 ++++++++++++++++--- resources/[essential]/es_extended/config.lua | 1 + .../[essential]/es_extended/server/common.lua | 4 +++ .../es_extended/server/functions.lua | 4 +++ .../[essential]/es_extended/server/main.lua | 7 +++++ 7 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 resources/[essential]/es_extended/client/common.lua diff --git a/resources/[essential]/es_extended/__resource.lua b/resources/[essential]/es_extended/__resource.lua index 4157559d..005516e5 100644 --- a/resources/[essential]/es_extended/__resource.lua +++ b/resources/[essential]/es_extended/__resource.lua @@ -15,6 +15,7 @@ server_scripts { client_scripts { 'config.lua', + 'client/common.lua', 'client/functions.lua', 'client/main.lua' } @@ -41,4 +42,16 @@ files { 'html/img/accounts/bank.png', 'html/img/accounts/black_money.png' +} + +exports { + 'getSharedObject' +} + +server_exports { + 'getSharedObject' +} + +dependencies { + 'essentialmode' } \ No newline at end of file diff --git a/resources/[essential]/es_extended/client/common.lua b/resources/[essential]/es_extended/client/common.lua new file mode 100644 index 00000000..26c0ed40 --- /dev/null +++ b/resources/[essential]/es_extended/client/common.lua @@ -0,0 +1,7 @@ +AddEventHandler('esx:getSharedObject', function(cb) + cb(ESX) +end) + +function getSharedObject() + return ESX +end diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 7f3d273b..18f52c63 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -17,6 +17,10 @@ ESX.UI.Menu.Opened = {} ESX.Game = {} ESX.Game.Utils = {} +ESX.GetConfig = function() + return Config +end + ESX.GetRandomString = function(length) math.randomseed(GetGameTimer()) @@ -123,6 +127,8 @@ end ESX.UI.Menu.RegisterType = function(type, open, close) + print('ESX.UI.Menu.RegisterType => ' .. type) + ESX.UI.Menu.RegisteredTypes[type] = { open = open, close = close, @@ -749,6 +755,27 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) end +ESX.Game.TeleportEntity = function(entity, coords, cb) + + Citizen.CreateThread(function() + + RequestCollisionAtCoord(coords.x, coords.y, coords.z) + + while not HasCollisionLoadedAroundEntity(entity) do + RequestCollisionAtCoord(coords.x, coords.y, coords.z) + Citizen.Wait(0) + end + + SetEntityCoords(entity, coords.x, coords.y, coords.z) + + if cb ~= nil then + cb() + end + + end) + +end + ESX.Game.Utils.DrawText3D = function(coords, text, size) local onScreen, x, y = World3dToScreen2d(coords.x, coords.y, coords.z) @@ -967,10 +994,6 @@ ESX.ShowInventory = function() end -AddEventHandler('esx:getSharedObject', function(cb) - cb(ESX) -end) - RegisterNetEvent('esx:serverCallback') AddEventHandler('esx:serverCallback', function(requestId, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z) ESX.ServerCallbacks[requestId](a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z) diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua index 2c891417..f1d53a77 100644 --- a/resources/[essential]/es_extended/config.lua +++ b/resources/[essential]/es_extended/config.lua @@ -6,6 +6,7 @@ Config.PaycheckInterval = 7 * 60000 Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true Config.RemoveInventoryItemDelay = 5 * 60000 +Config.Locale = 'fr_FR' Config.Weapons = { diff --git a/resources/[essential]/es_extended/server/common.lua b/resources/[essential]/es_extended/server/common.lua index 06d8f8af..b001fcaa 100644 --- a/resources/[essential]/es_extended/server/common.lua +++ b/resources/[essential]/es_extended/server/common.lua @@ -9,6 +9,10 @@ AddEventHandler('esx:getSharedObject', function(cb) cb(ESX) end) +function getSharedObject() + return ESX +end + AddEventHandler('onMySQLReady', function () MySQL.Async.fetchAll( diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index b1001dba..f3a25eea 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -4,6 +4,10 @@ for i = 48, 57 do table.insert(Charset, string.char(i)) end for i = 65, 90 do table.insert(Charset, string.char(i)) end for i = 97, 122 do table.insert(Charset, string.char(i)) end +ESX.GetConfig = function() + return Config +end + ESX.GetRandomString = function(length) math.randomseed(os.time()) diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index 5f86cd94..2523e3e8 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -279,6 +279,13 @@ AddEventHandler('esx:updateLoadout', function(loadout) xPlayer.loadout = loadout end) +RegisterServerEvent('esx:updateLastPosition') +AddEventHandler('esx:updateLastPosition', function(position) + local xPlayer = ESX.GetPlayerFromId(source) + xPlayer.lastPosition = position +end) + + RegisterServerEvent('esx:giveInventoryItem') AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCount) From 47d51c0fdf30df1af3c53bc57490c894f6f0469f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 10 Aug 2017 18:16:12 +0200 Subject: [PATCH 0263/3224] Remove debug code --- resources/[essential]/es_extended/client/functions.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 18f52c63..d2eb5fe4 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -126,8 +126,6 @@ ESX.UI.HUD.UpdateElement = function(name, data) end ESX.UI.Menu.RegisterType = function(type, open, close) - - print('ESX.UI.Menu.RegisterType => ' .. type) ESX.UI.Menu.RegisteredTypes[type] = { open = open, From 3fbbffa86ed80a1c05f18eb989063d6af3d551e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 10 Aug 2017 18:16:54 +0200 Subject: [PATCH 0264/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..1d7f5960 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_ambulancejob +FXServer ESX Ambulance Job From 5fa079bcee254db14c2ce1b02d25abce2a5e6f17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 10 Aug 2017 18:19:16 +0200 Subject: [PATCH 0265/3224] Update README.md --- README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/README.md b/README.md index 1d7f5960..fb224cbe 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,28 @@ # fxserver-esx_ambulancejob FXServer ESX Ambulance Job + +[REQUIREMENTS] + +* Auto mode + - esx_skin => https://github.com/FXServer-ESX/fxserver-esx_skin + +* Player management (boss actions **There is no way to earn money for now**) + * esx_society => https://github.com/FXServer-ESX/fxserver-esx_society + +[INSTALLATION] + +1) CD in your resources/[esx] folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-esx_ambulancejob esx_ambulancejob +``` +3) * Auto mode : Import esx_ambulancejob_minimal.sql in your database + * Player / Armory management : Import esx_ambulancejob_full.sql in your database + +4) Add this in your server.cfg : + +``` +start esx_ambulancejob +``` +5) * If you want player management you have to set Config.EnablePlayerManagement to true in config.lua + From 35b91603b38355ada38dbac11ab8ac77b641d292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 10 Aug 2017 18:20:07 +0200 Subject: [PATCH 0266/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fb224cbe..73b28889 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ FXServer ESX Ambulance Job git clone https://github.com/FXServer-ESX/fxserver-esx_ambulancejob esx_ambulancejob ``` 3) * Auto mode : Import esx_ambulancejob_minimal.sql in your database - * Player / Armory management : Import esx_ambulancejob_full.sql in your database + * Player management : Import esx_ambulancejob_full.sql in your database 4) Add this in your server.cfg : From c7f2c27e118754bff91de06fd8202f77fecaa942 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 10 Aug 2017 19:04:22 +0200 Subject: [PATCH 0267/3224] Add setInventoryItem + better weapon management --- .../es_extended/server/classes/player.lua | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/resources/[essential]/es_extended/server/classes/player.lua b/resources/[essential]/es_extended/server/classes/player.lua index 954dcf63..107960e7 100644 --- a/resources/[essential]/es_extended/server/classes/player.lua +++ b/resources/[essential]/es_extended/server/classes/player.lua @@ -300,6 +300,22 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end + self.setInventoryItem = function(name, count) + + local item = self.getInventoryItem(name) + local oldCount = item.count + item.count = count + + if oldCount > item.count then + TriggerEvent("esx:onRemoveInventoryItem", self.source, item, oldCount - item.count ) + TriggerClientEvent("esx:removeInventoryItem", self.source, item, oldCount - item.count ) + else + TriggerEvent("esx:onAddInventoryItem", self.source, item, item.count - oldCount) + TriggerClientEvent("esx:addInventoryItem", self.source, item, item.count - oldCount) + end + + end + self.setJob = function(name, grade) MySQL.Async.fetchAll( @@ -358,6 +374,22 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end end + local foundWeapon = false + + for i=1, #self.loadout, 1 do + if self.loadout[i].name == weaponName then + foundWeapon = true + end + end + + if not foundWeapon then + table.insert(self.loadout, { + name = weaponName, + ammo = ammon, + label = weaponLabel + }) + end + TriggerClientEvent('esx:addWeapon', self.source, weaponName, ammo) TriggerClientEvent("esx:addInventoryItem", self.source, {label = weaponLabel}, 1) end @@ -373,6 +405,15 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end end + local foundWeapon = false + + for i=1, #self.loadout, 1 do + if self.loadout[i].name == weaponName then + table.remove(self.loadout, i) + break + end + end + TriggerClientEvent('esx:removeWeapon', self.source, weaponName) TriggerClientEvent("esx:removeInventoryItem", self.source, {label = weaponLabel}, 1) end From d66c20c6772c506bb708ea794f0151031d99205d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 10 Aug 2017 19:11:31 +0200 Subject: [PATCH 0268/3224] Add files --- __resource.lua | 14 + client/main.lua | 675 +++++++++++++++++++++++++++++++++++ config.lua | 74 ++++ esx_ambulancejob_full.sql | 16 + esx_ambulancejob_minimal.sql | 12 + server/main.lua | 35 ++ 6 files changed, 826 insertions(+) create mode 100644 __resource.lua create mode 100644 client/main.lua create mode 100644 config.lua create mode 100644 esx_ambulancejob_full.sql create mode 100644 esx_ambulancejob_minimal.sql create mode 100644 server/main.lua diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..d181aa85 --- /dev/null +++ b/__resource.lua @@ -0,0 +1,14 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'ESX Ambulance Job' + +server_scripts { + '@mysql-async/lib/MySQL.lua', + 'config.lua', + 'server/main.lua' +} + +client_scripts { + 'config.lua', + 'client/main.lua' +} diff --git a/client/main.lua b/client/main.lua new file mode 100644 index 00000000..30b5ae82 --- /dev/null +++ b/client/main.lua @@ -0,0 +1,675 @@ +DoScreenFadeIn(0) + +local Keys = { + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, + ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, + ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, + ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, + ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 +} + +ESX = nil +local GUI = {} +GUI.Time = 0 +local PlayerData = {} +local FirstSpawn = true +local IsDead = false +local HasAlreadyEnteredMarker = false +local LastZone = nil +local CurrentAction = nil +local CurrentActionMsg = '' +local CurrentActionData = {} + +Citizen.CreateThread(function() + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end +end) + +function RespawnPed(ped, coords) + SetEntityCoordsNoOffset(ped, coords.x, coords.y, coords.z, false, false, false, true) + NetworkResurrectLocalPlayer(coords.x, coords.y, coords.z, coords.heading, true, false) + SetPlayerInvincible(ped, false) + TriggerEvent('playerSpawned', coords.x, coords.y, coords.z, coords.heading) + ClearPedBloodDamage(ped) +end + +function StartRespawnTimer() + + ESX.SetTimeout(Config.RespawnDelayAfterRPDeath, function() + + if IsDead then + + Citizen.CreateThread(function() + + DoScreenFadeOut(800) + + while not IsScreenFadedOut() do + Citizen.Wait(0) + end + + ESX.TriggerServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function() + + TriggerServerEvent('esx:updateLastPosition', Config.Zones.HospitalInteriorInside1.Pos) + + RespawnPed(GetPlayerPed(-1), Config.Zones.HospitalInteriorInside1.Pos) + StopScreenEffect('DeathFailOut') + DoScreenFadeIn(800) + end) + + end) + end + + end) + +end + +function TeleportFadeEffect(entity, coords) + + Citizen.CreateThread(function() + + DoScreenFadeOut(800) + + while not IsScreenFadedOut() do + Citizen.Wait(0) + end + + ESX.Game.TeleportEntity(entity, coords, function() + DoScreenFadeIn(800) + end) + + end) + +end + +function WarpPedInClosestVehicle(ped) + + local coords = GetEntityCoords(ped) + + local vehicle, distance = ESX.Game.GetClosestVehicle({ + x = coords.x, + y = coords.y, + z = coords.z + }) + + if distance ~= -1 and distance <= 5.0 then + + local maxSeats = GetVehicleMaxNumberOfPassengers(vehicle) + local freeSeat = nil + + for i=maxSeats - 1, 0, -1 do + if IsVehicleSeatFree(vehicle, i) then + freeSeat = i + break + end + end + + if freeSeat ~= nil then + TaskWarpPedIntoVehicle(ped, vehicle, freeSeat) + end + + else + ESX.ShowNotification('Aucun véhicule à proximité') + end + +end + +function OpenAmbulanceActionsMenu() + + local elements = { + {label = 'Vestiaire', value = 'cloakroom'} + } + + if Config.EnablePlayerManagement and PlayerData.job.grade_name == 'boss' then + table.insert(elements, {label = 'Retirer argent société', value = 'withdraw_society_money'}) + table.insert(elements, {label = 'Déposer argent', value = 'deposit_society_money'}) + end + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'ambulance_actions', + { + title = 'Ambulance', + elements = elements + }, + function(data, menu) + + if data.current.value == 'cloakroom' then + OpenCloakroomMenu() + end + + if data.current.value == 'withdraw_society_money' then + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'withdraw_society_money_amount', + { + title = 'Montant du retrait' + }, + function(data, menu) + + local amount = tonumber(data.value) + + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + menu.close() + TriggerServerEvent('esx_society:withdrawMoney', 'ambulance', amount) + end + + end, + function(data, menu) + menu.close() + end + ) + + end + + if data.current.value == 'deposit_society_money' then + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'deposit_money_amount', + { + title = 'Montant du dépôt' + }, + function(data, menu) + + local amount = tonumber(data.value) + + if amount == nil then + ESX.ShowNotification('Montant invalide') + else + menu.close() + TriggerServerEvent('esx_society:depositMoney', 'ambulance', amount) + end + + end, + function(data, menu) + menu.close() + end + ) + + end + + end, + function(data, menu) + + menu.close() + + CurrentAction = 'ambulance_actions_menu' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour ouvrir le menu' + CurrentActionData = {} + + end + ) + +end + +function OpenMobileAmbulanceActionsMenu() + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'mobile_ambulance_actions', + { + title = 'Ambulance', + elements = { + {label = 'Interaction citoyen', value = 'citizen_interaction'}, + } + }, + function(data, menu) + + if data.current.value == 'citizen_interaction' then + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'citizen_interaction', + { + title = 'Ambulance - Interactions Citoyen', + elements = { + {label = 'Réanimer', value = 'revive'}, + {label = 'Mettre dans véhicule', value = 'put_in_vehicle'}, + } + }, + function(data, menu) + + if data.current.value == 'revive' then + + menu.close() + + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification('Aucun joueur à proximité') + else + + local ped = GetPlayerPed(closestPlayer) + local health = GetEntityHealth(ped) + + if health == 0 then + + local playerPed = GetPlayerPed(-1) + local closestPlayerPed = GetPlayerPed(closestPlayer) + + Citizen.CreateThread(function() + + ESX.ShowNotification('Réanimation en cours') + + TaskStartScenarioInPlace(playerPed, 'CODE_HUMAN_MEDIC_TEND_TO_DEAD', 0, true) + Citizen.Wait(10000) + ClearPedTasks(playerPed) + + if GetEntityHealth(closestPlayerPed) == 0 then + TriggerServerEvent('esx_ambulancejob:revive', GetPlayerServerId(closestPlayer)) + ESX.ShowNotification('Vous avez réanimé ' .. GetPlayerName(closestPlayer)) + else + ESX.ShowNotification(GetPlayerName(closestPlayer) .. ' a succombé') + end + + end) + + else + ESX.ShowNotification(GetPlayerName(closestPlayer) .. ' n\'est pas inconscient') + end + + end + + end + + if data.current.value == 'put_in_vehicle' then + menu.close() + WarpPedInClosestVehicle(GetPlayerPed(closestPlayer)) + end + + end, + function(data, menu) + menu.close() + end + ) + + end + + end, + function(data, menu) + menu.close() + end + ) + +end + +function OpenCloakroomMenu() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'cloakroom', + { + title = 'Vestiaire', + align = 'top-left', + elements = { + {label = 'Tenue Civil', value = 'citizen_wear'}, + {label = 'Tenue Ambulancier', value = 'ambulance_wear'}, + }, + }, + function(data, menu) + + menu.close() + + if data.current.value == 'citizen_wear' then + + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) + TriggerEvent('skinchanger:loadSkin', skin) + end) + + end + + if data.current.value == 'ambulance_wear' then + + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) + + if skin.sex == 0 then + TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_male) + else + TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_female) + end + + end) + + end + + CurrentAction = 'ambulance_actions_menu' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour ouvrir le menu' + CurrentActionData = {} + + end, + function(data, menu) + menu.close() + end + ) + +end + +function OpenVehicleSpawnerMenu() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'cloakroom', + { + title = 'Véhicule', + align = 'top-left', + elements = { + {label = 'Ambulance', value = 'ambulance'}, + {label = 'Hélicoptère', value = 'polmav'}, + }, + }, + function(data, menu) + + menu.close() + + local model = data.current.value + + ESX.Game.SpawnVehicle(model, Config.Zones.VehicleSpawnPoint.Pos, 270.0, function(vehicle) + + local playerPed = GetPlayerPed(-1) + + if model == 'polmav' then + SetVehicleModKit(vehicle, 0) + SetVehicleLivery(vehicle, 1) + end + + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + + end) + + end, + function(data, menu) + + menu.close() + + CurrentAction = 'vehicle_spawner_menu' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour sortir un véhicule' + CurrentActionData = {} + + end + ) + +end + +AddEventHandler('playerSpawned', function() + + IsDead = false + + if FirstSpawn then + exports.spawnmanager:setAutoSpawn(false) + FirstSpawn = false + end + +end) + +RegisterNetEvent('esx:playerLoaded') +AddEventHandler('esx:playerLoaded', function(xPlayer) + + PlayerData = xPlayer + + if PlayerData.job.name == 'ambulance' then + + Config.Zones.AmbulanceActions.Type = 1 + Config.Zones.VehicleSpawner.Type = 1 + Config.Zones.VehicleDeleter.Type = 1 + + else + + Config.Zones.AmbulanceActions.Type = -1 + Config.Zones.VehicleSpawner.Type = -1 + Config.Zones.VehicleDeleter.Type = -1 + + end + +end) + +RegisterNetEvent('esx:setJob') +AddEventHandler('esx:setJob', function(job) + + PlayerData.job = job + + if PlayerData.job.name == 'ambulance' then + + Config.Zones.AmbulanceActions.Type = 1 + Config.Zones.VehicleSpawner.Type = 1 + Config.Zones.VehicleDeleter.Type = 1 + + else + + Config.Zones.AmbulanceActions.Type = -1 + Config.Zones.VehicleSpawner.Type = -1 + Config.Zones.VehicleDeleter.Type = -1 + + end + +end) + +AddEventHandler('baseevents:onPlayerDied', function(killerType, coords) + TriggerEvent('esx_ambulancejob:onPlayerDeath') +end) + +AddEventHandler('baseevents:onPlayerKilled', function(killerId, data) + TriggerEvent('esx_ambulancejob:onPlayerDeath') +end) + +AddEventHandler('esx_ambulancejob:onPlayerDeath', function() + + IsDead = true + + StartRespawnTimer() + + StartScreenEffect('DeathFailOut', 0, false) +end) + +RegisterNetEvent('esx_ambulancejob:revive') +AddEventHandler('esx_ambulancejob:revive', function() + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + Citizen.CreateThread(function() + + DoScreenFadeOut(800) + + while not IsScreenFadedOut() do + Citizen.Wait(0) + end + + TriggerServerEvent('esx:updateLastPosition', { + x = coords.x, + y = coords.y, + z = coords.z + }) + + RespawnPed(playerPed, { + x = coords.x, + y = coords.y, + z = coords.z + }) + + StopScreenEffect('DeathFailOut') + + DoScreenFadeIn(800) + + end) + +end) + +AddEventHandler('esx_ambulancejob:hasEnteredMarker', function(zone) + + if zone == 'HospitalInteriorEntering1' then + TeleportFadeEffect(GetPlayerPed(-1), Config.Zones.HospitalInteriorInside1.Pos) + end + + if zone == 'HospitalInteriorExit1' then + TeleportFadeEffect(GetPlayerPed(-1), Config.Zones.HospitalInteriorOutside1.Pos) + end + + if zone == 'HospitalInteriorEntering2' then + TeleportFadeEffect(GetPlayerPed(-1), Config.Zones.HospitalInteriorInside2.Pos) + end + + if zone == 'HospitalInteriorExit2' then + TeleportFadeEffect(GetPlayerPed(-1), Config.Zones.HospitalInteriorOutside2.Pos) + end + + if zone == 'AmbulanceActions' and PlayerData.job ~= nil and PlayerData.job.name == 'ambulance' then + CurrentAction = 'ambulance_actions_menu' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour ouvrir le menu' + CurrentActionData = {} + end + + if zone == 'VehicleSpawner' and PlayerData.job ~= nil and PlayerData.job.name == 'ambulance' then + CurrentAction = 'vehicle_spawner_menu' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour sortir un véhicule' + CurrentActionData = {} + end + + if zone == 'VehicleDeleter' and PlayerData.job ~= nil and PlayerData.job.name == 'ambulance' then + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + if IsPedInAnyVehicle(playerPed, false) then + + local vehicle, distance = ESX.Game.GetClosestVehicle({ + x = coords.x, + y = coords.y, + z = coords.z + }) + + if distance ~= -1 and distance <= 1.0 then + + CurrentAction = 'delete_vehicle' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour ranger le véhicule' + CurrentActionData = {vehicle = vehicle} + + end + + end + + end + +end) + +AddEventHandler('esx_ambulancejob:hasExitedMarker', function(zone) + CurrentAction = nil +end) + +-- Create blips +Citizen.CreateThread(function() + + local blip = AddBlipForCoord(Config.Zones.HospitalInteriorOutside1.Pos.x, Config.Zones.HospitalInteriorOutside1.Pos.y, Config.Zones.HospitalInteriorOutside1.Pos.z) + + SetBlipSprite (blip, 61) + SetBlipDisplay(blip, 4) + SetBlipScale (blip, 1.2) + SetBlipAsShortRange(blip, true) + + BeginTextCommandSetBlipName("STRING") + AddTextComponentString("Hôpital") + EndTextCommandSetBlipName(blip) + +end) + +-- Display markers +Citizen.CreateThread(function() + while true do + + Wait(0) + + local coords = GetEntityCoords(GetPlayerPed(-1)) + + for k,v in pairs(Config.Zones) do + + if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.MarkerSize.x, Config.MarkerSize.y, Config.MarkerSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) + end + end + + end +end) + +-- Activate menu when player is inside marker +Citizen.CreateThread(function() + while true do + + Wait(0) + + local coords = GetEntityCoords(GetPlayerPed(-1)) + local isInMarker = false + local currentZone = nil + + for k,v in pairs(Config.Zones) do + if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.MarkerSize.x) then + isInMarker = true + currentZone = k + end + end + + if isInMarker and not hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = true + lastZone = currentZone + TriggerEvent('esx_ambulancejob:hasEnteredMarker', currentZone) + end + + if not isInMarker and hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = false + TriggerEvent('esx_ambulancejob:hasExitedMarker', lastZone) + end + + end +end) + +-- Key Controls +Citizen.CreateThread(function() + while true do + + Citizen.Wait(0) + + if CurrentAction ~= nil then + + SetTextComponentFormat('STRING') + AddTextComponentString(CurrentActionMsg) + DisplayHelpTextFromStringLabel(0, 0, 1, -1) + + if IsControlPressed(0, Keys['E']) and PlayerData.job ~= nil and PlayerData.job.name == 'ambulance' and (GetGameTimer() - GUI.Time) > 150 then + + if CurrentAction == 'ambulance_actions_menu' then + OpenAmbulanceActionsMenu() + end + + if CurrentAction == 'vehicle_spawner_menu' then + OpenVehicleSpawnerMenu() + end + + if CurrentAction == 'delete_vehicle' then + ESX.Game.DeleteVehicle(CurrentActionData.vehicle) + end + + CurrentAction = nil + GUI.Time = GetGameTimer() + + end + + end + + if IsControlPressed(0, Keys['F6']) and PlayerData.job ~= nil and PlayerData.job.name == 'ambulance' and (GetGameTimer() - GUI.Time) > 150 then + OpenMobileAmbulanceActionsMenu() + GUI.Time = GetGameTimer() + end + + end +end) + +-- Load unloaded IPLs +Citizen.CreateThread(function() + LoadMpDlcMaps() + EnableMpDlcMaps(true) + RequestIpl('Coroner_Int_on') -- Morgue +end) \ No newline at end of file diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..391eb068 --- /dev/null +++ b/config.lua @@ -0,0 +1,74 @@ +Config = {} +Config.DrawDistance = 100.0 +Config.MarkerColor = {r = 102, g = 0, b = 102} +Config.MarkerSize = {x = 1.5, y = 1.5, z = 1.0} +Config.RespawnDelayAfterRPDeath = 5 * 1000 +Config.RemoveWeaponsAfterRPDeath = true +Config.RemoveCashAfterRPDeath = true +Config.RemoveItemsAfterRPDeath = true +Config.EnablePlayerManagement = false + +Config.Zones = { + + + HospitalInteriorEntering1 = { + Pos = {x = 1151.447, y = -1529.491, z = 34.375}, + Type = 1 + }, + + HospitalInteriorInside1 = { + Pos = {x = 251.464, y = -1369.770, z = 28.648}, + Type = -1 + }, + + HospitalInteriorOutside1 = { + Pos = {x = 1153.364, y = -1525.731, z = 33.843}, + Type = -1 + }, + + HospitalInteriorExit1 = { + Pos = {x = 253.612, y = -1371.66, z = 28.647}, + Type = 1 + }, + + HospitalInteriorEntering2 = { + Pos = {x = 1137.181, y = -1597.504, z = 33.692}, + Type = 1 + }, + + HospitalInteriorInside2 = { + Pos = {x = 240.508, y = -1360.565, z = 28.647}, + Type = -1 + }, + + HospitalInteriorOutside2 = { + Pos = {x = 1137.922, y = -1601.434, z = 33.692}, + Type = -1 + }, + + HospitalInteriorExit2 = { + Pos = {x = 238.587, y = -1359.113, z = 28.647}, + Type = 1 + }, + + AmbulanceActions = { + Pos = {x = 244.048, y = -1366.330, z = 28.647}, + Type = 1 + }, + + VehicleSpawner = { + Pos = {x = 1128.290, y = -1601.451, z = 33.893}, + Type = 1 + }, + + VehicleSpawnPoint = { + Pos = {x = 1138.061, y = -1607.882, z = 34.692}, + Type = -1 + }, + + VehicleDeleter = { + Pos = {x = 1122.436, y = -1617.600, z = 33.692}, + Type = 1 + } + +} diff --git a/esx_ambulancejob_full.sql b/esx_ambulancejob_full.sql new file mode 100644 index 00000000..7c8ecdac --- /dev/null +++ b/esx_ambulancejob_full.sql @@ -0,0 +1,16 @@ +USE `essentialmode` + +INSERT INTO `addon_account` (name, label, shared) VALUES + ('society_ambulance', 'Ambulance', 1), +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('ambulance',0,'ambulance','Ambulancier',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}'), + ('ambulance',1,'doctor','Medecin',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}'), + ('ambulance',2,'chief_doctor','Medecin-chef',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}'), + ('ambulance',3,'boss','Chirurgien',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}') +; + +INSERT INTO `jobs` (name, label) VALUES + ('ambulance','Ambulance') +; \ No newline at end of file diff --git a/esx_ambulancejob_minimal.sql b/esx_ambulancejob_minimal.sql new file mode 100644 index 00000000..2f7afe36 --- /dev/null +++ b/esx_ambulancejob_minimal.sql @@ -0,0 +1,12 @@ +USE `essentialmode` + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('ambulance',0,'ambulance','Ambulancier',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}'), + ('ambulance',1,'doctor','Medecin',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}'), + ('ambulance',2,'chief_doctor','Medecin-chef',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}'), + ('ambulance',3,'boss','Chirurgien',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}') +; + +INSERT INTO `jobs` (name, label) VALUES + ('ambulance','Ambulance') +; \ No newline at end of file diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..8d3bd208 --- /dev/null +++ b/server/main.lua @@ -0,0 +1,35 @@ +ESX = nil + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +RegisterServerEvent('esx_ambulancejob:revive') +AddEventHandler('esx_ambulancejob:revive', function(target) + TriggerClientEvent('esx_ambulancejob:revive', target) +end) + +ESX.RegisterServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function(source, cb) + + local xPlayer = ESX.GetPlayerFromId(source) + + if Config.RemoveCashAfterRPDeath then + xPlayer.set('money', 0) + xPlayer.setAccountMoney('black_money', 0) + end + + if Config.RemoveItemsAfterRPDeath then + for i=1, #xPlayer.inventory, 1 do + if xPlayer.inventory[i].count > 0 then + xPlayer.setInventoryItem(xPlayer.inventory[i].name, 0) + end + end + end + + if Config.RemoveWeaponsAfterRPDeath then + for i=1, #xPlayer.loadout, 1 do + xPlayer.removeWeapon(xPlayer.loadout[i].name) + end + end + + cb() + +end) \ No newline at end of file From 190cc5cf0d513655e77970943115150d7ae8bec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 10 Aug 2017 19:12:07 +0200 Subject: [PATCH 0269/3224] Update config --- config.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.lua b/config.lua index 391eb068..aa86bf2c 100644 --- a/config.lua +++ b/config.lua @@ -2,7 +2,7 @@ Config = {} Config.DrawDistance = 100.0 Config.MarkerColor = {r = 102, g = 0, b = 102} Config.MarkerSize = {x = 1.5, y = 1.5, z = 1.0} -Config.RespawnDelayAfterRPDeath = 5 * 1000 +Config.RespawnDelayAfterRPDeath = 10 * 60 * 1000 Config.RemoveWeaponsAfterRPDeath = true Config.RemoveCashAfterRPDeath = true Config.RemoveItemsAfterRPDeath = true From 63c122fa1d3b8ea42818e1dee124d5029b147d60 Mon Sep 17 00:00:00 2001 From: ig0ne Date: Fri, 11 Aug 2017 02:11:11 +0200 Subject: [PATCH 0270/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..6f51f9ff --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_drugs +FXserver ESX Drugs From 1724e778e8608e2d7450f86196b9f3c866fbe858 Mon Sep 17 00:00:00 2001 From: ig0ne Date: Fri, 11 Aug 2017 02:18:30 +0200 Subject: [PATCH 0271/3224] Update README.md --- README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/README.md b/README.md index 6f51f9ff..97e88e09 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,26 @@ # fxserver-esx_drugs FXserver ESX Drugs + +[REQUIREMENTS] + + * esx_policejob => https://github.com/FXServer-ESX/fxserver-esx_policejob + +[INSTALLATION] + +1) CD in your resources/[esx] folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-esx_drugs esx_drugs +``` +3) * Import esx_drugs.sql in your database + +4) Add this in your server.cfg : + +``` +start esx_drugs +``` + +[FEATURES] +* Use weed +* Cops can't see or interact with the drugs zones +* In the config.lua change the Config.RequiredCop to block the drugs zone in function of the cops count conected From de401cc8d24f39727986063a8454b9db2b4044bb Mon Sep 17 00:00:00 2001 From: ig0ne Date: Fri, 11 Aug 2017 02:19:05 +0200 Subject: [PATCH 0272/3224] Add files via upload --- __resource.lua | 7 + client/esx_drugs_cl.lua | 272 +++++++++++++++++++ config.lua | 20 ++ esx_drugs.sql | 8 + server/esx_drugs_sv.lua | 561 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 868 insertions(+) create mode 100644 __resource.lua create mode 100644 client/esx_drugs_cl.lua create mode 100644 config.lua create mode 100644 esx_drugs.sql create mode 100644 server/esx_drugs_sv.lua diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..12628236 --- /dev/null +++ b/__resource.lua @@ -0,0 +1,7 @@ +description 'esx_drugs' + +server_script 'server/esx_drugs_sv.lua' +server_script 'config.lua' + +client_script 'config.lua' +client_script 'client/esx_drugs_cl.lua' \ No newline at end of file diff --git a/client/esx_drugs_cl.lua b/client/esx_drugs_cl.lua new file mode 100644 index 00000000..cfe2f4c7 --- /dev/null +++ b/client/esx_drugs_cl.lua @@ -0,0 +1,272 @@ +local Keys = { + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, + ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, + ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, + ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, + ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 +} + +local PID = 0 +local GUI = {} +local cokeQTE = 0 +ESX = nil +GUI.Time = 0 +local coke_poochQTE = 0 +local weedQTE = 0 +local weed_poochQTE = 0 +local methQTE = 0 +local meth_poochQTE = 0 +local PlayerData = {} +local GUI = {} +local HasAlreadyEnteredMarker = false +local LastZone = nil +local CurrentAction = nil +local CurrentActionMsg = '' +local CurrentActionData = {} + +Citizen.CreateThread(function() + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end +end) + +AddEventHandler('esx_drugs:hasEnteredMarker', function(zone) + + ESX.UI.Menu.CloseAll() + + if zone == 'CokeFarm' then + if myJob ~= "police" then + CurrentAction = 'coke_harvest' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour récolter la coke' + CurrentActionData = {} + end + end + + if zone == 'CokeTreatment' then + if myJob ~= "police" then + if cokeQTE >= 5 then + CurrentAction = 'coke_treatment' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour traiter la coke' + CurrentActionData = {} + end + end + end + + if zone == 'CokeResell' then + if myJob ~= "police" then + if coke_poochQTE >= 1 then + CurrentAction = 'coke_resell' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour vendre la coke' + CurrentActionData = {} + end + end + end + + if zone == 'MethFarm' then + if myJob ~= "police" then + CurrentAction = 'meth_harvest' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour récolter la meth' + CurrentActionData = {} + end + end + + if zone == 'MethTreatment' then + if myJob ~= "police" then + if cokeQTE >= 5 then + CurrentAction = 'meth_treatment' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour traiter la meth' + CurrentActionData = {} + end + end + end + + if zone == 'MethResell' then + if myJob ~= "police" then + if coke_poochQTE >= 1 then + CurrentAction = 'meth_resell' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour vendre la meth' + CurrentActionData = {} + end + end + end + + if zone == 'WeedFarm' then + if myJob ~= "police" then + CurrentAction = 'weed_harvest' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour récolter la weed' + CurrentActionData = {} + end + end + + if zone == 'WeedTreatment' then + if myJob ~= "police" then + if cokeQTE >= 5 then + CurrentAction = 'weed_treatment' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour traiter la weed' + CurrentActionData = {} + end + end + end + + if zone == 'WeedResell' then + if myJob ~= "police" then + if coke_poochQTE >= 1 then + CurrentAction = 'weed_resell' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour vendre la weed' + CurrentActionData = {} + end + end + end +end) + +AddEventHandler('esx_drugs:hasExitedMarker', function(zone) + + CurrentAction = nil + ESX.UI.Menu.CloseAll() + + TriggerServerEvent('esx_drugs:stopHarvestCoke') + TriggerServerEvent('esx_drugs:stopTransformCoke') + TriggerServerEvent('esx_drugs:stopSellCoke') + TriggerServerEvent('esx_drugs:stopHarvestMeth') + TriggerServerEvent('esx_drugs:stopTransformMeth') + TriggerServerEvent('esx_drugs:stopSellMeth') + TriggerServerEvent('esx_drugs:stopHarvestWeed') + TriggerServerEvent('esx_drugs:stopTransformWeed') + TriggerServerEvent('esx_drugs:stopSellWeed') +end) + +-- Weed Effect +RegisterNetEvent('esx_drugs:onPot') +AddEventHandler('esx_drugs:onPot', function() + RequestAnimSet("MOVE_M@DRUNK@SLIGHTLYDRUNK") + while not HasAnimSetLoaded("MOVE_M@DRUNK@SLIGHTLYDRUNK") do + Citizen.Wait(0) + end + TaskStartScenarioInPlace(GetPlayerPed(-1), "WORLD_HUMAN_SMOKING_POT", 0, true) + Citizen.Wait(5000) + DoScreenFadeOut(1000) + Citizen.Wait(1000) + ClearPedTasksImmediately(GetPlayerPed(-1)) + SetTimecycleModifier("spectator5") + SetPedMotionBlur(GetPlayerPed(-1), true) + SetPedMovementClipset(GetPlayerPed(-1), "MOVE_M@DRUNK@SLIGHTLYDRUNK", true) + SetPedIsDrunk(GetPlayerPed(-1), true) + DoScreenFadeIn(1000) + Citizen.Wait(600000) + DoScreenFadeOut(1000) + Citizen.Wait(1000) + DoScreenFadeIn(1000) + ClearTimecycleModifier() + ResetScenarioTypesEnabled() + ResetPedMovementClipset(GetPlayerPed(-1), 0) + SetPedIsDrunk(GetPlayerPed(-1), false) + SetPedMotionBlur(GetPlayerPed(-1), false) +end) + +-- Render markers +Citizen.CreateThread(function() + while true do + + Wait(0) + + local coords = GetEntityCoords(GetPlayerPed(-1)) + + for k,v in pairs(Config.Zones) do + if(GetDistanceBetweenCoords(coords, v.x, v.y, v.z, true) < Config.DrawDistance) then + DrawMarker(Config.MarkerType, v.x, v.y, v.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.ZoneSize.x, Config.ZoneSize.y, Config.ZoneSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) + end + end + + end +end) + +-- RETURN NUMBER OF ITEMS FROM SERVER +RegisterNetEvent('esx_drugs:ReturnInventory') +AddEventHandler('esx_drugs:ReturnInventory', function(cokeNbr, cokepNbr, methNbr, methpNbr, weedNbr, weedpNbr, jobName, currentZone) + cokeQTE = cokeNbr + coke_poochQTE = cokepNbr + methQTE = methNbr + meth_poochQTE = methpNbr + weedQTE = weedNbr + weed_poochQTE = weedpNbr + myJob = jobName + TriggerEvent('esx_drugs:hasEnteredMarker', currentZone) +end) + +-- Activate menu when player is inside marker +Citizen.CreateThread(function() + while true do + + Wait(0) + + local coords = GetEntityCoords(GetPlayerPed(-1)) + local isInMarker = false + local currentZone = nil + + for k,v in pairs(Config.Zones) do + if(GetDistanceBetweenCoords(coords, v.x, v.y, v.z, true) < Config.ZoneSize.x / 2) then + isInMarker = true + currentZone = k + end + end + + if isInMarker and not hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = true + lastZone = currentZone + TriggerServerEvent('esx_drugs:GetUserInventory', currentZone) + end + + if not isInMarker and hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = false + TriggerEvent('esx_drugs:hasExitedMarker', lastZone) + end + + end +end) + +-- Key Controls +Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + if CurrentAction ~= nil then + SetTextComponentFormat('STRING') + AddTextComponentString(CurrentActionMsg) + DisplayHelpTextFromStringLabel(0, 0, 1, -1) + if IsControlJustReleased(0, 38) then + if CurrentAction == 'coke_harvest' then + TriggerServerEvent('esx_drugs:startHarvestCoke') + end + if CurrentAction == 'coke_treatment' then + TriggerServerEvent('esx_drugs:startTransformCoke') + end + if CurrentAction == 'coke_resell' then + TriggerServerEvent('esx_drugs:startSellCoke') + end + if CurrentAction == 'meth_harvest' then + TriggerServerEvent('esx_drugs:startHarvestMeth') + end + if CurrentAction == 'meth_treatment' then + TriggerServerEvent('esx_drugs:startTransformMeth') + end + if CurrentAction == 'meth_resell' then + TriggerServerEvent('esx_drugs:startSellCoke') + end + if CurrentAction == 'weed_harvest' then + TriggerServerEvent('esx_drugs:startHarvestWeed') + end + if CurrentAction == 'wedd_treatment' then + TriggerServerEvent('esx_drugs:startTransformWeed') + end + if CurrentAction == 'weed_resell' then + TriggerServerEvent('esx_drugs:startSellWeed') + end + CurrentAction = nil + end + end + end +end) diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..6699d8ca --- /dev/null +++ b/config.lua @@ -0,0 +1,20 @@ +Config = {} +Config.MarkerType = 1 +Config.DrawDistance = 100.0 +Config.ZoneSize = {x = 5.0, y = 5.0, z = 3.0} +--Config.MarkerColor = {r = 100, g = 204, b = 100} +Config.RequiredCopsCoke = 2 +Config.RequiredCopsMeth = 2 +Config.RequiredCopsWeed = 0 + +Config.Zones = { + CokeFarm = {x=2448.9228515625, y=-1836.8076171875, z=51.953701019287}, + CokeTreatment = {x=-458.13967895508, y=-2278.6174316406, z=7.5158290863037}, + CokeResell = {x=-1756.1984863281, y=427.31674194336, z=126.68292999268}, + MethFarm = {x=1525.298828125, y=1710.0217285156, z=109.00956726074}, + MethTreatment = {x=-1001.4151611328, y=4848.0087890625, z=274.00686645508}, + MethResell = {x=-63.592178344727, y=-1224.0709228516, z=27.768648147583}, + WeedFarm = {x=1609.125, y=6663.5942382813, z=20.961572647095}, + WeedTreatment = {x=91.061386108398, y=3750.0380859375, z=39.77326965332}, + WeedResell = {x=-54.249694824219, y=-1443.3666992188, z=31.068626403809} +} \ No newline at end of file diff --git a/esx_drugs.sql b/esx_drugs.sql new file mode 100644 index 00000000..6cad45ce --- /dev/null +++ b/esx_drugs.sql @@ -0,0 +1,8 @@ +INSERT INTO `items` (name, label) VALUES + ('weed', 'Weed'), + ('weed_pooch', 'Pochon de weed'), + ('coke', 'Coke'), + ('coke_pooch', 'Pochon de coke'), + ('meth', 'Meth'), + ('meth_pooch', 'Pochon de meth') +; \ No newline at end of file diff --git a/server/esx_drugs_sv.lua b/server/esx_drugs_sv.lua new file mode 100644 index 00000000..87cbff66 --- /dev/null +++ b/server/esx_drugs_sv.lua @@ -0,0 +1,561 @@ +ESX = nil +local CopsConnected = 0 +local PlayersHarvestingCoke = {} +local PlayersTransformingCoke = {} +local PlayersSellingCoke = {} +local PlayersHarvestingMeth = {} +local PlayersTransformingMeth = {} +local PlayersSellingMeth = {} +local PlayersHarvestingWeed = {} +local PlayersTransformingWeed = {} +local PlayersSellingWeed = {} + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +function CountCops() + + local xPlayers = ESX.GetPlayers() + + CopsConnected = 0 + + for k,v in pairs(xPlayers) do + if v.job.name == 'police' then + CopsConnected = CopsConnected + 1 + end + end + + SetTimeout(5000, CountCops) + +end + +CountCops() + +local function HarvestCoke(source) + + if CopsConnected < Config.RequiredCopsCoke then + TriggerClientEvent('esx:showNotification', source, 'Action ~r~impossible~s~, ~b~policiers~s~: ' .. CopsConnected .. '/' .. Config.RequiredCopsCoke) + return + end + + SetTimeout(5000, function() + + if PlayersHarvestingCoke[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + + local coke = xPlayer.getInventoryItem('coke') + + if coke.limit ~= -1 and coke.count >= coke.limit then + TriggerClientEvent('esx:showNotification', source, 'Vous ne pouvez plus ramasser de Cocaine, votre inventaire est ~r~plein~s~') + else + xPlayer.addInventoryItem('coke', 1) + HarvestCoke(source) + end + + end + end) +end + +RegisterServerEvent('esx_drugs:startHarvestCoke') +AddEventHandler('esx_drugs:startHarvestCoke', function() + + local _source = source + + PlayersHarvestingCoke[_source] = true + + TriggerClientEvent('esx:showNotification', _source, '~y~Ramassage en cours~s~...') + + HarvestCoke(source) + +end) + +RegisterServerEvent('esx_drugs:stopHarvestCoke') +AddEventHandler('esx_drugs:stopHarvestCoke', function() + + local _source = source + + PlayersHarvestingCoke[_source] = false + +end) + +local function TransformCoke(source) + + if CopsConnected < Config.RequiredCopsCoke then + TriggerClientEvent('esx:showNotification', source, 'Action ~r~impossible~s~, ~b~policiers~s~: ' .. CopsConnected .. '/' .. Config.RequiredCopsCoke) + return + end + + SetTimeout(10000, function() + + if PlayersTransformingCoke[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + + local cokeQuantity = xPlayer.getInventoryItem('coke').count + local poochQuantity = xPlayer.getInventoryItem('coke_pooch').count + + if poochQuantity > 35 then + TriggerClientEvent('esx:showNotification', source, 'Vous avez trop de pochons') + elseif cokeQuantity < 5 then + TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez pas assez de feuille de coca à ~r~conditionner~s~') + else + xPlayer.removeInventoryItem('coke', 5) + xPlayer.addInventoryItem('coke_pooch', 1) + + TransformCoke(source) + end + + end + end) +end + +RegisterServerEvent('esx_drugs:startTransformCoke') +AddEventHandler('esx_drugs:startTransformCoke', function() + + local _source = source + + PlayersTransformingCoke[_source] = true + + TriggerClientEvent('esx:showNotification', _source, '~y~Conditonnement en cours~s~...') + + TransformCoke(source) + +end) + +RegisterServerEvent('esx_drugs:stopTransformCoke') +AddEventHandler('esx_drugs:stopTransformCoke', function() + + local _source = source + + PlayersTransformingCoke[_source] = false + +end) + +local function SellCoke(source) + + if CopsConnected < Config.RequiredCopsCoke then + TriggerClientEvent('esx:showNotification', source, 'Action ~r~impossible~s~, ~b~policiers~s~: ' .. CopsConnected .. '/' .. Config.RequiredCopsCoke) + return + end + + SetTimeout(7500, function() + + if PlayersSellingCoke[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + + local poochQuantity = xPlayer.getInventoryItem('coke_pooch').count + + if poochQuantity == 0 then + TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez plus de pochons à ~r~vendre~s~') + else + xPlayer.removeInventoryItem('coke_pooch', 1) + if CopsConnected == 0 then + xPlayer.addAccountMoney('black_money', 198) + TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de coke~s~') + elseif CopsConnected == 1 then + xPlayer.addAccountMoney('black_money', 258) + TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de coke~s~') + elseif CopsConnected == 2 then + xPlayer.addAccountMoney('black_money', 308) + TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de coke~s~') + elseif CopsConnected == 3 then + xPlayer.addAccountMoney('black_money', 358) + TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de coke~s~') + elseif CopsConnected == 4 then + xPlayer.addAccountMoney('black_money', 396) + TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de coke~s~') + elseif CopsConnected >= 5 then + xPlayer.addAccountMoney('black_money', 428) + TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de coke~s~') + end + + SellCoke(source) + end + + end + end) +end + +RegisterServerEvent('esx_drugs:startSellCoke') +AddEventHandler('esx_drugs:startSellCoke', function() + + local _source = source + + PlayersSellingCoke[_source] = true + + TriggerClientEvent('esx:showNotification', _source, '~g~Vente en cours~s~...') + + SellCoke(source) + +end) + +RegisterServerEvent('esx_drugs:stopSellCoke') +AddEventHandler('esx_drugs:stopSellCoke', function() + + local _source = source + + PlayersSellingCoke[_source] = false + +end) + +local function HarvestMeth(source) + + if CopsConnected < Config.RequiredCopsMeth then + TriggerClientEvent('esx:showNotification', source, 'Action ~r~impossible~s~, ~b~policiers~s~: ' .. CopsConnected .. '/' .. Config.RequiredCopsMeth) + return + end + + SetTimeout(5000, function() + + if PlayersHarvestingMeth[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + + local meth = xPlayer.getInventoryItem('meth') + + if meth.limit ~= -1 and meth.count >= meth.limit then + TriggerClientEvent('esx:showNotification', source, 'Vous ne pouvez plus ramasser de Meth, votre inventaire est ~r~plein~s~') + else + xPlayer.addInventoryItem('meth', 1) + HarvestMeth(source) + end + + end + end) +end + +RegisterServerEvent('esx_drugs:startHarvestMeth') +AddEventHandler('esx_drugs:startHarvestMeth', function() + + local _source = source + + PlayersHarvestingMeth[_source] = true + + TriggerClientEvent('esx:showNotification', _source, '~y~Ramassage en cours~s~...') + + HarvestMeth(source) + +end) + +RegisterServerEvent('esx_drugs:stopHarvestMeth') +AddEventHandler('esx_drugs:stopHarvestMeth', function() + + local _source = source + + PlayersHarvestingMeth[_source] = false + +end) + +local function TransformMeth(source) + + if CopsConnected < Config.RequiredCopsMeth then + TriggerClientEvent('esx:showNotification', source, 'Action ~r~impossible~s~, ~b~policiers~s~: ' .. CopsConnected .. '/' .. Config.RequiredCopsMeth) + return + end + + SetTimeout(12000, function() + + if PlayersTransformingMeth[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + + local methQuantity = xPlayer.getInventoryItem('meth').count + local pochonQuantity = xPlayer.getInventoryItem('meth_pooch').count + + if pochonQuantity > 35 then + TriggerClientEvent('esx:showNotification', source, 'Vous avez trop de pochons') + elseif methQuantity < 5 then + TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez pas assez de Meth à ~r~conditionner~s~') + else + xPlayer.removeInventoryItem('meth', 5) + xPlayer.addInventoryItem('meth_pochon', 1) + + TransformMeth(source) + end + + end + end) +end + +RegisterServerEvent('esx_drugs:startTransformMeth') +AddEventHandler('esx_drugs:startTransformMeth', function() + + local _source = source + + PlayersTransformingMeth[_source] = true + + TriggerClientEvent('esx:showNotification', _source, '~y~Conditonnement en cours~s~...') + + TransformMeth(source) + +end) + +RegisterServerEvent('esx_drugs:stopTransformMeth') +AddEventHandler('esx_drugs:stopTransformMeth', function() + + local _source = source + + PlayersTransformingMeth[_source] = false + +end) + +local function SellMeth(source) + + if CopsConnected < Config.RequiredCopsMeth then + TriggerClientEvent('esx:showNotification', source, 'Action ~r~impossible~s~, ~b~policiers~s~: ' .. CopsConnected .. '/' .. Config.RequiredCopsMeth) + return + end + + SetTimeout(7500, function() + + if PlayersSellingMeth[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + + local pochonQuantity = xPlayer.getInventoryItem('meth_pooch').count + + if pochonQuantity == 0 then + TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez plus de pochons à ~r~vendre~s~') + else + xPlayer.removeInventoryItem('meth_pochon', 1) + if CopsConnected == 0 then + xPlayer.addAccountMoney('black_money', 276) + TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de meth~s~') + elseif CopsConnected == 1 then + xPlayer.addAccountMoney('black_money', 374) + TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de meth~s~') + elseif CopsConnected == 2 then + xPlayer.addAccountMoney('black_money', 474) + TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de meth~s~') + elseif CopsConnected == 3 then + xPlayer.addAccountMoney('black_money', 552) + TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de meth~s~') + elseif CopsConnected == 4 then + xPlayer.addAccountMoney('black_money', 616) + TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de meth~s~') + elseif CopsConnected == 5 then + xPlayer.addAccountMoney('black_money', 654) + TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de meth~s~') + elseif CopsConnected >= 6 then + xPlayer.addAccountMoney('black_money', 686) + TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de meth~s~') + end + + SellMeth(source) + end + + end + end) +end + +RegisterServerEvent('esx_drugs:startSellMeth') +AddEventHandler('esx_drugs:startSellMeth', function() + + local _source = source + + PlayersSellingMeth[_source] = true + + TriggerClientEvent('esx:showNotification', _source, '~g~Vente en cours~s~...') + + SellMeth(source) + +end) + +RegisterServerEvent('esx_drugs:stopSellMeth') +AddEventHandler('esx_drugs:stopSellMeth', function() + + local _source = source + + PlayersSellingMeth[_source] = false + +end) + +local function HarvestWeed(source) + + if CopsConnected < Config.RequiredCopsWeed then + TriggerClientEvent('esx:showNotification', source, 'Action ~r~impossible~s~, ~b~policiers~s~: ' .. CopsConnected .. '/' .. Config.RequiredCopsWeed) + return + end + + SetTimeout(5000, function() + + if PlayersHarvestingWeed[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + + local weed = xPlayer.getInventoryItem('weed') + + if weed.limit ~= -1 and weed.count >= weed.limit then + TriggerClientEvent('esx:showNotification', source, 'Vous ne pouvez plus ramasser de weed, votre inventaire est ~r~plein~s~') + else + xPlayer.addInventoryItem('weed', 1) + HarvestWeed(source) + end + + end + end) +end + +RegisterServerEvent('esx_drugs:startHarvestWeed') +AddEventHandler('esx_drugs:startHarvestWeed', function() + + local _source = source + + PlayersHarvestingWeed[_source] = true + + TriggerClientEvent('esx:showNotification', _source, '~y~Ramassage en cours~s~...') + + HarvestWeed(source) + +end) + +RegisterServerEvent('esx_drugs:stopHarvestWeed') +AddEventHandler('esx_drugs:stopHarvestWeed', function() + + local _source = source + + PlayersHarvestingWeed[_source] = false + +end) + +local function TransformWeed(source) + + if CopsConnected < Config.RequiredCopsWeed then + TriggerClientEvent('esx:showNotification', source, 'Action ~r~impossible~s~, ~b~policiers~s~: ' .. CopsConnected .. '/' .. Config.RequiredCopsWeed) + return + end + + SetTimeout(7500, function() + + if PlayersTransformingWeed[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + + local weedQuantity = xPlayer.getInventoryItem('weed').count + local poochQuantity = xPlayer.getInventoryItem('weed_pooch').count + + if poochQuantity > 35 then + TriggerClientEvent('esx:showNotification', source, 'Vous avez trop de pochons') + elseif weedQuantity < 5 then + TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez pas assez de weed à ~r~conditionner~s~') + else + xPlayer.removeInventoryItem('weed', 5) + xPlayer.addInventoryItem('weed_pooch', 1) + + TransformWeed(source) + end + + end + end) +end + +RegisterServerEvent('esx_drugs:startTransformWeed') +AddEventHandler('esx_drugs:startTransformWeed', function() + + local _source = source + + PlayersTransformingWeed[_source] = true + + TriggerClientEvent('esx:showNotification', _source, '~y~Conditonnement en cours~s~...') + + TransformWeed(source) + +end) + +RegisterServerEvent('esx_drugs:stopTransformWeed') +AddEventHandler('esx_drugs:stopTransformWeed', function() + + local _source = source + + PlayersTransformingWeed[_source] = false + +end) + +local function SellWeed(source) + + if CopsConnected < Config.RequiredCopsWeed then + TriggerClientEvent('esx_weedjob:showNotification', source, 'Action ~r~impossible~s~, ~b~policiers~s~: ' .. CopsConnected .. '/' .. Config.RequiredCopsWeed) + return + end + + SetTimeout(7500, function() + + if PlayersSellingWeed[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + + local poochQuantity = xPlayer.getInventoryItem('weed_pooch').count + + if poochQuantity == 0 then + TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez plus de pochons à ~r~vendre~s~') + else + xPlayer:removeInventoryItem('weed_pooch', 1) + if CopsConnected == 0 then + xPlayer.addAccountMoney('black_money', 108) + TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de weed~s~') + elseif CopsConnected == 1 then + xPlayer.addAccountMoney('black_money', 128) + TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de weed~s~') + elseif CopsConnected == 2 then + xPlayer.addAccountMoney('black_money', 152) + TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de weed~s~') + elseif CopsConnected == 3 then + xPlayer.addAccountMoney('black_money', 165) + TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de weed~s~') + elseif CopsConnected >= 4 then + xPlayer.addAccountMoney('black_money', 180) + TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de weed~s~') + end + + SellWeed(source) + end + + end + end) +end + +RegisterServerEvent('esx_drugs:startSellWeed') +AddEventHandler('esx_drugs:startSellWeed', function() + + local _source = source + + PlayersSellingWeed[_source] = true + + TriggerClientEvent('esx:showNotification', _source, '~g~Vente en cours~s~...') + + SellWeed(source) + +end) + +RegisterServerEvent('esx_drugs:stopSellWeed') +AddEventHandler('esx_drugs:stopSellWeed', function() + + local _source = source + + PlayersSellingWeed[_source] = false + +end) + +-- RETURN INVENTORY TO CLIENT +RegisterServerEvent('esx_drugs:GetUserInventory') +AddEventHandler('esx_drugs:GetUserInventory', function(currentZone) + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) + TriggerClientEvent('esx_drugs:ReturnInventory', _source, xPlayer.getInventoryItem('coke').count, xPlayer.getInventoryItem('coke_pooch').count, + xPlayer.getInventoryItem('meth').count, xPlayer.getInventoryItem('meth_pooch').count, + xPlayer.getInventoryItem('weed').count, xPlayer.getInventoryItem('weed_pooch').count, xPlayer.job.name, currentZone) +end) + +-- Register Usable Item +ESX.RegisterUsableItem('weed', function(source) + + local _source = source + local xPlayer = ESX.GetPlayerFromId(source) + + xPlayer.removeInventoryItem('weed', 1) + + TriggerClientEvent('esx_drugs:onPot', _source) + TriggerClientEvent('esx:showNotification', _source, 'Vous avez utilisé 1 de ~b~Weed') + +end) \ No newline at end of file From 45eed078250af116ad952ebea145a4dc4f3d69bb Mon Sep 17 00:00:00 2001 From: ig0ne Date: Fri, 11 Aug 2017 04:18:17 +0200 Subject: [PATCH 0273/3224] Debug drugs zone Debug for meth and weed zone treatment, selling --- client/esx_drugs_cl.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/esx_drugs_cl.lua b/client/esx_drugs_cl.lua index cfe2f4c7..9d935c73 100644 --- a/client/esx_drugs_cl.lua +++ b/client/esx_drugs_cl.lua @@ -77,7 +77,7 @@ AddEventHandler('esx_drugs:hasEnteredMarker', function(zone) if zone == 'MethTreatment' then if myJob ~= "police" then - if cokeQTE >= 5 then + if methQTE >= 5 then CurrentAction = 'meth_treatment' CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour traiter la meth' CurrentActionData = {} @@ -87,7 +87,7 @@ AddEventHandler('esx_drugs:hasEnteredMarker', function(zone) if zone == 'MethResell' then if myJob ~= "police" then - if coke_poochQTE >= 1 then + if meth_poochQTE >= 1 then CurrentAction = 'meth_resell' CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour vendre la meth' CurrentActionData = {} @@ -105,7 +105,7 @@ AddEventHandler('esx_drugs:hasEnteredMarker', function(zone) if zone == 'WeedTreatment' then if myJob ~= "police" then - if cokeQTE >= 5 then + if weedQTE >= 5 then CurrentAction = 'weed_treatment' CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour traiter la weed' CurrentActionData = {} @@ -115,7 +115,7 @@ AddEventHandler('esx_drugs:hasEnteredMarker', function(zone) if zone == 'WeedResell' then if myJob ~= "police" then - if coke_poochQTE >= 1 then + if weed_poochQTE >= 1 then CurrentAction = 'weed_resell' CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour vendre la weed' CurrentActionData = {} From 8103335ece3260971204b11e4aefb9a750ac9ed6 Mon Sep 17 00:00:00 2001 From: ig0ne Date: Fri, 11 Aug 2017 05:35:50 +0200 Subject: [PATCH 0274/3224] fix variable Declared a missing variable --- client/esx_drugs_cl.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/client/esx_drugs_cl.lua b/client/esx_drugs_cl.lua index 9d935c73..8a47bf97 100644 --- a/client/esx_drugs_cl.lua +++ b/client/esx_drugs_cl.lua @@ -20,6 +20,7 @@ local weedQTE = 0 local weed_poochQTE = 0 local methQTE = 0 local meth_poochQTE = 0 +local myJob = nil local PlayerData = {} local GUI = {} local HasAlreadyEnteredMarker = false From dfadbcb6af0e92175fccdd711e99d00f904c7000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 11 Aug 2017 12:51:25 +0200 Subject: [PATCH 0275/3224] Update esx_ambulancejob_full.sql --- esx_ambulancejob_full.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esx_ambulancejob_full.sql b/esx_ambulancejob_full.sql index 7c8ecdac..f368789a 100644 --- a/esx_ambulancejob_full.sql +++ b/esx_ambulancejob_full.sql @@ -1,4 +1,4 @@ -USE `essentialmode` +USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES ('society_ambulance', 'Ambulance', 1), @@ -13,4 +13,4 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ INSERT INTO `jobs` (name, label) VALUES ('ambulance','Ambulance') -; \ No newline at end of file +; From 11a894811c6fd2da841171be7053e48f1de1802c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 11 Aug 2017 12:51:37 +0200 Subject: [PATCH 0276/3224] Update esx_ambulancejob_minimal.sql --- esx_ambulancejob_minimal.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esx_ambulancejob_minimal.sql b/esx_ambulancejob_minimal.sql index 2f7afe36..9f142868 100644 --- a/esx_ambulancejob_minimal.sql +++ b/esx_ambulancejob_minimal.sql @@ -1,4 +1,4 @@ -USE `essentialmode` +USE `essentialmode`; INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES ('ambulance',0,'ambulance','Ambulancier',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}'), @@ -9,4 +9,4 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ INSERT INTO `jobs` (name, label) VALUES ('ambulance','Ambulance') -; \ No newline at end of file +; From 7acfc3e4fbb2db931d493c15c86c57b89da599fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 11 Aug 2017 15:46:21 +0200 Subject: [PATCH 0277/3224] Remove hardcoded phone numbers --- server/main.lua | 37 +------------------------------------ 1 file changed, 1 insertion(+), 36 deletions(-) diff --git a/server/main.lua b/server/main.lua index f6764d03..d0ff5f9a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -263,43 +263,8 @@ end) AddEventHandler('esx_phone:ready', function() TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) - - local xPlayer = ESX.GetPlayerFromId(source) - local xPlayers = ESX.GetPlayers() - local job = 'player' - + local xPlayer = ESX.GetPlayerFromId(source) print('MESSAGE => ' .. xPlayer.name .. '@' .. phoneNumber .. ' : ' .. message) - - for k, v in pairs(xPlayers) do - - if phoneNumber == "police" then - - if v.job.name == 'cop' then - job = "ALERTE POLICE" - TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, job, GetDistpatchRequestId()) - end - - elseif phoneNumber == "ambulance" then - - if v.job.name == 'ambulance' then - job = "ALERTE AMBULANCE" - TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, job, GetDistpatchRequestId()) - - end - - elseif phoneNumber == "depanneur" then - - if v.job.name == 'depanneur' then - job = "APPEL DÉPANNEUR" - TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, job, GetDistpatchRequestId()) - end - - elseif v.get('phoneNumber') == phoneNumber then - TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, job, false) - end - - end - end) end) From d39bb1e4d516049f628a9794e4c8283b36a80a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 11 Aug 2017 15:48:55 +0200 Subject: [PATCH 0278/3224] Add phone number --- client/main.lua | 13 +++++++++++++ server/main.lua | 17 +++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/client/main.lua b/client/main.lua index 30b5ae82..88d87c1a 100644 --- a/client/main.lua +++ b/client/main.lua @@ -449,6 +449,19 @@ AddEventHandler('esx:setJob', function(job) end) +RegisterNetEvent('esx_phone:loaded') +AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) + + local specialContact = { + name = 'Ambulance', + number = 'ambulance', + base64Icon = 'data:image/png;base64,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' + } + + TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) + +end) + AddEventHandler('baseevents:onPlayerDied', function(killerType, coords) TriggerEvent('esx_ambulancejob:onPlayerDeath') end) diff --git a/server/main.lua b/server/main.lua index 8d3bd208..7d4555fc 100644 --- a/server/main.lua +++ b/server/main.lua @@ -32,4 +32,21 @@ ESX.RegisterServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function( cb() +end) + +TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) + + local xPlayer = ESX.GetPlayerFromId(source) + local xPlayers = ESX.GetPlayers() + + if phoneNumber == 'ambulance' then + for k, v in pairs(xPlayers) do + if v.job.name == 'ambulance' then + TriggerEvent('esx_phone:getDistpatchRequestId', function(requestId) + TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'Alerte Ambulance', requestId) + end) + end + end + end + end) \ No newline at end of file From 37e5ad4afa9a886a5584b2b6d9b886413af9d056 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 11 Aug 2017 15:51:54 +0200 Subject: [PATCH 0279/3224] Add phone number --- client/main.lua | 17 +++++++++++++++-- server/main.lua | 17 +++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index f325c23a..80013822 100644 --- a/client/main.lua +++ b/client/main.lua @@ -348,7 +348,7 @@ function OpenPoliceActionsMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'vehicle_interaction', { - title = 'Interaction véhicule', + title = 'Interaction Véhicule', align = 'top-left', elements = { {label = 'Infos véhicule', value = 'vehicle_infos'}, @@ -420,7 +420,7 @@ function OpenPoliceActionsMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'citizen_interaction', { - title = 'Interaction voirie', + title = 'Interactions Voirie', align = 'top-left', elements = { {label = 'Plot', value = 'prop_roadcone02a'}, @@ -924,6 +924,19 @@ AddEventHandler('esx:setJob', function(job) PlayerData.job = job end) +RegisterNetEvent('esx_phone:loaded') +AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) + + local specialContact = { + name = 'Police', + number = 'police', + base64Icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDFGQTJDRkI0QUJCMTFFN0JBNkQ5OENBMUI4QUEzM0YiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDFGQTJDRkM0QUJCMTFFN0JBNkQ5OENBMUI4QUEzM0YiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo0MUZBMkNGOTRBQkIxMUU3QkE2RDk4Q0ExQjhBQTMzRiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo0MUZBMkNGQTRBQkIxMUU3QkE2RDk4Q0ExQjhBQTMzRiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PoW66EYAAAjGSURBVHjapJcLcFTV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' + } + + TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) + +end) + AddEventHandler('esx_policejob:hasEnteredMarker', function(station, part, partNum) if part == 'Cloakroom' then diff --git a/server/main.lua b/server/main.lua index 11ace9c4..efe9bc0a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -260,4 +260,21 @@ ESX.RegisterServerCallback('esx_policejob:buy', function(source, cb, amount) end) +end) + +TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) + + local xPlayer = ESX.GetPlayerFromId(source) + local xPlayers = ESX.GetPlayers() + + if phoneNumber == 'police' then + for k, v in pairs(xPlayers) do + if v.job.name == 'police' then + TriggerEvent('esx_phone:getDistpatchRequestId', function(requestId) + TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'Alerte police', requestId) + end) + end + end + end + end) \ No newline at end of file From 3fbbdb38559e656522d590f9ef1d1d171a9b54df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 11 Aug 2017 16:45:57 +0200 Subject: [PATCH 0280/3224] Fix callback triggering to early --- resources/[essential]/es_extended/client/main.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index 5e6e8591..66a26500 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -91,6 +91,10 @@ end) AddEventHandler('skinchanger:modelLoaded', function() + while not PlayerLoaded do + Citizen.Wait(0) + end + -- Restore loadout ESX.TriggerServerCallback('esx:getPlayerData', function(data) From fe1d0279309822f2d6e865f69350bc4076608b44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 11 Aug 2017 17:20:36 +0200 Subject: [PATCH 0281/3224] Add refresh function for menus --- resources/[essential]/es_extended/client/functions.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index d2eb5fe4..bb508164 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -176,12 +176,14 @@ ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change) end end - ESX.UI.Menu.RegisteredTypes[type].open(namespace, name, menu.data) - end end + menu.refresh = function() + ESX.UI.Menu.RegisteredTypes[type].open(namespace, name, menu.data) + end + menu.setElement = function(i, key, val) menu.data.elements[i][key] = val end From 430821d39c89189183e5dc8efa3ef73865b0094f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 11 Aug 2017 17:22:06 +0200 Subject: [PATCH 0282/3224] Fix refresh lag - works with newest esx version --- client/main.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/main.lua b/client/main.lua index be153b0a..718135a9 100644 --- a/client/main.lua +++ b/client/main.lua @@ -121,6 +121,7 @@ function OpenMenu(submitCb, cancelCb, restrict) -- Update max values TriggerEvent('skinchanger:getData', function(components, maxVals) + for i=1, #elements, 1 do if elements[i].textureof ~= nil then @@ -134,6 +135,9 @@ function OpenMenu(submitCb, cancelCb, restrict) end end + + menu.refresh() + end) end From bf637611d0efafc12d052b06b0e7741993ee8785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 11:24:30 +0200 Subject: [PATCH 0283/3224] Better server callback code + move events in common.lua --- .../es_extended/client/functions.lua | 4 ++-- .../[essential]/es_extended/server/common.lua | 16 ++++++++++++++++ .../es_extended/server/functions.lua | 17 ++--------------- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index bb508164..3b70390e 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -46,11 +46,11 @@ ESX.ShowNotification = function(msg) DrawNotification(0,1) end -ESX.TriggerServerCallback = function(name, cb, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z) +ESX.TriggerServerCallback = function(name, cb, ...) ESX.ServerCallbacks[ESX.CurrentRequestId] = cb - TriggerServerEvent('esx:triggerServerCallback', name, ESX.CurrentRequestId, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z) + TriggerServerEvent('esx:triggerServerCallback', name, ESX.CurrentRequestId, ...) if ESX.CurrentRequestId < 65535 then ESX.CurrentRequestId = ESX.CurrentRequestId + 1 diff --git a/resources/[essential]/es_extended/server/common.lua b/resources/[essential]/es_extended/server/common.lua index b001fcaa..ffadee09 100644 --- a/resources/[essential]/es_extended/server/common.lua +++ b/resources/[essential]/es_extended/server/common.lua @@ -54,3 +54,19 @@ AddEventHandler('esx:playerLoaded', function(source) } end) + +RegisterServerEvent('esx:clientLog') +AddEventHandler('esx:clientLog', function(msg) + RconPrint(msg .. "\n") +end) + +RegisterServerEvent('esx:triggerServerCallback') +AddEventHandler('esx:triggerServerCallback', function(name, requestId, ...) + + local _source = source + + ESX.TriggerServerCallback(name, requestID, _source, function(...) + TriggerClientEvent('esx:serverCallback', _source, requestId, ...) + end, ...) + +end) \ No newline at end of file diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index f3a25eea..c8dbc033 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -24,8 +24,8 @@ ESX.RegisterServerCallback = function(name, cb) ESX.ServerCallbacks[name] = cb end -ESX.TriggerServerCallback = function(name, requestId, source, cb, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z) - ESX.ServerCallbacks[name](source, cb, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z) +ESX.TriggerServerCallback = function(name, requestId, source, cb, ...) + ESX.ServerCallbacks[name](source, cb, ...) end ESX.SavePlayer = function(xPlayer, cb) @@ -194,16 +194,3 @@ ESX.GetWeaponLabel = function(name) end end - -RegisterServerEvent('esx:clientLog') -AddEventHandler('esx:clientLog', function(msg) - RconPrint(msg .. "\n") -end) - -RegisterServerEvent('esx:triggerServerCallback') -AddEventHandler('esx:triggerServerCallback', function(name, requestId, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z) - local _source = source - ESX.TriggerServerCallback(name, requestID, _source, function(a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z) - TriggerClientEvent('esx:serverCallback', _source, requestId, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z) - end, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z) -end) From df9e453bcc9c063799c2e5a2ecb5262e2a6af16a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 11:25:43 +0200 Subject: [PATCH 0284/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..b492ab18 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_status +FXServer ESX Status From 088364f78d594aa7966d9205bc47e18192808ee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 11:31:53 +0200 Subject: [PATCH 0285/3224] Update README.md --- README.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/README.md b/README.md index b492ab18..c17f0960 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,36 @@ # fxserver-esx_status FXServer ESX Status +[INSTALLATION] + +1) CD in your resources/[esx] folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-esx_status esx_status +``` +3) Add this in your server.cfg : + +``` +start esx_status +``` + +[HOWTO] + +server.lua +```lua + +local name = 'hunger' +local default = 1000000 +local color = '#CFAD0F' + +TriggerEvent('esx_status:registerStatus', name, default, color, + function(status) -- Visible calllback, if it return true the status will be visible + return true + end, + function(status) -- Tick callback, what to do at each tick + status.remove(200) + end, + {remove = 200} -- Client action (add / remove) so the client can be in sync with server +) + + +``` From 944de1000dc11a63fff6a847b3de04619412aee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 11:33:15 +0200 Subject: [PATCH 0286/3224] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c17f0960..476ac2fc 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,8 @@ FXServer ESX Status ``` git clone https://github.com/FXServer-ESX/fxserver-esx_status esx_status ``` -3) Add this in your server.cfg : +3) Import esx_status.sql in your database +4) Add this in your server.cfg : ``` start esx_status From 09d76deef3457761441e8d63fc278e5b9452623d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 11:35:52 +0200 Subject: [PATCH 0287/3224] Add files --- __resource.lua | 23 +++++ client/main.lua | 97 +++++++++++++++++++ config.lua | 5 + esx_status.sql | 3 + html/css/app.css | 20 ++++ html/scripts/app.js | 57 +++++++++++ html/ui.html | 14 +++ server/classes/status.lua | 52 ++++++++++ server/main.lua | 198 ++++++++++++++++++++++++++++++++++++++ 9 files changed, 469 insertions(+) create mode 100644 __resource.lua create mode 100644 client/main.lua create mode 100644 config.lua create mode 100644 esx_status.sql create mode 100644 html/css/app.css create mode 100644 html/scripts/app.js create mode 100644 html/ui.html create mode 100644 server/classes/status.lua create mode 100644 server/main.lua diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..f3fe55e6 --- /dev/null +++ b/__resource.lua @@ -0,0 +1,23 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'ESX Status' + +server_scripts { + '@mysql-async/lib/MySQL.lua', + 'config.lua', + 'server/classes/status.lua', + 'server/main.lua' +} + +client_scripts { + 'config.lua', + 'client/main.lua' +} + +ui_page 'html/ui.html' + +files { + 'html/ui.html', + 'html/css/app.css', + 'html/scripts/app.js' +} \ No newline at end of file diff --git a/client/main.lua b/client/main.lua new file mode 100644 index 00000000..fd69e2e4 --- /dev/null +++ b/client/main.lua @@ -0,0 +1,97 @@ +local Status = {} +local loaded = false + +RegisterNetEvent('esx_status:update') +AddEventHandler('esx_status:update', function(status) + + Status = status + + SendNUIMessage({ + update = true, + status = Status + }) + + if not loaded then + TriggerEvent('esx_status:loaded') + loaded = true + end + +end) + +AddEventHandler('esx_status:getStatus', function(name, cb) + + for i=1, #Status, 1 do + if Status[i].name == name then + cb(Status[i]) + return + end + end + +end) + +AddEventHandler('esx_status:setDisplay', function(val) + + SendNUIMessage({ + setDisplay = true, + display = val + }) + +end) + +-- Calculate status +Citizen.CreateThread(function() + while true do + + for i=1, #Status, 1 do + + if Status[i].clientAction.add ~= nil then + + local val = Status[i].clientAction.add + + if Status[i].val + val > Config.StatusMax then + Status[i].val = StatusMax + else + Status[i].val = Status[i].val + val + end + + end + + if Status[i].clientAction.remove ~= nil then + + local val = Status[i].clientAction.remove + + if Status[i].val - val < 0 then + Status[i].val = 0 + else + Status[i].val = Status[i].val - val + end + + end + + end + + SendNUIMessage({ + update = true, + status = Status + }) + + Citizen.Wait(Config.TickTime) + + end +end) + +-- Pause menu disable hud display +local isPaused = false + +Citizen.CreateThread(function() + while true do + Citizen.Wait(1) + if IsPauseMenuActive() and not isPaused then + isPaused = true + TriggerEvent('esx_status:setDisplay', 0.0) + elseif not IsPauseMenuActive() and isPaused then + isPaused = false + TriggerEvent('esx_status:setDisplay', 0.5) + end + end +end) \ No newline at end of file diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..862ec1bd --- /dev/null +++ b/config.lua @@ -0,0 +1,5 @@ +Config = {} + +Config.StatusMax = 1000000 +Config.TickTime = 1000 +Config.UpdateClientTime = 60000 \ No newline at end of file diff --git a/esx_status.sql b/esx_status.sql new file mode 100644 index 00000000..b62fd8dd --- /dev/null +++ b/esx_status.sql @@ -0,0 +1,3 @@ +USE `essentialmode`; + +ALTER TABLE `users` ADD COLUMN `status` LONGTEXT NULL; diff --git a/html/css/app.css b/html/css/app.css new file mode 100644 index 00000000..d92580fa --- /dev/null +++ b/html/css/app.css @@ -0,0 +1,20 @@ +#status_list { + position: absolute; + left : 23; + bottom : 21%; + width : 14.5%; + opacity: 0.3; +} + +.status { + padding: 1px; + margin: 0.3em; +} + +.status_inner { + padding: 1px; +} + +.status_val { + height : 0.5em; +} \ No newline at end of file diff --git a/html/scripts/app.js b/html/scripts/app.js new file mode 100644 index 00000000..e009ce7e --- /dev/null +++ b/html/scripts/app.js @@ -0,0 +1,57 @@ +(function(){ + + let status = [] + + let renderStatus = function(){ + + $('#status_list').html(''); + + for(let i=0; i' + + '
' + + '
' + + '
' + + ''); + + statusDiv.find('.status_inner') + .css({'border' : '1px solid ' + status[i].color}) + ; + + statusDiv.find('.status_val') + .css({ + 'background-color' : status[i].color, + 'width' : (status[i].val / 10000) + '%' + }) + ; + + $('#status_list').append(statusDiv) + } + + } + + window.onData = function(data){ + + if(data.update){ + + status.length = 0; + + for(let i=0; i + + + + + + +
+ + + + + + \ No newline at end of file diff --git a/server/classes/status.lua b/server/classes/status.lua new file mode 100644 index 00000000..f400eb53 --- /dev/null +++ b/server/classes/status.lua @@ -0,0 +1,52 @@ +function CreateStatus(xPlayer, name, default, color, visible, tickCallback, clientAction) + + local self = {} + + self.val = default + self.xPlayer = xPlayer + self.name = name + self.default = default + self.color = color + self.visible = visible + self.tickCallback = tickCallback + self.clientAction = clientAction + + self._set = function(k, v) + self[k] = v + end + + self._get = function(k) + return self[k] + end + + self.onTick = function() + self.tickCallback(self) + end + + self.set = function(val) + self.val = val + end + + self.add = function(val) + if self.val + val > Config.StatusMax then + self.val = StatusMax + else + self.val = self.val + val + end + end + + self.remove = function(val) + if self.val - val < 0 then + self.val = 0 + else + self.val = self.val - val + end + end + + self.updateClient = function() + TriggerEvent('esx_status:updateClient', self.xPlayer.source) + end + + return self + +end diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..6358de60 --- /dev/null +++ b/server/main.lua @@ -0,0 +1,198 @@ +ESX = nil +local RegisteredStatus = {} + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +AddEventHandler('esx_status:registerStatus', function(name, default, color, visible, tickCallback, clientAction) + + table.insert(RegisteredStatus, { + name = name, + default = default, + color = color, + visible = visible, + tickCallback = tickCallback, + clientAction = clientAction + }) + +end) + +AddEventHandler('esx:playerLoaded', function(source) + + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) + + MySQL.Async.fetchAll( + 'SELECT * FROM users WHERE identifier = @identifier', + { + ['@identifier'] = xPlayer.identifier + }, + function(result) + + local data = {} + local savedStatus = {} + + if result[1].status ~= nil then + data = json.decode(result[1].status) + end + + for i=1, #data, 1 do + savedStatus[data[i].name] = data[i] + end + + local status = {} + + for i=1, #RegisteredStatus, 1 do + + local s = RegisteredStatus[i] + local default = nil + + if savedStatus[s.name] ~= nil then + default = savedStatus[s.name].val + else + default = s.default + end + + table.insert(status, CreateStatus(xPlayer, s.name, default, s.color, s.visible, s.tickCallback, s.clientAction)) + end + + xPlayer.set('status', status) + + TriggerEvent('esx_status:updateClient', _source) + + end + ) + +end) + +AddEventHandler('esx:playerDropped', function(source) + + local xPlayer = ESX.GetPlayerFromId(source) + + local data = {} + local status = xPlayer.get('status') + + for i=1, #status, 1 do + + local s = status[i] + + table.insert(data, { + name = s._get('name'), + val = s._get('val') + }) + end + + MySQL.Async.execute( + 'UPDATE users SET status = @status WHERE identifier = @identifier', + { + ['@status'] = json.encode(data), + ['@identifier'] = xPlayer.identifier + } + ) + +end) + +AddEventHandler('esx_status:getStatus', function(playerId, statusName, cb) + + local xPlayer = ESX.GetPlayerFromId(playerId) + local status = xPlayer.get('status') + + for i=1, #status, 1 do + if status[i]._get('name') == statusName then + cb(status[i]) + break + end + end + +end) + +AddEventHandler('esx_status:updateClient', function(playerId) + + local xPlayer = ESX.GetPlayerFromId(playerId) + local data = {} + local status = xPlayer.get('status') + + for i=1, #status, 1 do + table.insert(data, { + name = status[i]._get('name'), + val = status[i]._get('val'), + color = status[i]._get('color'), + visible = status[i]._get('visible')(status[i]), + clientAction = status[i]._get('clientAction'), + max = Config.StatusMax + }) + end + + TriggerClientEvent('esx_status:update', playerId, data) + +end) + +function TickStatus() + + local xPlayers = ESX.GetPlayers() + + for k,v in pairs(xPlayers) do + + local status = v.get('status') + + if status ~= nil then + + for i=1, #status, 1 do + status[i]._get('onTick')() + end + + end + + end + + SetTimeout(Config.TickTime, TickStatus) + +end + +function UpdateClients() + + local xPlayers = ESX.GetPlayers() + + for k,v in pairs(xPlayers) do + TriggerEvent('esx_status:updateClient', v.source) + end + + SetTimeout(Config.UpdateClientTime, UpdateClients) + +end + +function SaveData() + + local xPlayers = ESX.GetPlayers() + + for k,v in pairs(xPlayers) do + + local data = {} + local status = v.get('status') + + for i=1, #status, 1 do + + local s = status[i] + + table.insert(data, { + name = s._get('name'), + val = s._get('val') + }) + end + + MySQL.Async.execute( + 'UPDATE users SET status = @status WHERE identifier = @identifier', + { + ['@status'] = json.encode(data), + ['@identifier'] = v.identifier + } + ) + + end + + SetTimeout(60000, SaveData) + +end + +TickStatus() +UpdateClients() +SaveData() \ No newline at end of file From e62f067613390a333843f2245dd14b4c9ae9589a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 11:40:24 +0200 Subject: [PATCH 0288/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..9e02bc6d --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_basicneeds +FXServer ESX Basic Needs From 5152584799c3b1c9f579b359f6b27e77be7bfbcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 11:41:01 +0200 Subject: [PATCH 0289/3224] Update README.md --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 9e02bc6d..df45e168 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,16 @@ # fxserver-esx_basicneeds FXServer ESX Basic Needs + +[INSTALLATION] + +1) CD in your resources/[esx] folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-esx_basicneeds esx_basicneeds +``` +3) Import esx_basicneeds.sql in your database +4) Add this in your server.cfg : + +``` +start esx_basicneeds +``` From 043f1d6f0cfadae82c1bba2679973493a8b106e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 11:41:43 +0200 Subject: [PATCH 0290/3224] Add start baseevents --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 73b28889..4c17b6e8 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ git clone https://github.com/FXServer-ESX/fxserver-esx_ambulancejob esx_ambulanc 4) Add this in your server.cfg : ``` +start baseevents start esx_ambulancejob ``` 5) * If you want player management you have to set Config.EnablePlayerManagement to true in config.lua From b0481a87f9c0f3196fdfc4f028eea05e41ba906e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 11:46:03 +0200 Subject: [PATCH 0291/3224] Add files --- __resource.lua | 13 ++++++ client/main.lua | 113 +++++++++++++++++++++++++++++++++++++++++++++ config.lua | 4 ++ esx_basicneeds.sql | 6 +++ server/main.lua | 74 +++++++++++++++++++++++++++++ 5 files changed, 210 insertions(+) create mode 100644 __resource.lua create mode 100644 client/main.lua create mode 100644 config.lua create mode 100644 esx_basicneeds.sql create mode 100644 server/main.lua diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..70b8e086 --- /dev/null +++ b/__resource.lua @@ -0,0 +1,13 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'ESX Basic Needs' + +server_scripts { + 'config.lua', + 'server/main.lua' +} + +client_scripts { + 'config.lua', + 'client/main.lua' +} diff --git a/client/main.lua b/client/main.lua new file mode 100644 index 00000000..1ea6d25e --- /dev/null +++ b/client/main.lua @@ -0,0 +1,113 @@ +ESX = nil +local IsDead = false + +Citizen.CreateThread(function() + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end +end) + +AddEventHandler('playerSpawned', function() + + if IsDead then + TriggerServerEvent('esx_basicneeds:resetStatus') + end + + IsDead = false +end) + +AddEventHandler('esx_status:loaded', function(status) + + Citizen.CreateThread(function() + + while true do + + Wait(1000) + + local playerPed = GetPlayerPed(-1) + local prevHealth = GetEntityHealth(playerPed) + local health = prevHealth + + TriggerEvent('esx_status:getStatus', 'hunger', function(status) + + if status.val == 0 then + + if prevHealth <= 150 then + health = health - 5 + else + health = health - 1 + end + + end + + end) + + TriggerEvent('esx_status:getStatus', 'thirst', function(status) + + if status.val == 0 then + + if prevHealth <= 150 then + health = health - 5 + else + health = health - 1 + end + + end + + end) + + if health ~= prevHealth then + SetEntityHealth(playerPed, health) + end + + end + + end) + + Citizen.CreateThread(function() + + while true do + + Wait(0) + + local playerPed = GetPlayerPed(-1) + + if IsEntityDead(playerPed) and not IsDead then + IsDead = true + end + + end + + end) + +end) + +RegisterNetEvent('esx_basicneeds:onEat') +AddEventHandler('esx_basicneeds:onEat', function() + + local pid = PlayerPedId() + + RequestAnimDict("mp_player_inteat@burger") + + while not HasAnimDictLoaded("mp_player_inteat@burger") do + Wait(0) + end + + TaskPlayAnim(pid, 'mp_player_inteat@burger', 'mp_player_int_eat_burger', 1.0, -1.0, 2000, 0, 1, true, true, true) +end) + +RegisterNetEvent('esx_basicneeds:onDrink') +AddEventHandler('esx_basicneeds:onDrink', function() + + local pid = PlayerPedId() + + RequestAnimDict("amb@world_human_drinking@coffee@male@idle_a") + + while not HasAnimDictLoaded("amb@world_human_drinking@coffee@male@idle_a") do + Wait(0) + end + + TaskPlayAnim(pid, 'amb@world_human_drinking@coffee@male@idle_a', 'idle_a', 1.0, -1.0, 2000, 0, 1, true, true, true) + +end) diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..db3c2fca --- /dev/null +++ b/config.lua @@ -0,0 +1,4 @@ +Config = {} + +Config.TickTime = 100 +Config.UpdateClientTime = 5000 \ No newline at end of file diff --git a/esx_basicneeds.sql b/esx_basicneeds.sql new file mode 100644 index 00000000..fa844f57 --- /dev/null +++ b/esx_basicneeds.sql @@ -0,0 +1,6 @@ +USE `essentialmode`; + +INSERT INTO `items` (name, label) VALUES + ('bread', 'Pain') + ('water', 'Eau') +; \ No newline at end of file diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..ec61b623 --- /dev/null +++ b/server/main.lua @@ -0,0 +1,74 @@ +TriggerEvent('esx_status:registerStatus', 'hunger', 1000000, '#CFAD0F', + function(status) + return true + end, + function(status) + status.remove(200) + end, + {remove = 200} +) + +TriggerEvent('esx_status:registerStatus', 'thirst', 1000000, '#0C98F1', + function(status) + return true + end, + function(status) + status.remove(250) + end, + {remove = 250} +) + +RegisterServerEvent('esx_basicneeds:resetStatus') +AddEventHandler('esx_basicneeds:resetStatus', function() + + local _source = source + + TriggerEvent('esx_status:getStatus', _source, 'hunger', function(status) + status.set(500000) + status.updateClient() + end) + + TriggerEvent('esx_status:getStatus', _source, 'thirst', function(status) + status.set(500000) + status.updateClient() + end) + +end) + +TriggerEvent('esx:registerUsableItem', 'bread', function(source) + + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) + + xPlayer.removeInventoryItem('bread', 1) + + TriggerEvent('esx_status:getStatus', _source, 'hunger', function(status) + + status.add(200000) + status.updateClient() + + TriggerClientEvent('esx_basicneeds:onEat', _source) + TriggerClientEvent('esx:showNotification', _source, 'Vous avez utilisé 1x pain') + + end) + +end) + +TriggerEvent('esx:registerUsableItem', 'water', function(source) + + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) + + xPlayer.removeInventoryItem('water', 1) + + TriggerEvent('esx_status:getStatus', _source, 'thirst', function(status) + + status.add(200000) + status.updateClient() + + TriggerClientEvent('esx_basicneeds:onDrink', _source) + TriggerClientEvent('esx:showNotification', _source, 'Vous avez utilisé 1x Eau') + + end) + +end) \ No newline at end of file From 753bca76e74a9017e3e3d1aa0e7ddf38ebb80641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 11:47:13 +0200 Subject: [PATCH 0292/3224] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index df45e168..030c4346 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ # fxserver-esx_basicneeds FXServer ESX Basic Needs +[INFO] + +This plugin add hunger and thirst status, they can be increased when eating bread or drinking water + [INSTALLATION] 1) CD in your resources/[esx] folder From 9244d3726555cbcf2cb0a48beaed0f1701cd5678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 12:29:07 +0200 Subject: [PATCH 0293/3224] Base for translating es_extended --- .../[essential]/es_extended/__resource.lua | 8 ++ .../es_extended/client/functions.lua | 12 +-- resources/[essential]/es_extended/config.lua | 84 +------------------ .../es_extended/config.weapons.lua | 81 ++++++++++++++++++ resources/[essential]/es_extended/locale.lua | 9 ++ .../[essential]/es_extended/locales/en.lua | 8 ++ .../[essential]/es_extended/locales/fr.lua | 8 ++ 7 files changed, 121 insertions(+), 89 deletions(-) create mode 100644 resources/[essential]/es_extended/config.weapons.lua create mode 100644 resources/[essential]/es_extended/locale.lua create mode 100644 resources/[essential]/es_extended/locales/en.lua create mode 100644 resources/[essential]/es_extended/locales/fr.lua diff --git a/resources/[essential]/es_extended/__resource.lua b/resources/[essential]/es_extended/__resource.lua index 005516e5..84a0f8dc 100644 --- a/resources/[essential]/es_extended/__resource.lua +++ b/resources/[essential]/es_extended/__resource.lua @@ -6,6 +6,10 @@ server_scripts { '@async/async.lua', '@mysql-async/lib/MySQL.lua', 'config.lua', + 'locale.lua', + 'locales/fr.lua', + 'locales/en.lua', + 'config.weapons.lua', 'server/common.lua', 'server/classes/player.lua', 'server/functions.lua', @@ -15,6 +19,10 @@ server_scripts { client_scripts { 'config.lua', + 'locale.lua', + 'locales/fr.lua', + 'locales/en.lua', + 'config.weapons.lua', 'client/common.lua', 'client/functions.lua', 'client/main.lua' diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 3b70390e..7839dd7e 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -874,7 +874,7 @@ ESX.ShowInventory = function() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'inventory', { - title = 'Inventaire', + title = _U('inventory'), align = 'bottom-right', elements = elements, }, @@ -885,17 +885,17 @@ ESX.ShowInventory = function() local elements = {} if data.current.usable then - table.insert(elements, {label = 'Utiliser', action = 'use', type = data.current.type, value = data.current.value}) + table.insert(elements, {label = _U('use'), action = 'use', type = data.current.type, value = data.current.value}) end - table.insert(elements, {label = 'Donner', action = 'give', type = data.current.type, value = data.current.value}) - table.insert(elements, {label = 'Jeter', action = 'remove', type = data.current.type, value = data.current.value}) - table.insert(elements, {label = 'Retour', action = 'return'}) + table.insert(elements, {label = _U('give'), action = 'give', type = data.current.type, value = data.current.value}) + table.insert(elements, {label = _U('remove'), action = 'remove', type = data.current.type, value = data.current.value}) + table.insert(elements, {label = _U('return'), action = 'return'}) ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'inventory_item', { - title = 'Inventaire', + title = _U('inventory'), align = 'bottom-right', elements = elements, }, diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua index f1d53a77..b372f0eb 100644 --- a/resources/[essential]/es_extended/config.lua +++ b/resources/[essential]/es_extended/config.lua @@ -6,86 +6,4 @@ Config.PaycheckInterval = 7 * 60000 Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true Config.RemoveInventoryItemDelay = 5 * 60000 -Config.Locale = 'fr_FR' - -Config.Weapons = { - - {name = 'WEAPON_KNIFE', label = 'Couteau'}, - {name = 'WEAPON_NIGHTSTICK', label = 'Matraque'}, - {name = 'WEAPON_HAMMER', label = 'Marteau'}, - {name = 'WEAPON_BAT', label = 'Bat'}, - {name = 'WEAPON_GOLFCLUB', label = 'Club de golfe'}, - {name = 'WEAPON_CROWBAR', label = 'Pied de biche'}, - {name = 'WEAPON_PISTOL', label = 'Pistolet'}, - {name = 'WEAPON_COMBATPISTOL', label = 'Pistolet de combat'}, - {name = 'WEAPON_APPISTOL', label = 'Pistolet automatique'}, - {name = 'WEAPON_PISTOL50', label = 'Pistolet calibre 50'}, - {name = 'WEAPON_MICROSMG', label = 'Micro SMG'}, - {name = 'WEAPON_SMG', label = 'SMG'}, - {name = 'WEAPON_ASSAULTSMG', label = 'SMG d\'assaut'}, - {name = 'WEAPON_ASSAULTRIFLE', label = 'Fusil d\'assaut'}, - {name = 'WEAPON_CARBINERIFLE', label = 'Carabine d\'assaut'}, - {name = 'WEAPON_ADVANCEDRIFLE', label = 'Fusil avancé'}, - {name = 'WEAPON_MG', label = 'Mitrailleuse'}, - {name = 'WEAPON_COMBATMG', label = 'Mitrailleuse de combat'}, - {name = 'WEAPON_PUMPSHOTGUN', label = 'Fusil à pompe'}, - {name = 'WEAPON_SAWNOFFSHOTGUN', label = 'Carabine à canon scié'}, - {name = 'WEAPON_ASSAULTSHOTGUN', label = 'Carabine d\'assaut'}, - {name = 'WEAPON_BULLPUPSHOTGUN', label = 'Carabine Bullpup'}, - {name = 'WEAPON_STUNGUN', label = 'Tazer'}, - {name = 'WEAPON_SNIPERRIFLE', label = 'Fusil de sniper'}, - {name = 'WEAPON_HEAVYSNIPER', label = 'Fusil de sniper lourd'}, - {name = 'WEAPON_REMOTESNIPER', label = 'Fusil de sniper à distance'}, - {name = 'WEAPON_GRENADELAUNCHER', label = 'Lance-grenade'}, - {name = 'WEAPON_RPG', label = 'Lance-rocket'}, - {name = 'WEAPON_STINGER', label = 'Lance-Missile Stinger'}, - {name = 'WEAPON_MINIGUN', label = 'Minigun'}, - {name = 'WEAPON_GRENADE', label = 'Grenade'}, - {name = 'WEAPON_STICKYBOMB', label = 'Bombe collante'}, - {name = 'WEAPON_SMOKEGRENADE', label = 'Grenade fumigène'}, - {name = 'WEAPON_BZGAS', label = 'Grenade à gaz BZ'}, - {name = 'WEAPON_MOLOTOV', label = 'Cocktail molotov'}, - {name = 'WEAPON_FIREEXTINGUISHER', label = 'Extincteur'}, - {name = 'WEAPON_PETROLCAN', label = 'Jerrican d\'essence'}, - {name = 'WEAPON_DIGISCANNER', label = 'Digiscanner'}, - {name = 'WEAPON_BALL', label = 'Balle'}, - {name = 'WEAPON_SNSPISTOL', label = 'Pistolet SNS'}, - {name = 'WEAPON_BOTTLE', label = 'Bouteille'}, - {name = 'WEAPON_GUSENBERG', label = 'Balayeuse Gusenberg'}, - {name = 'WEAPON_SPECIALCARBINE', label = 'Carabine spéciale'}, - {name = 'WEAPON_HEAVYPISTOL', label = 'Pistolet lourd'}, - {name = 'WEAPON_BULLPUPRIFLE', label = 'Fusil Bullpup'}, - {name = 'WEAPON_DAGGER', label = 'Poignard'}, - {name = 'WEAPON_VINTAGEPISTOL', label = 'Pistolet vintage'}, - {name = 'WEAPON_FIREWORK', label = 'Feu d\'artifice'}, - {name = 'WEAPON_MUSKET', label = 'Mousquet'}, - {name = 'WEAPON_HEAVYSHOTGUN', label = 'Fusil à pompe lourd'}, - {name = 'WEAPON_MARKSMANRIFLE', label = 'Fusil Marksman'}, - {name = 'WEAPON_HOMINGLAUNCHER', label = 'Lance tête-chercheuse'}, - {name = 'WEAPON_PROXMINE', label = 'Mine de proximité'}, - {name = 'WEAPON_SNOWBALL', label = 'Boule de neige'}, - {name = 'WEAPON_FLAREGUN', label = 'Lance fusée de détresse'}, - {name = 'WEAPON_GARBAGEBAG', label = 'Sac poubelle'}, - {name = 'WEAPON_HANDCUFFS', label = 'Menottes'}, - {name = 'WEAPON_COMBATPDW', label = 'Arme de défense personnelle'}, - {name = 'WEAPON_MARKSMANPISTOL', label = 'Pistolet Marksman'}, - {name = 'WEAPON_KNUCKLE', label = 'Poing américain'}, - {name = 'WEAPON_HATCHET', label = 'Hachette'}, - {name = 'WEAPON_RAILGUN', label = 'Canon éléctrique'}, - {name = 'WEAPON_MACHETE', label = 'Machetta'}, - {name = 'WEAPON_MACHINEPISTOL', label = 'Pistolet mitrailleur'}, - {name = 'WEAPON_SWITCHBLADE', label = 'Couteau à cran d\'arrêt'}, - {name = 'WEAPON_REVOLVER', label = 'Revolver'}, - {name = 'WEAPON_DBSHOTGUN', label = 'Fusil à pompe double canon'}, - {name = 'WEAPON_COMPACTRIFLE', label = 'Fusil compact'}, - {name = 'WEAPON_AUTOSHOTGUN', label = 'Fusil à pompe automatique'}, - {name = 'WEAPON_BATTLEAXE', label = 'Hache de combat'}, - {name = 'WEAPON_COMPACTLAUNCHER', label = 'Lanceur compact'}, - {name = 'WEAPON_MINISMG', label = 'Mini SMG'}, - {name = 'WEAPON_PIPEBOMB', label = 'Bombe tuyau'}, - {name = 'WEAPON_POOLCUE', label = 'Queue de billard'}, - {name = 'WEAPON_WRENCH', label = 'Clé'}, - {name = 'WEAPON_FLASHLIGHT', label = 'Lampe torche'}, - {name = 'GADGET_NIGHTVISION', label = 'Vision nocturne'}, - {name = 'GADGET_PARACHUTE', label = 'Parachute'}, -} \ No newline at end of file +Config.Locale = 'fr' diff --git a/resources/[essential]/es_extended/config.weapons.lua b/resources/[essential]/es_extended/config.weapons.lua new file mode 100644 index 00000000..4210cd94 --- /dev/null +++ b/resources/[essential]/es_extended/config.weapons.lua @@ -0,0 +1,81 @@ +Config.Weapons = { + + {name = 'WEAPON_KNIFE', label = _U('weapon_knife')}, + {name = 'WEAPON_NIGHTSTICK', label = 'Matraque'}, + {name = 'WEAPON_HAMMER', label = 'Marteau'}, + {name = 'WEAPON_BAT', label = 'Bat'}, + {name = 'WEAPON_GOLFCLUB', label = 'Club de golfe'}, + {name = 'WEAPON_CROWBAR', label = 'Pied de biche'}, + {name = 'WEAPON_PISTOL', label = 'Pistolet'}, + {name = 'WEAPON_COMBATPISTOL', label = 'Pistolet de combat'}, + {name = 'WEAPON_APPISTOL', label = 'Pistolet automatique'}, + {name = 'WEAPON_PISTOL50', label = 'Pistolet calibre 50'}, + {name = 'WEAPON_MICROSMG', label = 'Micro SMG'}, + {name = 'WEAPON_SMG', label = 'SMG'}, + {name = 'WEAPON_ASSAULTSMG', label = 'SMG d\'assaut'}, + {name = 'WEAPON_ASSAULTRIFLE', label = 'Fusil d\'assaut'}, + {name = 'WEAPON_CARBINERIFLE', label = 'Carabine d\'assaut'}, + {name = 'WEAPON_ADVANCEDRIFLE', label = 'Fusil avancé'}, + {name = 'WEAPON_MG', label = 'Mitrailleuse'}, + {name = 'WEAPON_COMBATMG', label = 'Mitrailleuse de combat'}, + {name = 'WEAPON_PUMPSHOTGUN', label = 'Fusil à pompe'}, + {name = 'WEAPON_SAWNOFFSHOTGUN', label = 'Carabine à canon scié'}, + {name = 'WEAPON_ASSAULTSHOTGUN', label = 'Carabine d\'assaut'}, + {name = 'WEAPON_BULLPUPSHOTGUN', label = 'Carabine Bullpup'}, + {name = 'WEAPON_STUNGUN', label = 'Tazer'}, + {name = 'WEAPON_SNIPERRIFLE', label = 'Fusil de sniper'}, + {name = 'WEAPON_HEAVYSNIPER', label = 'Fusil de sniper lourd'}, + {name = 'WEAPON_REMOTESNIPER', label = 'Fusil de sniper à distance'}, + {name = 'WEAPON_GRENADELAUNCHER', label = 'Lance-grenade'}, + {name = 'WEAPON_RPG', label = 'Lance-rocket'}, + {name = 'WEAPON_STINGER', label = 'Lance-Missile Stinger'}, + {name = 'WEAPON_MINIGUN', label = 'Minigun'}, + {name = 'WEAPON_GRENADE', label = 'Grenade'}, + {name = 'WEAPON_STICKYBOMB', label = 'Bombe collante'}, + {name = 'WEAPON_SMOKEGRENADE', label = 'Grenade fumigène'}, + {name = 'WEAPON_BZGAS', label = 'Grenade à gaz BZ'}, + {name = 'WEAPON_MOLOTOV', label = 'Cocktail molotov'}, + {name = 'WEAPON_FIREEXTINGUISHER', label = 'Extincteur'}, + {name = 'WEAPON_PETROLCAN', label = 'Jerrican d\'essence'}, + {name = 'WEAPON_DIGISCANNER', label = 'Digiscanner'}, + {name = 'WEAPON_BALL', label = 'Balle'}, + {name = 'WEAPON_SNSPISTOL', label = 'Pistolet SNS'}, + {name = 'WEAPON_BOTTLE', label = 'Bouteille'}, + {name = 'WEAPON_GUSENBERG', label = 'Balayeuse Gusenberg'}, + {name = 'WEAPON_SPECIALCARBINE', label = 'Carabine spéciale'}, + {name = 'WEAPON_HEAVYPISTOL', label = 'Pistolet lourd'}, + {name = 'WEAPON_BULLPUPRIFLE', label = 'Fusil Bullpup'}, + {name = 'WEAPON_DAGGER', label = 'Poignard'}, + {name = 'WEAPON_VINTAGEPISTOL', label = 'Pistolet vintage'}, + {name = 'WEAPON_FIREWORK', label = 'Feu d\'artifice'}, + {name = 'WEAPON_MUSKET', label = 'Mousquet'}, + {name = 'WEAPON_HEAVYSHOTGUN', label = 'Fusil à pompe lourd'}, + {name = 'WEAPON_MARKSMANRIFLE', label = 'Fusil Marksman'}, + {name = 'WEAPON_HOMINGLAUNCHER', label = 'Lance tête-chercheuse'}, + {name = 'WEAPON_PROXMINE', label = 'Mine de proximité'}, + {name = 'WEAPON_SNOWBALL', label = 'Boule de neige'}, + {name = 'WEAPON_FLAREGUN', label = 'Lance fusée de détresse'}, + {name = 'WEAPON_GARBAGEBAG', label = 'Sac poubelle'}, + {name = 'WEAPON_HANDCUFFS', label = 'Menottes'}, + {name = 'WEAPON_COMBATPDW', label = 'Arme de défense personnelle'}, + {name = 'WEAPON_MARKSMANPISTOL', label = 'Pistolet Marksman'}, + {name = 'WEAPON_KNUCKLE', label = 'Poing américain'}, + {name = 'WEAPON_HATCHET', label = 'Hachette'}, + {name = 'WEAPON_RAILGUN', label = 'Canon éléctrique'}, + {name = 'WEAPON_MACHETE', label = 'Machetta'}, + {name = 'WEAPON_MACHINEPISTOL', label = 'Pistolet mitrailleur'}, + {name = 'WEAPON_SWITCHBLADE', label = 'Couteau à cran d\'arrêt'}, + {name = 'WEAPON_REVOLVER', label = 'Revolver'}, + {name = 'WEAPON_DBSHOTGUN', label = 'Fusil à pompe double canon'}, + {name = 'WEAPON_COMPACTRIFLE', label = 'Fusil compact'}, + {name = 'WEAPON_AUTOSHOTGUN', label = 'Fusil à pompe automatique'}, + {name = 'WEAPON_BATTLEAXE', label = 'Hache de combat'}, + {name = 'WEAPON_COMPACTLAUNCHER', label = 'Lanceur compact'}, + {name = 'WEAPON_MINISMG', label = 'Mini SMG'}, + {name = 'WEAPON_PIPEBOMB', label = 'Bombe tuyau'}, + {name = 'WEAPON_POOLCUE', label = 'Queue de billard'}, + {name = 'WEAPON_WRENCH', label = 'Clé'}, + {name = 'WEAPON_FLASHLIGHT', label = 'Lampe torche'}, + {name = 'GADGET_NIGHTVISION', label = 'Vision nocturne'}, + {name = 'GADGET_PARACHUTE', label = 'Parachute'}, +} \ No newline at end of file diff --git a/resources/[essential]/es_extended/locale.lua b/resources/[essential]/es_extended/locale.lua new file mode 100644 index 00000000..5fd59603 --- /dev/null +++ b/resources/[essential]/es_extended/locale.lua @@ -0,0 +1,9 @@ +Locales = {} + +function _(str, ...) -- Translate string + return string.format(Locales[Config.Locale][str], ...) +end + +function _U(str, ...) -- Translate string first char uppercase + return _(str, ...):gsub("^%l", string.upper) +end diff --git a/resources/[essential]/es_extended/locales/en.lua b/resources/[essential]/es_extended/locales/en.lua new file mode 100644 index 00000000..1c4b0fb4 --- /dev/null +++ b/resources/[essential]/es_extended/locales/en.lua @@ -0,0 +1,8 @@ +Locales.en = { + ['inventory'] = 'inventory', + ['use'] = 'use', + ['give'] = 'give', + ['remove'] = 'remove', + ['return'] = 'return', + ['weapon_knife'] = 'knife', +} \ No newline at end of file diff --git a/resources/[essential]/es_extended/locales/fr.lua b/resources/[essential]/es_extended/locales/fr.lua new file mode 100644 index 00000000..77204f96 --- /dev/null +++ b/resources/[essential]/es_extended/locales/fr.lua @@ -0,0 +1,8 @@ +Locales['fr'] = { + ['inventory'] = 'inventaire', + ['use'] = 'utiliser', + ['give'] = 'donner', + ['remove'] = 'jeter', + ['return'] = 'retour', + ['weapon_knife'] = 'couteau', +} \ No newline at end of file From c5382f838c9eee8eb50d5e9bf784cd63a312c507 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 12:31:03 +0200 Subject: [PATCH 0294/3224] Fix typo --- resources/[essential]/es_extended/locales/en.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/locales/en.lua b/resources/[essential]/es_extended/locales/en.lua index 1c4b0fb4..42abd3f0 100644 --- a/resources/[essential]/es_extended/locales/en.lua +++ b/resources/[essential]/es_extended/locales/en.lua @@ -1,4 +1,4 @@ -Locales.en = { +Locales['en'] = { ['inventory'] = 'inventory', ['use'] = 'use', ['give'] = 'give', From aafec3d4f98af6bd9816cb8a086de16fc9d4992f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 12:50:37 +0200 Subject: [PATCH 0295/3224] Add missing coma --- esx_basicneeds.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esx_basicneeds.sql b/esx_basicneeds.sql index fa844f57..6b9d3098 100644 --- a/esx_basicneeds.sql +++ b/esx_basicneeds.sql @@ -1,6 +1,6 @@ USE `essentialmode`; INSERT INTO `items` (name, label) VALUES - ('bread', 'Pain') + ('bread', 'Pain'), ('water', 'Eau') -; \ No newline at end of file +; From 23a20fd8d507d1bcc7940bc2d46c6bc23feb4d8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 12:54:00 +0200 Subject: [PATCH 0296/3224] Fix vehicle spawn --- client/main.lua | 88 ++++++++++++++----------------------------------- config.lua | 2 +- 2 files changed, 26 insertions(+), 64 deletions(-) diff --git a/client/main.lua b/client/main.lua index ca18a59a..93c7562b 100644 --- a/client/main.lua +++ b/client/main.lua @@ -41,6 +41,24 @@ Citizen.CreateThread(function() end) +function DeleteShopInsideVehicle() + + if IsAnyVehicleNearPoint(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 5.0) then + + local vehicle, distance = ESX.Game.GetClosestVehicle({ + x = Config.Zones.ShopInside.Pos.x, + y = Config.Zones.ShopInside.Pos.y, + z = Config.Zones.ShopInside.Pos.z + }) + + if distance <= 5.0 then + DeleteVehicle(vehicle) + end + + end + +end + function OpenShopMenu() ESX.UI.Menu.CloseAll() @@ -139,19 +157,7 @@ function OpenShopMenu() if hasEnoughMoney then - if IsAnyVehicleNearPoint(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 3.0) then - - local vehicle, distance = ESX.Game.GetClosestVehicle({ - x = Config.Zones.ShopInside.Pos.x, - y = Config.Zones.ShopInside.Pos.y, - z = Config.Zones.ShopInside.Pos.z - }) - - if distance <= 3.0 then - DeleteVehicle(vehicle) - end - - end + DeleteShopInsideVehicle() ESX.Game.SpawnVehicle(vehicleData.model, { x = Config.Zones.ShopOutside.Pos.x, @@ -201,19 +207,7 @@ function OpenShopMenu() CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' CurrentActionData = {} - if IsAnyVehicleNearPoint(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 3.0) then - - local vehicle, distance = ESX.Game.GetClosestVehicle({ - x = Config.Zones.ShopInside.Pos.x, - y = Config.Zones.ShopInside.Pos.y, - z = Config.Zones.ShopInside.Pos.z - }) - - if distance <= 3.0 then - DeleteVehicle(vehicle) - end - - end + FreezeEntityPosition(playerPed, false) SetEntityVisible(playerPed, true) @@ -230,19 +224,7 @@ function OpenShopMenu() local vehicleData = vehiclesByCategory[data.current.name][data.current.value + 1] local playerPed = GetPlayerPed(-1) - if IsAnyVehicleNearPoint(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 3.0) then - - local vehicle, distance = ESX.Game.GetClosestVehicle({ - x = Config.Zones.ShopInside.Pos.x, - y = Config.Zones.ShopInside.Pos.y, - z = Config.Zones.ShopInside.Pos.z - }) - - if distance <= 3.0 then - DeleteVehicle(vehicle) - end - - end + DeleteShopInsideVehicle() ESX.Game.SpawnLocalVehicle(vehicleData.model, { x = Config.Zones.ShopInside.Pos.x, @@ -257,19 +239,7 @@ function OpenShopMenu() end ) - if IsAnyVehicleNearPoint(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 3.0) then - - local vehicle, distance = ESX.Game.GetClosestVehicle({ - x = Config.Zones.ShopInside.Pos.x, - y = Config.Zones.ShopInside.Pos.y, - z = Config.Zones.ShopInside.Pos.z - }) - - if distance <= 3.0 then - DeleteVehicle(vehicle) - end - - end + DeleteShopInsideVehicle() ESX.Game.SpawnLocalVehicle(firstVehicleData.model, { x = Config.Zones.ShopInside.Pos.x, @@ -308,12 +278,7 @@ function OpenResellerMenu() end if data.current.value == 'depop_vehicle' then - - if IsAnyVehicleNearPoint(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 3.0) then - local vehicle = GetClosestVehicle(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 3.0, 0, 71) - DeleteVehicle(vehicle) - end - + DeleteShopInsideVehicle() end if data.current.value == 'create_bill' then @@ -391,7 +356,7 @@ function OpenResellerMenu() local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if closestPlayer == -1 or closestDistance > 3.0 then + if closestPlayer == -1 or closestDistance > 5.0 then ESX.ShowNotification('Aucun joueur à proximité') else @@ -504,10 +469,7 @@ function OpenPopVehicleMenu() local model = data.current.value - if IsAnyVehicleNearPoint(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 3.0) then - local vehicle = GetClosestVehicle(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 3.0, 0, 71) - DeleteVehicle(vehicle) - end + DeleteShopInsideVehicle() ESX.Game.SpawnLocalVehicle(model, { x = Config.Zones.ShopInside.Pos.x, diff --git a/config.lua b/config.lua index 5c6f2113..238ef765 100644 --- a/config.lua +++ b/config.lua @@ -1,7 +1,7 @@ Config = {} Config.DrawDistance = 100.0 Config.MarkerColor = {r = 120, g = 120, b = 240} -Config.EnablePlayerManagement = false -- If set to true, you need esx_billing and esx_society +Config.EnablePlayerManagement = false -- If set to true, you need esx_addonaccount, esx_billing and esx_society Config.EnablePvCommand = true Config.ResellPercentage = 50 From ce467b7ba7bf03732c4e4611af27beee8f708d79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 13:01:46 +0200 Subject: [PATCH 0297/3224] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 030c4346..58a49a4f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ # fxserver-esx_basicneeds FXServer ESX Basic Needs +[REQUIREMENTS] + +- esx_status => https://github.com/FXServer-ESX/fxserver-esx_status + [INFO] This plugin add hunger and thirst status, they can be increased when eating bread or drinking water From 6e0a1a31ed70d7c51e9b705d5f4285f89ab5df73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 13:12:59 +0200 Subject: [PATCH 0298/3224] Fix StatusMax --- server/classes/status.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/classes/status.lua b/server/classes/status.lua index f400eb53..b81969cc 100644 --- a/server/classes/status.lua +++ b/server/classes/status.lua @@ -2,7 +2,7 @@ function CreateStatus(xPlayer, name, default, color, visible, tickCallback, clie local self = {} - self.val = default + self.val = default self.xPlayer = xPlayer self.name = name self.default = default @@ -29,7 +29,7 @@ function CreateStatus(xPlayer, name, default, color, visible, tickCallback, clie self.add = function(val) if self.val + val > Config.StatusMax then - self.val = StatusMax + self.val = Config.StatusMax else self.val = self.val + val end From f4d131b6a9303e599f62dfac3d55faad2274739a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 13:13:36 +0200 Subject: [PATCH 0299/3224] Fix ESX.RegisterUsableItem --- server/main.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/server/main.lua b/server/main.lua index ec61b623..ac790c30 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,3 +1,7 @@ +ESX = nil + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + TriggerEvent('esx_status:registerStatus', 'hunger', 1000000, '#CFAD0F', function(status) return true @@ -35,7 +39,7 @@ AddEventHandler('esx_basicneeds:resetStatus', function() end) -TriggerEvent('esx:registerUsableItem', 'bread', function(source) +ESX.RegisterUsableItem('bread', function(source) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) @@ -54,7 +58,7 @@ TriggerEvent('esx:registerUsableItem', 'bread', function(source) end) -TriggerEvent('esx:registerUsableItem', 'water', function(source) +ESX.RegisterUsableItem('water', function(source) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) From f2c068f981561a1b247dcb8de385db649bb75983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 14:12:29 +0200 Subject: [PATCH 0300/3224] Really fix vehicle spawn in each other --- client/main.lua | 148 +++++++++++++++++++++++++++--------------------- server/main.lua | 4 +- 2 files changed, 84 insertions(+), 68 deletions(-) diff --git a/client/main.lua b/client/main.lua index 93c7562b..48a6a055 100644 --- a/client/main.lua +++ b/client/main.lua @@ -41,21 +41,27 @@ Citizen.CreateThread(function() end) -function DeleteShopInsideVehicle() +function DeleteShopInsideVehicle(cb) - if IsAnyVehicleNearPoint(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 5.0) then + Citizen.CreateThread(function() + + while IsAnyVehicleNearPoint(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 5.0) do + + local vehicle, distance = ESX.Game.GetClosestVehicle(Config.Zones.ShopInside.Pos) - local vehicle, distance = ESX.Game.GetClosestVehicle({ - x = Config.Zones.ShopInside.Pos.x, - y = Config.Zones.ShopInside.Pos.y, - z = Config.Zones.ShopInside.Pos.z - }) - - if distance <= 5.0 then - DeleteVehicle(vehicle) + if distance <= 5.0 then + ESX.Game.DeleteVehicle(vehicle) + end + + Citizen.Wait(0) + end - - end + + if cb ~= nil then + cb() + end + + end) end @@ -157,25 +163,27 @@ function OpenShopMenu() if hasEnoughMoney then - DeleteShopInsideVehicle() + DeleteShopInsideVehicle(function() - ESX.Game.SpawnVehicle(vehicleData.model, { - x = Config.Zones.ShopOutside.Pos.x, - y = Config.Zones.ShopOutside.Pos.y, - z = Config.Zones.ShopOutside.Pos.z - }, -20.0, function(vehicle) - - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + ESX.Game.SpawnVehicle(vehicleData.model, { + x = Config.Zones.ShopOutside.Pos.x, + y = Config.Zones.ShopOutside.Pos.y, + z = Config.Zones.ShopOutside.Pos.z + }, -20.0, function(vehicle) + + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) + local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) - TriggerServerEvent('esx_vehicleshop:setVehicleOwned', vehicleProps) + TriggerServerEvent('esx_vehicleshop:setVehicleOwned', vehicleProps) + + end) + + FreezeEntityPosition(playerPed, false) + SetEntityVisible(playerPed, true) end) - FreezeEntityPosition(playerPed, false) - SetEntityVisible(playerPed, true) - else ESX.ShowNotification('Vous n\'avez pas assez d\'argent') end @@ -201,22 +209,24 @@ function OpenShopMenu() menu.close() - local playerPed = GetPlayerPed(-1) + DeleteShopInsideVehicle(function() - CurrentAction = 'shop_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' - CurrentActionData = {} + local playerPed = GetPlayerPed(-1) + CurrentAction = 'shop_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {} + FreezeEntityPosition(playerPed, false) + SetEntityVisible(playerPed, true) - FreezeEntityPosition(playerPed, false) - SetEntityVisible(playerPed, true) + if Config.EnablePlayerManagement then + SetEntityCoords(playerPed, Config.Zones.BossActions.Pos.x, Config.Zones.BossActions.Pos.y, Config.Zones.BossActions.Pos.z) + else + SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos.x, Config.Zones.ShopEntering.Pos.y, Config.Zones.ShopEntering.Pos.z) + end - if Config.EnablePlayerManagement then - SetEntityCoords(playerPed, Config.Zones.BossActions.Pos.x, Config.Zones.BossActions.Pos.y, Config.Zones.BossActions.Pos.z) - else - SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos.x, Config.Zones.ShopEntering.Pos.y, Config.Zones.ShopEntering.Pos.z) - end + end) end, function(data, menu) @@ -224,31 +234,35 @@ function OpenShopMenu() local vehicleData = vehiclesByCategory[data.current.name][data.current.value + 1] local playerPed = GetPlayerPed(-1) - DeleteShopInsideVehicle() + DeleteShopInsideVehicle(function() + + ESX.Game.SpawnLocalVehicle(vehicleData.model, { + x = Config.Zones.ShopInside.Pos.x, + y = Config.Zones.ShopInside.Pos.y, + z = Config.Zones.ShopInside.Pos.z + }, 90.0, function(vehicle) + CurrentVehicle = vehicle + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + FreezeEntityPosition(vehicle, true) + end) - ESX.Game.SpawnLocalVehicle(vehicleData.model, { - x = Config.Zones.ShopInside.Pos.x, - y = Config.Zones.ShopInside.Pos.y, - z = Config.Zones.ShopInside.Pos.z - }, 90.0, function(vehicle) - CurrentVehicle = vehicle - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - FreezeEntityPosition(vehicle, true) end) end ) - DeleteShopInsideVehicle() + DeleteShopInsideVehicle(function() + + ESX.Game.SpawnLocalVehicle(firstVehicleData.model, { + x = Config.Zones.ShopInside.Pos.x, + y = Config.Zones.ShopInside.Pos.y, + z = Config.Zones.ShopInside.Pos.z + }, 90.0, function(vehicle) + CurrentVehicle = vehicle + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + FreezeEntityPosition(vehicle, true) + end) - ESX.Game.SpawnLocalVehicle(firstVehicleData.model, { - x = Config.Zones.ShopInside.Pos.x, - y = Config.Zones.ShopInside.Pos.y, - z = Config.Zones.ShopInside.Pos.z - }, 90.0, function(vehicle) - CurrentVehicle = vehicle - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - FreezeEntityPosition(vehicle, true) end) end @@ -469,21 +483,23 @@ function OpenPopVehicleMenu() local model = data.current.value - DeleteShopInsideVehicle() + DeleteShopInsideVehicle(function() - ESX.Game.SpawnLocalVehicle(model, { - x = Config.Zones.ShopInside.Pos.x, - y = Config.Zones.ShopInside.Pos.y, - z = Config.Zones.ShopInside.Pos.z - }, 90.0, function(vehicle) - - CurrentVehicle = vehicle + ESX.Game.SpawnLocalVehicle(model, { + x = Config.Zones.ShopInside.Pos.x, + y = Config.Zones.ShopInside.Pos.y, + z = Config.Zones.ShopInside.Pos.z + }, 90.0, function(vehicle) + + CurrentVehicle = vehicle - for i=1, #Vehicles, 1 do - if model == Vehicles[i].model then - CurrentVehicleData = Vehicles[i] + for i=1, #Vehicles, 1 do + if model == Vehicles[i].model then + CurrentVehicleData = Vehicles[i] + end end - end + + end) end) diff --git a/server/main.lua b/server/main.lua index 2c31860c..83ef44ec 100644 --- a/server/main.lua +++ b/server/main.lua @@ -33,7 +33,7 @@ function RemoveOwnedVehicle(plate) end -AddEventHandler('onMySQLReady', function() +-- AddEventHandler('onMySQLReady', function() Categories = MySQL.Sync.fetchAll('SELECT * FROM vehicle_categories') local vehicles = MySQL.Sync.fetchAll('SELECT * FROM vehicles') @@ -52,7 +52,7 @@ AddEventHandler('onMySQLReady', function() end -end) +-- end) RegisterServerEvent('esx_vehicleshop:setVehicleOwned') AddEventHandler('esx_vehicleshop:setVehicleOwned', function(vehicleProps) From 865f986e49ff009ff21920d11d632fb82a99d84a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 14:20:31 +0200 Subject: [PATCH 0301/3224] Put back onMySQLReady event --- server/main.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/main.lua b/server/main.lua index 83ef44ec..2c31860c 100644 --- a/server/main.lua +++ b/server/main.lua @@ -33,7 +33,7 @@ function RemoveOwnedVehicle(plate) end --- AddEventHandler('onMySQLReady', function() +AddEventHandler('onMySQLReady', function() Categories = MySQL.Sync.fetchAll('SELECT * FROM vehicle_categories') local vehicles = MySQL.Sync.fetchAll('SELECT * FROM vehicles') @@ -52,7 +52,7 @@ end end --- end) +end) RegisterServerEvent('esx_vehicleshop:setVehicleOwned') AddEventHandler('esx_vehicleshop:setVehicleOwned', function(vehicleProps) From ae5d1433dbc9d1c4488e771de75b26f5af71204b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 14:46:42 +0200 Subject: [PATCH 0302/3224] Menu fixes --- client/main.lua | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/client/main.lua b/client/main.lua index 48a6a055..19060077 100644 --- a/client/main.lua +++ b/client/main.lua @@ -138,8 +138,6 @@ function OpenShopMenu() }, function(data2, menu2) - menu2.close() - if data2.current.value == 'yes' then if Config.EnablePlayerManagement then @@ -147,6 +145,10 @@ function OpenShopMenu() ESX.TriggerServerCallback('esx_vehicleshop:buyVehicleSociety', function(hasEnoughMoney) if hasEnoughMoney then + + menu.close() + menu2.close() + ESX.ShowNotification('Vous avez acheté un véhicule') else ESX.ShowNotification('Vous n\'avez pas assez d\'argent sur votre compte société') @@ -156,13 +158,13 @@ function OpenShopMenu() else - menu2.close() - menu.close() - ESX.TriggerServerCallback('esx_vehicleshop:buyVehicle', function(hasEnoughMoney) if hasEnoughMoney then + menu.close() + menu2.close() + DeleteShopInsideVehicle(function() ESX.Game.SpawnVehicle(vehicleData.model, { From c974a834d02d56ca3764c92f263222f9508996d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 16:12:45 +0200 Subject: [PATCH 0303/3224] Enable html in menus --- __resource.lua | 4 ++++ html/js/app.js | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/__resource.lua b/__resource.lua index 3774ff9e..8940757b 100644 --- a/__resource.lua +++ b/__resource.lua @@ -20,4 +20,8 @@ files { 'html/img/cursor.png', 'html/img/keys/enter.png', 'html/img/keys/return.png', +} + +dependencies { + 'es_extended' } \ No newline at end of file diff --git a/html/js/app.js b/html/js/app.js index 213c0d59..2ca0f6de 100644 --- a/html/js/app.js +++ b/html/js/app.js @@ -2,11 +2,11 @@ let MenuTpl = '
' + + ''+ + '' + ; + + let DefaultWithTypeAndCountTpl = + '
{{title}}
' + + ''+ + '' + ; + + let CustomersTpl = + '' + + '' + + 'Client' + + 'Solde' + + 'Actions' + + '' + + '' + + '' + + '{{#customers}}' + + '' + + '{{name}}' + + '${{bank_savings}}' + + '' + + '' + + '' + + '' + + '' + + '{{/customers}}' + + '' + ; + + let menus = { + + banque : { + title : 'Banque', + visible : false, + current : -1, + hasControl: false, + template : DefaultTpl, + + items: [ + {label: 'Clients', value: 'customers'}, + {label: 'Retirer argent société', value: 'withdraw_society_money'}, + {label: 'Blanchir de l\'argent', value: 'wash_money'} + ] + }, + + banque_actions : { + title : 'Banque', + visible : false, + current : 0, + hasControl: true, + template : DefaultTpl, + + items: [] + }, + } + + let renderMenus = function(){ + for(let k in menus){ + + let elem = $('#menu_' + k); + + elem.html(Mustache.render(menus[k].template, menus[k])); + + if(menus[k].visible) + elem.show(); + else + elem.hide(); + + } + } + + let showMenu = function(menu){ + + currentMenu = menu; + + for(let k in menus) + menus[k].visible = false; + + menus[menu].visible = true; + + renderMenus(); + + if(menus[currentMenu].items.length > 0){ + + $('#menu_' + currentMenu + ' .menu-item').removeClass('selected'); + $('#menu_' + currentMenu + ' .menu-item:eq(0)').addClass('selected'); + + menus[currentMenu].current = 0; + currentVal = menus[currentMenu].items[menus[currentMenu].current].value; + currentType = $('#menu_' + currentMenu + ' .menu-item:eq(0)').data('type'); + currentAction = $('#menu_' + currentMenu + ' .menu-item:eq(0)').data('action'); + currentCount = $('#menu_' + currentMenu + ' .menu-item:eq(0)').data('count'); + } + + $('#ctl_return').show(); + + isMenuOpen = true + isShowingControls = false + } + + let hideMenus = function(){ + + for(let k in menus) + menus[k].visible = false; + + renderMenus(); + isMenuOpen = false; + } + + let showControl = function(control){ + + hideControls(); + $('#ctl_' + control).show(); + isShowingControls = true; + currentControl = control; + } + + let hideControls = function(){ + + for(let k in menus) + $('#ctl_' + k).hide(); + + $('#ctl_return').hide(); + + isShowingControls = false; + } + + let showCustomers = function(customers, bankMoney){ + + let view = { + customers: customers + } + + $('#bank-money').text('$' + bankMoney) + $('#customer-list').html(Mustache.render(CustomersTpl, view)); + + $('#customer-list .transfer-btn').click(function(){ + showTransferDialog($(this).data('identifier')) + }); + + $('#customer-list .withdraw-btn').click(function(){ + showWithdrawBankSavingsDialog($(this).data('identifier')) + }); + + $('#customers').show(); + $(cursor).show(); + } + + let hideCustomers = function(){ + $('#customers').hide(); + $(cursor).hide(); + } + + let showTransferDialog = function(identifier){ + $('#transfer-dialog-amount').val(''); + $('#transfer-dialog-identifier').val(identifier); + $('#transfer-dialog').show(); + } + + let hideTransferDialog = function(){ + $('#transfer-dialog').hide(); + } + + let showWithdrawBankSavingsDialog = function(identifier){ + $('#withdraw-bank-savings-dialog-amount').val(''); + $('#withdraw-bank-savings-dialog-identifier').val(identifier); + $('#withdraw-bank-savings-dialog').show(); + } + + let hideWithdrawBankSavingsDialog = function(){ + $('#withdraw-bank-savings-dialog').hide(); + } + + let showBillingDialog = function(){ + $('#billing-dialog-amount').val(''); + $('#billing-dialog').show(); + $(cursor).show(); + } + + let hideBillingDialog = function(){ + $('#billing-dialog').hide(); + $(cursor).hide(); + } + + let showWithdrawDialog = function(){ + $('#withdraw-dialog-amount').val(''); + $('#withdraw-dialog').show(); + $(cursor).show(); + } + + let hideWithdrawDialog = function(){ + $('#withdraw-dialog').hide(); + $(cursor).hide(); + } + + let showWashMoneyDialog = function(){ + $('#washmoney-dialog-amount').val(''); + $('#washmoney-dialog').show(); + $(cursor).show(); + } + + let hideWashMoneyDialog = function(){ + $('#washmoney-dialog').hide(); + $(cursor).hide(); + } + + let showWithdrawSocietyMoneyDialog = function(){ + $('#withdraw-society-money-dialog-amount').val(''); + $('#withdraw-society-money-dialog').show(); + $(cursor).show(); + } + + let hideWithdrawSocietyMoneyDialog = function(){ + $('#withdraw-society-money-dialog').hide(); + $(cursor).hide(); + } + + $('#transfer-dialog-send').click(function(){ + + $.post('http://esx_bankerjob/transfer', JSON.stringify({ + identifier: $('#transfer-dialog-identifier').val(), + amount : parseFloat($('#transfer-dialog-amount').val()) + })) + + hideTransferDialog(); + + }); + + $('#withdraw-bank-savings-dialog-send').click(function(){ + + $.post('http://esx_bankerjob/withdraw_bank_savings', JSON.stringify({ + identifier: $('#withdraw-bank-savings-dialog-identifier').val(), + amount : parseFloat($('#withdraw-bank-savings-dialog-amount').val()) + })) + + hideWithdrawBankSavingsDialog(); + + }); + + $('#billing-dialog-send').click(function(){ + + $.post('http://esx_bankerjob/billing', JSON.stringify({ + amount: parseFloat($('#billing-dialog-amount').val()) + })) + + hideBillingDialog(); + + }); + + $('#withdraw-dialog-send').click(function(){ + + $.post('http://esx_bankerjob/withdraw', JSON.stringify({ + amount: parseFloat($('#withdraw-dialog-amount').val()) + })) + + hideWithdrawDialog(); + + }); + + $('#washmoney-dialog-send').click(function(){ + + $.post('http://esx_bankerjob/wash_money', JSON.stringify({ + amount: parseFloat($('#washmoney-dialog-amount').val()) + })) + + hideWashMoneyDialog(); + + }); + + $('#withdraw-society-money-dialog-send').click(function(){ + $.post('http://esx_bankerjob/withdraw_society_money', JSON.stringify({ + amount: parseFloat($('#withdraw-society-money-dialog-amount').val()) + })) + + hideWithdrawSocietyMoneyDialog(); + }); + + let documentWidth = document.documentElement.clientWidth; + let documentHeight = document.documentElement.clientHeight; + + let cursor = document.getElementById("cursor"); + let cursorX = documentWidth / 2; + let cursorY = documentHeight / 2; + + function UpdateCursorPos() { + cursor.style.left = cursorX; + cursor.style.top = cursorY; + } + + function Click(x, y) { + let element = $(document.elementFromPoint(x, y)); + element.focus().click(); + } + + function scrollCustomers(direction){ + + let element = $('#customers .head-content')[0]; + + if(direction == 'UP') + element.scrollTop -= 32; + + if(direction == 'DOWN') + element.scrollTop += 32; + + } + + $(document).mousemove(function(event) { + cursorX = event.pageX; + cursorY = event.pageY; + UpdateCursorPos(); + }); + + let isMenuOpen = false + let isShowingControls = false; + let currentMenu = null; + let currentControl = null; + let currentVal = null; + let currentType = null; + let currentAction = null; + let currentCount = null; + + renderMenus(); + + window.onData = function(data){ + + if(data.click === true){ + Click(cursorX - 1, cursorY - 1); + } + + if(data.showControls === true){ + currentMenu = data.controls; + showControl(data.controls); + } + + if(data.showControls === false){ + hideControls(); + } + + if(data.showMenu === true){ + hideControls(); + + if(data.items) + menus[data.menu].items = data.items + + showMenu(data.menu); + } + + if(data.showMenu === false){ + hideMenus(); + } + + if(data.showCustomers === true){ + showCustomers(data.customers, data.bankMoney); + } + + if(data.showCustomers === false){ + hideCustomers(); + } + + if(data.showBillingDialog === true){ + showBillingDialog(); + } + + if(data.showBillingDialog === false){ + hideBillingDialog(); + } + + if(data.showWithdrawDialog === true){ + showWithdrawDialog(); + } + + if(data.showWithdrawDialog === false){ + hideWithdrawDialog(); + } + + if(data.showWashMoneyDialog === true){ + showWashMoneyDialog(); + } + + if(data.showWashMoneyDialog === false){ + hideWashMoneyDialog(); + } + + if(data.showWithdrawSocietyMoneyDialog === true){ + showWithdrawSocietyMoneyDialog(); + } + + if(data.showWithdrawSocietyMoneyDialog === false){ + hideWithdrawSocietyMoneyDialog(); + } + + if(data.move && isMenuOpen){ + + if(data.move == 'UP'){ + if(menus[currentMenu].current > 0) + menus[currentMenu].current--; + } + + if(data.move == 'DOWN'){ + + let max = $('#menu_' + currentMenu + ' .menu-item').length; + + if(menus[currentMenu].current < max - 1) + menus[currentMenu].current++; + } + + $('#menu_' + currentMenu + ' .menu-item').removeClass('selected'); + $('#menu_' + currentMenu + ' .menu-item:eq(' + menus[currentMenu].current + ')').addClass('selected'); + + currentVal = menus[currentMenu].items[menus[currentMenu].current].value; + currentType = $('#menu_' + currentMenu + ' .menu-item:eq(' + menus[currentMenu].current + ')').data('type'); + currentAction = $('#menu_' + currentMenu + ' .menu-item:eq(' + menus[currentMenu].current + ')').data('action'); + currentCount = $('#menu_' + currentMenu + ' .menu-item:eq(' + menus[currentMenu].current + ')').data('count'); + } + + if(data.enterPressed){ + + if(isShowingControls){ + + $.post('http://esx_bankerjob/select_control', JSON.stringify({ + control: currentControl, + })) + + hideControls(); + showMenu(currentMenu); + + } else if(isMenuOpen) { + + if(menus[currentMenu].current != -1){ + $.post('http://esx_bankerjob/select', JSON.stringify({ + menu : currentMenu, + val : currentVal, + type : currentType, + action: currentAction, + count : currentCount + })) + } + + let elem = $('#menu_' + currentMenu + ' .menu-item.selected') + + if(elem.data('remove-on-select') == true){ + + elem.remove(); + + menus[currentMenu].items.splice(menus[currentMenu].current, 1) + menus[currentMenu].current = 0; + + $('#menu_' + currentMenu + ' .menu-item').removeClass('selected'); + $('#menu_' + currentMenu + ' .menu-item:eq(0)').addClass('selected'); + + currentVal = menus[currentMenu].items[0].value; + currentType = $('#menu_' + currentMenu + ' .menu-item:eq(0)').data('type'); + currentAction = $('#menu_' + currentMenu + ' .menu-item:eq(0)').data('action'); + currentCount = $('#menu_' + currentMenu + ' .menu-item:eq(0)').data('count'); + } + + } + + } + + if(data.backspacePressed){ + + if(isMenuOpen && currentMenu == 'banque'){ + hideMenus(); + $('#ctl_return').hide(); + showControl('banque'); + } + + if(isMenuOpen && currentMenu == 'banque_actions'){ + hideMenus(); + $('#ctl_return').hide(); + } + + } + } + + document.onkeyup = function (data) { + if (data.which == 27) { + $.post('http://esx_bankerjob/escape', '{}'); + } + }; + + document.onwheel = function (data) { + + if (data.deltaY < 0) { + scrollCustomers('UP'); + } + + if (data.deltaY > 0) { + scrollCustomers('DOWN'); + } + + }; + + $('form').submit(function(){ + return false; + }); + + window.onload = function(e){ window.addEventListener('message', function(event){ onData(event.data) }); } + +})() \ No newline at end of file diff --git a/html/scripts/bootstrap.js b/html/scripts/bootstrap.js new file mode 100644 index 00000000..8a2e99a5 --- /dev/null +++ b/html/scripts/bootstrap.js @@ -0,0 +1,2377 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under the MIT license + */ + +if (typeof jQuery === 'undefined') { + throw new Error('Bootstrap\'s JavaScript requires jQuery') +} + ++function ($) { + 'use strict'; + var version = $.fn.jquery.split(' ')[0].split('.') + if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) { + throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4') + } +}(jQuery); + +/* ======================================================================== + * Bootstrap: transition.js v3.3.7 + * http://getbootstrap.com/javascript/#transitions + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) + // ============================================================ + + function transitionEnd() { + var el = document.createElement('bootstrap') + + var transEndEventNames = { + WebkitTransition : 'webkitTransitionEnd', + MozTransition : 'transitionend', + OTransition : 'oTransitionEnd otransitionend', + transition : 'transitionend' + } + + for (var name in transEndEventNames) { + if (el.style[name] !== undefined) { + return { end: transEndEventNames[name] } + } + } + + return false // explicit for ie8 ( ._.) + } + + // http://blog.alexmaccaw.com/css-transitions + $.fn.emulateTransitionEnd = function (duration) { + var called = false + var $el = this + $(this).one('bsTransitionEnd', function () { called = true }) + var callback = function () { if (!called) $($el).trigger($.support.transition.end) } + setTimeout(callback, duration) + return this + } + + $(function () { + $.support.transition = transitionEnd() + + if (!$.support.transition) return + + $.event.special.bsTransitionEnd = { + bindType: $.support.transition.end, + delegateType: $.support.transition.end, + handle: function (e) { + if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) + } + } + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: alert.js v3.3.7 + * http://getbootstrap.com/javascript/#alerts + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // ALERT CLASS DEFINITION + // ====================== + + var dismiss = '[data-dismiss="alert"]' + var Alert = function (el) { + $(el).on('click', dismiss, this.close) + } + + Alert.VERSION = '3.3.7' + + Alert.TRANSITION_DURATION = 150 + + Alert.prototype.close = function (e) { + var $this = $(this) + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + var $parent = $(selector === '#' ? [] : selector) + + if (e) e.preventDefault() + + if (!$parent.length) { + $parent = $this.closest('.alert') + } + + $parent.trigger(e = $.Event('close.bs.alert')) + + if (e.isDefaultPrevented()) return + + $parent.removeClass('in') + + function removeElement() { + // detach from parent, fire event then clean up data + $parent.detach().trigger('closed.bs.alert').remove() + } + + $.support.transition && $parent.hasClass('fade') ? + $parent + .one('bsTransitionEnd', removeElement) + .emulateTransitionEnd(Alert.TRANSITION_DURATION) : + removeElement() + } + + + // ALERT PLUGIN DEFINITION + // ======================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.alert') + + if (!data) $this.data('bs.alert', (data = new Alert(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.alert + + $.fn.alert = Plugin + $.fn.alert.Constructor = Alert + + + // ALERT NO CONFLICT + // ================= + + $.fn.alert.noConflict = function () { + $.fn.alert = old + return this + } + + + // ALERT DATA-API + // ============== + + $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: button.js v3.3.7 + * http://getbootstrap.com/javascript/#buttons + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // BUTTON PUBLIC CLASS DEFINITION + // ============================== + + var Button = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Button.DEFAULTS, options) + this.isLoading = false + } + + Button.VERSION = '3.3.7' + + Button.DEFAULTS = { + loadingText: 'loading...' + } + + Button.prototype.setState = function (state) { + var d = 'disabled' + var $el = this.$element + var val = $el.is('input') ? 'val' : 'html' + var data = $el.data() + + state += 'Text' + + if (data.resetText == null) $el.data('resetText', $el[val]()) + + // push to event loop to allow forms to submit + setTimeout($.proxy(function () { + $el[val](data[state] == null ? this.options[state] : data[state]) + + if (state == 'loadingText') { + this.isLoading = true + $el.addClass(d).attr(d, d).prop(d, true) + } else if (this.isLoading) { + this.isLoading = false + $el.removeClass(d).removeAttr(d).prop(d, false) + } + }, this), 0) + } + + Button.prototype.toggle = function () { + var changed = true + var $parent = this.$element.closest('[data-toggle="buttons"]') + + if ($parent.length) { + var $input = this.$element.find('input') + if ($input.prop('type') == 'radio') { + if ($input.prop('checked')) changed = false + $parent.find('.active').removeClass('active') + this.$element.addClass('active') + } else if ($input.prop('type') == 'checkbox') { + if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false + this.$element.toggleClass('active') + } + $input.prop('checked', this.$element.hasClass('active')) + if (changed) $input.trigger('change') + } else { + this.$element.attr('aria-pressed', !this.$element.hasClass('active')) + this.$element.toggleClass('active') + } + } + + + // BUTTON PLUGIN DEFINITION + // ======================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.button') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.button', (data = new Button(this, options))) + + if (option == 'toggle') data.toggle() + else if (option) data.setState(option) + }) + } + + var old = $.fn.button + + $.fn.button = Plugin + $.fn.button.Constructor = Button + + + // BUTTON NO CONFLICT + // ================== + + $.fn.button.noConflict = function () { + $.fn.button = old + return this + } + + + // BUTTON DATA-API + // =============== + + $(document) + .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { + var $btn = $(e.target).closest('.btn') + Plugin.call($btn, 'toggle') + if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) { + // Prevent double click on radios, and the double selections (so cancellation) on checkboxes + e.preventDefault() + // The target component still receive the focus + if ($btn.is('input,button')) $btn.trigger('focus') + else $btn.find('input:visible,button:visible').first().trigger('focus') + } + }) + .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { + $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: carousel.js v3.3.7 + * http://getbootstrap.com/javascript/#carousel + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // CAROUSEL CLASS DEFINITION + // ========================= + + var Carousel = function (element, options) { + this.$element = $(element) + this.$indicators = this.$element.find('.carousel-indicators') + this.options = options + this.paused = null + this.sliding = null + this.interval = null + this.$active = null + this.$items = null + + this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) + + this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element + .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) + .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) + } + + Carousel.VERSION = '3.3.7' + + Carousel.TRANSITION_DURATION = 600 + + Carousel.DEFAULTS = { + interval: 5000, + pause: 'hover', + wrap: true, + keyboard: true + } + + Carousel.prototype.keydown = function (e) { + if (/input|textarea/i.test(e.target.tagName)) return + switch (e.which) { + case 37: this.prev(); break + case 39: this.next(); break + default: return + } + + e.preventDefault() + } + + Carousel.prototype.cycle = function (e) { + e || (this.paused = false) + + this.interval && clearInterval(this.interval) + + this.options.interval + && !this.paused + && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) + + return this + } + + Carousel.prototype.getItemIndex = function (item) { + this.$items = item.parent().children('.item') + return this.$items.index(item || this.$active) + } + + Carousel.prototype.getItemForDirection = function (direction, active) { + var activeIndex = this.getItemIndex(active) + var willWrap = (direction == 'prev' && activeIndex === 0) + || (direction == 'next' && activeIndex == (this.$items.length - 1)) + if (willWrap && !this.options.wrap) return active + var delta = direction == 'prev' ? -1 : 1 + var itemIndex = (activeIndex + delta) % this.$items.length + return this.$items.eq(itemIndex) + } + + Carousel.prototype.to = function (pos) { + var that = this + var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) + + if (pos > (this.$items.length - 1) || pos < 0) return + + if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" + if (activeIndex == pos) return this.pause().cycle() + + return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) + } + + Carousel.prototype.pause = function (e) { + e || (this.paused = true) + + if (this.$element.find('.next, .prev').length && $.support.transition) { + this.$element.trigger($.support.transition.end) + this.cycle(true) + } + + this.interval = clearInterval(this.interval) + + return this + } + + Carousel.prototype.next = function () { + if (this.sliding) return + return this.slide('next') + } + + Carousel.prototype.prev = function () { + if (this.sliding) return + return this.slide('prev') + } + + Carousel.prototype.slide = function (type, next) { + var $active = this.$element.find('.item.active') + var $next = next || this.getItemForDirection(type, $active) + var isCycling = this.interval + var direction = type == 'next' ? 'left' : 'right' + var that = this + + if ($next.hasClass('active')) return (this.sliding = false) + + var relatedTarget = $next[0] + var slideEvent = $.Event('slide.bs.carousel', { + relatedTarget: relatedTarget, + direction: direction + }) + this.$element.trigger(slideEvent) + if (slideEvent.isDefaultPrevented()) return + + this.sliding = true + + isCycling && this.pause() + + if (this.$indicators.length) { + this.$indicators.find('.active').removeClass('active') + var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) + $nextIndicator && $nextIndicator.addClass('active') + } + + var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" + if ($.support.transition && this.$element.hasClass('slide')) { + $next.addClass(type) + $next[0].offsetWidth // force reflow + $active.addClass(direction) + $next.addClass(direction) + $active + .one('bsTransitionEnd', function () { + $next.removeClass([type, direction].join(' ')).addClass('active') + $active.removeClass(['active', direction].join(' ')) + that.sliding = false + setTimeout(function () { + that.$element.trigger(slidEvent) + }, 0) + }) + .emulateTransitionEnd(Carousel.TRANSITION_DURATION) + } else { + $active.removeClass('active') + $next.addClass('active') + this.sliding = false + this.$element.trigger(slidEvent) + } + + isCycling && this.cycle() + + return this + } + + + // CAROUSEL PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.carousel') + var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) + var action = typeof option == 'string' ? option : options.slide + + if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) + if (typeof option == 'number') data.to(option) + else if (action) data[action]() + else if (options.interval) data.pause().cycle() + }) + } + + var old = $.fn.carousel + + $.fn.carousel = Plugin + $.fn.carousel.Constructor = Carousel + + + // CAROUSEL NO CONFLICT + // ==================== + + $.fn.carousel.noConflict = function () { + $.fn.carousel = old + return this + } + + + // CAROUSEL DATA-API + // ================= + + var clickHandler = function (e) { + var href + var $this = $(this) + var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 + if (!$target.hasClass('carousel')) return + var options = $.extend({}, $target.data(), $this.data()) + var slideIndex = $this.attr('data-slide-to') + if (slideIndex) options.interval = false + + Plugin.call($target, options) + + if (slideIndex) { + $target.data('bs.carousel').to(slideIndex) + } + + e.preventDefault() + } + + $(document) + .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) + .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) + + $(window).on('load', function () { + $('[data-ride="carousel"]').each(function () { + var $carousel = $(this) + Plugin.call($carousel, $carousel.data()) + }) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: collapse.js v3.3.7 + * http://getbootstrap.com/javascript/#collapse + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + +/* jshint latedef: false */ + ++function ($) { + 'use strict'; + + // COLLAPSE PUBLIC CLASS DEFINITION + // ================================ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Collapse.DEFAULTS, options) + this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' + + '[data-toggle="collapse"][data-target="#' + element.id + '"]') + this.transitioning = null + + if (this.options.parent) { + this.$parent = this.getParent() + } else { + this.addAriaAndCollapsedClass(this.$element, this.$trigger) + } + + if (this.options.toggle) this.toggle() + } + + Collapse.VERSION = '3.3.7' + + Collapse.TRANSITION_DURATION = 350 + + Collapse.DEFAULTS = { + toggle: true + } + + Collapse.prototype.dimension = function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } + + Collapse.prototype.show = function () { + if (this.transitioning || this.$element.hasClass('in')) return + + var activesData + var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') + + if (actives && actives.length) { + activesData = actives.data('bs.collapse') + if (activesData && activesData.transitioning) return + } + + var startEvent = $.Event('show.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + if (actives && actives.length) { + Plugin.call(actives, 'hide') + activesData || actives.data('bs.collapse', null) + } + + var dimension = this.dimension() + + this.$element + .removeClass('collapse') + .addClass('collapsing')[dimension](0) + .attr('aria-expanded', true) + + this.$trigger + .removeClass('collapsed') + .attr('aria-expanded', true) + + this.transitioning = 1 + + var complete = function () { + this.$element + .removeClass('collapsing') + .addClass('collapse in')[dimension]('') + this.transitioning = 0 + this.$element + .trigger('shown.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + var scrollSize = $.camelCase(['scroll', dimension].join('-')) + + this.$element + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) + } + + Collapse.prototype.hide = function () { + if (this.transitioning || !this.$element.hasClass('in')) return + + var startEvent = $.Event('hide.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + var dimension = this.dimension() + + this.$element[dimension](this.$element[dimension]())[0].offsetHeight + + this.$element + .addClass('collapsing') + .removeClass('collapse in') + .attr('aria-expanded', false) + + this.$trigger + .addClass('collapsed') + .attr('aria-expanded', false) + + this.transitioning = 1 + + var complete = function () { + this.transitioning = 0 + this.$element + .removeClass('collapsing') + .addClass('collapse') + .trigger('hidden.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + this.$element + [dimension](0) + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION) + } + + Collapse.prototype.toggle = function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + Collapse.prototype.getParent = function () { + return $(this.options.parent) + .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') + .each($.proxy(function (i, element) { + var $element = $(element) + this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) + }, this)) + .end() + } + + Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { + var isOpen = $element.hasClass('in') + + $element.attr('aria-expanded', isOpen) + $trigger + .toggleClass('collapsed', !isOpen) + .attr('aria-expanded', isOpen) + } + + function getTargetFromTrigger($trigger) { + var href + var target = $trigger.attr('data-target') + || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 + + return $(target) + } + + + // COLLAPSE PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.collapse') + var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false + if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.collapse + + $.fn.collapse = Plugin + $.fn.collapse.Constructor = Collapse + + + // COLLAPSE NO CONFLICT + // ==================== + + $.fn.collapse.noConflict = function () { + $.fn.collapse = old + return this + } + + + // COLLAPSE DATA-API + // ================= + + $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { + var $this = $(this) + + if (!$this.attr('data-target')) e.preventDefault() + + var $target = getTargetFromTrigger($this) + var data = $target.data('bs.collapse') + var option = data ? 'toggle' : $this.data() + + Plugin.call($target, option) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: dropdown.js v3.3.7 + * http://getbootstrap.com/javascript/#dropdowns + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // DROPDOWN CLASS DEFINITION + // ========================= + + var backdrop = '.dropdown-backdrop' + var toggle = '[data-toggle="dropdown"]' + var Dropdown = function (element) { + $(element).on('click.bs.dropdown', this.toggle) + } + + Dropdown.VERSION = '3.3.7' + + function getParent($this) { + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + var $parent = selector && $(selector) + + return $parent && $parent.length ? $parent : $this.parent() + } + + function clearMenus(e) { + if (e && e.which === 3) return + $(backdrop).remove() + $(toggle).each(function () { + var $this = $(this) + var $parent = getParent($this) + var relatedTarget = { relatedTarget: this } + + if (!$parent.hasClass('open')) return + + if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return + + $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) + + if (e.isDefaultPrevented()) return + + $this.attr('aria-expanded', 'false') + $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget)) + }) + } + + Dropdown.prototype.toggle = function (e) { + var $this = $(this) + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { + // if mobile we use a backdrop because click events don't delegate + $(document.createElement('div')) + .addClass('dropdown-backdrop') + .insertAfter($(this)) + .on('click', clearMenus) + } + + var relatedTarget = { relatedTarget: this } + $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) + + if (e.isDefaultPrevented()) return + + $this + .trigger('focus') + .attr('aria-expanded', 'true') + + $parent + .toggleClass('open') + .trigger($.Event('shown.bs.dropdown', relatedTarget)) + } + + return false + } + + Dropdown.prototype.keydown = function (e) { + if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return + + var $this = $(this) + + e.preventDefault() + e.stopPropagation() + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + if (!isActive && e.which != 27 || isActive && e.which == 27) { + if (e.which == 27) $parent.find(toggle).trigger('focus') + return $this.trigger('click') + } + + var desc = ' li:not(.disabled):visible a' + var $items = $parent.find('.dropdown-menu' + desc) + + if (!$items.length) return + + var index = $items.index(e.target) + + if (e.which == 38 && index > 0) index-- // up + if (e.which == 40 && index < $items.length - 1) index++ // down + if (!~index) index = 0 + + $items.eq(index).trigger('focus') + } + + + // DROPDOWN PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.dropdown') + + if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.dropdown + + $.fn.dropdown = Plugin + $.fn.dropdown.Constructor = Dropdown + + + // DROPDOWN NO CONFLICT + // ==================== + + $.fn.dropdown.noConflict = function () { + $.fn.dropdown = old + return this + } + + + // APPLY TO STANDARD DROPDOWN ELEMENTS + // =================================== + + $(document) + .on('click.bs.dropdown.data-api', clearMenus) + .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) + .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) + .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) + .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: modal.js v3.3.7 + * http://getbootstrap.com/javascript/#modals + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // MODAL CLASS DEFINITION + // ====================== + + var Modal = function (element, options) { + this.options = options + this.$body = $(document.body) + this.$element = $(element) + this.$dialog = this.$element.find('.modal-dialog') + this.$backdrop = null + this.isShown = null + this.originalBodyPad = null + this.scrollbarWidth = 0 + this.ignoreBackdropClick = false + + if (this.options.remote) { + this.$element + .find('.modal-content') + .load(this.options.remote, $.proxy(function () { + this.$element.trigger('loaded.bs.modal') + }, this)) + } + } + + Modal.VERSION = '3.3.7' + + Modal.TRANSITION_DURATION = 300 + Modal.BACKDROP_TRANSITION_DURATION = 150 + + Modal.DEFAULTS = { + backdrop: true, + keyboard: true, + show: true + } + + Modal.prototype.toggle = function (_relatedTarget) { + return this.isShown ? this.hide() : this.show(_relatedTarget) + } + + Modal.prototype.show = function (_relatedTarget) { + var that = this + var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) + + this.$element.trigger(e) + + if (this.isShown || e.isDefaultPrevented()) return + + this.isShown = true + + this.checkScrollbar() + this.setScrollbar() + this.$body.addClass('modal-open') + + this.escape() + this.resize() + + this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this)) + + this.$dialog.on('mousedown.dismiss.bs.modal', function () { + that.$element.one('mouseup.dismiss.bs.modal', function (e) { + if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true + }) + }) + + this.backdrop(function () { + var transition = $.support.transition && that.$element.hasClass('fade') + + if (!that.$element.parent().length) { + that.$element.appendTo(that.$body) // don't move modals dom position + } + + that.$element + .show() + .scrollTop(0) + + that.adjustDialog() + + if (transition) { + that.$element[0].offsetWidth // force reflow + } + + that.$element.addClass('in') + + that.enforceFocus() + + var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }) + + transition ? + that.$dialog // wait for modal to slide in + .one('bsTransitionEnd', function () { + that.$element.trigger('focus').trigger(e) + }) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + that.$element.trigger('focus').trigger(e) + }) + } + + Modal.prototype.hide = function (e) { + if (e) e.preventDefault() + + e = $.Event('hide.bs.modal') + + this.$element.trigger(e) + + if (!this.isShown || e.isDefaultPrevented()) return + + this.isShown = false + + this.escape() + this.resize() + + $(document).off('focusin.bs.modal') + + this.$element + .removeClass('in') + .off('click.dismiss.bs.modal') + .off('mouseup.dismiss.bs.modal') + + this.$dialog.off('mousedown.dismiss.bs.modal') + + $.support.transition && this.$element.hasClass('fade') ? + this.$element + .one('bsTransitionEnd', $.proxy(this.hideModal, this)) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + this.hideModal() + } + + Modal.prototype.enforceFocus = function () { + $(document) + .off('focusin.bs.modal') // guard against infinite focus loop + .on('focusin.bs.modal', $.proxy(function (e) { + if (document !== e.target && + this.$element[0] !== e.target && + !this.$element.has(e.target).length) { + this.$element.trigger('focus') + } + }, this)) + } + + Modal.prototype.escape = function () { + if (this.isShown && this.options.keyboard) { + this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) { + e.which == 27 && this.hide() + }, this)) + } else if (!this.isShown) { + this.$element.off('keydown.dismiss.bs.modal') + } + } + + Modal.prototype.resize = function () { + if (this.isShown) { + $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this)) + } else { + $(window).off('resize.bs.modal') + } + } + + Modal.prototype.hideModal = function () { + var that = this + this.$element.hide() + this.backdrop(function () { + that.$body.removeClass('modal-open') + that.resetAdjustments() + that.resetScrollbar() + that.$element.trigger('hidden.bs.modal') + }) + } + + Modal.prototype.removeBackdrop = function () { + this.$backdrop && this.$backdrop.remove() + this.$backdrop = null + } + + Modal.prototype.backdrop = function (callback) { + var that = this + var animate = this.$element.hasClass('fade') ? 'fade' : '' + + if (this.isShown && this.options.backdrop) { + var doAnimate = $.support.transition && animate + + this.$backdrop = $(document.createElement('div')) + .addClass('modal-backdrop ' + animate) + .appendTo(this.$body) + + this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) { + if (this.ignoreBackdropClick) { + this.ignoreBackdropClick = false + return + } + if (e.target !== e.currentTarget) return + this.options.backdrop == 'static' + ? this.$element[0].focus() + : this.hide() + }, this)) + + if (doAnimate) this.$backdrop[0].offsetWidth // force reflow + + this.$backdrop.addClass('in') + + if (!callback) return + + doAnimate ? + this.$backdrop + .one('bsTransitionEnd', callback) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callback() + + } else if (!this.isShown && this.$backdrop) { + this.$backdrop.removeClass('in') + + var callbackRemove = function () { + that.removeBackdrop() + callback && callback() + } + $.support.transition && this.$element.hasClass('fade') ? + this.$backdrop + .one('bsTransitionEnd', callbackRemove) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callbackRemove() + + } else if (callback) { + callback() + } + } + + // these following methods are used to handle overflowing modals + + Modal.prototype.handleUpdate = function () { + this.adjustDialog() + } + + Modal.prototype.adjustDialog = function () { + var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight + + this.$element.css({ + paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', + paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' + }) + } + + Modal.prototype.resetAdjustments = function () { + this.$element.css({ + paddingLeft: '', + paddingRight: '' + }) + } + + Modal.prototype.checkScrollbar = function () { + var fullWindowWidth = window.innerWidth + if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8 + var documentElementRect = document.documentElement.getBoundingClientRect() + fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left) + } + this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth + this.scrollbarWidth = this.measureScrollbar() + } + + Modal.prototype.setScrollbar = function () { + var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) + this.originalBodyPad = document.body.style.paddingRight || '' + if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) + } + + Modal.prototype.resetScrollbar = function () { + this.$body.css('padding-right', this.originalBodyPad) + } + + Modal.prototype.measureScrollbar = function () { // thx walsh + var scrollDiv = document.createElement('div') + scrollDiv.className = 'modal-scrollbar-measure' + this.$body.append(scrollDiv) + var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth + this.$body[0].removeChild(scrollDiv) + return scrollbarWidth + } + + + // MODAL PLUGIN DEFINITION + // ======================= + + function Plugin(option, _relatedTarget) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.modal') + var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data) $this.data('bs.modal', (data = new Modal(this, options))) + if (typeof option == 'string') data[option](_relatedTarget) + else if (options.show) data.show(_relatedTarget) + }) + } + + var old = $.fn.modal + + $.fn.modal = Plugin + $.fn.modal.Constructor = Modal + + + // MODAL NO CONFLICT + // ================= + + $.fn.modal.noConflict = function () { + $.fn.modal = old + return this + } + + + // MODAL DATA-API + // ============== + + $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { + var $this = $(this) + var href = $this.attr('href') + var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7 + var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) + + if ($this.is('a')) e.preventDefault() + + $target.one('show.bs.modal', function (showEvent) { + if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown + $target.one('hidden.bs.modal', function () { + $this.is(':visible') && $this.trigger('focus') + }) + }) + Plugin.call($target, option, this) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: tooltip.js v3.3.7 + * http://getbootstrap.com/javascript/#tooltip + * Inspired by the original jQuery.tipsy by Jason Frame + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // TOOLTIP PUBLIC CLASS DEFINITION + // =============================== + + var Tooltip = function (element, options) { + this.type = null + this.options = null + this.enabled = null + this.timeout = null + this.hoverState = null + this.$element = null + this.inState = null + + this.init('tooltip', element, options) + } + + Tooltip.VERSION = '3.3.7' + + Tooltip.TRANSITION_DURATION = 150 + + Tooltip.DEFAULTS = { + animation: true, + placement: 'top', + selector: false, + template: '', + trigger: 'hover focus', + title: '', + delay: 0, + html: false, + container: false, + viewport: { + selector: 'body', + padding: 0 + } + } + + Tooltip.prototype.init = function (type, element, options) { + this.enabled = true + this.type = type + this.$element = $(element) + this.options = this.getOptions(options) + this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport)) + this.inState = { click: false, hover: false, focus: false } + + if (this.$element[0] instanceof document.constructor && !this.options.selector) { + throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!') + } + + var triggers = this.options.trigger.split(' ') + + for (var i = triggers.length; i--;) { + var trigger = triggers[i] + + if (trigger == 'click') { + this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) + } else if (trigger != 'manual') { + var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' + var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' + + this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) + this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) + } + } + + this.options.selector ? + (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : + this.fixTitle() + } + + Tooltip.prototype.getDefaults = function () { + return Tooltip.DEFAULTS + } + + Tooltip.prototype.getOptions = function (options) { + options = $.extend({}, this.getDefaults(), this.$element.data(), options) + + if (options.delay && typeof options.delay == 'number') { + options.delay = { + show: options.delay, + hide: options.delay + } + } + + return options + } + + Tooltip.prototype.getDelegateOptions = function () { + var options = {} + var defaults = this.getDefaults() + + this._options && $.each(this._options, function (key, value) { + if (defaults[key] != value) options[key] = value + }) + + return options + } + + Tooltip.prototype.enter = function (obj) { + var self = obj instanceof this.constructor ? + obj : $(obj.currentTarget).data('bs.' + this.type) + + if (!self) { + self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) + $(obj.currentTarget).data('bs.' + this.type, self) + } + + if (obj instanceof $.Event) { + self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true + } + + if (self.tip().hasClass('in') || self.hoverState == 'in') { + self.hoverState = 'in' + return + } + + clearTimeout(self.timeout) + + self.hoverState = 'in' + + if (!self.options.delay || !self.options.delay.show) return self.show() + + self.timeout = setTimeout(function () { + if (self.hoverState == 'in') self.show() + }, self.options.delay.show) + } + + Tooltip.prototype.isInStateTrue = function () { + for (var key in this.inState) { + if (this.inState[key]) return true + } + + return false + } + + Tooltip.prototype.leave = function (obj) { + var self = obj instanceof this.constructor ? + obj : $(obj.currentTarget).data('bs.' + this.type) + + if (!self) { + self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) + $(obj.currentTarget).data('bs.' + this.type, self) + } + + if (obj instanceof $.Event) { + self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false + } + + if (self.isInStateTrue()) return + + clearTimeout(self.timeout) + + self.hoverState = 'out' + + if (!self.options.delay || !self.options.delay.hide) return self.hide() + + self.timeout = setTimeout(function () { + if (self.hoverState == 'out') self.hide() + }, self.options.delay.hide) + } + + Tooltip.prototype.show = function () { + var e = $.Event('show.bs.' + this.type) + + if (this.hasContent() && this.enabled) { + this.$element.trigger(e) + + var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) + if (e.isDefaultPrevented() || !inDom) return + var that = this + + var $tip = this.tip() + + var tipId = this.getUID(this.type) + + this.setContent() + $tip.attr('id', tipId) + this.$element.attr('aria-describedby', tipId) + + if (this.options.animation) $tip.addClass('fade') + + var placement = typeof this.options.placement == 'function' ? + this.options.placement.call(this, $tip[0], this.$element[0]) : + this.options.placement + + var autoToken = /\s?auto?\s?/i + var autoPlace = autoToken.test(placement) + if (autoPlace) placement = placement.replace(autoToken, '') || 'top' + + $tip + .detach() + .css({ top: 0, left: 0, display: 'block' }) + .addClass(placement) + .data('bs.' + this.type, this) + + this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) + this.$element.trigger('inserted.bs.' + this.type) + + var pos = this.getPosition() + var actualWidth = $tip[0].offsetWidth + var actualHeight = $tip[0].offsetHeight + + if (autoPlace) { + var orgPlacement = placement + var viewportDim = this.getPosition(this.$viewport) + + placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' : + placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' : + placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' : + placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' : + placement + + $tip + .removeClass(orgPlacement) + .addClass(placement) + } + + var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) + + this.applyPlacement(calculatedOffset, placement) + + var complete = function () { + var prevHoverState = that.hoverState + that.$element.trigger('shown.bs.' + that.type) + that.hoverState = null + + if (prevHoverState == 'out') that.leave(that) + } + + $.support.transition && this.$tip.hasClass('fade') ? + $tip + .one('bsTransitionEnd', complete) + .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : + complete() + } + } + + Tooltip.prototype.applyPlacement = function (offset, placement) { + var $tip = this.tip() + var width = $tip[0].offsetWidth + var height = $tip[0].offsetHeight + + // manually read margins because getBoundingClientRect includes difference + var marginTop = parseInt($tip.css('margin-top'), 10) + var marginLeft = parseInt($tip.css('margin-left'), 10) + + // we must check for NaN for ie 8/9 + if (isNaN(marginTop)) marginTop = 0 + if (isNaN(marginLeft)) marginLeft = 0 + + offset.top += marginTop + offset.left += marginLeft + + // $.fn.offset doesn't round pixel values + // so we use setOffset directly with our own function B-0 + $.offset.setOffset($tip[0], $.extend({ + using: function (props) { + $tip.css({ + top: Math.round(props.top), + left: Math.round(props.left) + }) + } + }, offset), 0) + + $tip.addClass('in') + + // check to see if placing tip in new offset caused the tip to resize itself + var actualWidth = $tip[0].offsetWidth + var actualHeight = $tip[0].offsetHeight + + if (placement == 'top' && actualHeight != height) { + offset.top = offset.top + height - actualHeight + } + + var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) + + if (delta.left) offset.left += delta.left + else offset.top += delta.top + + var isVertical = /top|bottom/.test(placement) + var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight + var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' + + $tip.offset(offset) + this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) + } + + Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) { + this.arrow() + .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') + .css(isVertical ? 'top' : 'left', '') + } + + Tooltip.prototype.setContent = function () { + var $tip = this.tip() + var title = this.getTitle() + + $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) + $tip.removeClass('fade in top bottom left right') + } + + Tooltip.prototype.hide = function (callback) { + var that = this + var $tip = $(this.$tip) + var e = $.Event('hide.bs.' + this.type) + + function complete() { + if (that.hoverState != 'in') $tip.detach() + if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary. + that.$element + .removeAttr('aria-describedby') + .trigger('hidden.bs.' + that.type) + } + callback && callback() + } + + this.$element.trigger(e) + + if (e.isDefaultPrevented()) return + + $tip.removeClass('in') + + $.support.transition && $tip.hasClass('fade') ? + $tip + .one('bsTransitionEnd', complete) + .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : + complete() + + this.hoverState = null + + return this + } + + Tooltip.prototype.fixTitle = function () { + var $e = this.$element + if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') { + $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') + } + } + + Tooltip.prototype.hasContent = function () { + return this.getTitle() + } + + Tooltip.prototype.getPosition = function ($element) { + $element = $element || this.$element + + var el = $element[0] + var isBody = el.tagName == 'BODY' + + var elRect = el.getBoundingClientRect() + if (elRect.width == null) { + // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 + elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) + } + var isSvg = window.SVGElement && el instanceof window.SVGElement + // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3. + // See https://github.com/twbs/bootstrap/issues/20280 + var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset()) + var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } + var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null + + return $.extend({}, elRect, scroll, outerDims, elOffset) + } + + Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { + return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : + placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : + placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : + /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } + + } + + Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { + var delta = { top: 0, left: 0 } + if (!this.$viewport) return delta + + var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 + var viewportDimensions = this.getPosition(this.$viewport) + + if (/right|left/.test(placement)) { + var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll + var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight + if (topEdgeOffset < viewportDimensions.top) { // top overflow + delta.top = viewportDimensions.top - topEdgeOffset + } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow + delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset + } + } else { + var leftEdgeOffset = pos.left - viewportPadding + var rightEdgeOffset = pos.left + viewportPadding + actualWidth + if (leftEdgeOffset < viewportDimensions.left) { // left overflow + delta.left = viewportDimensions.left - leftEdgeOffset + } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow + delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset + } + } + + return delta + } + + Tooltip.prototype.getTitle = function () { + var title + var $e = this.$element + var o = this.options + + title = $e.attr('data-original-title') + || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) + + return title + } + + Tooltip.prototype.getUID = function (prefix) { + do prefix += ~~(Math.random() * 1000000) + while (document.getElementById(prefix)) + return prefix + } + + Tooltip.prototype.tip = function () { + if (!this.$tip) { + this.$tip = $(this.options.template) + if (this.$tip.length != 1) { + throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!') + } + } + return this.$tip + } + + Tooltip.prototype.arrow = function () { + return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) + } + + Tooltip.prototype.enable = function () { + this.enabled = true + } + + Tooltip.prototype.disable = function () { + this.enabled = false + } + + Tooltip.prototype.toggleEnabled = function () { + this.enabled = !this.enabled + } + + Tooltip.prototype.toggle = function (e) { + var self = this + if (e) { + self = $(e.currentTarget).data('bs.' + this.type) + if (!self) { + self = new this.constructor(e.currentTarget, this.getDelegateOptions()) + $(e.currentTarget).data('bs.' + this.type, self) + } + } + + if (e) { + self.inState.click = !self.inState.click + if (self.isInStateTrue()) self.enter(self) + else self.leave(self) + } else { + self.tip().hasClass('in') ? self.leave(self) : self.enter(self) + } + } + + Tooltip.prototype.destroy = function () { + var that = this + clearTimeout(this.timeout) + this.hide(function () { + that.$element.off('.' + that.type).removeData('bs.' + that.type) + if (that.$tip) { + that.$tip.detach() + } + that.$tip = null + that.$arrow = null + that.$viewport = null + that.$element = null + }) + } + + + // TOOLTIP PLUGIN DEFINITION + // ========================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.tooltip') + var options = typeof option == 'object' && option + + if (!data && /destroy|hide/.test(option)) return + if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.tooltip + + $.fn.tooltip = Plugin + $.fn.tooltip.Constructor = Tooltip + + + // TOOLTIP NO CONFLICT + // =================== + + $.fn.tooltip.noConflict = function () { + $.fn.tooltip = old + return this + } + +}(jQuery); + +/* ======================================================================== + * Bootstrap: popover.js v3.3.7 + * http://getbootstrap.com/javascript/#popovers + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // POPOVER PUBLIC CLASS DEFINITION + // =============================== + + var Popover = function (element, options) { + this.init('popover', element, options) + } + + if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') + + Popover.VERSION = '3.3.7' + + Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { + placement: 'right', + trigger: 'click', + content: '', + template: '' + }) + + + // NOTE: POPOVER EXTENDS tooltip.js + // ================================ + + Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) + + Popover.prototype.constructor = Popover + + Popover.prototype.getDefaults = function () { + return Popover.DEFAULTS + } + + Popover.prototype.setContent = function () { + var $tip = this.tip() + var title = this.getTitle() + var content = this.getContent() + + $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) + $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events + this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' + ](content) + + $tip.removeClass('fade top bottom left right in') + + // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do + // this manually by checking the contents. + if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() + } + + Popover.prototype.hasContent = function () { + return this.getTitle() || this.getContent() + } + + Popover.prototype.getContent = function () { + var $e = this.$element + var o = this.options + + return $e.attr('data-content') + || (typeof o.content == 'function' ? + o.content.call($e[0]) : + o.content) + } + + Popover.prototype.arrow = function () { + return (this.$arrow = this.$arrow || this.tip().find('.arrow')) + } + + + // POPOVER PLUGIN DEFINITION + // ========================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.popover') + var options = typeof option == 'object' && option + + if (!data && /destroy|hide/.test(option)) return + if (!data) $this.data('bs.popover', (data = new Popover(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.popover + + $.fn.popover = Plugin + $.fn.popover.Constructor = Popover + + + // POPOVER NO CONFLICT + // =================== + + $.fn.popover.noConflict = function () { + $.fn.popover = old + return this + } + +}(jQuery); + +/* ======================================================================== + * Bootstrap: scrollspy.js v3.3.7 + * http://getbootstrap.com/javascript/#scrollspy + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // SCROLLSPY CLASS DEFINITION + // ========================== + + function ScrollSpy(element, options) { + this.$body = $(document.body) + this.$scrollElement = $(element).is(document.body) ? $(window) : $(element) + this.options = $.extend({}, ScrollSpy.DEFAULTS, options) + this.selector = (this.options.target || '') + ' .nav li > a' + this.offsets = [] + this.targets = [] + this.activeTarget = null + this.scrollHeight = 0 + + this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this)) + this.refresh() + this.process() + } + + ScrollSpy.VERSION = '3.3.7' + + ScrollSpy.DEFAULTS = { + offset: 10 + } + + ScrollSpy.prototype.getScrollHeight = function () { + return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) + } + + ScrollSpy.prototype.refresh = function () { + var that = this + var offsetMethod = 'offset' + var offsetBase = 0 + + this.offsets = [] + this.targets = [] + this.scrollHeight = this.getScrollHeight() + + if (!$.isWindow(this.$scrollElement[0])) { + offsetMethod = 'position' + offsetBase = this.$scrollElement.scrollTop() + } + + this.$body + .find(this.selector) + .map(function () { + var $el = $(this) + var href = $el.data('target') || $el.attr('href') + var $href = /^#./.test(href) && $(href) + + return ($href + && $href.length + && $href.is(':visible') + && [[$href[offsetMethod]().top + offsetBase, href]]) || null + }) + .sort(function (a, b) { return a[0] - b[0] }) + .each(function () { + that.offsets.push(this[0]) + that.targets.push(this[1]) + }) + } + + ScrollSpy.prototype.process = function () { + var scrollTop = this.$scrollElement.scrollTop() + this.options.offset + var scrollHeight = this.getScrollHeight() + var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() + var offsets = this.offsets + var targets = this.targets + var activeTarget = this.activeTarget + var i + + if (this.scrollHeight != scrollHeight) { + this.refresh() + } + + if (scrollTop >= maxScroll) { + return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) + } + + if (activeTarget && scrollTop < offsets[0]) { + this.activeTarget = null + return this.clear() + } + + for (i = offsets.length; i--;) { + activeTarget != targets[i] + && scrollTop >= offsets[i] + && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1]) + && this.activate(targets[i]) + } + } + + ScrollSpy.prototype.activate = function (target) { + this.activeTarget = target + + this.clear() + + var selector = this.selector + + '[data-target="' + target + '"],' + + this.selector + '[href="' + target + '"]' + + var active = $(selector) + .parents('li') + .addClass('active') + + if (active.parent('.dropdown-menu').length) { + active = active + .closest('li.dropdown') + .addClass('active') + } + + active.trigger('activate.bs.scrollspy') + } + + ScrollSpy.prototype.clear = function () { + $(this.selector) + .parentsUntil(this.options.target, '.active') + .removeClass('active') + } + + + // SCROLLSPY PLUGIN DEFINITION + // =========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.scrollspy') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.scrollspy + + $.fn.scrollspy = Plugin + $.fn.scrollspy.Constructor = ScrollSpy + + + // SCROLLSPY NO CONFLICT + // ===================== + + $.fn.scrollspy.noConflict = function () { + $.fn.scrollspy = old + return this + } + + + // SCROLLSPY DATA-API + // ================== + + $(window).on('load.bs.scrollspy.data-api', function () { + $('[data-spy="scroll"]').each(function () { + var $spy = $(this) + Plugin.call($spy, $spy.data()) + }) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: tab.js v3.3.7 + * http://getbootstrap.com/javascript/#tabs + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // TAB CLASS DEFINITION + // ==================== + + var Tab = function (element) { + // jscs:disable requireDollarBeforejQueryAssignment + this.element = $(element) + // jscs:enable requireDollarBeforejQueryAssignment + } + + Tab.VERSION = '3.3.7' + + Tab.TRANSITION_DURATION = 150 + + Tab.prototype.show = function () { + var $this = this.element + var $ul = $this.closest('ul:not(.dropdown-menu)') + var selector = $this.data('target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + if ($this.parent('li').hasClass('active')) return + + var $previous = $ul.find('.active:last a') + var hideEvent = $.Event('hide.bs.tab', { + relatedTarget: $this[0] + }) + var showEvent = $.Event('show.bs.tab', { + relatedTarget: $previous[0] + }) + + $previous.trigger(hideEvent) + $this.trigger(showEvent) + + if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return + + var $target = $(selector) + + this.activate($this.closest('li'), $ul) + this.activate($target, $target.parent(), function () { + $previous.trigger({ + type: 'hidden.bs.tab', + relatedTarget: $this[0] + }) + $this.trigger({ + type: 'shown.bs.tab', + relatedTarget: $previous[0] + }) + }) + } + + Tab.prototype.activate = function (element, container, callback) { + var $active = container.find('> .active') + var transition = callback + && $.support.transition + && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length) + + function next() { + $active + .removeClass('active') + .find('> .dropdown-menu > .active') + .removeClass('active') + .end() + .find('[data-toggle="tab"]') + .attr('aria-expanded', false) + + element + .addClass('active') + .find('[data-toggle="tab"]') + .attr('aria-expanded', true) + + if (transition) { + element[0].offsetWidth // reflow for transition + element.addClass('in') + } else { + element.removeClass('fade') + } + + if (element.parent('.dropdown-menu').length) { + element + .closest('li.dropdown') + .addClass('active') + .end() + .find('[data-toggle="tab"]') + .attr('aria-expanded', true) + } + + callback && callback() + } + + $active.length && transition ? + $active + .one('bsTransitionEnd', next) + .emulateTransitionEnd(Tab.TRANSITION_DURATION) : + next() + + $active.removeClass('in') + } + + + // TAB PLUGIN DEFINITION + // ===================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.tab') + + if (!data) $this.data('bs.tab', (data = new Tab(this))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.tab + + $.fn.tab = Plugin + $.fn.tab.Constructor = Tab + + + // TAB NO CONFLICT + // =============== + + $.fn.tab.noConflict = function () { + $.fn.tab = old + return this + } + + + // TAB DATA-API + // ============ + + var clickHandler = function (e) { + e.preventDefault() + Plugin.call($(this), 'show') + } + + $(document) + .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler) + .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: affix.js v3.3.7 + * http://getbootstrap.com/javascript/#affix + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // AFFIX CLASS DEFINITION + // ====================== + + var Affix = function (element, options) { + this.options = $.extend({}, Affix.DEFAULTS, options) + + this.$target = $(this.options.target) + .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) + .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) + + this.$element = $(element) + this.affixed = null + this.unpin = null + this.pinnedOffset = null + + this.checkPosition() + } + + Affix.VERSION = '3.3.7' + + Affix.RESET = 'affix affix-top affix-bottom' + + Affix.DEFAULTS = { + offset: 0, + target: window + } + + Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) { + var scrollTop = this.$target.scrollTop() + var position = this.$element.offset() + var targetHeight = this.$target.height() + + if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false + + if (this.affixed == 'bottom') { + if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom' + return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom' + } + + var initializing = this.affixed == null + var colliderTop = initializing ? scrollTop : position.top + var colliderHeight = initializing ? targetHeight : height + + if (offsetTop != null && scrollTop <= offsetTop) return 'top' + if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom' + + return false + } + + Affix.prototype.getPinnedOffset = function () { + if (this.pinnedOffset) return this.pinnedOffset + this.$element.removeClass(Affix.RESET).addClass('affix') + var scrollTop = this.$target.scrollTop() + var position = this.$element.offset() + return (this.pinnedOffset = position.top - scrollTop) + } + + Affix.prototype.checkPositionWithEventLoop = function () { + setTimeout($.proxy(this.checkPosition, this), 1) + } + + Affix.prototype.checkPosition = function () { + if (!this.$element.is(':visible')) return + + var height = this.$element.height() + var offset = this.options.offset + var offsetTop = offset.top + var offsetBottom = offset.bottom + var scrollHeight = Math.max($(document).height(), $(document.body).height()) + + if (typeof offset != 'object') offsetBottom = offsetTop = offset + if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) + if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) + + var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom) + + if (this.affixed != affix) { + if (this.unpin != null) this.$element.css('top', '') + + var affixType = 'affix' + (affix ? '-' + affix : '') + var e = $.Event(affixType + '.bs.affix') + + this.$element.trigger(e) + + if (e.isDefaultPrevented()) return + + this.affixed = affix + this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null + + this.$element + .removeClass(Affix.RESET) + .addClass(affixType) + .trigger(affixType.replace('affix', 'affixed') + '.bs.affix') + } + + if (affix == 'bottom') { + this.$element.offset({ + top: scrollHeight - height - offsetBottom + }) + } + } + + + // AFFIX PLUGIN DEFINITION + // ======================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.affix') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.affix', (data = new Affix(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.affix + + $.fn.affix = Plugin + $.fn.affix.Constructor = Affix + + + // AFFIX NO CONFLICT + // ================= + + $.fn.affix.noConflict = function () { + $.fn.affix = old + return this + } + + + // AFFIX DATA-API + // ============== + + $(window).on('load', function () { + $('[data-spy="affix"]').each(function () { + var $spy = $(this) + var data = $spy.data() + + data.offset = data.offset || {} + + if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom + if (data.offsetTop != null) data.offset.top = data.offsetTop + + Plugin.call($spy, data) + }) + }) + +}(jQuery); diff --git a/html/scripts/mustache.min.js b/html/scripts/mustache.min.js new file mode 100644 index 00000000..520cfcb9 --- /dev/null +++ b/html/scripts/mustache.min.js @@ -0,0 +1 @@ +(function defineMustache(global,factory){if(typeof exports==="object"&&exports&&typeof exports.nodeName!=="string"){factory(exports)}else if(typeof define==="function"&&define.amd){define(["exports"],factory)}else{global.Mustache={};factory(global.Mustache)}})(this,function mustacheFactory(mustache){var objectToString=Object.prototype.toString;var isArray=Array.isArray||function isArrayPolyfill(object){return objectToString.call(object)==="[object Array]"};function isFunction(object){return typeof object==="function"}function typeStr(obj){return isArray(obj)?"array":typeof obj}function escapeRegExp(string){return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}function hasProperty(obj,propName){return obj!=null&&typeof obj==="object"&&propName in obj}var regExpTest=RegExp.prototype.test;function testRegExp(re,string){return regExpTest.call(re,string)}var nonSpaceRe=/\S/;function isWhitespace(string){return!testRegExp(nonSpaceRe,string)}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(string){return String(string).replace(/[&<>"'`=\/]/g,function fromEntityMap(s){return entityMap[s]})}var whiteRe=/\s*/;var spaceRe=/\s+/;var equalsRe=/\s*=/;var curlyRe=/\s*\}/;var tagRe=/#|\^|\/|>|\{|&|=|!/;function parseTemplate(template,tags){if(!template)return[];var sections=[];var tokens=[];var spaces=[];var hasTag=false;var nonSpace=false;function stripSpace(){if(hasTag&&!nonSpace){while(spaces.length)delete tokens[spaces.pop()]}else{spaces=[]}hasTag=false;nonSpace=false}var openingTagRe,closingTagRe,closingCurlyRe;function compileTags(tagsToCompile){if(typeof tagsToCompile==="string")tagsToCompile=tagsToCompile.split(spaceRe,2);if(!isArray(tagsToCompile)||tagsToCompile.length!==2)throw new Error("Invalid tags: "+tagsToCompile);openingTagRe=new RegExp(escapeRegExp(tagsToCompile[0])+"\\s*");closingTagRe=new RegExp("\\s*"+escapeRegExp(tagsToCompile[1]));closingCurlyRe=new RegExp("\\s*"+escapeRegExp("}"+tagsToCompile[1]))}compileTags(tags||mustache.tags);var scanner=new Scanner(template);var start,type,value,chr,token,openSection;while(!scanner.eos()){start=scanner.pos;value=scanner.scanUntil(openingTagRe);if(value){for(var i=0,valueLength=value.length;i0?sections[sections.length-1][4]:nestedTokens;break;default:collector.push(token)}}return nestedTokens}function Scanner(string){this.string=string;this.tail=string;this.pos=0}Scanner.prototype.eos=function eos(){return this.tail===""};Scanner.prototype.scan=function scan(re){var match=this.tail.match(re);if(!match||match.index!==0)return"";var string=match[0];this.tail=this.tail.substring(string.length);this.pos+=string.length;return string};Scanner.prototype.scanUntil=function scanUntil(re){var index=this.tail.search(re),match;switch(index){case-1:match=this.tail;this.tail="";break;case 0:match="";break;default:match=this.tail.substring(0,index);this.tail=this.tail.substring(index)}this.pos+=match.length;return match};function Context(view,parentContext){this.view=view;this.cache={".":this.view};this.parent=parentContext}Context.prototype.push=function push(view){return new Context(view,this)};Context.prototype.lookup=function lookup(name){var cache=this.cache;var value;if(cache.hasOwnProperty(name)){value=cache[name]}else{var context=this,names,index,lookupHit=false;while(context){if(name.indexOf(".")>0){value=context.view;names=name.split(".");index=0;while(value!=null&&index")value=this.renderPartial(token,context,partials,originalTemplate);else if(symbol==="&")value=this.unescapedValue(token,context);else if(symbol==="name")value=this.escapedValue(token,context);else if(symbol==="text")value=this.rawValue(token);if(value!==undefined)buffer+=value}return buffer};Writer.prototype.renderSection=function renderSection(token,context,partials,originalTemplate){var self=this;var buffer="";var value=context.lookup(token[1]);function subRender(template){return self.render(template,context,partials)}if(!value)return;if(isArray(value)){for(var j=0,valueLength=value.length;j + + + + + + + + + +
+
+

+ + Banque +

+
+
+
+
+
+
+
+ +
+
+

+ + Montant ? +

+
+
+
+ + + +
+
+
+ +
+
+

+ + Montant ? +

+
+
+
+ + + +
+
+
+ +
+
+

+ + Montant ? +

+
+
+
+ + +
+
+
+ +
+
+

+ + Montant ? +

+
+
+
+ + +
+
+
+ +
+
+

+ + Montant ? +

+
+
+
+ + +
+
+
+ +
+
+

+ + Montant ? +

+
+
+
+ + +
+
+
+ + + + +
+
 Banque
+
 Banque
+
 Retour
+
+ + + + + + + + \ No newline at end of file diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..3cc454a0 --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,21 @@ +Locales['en'] = { + ['actions'] = 'actions', + ['amount'] = 'amount', + ['balance'] = 'balance', + ['bank'] = 'bank', + ['bill_amount'] = 'bill amount', + ['billing'] = 'billing', + ['customer'] = 'customer', + ['customers'] = 'clients', + ['deposit'] = 'deposit', + ['deposit_amount'] = 'deposit amount', + ['deposit_society_money'] = 'deposit society money', + ['invalid_amount'] = 'invalid amount', + ['no_player_nearby'] = 'no player nearby', + ['press_input_context_to_open_menu'] = 'press ~INPUT_CONTEXT~ to open menu', + ['property'] = 'property', + ['wash_money'] = 'wash money', + ['withdraw'] = 'withdraw', + ['withdraw_amount'] = 'withdraw amount', + ['withdraw_society_money'] = 'withdraw society money', +} \ No newline at end of file diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..6e927506 --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,21 @@ +Locales['fr'] = { + ['actions'] = 'actions', + ['amount'] = 'montant', + ['balance'] = 'solde', + ['bank'] = 'banque', + ['bill_amount'] = 'montant de la facture', + ['billing'] = 'facturation', + ['customer'] = 'client', + ['customers'] = 'clients', + ['deposit'] = 'virement', + ['deposit_amount'] = 'montant du dépôt', + ['deposit_society_money'] = 'déposer argent société', + ['invalid_amount'] = 'montant invalide', + ['no_player_nearby'] = 'aucun joueur à proximité', + ['press_input_context_to_open_menu'] = 'appuyez sur ~INPUT_CONTEXT~ pour ouvrir le menu', + ['property'] = 'propriété', + ['wash_money'] = 'blanchir argent', + ['withdraw'] = 'retrait', + ['withdraw_amount'] = 'montant du retrait', + ['withdraw_society_money'] = 'retirer argent société', +} \ No newline at end of file diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..f9f2ec56 --- /dev/null +++ b/server/main.lua @@ -0,0 +1,136 @@ +ESX = nil + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +RegisterServerEvent('esx_bankerjob:customerDeposit') +AddEventHandler('esx_bankerjob:customerDeposit', function(target, amount) + + local xPlayer = ESX.GetPlayerFromId(target) + + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_banker', function(account) + account.removeMoney(amount) + end) + + TriggerEvent('esx_addonaccount:getAccount', 'bank_savings', xPlayer.identifier, function(account) + account.addMoney(amount) + end) + +end) + +RegisterServerEvent('esx_bankerjob:customerWithdraw') +AddEventHandler('esx_bankerjob:customerWithdraw', function(target, amount) + + local xPlayer = ESX.GetPlayerFromId(target) + + TriggerEvent('esx_addonaccount:getAccount', 'bank_savings', xPlayer.identifier, function(account) + account.removeMoney(amount) + end) + + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_banker', function(account) + account.addMoney(amount) + end) + +end) + +ESX.RegisterServerCallback('esx_bankerjob:getCustomers', function(source, cb) + + local xPlayers = ESX.GetPlayers() + local customers = {} + + for k,v in pairs(xPlayers) do + + TriggerEvent('esx_addonaccount:getAccount', 'bank_savings', v.identifier, function(account) + table.insert(customers, { + source = v.source, + name = GetPlayerName(v.source), + bankSavings = account.money + }) + end) + + end + + cb(customers) + +end) + +TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) + + local xPlayer = ESX.GetPlayerFromId(source) + local xPlayers = ESX.GetPlayers() + + if phoneNumber == 'banker' then + for k, v in pairs(xPlayers) do + if v.job.name == 'banker' then + TriggerEvent('esx_phone:getDistpatchRequestId', function(requestId) + TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'Client Banque') + end) + end + end + end + +end) + +function CalculateBankSavings(d, h, m) + + MySQL.Async.fetchAll( + 'SELECT * FROM addon_account_data WHERE account_name = @account_name', + { + ['@account_name'] = 'bank_savings' + }, + function(result) + + local bankInterests = 0 + local xPlayers = ESX.GetPlayers() + + for i=1, #result, 1 do + + local foundPlayer = false + local xPlayer = nil + + for k,v in pairs(xPlayers) do + if v.identifier == result[i].owner then + foundPlayer = true + xPlayer = v + end + end + + if foundPlayer then + + TriggerEvent('esx_addonaccount:getAccount', 'bank_savings', xPlayer.identifier, function(account) + + local interests = math.floor(account.money / 100 * Config.BankSavingPercentage) + bankInterests = bankInterests + interests + + account.addMoney(interests) + + end) + + else + + local interests = math.floor(result[i].money / 100 * Config.BankSavingPercentage) + local newMoney = result[i].money + interests; + bankInterests = bankInterests + interests + + MySQL.Async.execute( + 'UPDATE addon_account_data SET money = @money WHERE owner = @owner AND account_name = @account_name', + { + ['@money'] = newMoney, + ['@owner'] = result[i].owner, + ['@account_name'] = 'bank_savings' + } + ) + + end + + end + + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_banker', function(account) + account.addMoney(bankInterests) + end) + + end + ) + +end + +TriggerEvent('cron:runAt', 22, 00, CalculateBankSavings) From a477d7b4a4cfb383799358c635becc47975d0582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 23:06:05 +0200 Subject: [PATCH 0312/3224] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d2365ff7..4cc0ae94 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ FXServer ESX BankerJob [REQUIREMENTS] +- cron => https://github.com/FXServer-ESX/fxserver-cron - esx_addonaccount => https://github.com/FXServer-ESX/fxserver-esx_addonaccount - esx_society => https://github.com/FXServer-ESX/fxserver-esx_society From a59c3a984be62a6cb8dd05b15e45e7a8f989863f Mon Sep 17 00:00:00 2001 From: nlmarcio Date: Sat, 12 Aug 2017 23:06:22 +0200 Subject: [PATCH 0313/3224] Add Weapon pickup Allows you to drop your weapon from the inventory. Possibility to spawn the weapon on the ground by activating Config.EnableWeaponPickup in config.lua --- resources/[essential]/es_extended/client/main.lua | 11 ++++++++++- resources/[essential]/es_extended/config.lua | 1 + resources/[essential]/es_extended/server/main.lua | 9 +++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index 66a26500..416db725 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -373,4 +373,13 @@ if Config.DisableWantedLevel then end end) -end \ No newline at end of file +end + +-- Pickup Weapon +RegisterNetEvent('esx:pickupWeapon') +AddEventHandler('esx:pickupWeapon', function(weaponPickup, weaponName) + local ped = GetPlayerPed(-1) + local playerPedPos = GetEntityCoords(ped, true) + CreateAmbientPickup(GetHashKey(weaponPickup), playerPedPos.x + 2.0, playerPedPos.y, playerPedPos.z + 0.5, 0, 999, 1, false, true) + +end) diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua index b372f0eb..d87401a8 100644 --- a/resources/[essential]/es_extended/config.lua +++ b/resources/[essential]/es_extended/config.lua @@ -7,3 +7,4 @@ Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true Config.RemoveInventoryItemDelay = 5 * 60000 Config.Locale = 'fr' +Config.EnableWeaponPickup = false diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index 2523e3e8..1e1ffd03 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -479,17 +479,26 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) elseif type == 'item_weapon' then + local xPlayer = ESX.GetPlayerFromId(source) + local weaponLabel = itemName + local weaponName = nil + local weaponPickup = nil for i=1, #Config.Weapons, 1 do if Config.Weapons[i].name == itemName then weaponLabel = Config.Weapons[i].label + weaponName = Config.Weapons[i].name + weaponPickup = 'PICKUP_'..weaponName break end end SetTimeout(Config.RemoveInventoryItemDelay, function() xPlayer.removeWeapon(itemName) + if Config.EnableWeaponPickup then + TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, weaponName) + end TriggerClientEvent('esx:showNotification', _source, 'Vous avez ~r~jeté~s~ x1 ' .. ' ~g~' .. weaponLabel) end) From f47ad0aab8aadc4b6e652cd46871ce34baf8a12d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 23:12:56 +0200 Subject: [PATCH 0314/3224] Fix SQL - Thanks to @AdrineX --- esx_bankerjob.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esx_bankerjob.sql b/esx_bankerjob.sql index 661f15bf..5f63c947 100644 --- a/esx_bankerjob.sql +++ b/esx_bankerjob.sql @@ -1,6 +1,6 @@ -USE `gta5_gamemode_essential`; +USE `essentialmode`; -INSERT INTO `addon_account` (account_name, label, shared) VALUES +INSERT INTO `addon_account` (name, label, shared) VALUES ('society_banker','Banque',1), ('bank_savings','Livret Bleu',0) ; From fc475a04383f8c0f92572d76f17a547cbe36b583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 23:13:48 +0200 Subject: [PATCH 0315/3224] Remove garbage code - Thanks to @Foxi10 --- client/main.lua | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/client/main.lua b/client/main.lua index 2505206d..b9ccdecb 100644 --- a/client/main.lua +++ b/client/main.lua @@ -418,10 +418,5 @@ Citizen.CreateThread(function() end - if IsControlPressed(0, Keys['F6']) and PlayerData.job ~= nil and PlayerData.job.name == 'banker' and (GetGameTimer() - GUI.Time) > 150 then - OpenMobileAmbulanceActionsMenu() - GUI.Time = GetGameTimer() - end - end -end) \ No newline at end of file +end) From e270494b1de674e1856760451260504b59c4f4eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 23:42:24 +0200 Subject: [PATCH 0316/3224] Add givemoney, giveaccountmoney, giveitem and giveweapon commands --- .../es_extended/server/commands.lua | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/resources/[essential]/es_extended/server/commands.lua b/resources/[essential]/es_extended/server/commands.lua index cf54ee92..d81a2100 100644 --- a/resources/[essential]/es_extended/server/commands.lua +++ b/resources/[essential]/es_extended/server/commands.lua @@ -47,3 +47,71 @@ end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = 'Spawn un véhicule'}) +TriggerEvent('es:addGroupCommand', 'givemoney', 'admin', function(source, args, user) + + local _source = source + local xPlayer = ESX.GetPlayerFromId(args[2]) + local amount = tonumber(args[3]) + + if amount ~= nil then + xPlayer.addMoney(amount) + else + TriggerClientEvent('esx:showNotification', _source, 'Montant invalide') + end + +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end, {help = 'givemoney [id] [montant]'}) + +TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, args, user) + + local _source = source + local xPlayer = ESX.GetPlayerFromId(args[2]) + local account = args[3] + local amount = tonumber(args[4]) + + if amount ~= nil then + if xPlayer.getAccount(account) ~= nil then + xPlayer.addAccountMoney(account, amount) + else + TriggerClientEvent('esx:showNotification', _source, 'Compte invalide') + end + else + TriggerClientEvent('esx:showNotification', _source, 'Montant invalide') + end + +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end, {help = 'giveaccountmoney [id] [compte] [montant]'}) + +TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, user) + + local _source = source + local xPlayer = ESX.GetPlayerFromId(args[2]) + local item = args[3] + local count = (args[4] == nil and 1 or tonumber(args[4])) + + if count ~= nil then + if xPlayer.getInventoryItem(item) ~= nil then + xPlayer.addInventoryItem(item, count) + else + TriggerClientEvent('esx:showNotification', _source, 'Item invalide') + end + else + TriggerClientEvent('esx:showNotification', _source, 'Quantité invalide') + end + +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end, {help = 'giveitem [id] [item] [[quantité]]'}) + +TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, user) + + local xPlayer = ESX.GetPlayerFromId(args[2]) + local weaponName = string.upper(args[3]) + + xPlayer.addWeapon(weaponName, 1000) + +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end, {help = 'giveweapon [id] [arme]'}) From 7b3963d67a0800f2351ef8c0a21e20b09945fac0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 00:06:02 +0200 Subject: [PATCH 0317/3224] reorganize code + close menu when they should be closed --- .../es_extended/client/functions.lua | 22 +++++++++++-------- .../[essential]/es_extended/client/main.lua | 19 +++++++++------- resources/[essential]/es_extended/config.lua | 2 +- .../es_extended/server/commands.lua | 1 + .../[essential]/es_extended/server/main.lua | 8 +++++-- 5 files changed, 32 insertions(+), 20 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 7839dd7e..32a871b9 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -915,7 +915,7 @@ ESX.ShowInventory = function() { title = 'Quantité' }, - function(data2, menu) + function(data2, menu2) local quantity = tonumber(data2.value) local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() @@ -926,9 +926,11 @@ ESX.ShowInventory = function() TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) end + menu2.close() menu.close() + end, - function(data2, menu) + function(data2, menu2) menu.close() end ) @@ -946,23 +948,22 @@ ESX.ShowInventory = function() { title = 'Quantité' }, - function(data2, menu) + function(data2, menu2) local quantity = tonumber(data2.value) if quantity == nil then ESX.ShowNotification('Montant invalide') else - - menu.close() - TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) - end + + menu2.close() + menu.close() end, - function(data2, menu) - menu.close() + function(data2, menu2) + menu2.close() end ) @@ -972,6 +973,9 @@ ESX.ShowInventory = function() TriggerServerEvent('esx:useItem', data.current.value) + menu2.close() + menu.close() + elseif data.current.action == 'return' then ESX.UI.Menu.CloseAll() ESX.ShowInventory() diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index 416db725..d0266595 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -249,6 +249,17 @@ AddEventHandler('esx:spawnVehicle', function(model) end) +-- Pickup Weapon +RegisterNetEvent('esx:pickupWeapon') +AddEventHandler('esx:pickupWeapon', function(weaponPickup, weaponName) + + local ped = GetPlayerPed(-1) + local playerPedPos = GetEntityCoords(ped, true) + + CreateAmbientPickup(GetHashKey(weaponPickup), playerPedPos.x + 2.0, playerPedPos.y, playerPedPos.z + 0.5, 0, 1000, 1, false, true) + +end) + -- Pause menu disable HUD display Citizen.CreateThread(function() while true do @@ -375,11 +386,3 @@ if Config.DisableWantedLevel then end --- Pickup Weapon -RegisterNetEvent('esx:pickupWeapon') -AddEventHandler('esx:pickupWeapon', function(weaponPickup, weaponName) - local ped = GetPlayerPed(-1) - local playerPedPos = GetEntityCoords(ped, true) - CreateAmbientPickup(GetHashKey(weaponPickup), playerPedPos.x + 2.0, playerPedPos.y, playerPedPos.z + 0.5, 0, 999, 1, false, true) - -end) diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua index d87401a8..a0546b7b 100644 --- a/resources/[essential]/es_extended/config.lua +++ b/resources/[essential]/es_extended/config.lua @@ -6,5 +6,5 @@ Config.PaycheckInterval = 7 * 60000 Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true Config.RemoveInventoryItemDelay = 5 * 60000 +Config.EnableWeaponPickup = false Config.Locale = 'fr' -Config.EnableWeaponPickup = false diff --git a/resources/[essential]/es_extended/server/commands.lua b/resources/[essential]/es_extended/server/commands.lua index d81a2100..6b47414d 100644 --- a/resources/[essential]/es_extended/server/commands.lua +++ b/resources/[essential]/es_extended/server/commands.lua @@ -115,3 +115,4 @@ TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = 'giveweapon [id] [arme]'}) + diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index 1e1ffd03..8f7a47cb 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -481,8 +481,8 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) local xPlayer = ESX.GetPlayerFromId(source) - local weaponLabel = itemName - local weaponName = nil + local weaponLabel = itemName + local weaponName = nil local weaponPickup = nil for i=1, #Config.Weapons, 1 do @@ -495,11 +495,15 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) end SetTimeout(Config.RemoveInventoryItemDelay, function() + xPlayer.removeWeapon(itemName) + if Config.EnableWeaponPickup then TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, weaponName) end + TriggerClientEvent('esx:showNotification', _source, 'Vous avez ~r~jeté~s~ x1 ' .. ' ~g~' .. weaponLabel) + end) end From 031030adbe779e5c09ad20d9a1b5ccfa800bb968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 00:20:57 +0200 Subject: [PATCH 0318/3224] add menu.close() --- resources/[essential]/es_extended/client/functions.lua | 3 +++ resources/[essential]/es_extended/server/main.lua | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 32a871b9..0d38862a 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -940,7 +940,10 @@ ESX.ShowInventory = function() elseif data.current.action == 'remove' then if type == 'item_weapon' then + TriggerServerEvent('esx:removeInventoryItem', type, item, 1) + menu.close() + else ESX.UI.Menu.Open( diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index 8f7a47cb..c06d44b8 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -479,8 +479,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) elseif type == 'item_weapon' then - local xPlayer = ESX.GetPlayerFromId(source) - + local xPlayer = ESX.GetPlayerFromId(source) local weaponLabel = itemName local weaponName = nil local weaponPickup = nil From d055789eb24e038b28cdfe68cc0a27b13e410ce2 Mon Sep 17 00:00:00 2001 From: AdrineX Date: Sun, 13 Aug 2017 06:15:48 +0300 Subject: [PATCH 0319/3224] weed treatment fix --- client/esx_drugs_cl.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/esx_drugs_cl.lua b/client/esx_drugs_cl.lua index 8a47bf97..1eafc49f 100644 --- a/client/esx_drugs_cl.lua +++ b/client/esx_drugs_cl.lua @@ -260,7 +260,7 @@ Citizen.CreateThread(function() if CurrentAction == 'weed_harvest' then TriggerServerEvent('esx_drugs:startHarvestWeed') end - if CurrentAction == 'wedd_treatment' then + if CurrentAction == 'weed_treatment' then TriggerServerEvent('esx_drugs:startTransformWeed') end if CurrentAction == 'weed_resell' then From 433b806b7d79e259e8126182deef7cd3b1fa6e43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 10:06:01 +0200 Subject: [PATCH 0320/3224] Temporary fix for esx_vehicleshop --- client/main.lua | 52 ++++++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/client/main.lua b/client/main.lua index bc3900f9..66d7d59f 100644 --- a/client/main.lua +++ b/client/main.lua @@ -21,7 +21,7 @@ local CurrentActionMsg = '' local CurrentActionData = {} local Categories = {} local Vehicles = {} -local CurrentVehicle = nil +local LastVehicles = {} local CurrentVehicleData = nil Citizen.CreateThread(function() @@ -43,25 +43,33 @@ end) function DeleteShopInsideVehicle(cb) - Citizen.CreateThread(function() + -- Citizen.CreateThread(function() - while IsAnyVehicleNearPoint(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 5.0) do + -- while IsAnyVehicleNearPoint(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 5.0) do - local vehicle, distance = ESX.Game.GetClosestVehicle(Config.Zones.ShopInside.Pos) + -- local vehicle, distance = ESX.Game.GetClosestVehicle(Config.Zones.ShopInside.Pos) - if distance <= 5.0 then - ESX.Game.DeleteVehicle(vehicle) - end + -- if distance <= 5.0 then + -- ESX.Game.DeleteVehicle(vehicle) + -- end - Citizen.Wait(0) + -- Citizen.Wait(0) - end + -- end - if cb ~= nil then - cb() - end + -- if cb ~= nil then + -- cb() + -- end - end) + -- end) + + while #LastVehicles > 0 do + local vehicle = LastVehicles[1] + ESX.Game.DeleteVehicle(vehicle) + table.remove(LastVehicles, 1) + end + + cb() end @@ -146,8 +154,8 @@ function OpenShopMenu() if hasEnoughMoney then - menu.close() menu2.close() + menu.close() ESX.ShowNotification('Vous avez acheté un véhicule') else @@ -162,8 +170,8 @@ function OpenShopMenu() if hasEnoughMoney then - menu.close() menu2.close() + menu.close() DeleteShopInsideVehicle(function() @@ -243,7 +251,7 @@ function OpenShopMenu() y = Config.Zones.ShopInside.Pos.y, z = Config.Zones.ShopInside.Pos.z }, 90.0, function(vehicle) - CurrentVehicle = vehicle + table.insert(LastVehicles, vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) FreezeEntityPosition(vehicle, true) end) @@ -260,7 +268,7 @@ function OpenShopMenu() y = Config.Zones.ShopInside.Pos.y, z = Config.Zones.ShopInside.Pos.z }, 90.0, function(vehicle) - CurrentVehicle = vehicle + table.insert(LastVehicles, vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) FreezeEntityPosition(vehicle, true) end) @@ -344,7 +352,7 @@ function OpenResellerMenu() ESX.ShowNotification('Aucun joueur à proximité') else - local vehicleProps = ESX.Game.GetVehicleProperties(CurrentVehicle) + local vehicleProps = ESX.Game.GetVehicleProperties(LastVehicles[#LastVehicles]) local model = CurrentVehicleData.model TriggerServerEvent('esx_vehicleshop:sellVehicle', model) @@ -376,9 +384,9 @@ function OpenResellerMenu() ESX.ShowNotification('Aucun joueur à proximité') else - SetVehicleNumberPlateText(CurrentVehicle, 'LOC ' .. ESX.GetRandomString(5)) + SetVehicleNumberPlateText(LastVehicles[#LastVehicles], 'LOC ' .. ESX.GetRandomString(5)) - local vehicleProps = ESX.Game.GetVehicleProperties(CurrentVehicle) + local vehicleProps = ESX.Game.GetVehicleProperties(LastVehicles[#LastVehicles]) local model = CurrentVehicleData.model TriggerServerEvent('esx_vehicleshop:rentVehicle', model, vehicleProps.plate, GetPlayerName(closestPlayer), CurrentVehicleData.price, amount, GetPlayerServerId(closestPlayer)) @@ -493,7 +501,7 @@ function OpenPopVehicleMenu() z = Config.Zones.ShopInside.Pos.z }, 90.0, function(vehicle) - CurrentVehicle = vehicle + table.insert(LastVehicles, vehicle) for i=1, #Vehicles, 1 do if model == Vehicles[i].model then @@ -780,7 +788,7 @@ AddEventHandler('esx_vehicleshop:hasEnteredMarker', function(zone) end - if zone == 'BossActions' and PlayerData.job ~= nil and PlayerData.job.name == 'cardealer' and PlayerData.job.grade_name == 'boss' then + if zone == 'BossActions' and Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.name == 'cardealer' and PlayerData.job.grade_name == 'boss' then CurrentAction = 'boss_actions_menu' CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' From 8388a8d05ea9e72df1ee9c65aecf62db2169cec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 10:38:13 +0200 Subject: [PATCH 0321/3224] Fix give item close + TriggerServerCallback debug message --- resources/[essential]/es_extended/client/functions.lua | 2 +- resources/[essential]/es_extended/server/functions.lua | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 0d38862a..fe32b357 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -931,7 +931,7 @@ ESX.ShowInventory = function() end, function(data2, menu2) - menu.close() + menu2.close() end ) diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index c8dbc033..c5541654 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -25,7 +25,13 @@ ESX.RegisterServerCallback = function(name, cb) end ESX.TriggerServerCallback = function(name, requestId, source, cb, ...) - ESX.ServerCallbacks[name](source, cb, ...) + + if ESX.ServerCallbacks[name] ~= nil then + ESX.ServerCallbacks[name](source, cb, ...) + else + print('TriggerServerCallback => [' .. name .. '] does not exists') + end + end ESX.SavePlayer = function(xPlayer, cb) From 62a14139699fca1c9a7a3819ab0fc513f3512c4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 11:13:15 +0200 Subject: [PATCH 0322/3224] Temporary fix for getting vehicle handles --- client/main.lua | 185 +++++++++++++++++++++--------------------------- 1 file changed, 82 insertions(+), 103 deletions(-) diff --git a/client/main.lua b/client/main.lua index 5d861352..4a9b9e77 100644 --- a/client/main.lua +++ b/client/main.lua @@ -20,109 +20,102 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) if IsPedInAnyVehicle(playerPed, false) then - local vehicle, distance = ESX.Game.GetClosestVehicle({ - x = coords.x, - y = coords.y, - z = coords.z - }) + local vehicle = GetVehiclePedIsIn(playerPed, false) - if distance <= 2.0 then + if GetPedInVehicleSeat(vehicle, -1) == playerPed then - if GetPedInVehicleSeat(vehicle, -1) == playerPed then + local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) - local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) + local spawnCoords = { + x = garage.InteriorSpawnPoint.Pos.x, + y = garage.InteriorSpawnPoint.Pos.y, + z = garage.InteriorSpawnPoint.Pos.z + } - local spawnCoords = { - x = garage.InteriorSpawnPoint.Pos.x, - y = garage.InteriorSpawnPoint.Pos.y, - z = garage.InteriorSpawnPoint.Pos.z - } + ESX.Game.DeleteVehicle(vehicle) - ESX.Game.DeleteVehicle(vehicle) + ESX.Game.Teleport(playerPed, spawnCoords, function() - ESX.Game.Teleport(playerPed, spawnCoords, function() + TriggerEvent('instance:create') - TriggerEvent('instance:create') + ESX.Game.SpawnLocalVehicle(vehicleProps.model, spawnCoords, garage.InteriorSpawnPoint.Heading, function(vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + ESX.Game.SetVehicleProperties(vehicle, vehicleProps) + end) - ESX.Game.SpawnLocalVehicle(vehicleProps.model, spawnCoords, garage.InteriorSpawnPoint.Heading, function(vehicle) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - ESX.Game.SetVehicleProperties(vehicle, vehicleProps) - end) + ESX.TriggerServerCallback('esx_vehicleshop:getVehiclesInGarage', function(vehicles) - ESX.TriggerServerCallback('esx_vehicleshop:getVehiclesInGarage', function(vehicles) + for i=1, #garage.Parkings, 1 do + for j=1, #vehicles, 1 do - for i=1, #garage.Parkings, 1 do - for j=1, #vehicles, 1 do + if i == vehicles[j].zone then + + local spawn = function(j) - if i == vehicles[j].zone then - - local spawn = function(j) - - ESX.Game.SpawnLocalVehicle(vehicles[j].vehicle.model, { - x = garage.Parkings[i].Pos.x, - y = garage.Parkings[i].Pos.y, - z = garage.Parkings[i].Pos.z - }, garage.Parkings[i].Heading, function(vehicle) - ESX.Game.SetVehicleProperties(vehicle, vehicles[j].vehicle) - end) - - end - - spawn(j) + ESX.Game.SpawnLocalVehicle(vehicles[j].vehicle.model, { + x = garage.Parkings[i].Pos.x, + y = garage.Parkings[i].Pos.y, + z = garage.Parkings[i].Pos.z + }, garage.Parkings[i].Heading, function(vehicle) + ESX.Game.SetVehicleProperties(vehicle, vehicles[j].vehicle) + end) end + spawn(j) + end + end + end - end, name) + end, name) - end) + end) - else + else - ESX.Game.Teleport(playerPed, { - x = garage.InteriorSpawnPoint.Pos.x, - y = garage.InteriorSpawnPoint.Pos.y, - z = garage.InteriorSpawnPoint.Pos.z - }, function() + ESX.Game.Teleport(playerPed, { + x = garage.InteriorSpawnPoint.Pos.x, + y = garage.InteriorSpawnPoint.Pos.y, + z = garage.InteriorSpawnPoint.Pos.z + }, function() - TriggerEvent('instance:create') + TriggerEvent('instance:create') - ESX.TriggerServerCallback('esx_vehicleshop:getVehiclesInGarage', function(vehicles) + ESX.TriggerServerCallback('esx_vehicleshop:getVehiclesInGarage', function(vehicles) - for i=1, #garage.Parkings, 1 do - for j=1, #vehicles, 1 do + for i=1, #garage.Parkings, 1 do + for j=1, #vehicles, 1 do - if i == vehicles[j].zone then - - local spawn = function(j) + if i == vehicles[j].zone then + + local spawn = function(j) - ESX.Game.SpawnLocalVehicle(vehicles[j].vehicle.model, { - x = garage.Parkings[i].Pos.x, - y = garage.Parkings[i].Pos.y, - z = garage.Parkings[i].Pos.z - }, garage.Parkings[i].Heading, function(vehicle) - ESX.Game.SetVehicleProperties(vehicle, vehicles[j].vehicle) - end) - - end - - spawn(j) + ESX.Game.SpawnLocalVehicle(vehicles[j].vehicle.model, { + x = garage.Parkings[i].Pos.x, + y = garage.Parkings[i].Pos.y, + z = garage.Parkings[i].Pos.z + }, garage.Parkings[i].Heading, function(vehicle) + ESX.Game.SetVehicleProperties(vehicle, vehicles[j].vehicle) + end) end + spawn(j) + end + end + end - end, name) + end, name) - end) - - end + end) end + else ESX.Game.Teleport(playerPed, { @@ -175,36 +168,28 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) if IsPedInAnyVehicle(playerPed, false) then - local vehicle, distance = ESX.Game.GetClosestVehicle({ - x = coords.x, - y = coords.y, - z = coords.z - }) + local vehicle = GetVehiclePedIsIn(playerPed, false) + local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) + + local spawnCoords = { + x = garage.ExteriorSpawnPoint.Pos.x, + y = garage.ExteriorSpawnPoint.Pos.y, + z = garage.ExteriorSpawnPoint.Pos.z + } - if distance <= 2.0 then + ESX.Game.DeleteVehicle(vehicle) - local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) - - local spawnCoords = { - x = garage.ExteriorSpawnPoint.Pos.x, - y = garage.ExteriorSpawnPoint.Pos.y, - z = garage.ExteriorSpawnPoint.Pos.z - } + ESX.Game.Teleport(playerPed, spawnCoords, function() - ESX.Game.DeleteVehicle(vehicle) - - ESX.Game.Teleport(playerPed, spawnCoords, function() - - TriggerEvent('instance:close') - - ESX.Game.SpawnVehicle(vehicleProps.model, spawnCoords, garage.ExteriorSpawnPoint.Heading, function(vehicle) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - ESX.Game.SetVehicleProperties(vehicle, vehicleProps) - end) + TriggerEvent('instance:close') + ESX.Game.SpawnVehicle(vehicleProps.model, spawnCoords, garage.ExteriorSpawnPoint.Heading, function(vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + ESX.Game.SetVehicleProperties(vehicle, vehicleProps) end) - end + end) + else @@ -220,13 +205,9 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) for i=1, #garage.Parkings, 1 do - local vehicle, distance = ESX.Game.GetClosestVehicle({ - x = garage.Parkings[i].Pos.x, - y = garage.Parkings[i].Pos.y, - z = garage.Parkings[i].Pos.z - }) + local vehicle = GetClosestVehicle(garage.Parkings[i].Pos.x, garage.Parkings[i].Pos.y, garage.Parkings[i].Pos.z, 2.0, 0, 71) - if distance <= 2.0 then + if DoesEntityExist(vehicle) then ESX.Game.DeleteVehicle(vehicle) end @@ -241,12 +222,10 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) if IsPedInAnyVehicle(playerPed, false) then - local vehicle, distance = ESX.Game.GetClosestVehicle() - local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) + local vehicle = GetVehiclePedIsIn(playerPed, false) + local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) - if distance <= 2.0 then - TriggerServerEvent('esx_garage:setParking', name, parking, vehicleProps) - end + TriggerServerEvent('esx_garage:setParking', name, parking, vehicleProps) end From 8fc39925bd0f573ca850f42f706e8f2df8447167 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 11:51:22 +0200 Subject: [PATCH 0323/3224] Update esx_bankerjob.sql --- esx_bankerjob.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_bankerjob.sql b/esx_bankerjob.sql index 5f63c947..40b86b7a 100644 --- a/esx_bankerjob.sql +++ b/esx_bankerjob.sql @@ -14,5 +14,5 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ('banker',1,'banker','Banquier',20,'{}','{}'), ('banker',2,'business_banker','Banquier daffaire',30,'{}','{}'), ('banker',3,'trader','Trader',40,'{}','{}'), - ('banker',4,'boss','Patron',0,'{}','{}'), + ('banker',4,'boss','Patron',0,'{}','{}') ; From 7cbcab51e19e2fa0df634c48179bc0e5271bb5d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 12:21:18 +0200 Subject: [PATCH 0324/3224] Add neon support for ESX.Game.GetVehicleProperties and ESX.Game.SetVehicleProperties --- .../[essential]/es_extended/client/functions.lua | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index fe32b357..2a489e33 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -599,6 +599,13 @@ ESX.Game.GetVehicleProperties = function(vehicle) wheels = GetVehicleWheelType(vehicle), windowTint = GetVehicleWindowTint(vehicle), + neonEnabled = { + IsVehicleNeonLightEnabled(vehicle, 0), + IsVehicleNeonLightEnabled(vehicle, 1), + IsVehicleNeonLightEnabled(vehicle, 2), + IsVehicleNeonLightEnabled(vehicle, 3) + } + neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), modSpoilers = GetVehicleMod(vehicle, 0), @@ -665,6 +672,13 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) SetVehicleWindowTint(vehicle, props.windowTint) end + if props.neonEnabled ~= nil then + SetVehicleNeonLightEnabled(vehicle, 0, props.neonEnabled[1]), + SetVehicleNeonLightEnabled(vehicle, 1, props.neonEnabled[2]), + SetVehicleNeonLightEnabled(vehicle, 2, props.neonEnabled[3]), + SetVehicleNeonLightEnabled(vehicle, 3, props.neonEnabled[4]) + end + if props.neonColor ~= nil then SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) end From d8f64a409892655b0248e5c3bfa9fd37b1553f0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 12:46:36 +0200 Subject: [PATCH 0325/3224] Fix typo --- resources/[essential]/es_extended/client/functions.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 2a489e33..ccbd1138 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -673,9 +673,9 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) end if props.neonEnabled ~= nil then - SetVehicleNeonLightEnabled(vehicle, 0, props.neonEnabled[1]), - SetVehicleNeonLightEnabled(vehicle, 1, props.neonEnabled[2]), - SetVehicleNeonLightEnabled(vehicle, 2, props.neonEnabled[3]), + SetVehicleNeonLightEnabled(vehicle, 0, props.neonEnabled[1]) + SetVehicleNeonLightEnabled(vehicle, 1, props.neonEnabled[2]) + SetVehicleNeonLightEnabled(vehicle, 2, props.neonEnabled[3]) SetVehicleNeonLightEnabled(vehicle, 3, props.neonEnabled[4]) end From 10def0786dde6579ede6d9e4d7e44e452477d1a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 12:55:09 +0200 Subject: [PATCH 0326/3224] Update vehicle color apply functions --- resources/[essential]/es_extended/client/functions.lua | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index ccbd1138..765ef2ed 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -656,8 +656,14 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) SetVehicleDirtLevel(vehicle, props.dirtLevel) end - if props.color1 ~= nil and props.color2 ~= nil then - SetVehicleColours(vehicle, props.color1, props.color2) + if props.color1 ~= nil then + local colour1, colour2 = GetVehicleColours(vehicle) + SetVehicleColours(vehicle, props.color1, color2) + end + + if props.color2 ~= nil then + local colour1, colour2 = GetVehicleColours(vehicle) + SetVehicleColours(vehicle, color1, props.color2) end if props.pearlescentColor ~= nil and props.wheelColor ~= nil then From 94f61f2ed4780340c28785ad7b122bda6fb3f20b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 13:10:17 +0200 Subject: [PATCH 0327/3224] Fix wrong var names --- resources/[essential]/es_extended/client/functions.lua | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 765ef2ed..33e448c9 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -578,7 +578,7 @@ end ESX.Game.GetVehicleProperties = function(vehicle) - local colour1, colour2 = GetVehicleColours(vehicle) + local color1, color2 = GetVehicleColours(vehicle) local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) return { @@ -591,8 +591,6 @@ ESX.Game.GetVehicleProperties = function(vehicle) health = GetEntityHealth(vehicle), dirtLevel = GetVehicleDirtLevel(vehicle), - color1 = colour1, - color2 = colour2, pearlescentColor = pearlescentColor, wheelColor = wheelColor, @@ -657,12 +655,12 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) end if props.color1 ~= nil then - local colour1, colour2 = GetVehicleColours(vehicle) + local color1, color2 = GetVehicleColours(vehicle) SetVehicleColours(vehicle, props.color1, color2) end if props.color2 ~= nil then - local colour1, colour2 = GetVehicleColours(vehicle) + local color1, color2 = GetVehicleColours(vehicle) SetVehicleColours(vehicle, color1, props.color2) end From d41ba790757599ae76703823b4a3d59a98d24889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 14:07:12 +0200 Subject: [PATCH 0328/3224] Fix bugs --- resources/[essential]/es_extended/client/functions.lua | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 33e448c9..c6c7a795 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -591,6 +591,9 @@ ESX.Game.GetVehicleProperties = function(vehicle) health = GetEntityHealth(vehicle), dirtLevel = GetVehicleDirtLevel(vehicle), + color1 = color1, + color2 = color2, + pearlescentColor = pearlescentColor, wheelColor = wheelColor, @@ -601,8 +604,8 @@ ESX.Game.GetVehicleProperties = function(vehicle) IsVehicleNeonLightEnabled(vehicle, 0), IsVehicleNeonLightEnabled(vehicle, 1), IsVehicleNeonLightEnabled(vehicle, 2), - IsVehicleNeonLightEnabled(vehicle, 3) - } + IsVehicleNeonLightEnabled(vehicle, 3), + }, neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), From 922d6cb5c76f8ed24e34787b5022a1324c06c736 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 14:08:00 +0200 Subject: [PATCH 0329/3224] Cleaner code --- client/main.lua | 146 +++++++++++++++++++----------------------------- 1 file changed, 57 insertions(+), 89 deletions(-) diff --git a/client/main.lua b/client/main.lua index 66d7d59f..de821b93 100644 --- a/client/main.lua +++ b/client/main.lua @@ -41,27 +41,7 @@ Citizen.CreateThread(function() end) -function DeleteShopInsideVehicle(cb) - - -- Citizen.CreateThread(function() - - -- while IsAnyVehicleNearPoint(Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 5.0) do - - -- local vehicle, distance = ESX.Game.GetClosestVehicle(Config.Zones.ShopInside.Pos) - - -- if distance <= 5.0 then - -- ESX.Game.DeleteVehicle(vehicle) - -- end - - -- Citizen.Wait(0) - - -- end - - -- if cb ~= nil then - -- cb() - -- end - - -- end) +function DeleteShopInsideVehicles() while #LastVehicles > 0 do local vehicle = LastVehicles[1] @@ -69,8 +49,6 @@ function DeleteShopInsideVehicle(cb) table.remove(LastVehicles, 1) end - cb() - end function OpenShopMenu() @@ -173,27 +151,25 @@ function OpenShopMenu() menu2.close() menu.close() - DeleteShopInsideVehicle(function() + DeleteShopInsideVehicles() - ESX.Game.SpawnVehicle(vehicleData.model, { - x = Config.Zones.ShopOutside.Pos.x, - y = Config.Zones.ShopOutside.Pos.y, - z = Config.Zones.ShopOutside.Pos.z - }, -20.0, function(vehicle) - - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + ESX.Game.SpawnVehicle(vehicleData.model, { + x = Config.Zones.ShopOutside.Pos.x, + y = Config.Zones.ShopOutside.Pos.y, + z = Config.Zones.ShopOutside.Pos.z + }, -20.0, function(vehicle) + + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) + local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) - TriggerServerEvent('esx_vehicleshop:setVehicleOwned', vehicleProps) - - end) - - FreezeEntityPosition(playerPed, false) - SetEntityVisible(playerPed, true) + TriggerServerEvent('esx_vehicleshop:setVehicleOwned', vehicleProps) end) + FreezeEntityPosition(playerPed, false) + SetEntityVisible(playerPed, true) + else ESX.ShowNotification('Vous n\'avez pas assez d\'argent') end @@ -219,24 +195,22 @@ function OpenShopMenu() menu.close() - DeleteShopInsideVehicle(function() + DeleteShopInsideVehicles() - local playerPed = GetPlayerPed(-1) + local playerPed = GetPlayerPed(-1) - CurrentAction = 'shop_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' - CurrentActionData = {} + CurrentAction = 'shop_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {} - FreezeEntityPosition(playerPed, false) - SetEntityVisible(playerPed, true) + FreezeEntityPosition(playerPed, false) + SetEntityVisible(playerPed, true) - if Config.EnablePlayerManagement then - SetEntityCoords(playerPed, Config.Zones.BossActions.Pos.x, Config.Zones.BossActions.Pos.y, Config.Zones.BossActions.Pos.z) - else - SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos.x, Config.Zones.ShopEntering.Pos.y, Config.Zones.ShopEntering.Pos.z) - end - - end) + if Config.EnablePlayerManagement then + SetEntityCoords(playerPed, Config.Zones.BossActions.Pos.x, Config.Zones.BossActions.Pos.y, Config.Zones.BossActions.Pos.z) + else + SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos.x, Config.Zones.ShopEntering.Pos.y, Config.Zones.ShopEntering.Pos.z) + end end, function(data, menu) @@ -244,35 +218,31 @@ function OpenShopMenu() local vehicleData = vehiclesByCategory[data.current.name][data.current.value + 1] local playerPed = GetPlayerPed(-1) - DeleteShopInsideVehicle(function() - - ESX.Game.SpawnLocalVehicle(vehicleData.model, { - x = Config.Zones.ShopInside.Pos.x, - y = Config.Zones.ShopInside.Pos.y, - z = Config.Zones.ShopInside.Pos.z - }, 90.0, function(vehicle) - table.insert(LastVehicles, vehicle) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - FreezeEntityPosition(vehicle, true) - end) + DeleteShopInsideVehicles() + ESX.Game.SpawnLocalVehicle(vehicleData.model, { + x = Config.Zones.ShopInside.Pos.x, + y = Config.Zones.ShopInside.Pos.y, + z = Config.Zones.ShopInside.Pos.z + }, 90.0, function(vehicle) + table.insert(LastVehicles, vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + FreezeEntityPosition(vehicle, true) end) end ) - DeleteShopInsideVehicle(function() - - ESX.Game.SpawnLocalVehicle(firstVehicleData.model, { - x = Config.Zones.ShopInside.Pos.x, - y = Config.Zones.ShopInside.Pos.y, - z = Config.Zones.ShopInside.Pos.z - }, 90.0, function(vehicle) - table.insert(LastVehicles, vehicle) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - FreezeEntityPosition(vehicle, true) - end) + DeleteShopInsideVehicles() + ESX.Game.SpawnLocalVehicle(firstVehicleData.model, { + x = Config.Zones.ShopInside.Pos.x, + y = Config.Zones.ShopInside.Pos.y, + z = Config.Zones.ShopInside.Pos.z + }, 90.0, function(vehicle) + table.insert(LastVehicles, vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + FreezeEntityPosition(vehicle, true) end) end @@ -302,7 +272,7 @@ function OpenResellerMenu() end if data.current.value == 'depop_vehicle' then - DeleteShopInsideVehicle() + DeleteShopInsideVehicles() end if data.current.value == 'create_bill' then @@ -493,23 +463,21 @@ function OpenPopVehicleMenu() local model = data.current.value - DeleteShopInsideVehicle(function() + DeleteShopInsideVehicles() - ESX.Game.SpawnVehicle(model, { - x = Config.Zones.ShopInside.Pos.x, - y = Config.Zones.ShopInside.Pos.y, - z = Config.Zones.ShopInside.Pos.z - }, 90.0, function(vehicle) - - table.insert(LastVehicles, vehicle) + ESX.Game.SpawnVehicle(model, { + x = Config.Zones.ShopInside.Pos.x, + y = Config.Zones.ShopInside.Pos.y, + z = Config.Zones.ShopInside.Pos.z + }, 90.0, function(vehicle) + + table.insert(LastVehicles, vehicle) - for i=1, #Vehicles, 1 do - if model == Vehicles[i].model then - CurrentVehicleData = Vehicles[i] - end + for i=1, #Vehicles, 1 do + if model == Vehicles[i].model then + CurrentVehicleData = Vehicles[i] end - - end) + end end) From 2379178fa5c586396c84fa0acbc4659cef543901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 16:18:36 +0200 Subject: [PATCH 0330/3224] Update README.md --- README.md | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/README.md b/README.md index fa8471cb..b827b23e 100644 --- a/README.md +++ b/README.md @@ -47,13 +47,3 @@ start esx_menu_list start esx_menu_dialog ``` -4) Create a resource or add this in an existing resource : - -``` -server.lua - -TriggerEvent('es:setDefaultSettings', { - nativeMoneySystem = false, -}); - -``` From b8411cc92c871c37e66056a55e3f925a87507fb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 17:16:29 +0200 Subject: [PATCH 0331/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..b092e439 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_shops +FXServer ESX Shops From 3afa93d090a56fccc6ee69a3a8b88f0aba3a5899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 17:17:23 +0200 Subject: [PATCH 0332/3224] Update README.md --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index b092e439..1bfeb057 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,16 @@ # fxserver-esx_shops FXServer ESX Shops + +[INSTALLATION] + +1) CD in your resources/[esx] folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-esx_shops esx_shops +``` +3) Import esx_shops.sql in your database +4) Add this in your server.cfg : + +``` +start esx_shops +``` From 7080f8b5b68af8da55cb24f4bf7ca8128495d738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 17:21:04 +0200 Subject: [PATCH 0333/3224] Add files --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++ __resource.lua | 12 + client/main.lua | 163 ++++++++++++ config.lua | 49 ++++ esx_shops.sql | 20 ++ server/main.lua | 69 +++++ 6 files changed, 987 insertions(+) create mode 100644 LICENSE.txt create mode 100644 __resource.lua create mode 100644 client/main.lua create mode 100644 config.lua create mode 100644 esx_shops.sql create mode 100644 server/main.lua diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..47caca54 --- /dev/null +++ b/__resource.lua @@ -0,0 +1,12 @@ +description 'ESX Mecano Job' + +client_scripts { + 'config.lua', + 'client/main.lua' +} + +server_scripts { + '@mysql-async/lib/MySQL.lua', + 'config.lua', + 'server/main.lua' +} \ No newline at end of file diff --git a/client/main.lua b/client/main.lua new file mode 100644 index 00000000..fe65c57f --- /dev/null +++ b/client/main.lua @@ -0,0 +1,163 @@ +ESX = nil +local HasAlreadyEnteredMarker = false +local LastZone = nil +local CurrentAction = nil +local CurrentActionMsg = '' +local CurrentActionData = {} + +Citizen.CreateThread(function() + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end +end) + +AddEventHandler('onClientMapStart', function() + + ESX.TriggerServerCallback('esx_shop:requestDBItems', function(ShopItems) + for k,v in pairs(ShopItems) do + Config.Zones[k].Items = v + end + end) + +end) + +function OpenShopMenu(zone) + + local elements = {} + + for i=1, #Config.Zones[zone].Items, 1 do + + local item = Config.Zones[zone].Items[i] + + table.insert(elements, { + label = item.label .. ' - $' .. item.price .. ' ', + realLabel = item.label, + value = item.name, + price = item.price + }) + + end + + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'shop', + { + title = 'Magasin', + elements = elements + }, + function(data, menu) + TriggerServerEvent('esx_shop:buyItem', data.current.value, data.current.price) + end, + function(data, menu) + + menu.close() + + CurrentAction = 'shop_menu' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au magasin.' + CurrentActionData = {zone = zone} + end + ) +end + +AddEventHandler('esx_shop:hasEnteredMarker', function(zone) + + CurrentAction = 'shop_menu' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au magasin.' + CurrentActionData = {zone = zone} + +end) + +AddEventHandler('esx_shop:hasExitedMarker', function(zone) + + CurrentAction = nil + ESX.UI.Menu.CloseAll() + +end) + +-- Create Blips +Citizen.CreateThread(function() + for k,v in pairs(Config.Zones) do + for i = 1, #v.Pos, 1 do + local blip = AddBlipForCoord(v.Pos[i].x, v.Pos[i].y, v.Pos[i].z) + SetBlipSprite (blip, 52) + SetBlipDisplay(blip, 4) + SetBlipScale (blip, 1.0) + SetBlipColour (blip, 2) + SetBlipAsShortRange(blip, true) + BeginTextCommandSetBlipName("STRING") + AddTextComponentString("Magasins") + EndTextCommandSetBlipName(blip) + end + end +end) + +-- Display markers +Citizen.CreateThread(function() + while true do + Wait(0) + local coords = GetEntityCoords(GetPlayerPed(-1)) + for k,v in pairs(Config.Zones) do + for i = 1, #v.Pos, 1 do + if(Config.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos[i].x, v.Pos[i].y, v.Pos[i].z, true) < Config.DrawDistance) then + DrawMarker(Config.Type, v.Pos[i].x, v.Pos[i].y, v.Pos[i].z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.Size.x, Config.Size.y, Config.Size.z, Config.Color.r, Config.Color.g, Config.Color.b, 100, false, true, 2, false, false, false, false) + end + end + end + end +end) + +-- Enter / Exit marker events +Citizen.CreateThread(function() + while true do + Wait(0) + local coords = GetEntityCoords(GetPlayerPed(-1)) + local isInMarker = false + local currentZone = nil + + for k,v in pairs(Config.Zones) do + for i = 1, #v.Pos, 1 do + if(GetDistanceBetweenCoords(coords, v.Pos[i].x, v.Pos[i].y, v.Pos[i].z, true) < Config.Size.x) then + isInMarker = true + ShopItems = v.Items + currentZone = k + LastZone = k + end + end + end + if isInMarker and not HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = true + TriggerEvent('esx_shop:hasEnteredMarker', currentZone) + end + if not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent('esx_shop:hasExitedMarker', LastZone) + end + end +end) + +-- Key Controls +Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + if CurrentAction ~= nil then + + SetTextComponentFormat('STRING') + AddTextComponentString(CurrentActionMsg) + DisplayHelpTextFromStringLabel(0, 0, 1, -1) + + if IsControlJustReleased(0, 38) then + + if CurrentAction == 'shop_menu' then + OpenShopMenu(CurrentActionData.zone) + end + + CurrentAction = nil + + end + + end + end +end) \ No newline at end of file diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..6c7dd251 --- /dev/null +++ b/config.lua @@ -0,0 +1,49 @@ +Config = {} + +Config.DrawDistance = 100 +Config.Size = {x = 1.5, y = 1.5, z = 1.5} +Config.Color = {r = 0, g = 128, b = 255} +Config.Type = 1 + +Config.Zones = { + + TwentyFourSeven = { + Items = {}, + Pos = { + {x = 373.875, y = 325.896, z = 102.566}, + {x = 2557.458, y = 382.282, z = 107.622}, + {x = -3038.939, y = 585.954, z = 6.908}, + {x = -3241.927, y = 1001.462, z = 11.830}, + {x = 547.431, y = 2671.710, z = 41.156}, + {x = 1961.464, y = 3740.672, z = 31.343}, + {x = 2678.916, y = 3280.671, z = 54.241}, + {x = 1729.216, y = 6414.131, z = 34.037} + } + }, + + RobsLiquor = { + Items = {}, + Pos = { + {x = 1135.808, y = -982.281, z = 45.415}, + {x = -1222.915, y = -906.983, z = 11.326}, + {x = -1487.553, y = -379.107, z = 39.163}, + {x = -2968.243, y = 390.910, z = 14.043}, + {x = 1166.024, y = 2708.930, z = 37.157}, + {x = 1392.562, y = 3604.684, z = 33.980}, + {x = 127.830, y = -1284.796, z = 29.280}, --StripClub + {x = -1393.409, y = -606.624, z = 30.319}, --Tequila la + {x = -559.906, y = 287.093, z = 82.176} --Bahamamas + } + }, + + LTDgasoline = { + Items = {}, + Pos = { + {x = -48.519, y = -1757.514, z = 28.421}, + {x = 1163.373, y = -323.801, z = 68.205}, + {x = -707.501, y = -914.260, z = 18.215}, + {x = -1820.523, y = 792.518, z = 137.118}, + {x = 1698.388, y = 4924.404, z = 41.063} + } + } +} \ No newline at end of file diff --git a/esx_shops.sql b/esx_shops.sql new file mode 100644 index 00000000..b9f72161 --- /dev/null +++ b/esx_shops.sql @@ -0,0 +1,20 @@ +USE `essentialmode`; + +CREATE TABLE `shops` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `item` varchar(255) NOT NULL, + `price` int(11) NOT NULL, + + PRIMARY KEY (`id`) +); + +INSERT INTO `shops` (name, item, price) VALUES + ('TwentyFourSeven','bread',30), + ('TwentyFourSeven','water',15), + ('RobsLiquor','bread',30), + ('RobsLiquor','water',15), + ('LTDgasoline','bread',30), + ('LTDgasoline','water',15) +; \ No newline at end of file diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..9d80efbe --- /dev/null +++ b/server/main.lua @@ -0,0 +1,69 @@ +ESX = nil +local ItemsLabels = {} + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +AddEventHandler('onMySQLReady', function() + + MySQL.Async.fetchAll( + 'SELECT * FROM items', + {}, + function(result) + + for i=1, #result, 1 do + ItemsLabels[result[i].name] = result[i].label + end-- + + end + ) + +end) + +ESX.RegisterServerCallback('esx_shop:requestDBItems', function(source, cb) + + MySQL.Async.fetchAll( + 'SELECT * FROM shops', + {}, + function(result) + + local shopItems = {} + + for i=1, #result, 1 do + + if shopItems[result[i].name] == nil then + shopItems[result[i].name] = {} + end + + table.insert(shopItems[result[i].name], { + name = result[i].item, + price = result[i].price, + label = ItemsLabels[result[i].item] + }) + + end + + cb(shopItems) + + end + ) + +end) + +RegisterServerEvent('esx_shop:buyItem') +AddEventHandler('esx_shop:buyItem', function(itemName, price) + + local _source = source + local xPlayer = ESX.GetPlayerFromId(source) + + if xPlayer.get('money') >= price then + + xPlayer.removeMoney(price) + xPlayer.addInventoryItem(itemName, 1) + + TriggerClientEvent('esx:showNotification', _source, 'Vous avez acheté ~b~1x ' .. ItemsLabels[itemName]) + + else + TriggerClientEvent('esx:showNotification', _source, 'Vous n\'avez ~r~pas assez~s~ d\'argent.') + end + +end) From ca7cc2879172baf2f8246f3456bbf2bbba268a76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 20:56:40 +0200 Subject: [PATCH 0334/3224] Fix prop detection + probably fix getclosestvehicle --- client/main.lua | 46 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/client/main.lua b/client/main.lua index 80013822..aff4c245 100644 --- a/client/main.lua +++ b/client/main.lua @@ -420,7 +420,7 @@ function OpenPoliceActionsMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'citizen_interaction', { - title = 'Interactions Voirie', + title = 'Interaction Voirie', align = 'top-left', elements = { {label = 'Plot', value = 'prop_roadcone02a'}, @@ -1343,6 +1343,15 @@ end) -- Enter / Exit entity zone events Citizen.CreateThread(function() + + local trackedEntities = { + 'prop_roadcone02a', + 'prop_barrier_work06a', + 'p_ld_stinger_s', + 'prop_boxpile_07d', + 'hei_prop_cash_crate_half_full' + } + while true do Citizen.Wait(0) @@ -1350,19 +1359,32 @@ Citizen.CreateThread(function() local playerPed = GetPlayerPed(-1) local coords = GetEntityCoords(playerPed) - local entity, distance = ESX.Game.GetClosestObject({ - 'prop_roadcone02a', - 'prop_barrier_work06a', - 'p_ld_stinger_s', - 'prop_boxpile_07d', - 'hei_prop_cash_crate_half_full' - }) + local closestDistance = -1 + local closestEntity = nil - if distance ~= -1 and distance <= 3.0 then + for i=1, #trackedEntities, 1 do + + local object = GetClosestObjectOfType(coords.x, coords.y, coords.z, 3.0, GetHashKey(trackedEntities[i]), false, false, false) + + if DoesEntityExist(object) then - if LastEntity ~= entity then - TriggerEvent('esx_policejob:hasEnteredEntityZone', entity) - LastEntity = entity + local objCoords = GetEntityCoords(object) + local distance = GetDistanceBetweenCoords(coords.x, coords.y, coords.z, objCoords.x, objCoords.y, objCoords.z, true) + + if closestDistance == -1 or closestDistance > distance then + closestDistance = distance + closestEntity = object + end + + end + + end + + if closestDistance ~= -1 and closestDistance <= 3.0 then + + if LastEntity ~= closestEntity then + TriggerEvent('esx_policejob:hasEnteredEntityZone', closestEntity) + LastEntity = closestEntity end else From bd4559667fe5c1ea9d51b3dc9d873623f7683ffe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 21:17:07 +0200 Subject: [PATCH 0335/3224] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 577f6681..f29d2432 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ FXServer ESX Taxi Job [REQUIREMENTS] * Auto mode - * No need to download another resource - + * esx_service => https://github.com/FXServer-ESX/fxserver-esx_service + * Player management (billing and boss actions) * esx_society => https://github.com/FXServer-ESX/fxserver-esx_society * esx_billing => https://github.com/FXServer-ESX/fxserver-esx_billing From 3df33a64d385ca733859db61ac53f1eca8826627 Mon Sep 17 00:00:00 2001 From: Aleweadan Date: Sun, 13 Aug 2017 22:24:13 +0200 Subject: [PATCH 0336/3224] Minor fix --- esx_ambulancejob_full.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_ambulancejob_full.sql b/esx_ambulancejob_full.sql index f368789a..4d22f6be 100644 --- a/esx_ambulancejob_full.sql +++ b/esx_ambulancejob_full.sql @@ -1,7 +1,7 @@ USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES - ('society_ambulance', 'Ambulance', 1), + ('society_ambulance', 'Ambulance', 1) ; INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES From 91ba5e08c8e8454f7e80f727cd9a53e19f49e624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 22:24:36 +0200 Subject: [PATCH 0337/3224] Update esx_realestateagentjob.sql --- esx_realestateagentjob.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_realestateagentjob.sql b/esx_realestateagentjob.sql index c15aa369..947ff9bc 100644 --- a/esx_realestateagentjob.sql +++ b/esx_realestateagentjob.sql @@ -1,4 +1,4 @@ -USE `gta5_gamemode_essential`; +USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES ('society_realestateagent','Agent Immobilier',1) From 5797ea37ce4b27d752b949ed2557c636c75a36dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 22:39:05 +0200 Subject: [PATCH 0338/3224] Fix source --- server/main.lua | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/server/main.lua b/server/main.lua index 1828d4a1..0c5ac3f9 100644 --- a/server/main.lua +++ b/server/main.lua @@ -40,12 +40,14 @@ ESX.RegisterServerCallback('esx_service:enableService', function(source, cb, nam end) -AddEventHandler('playerDropped', function(source) +AddEventHandler('playerDropped', function() + local _source = source + for k,v in pairs(InService) do - if v[source] == true then - v[source] = nil + if v[_source] == true then + v[_source] = nil end end -end) \ No newline at end of file +end) From f2337dae21e3d1b6772afbd1da8a8c1d68d91f1a Mon Sep 17 00:00:00 2001 From: Don Date: Mon, 14 Aug 2017 14:37:48 -0700 Subject: [PATCH 0339/3224] multilanguagesupport Added multi-language support --- __resource.lua | 8 ++++++- client/main.lua | 64 ++++++++++++++++++++++++------------------------- config.lua | 1 + locales/en.lua | 33 +++++++++++++++++++++++++ locales/fr.lua | 33 +++++++++++++++++++++++++ 5 files changed, 106 insertions(+), 33 deletions(-) create mode 100644 locales/en.lua create mode 100644 locales/fr.lua diff --git a/__resource.lua b/__resource.lua index d181aa85..507ade9c 100644 --- a/__resource.lua +++ b/__resource.lua @@ -4,11 +4,17 @@ description 'ESX Ambulance Job' server_scripts { '@mysql-async/lib/MySQL.lua', + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', 'config.lua', 'server/main.lua' } client_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', 'config.lua', 'client/main.lua' -} +} \ No newline at end of file diff --git a/client/main.lua b/client/main.lua index 88d87c1a..c7b67f96 100644 --- a/client/main.lua +++ b/client/main.lua @@ -114,7 +114,7 @@ function WarpPedInClosestVehicle(ped) end else - ESX.ShowNotification('Aucun véhicule à proximité') + ESX.ShowNotification(_U('no_vehicles')) end end @@ -122,12 +122,12 @@ end function OpenAmbulanceActionsMenu() local elements = { - {label = 'Vestiaire', value = 'cloakroom'} + {label = _U('cloakroom'), value = 'cloakroom'} } if Config.EnablePlayerManagement and PlayerData.job.grade_name == 'boss' then - table.insert(elements, {label = 'Retirer argent société', value = 'withdraw_society_money'}) - table.insert(elements, {label = 'Déposer argent', value = 'deposit_society_money'}) + table.insert(elements, {label = _U('withdraw_society'), value = 'withdraw_society_money'}) + table.insert(elements, {label = _U('deposit_society'), value = 'deposit_society_money'}) end ESX.UI.Menu.CloseAll() @@ -135,7 +135,7 @@ function OpenAmbulanceActionsMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'ambulance_actions', { - title = 'Ambulance', + title = _U('ambulance'), elements = elements }, function(data, menu) @@ -149,14 +149,14 @@ function OpenAmbulanceActionsMenu() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'withdraw_society_money_amount', { - title = 'Montant du retrait' + title = _U('money_withdraw') }, function(data, menu) local amount = tonumber(data.value) if amount == nil then - ESX.ShowNotification('Montant invalide') + ESX.ShowNotification(_U('invalid_amount')) else menu.close() TriggerServerEvent('esx_society:withdrawMoney', 'ambulance', amount) @@ -175,14 +175,14 @@ function OpenAmbulanceActionsMenu() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'deposit_money_amount', { - title = 'Montant du dépôt' + title = _U('deposit_amount') }, function(data, menu) local amount = tonumber(data.value) if amount == nil then - ESX.ShowNotification('Montant invalide') + ESX.ShowNotification(_U('invalid_amount')) else menu.close() TriggerServerEvent('esx_society:depositMoney', 'ambulance', amount) @@ -202,7 +202,7 @@ function OpenAmbulanceActionsMenu() menu.close() CurrentAction = 'ambulance_actions_menu' - CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour ouvrir le menu' + CurrentActionMsg = _U('open_menu') CurrentActionData = {} end @@ -217,9 +217,9 @@ function OpenMobileAmbulanceActionsMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'mobile_ambulance_actions', { - title = 'Ambulance', + title = _U('ambulance'), elements = { - {label = 'Interaction citoyen', value = 'citizen_interaction'}, + {label = _U('ems_menu'), value = 'citizen_interaction'}, } }, function(data, menu) @@ -229,10 +229,10 @@ function OpenMobileAmbulanceActionsMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'citizen_interaction', { - title = 'Ambulance - Interactions Citoyen', + title = _U('ems_menu_title'), elements = { - {label = 'Réanimer', value = 'revive'}, - {label = 'Mettre dans véhicule', value = 'put_in_vehicle'}, + {label = _U('ems_menu_revive'), value = 'revive'}, + {label = _U('ems_menu_putincar'), value = 'put_in_vehicle'}, } }, function(data, menu) @@ -244,7 +244,7 @@ function OpenMobileAmbulanceActionsMenu() local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification('Aucun joueur à proximité') + ESX.ShowNotification(_U('no_players')) else local ped = GetPlayerPed(closestPlayer) @@ -257,7 +257,7 @@ function OpenMobileAmbulanceActionsMenu() Citizen.CreateThread(function() - ESX.ShowNotification('Réanimation en cours') + ESX.ShowNotification(_U('revive_inprogress')) TaskStartScenarioInPlace(playerPed, 'CODE_HUMAN_MEDIC_TEND_TO_DEAD', 0, true) Citizen.Wait(10000) @@ -265,15 +265,15 @@ function OpenMobileAmbulanceActionsMenu() if GetEntityHealth(closestPlayerPed) == 0 then TriggerServerEvent('esx_ambulancejob:revive', GetPlayerServerId(closestPlayer)) - ESX.ShowNotification('Vous avez réanimé ' .. GetPlayerName(closestPlayer)) + ESX.ShowNotification(_U('revive_complete') .. GetPlayerName(closestPlayer)) else - ESX.ShowNotification(GetPlayerName(closestPlayer) .. ' a succombé') + ESX.ShowNotification(GetPlayerName(closestPlayer) .. _U('isdead')) end end) else - ESX.ShowNotification(GetPlayerName(closestPlayer) .. ' n\'est pas inconscient') + ESX.ShowNotification(GetPlayerName(closestPlayer) .. _U('unconscious')) end end @@ -306,11 +306,11 @@ function OpenCloakroomMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'cloakroom', { - title = 'Vestiaire', + title = _U('cloakroom'), align = 'top-left', elements = { - {label = 'Tenue Civil', value = 'citizen_wear'}, - {label = 'Tenue Ambulancier', value = 'ambulance_wear'}, + {label = _U('ems_clothes_civil'), value = 'citizen_wear'}, + {label = _U('ems_clothes_ems'), value = 'ambulance_wear'}, }, }, function(data, menu) @@ -340,7 +340,7 @@ function OpenCloakroomMenu() end CurrentAction = 'ambulance_actions_menu' - CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour ouvrir le menu' + CurrentActionMsg = _U('open_menu') CurrentActionData = {} end, @@ -356,11 +356,11 @@ function OpenVehicleSpawnerMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'cloakroom', { - title = 'Véhicule', + title = _U('veh_menu'), align = 'top-left', elements = { - {label = 'Ambulance', value = 'ambulance'}, - {label = 'Hélicoptère', value = 'polmav'}, + {label = _U('ambulance'), value = 'ambulance'}, + {label = _U('helicopter'), value = 'polmav'}, }, }, function(data, menu) @@ -388,7 +388,7 @@ function OpenVehicleSpawnerMenu() menu.close() CurrentAction = 'vehicle_spawner_menu' - CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour sortir un véhicule' + CurrentActionMsg = _U('veh_spawn') CurrentActionData = {} end @@ -533,13 +533,13 @@ AddEventHandler('esx_ambulancejob:hasEnteredMarker', function(zone) if zone == 'AmbulanceActions' and PlayerData.job ~= nil and PlayerData.job.name == 'ambulance' then CurrentAction = 'ambulance_actions_menu' - CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour ouvrir le menu' + CurrentActionMsg = _U('open_menu') CurrentActionData = {} end if zone == 'VehicleSpawner' and PlayerData.job ~= nil and PlayerData.job.name == 'ambulance' then CurrentAction = 'vehicle_spawner_menu' - CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour sortir un véhicule' + CurrentActionMsg = _U('veh_spawn') CurrentActionData = {} end @@ -559,7 +559,7 @@ AddEventHandler('esx_ambulancejob:hasEnteredMarker', function(zone) if distance ~= -1 and distance <= 1.0 then CurrentAction = 'delete_vehicle' - CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour ranger le véhicule' + CurrentActionMsg = _U('store_veh') CurrentActionData = {vehicle = vehicle} end @@ -585,7 +585,7 @@ Citizen.CreateThread(function() SetBlipAsShortRange(blip, true) BeginTextCommandSetBlipName("STRING") - AddTextComponentString("Hôpital") + AddTextComponentString(_U('hospital')) EndTextCommandSetBlipName(blip) end) diff --git a/config.lua b/config.lua index aa86bf2c..f41fe565 100644 --- a/config.lua +++ b/config.lua @@ -7,6 +7,7 @@ Config.RemoveWeaponsAfterRPDeath = true Config.RemoveCashAfterRPDeath = true Config.RemoveItemsAfterRPDeath = true Config.EnablePlayerManagement = false +Config.Locale = 'fr' Config.Zones = { diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..26d663dd --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,33 @@ +Locales['en'] = { + --Cloakroom + ['cloakroom'] = 'locker Room', + ['ems_clothes_civil'] = 'civilian Clothes', + ['ems_clothes_ems'] = 'eMS Clothes', + --Vehicles + ['veh_menu'] = 'vehicle', + ['veh_spawn'] = 'press ~INPUT_CONTEXT~ to get a Vehicle or Helicopter', + ['store_veh'] = 'press ~INPUT_CONTEXT~ to store the vehicle', + ['ambulance'] = 'ambulance', + ['helicopter'] = 'helicopter', + --Action Menu + ['hospital'] = 'hospital', + ['revive_inprogress'] = 'revive in progress', + ['revive_complete'] = 'you have been revived ', + ['no_players'] = 'no players nearby', + ['no_vehicles'] = 'no vehicles nearby', + ['isdead'] = 'is dead', + ['unconscious'] = 'is not unconscious', + --Boss Menu + ['deposit_society'] = 'eMS Deposit', + ['withdraw_society'] = 'eMS Withdraw', + --Misc + ['invalid_amount'] = '~r~invalid amount', + ['open_menu'] = 'press ~INPUT_CONTEXT~ to open the menu', + ['deposit_amount'] = 'deposit Amount', + ['money_withdraw'] = 'amount withdrawn', + -- F6 Menu + ['ems_menu'] = 'eMS Menu', + ['ems_menu_title'] = 'ambulance - EMS Menu', + ['ems_menu_revive'] = 'revive Player', + ['ems_menu_putincar'] = 'put in Vehicle', +} \ No newline at end of file diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..da7d1d2e --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,33 @@ +Locales['fr'] = { + --Cloakroom + ['cloakroom'] = 'Vestiaire', + ['ems_clothes_civil'] = 'Tenue Civil', + ['ems_clothes_ems'] = 'Tenue Ambulancier', + --Vehicles + ['veh_menu'] = 'véhicule', + ['veh_spawn'] = 'appuyez sur ~INPUT_CONTEXT~ pour sortir un véhicule', + ['store_veh'] = 'appuyez sur ~INPUT_CONTEXT~ pour ranger le véhicule', + ['ambulance'] = 'ambulance', + ['helicopter'] = 'hélicoptère', + --Action Menu + ['hospital'] = 'hôpital', + ['revive_inprogress'] = 'réanimation en cours', + ['revive_complete'] = 'vous avez réanimé ', + ['no_players'] = 'aucun joueur à proximité', + ['no_vehicles'] = 'aucun véhicule à proximité', + ['isdead'] = 'a succombé', + ['unconscious'] = 'n\'est pas inconscient', + --Boss Menu + ['deposit_society'] = 'déposer argent', + ['withdraw_society'] = 'retirer argent société', + --Misc + ['invalid_amount'] = '~r~montant invalide', + ['open_menu'] = 'appuyez sur ~INPUT_CONTEXT~ pour ouvrir le menu', + ['deposit_amount'] = 'montant du dépôt', + ['money_withdraw'] = 'montant du retrait', + -- F6 Menu + ['ems_menu'] = 'interaction citoyen', + ['ems_menu_title'] = 'ambulance - Interactions Citoyen', + ['ems_menu_revive'] = 'réanimer', + ['ems_menu_putincar'] = 'mettre dans véhicule', +} \ No newline at end of file From f175149adf9a3d2c5bee15ab30e8ea1ca7d15657 Mon Sep 17 00:00:00 2001 From: Don Date: Mon, 14 Aug 2017 15:06:48 -0700 Subject: [PATCH 0340/3224] Multi-Language support Added multi-language support --- __resource.lua | 31 +++++++++++++++++++------------ client/esx_atm_cl.lua | 2 +- config.lua | 3 ++- locales/en.lua | 6 ++++++ locales/fr.lua | 6 ++++++ server/esx_atm_sv.lua | 8 ++++---- 6 files changed, 38 insertions(+), 18 deletions(-) create mode 100644 locales/en.lua create mode 100644 locales/fr.lua diff --git a/__resource.lua b/__resource.lua index 10f49234..024bfe07 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,18 +1,25 @@ -description 'ESX ATM' +server_script{ + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', + 'config.lua', + 'server/esx_atm_sv.lua' +} -server_script 'server/esx_atm_sv.lua' - -client_script { - 'config.lua', - 'client/esx_atm_cl.lua' +client_script{ + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', + 'config.lua', + 'client/esx_atm_cl.lua' } ui_page 'html/ui.html' -files { - 'html/ui.html', - 'html/pdown.ttf', - 'html/img/cursor.png', - 'html/css/app.css', - 'html/scripts/app.js' +files{ + 'html/ui.html', + 'html/pdown.ttf', + 'html/img/cursor.png', + 'html/css/app.css', + 'html/scripts/app.js' } \ No newline at end of file diff --git a/client/esx_atm_cl.lua b/client/esx_atm_cl.lua index b0fa1854..8b959333 100644 --- a/client/esx_atm_cl.lua +++ b/client/esx_atm_cl.lua @@ -74,7 +74,7 @@ Citizen.CreateThread(function() if(GetDistanceBetweenCoords(coords, Config.ATMS[i].x, Config.ATMS[i].y, Config.ATMS[i].z, true) < Config.ZoneSize.x / 2) then isInATMMarker = true SetTextComponentFormat('STRING') - AddTextComponentString('Appuyez sur ~INPUT_PICKUP~ pour déposer ou retirer du ~g~cash~s~.') + AddTextComponentString(_U('press_e_atm')) DisplayHelpTextFromStringLabel(0, 0, 1, -1) end end diff --git a/config.lua b/config.lua index a57596af..da5415ab 100644 --- a/config.lua +++ b/config.lua @@ -5,8 +5,9 @@ Config.ZoneSize = {x = 3.0, y = 3.0, z = 0.3} Config.MarkerColor = {r = 100, g = 100, b = 204} Config.ZDiff = 2.0 Config.BlipSprite = 431 +Config.Locale = 'fr' - Config.ATMS = { +Config.ATMS = { { ['x'] = -386.733, ['y'] = 6045.953, ['z'] = 31.501}, { ['x'] = -110.753, ['y'] = 6467.703, ['z'] = 31.784}, { ['x'] = 155.4300, ['y'] = 6641.991, ['z'] = 31.784}, diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..4af17004 --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,6 @@ +Locales['en'] = { + ['invalid_amount'] = '~r~invalid amount', + ['deposit_money'] = 'you have deposited ~g~$', + ['withdraw_money'] = 'you withdrawn ~g~$', + ['press_e_atm'] = 'press sure ~INPUT_PICKUP~ for deposit or withdraw from ~g~ATM~s~.', +} \ No newline at end of file diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..5a7e81c2 --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,6 @@ +Locales['fr'] = { + ['invalid_amount'] = '~r~montant invalide', + ['deposit_money'] = 'vous avez déposé ~g~$', + ['withdraw_money'] = 'vous avez retiré ~g~$', + ['press_e_atm'] = 'appuyez sur ~INPUT_PICKUP~ pour déposer ou retirer du ~g~cash~s~.', +} \ No newline at end of file diff --git a/server/esx_atm_sv.lua b/server/esx_atm_sv.lua index ca05e499..341b7c1f 100644 --- a/server/esx_atm_sv.lua +++ b/server/esx_atm_sv.lua @@ -7,11 +7,11 @@ AddEventHandler('esx_atm:deposit', function(amount) local xPlayer = ESX.GetPlayerFromId(_source) amount = tonumber(amount) if amount == nil or amount <= 0 or amount > xPlayer.getMoney() then - TriggerClientEvent('esx:showNotification', _source, '~r~Montant invalide') + TriggerClientEvent('esx:showNotification', _source, _U('invalid_amount')) else xPlayer.removeMoney(amount) xPlayer.addAccountMoney('bank', amount) - TriggerClientEvent('esx:showNotification', _source, 'Vous avez déposé ~g~' .. amount .. '$~s~.') + TriggerClientEvent('esx:showNotification', _source, _U('deposit_money') .. amount .. '~s~.') TriggerClientEvent('esx_atm:closeATM', _source) end end) @@ -25,11 +25,11 @@ AddEventHandler('esx_atm:withdraw', function(amount) local accountMoney = 0 accountMoney = xPlayer.getAccount('bank').money if amount == nil or amount <= 0 or amount > accountMoney then - TriggerClientEvent('esx:showNotification', _source, '~r~Montant invalide') + TriggerClientEvent('esx:showNotification', _source, _U('invalid_amount')) else xPlayer.removeAccountMoney('bank', amount) xPlayer.addMoney(amount) - TriggerClientEvent('esx:showNotification', _source, 'Vous avez retiré ~g~' .. amount .. '$~s~.') + TriggerClientEvent('esx:showNotification', _source, _U('withdraw_money') .. amount .. '~s~.') TriggerClientEvent('esx_atm:closeATM', _source) end end) \ No newline at end of file From dcb3c667408b8202b0cfefbe75794877f639f728 Mon Sep 17 00:00:00 2001 From: angerthosenear Date: Sun, 13 Aug 2017 17:34:04 -0500 Subject: [PATCH 0341/3224] Grammatical fix (en) --- locales/en.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/en.lua b/locales/en.lua index 4af17004..45358ed9 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -2,5 +2,5 @@ Locales['en'] = { ['invalid_amount'] = '~r~invalid amount', ['deposit_money'] = 'you have deposited ~g~$', ['withdraw_money'] = 'you withdrawn ~g~$', - ['press_e_atm'] = 'press sure ~INPUT_PICKUP~ for deposit or withdraw from ~g~ATM~s~.', -} \ No newline at end of file + ['press_e_atm'] = 'press ~INPUT_PICKUP~ for deposit or withdrawal from ~g~ATM~s~.', +} From 9cd25a852e31928ed5ce66fe3c1b3e4fe3662e52 Mon Sep 17 00:00:00 2001 From: renaiku Date: Mon, 14 Aug 2017 01:48:16 +0200 Subject: [PATCH 0342/3224] Add pearl + wheels support --- resources/[essential]/es_extended/client/functions.lua | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index c6c7a795..f3c04818 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -667,8 +667,14 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) SetVehicleColours(vehicle, color1, props.color2) end - if props.pearlescentColor ~= nil and props.wheelColor ~= nil then - SetVehicleExtraColours(vehicle, props.pearlescentColor, props.wheelColor) + if props.pearlescentColor ~= nil then + local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) + SetVehicleExtraColours(vehicle, props.pearlescentColor, wheelColor) + end + + if props.wheelColor ~= nil then + local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) + SetVehicleExtraColours(vehicle, pearlescentColor, props.wheelColor) end if props.wheels ~= nil then From afe05509bc5add5a4f10237a0b672c45bad4178a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 14 Aug 2017 13:42:18 +0200 Subject: [PATCH 0343/3224] Fix source in playerDropped --- server/esx_jobs_sv.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/esx_jobs_sv.lua b/server/esx_jobs_sv.lua index 5c1f7ce7..215886c2 100644 --- a/server/esx_jobs_sv.lua +++ b/server/esx_jobs_sv.lua @@ -4,7 +4,7 @@ local Players = {} ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) -AddEventHandler('esx:playerDropped', function(source) +AddEventHandler('esx:playerDropped', function() local _source = source local xPlayer = ESX.GetPlayerFromId(_source) local caution = xPlayer.get('caution') @@ -125,4 +125,4 @@ AddEventHandler('esx_jobs:caution', function(cautionType, cautionAmount, spawnPo xPlayer.set('caution', 0) TriggerClientEvent('esx:showNotification', source, 'Une caution de ~g~'.. cautionAmount .. '$ ~s~vous a été rendue.') end -end) \ No newline at end of file +end) From 1f2b2119905b584629dd3ed0849158b66f103cdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 14 Aug 2017 13:46:31 +0200 Subject: [PATCH 0344/3224] Bring back source --- server/esx_jobs_sv.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/esx_jobs_sv.lua b/server/esx_jobs_sv.lua index 215886c2..94e750b6 100644 --- a/server/esx_jobs_sv.lua +++ b/server/esx_jobs_sv.lua @@ -4,7 +4,7 @@ local Players = {} ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) -AddEventHandler('esx:playerDropped', function() +AddEventHandler('esx:playerDropped', function(source) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) local caution = xPlayer.get('caution') From 52406653d4b7a2c48ca94db87b0ebfc815942a9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 14 Aug 2017 13:51:55 +0200 Subject: [PATCH 0345/3224] Update esx_jobs_sv.lua --- server/esx_jobs_sv.lua | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/server/esx_jobs_sv.lua b/server/esx_jobs_sv.lua index 94e750b6..4bc5290e 100644 --- a/server/esx_jobs_sv.lua +++ b/server/esx_jobs_sv.lua @@ -4,6 +4,11 @@ local Players = {} ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) +AddEventHandler('esx:playerLodaded', function(source) + local xPlayer = ESX.GetPlayerFromId(source) + xPlayer.set('caution', 0) +end) + AddEventHandler('esx:playerDropped', function(source) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) @@ -39,13 +44,6 @@ AddEventHandler('esx_jobs:giveBackCautionInCaseOfDrop', function() end end) -RegisterServerEvent('esx_jobs:setCaution') -AddEventHandler('esx_jobs:setCaution', function() - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) - xPlayer.set('caution', 0) -end) - local function Work(source, item) SetTimeout(item[1].time, function() From 8f4b29946cf72509b89cd73712694c4bc91ff716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 14 Aug 2017 13:53:16 +0200 Subject: [PATCH 0346/3224] Update esx_jobs_sv.lua --- server/esx_jobs_sv.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/esx_jobs_sv.lua b/server/esx_jobs_sv.lua index 4bc5290e..2cec943a 100644 --- a/server/esx_jobs_sv.lua +++ b/server/esx_jobs_sv.lua @@ -4,7 +4,7 @@ local Players = {} ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) -AddEventHandler('esx:playerLodaded', function(source) +AddEventHandler('esx:playerLoaded', function(source) local xPlayer = ESX.GetPlayerFromId(source) xPlayer.set('caution', 0) end) From 086c4619ab8dc189f133b7233207bf47438652a6 Mon Sep 17 00:00:00 2001 From: Don Date: Tue, 15 Aug 2017 07:23:05 -0700 Subject: [PATCH 0347/3224] Multi-language support Added multi-language support --- __resource.lua | 6 ++ client/main.lua | 150 ++++++++++++++++++++++++------------------------ config.lua | 1 + locales/en.lua | 91 +++++++++++++++++++++++++++++ locales/fr.lua | 91 +++++++++++++++++++++++++++++ server/main.lua | 14 ++--- 6 files changed, 271 insertions(+), 82 deletions(-) create mode 100644 locales/en.lua create mode 100644 locales/fr.lua diff --git a/__resource.lua b/__resource.lua index d486b6f5..a5448753 100644 --- a/__resource.lua +++ b/__resource.lua @@ -3,12 +3,18 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ESX Police Job' server_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', '@mysql-async/lib/MySQL.lua', 'config.lua', 'server/main.lua' } client_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', 'config.lua', 'client/main.lua' } diff --git a/client/main.lua b/client/main.lua index aff4c245..374949a2 100644 --- a/client/main.lua +++ b/client/main.lua @@ -52,11 +52,11 @@ function OpenCloakroomMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'cloakroom', { - title = 'Vestiaire', + title = _U('cloakroom'), align = 'top-left', elements = { - {label = 'Tenue Civil', value = 'citizen_wear'}, - {label = 'Tenue Policier', value = 'police_wear'}, + {label = _U('citizen_wear'), value = 'citizen_wear'}, + {label = _U('police_wear'), value = 'police_wear'}, }, }, function(data, menu) @@ -86,7 +86,7 @@ function OpenCloakroomMenu() end CurrentAction = 'menu_cloakroom' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour vous changer' + CurrentActionMsg = _U('open_cloackroom') CurrentActionData = {} end, @@ -95,7 +95,7 @@ function OpenCloakroomMenu() menu.close() CurrentAction = 'menu_cloakroom' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour vous changer' + CurrentActionMsg = _U('open_cloackroom') CurrentActionData = {} end ) @@ -107,12 +107,12 @@ function OpenArmoryMenu(station) if Config.EnableArmoryManagement then local elements = { - {label = 'Prendre Arme', value = 'get_weapon'}, - {label = 'Déposer Arme', value = 'put_weapon'} + {label = _U('get_weapon'), value = 'get_weapon'}, + {label = _U('put_weapon'), value = 'put_weapon'} } if PlayerData.job.grade_name == 'boss' then - table.insert(elements, {label = 'Acheter Armes', value = 'buy_weapons'}) + table.insert(elements, {label = _U('buy_weapons'), value = 'buy_weapons'}) end ESX.UI.Menu.CloseAll() @@ -120,7 +120,7 @@ function OpenArmoryMenu(station) ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'armory', { - title = 'Armurerie', + title = _U('armory'), align = 'top-left', elements = elements, }, @@ -144,7 +144,7 @@ function OpenArmoryMenu(station) menu.close() CurrentAction = 'menu_armory' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder à l\'armurerie' + CurrentActionMsg = _U('open_armory') CurrentActionData = {station = station} end ) @@ -163,7 +163,7 @@ function OpenArmoryMenu(station) ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'armory', { - title = 'Armurerie', + title = _U('armory'), align = 'top-left', elements = elements, }, @@ -176,7 +176,7 @@ function OpenArmoryMenu(station) menu.close() CurrentAction = 'menu_armory' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder à l\'armurerie' + CurrentActionMsg = _U('open_armory') CurrentActionData = {station = station} end @@ -201,7 +201,7 @@ function OpenVehicleSpawnerMenu(station, partNum) ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'vehicle_spawner', { - title = 'Véhicule', + title = _U('vehicle_menu'), align = 'top-left', elements = elements, }, @@ -248,7 +248,7 @@ function OpenVehicleSpawnerMenu(station, partNum) end) else - ESX.ShowNotification('Service complet : ' .. inServiceCount .. '/' .. maxInService) + ESX.ShowNotification(_U('service_max') .. inServiceCount .. '/' .. maxInService) end end, 'police') @@ -256,7 +256,7 @@ function OpenVehicleSpawnerMenu(station, partNum) end else - ESX.ShowNotification('Il y a déja un véhicule de sorti') + ESX.ShowNotification(_U('vehicle_out')) end end, @@ -265,7 +265,7 @@ function OpenVehicleSpawnerMenu(station, partNum) menu.close() CurrentAction = 'menu_vehicle_spawner' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour sortir un véhicule' + CurrentActionMsg = _U('vehicle_spawner') CurrentActionData = {station = station, partNum = partNum} end @@ -283,9 +283,9 @@ function OpenPoliceActionsMenu() title = 'Police', align = 'top-left', elements = { - {label = 'Interaction citoyen', value = 'citizen_interaction'}, - {label = 'Interaction véhicule', value = 'vehicle_interaction'}, - {label = 'Placer objets', value = 'object_spawner'}, + {label = _U('citizen_interaction'), value = 'citizen_interaction'}, + {label = _U('vehicle_interaction'), value = 'vehicle_interaction'}, + {label = _U('object_spawner'), value = 'object_spawner'}, }, }, function(data, menu) @@ -295,14 +295,14 @@ function OpenPoliceActionsMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'citizen_interaction', { - title = 'Interaction Citoyen', + title = _U('citizen_interaction'), align = 'top-left', elements = { - {label = 'Carte d\'identité', value = 'identity_card'}, - {label = 'Fouiller', value = 'body_search'}, - {label = 'Menotter / Démenotter', value = 'handcuff'}, - {label = 'Mettre dans véhicule', value = 'put_in_vehicle'}, - {label = 'Amende', value = 'fine'} + {label = _U('id_card'), value = 'identity_card'}, + {label = _U('search'), value = 'body_search'}, + {label = _U('handcuff'), value = 'handcuff'}, + {label = _U('put_in_vehicle'), value = 'put_in_vehicle'}, + {label = _U('fine'), value = 'fine'} }, }, function(data2, menu2) @@ -332,7 +332,7 @@ function OpenPoliceActionsMenu() end else - ESX.ShowNotification('Aucun joueur à proximité') + ESX.ShowNotification(_U('no_players_nearby')) end end, @@ -348,11 +348,11 @@ function OpenPoliceActionsMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'vehicle_interaction', { - title = 'Interaction Véhicule', + title = _U('vehicle_interaction'), align = 'top-left', elements = { - {label = 'Infos véhicule', value = 'vehicle_infos'}, - {label = 'Crocheter véhicule', value = 'hijack_vehicle'}, + {label = _U('vehicle_info'), value = 'vehicle_infos'}, + {label = _U('pick_lock'), value = 'hijack_vehicle'}, }, }, function(data2, menu2) @@ -393,7 +393,7 @@ function OpenPoliceActionsMenu() SetVehicleDoorsLocked(vehicle, 1) SetVehicleDoorsLockedForAllPlayers(vehicle, false) - TriggerEvent('esx:showNotification', 'Véhicule ~g~déverouillé~s~') + TriggerEvent('esx:showNotification', _U('vehicle_unlocked')) end) @@ -404,7 +404,7 @@ function OpenPoliceActionsMenu() end else - ESX.ShowNotification('Aucun véhicule à proximité') + ESX.ShowNotification(_U('no_vehicles_nearby')) end end, @@ -420,14 +420,14 @@ function OpenPoliceActionsMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'citizen_interaction', { - title = 'Interaction Voirie', + title = _U('traffic_interaction'), align = 'top-left', elements = { - {label = 'Plot', value = 'prop_roadcone02a'}, - {label = 'Barrière', value = 'prop_barrier_work06a'}, - {label = 'Herse', value = 'p_ld_stinger_s'}, - {label = 'Caisse', value = 'prop_boxpile_07d'}, - {label = 'Caisse', value = 'hei_prop_cash_crate_half_full'} + {label = _U('cone'), value = 'prop_roadcone02a'}, + {label = _U('barrier'), value = 'prop_barrier_work06a'}, + {label = _U('spikestrips'), value = 'p_ld_stinger_s'}, + {label = _U('box'), value = 'prop_boxpile_07d'}, + {label = _U('cash'), value = 'hei_prop_cash_crate_half_full'} }, }, function(data2, menu2) @@ -483,12 +483,12 @@ function OpenIdentityCardMenu(player) end local elements = { - {label = 'Nom : ' .. data.name, value = nil}, + {label = _U('name') .. data.name, value = nil}, {label = jobLabel, value = nil}, } if data.drunk ~= nil then - table.insert(elements, {label = 'Alcoolémie : ' .. data.drunk .. '%', value = nil}) + table.insert(elements, {label = _U('bac') .. data.drunk .. '%', value = nil}) end if data.licenses ~= nil then @@ -504,7 +504,7 @@ function OpenIdentityCardMenu(player) ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'citizen_interaction', { - title = 'Interaction Citoyen', + title = _U('citizen_interaction'), align = 'top-left', elements = elements, }, @@ -535,7 +535,7 @@ function OpenBodySearchMenu(player) end table.insert(elements, { - label = 'Confisquer argent sale : $' .. blackMoney, + label = _U('confiscate_dirty') .. blackMoney, value = 'black_money', itemType = 'item_account', amount = blackMoney @@ -545,19 +545,19 @@ function OpenBodySearchMenu(player) for i=1, #data.weapons, 1 do table.insert(elements, { - label = 'Confisquer ' .. ESX.GetWeaponLabel(data.weapons[i].name), + label = _U('confiscate') .. ESX.GetWeaponLabel(data.weapons[i].name), value = data.weapons[i].name, itemType = 'item_weapon', amount = data.ammo, }) end - table.insert(elements, {label = '--- Inventaire ---', value = nil}) + table.insert(elements, {label = _U('inventory_label'), value = nil}) for i=1, #data.inventory, 1 do if data.inventory[i].count > 0 then table.insert(elements, { - label = 'Confisquer x' .. data.inventory[i].count .. ' ' .. data.inventory[i].label, + label = _U('confiscate_inv') .. data.inventory[i].count .. ' ' .. data.inventory[i].label, value = data.inventory[i].name, itemType = 'item_standard', amount = data.inventory[i].count, @@ -569,7 +569,7 @@ function OpenBodySearchMenu(player) ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'body_search', { - title = 'Fouille', + title = _U('search'), align = 'top-left', elements = elements, }, @@ -602,13 +602,13 @@ function OpenFineMenu(player) ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'fine', { - title = 'Amende', + title = _U('fine'), align = 'top-left', elements = { - {label = 'Code de la route', value = 0}, - {label = 'Délit mineur', value = 1}, - {label = 'Délit moyen', value = 2}, - {label = 'Délit grave', value = 3} + {label = _U('traffic_offense'), value = 0}, + {label = _U('minor_offense'), value = 1}, + {label = _U('average_offense'), value = 2}, + {label = _U('major_offense'), value = 3} }, }, function(data, menu) @@ -641,7 +641,7 @@ function OpenFineCategoryMenu(player, category) ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'fine_category', { - title = 'Amende', + title = _U('fine'), align = 'top-left', elements = elements, }, @@ -653,9 +653,9 @@ function OpenFineCategoryMenu(player, category) menu.close() if Config.EnablePlayerManagement then - TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(player), 'society_police', 'Amende : ' .. label, amount) + TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(player), 'society_police', _U('fine_total') .. label, amount) else - TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(player), '', 'Amende : ' .. label, amount) + TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(player), '', _U('fine_total') .. label, amount) end ESX.SetTimeout(300, function() @@ -678,18 +678,18 @@ function OpenVehicleInfosMenu(vehicleData) local elements = {} - table.insert(elements, {label = 'N°: ' .. infos.plate, value = nil}) + table.insert(elements, {label = _U('plate') .. infos.plate, value = nil}) if infos.owner == nil then - table.insert(elements, {label = 'Propriétaire : Inconnu', value = nil}) + table.insert(elements, {label = _U('owner_unknown'), value = nil}) else - table.insert(elements, {label = 'Propriétaire : ' .. infos.owner, value = nil}) + table.insert(elements, {label = _U('owner') .. infos.owner, value = nil}) end ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'vehicle_infos', { - title = 'Infos Véhicule', + title = _U('vehicle_info'), align = 'top-left', elements = elements, }, @@ -718,7 +718,7 @@ function OpenGetWeaponMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'armory_get_weapon', { - title = 'Armurerie - Prendre Arme', + title = _U('get_weapon_menu'), align = 'top-left', elements = elements, }, @@ -760,7 +760,7 @@ function OpenPutWeaponMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'armory_put_weapon', { - title = 'Armurerie - Déposer Arme', + title = _U('put_weapon_menu'), align = 'top-left', elements = elements, }, @@ -805,7 +805,7 @@ function OpenBuyWeaponsMenu(station) ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'armory_buy_weapons', { - title = 'Armurerie - Acheter Armes', + title = _U('buy_weapon_menu'), align = 'top-left', elements = elements, }, @@ -818,7 +818,7 @@ function OpenBuyWeaponsMenu(station) OpenBuyWeaponsMenu(station) end, data.current.value) else - ESX.ShowNotification('Vous n\'avez pas assez d\'argent') + ESX.ShowNotification(_U('not_enough_money')) end end, data.current.price) @@ -842,8 +842,8 @@ function OpenBossActionsMenu() { title = PlayerData.job.grade_label, elements = { - {label = 'Retirer argent société', value = 'withdraw_society_money'}, - {label = 'Déposer argent', value = 'deposit_money'}, + {label = _U('take_company_money'), value = 'withdraw_society_money'}, + {label = _U('deposit_money'), value = 'deposit_money'}, } }, function(data, menu) @@ -853,14 +853,14 @@ function OpenBossActionsMenu() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'withdraw_society_money_amount', { - title = 'Montant du retrait' + title = _U('amount_of_withdrawal') }, function(data, menu) local amount = tonumber(data.value) if amount == nil then - ESX.ShowNotification('Montant invalide') + ESX.ShowNotification(_U('invalid_amount')) else menu.close() TriggerServerEvent('esx_society:withdrawMoney', 'police', amount) @@ -879,14 +879,14 @@ function OpenBossActionsMenu() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'deposit_money_amount', { - title = 'Montant du dépôt' + title = _U('amount_of_deposit') }, function(data, menu) local amount = tonumber(data.value) if amount == nil then - ESX.ShowNotification('Montant invalide') + ESX.ShowNotification(_U('invalid_amount')) else menu.close() TriggerServerEvent('esx_society:depositMoney', 'police', amount) @@ -906,7 +906,7 @@ function OpenBossActionsMenu() menu.close() CurrentAction = 'menu_boss_actions' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour ouvrir le menu' + CurrentActionMsg = _U('open_bossmenu') CurrentActionData = {} end @@ -941,19 +941,19 @@ AddEventHandler('esx_policejob:hasEnteredMarker', function(station, part, partNu if part == 'Cloakroom' then CurrentAction = 'menu_cloakroom' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour vous changer' + CurrentActionMsg = _U('open_cloackroom') CurrentActionData = {} end if part == 'Armory' then CurrentAction = 'menu_armory' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder à l\'armurerie' + CurrentActionMsg = _U('open_armory') CurrentActionData = {station = station} end if part == 'VehicleSpawner' then CurrentAction = 'menu_vehicle_spawner' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour sortir un véhicule' + CurrentActionMsg = _U('vehicle_spawner') CurrentActionData = {station = station, partNum = partNum} end @@ -992,7 +992,7 @@ AddEventHandler('esx_policejob:hasEnteredMarker', function(station, part, partNu if distance <= 2.0 then CurrentAction = 'delete_vehicle' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour ranger le véhicule' + CurrentActionMsg = _U('store_vehicle') CurrentActionData = {vehicle = vehicle} end @@ -1002,7 +1002,7 @@ AddEventHandler('esx_policejob:hasEnteredMarker', function(station, part, partNu if part == 'BossActions' then CurrentAction = 'menu_boss_actions' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour ouvrir le menu' + CurrentActionMsg = _U('open_bossmenu') CurrentActionData = {} end @@ -1018,7 +1018,7 @@ AddEventHandler('esx_policejob:hasEnteredEntityZone', function(entity) if PlayerData.job ~= nil and PlayerData.job.name == 'police' and not IsPedInAnyVehicle(playerPed, false) then CurrentAction = 'remove_entity' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour enlever l\'objet' + CurrentActionMsg = _U('remove_object') CurrentActionData = {entity = entity} end @@ -1152,7 +1152,7 @@ Citizen.CreateThread(function() SetBlipAsShortRange(blip, true) BeginTextCommandSetBlipName("STRING") - AddTextComponentString("Commissariat") + AddTextComponentString(_U('map_blip')) EndTextCommandSetBlipName(blip) end diff --git a/config.lua b/config.lua index 00e67176..4a1defb3 100644 --- a/config.lua +++ b/config.lua @@ -6,6 +6,7 @@ Config.MarkerColor = {r = 50, g = 50, b = 204} Config.EnablePlayerManagement = false Config.EnableArmoryManagement = false Config.MaxInService = -1 +Config.Locale = 'en' Config.PoliceStations = { diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..0ad97fbe --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,91 @@ +Locales['en'] = { + --Cloackroom + ['cloakroom'] = 'locker room', + ['citizen_wear'] = 'civilian Outfit', + ['police_wear'] = 'police Outfit', + ['open_cloackroom'] = 'press ~INPUT_CONTEXT~ to change', + --Armory + ['get_weapon'] = 'get Weapon', + ['put_weapon'] = 'put Weapon', + ['buy_weapons'] = 'buy Weapons', + ['armory'] = 'armory', + ['open_armory'] = 'press ~INPUT_CONTEXT~ to access the armory', + --Vehicles + ['vehicle_menu'] = 'vehicle', + ['vehicle_out'] = 'there is already a car out of the garage', + ['vehicle_spawner'] = 'press ~INPUT_CONTEXT~ to take out a vehicle', + ['store_vehicle'] = 'press ~INPUT_CONTEXT~ to store the vehicle', + ['service_max'] = 'Max officers in service : ', + --Action Menu + ['citizen_interaction'] = 'citizen Interaction', + ['vehicle_interaction'] = 'vehicle Interaction', + ['object_spawner'] = 'object Spawner', + + ['id_card'] = 'iD Card', + ['search'] = 'search', + ['handcuff'] = 'cuff / Uncuff', + ['put_in_vehicle'] = 'put in Vehicle', + ['fine'] = 'fine', + ['no_players_nearby'] = 'no players nearby', + + ['vehicle_info'] = 'vehicle Info', + ['pick_lock'] = 'lockpick Vehicle', + ['vehicle_unlocked'] = 'vehicle ~g~Unlocked~s~', + ['no_vehicles_nearby'] = 'no vehicles nearby', + ['traffic_interaction'] = 'Interaction Voirie', + ['cone'] = 'cone', + ['barrier'] = 'barrier', + ['spikestrips'] = 'spikestrips', + ['box'] = 'box', + ['cash'] = 'Box of cash', + --ID Card Menu + ['name'] = 'name : ', + ['bac'] = 'bAC : ', + --Body Search Menu + ['confiscate_dirty'] = 'confiscate dirty money : $', + ['guns_label'] = '--- Guns ---', + ['confiscate'] = 'confiscate ', + ['inventory_label'] = '--- Inventory ---', + ['confiscate_inv'] = 'confiscate x', + + ['traffic_offense'] = 'traffic Offense', + ['minor_offense'] = 'minor Offense', + ['average_offense'] = 'average Offense', + ['major_offense'] = 'major Offense', + ['fine_total'] = 'fine : ', + --Vehicle Info Menu + ['plate'] = 'Plate: ', + ['owner_unknown'] = 'owner : Unknown', + ['owner'] = 'owner : ', + --Weapons Menus + ['get_weapon_menu'] = 'armory - Take Weapon', + ['put_weapon_menu'] = 'armory - Put Weapon', + ['buy_weapon_menu'] = 'armory - Buy Guns', + ['not_enough_money'] = 'you do not have enough money', + --Boss Menu + ['take_company_money'] = 'withdraw Company Money', + ['deposit_money'] = 'deposit Money', + ['amount_of_withdrawal'] = 'amount of Withdrawal', + ['invalid_amount'] = 'amount Invalid', + ['amount_of_deposit'] = 'amount of Deposit', + ['open_bossmenu'] = 'press ~INPUT_CONTEXT~ to open the menu', + --Misc + ['remove_object'] = 'press ~INPUT_CONTEXT~ to delete the object', + ['map_blip'] = 'police Station', + --Notifications + ['from'] = '~s~ from ~b~', + ['you_have_confinv'] = 'you have confiscated ~y~x', + ['confinv'] = '~s~ confiscated from you ~y~x', + ['you_have_confdm'] = 'you have confiscated ~y~$', + ['confdm'] = '~s~ confiscated from you ~y~$', + ['you_have_confweapon'] = 'you have confiscated ~y~x1 ', + ['confweapon'] = '~s~ confiscated from you ~y~x1 ', + ['alert_police'] = 'alert police', + --Authorized Vehicles + ['police'] = 'patrol Vehicle 1', + ['police2'] = 'patrol Vehicle 2', + ['police3'] = 'patrol Vehicle 3', + ['police4'] = 'unmarked Vehicle', + ['policeb'] = 'motorcycle', + ['policet'] = 'transport Van', +} \ No newline at end of file diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..6756fbeb --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,91 @@ +Locales['fr'] = { + --Cloakroom + ['cloakroom'] = 'vestiaire', + ['citizen_wear'] = 'tenue Civil', + ['police_wear'] = 'tenue Policier', + ['open_cloackroom'] = 'appuez sur ~INPUT_CONTEXT~ pour vous changer', + --Armory + ['get_weapon'] = 'prendre Arme', + ['put_weapon'] = 'déposer Arme', + ['buy_weapons'] = 'acheter Armes', + ['armory'] = 'armurerie', + ['open_armory'] = 'appuez sur ~INPUT_CONTEXT~ pour accéder à l\'armurerie', + --Vehicles + ['vehicle_menu'] = 'véhicule', + ['vehicle_out'] = 'il y a déja un véhicule de sorti', + ['vehicle_spawner'] = 'appuez sur ~INPUT_CONTEXT~ pour sortir un véhicule', + ['store_vehicle'] = 'appuez sur ~INPUT_CONTEXT~ pour ranger le véhicule', + ['service_max'] = 'Service complet : ', + --Action Menu + ['citizen_interaction'] = 'interaction citoyen', + ['vehicle_interaction'] = 'interaction véhicule', + ['object_spawner'] = 'placer objets', + + ['id_card'] = 'carte d\'identité', + ['search'] = 'fouiller', + ['handcuff'] = 'menotter / Démenotter', + ['put_in_vehicle'] = 'mettre dans véhicule', + ['fine'] = 'Amende', + ['no_players_nearby'] = 'aucun joueur à proximité', + + ['vehicle_info'] = 'infos véhicule', + ['pick_lock'] = 'crocheter véhicule', + ['vehicle_unlocked'] = 'véhicule ~g~déverouillé~s~', + ['no_vehicles_nearby'] = 'aucun véhicule à proximité', + ['traffic_interaction'] = 'Interaction Voirie', + ['cone'] = 'plot', + ['barrier'] = 'barrière', + ['spikestrips'] = 'herse', + ['box'] = 'caisse', + ['cash'] = 'caisse', + --ID Card Menu + ['name'] = 'nom : ', + ['bac'] = 'alcoolémie : ', + --Body Search Menu + ['confiscate_dirty'] = 'confisquer argent sale : $', + ['guns_label'] = '--- Armes ---', + ['confiscate'] = 'confisquer ', + ['inventory_label'] = '--- Inventaire ---', + ['confiscate_inv'] = 'confisquer x', + + ['traffic_offense'] = 'code de la route', + ['minor_offense'] = 'délit mineur', + ['average_offense'] = 'délit moyen', + ['major_offense'] = 'délit grave', + ['fine_total'] = 'amende : ', + --Vehicle Info Menu + ['plate'] = 'N°: ', + ['owner_unknown'] = 'propriétaire : Inconnu', + ['owner'] = 'propriétaire : ', + --Weapons Menus + ['get_weapon_menu'] = 'armurerie - Prendre Arme', + ['put_weapon_menu'] = 'armurerie - Déposer Arme', + ['buy_weapon_menu'] = 'armurerie - Acheter Armes', + ['not_enough_money'] = 'vous n\'avez pas assez d\'argent', + --Boss Menu + ['take_company_money'] = 'retirer argent société', + ['deposit_money'] = 'déposer argent', + ['amount_of_withdrawal'] = 'montant du retrait', + ['invalid_amount'] = 'montant invalide', + ['amount_of_deposit'] = 'montant du dépôt', + ['open_bossmenu'] = 'appuez sur ~INPUT_CONTEXT~ pour ouvrir le menu', + --Misc + ['remove_object'] = 'appuez sur ~INPUT_CONTEXT~ pour enlever l\'objet', + ['map_blip'] = 'Commissariat', + --Notifications + ['from'] = '~s~ à ~b~', + ['you_have_confinv'] = 'vous avez confisqué ~y~x', + ['confinv'] = '~s~ vous a confisqué ~y~x', + ['you_have_confdm'] = 'vous avez confisqué ~y~$', + ['confdm'] = '~s~ vous a confisqué ~y~$', + ['you_have_confweapon'] = 'vous avez confisqué ~y~x1 ', + ['confweapon'] = '~s~ vous a confisqué ~y~x1 ', + ['alert_police'] = 'alerte police', + --Authorized Vehicles + ['police'] = 'véhicule de patrouille 1', + ['police2'] = 'véhicule de patrouille 2', + ['police3'] = 'véhicule de patrouille 3', + ['police4'] = 'véhicule civil', + ['policeb'] = 'moto', + ['policet'] = 'van de transport', +} \ No newline at end of file diff --git a/server/main.lua b/server/main.lua index efe9bc0a..7bb6445e 100644 --- a/server/main.lua +++ b/server/main.lua @@ -25,8 +25,8 @@ AddEventHandler('esx_policejob:confiscatePlayerItem', function(target, itemType, targetXPlayer.removeInventoryItem(itemName, amount) sourceXPlayer.addInventoryItem(itemName, amount) - TriggerClientEvent('esx:showNotification', sourceXPlayer.source, 'Vous avez confisqué ~y~x' .. amount .. ' ' .. label .. '~s~ à ~b~' .. targetXPlayer.name) - TriggerClientEvent('esx:showNotification', targetXPlayer.source, '~b~' .. targetXPlayer.name .. '~s~ vous a confisqué ~y~x' .. amount .. ' ' .. label ) + TriggerClientEvent('esx:showNotification', sourceXPlayer.source, _U('you_have_confinv') .. amount .. ' ' .. label .. _U('from') .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', targetXPlayer.source, '~b~' .. targetXPlayer.name .. _U('confinv') .. amount .. ' ' .. label ) end @@ -35,8 +35,8 @@ AddEventHandler('esx_policejob:confiscatePlayerItem', function(target, itemType, targetXPlayer.removeAccountMoney(itemName, amount) sourceXPlayer.addAccountMoney(itemName, amount) - TriggerClientEvent('esx:showNotification', sourceXPlayer.source, 'Vous avez confisqué ~y~$' .. amount .. '~s~ à ~b~' .. targetXPlayer.name) - TriggerClientEvent('esx:showNotification', targetXPlayer.source, '~b~' .. targetXPlayer.name .. '~s~ vous a confisqué ~y~$' .. amount) + TriggerClientEvent('esx:showNotification', sourceXPlayer.source, _U('you_have_confdm') .. amount .. _U('from') .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', targetXPlayer.source, '~b~' .. targetXPlayer.name .. _U('confdm') .. amount) end @@ -45,8 +45,8 @@ AddEventHandler('esx_policejob:confiscatePlayerItem', function(target, itemType, targetXPlayer.removeWeapon(itemName) sourceXPlayer.addWeapon(itemName, amount) - TriggerClientEvent('esx:showNotification', sourceXPlayer.source, 'Vous avez confisqué ~y~x1 ' .. ESX.GetWeaponLabel(itemName) .. '~s~ à ~b~' .. targetXPlayer.name) - TriggerClientEvent('esx:showNotification', targetXPlayer.source, '~b~' .. targetXPlayer.name .. '~s~ vous a confisqué ~y~x1 ' .. ESX.GetWeaponLabel(itemName)) + TriggerClientEvent('esx:showNotification', sourceXPlayer.source, _U('you_have_confweapon') .. ESX.GetWeaponLabel(itemName) .. _U('from') .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', targetXPlayer.source, '~b~' .. targetXPlayer.name .. _U('confweapon') .. ESX.GetWeaponLabel(itemName)) end @@ -271,7 +271,7 @@ TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message for k, v in pairs(xPlayers) do if v.job.name == 'police' then TriggerEvent('esx_phone:getDistpatchRequestId', function(requestId) - TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'Alerte police', requestId) + TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, _('alert_police'), requestId) end) end end From 3a2788df42a41a995cdfe31138fc80bb94f08dc8 Mon Sep 17 00:00:00 2001 From: imThaku Date: Mon, 14 Aug 2017 16:39:11 +0200 Subject: [PATCH 0348/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..1b73edab --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_weashops +Legal or illegal gun shop From 2d84093e177258528fb1d63b3a04740fe302f590 Mon Sep 17 00:00:00 2001 From: imThaku Date: Mon, 14 Aug 2017 16:40:45 +0200 Subject: [PATCH 0349/3224] esx_weashop v1.0.0 --- esx_weashops/LICENSE.txt | 674 +++++++++++++++++++++++++++++++++++ esx_weashops/README.md | 16 + esx_weashops/__resource.lua | 12 + esx_weashops/client/main.lua | 165 +++++++++ esx_weashops/config.lua | 27 ++ esx_weashops/esx_shops.sql | 17 + esx_weashops/server/main.lua | 82 +++++ 7 files changed, 993 insertions(+) create mode 100644 esx_weashops/LICENSE.txt create mode 100644 esx_weashops/README.md create mode 100644 esx_weashops/__resource.lua create mode 100644 esx_weashops/client/main.lua create mode 100644 esx_weashops/config.lua create mode 100644 esx_weashops/esx_shops.sql create mode 100644 esx_weashops/server/main.lua diff --git a/esx_weashops/LICENSE.txt b/esx_weashops/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/esx_weashops/LICENSE.txt @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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 +. \ No newline at end of file diff --git a/esx_weashops/README.md b/esx_weashops/README.md new file mode 100644 index 00000000..1bfeb057 --- /dev/null +++ b/esx_weashops/README.md @@ -0,0 +1,16 @@ +# fxserver-esx_shops +FXServer ESX Shops + +[INSTALLATION] + +1) CD in your resources/[esx] folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-esx_shops esx_shops +``` +3) Import esx_shops.sql in your database +4) Add this in your server.cfg : + +``` +start esx_shops +``` diff --git a/esx_weashops/__resource.lua b/esx_weashops/__resource.lua new file mode 100644 index 00000000..47caca54 --- /dev/null +++ b/esx_weashops/__resource.lua @@ -0,0 +1,12 @@ +description 'ESX Mecano Job' + +client_scripts { + 'config.lua', + 'client/main.lua' +} + +server_scripts { + '@mysql-async/lib/MySQL.lua', + 'config.lua', + 'server/main.lua' +} \ No newline at end of file diff --git a/esx_weashops/client/main.lua b/esx_weashops/client/main.lua new file mode 100644 index 00000000..fc3ac617 --- /dev/null +++ b/esx_weashops/client/main.lua @@ -0,0 +1,165 @@ +ESX = nil +local HasAlreadyEnteredMarker = false +local LastZone = nil +local CurrentAction = nil +local CurrentActionMsg = '' +local CurrentActionData = {} + +Citizen.CreateThread(function() + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end +end) + +AddEventHandler('onClientMapStart', function() + + ESX.TriggerServerCallback('esx_weashop:requestDBItems', function(ShopItems) + for k,v in pairs(ShopItems) do + Config.Zones[k].Items = v + end + end) + +end) + +function OpenShopMenu(zone) + + local elements = {} + + for i=1, #Config.Zones[zone].Items, 1 do + + local item = Config.Zones[zone].Items[i] + + table.insert(elements, { + label = item.label .. ' - $' .. item.price .. ' ', + realLabel = item.label, + value = item.name, + price = item.price + }) + + end + + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'shop', + { + title = 'Magasin', + elements = elements + }, + function(data, menu) + TriggerServerEvent('esx_weashop:buyItem', data.current.value, data.current.price, zone) + end, + function(data, menu) + + menu.close() + + CurrentAction = 'shop_menu' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au magasin.' + CurrentActionData = {zone = zone} + end + ) +end + +AddEventHandler('esx_weashop:hasEnteredMarker', function(zone) + + CurrentAction = 'shop_menu' + CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au magasin.' + CurrentActionData = {zone = zone} + +end) + +AddEventHandler('esx_weashop:hasExitedMarker', function(zone) + + CurrentAction = nil + ESX.UI.Menu.CloseAll() + +end) + +-- Create Blips +Citizen.CreateThread(function() + for k,v in pairs(Config.Zones) do + if v.legal==0 then + for i = 1, #v.Pos, 1 do + local blip = AddBlipForCoord(v.Pos[i].x, v.Pos[i].y, v.Pos[i].z) + SetBlipSprite (blip, 154) + SetBlipDisplay(blip, 4) + SetBlipScale (blip, 1.0) + SetBlipColour (blip, 2) + SetBlipAsShortRange(blip, true) + BeginTextCommandSetBlipName("STRING") + AddTextComponentString("GunShop") + EndTextCommandSetBlipName(blip) + end + end + end +end) + +-- Display markers +Citizen.CreateThread(function() + while true do + Wait(0) + local coords = GetEntityCoords(GetPlayerPed(-1)) + for k,v in pairs(Config.Zones) do + for i = 1, #v.Pos, 1 do + if(Config.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos[i].x, v.Pos[i].y, v.Pos[i].z, true) < Config.DrawDistance) then + DrawMarker(Config.Type, v.Pos[i].x, v.Pos[i].y, v.Pos[i].z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.Size.x, Config.Size.y, Config.Size.z, Config.Color.r, Config.Color.g, Config.Color.b, 100, false, true, 2, false, false, false, false) + end + end + end + end +end) + +-- Enter / Exit marker events +Citizen.CreateThread(function() + while true do + Wait(0) + local coords = GetEntityCoords(GetPlayerPed(-1)) + local isInMarker = false + local currentZone = nil + + for k,v in pairs(Config.Zones) do + for i = 1, #v.Pos, 1 do + if(GetDistanceBetweenCoords(coords, v.Pos[i].x, v.Pos[i].y, v.Pos[i].z, true) < Config.Size.x) then + isInMarker = true + ShopItems = v.Items + currentZone = k + LastZone = k + end + end + end + if isInMarker and not HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = true + TriggerEvent('esx_weashop:hasEnteredMarker', currentZone) + end + if not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent('esx_weashop:hasExitedMarker', LastZone) + end + end +end) + +-- Key Controls +Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + if CurrentAction ~= nil then + + SetTextComponentFormat('STRING') + AddTextComponentString(CurrentActionMsg) + DisplayHelpTextFromStringLabel(0, 0, 1, -1) + + if IsControlJustReleased(0, 38) then + + if CurrentAction == 'shop_menu' then + OpenShopMenu(CurrentActionData.zone) + end + + CurrentAction = nil + + end + + end + end +end) \ No newline at end of file diff --git a/esx_weashops/config.lua b/esx_weashops/config.lua new file mode 100644 index 00000000..5006a708 --- /dev/null +++ b/esx_weashops/config.lua @@ -0,0 +1,27 @@ +Config = {} + +Config.DrawDistance = 100 +Config.Size = {x = 1.5, y = 1.5, z = 1.5} +Config.Color = {r = 0, g = 128, b = 255} +Config.Type = 1 + +Config.Zones = { + + GunShop = { + legal=0, + Items = {}, + Pos = { + {x = -662.180053710938, y =-934.961120605469, z = 20.8292293548584} + + } + }, + blackweashop = { + legal=1, + Items = {}, + Pos = { + {x = -1306.23986816406, y =-394.018707275391, z = 35.6958122253418} + + } + }, + +} \ No newline at end of file diff --git a/esx_weashops/esx_shops.sql b/esx_weashops/esx_shops.sql new file mode 100644 index 00000000..ee90319f --- /dev/null +++ b/esx_weashops/esx_shops.sql @@ -0,0 +1,17 @@ +USE `essentialmode`; + +CREATE TABLE `weashops` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `item` varchar(255) NOT NULL, + `price` int(11) NOT NULL, + + PRIMARY KEY (`id`) +); + + +INSERT INTO `weashops` (name, item, price) VALUES + ('GunShop','WEAPON_Pistol',300), + ('blackweashop','WEAPON_Pistol',500) +; \ No newline at end of file diff --git a/esx_weashops/server/main.lua b/esx_weashops/server/main.lua new file mode 100644 index 00000000..ae222d5f --- /dev/null +++ b/esx_weashops/server/main.lua @@ -0,0 +1,82 @@ +ESX = nil +local ItemsLabels = {} + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +AddEventHandler('onMySQLReady', function() + + MySQL.Async.fetchAll( + 'SELECT * FROM items', + {}, + function(result) + + for i=1, #result, 1 do + ItemsLabels[result[i].name] = result[i].label + end-- + + end + ) + +end) + +ESX.RegisterServerCallback('esx_weashop:requestDBItems', function(source, cb) + + MySQL.Async.fetchAll( + 'SELECT * FROM weashops', + {}, + function(result) + + local shopItems = {} + + for i=1, #result, 1 do + + if shopItems[result[i].name] == nil then + shopItems[result[i].name] = {} + end + + table.insert(shopItems[result[i].name], { + name = result[i].item, + price = result[i].price, + label = ESX.GetWeaponLabel(result[i].item) + }) + + end + + cb(shopItems) + + end + ) + +end) + +RegisterServerEvent('esx_weashop:buyItem') +AddEventHandler('esx_weashop:buyItem', function(itemName, price,zone) + + local _source = source + local xPlayer = ESX.GetPlayerFromId(source) + local account = xPlayer.getAccount('black_money') + + if zone=="blackweashop" then + if account.money >= price then + + xPlayer.removeAccountMoney('black_money', price) + xPlayer.addWeapon(itemName, 42) + TriggerClientEvent('esx:showNotification', _source, 'Vous avez acheté ~b~1x ' .. ItemsLabels[itemName]) + + else + TriggerClientEvent('esx:showNotification', _source, 'Vous n\'avez ~r~pas assez~s~ d\'argent sale') + end + + else if xPlayer.get('money') >= price then + + xPlayer.removeMoney(price) + xPlayer.addWeapon(itemName, 42) + + TriggerClientEvent('esx:showNotification', _source, 'Vous avez acheté ~b~1x ' .. ItemsLabels[itemName]) + + else + TriggerClientEvent('esx:showNotification', _source, 'Vous n\'avez ~r~pas assez~s~ d\'argent.') + end + end + +end) From ead076c2567daedae5e18da86d20a07568cf4124 Mon Sep 17 00:00:00 2001 From: imThaku Date: Mon, 14 Aug 2017 16:41:37 +0200 Subject: [PATCH 0350/3224] Update sql --- esx_weashops/{esx_shops.sql => esx_weashops.sql} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename esx_weashops/{esx_shops.sql => esx_weashops.sql} (99%) diff --git a/esx_weashops/esx_shops.sql b/esx_weashops/esx_weashops.sql similarity index 99% rename from esx_weashops/esx_shops.sql rename to esx_weashops/esx_weashops.sql index ee90319f..15819db8 100644 --- a/esx_weashops/esx_shops.sql +++ b/esx_weashops/esx_weashops.sql @@ -14,4 +14,4 @@ CREATE TABLE `weashops` ( INSERT INTO `weashops` (name, item, price) VALUES ('GunShop','WEAPON_Pistol',300), ('blackweashop','WEAPON_Pistol',500) -; \ No newline at end of file +; From 947bfac27c7e0b7d558eee1566db203f29bc703e Mon Sep 17 00:00:00 2001 From: imThaku Date: Mon, 14 Aug 2017 16:42:41 +0200 Subject: [PATCH 0351/3224] Update readMe --- esx_weashops/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/esx_weashops/README.md b/esx_weashops/README.md index 1bfeb057..cecf1651 100644 --- a/esx_weashops/README.md +++ b/esx_weashops/README.md @@ -1,14 +1,14 @@ -# fxserver-esx_shops -FXServer ESX Shops +# fxserver-esx_weashops +FXServer ESX Weapon Shops [INSTALLATION] 1) CD in your resources/[esx] folder 2) Clone the repository ``` -git clone https://github.com/FXServer-ESX/fxserver-esx_shops esx_shops + ``` -3) Import esx_shops.sql in your database +3) Import esx_weashops.sql in your database 4) Add this in your server.cfg : ``` From 3eb0647e11e774df6a2c5f5d2143effc272d2f7c Mon Sep 17 00:00:00 2001 From: imThaku Date: Mon, 14 Aug 2017 16:43:01 +0200 Subject: [PATCH 0352/3224] Delet old readme --- README.md | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 README.md diff --git a/README.md b/README.md deleted file mode 100644 index 1b73edab..00000000 --- a/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# fxserver-esx_weashops -Legal or illegal gun shop From 3569191dc02bb14b8808f3fa0aa498f0b9631da1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 15 Aug 2017 09:34:13 +0200 Subject: [PATCH 0353/3224] Fix camera not closing --- client/main.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 718135a9..94e89424 100644 --- a/client/main.lua +++ b/client/main.lua @@ -93,7 +93,10 @@ function OpenMenu(submitCb, cancelCb, restrict) align = 'top-left', elements = elements }, - submitCb, + function(data, menu) + submitCb(data, menu) + DeleteSkinCam() + end, function(data, menu) menu.close() From a3a7eaa584ac60dd1b9f55a5ea00bb0a5e243f75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 15 Aug 2017 09:53:14 +0200 Subject: [PATCH 0354/3224] UseItem fixes + add paycheck --- .../es_extended/client/functions.lua | 5 ++-- .../es_extended/server/functions.lua | 23 +++++++++++++++++++ .../[essential]/es_extended/server/main.lua | 14 +++++++++-- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index f3c04818..60d2aff5 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -1003,12 +1003,11 @@ ESX.ShowInventory = function() TriggerServerEvent('esx:useItem', data.current.value) - menu2.close() - menu.close() - elseif data.current.action == 'return' then + ESX.UI.Menu.CloseAll() ESX.ShowInventory() + end end, diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index c5541654..97b9f252 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -158,6 +158,29 @@ ESX.StartDBSync = function() end +ESX.StartPayCheck = function() + + function payCheck() + + local xPlayers = ESX.GetPlayers() + + for k,v in pairs(xPlayers) do + + if v.job.grade_salary > 0 then + v.addMoney(v.job.grade_salary) + TriggerClientEvent('esx:showNotification', v.source, 'Vous avez reçu votre salaire : ~g~$' .. v.job.grade_salary) + end + + end + + SetTimeout(Config.PaycheckInterval, payCheck) + + end + + SetTimeout(Config.PaycheckInterval, payCheck) + +end + ESX.GetPlayers = function() return ESX.Players end diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index c06d44b8..4338ed81 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -510,8 +510,17 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) end) RegisterServerEvent('esx:useItem') -AddEventHandler('esx:useItem', function(item) - ESX.UseItem(source, item) +AddEventHandler('esx:useItem', function(itemName) + + local xPlayer = ESX.GetPlayerFromId(source) + local count = xPlayer.getInventoryItem(itemName).count + + if count > 0 then + ESX.UseItem(source, itemName) + else + TriggerClientEvent('esx:showNotification', xPlayer.source, 'Action impossible') + end + end) ESX.RegisterServerCallback('esx:getPlayerData', function(source, cb) @@ -547,3 +556,4 @@ end) TriggerEvent("es:addGroup", "jobmaster", "user", function(group) end) ESX.StartDBSync() +ESX.StartPayCheck() \ No newline at end of file From 1f05dc533ccfa1248aea8f9666bcd071a959307f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 15 Aug 2017 09:58:51 +0200 Subject: [PATCH 0355/3224] Fix messages not sending to players --- server/main.lua | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index d0ff5f9a..e7b50eac 100644 --- a/server/main.lua +++ b/server/main.lua @@ -263,8 +263,18 @@ end) AddEventHandler('esx_phone:ready', function() TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) - local xPlayer = ESX.GetPlayerFromId(source) + + local xPlayer = ESX.GetPlayerFromId(source) + local xPlayers = ESX.GetPlayers() + print('MESSAGE => ' .. xPlayer.name .. '@' .. phoneNumber .. ' : ' .. message) + + for k, v in pairs(xPlayers) do + if v.get('phoneNumber') == phoneNumber then + TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, job, false) + end + end + end) end) From 1393a3cbaf16c6b16a9316f62dfdc0b8b6601ab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 15 Aug 2017 10:22:35 +0200 Subject: [PATCH 0356/3224] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..540ccb46 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-esx_barbershop +FXServer ESX Barber Shop From dc3740fd705eaabe8c3bfc694e089d728beb5651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 15 Aug 2017 10:23:39 +0200 Subject: [PATCH 0357/3224] Fix README error --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e808c500..4920c6ce 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ FXServer ESX ClotheShop 1) CD in your resources/[esx] folder 2) Clone the repository ``` -git clone https://github.com/FXServer-ESX/fxserver-clotheshop clotheshop +git clone https://github.com/FXServer-ESX/fxserver-esx_clotheshop clotheshop ``` 3) Add this in your server.cfg : From 77a718982407caf6fd81817f18a5eba3c2aa45b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 15 Aug 2017 10:24:01 +0200 Subject: [PATCH 0358/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4920c6ce..8a846386 100644 --- a/README.md +++ b/README.md @@ -15,5 +15,5 @@ git clone https://github.com/FXServer-ESX/fxserver-esx_clotheshop clotheshop 3) Add this in your server.cfg : ``` -start clotheshop +start esx_clotheshop ``` From bfb490e76cfbdf3d4c92104a04abd0225b0a2505 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 15 Aug 2017 10:24:11 +0200 Subject: [PATCH 0359/3224] Update README.md --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.md b/README.md index 540ccb46..886ee230 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,19 @@ # fxserver-esx_barbershop FXServer ESX Barber Shop + +[REQUIREMENTS] + +- esx_skin => https://github.com/FXServer-ESX/fxserver-esx_skin + +[INSTALLATION] + +1) CD in your resources/[esx] folder +2) Clone the repository +``` +git clone https://github.com/FXServer-ESX/fxserver-esx_barbershop esx_barbershop +``` +3) Add this in your server.cfg : + +``` +start esx_barbershop +``` From 5caa2bfa934c857410dd8ae913f79e65580c7d39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 15 Aug 2017 10:24:52 +0200 Subject: [PATCH 0360/3224] Add files --- __resource.lua | 14 +++ client/main.lua | 239 ++++++++++++++++++++++++++++++++++++++++++++++++ config.lua | 31 +++++++ server/main.lua | 26 ++++++ 4 files changed, 310 insertions(+) create mode 100644 __resource.lua create mode 100644 client/main.lua create mode 100644 config.lua create mode 100644 server/main.lua diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..e16934cb --- /dev/null +++ b/__resource.lua @@ -0,0 +1,14 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'ESX BarberShop' + +server_scripts { + '@mysql-async/lib/MySQL.lua', + 'config.lua', + 'server/main.lua' +} + +client_scripts { + 'config.lua', + 'client/main.lua' +} diff --git a/client/main.lua b/client/main.lua new file mode 100644 index 00000000..150032c8 --- /dev/null +++ b/client/main.lua @@ -0,0 +1,239 @@ +local Keys = { + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, + ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, + ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, + ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, + ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 +} + +ESX = nil +local GUI = {} +GUI.Time = 0 +local HasAlreadyEnteredMarker = false +local LastZone = nil +local CurrentAction = nil +local CurrentActionMsg = '' +local CurrentActionData = {} + +Citizen.CreateThread(function() + + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end + +end) + +function OpenShopMenu() + + TriggerEvent('esx_skin:openRestrictedMenu', function(data, menu) + + menu.close() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'shop_confirm', + { + title = 'Valider cet achat ?', + align = 'top-left', + elements = { + {label = 'Oui', value = 'yes'}, + {label = 'Non', value = 'no'}, + } + }, + function(data, menu) + + menu.close() + + if data.current.value == 'yes' then + + ESX.TriggerServerCallback('esx_barbershop:checkMoney', function(hasEnoughMoney) + + if hasEnoughMoney then + + TriggerEvent('skinchanger:getSkin', function(skin) + TriggerServerEvent('esx_skin:save', skin) + end) + + TriggerServerEvent('esx_barbershop:pay') + else + + TriggerEvent('esx_skin:getLastSkin', function(skin) + TriggerEvent('skinchanger:loadSkin', skin) + end) + + ESX.ShowNotification('Vous n\'avez pas assez d\'argent') + + end + + end) + + end + + if data.current.value == 'no' then + + TriggerEvent('esx_skin:getLastSkin', function(skin) + TriggerEvent('skinchanger:loadSkin', skin) + end) + + end + + CurrentAction = 'shop_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {} + + end, + function(data, menu) + + menu.close() + + CurrentAction = 'shop_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {} + + end + ) + + end, function(data, menu) + + menu.close() + + CurrentAction = 'shop_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {} + + end, { + 'beard_1', + 'beard_2', + 'beard_3', + 'beard_4', + 'hair_1', + 'hair_2', + 'hair_color_1', + 'hair_color_2', + 'eyebrows_1', + 'eyebrows_2', + 'eyebrows_3', + 'eyebrows_4', + 'makeup_1', + 'makeup_2', + 'makeup_3', + 'makeup_4', + 'lipstick_1', + 'lipstick_2', + 'lipstick_3', + 'lipstick_4', + 'ears_1', + 'ears_2', + }) + +end + +AddEventHandler('esx_barbershop:hasEnteredMarker', function(zone) + CurrentAction = 'shop_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {} +end) + +AddEventHandler('esx_barbershop:hasExitedMarker', function(zone) + CurrentAction = nil +end) + +-- Create Blips +Citizen.CreateThread(function() + + for i=1, #Config.Shops, 1 do + + local blip = AddBlipForCoord(Config.Shops[i].x, Config.Shops[i].y, Config.Shops[i].z) + + SetBlipSprite (blip, 71) + SetBlipDisplay(blip, 4) + SetBlipScale (blip, 1.0) + SetBlipColour (blip, 51) + SetBlipAsShortRange(blip, true) + + BeginTextCommandSetBlipName("STRING") + AddTextComponentString("Coiffeur / Barbier") + EndTextCommandSetBlipName(blip) + end + +end) + +-- Display markers +Citizen.CreateThread(function() + while true do + + Wait(0) + + local coords = GetEntityCoords(GetPlayerPed(-1)) + + for k,v in pairs(Config.Zones) do + if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) + end + end + + end +end) + +-- Enter / Exit marker events +Citizen.CreateThread(function() + while true do + + Wait(0) + + local coords = GetEntityCoords(GetPlayerPed(-1)) + local isInMarker = false + local currentZone = nil + + for k,v in pairs(Config.Zones) do + if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then + isInMarker = true + currentZone = k + end + end + + if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then + HasAlreadyEnteredMarker = true + LastZone = currentZone + TriggerEvent('esx_barbershop:hasEnteredMarker', currentZone) + end + + if not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent('esx_barbershop:hasExitedMarker', LastZone) + end + + end +end) + +-- Key controls +Citizen.CreateThread(function() + while true do + + Citizen.Wait(0) + + if CurrentAction ~= nil then + + SetTextComponentFormat('STRING') + AddTextComponentString(CurrentActionMsg) + DisplayHelpTextFromStringLabel(0, 0, 1, -1) + + if IsControlPressed(0, Keys['E']) and (GetGameTimer() - GUI.Time) > 300 then + + if CurrentAction == 'shop_menu' then + OpenShopMenu() + end + + CurrentAction = nil + GUI.Time = GetGameTimer() + + end + + end + + end +end) \ No newline at end of file diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..290e2aec --- /dev/null +++ b/config.lua @@ -0,0 +1,31 @@ +Config = {} + +Config.Price = 100 + +Config.DrawDistance = 100.0 +Config.MarkerSize = {x = 1.5, y = 1.5, z = 1.0} +Config.MarkerColor = {r = 102, g = 102, b = 204} +Config.MarkerType = 1 + +Config.Zones = {} + +Config.Shops = { + {x = -814.308, y = -183.823, z = 36.568}, + {x = 136.826, y = -1708.373, z = 28.291}, + {x = -1282.604, y = -1116.757, z = 5.990}, + {x = 1931.513, y = 3729.671, z = 31.844}, + {x = 1212.840, y = -472.921, z = 62.208}, + {x = -32.885, y = -152.319, z = 56.076}, + {x = -278.077, y = 6228.463, z = 30.695}, +} + +for i=1, #Config.Shops, 1 do + + Config.Zones['Shop_' .. i] = { + Pos = Config.Shops[i], + Size = Config.MarkerSize, + Color = Config.MarkerColor, + Type = Config.MarkerType + } + +end \ No newline at end of file diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..ea58941f --- /dev/null +++ b/server/main.lua @@ -0,0 +1,26 @@ +ESX = nil + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +RegisterServerEvent('esx_barbershop:pay') +AddEventHandler('esx_barbershop:pay', function() + + local xPlayer = ESX.GetPlayerFromId(source) + + xPlayer.removeMoney(Config.Price) + + TriggerClientEvent('esx:showNotification', source, 'Vous avez payé $' .. Config.Price) + +end) + +ESX.RegisterServerCallback('esx_barbershop:checkMoney', function(source, cb) + + local xPlayer = ESX.GetPlayerFromId(source) + + if xPlayer.get('money') >= Config.Price then + cb(true) + else + cb(false) + end + +end) From dc2dec383541304db5eed3de8d206eb41986f31e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 15 Aug 2017 10:29:04 +0200 Subject: [PATCH 0361/3224] Add fine_types in SQL --- esx_policejob_full.sql | 55 +++++++++++++++++++++++++++++++++++++++ esx_policejob_minimal.sql | 55 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/esx_policejob_full.sql b/esx_policejob_full.sql index e3e1254a..68599dc1 100644 --- a/esx_policejob_full.sql +++ b/esx_policejob_full.sql @@ -16,3 +16,58 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ('police',2,'lieutenant','Lieutenant',65,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":2,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"glasses\":0,\"decals_1\":8,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"torso_2\":0,\"arms\":41,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"hair_2\":3,\"decals_2\":2,\"hair_color_2\":0,\"hair_color_1\":10,\"helmet_2\":0,\"face\":21,\"shoes\":24,\"torso_2\":0,\"glasses_2\":1,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"pants_2\":0,\"decals_1\":7,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}'), ('police',3,'boss','Commandant',80,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"arms\":41,\"torso_2\":0,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"decals_1\":8,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":21,\"helmet_2\":0,\"hair_2\":3,\"decals_1\":7,\"torso_2\":0,\"hair_color_1\":10,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"glasses_2\":1,\"shoes\":24,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}') ; + +INSERT INTO `fine_types` (label, amount, category) VALUES + ('Usage abusif du klaxon',30,0), + ('Franchir une ligne continue',40,0), + ('Circulation à contresens',250,0), + ('Demi-tour non autorisé',250,0), + ('Circulation hors-route',170,0), + ('Non-respect des distances de sécurité',30,0), + ('Arrêt dangereux / interdit',150,0), + ('Stationnement gênant / interdit',70,0), + ('Non respect de la priorité à droite',70,0), + ('Non-respect à un véhicule prioritaire',90,0), + ('Non-respect d\'un stop',105,0), + ('Non-respect d\'un feu rouge',130,0), + ('Dépassement dangereux',100,0), + ('Véhicule non en état',100,0), + ('Conduite sans permis',1500,0), + ('Délit de fuite',800,0), + ('Excès de vitesse < 5 kmh',90,0), + ('Excès de vitesse 5-15 kmh',120,0), + ('Excès de vitesse 15-30 kmh',180,0), + ('Excès de vitesse > 30 kmh',300,0), + ('Entrave de la circulation',110,1), + ('Dégradation de la voie publique',90,1), + ('Trouble à l\'ordre publique',90,1), + ('Entrave opération de police',130,1), + ('Insulte envers / entre civils',75,1), + ('Outrage à agent de police',110,1), + ('Menace verbale ou intimidation envers civil',90,1), + ('Menace verbale ou intimidation envers policier',150,1), + ('Manifestation illégale',250,1), + ('Tentative de corruption',1500,1), + ('Arme blanche sortie en ville',120,2), + ('Arme léthale sortie en ville',300,2), + ('Port d\'arme non autorisé (défaut de license)',600,2), + ('Port d\'arme illégal',700,2), + ('Pris en flag lockpick',300,2), + ('Vol de voiture',1800,2), + ('Vente de drogue',1500,2), + ('Fabriquation de drogue',1500,2), + ('Possession de drogue',650,2), + ('Prise d\'ôtage civil',1500,2), + ('Prise d\'ôtage agent de l\'état',2000,2), + ('Braquage particulier',650,2), + ('Braquage magasin',650,2), + ('Braquage de banque',1500,2), + ('Tir sur civil',2000,3), + ('Tir sur agent de l\'état',2500,3), + ('Tentative de meurtre sur civil',3000,3), + ('Tentative de meurtre sur agent de l\'état',5000,3), + ('Meurtre sur civil',10000,3), + ('Meurte sur agent de l\'état',30000,3), + ('Meurtre involontaire',1800,3), + ('Escroquerie à l\'entreprise',2000,2) +; diff --git a/esx_policejob_minimal.sql b/esx_policejob_minimal.sql index daf423d6..a916b0eb 100644 --- a/esx_policejob_minimal.sql +++ b/esx_policejob_minimal.sql @@ -8,3 +8,58 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ('police',2,'lieutenant','Lieutenant',65,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":2,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"glasses\":0,\"decals_1\":8,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"torso_2\":0,\"arms\":41,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"hair_2\":3,\"decals_2\":2,\"hair_color_2\":0,\"hair_color_1\":10,\"helmet_2\":0,\"face\":21,\"shoes\":24,\"torso_2\":0,\"glasses_2\":1,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"pants_2\":0,\"decals_1\":7,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}'), ('police',3,'boss','Commandant',80,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"arms\":41,\"torso_2\":0,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"decals_1\":8,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":21,\"helmet_2\":0,\"hair_2\":3,\"decals_1\":7,\"torso_2\":0,\"hair_color_1\":10,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"glasses_2\":1,\"shoes\":24,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}') ; + +INSERT INTO `fine_types` (label, amount, category) VALUES + ('Usage abusif du klaxon',30,0), + ('Franchir une ligne continue',40,0), + ('Circulation à contresens',250,0), + ('Demi-tour non autorisé',250,0), + ('Circulation hors-route',170,0), + ('Non-respect des distances de sécurité',30,0), + ('Arrêt dangereux / interdit',150,0), + ('Stationnement gênant / interdit',70,0), + ('Non respect de la priorité à droite',70,0), + ('Non-respect à un véhicule prioritaire',90,0), + ('Non-respect d\'un stop',105,0), + ('Non-respect d\'un feu rouge',130,0), + ('Dépassement dangereux',100,0), + ('Véhicule non en état',100,0), + ('Conduite sans permis',1500,0), + ('Délit de fuite',800,0), + ('Excès de vitesse < 5 kmh',90,0), + ('Excès de vitesse 5-15 kmh',120,0), + ('Excès de vitesse 15-30 kmh',180,0), + ('Excès de vitesse > 30 kmh',300,0), + ('Entrave de la circulation',110,1), + ('Dégradation de la voie publique',90,1), + ('Trouble à l\'ordre publique',90,1), + ('Entrave opération de police',130,1), + ('Insulte envers / entre civils',75,1), + ('Outrage à agent de police',110,1), + ('Menace verbale ou intimidation envers civil',90,1), + ('Menace verbale ou intimidation envers policier',150,1), + ('Manifestation illégale',250,1), + ('Tentative de corruption',1500,1), + ('Arme blanche sortie en ville',120,2), + ('Arme léthale sortie en ville',300,2), + ('Port d\'arme non autorisé (défaut de license)',600,2), + ('Port d\'arme illégal',700,2), + ('Pris en flag lockpick',300,2), + ('Vol de voiture',1800,2), + ('Vente de drogue',1500,2), + ('Fabriquation de drogue',1500,2), + ('Possession de drogue',650,2), + ('Prise d\'ôtage civil',1500,2), + ('Prise d\'ôtage agent de l\'état',2000,2), + ('Braquage particulier',650,2), + ('Braquage magasin',650,2), + ('Braquage de banque',1500,2), + ('Tir sur civil',2000,3), + ('Tir sur agent de l\'état',2500,3), + ('Tentative de meurtre sur civil',3000,3), + ('Tentative de meurtre sur agent de l\'état',5000,3), + ('Meurtre sur civil',10000,3), + ('Meurte sur agent de l\'état',30000,3), + ('Meurtre involontaire',1800,3), + ('Escroquerie à l\'entreprise',2000,2) +; \ No newline at end of file From 9856d1ea3db1a0b099a047b6b114fd3928599a5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 15 Aug 2017 10:36:43 +0200 Subject: [PATCH 0362/3224] Add CREATE_TABLE fine_types --- esx_policejob_full.sql | 10 ++++++++++ esx_policejob_minimal.sql | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/esx_policejob_full.sql b/esx_policejob_full.sql index 68599dc1..3c26e954 100644 --- a/esx_policejob_full.sql +++ b/esx_policejob_full.sql @@ -17,6 +17,16 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ('police',3,'boss','Commandant',80,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"arms\":41,\"torso_2\":0,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"decals_1\":8,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":21,\"helmet_2\":0,\"hair_2\":3,\"decals_1\":7,\"torso_2\":0,\"hair_color_1\":10,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"glasses_2\":1,\"shoes\":24,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}') ; +CREATE TABLE `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`) +); + INSERT INTO `fine_types` (label, amount, category) VALUES ('Usage abusif du klaxon',30,0), ('Franchir une ligne continue',40,0), diff --git a/esx_policejob_minimal.sql b/esx_policejob_minimal.sql index a916b0eb..0105430d 100644 --- a/esx_policejob_minimal.sql +++ b/esx_policejob_minimal.sql @@ -9,6 +9,17 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ('police',3,'boss','Commandant',80,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"arms\":41,\"torso_2\":0,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"decals_1\":8,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":21,\"helmet_2\":0,\"hair_2\":3,\"decals_1\":7,\"torso_2\":0,\"hair_color_1\":10,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"glasses_2\":1,\"shoes\":24,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}') ; +CREATE TABLE `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`) +); + + INSERT INTO `fine_types` (label, amount, category) VALUES ('Usage abusif du klaxon',30,0), ('Franchir une ligne continue',40,0), From 9b40b93f02b1c0ecaa78ac1489f3ae8134884050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 15 Aug 2017 11:03:44 +0200 Subject: [PATCH 0363/3224] Fix wrong player name on identity card --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 7bb6445e..37345b40 100644 --- a/server/main.lua +++ b/server/main.lua @@ -67,7 +67,7 @@ ESX.RegisterServerCallback('esx_policejob:getOtherPlayerData', function(source, local xPlayer = ESX.GetPlayerFromId(target) local data = { - name = GetPlayerName(source), + name = GetPlayerName(target), job = xPlayer.job, inventory = xPlayer.inventory, accounts = xPlayer.accounts, From 687b1351ae6f5c5a98259d64fbbd7793e49abd4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 15 Aug 2017 11:05:18 +0200 Subject: [PATCH 0364/3224] Fix status --- server/main.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 37345b40..fdd8932e 100644 --- a/server/main.lua +++ b/server/main.lua @@ -75,7 +75,11 @@ ESX.RegisterServerCallback('esx_policejob:getOtherPlayerData', function(source, } TriggerEvent('esx_status:getStatus', _source, 'drunk', function(status) - data.drunk = status:getPercent() + + if status ~= nil then + data.drunk = status.getPercent() + end + end) TriggerEvent('esx_license:getLicenses', _source, function(licenses) From 4ff3c0d654e3d26170cb6764be1895491e5ae691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 15 Aug 2017 14:32:56 +0200 Subject: [PATCH 0365/3224] Add removeSpecialContact + disable gps option --- client/main.lua | 12 ++++++++++- html/scripts/app.js | 52 +++++++++++++++++++++++++++++++++------------ 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/client/main.lua b/client/main.lua index 73dc6121..be5ca732 100644 --- a/client/main.lua +++ b/client/main.lua @@ -108,6 +108,16 @@ AddEventHandler('esx_phone:addSpecialContact', function(name, phoneNumber, base6 end) +RegisterNetEvent('esx_phone:removeSpecialContact') +AddEventHandler('esx_phone:removeSpecialContact', function(phoneNumber) + + SendNUIMessage({ + removeSpecialContact = true, + number = phoneNumber + }) + +end) + RegisterNUICallback('add_contact', function(data, cb) local phoneNumber = tonumber(data.phoneNumber) @@ -167,7 +177,7 @@ AddEventHandler('esx_phone:stopDispatch', function(dispatchRequestId, playerName end) -RegisterNUICallback('setGPS', function(data) +RegisterNUICallback('setGPS', function(data) SetNewWaypoint(data.x, data.y) ESX.ShowNotification('Position entrée dans le GPS') end) diff --git a/html/scripts/app.js b/html/scripts/app.js index 4934837c..a4f64f5a 100644 --- a/html/scripts/app.js +++ b/html/scripts/app.js @@ -206,9 +206,9 @@ okNumberData : fromNumber, gpsLocationX : (messages[i].job == 'player') ? '' : messages[i].position.x, gpsLocationY : (messages[i].job == 'player') ? '' : messages[i].position.y, - activeGPS : (messages[i].job == 'player') ? '' : "active", + activeGPS : (messages[i].job == 'player') ? '' : (messages[i].position) ? 'active' : '', jobData : (messages[i].job == 'player') ? '' : messages[i].job, - showOK : (messages[i].job == 'player') ? '' : "showOK" + showOK : (messages[i].job == 'player') ? '' : 'showOK' } let html = Mustache.render(MessageTpl, view); @@ -249,17 +249,40 @@ element.scrollTop += 100; } - window.addSpecialContact = function(name, number, base64Icon){ - - specialContacts.push({ - name : name, - number : number, - base64Icon: base64Icon - }); + let addSpecialContact = function(name, number, base64Icon){ + + let found = false - specialContacts.sort((a,b) => { - return a.name.localeCompare(b.name); - }); + for(let i=0; i { + return a.name.localeCompare(b.name); + }); + + renderSpecialContacts(); + + } + + } + + let removeSpecialContact = function(number){ + + for(let i=0; i Date: Tue, 15 Aug 2017 18:08:56 +0200 Subject: [PATCH 0366/3224] Set fr as default locale --- config.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.lua b/config.lua index 4a1defb3..b111e511 100644 --- a/config.lua +++ b/config.lua @@ -6,7 +6,7 @@ Config.MarkerColor = {r = 50, g = 50, b = 204} Config.EnablePlayerManagement = false Config.EnableArmoryManagement = false Config.MaxInService = -1 -Config.Locale = 'en' +Config.Locale = 'fr' Config.PoliceStations = { From fdcd78325f816f809ab926e233bae546ddafa360 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 15 Aug 2017 12:52:46 -0400 Subject: [PATCH 0367/3224] Multi-language support Completed multi-language support, added params to commands. --- .../es_extended/client/functions.lua | 8 +- resources/[essential]/es_extended/config.lua | 5 +- .../es_extended/config.weapons.lua | 154 +++++++++--------- .../[essential]/es_extended/locales/en.lua | 115 ++++++++++++- .../[essential]/es_extended/locales/fr.lua | 115 ++++++++++++- .../es_extended/server/commands.lua | 31 ++-- .../es_extended/server/functions.lua | 2 +- .../[essential]/es_extended/server/main.lua | 52 +++--- 8 files changed, 354 insertions(+), 128 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 60d2aff5..8a33b9eb 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -940,7 +940,7 @@ ESX.ShowInventory = function() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'inventory_item_count_give', { - title = 'Quantité' + title = _U('amount') }, function(data2, menu2) @@ -948,7 +948,7 @@ ESX.ShowInventory = function() local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification('Aucun joueur à proximité') + ESX.ShowNotification(_U('players_nearby')) else TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) end @@ -976,14 +976,14 @@ ESX.ShowInventory = function() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'inventory_item_count_remove', { - title = 'Quantité' + title = _U('amount') }, function(data2, menu2) local quantity = tonumber(data2.value) if quantity == nil then - ESX.ShowNotification('Montant invalide') + ESX.ShowNotification(_U('amount_invalid')) else TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) end diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua index a0546b7b..51392295 100644 --- a/resources/[essential]/es_extended/config.lua +++ b/resources/[essential]/es_extended/config.lua @@ -1,10 +1,11 @@ Config = {} Config.MaxPlayers = 32 Config.Accounts = {'bank', 'black_money'} -Config.AccountLabels = {bank = 'Banque', black_money = 'Argent Sale'} +Config.AccountLabels = {bank = 'Banque', black_money = 'Argent Sale'} -- French +--Config.AccountLabels = {bank = 'Bank', black_money = 'Dirty Money'} -- English Config.PaycheckInterval = 7 * 60000 Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true Config.RemoveInventoryItemDelay = 5 * 60000 Config.EnableWeaponPickup = false -Config.Locale = 'fr' +Config.Locale = 'en' diff --git a/resources/[essential]/es_extended/config.weapons.lua b/resources/[essential]/es_extended/config.weapons.lua index 4210cd94..3ce8b4c5 100644 --- a/resources/[essential]/es_extended/config.weapons.lua +++ b/resources/[essential]/es_extended/config.weapons.lua @@ -1,81 +1,81 @@ Config.Weapons = { {name = 'WEAPON_KNIFE', label = _U('weapon_knife')}, - {name = 'WEAPON_NIGHTSTICK', label = 'Matraque'}, - {name = 'WEAPON_HAMMER', label = 'Marteau'}, - {name = 'WEAPON_BAT', label = 'Bat'}, - {name = 'WEAPON_GOLFCLUB', label = 'Club de golfe'}, - {name = 'WEAPON_CROWBAR', label = 'Pied de biche'}, - {name = 'WEAPON_PISTOL', label = 'Pistolet'}, - {name = 'WEAPON_COMBATPISTOL', label = 'Pistolet de combat'}, - {name = 'WEAPON_APPISTOL', label = 'Pistolet automatique'}, - {name = 'WEAPON_PISTOL50', label = 'Pistolet calibre 50'}, - {name = 'WEAPON_MICROSMG', label = 'Micro SMG'}, - {name = 'WEAPON_SMG', label = 'SMG'}, - {name = 'WEAPON_ASSAULTSMG', label = 'SMG d\'assaut'}, - {name = 'WEAPON_ASSAULTRIFLE', label = 'Fusil d\'assaut'}, - {name = 'WEAPON_CARBINERIFLE', label = 'Carabine d\'assaut'}, - {name = 'WEAPON_ADVANCEDRIFLE', label = 'Fusil avancé'}, - {name = 'WEAPON_MG', label = 'Mitrailleuse'}, - {name = 'WEAPON_COMBATMG', label = 'Mitrailleuse de combat'}, - {name = 'WEAPON_PUMPSHOTGUN', label = 'Fusil à pompe'}, - {name = 'WEAPON_SAWNOFFSHOTGUN', label = 'Carabine à canon scié'}, - {name = 'WEAPON_ASSAULTSHOTGUN', label = 'Carabine d\'assaut'}, - {name = 'WEAPON_BULLPUPSHOTGUN', label = 'Carabine Bullpup'}, - {name = 'WEAPON_STUNGUN', label = 'Tazer'}, - {name = 'WEAPON_SNIPERRIFLE', label = 'Fusil de sniper'}, - {name = 'WEAPON_HEAVYSNIPER', label = 'Fusil de sniper lourd'}, - {name = 'WEAPON_REMOTESNIPER', label = 'Fusil de sniper à distance'}, - {name = 'WEAPON_GRENADELAUNCHER', label = 'Lance-grenade'}, - {name = 'WEAPON_RPG', label = 'Lance-rocket'}, - {name = 'WEAPON_STINGER', label = 'Lance-Missile Stinger'}, - {name = 'WEAPON_MINIGUN', label = 'Minigun'}, - {name = 'WEAPON_GRENADE', label = 'Grenade'}, - {name = 'WEAPON_STICKYBOMB', label = 'Bombe collante'}, - {name = 'WEAPON_SMOKEGRENADE', label = 'Grenade fumigène'}, - {name = 'WEAPON_BZGAS', label = 'Grenade à gaz BZ'}, - {name = 'WEAPON_MOLOTOV', label = 'Cocktail molotov'}, - {name = 'WEAPON_FIREEXTINGUISHER', label = 'Extincteur'}, - {name = 'WEAPON_PETROLCAN', label = 'Jerrican d\'essence'}, - {name = 'WEAPON_DIGISCANNER', label = 'Digiscanner'}, - {name = 'WEAPON_BALL', label = 'Balle'}, - {name = 'WEAPON_SNSPISTOL', label = 'Pistolet SNS'}, - {name = 'WEAPON_BOTTLE', label = 'Bouteille'}, - {name = 'WEAPON_GUSENBERG', label = 'Balayeuse Gusenberg'}, - {name = 'WEAPON_SPECIALCARBINE', label = 'Carabine spéciale'}, - {name = 'WEAPON_HEAVYPISTOL', label = 'Pistolet lourd'}, - {name = 'WEAPON_BULLPUPRIFLE', label = 'Fusil Bullpup'}, - {name = 'WEAPON_DAGGER', label = 'Poignard'}, - {name = 'WEAPON_VINTAGEPISTOL', label = 'Pistolet vintage'}, - {name = 'WEAPON_FIREWORK', label = 'Feu d\'artifice'}, - {name = 'WEAPON_MUSKET', label = 'Mousquet'}, - {name = 'WEAPON_HEAVYSHOTGUN', label = 'Fusil à pompe lourd'}, - {name = 'WEAPON_MARKSMANRIFLE', label = 'Fusil Marksman'}, - {name = 'WEAPON_HOMINGLAUNCHER', label = 'Lance tête-chercheuse'}, - {name = 'WEAPON_PROXMINE', label = 'Mine de proximité'}, - {name = 'WEAPON_SNOWBALL', label = 'Boule de neige'}, - {name = 'WEAPON_FLAREGUN', label = 'Lance fusée de détresse'}, - {name = 'WEAPON_GARBAGEBAG', label = 'Sac poubelle'}, - {name = 'WEAPON_HANDCUFFS', label = 'Menottes'}, - {name = 'WEAPON_COMBATPDW', label = 'Arme de défense personnelle'}, - {name = 'WEAPON_MARKSMANPISTOL', label = 'Pistolet Marksman'}, - {name = 'WEAPON_KNUCKLE', label = 'Poing américain'}, - {name = 'WEAPON_HATCHET', label = 'Hachette'}, - {name = 'WEAPON_RAILGUN', label = 'Canon éléctrique'}, - {name = 'WEAPON_MACHETE', label = 'Machetta'}, - {name = 'WEAPON_MACHINEPISTOL', label = 'Pistolet mitrailleur'}, - {name = 'WEAPON_SWITCHBLADE', label = 'Couteau à cran d\'arrêt'}, - {name = 'WEAPON_REVOLVER', label = 'Revolver'}, - {name = 'WEAPON_DBSHOTGUN', label = 'Fusil à pompe double canon'}, - {name = 'WEAPON_COMPACTRIFLE', label = 'Fusil compact'}, - {name = 'WEAPON_AUTOSHOTGUN', label = 'Fusil à pompe automatique'}, - {name = 'WEAPON_BATTLEAXE', label = 'Hache de combat'}, - {name = 'WEAPON_COMPACTLAUNCHER', label = 'Lanceur compact'}, - {name = 'WEAPON_MINISMG', label = 'Mini SMG'}, - {name = 'WEAPON_PIPEBOMB', label = 'Bombe tuyau'}, - {name = 'WEAPON_POOLCUE', label = 'Queue de billard'}, - {name = 'WEAPON_WRENCH', label = 'Clé'}, - {name = 'WEAPON_FLASHLIGHT', label = 'Lampe torche'}, - {name = 'GADGET_NIGHTVISION', label = 'Vision nocturne'}, - {name = 'GADGET_PARACHUTE', label = 'Parachute'}, + {name = 'WEAPON_NIGHTSTICK', label = _U('weapon_nightstick')}, + {name = 'WEAPON_HAMMER', label = _U('weapon_hammer')}, + {name = 'WEAPON_BAT', label = _U('weapon_bat')}, + {name = 'WEAPON_GOLFCLUB', label = _U('weapon_golfclub')}, + {name = 'WEAPON_CROWBAR', label = _U('weapon_crowbar')}, + {name = 'WEAPON_PISTOL', label = _U('weapon_pistol')}, + {name = 'WEAPON_COMBATPISTOL', label = _U('weapon_combatpistol')}, + {name = 'WEAPON_APPISTOL', label = _U('weapon_appistol')}, + {name = 'WEAPON_PISTOL50', label = _U('weapon_pistol50')}, + {name = 'WEAPON_MICROSMG', label = _U('weapon_microsmg')}, + {name = 'WEAPON_SMG', label = _U('weapon_smg')}, + {name = 'WEAPON_ASSAULTSMG', label = _U('weapon_assaultsmg')}, + {name = 'WEAPON_ASSAULTRIFLE', label = _U('weapon_assaultrifle')}, + {name = 'WEAPON_CARBINERIFLE', label = _U('weapon_carbinerifle')}, + {name = 'WEAPON_ADVANCEDRIFLE', label = _U('weapon_advancedrifle')}, + {name = 'WEAPON_MG', label = _U('weapon_mg')}, + {name = 'WEAPON_COMBATMG', label = _U('weapon_combatmg')}, + {name = 'WEAPON_PUMPSHOTGUN', label = _U('weapon_pumpshotgun')}, + {name = 'WEAPON_SAWNOFFSHOTGUN', label = _U('weapon_sawnoffshotgun')}, + {name = 'WEAPON_ASSAULTSHOTGUN', label = _U('weapon_assaultshotgun')}, + {name = 'WEAPON_BULLPUPSHOTGUN', label = _U('weapon_bullpupshotgun')}, + {name = 'WEAPON_STUNGUN', label = _U('weapon_stungun')}, + {name = 'WEAPON_SNIPERRIFLE', label = _U('weapon_sniperrifle')}, + {name = 'WEAPON_HEAVYSNIPER', label = _U('weapon_heavysniper')}, + {name = 'WEAPON_REMOTESNIPER', label = _U('weapon_remotesniper')}, + {name = 'WEAPON_GRENADELAUNCHER', label = _U('weapon_grenadelauncher')}, + {name = 'WEAPON_RPG', label = _U('weapon_rpg')}, + {name = 'WEAPON_STINGER', label = _U('weapon_stinger')}, + {name = 'WEAPON_MINIGUN', label = _U('weapon_minigun')}, + {name = 'WEAPON_GRENADE', label = _U('weapon_grenade')}, + {name = 'WEAPON_STICKYBOMB', label = _U('weapon_stickybomb')}, + {name = 'WEAPON_SMOKEGRENADE', label = _U('weapon_smokegrenade')}, + {name = 'WEAPON_BZGAS', label = _U('weapon_bzgas')}, + {name = 'WEAPON_MOLOTOV', label = _U('weapon_molotov')}, + {name = 'WEAPON_FIREEXTINGUISHER', label = _U('weapon_fireextinguisher')}, + {name = 'WEAPON_PETROLCAN', label = _U('weapon_petrolcan')}, + {name = 'WEAPON_DIGISCANNER', label = _U('weapon_digiscanner')}, + {name = 'WEAPON_BALL', label = _U('weapon_ball')}, + {name = 'WEAPON_SNSPISTOL', label = _U('weapon_snspistol')}, + {name = 'WEAPON_BOTTLE', label = _U('weapon_bottle')}, + {name = 'WEAPON_GUSENBERG', label = _U('weapon_gusenberg')}, + {name = 'WEAPON_SPECIALCARBINE', label = _U('weapon_specialcarbine')}, + {name = 'WEAPON_HEAVYPISTOL', label = _U('weapon_heavypistol')}, + {name = 'WEAPON_BULLPUPRIFLE', label = _U('weapon_bullpuprifle')}, + {name = 'WEAPON_DAGGER', label = _U('weapon_dagger')}, + {name = 'WEAPON_VINTAGEPISTOL', label = _U('weapon_vintagepistol')}, + {name = 'WEAPON_FIREWORK', label = _U('weapon_firework')}, + {name = 'WEAPON_MUSKET', label = _U('weapon_musket')}, + {name = 'WEAPON_HEAVYSHOTGUN', label = _U('weapon_heavyshotgun')}, + {name = 'WEAPON_MARKSMANRIFLE', label = _U('weapon_marksmanrifle')}, + {name = 'WEAPON_HOMINGLAUNCHER', label = _U('weapon_hominglauncher')}, + {name = 'WEAPON_PROXMINE', label = _U('weapon_proxmine')}, + {name = 'WEAPON_SNOWBALL', label = _U('weapon_snowball')}, + {name = 'WEAPON_FLAREGUN', label = _U('weapon_flaregun')}, + {name = 'WEAPON_GARBAGEBAG', label = _U('weapon_garbagebag')}, + {name = 'WEAPON_HANDCUFFS', label = _U('weapon_handcuffs')}, + {name = 'WEAPON_COMBATPDW', label = _U('weapon_combatpdw')}, + {name = 'WEAPON_MARKSMANPISTOL', label = _U('weapon_marksmanpistol')}, + {name = 'WEAPON_KNUCKLE', label = _U('weapon_knuckle')}, + {name = 'WEAPON_HATCHET', label = _U('weapon_hatchet')}, + {name = 'WEAPON_RAILGUN', label = _U('weapon_railgun')}, + {name = 'WEAPON_MACHETE', label = _U('weapon_machete')}, + {name = 'WEAPON_MACHINEPISTOL', label = _U('weapon_machinepistol')}, + {name = 'WEAPON_SWITCHBLADE', label = _U('weapon_switchblade')}, + {name = 'WEAPON_REVOLVER', label = _U('weapon_revolver')}, + {name = 'WEAPON_DBSHOTGUN', label = _U('weapon_dbshotgun')}, + {name = 'WEAPON_COMPACTRIFLE', label = _U('weapon_compactrifle')}, + {name = 'WEAPON_AUTOSHOTGUN', label = _U('weapon_autoshotgun')}, + {name = 'WEAPON_BATTLEAXE', label = _U('weapon_battleaxe')}, + {name = 'WEAPON_COMPACTLAUNCHER', label = _U('weapon_compactlauncher')}, + {name = 'WEAPON_MINISMG', label = _U('weapon_minismg')}, + {name = 'WEAPON_PIPEBOMB', label = _U('weapon_pipebomb')}, + {name = 'WEAPON_POOLCUE', label = _U('weapon_poolcue')}, + {name = 'WEAPON_WRENCH', label = _U('weapon_wrench')}, + {name = 'WEAPON_FLASHLIGHT', label = _U('weapon_flashlight')}, + {name = 'GADGET_NIGHTVISION', label = _U('gadget_nightvision')}, + {name = 'GADGET_PARACHUTE', label = _U('gadget_parachute')}, } \ No newline at end of file diff --git a/resources/[essential]/es_extended/locales/en.lua b/resources/[essential]/es_extended/locales/en.lua index 42abd3f0..b1f3aa26 100644 --- a/resources/[essential]/es_extended/locales/en.lua +++ b/resources/[essential]/es_extended/locales/en.lua @@ -4,5 +4,118 @@ Locales['en'] = { ['give'] = 'give', ['remove'] = 'remove', ['return'] = 'return', - ['weapon_knife'] = 'knife', + ['amount'] = 'amount', + ['amount_invalid'] = 'invalid amount', + ['players_nearby'] = 'no players nearby', + ['ex_inv_lim'] = 'action not possible, exceeding invetory limit for ~b~', + ['yougave'] = 'you gave', + ['youreceived'] = 'you received', + ['to'] = '~s~ to ~b~', + ['by'] = '~s~ by ~b~', + ['imp_invalid_quantity'] = 'action impossible, invalid quantity', + ['imp_invalid_amount'] = 'action impossible, invalid amount', + ['delete_five_min'] = '~r~delete~s~ in 5 minutes', + ['threw'] = 'you ~r~threw~s~', + ['rec_salary'] = 'you received your salary: ', + ['act_imp'] = 'action impossible', + -- Commands + ['setjob'] = 'assign a job to a user', + ['id_param'] = 'the id of the player', + ['setjob_param2'] = 'the job you wish to assign', + ['setjob_param3'] = 'the job level', + ['load_ipl'] = 'load ipl', + ['unload_ipl'] = 'unload ipl', + ['play_anim'] = 'play animation', + ['play_emote'] = 'play emote', + ['spawn_car'] = 'spawn a car', + ['spawn_car_param'] = 'name of car', + ['givemoney'] = 'give money', + ['money_amount'] = 'amount of money', + ['invalid_account'] = 'invalid account', + ['account'] = 'account', + ['giveaccountmoney'] = 'give account money', + ['invalid_item'] = 'invalid item', + ['item'] = 'item', + ['giveitem'] = 'give item', + ['weapon'] = 'weapon', + ['giveweapon'] = 'give weapon', + -- Weapons + ['weapon_knife'] = 'knife', + ['weapon_nightstick'] = 'nightstick', + ['weapon_hammer'] = 'hammer', + ['weapon_bat'] = 'bat', + ['weapon_golfclub'] = 'golf club', + ['weapon_crowbar'] = 'crow bar', + ['weapon_pistol'] = 'pistol', + ['weapon_combatpistol'] = 'combat pistol', + ['weapon_appistol'] = 'ap pistol', + ['weapon_pistol50'] = 'pistol .50', + ['weapon_microsmg'] = 'micro smg', + ['weapon_smg'] = 'smg', + ['weapon_assaultsmg'] = 'assault smg', + ['weapon_assaultrifle'] = 'assault rifle', + ['weapon_carbinerifle'] = 'carbine rifle', + ['weapon_advancedrifle'] = 'advanced rifle', + ['weapon_mg'] = 'mg', + ['weapon_combatmg'] = 'combat mg', + ['weapon_pumpshotgun'] = 'pump shotgun', + ['weapon_sawnoffshotgun'] = 'sawed off shotgun', + ['weapon_assaultshotgun'] = 'assault shotgun', + ['weapon_bullpupshotgun'] = 'bullpup shotgun', + ['weapon_stungun'] = 'tazer', + ['weapon_sniperrifle'] = 'sniper rifle', + ['weapon_heavysniper'] = 'heavy sniper', + ['weapon_remotesniper'] = 'remote sniper', + ['weapon_grenadelauncher'] = 'grenade launcher', + ['weapon_rpg'] = 'rocket launcher', + ['weapon_stinger'] = 'stinger', + ['weapon_minigun'] = 'minigun', + ['weapon_grenade'] = 'grenade', + ['weapon_stickybomb'] = 'sticky bomb', + ['weapon_smokegrenade'] = 'smoke grenade', + ['weapon_bzgas'] = 'bz gas', + ['weapon_molotov'] = 'molotov cocktail', + ['weapon_fireextinguisher'] = 'fire extinguisher', + ['weapon_petrolcan'] = 'jerrycan', + ['weapon_digiscanner'] = 'digiscanner', + ['weapon_ball'] = 'ball', + ['weapon_snspistol'] = 'sns pistol', + ['weapon_bottle'] = 'bottle', + ['weapon_gusenberg'] = 'gusenberg sweeper', + ['weapon_specialcarbine'] = 'special carbine', + ['weapon_heavypistol'] = 'heavy pistol', + ['weapon_bullpuprifle'] = 'bullpup rifle', + ['weapon_dagger'] = 'dagger', + ['weapon_vintagepistol'] = 'vintage pistol', + ['weapon_firework'] = 'firework', + ['weapon_musket'] = 'musket', + ['weapon_heavyshotgun'] = 'heavy shotgun', + ['weapon_marksmanrifle'] = 'marksman rifle', + ['weapon_hominglauncher'] = 'homing launcher', + ['weapon_proxmine'] = 'proximity mine', + ['weapon_snowball'] = 'snow ball', + ['weapon_flaregun'] = 'flaregun', + ['weapon_garbagebag'] = 'garbage bag', + ['weapon_handcuffs'] = 'handcuffs', + ['weapon_combatpdw'] = 'combat pdw', + ['weapon_marksmanpistol'] = 'marksman pistol', + ['weapon_knuckle'] = 'knuckledusters', + ['weapon_hatchet'] = 'hatchet', + ['weapon_railgun'] = 'railgun', + ['weapon_machete'] = 'machete', + ['weapon_machinepistol'] = 'machine pistol', + ['weapon_switchblade'] = 'switchblade', + ['weapon_revolver'] = 'heavy revolver', + ['weapon_dbshotgun'] = 'double barrel shotgun', + ['weapon_compactrifle'] = 'compact rifle', + ['weapon_autoshotgun'] = 'auto shotgun', + ['weapon_battleaxe'] = 'battle axe', + ['weapon_compactlauncher'] = 'compact launcher', + ['weapon_minismg'] = 'mini smg', + ['weapon_pipebomb'] = 'pipe bomb', + ['weapon_poolcue'] = 'pool cue', + ['weapon_wrench'] = 'pipe wrench', + ['weapon_flashlight'] = 'flashlight', + ['gadget_nightvision'] = 'night vision', + ['gadget_parachute'] = 'parachute', } \ No newline at end of file diff --git a/resources/[essential]/es_extended/locales/fr.lua b/resources/[essential]/es_extended/locales/fr.lua index 77204f96..fa699bf5 100644 --- a/resources/[essential]/es_extended/locales/fr.lua +++ b/resources/[essential]/es_extended/locales/fr.lua @@ -4,5 +4,118 @@ Locales['fr'] = { ['give'] = 'donner', ['remove'] = 'jeter', ['return'] = 'retour', - ['weapon_knife'] = 'couteau', + ['amount'] = 'quantité', + ['amount_invalid'] = 'montant invalide', + ['players_nearby'] = 'aucun joueur à proximité', + ['ex_inv_lim'] = 'action impossible, depassement de la limite d\'inventaire pour ~b~', + ['yougave'] = 'vous avez donné', + ['youreceived'] = 'vous avez reçu', + ['to'] = '~s~ à ~b~', + ['by'] = '~s~ par ~b~', + ['imp_invalid_quantity'] = 'action impossible, ~r~quantité invalide', + ['imp_invalid_amount'] = 'action impossible, ~r~montant invalide', + ['delete_five_min'] = '~r~suppression~s~ dans 5 minutes', + ['threw'] = 'vous avez ~r~jeté~s~', + ['rec_salary'] = 'vous avez reçu votre salaire : ', + ['act_imp'] = 'action impossible', + -- Commands + ['setjob'] = 'assigner job', + ['id_param'] = 'identification du joueur', + ['setjob_param2'] = 'le travail que vous souhaitez assigner', + ['setjob_param3'] = 'le niveau d\'emploi', + ['load_ipl'] = 'charger ipl', + ['unload_ipl'] = 'décharger ipl', + ['play_anim'] = 'jouer animation', + ['play_emote'] = 'jouer emote', + ['spawn_car'] = 'spawn un véhicule', + ['spawn_car_param'] = 'nom de la voiture', + ['givemoney'] = 'donner de l\'argent', + ['money_amount'] = 'somme d\'argent', + ['invalid_account'] = 'compete invalide', + ['account'] = 'compte', + ['giveaccountmoney'] = 'donner de l\'argent au compte', + ['invalid_item'] = 'item invalide', + ['item'] = 'article', + ['giveitem'] = 'donner un article', + ['weapon'] = 'arme', + ['giveweapon'] = 'donner de l\'arme', + -- Weapons + ['weapon_knife'] = 'couteau', + ['weapon_nightstick'] = 'matraque', + ['weapon_hammer'] = 'marteau', + ['weapon_bat'] = 'bat', + ['weapon_golfclub'] = 'club de golfe', + ['weapon_crowbar'] = 'pied de biche', + ['weapon_pistol'] = 'pistolet', + ['weapon_combatpistol'] = 'pistolet de combat', + ['weapon_appistol'] = 'pistolet automatique', + ['weapon_pistol50'] = 'pistolet calibre 50', + ['weapon_microsmg'] = 'micro smg', + ['weapon_smg'] = 'smg', + ['weapon_assaultsmg'] = 'smg d\'assaut', + ['weapon_assaultrifle'] = 'fusil d\'assaut', + ['weapon_carbinerifle'] = 'carabine d\'assaut', + ['weapon_advancedrifle'] = 'fusil avancé', + ['weapon_mg'] = 'mitrailleuse', + ['weapon_combatmg'] = 'mitrailleuse de combat', + ['weapon_pumpshotgun'] = 'fusil à pompe', + ['weapon_sawnoffshotgun'] = 'carabine à canon scié', + ['weapon_assaultshotgun'] = 'carabine d\'assaut', + ['weapon_bullpupshotgun'] = 'carabine bullpup', + ['weapon_stungun'] = 'tazer', + ['weapon_sniperrifle'] = 'fusil de sniper', + ['weapon_heavysniper'] = 'fusil de sniper lourd', + ['weapon_remotesniper'] = 'fusil de sniper à distance', + ['weapon_grenadelauncher'] = 'lance-grenade', + ['weapon_rpg'] = 'lance-rocket', + ['weapon_stinger'] = 'lance-missile stinger', + ['weapon_minigun'] = 'minigun', + ['weapon_grenade'] = 'grenade', + ['weapon_stickybomb'] = 'bombe collante', + ['weapon_smokegrenade'] = 'grenade fumigène', + ['weapon_bzgas'] = 'grenade à gaz bz', + ['weapon_molotov'] = 'cocktail molotov', + ['weapon_fireextinguisher'] = 'extincteur', + ['weapon_petrolcan'] = 'jerrican d\'essence', + ['weapon_digiscanner'] = 'digiscanner', + ['weapon_ball'] = 'balle', + ['weapon_snspistol'] = 'pistolet sns', + ['weapon_bottle'] = 'bouteille', + ['weapon_gusenberg'] = 'balayeuse gusenberg', + ['weapon_specialcarbine'] = 'carabine spéciale', + ['weapon_heavypistol'] = 'pistolet lourd', + ['weapon_bullpuprifle'] = 'fusil bullpup', + ['weapon_dagger'] = 'poignard', + ['weapon_vintagepistol'] = 'pistolet vintage', + ['weapon_firework'] = 'feu d\'artifice', + ['weapon_musket'] = 'mousquet', + ['weapon_heavyshotgun'] = 'fusil à pompe lourd', + ['weapon_marksmanrifle'] = 'fusil marksman', + ['weapon_hominglauncher'] = 'lance tête-chercheuse', + ['weapon_proxmine'] = 'mine de proximité', + ['weapon_snowball'] = 'boule de neige', + ['weapon_flaregun'] = 'lance fusée de détresse', + ['weapon_garbagebag'] = 'sac poubelle', + ['weapon_handcuffs'] = 'menottes', + ['weapon_combatpdw'] = 'arme de défense personnelle', + ['weapon_marksmanpistol'] = 'pistolet marksman', + ['weapon_knuckle'] = 'poing américain', + ['weapon_hatchet'] = 'hachette', + ['weapon_railgun'] = 'canon éléctrique', + ['weapon_machete'] = 'machetta', + ['weapon_machinepistol'] = 'pistolet mitrailleur', + ['weapon_switchblade'] = 'couteau à cran d\'arrêt', + ['weapon_revolver'] = 'revolver', + ['weapon_dbshotgun'] = 'fusil à pompe double canon', + ['weapon_compactrifle'] = 'fusil compact', + ['weapon_autoshotgun'] = 'fusil à pompe automatique', + ['weapon_battleaxe'] = 'hache de combat', + ['weapon_compactlauncher'] = 'lanceur compact', + ['weapon_minismg'] = 'mini smg', + ['weapon_pipebomb'] = 'bombe tuyau', + ['weapon_poolcue'] = 'queue de billard', + ['weapon_wrench'] = 'clé', + ['weapon_flashlight'] = 'lampe torche', + ['gadget_nightvision'] = 'vision nocturne', + ['gadget_parachute'] = 'parachute', } \ No newline at end of file diff --git a/resources/[essential]/es_extended/server/commands.lua b/resources/[essential]/es_extended/server/commands.lua index 6b47414d..16def62e 100644 --- a/resources/[essential]/es_extended/server/commands.lua +++ b/resources/[essential]/es_extended/server/commands.lua @@ -15,37 +15,37 @@ TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, xPlayer.setJob(args[3], tonumber(args[4])) end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end, {help = 'Assigner job => setjob [id] [job] [grade_id]'}) +end, {help = _U('setjob'), params = {{name = "id", help = _U('id_param')}, {name = "job", help = _U('setjob_param2')}, {name = "grade_id", help = _U('setjob_param3')}}}) TriggerEvent('es:addGroupCommand', 'loadipl', 'admin', function(source, args, user) TriggerClientEvent('esx:loadIPL', -1, args[2]) end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end, {help = 'Charger ipl'}) +end, {help = _U('load_ipl')}) TriggerEvent('es:addGroupCommand', 'unloadipl', 'admin', function(source, args, user) TriggerClientEvent('esx:unloadIPL', -1, args[2]) end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end, {help = 'Décharger ipl'}) +end, {help = _U('unload_ipl')}) TriggerEvent('es:addGroupCommand', 'playanim', 'admin', function(source, args, user) TriggerClientEvent('esx:playAnim', -1, args[2], args[3]) end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end, {help = 'Jouer animation'}) +end, {help = _U('play_anim')}) TriggerEvent('es:addGroupCommand', 'playemote', 'admin', function(source, args, user) TriggerClientEvent('esx:playEmote', -1, args[2]) end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end, {help = 'Jouer emote'}) +end, {help = _U('play_emote')}) TriggerEvent('es:addGroupCommand', 'car', 'admin', function(source, args, user) TriggerClientEvent('esx:spawnVehicle', source, args[2]) end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end, {help = 'Spawn un véhicule'}) +end, {help = _U('spawn_car'), params = {{name = "car", help = _U('spawn_car_param')}}}) TriggerEvent('es:addGroupCommand', 'givemoney', 'admin', function(source, args, user) @@ -56,12 +56,12 @@ TriggerEvent('es:addGroupCommand', 'givemoney', 'admin', function(source, args, if amount ~= nil then xPlayer.addMoney(amount) else - TriggerClientEvent('esx:showNotification', _source, 'Montant invalide') + TriggerClientEvent('esx:showNotification', _source, _U('amount_invalid')) end end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end, {help = 'givemoney [id] [montant]'}) +end, {help = _U('givemoney'), params = {{name = "id", help = _U('id_param')}, {name = "amount", help = _U('money_amount')}}}) TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, args, user) @@ -74,15 +74,15 @@ TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, if xPlayer.getAccount(account) ~= nil then xPlayer.addAccountMoney(account, amount) else - TriggerClientEvent('esx:showNotification', _source, 'Compte invalide') + TriggerClientEvent('esx:showNotification', _source, _U('invalid_account')) end else - TriggerClientEvent('esx:showNotification', _source, 'Montant invalide') + TriggerClientEvent('esx:showNotification', _source, _U('amount_invalid')) end end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end, {help = 'giveaccountmoney [id] [compte] [montant]'}) +end, {help = _U('giveaccountmoney'), params = {{name = "id", help = _U('id_param')}, {name = "account", help = _U('account')}, {name = "amount", help = _U('money_amount')}}}) TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, user) @@ -95,15 +95,15 @@ TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, u if xPlayer.getInventoryItem(item) ~= nil then xPlayer.addInventoryItem(item, count) else - TriggerClientEvent('esx:showNotification', _source, 'Item invalide') + TriggerClientEvent('esx:showNotification', _source, _U('invalid_item')) end else - TriggerClientEvent('esx:showNotification', _source, 'Quantité invalide') + TriggerClientEvent('esx:showNotification', _source, _U('invalid_amount')) end end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end, {help = 'giveitem [id] [item] [[quantité]]'}) +end, {help = _U('giveitem'), params = {{name = "id", help = _U('id_param')}, {name = "item", help = _U('item')}, {name = "amount", help = _U('amount')}}}) TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, user) @@ -114,5 +114,4 @@ TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end, {help = 'giveweapon [id] [arme]'}) - +end, {help = _U('giveweapon'), params = {{name = "id", help = _U('id_param')}, {name = "weapon", help = _U('weapon')}}}) \ No newline at end of file diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index 97b9f252..000402cf 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -168,7 +168,7 @@ ESX.StartPayCheck = function() if v.job.grade_salary > 0 then v.addMoney(v.job.grade_salary) - TriggerClientEvent('esx:showNotification', v.source, 'Vous avez reçu votre salaire : ~g~$' .. v.job.grade_salary) + TriggerClientEvent('esx:showNotification', v.source, _U('rec_salary') .. '~g~$' .. v.job.grade_salary) end end diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index 4338ed81..6d56ac13 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -302,17 +302,17 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo if itemCount > 0 and sourceItem.count >= itemCount then if targetItem.limit ~= -1 and (targetItem.count + sourceItem.count) > targetItem.limit then - TriggerClientEvent('esx:showNotification', target, 'Action impossible, depassement de la limite d\'inventaire pour ~b~' .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', target, _U('ex_inv_lim') .. targetXPlayer.name) else sourceXPlayer.removeInventoryItem(itemName, itemCount) targetXPlayer.addInventoryItem (itemName, itemCount) - TriggerClientEvent('esx:showNotification', _source, 'Vous avez donné ~g~x' .. itemCount .. ' ' .. ESX.Items[itemName].label .. '~s~ à ~b~' .. targetXPlayer.name) - TriggerClientEvent('esx:showNotification', target, 'Vous avez reçu ~g~x' .. itemCount .. ' ' .. ESX.Items[itemName].label .. '~s~ par ~b~' .. sourceXPlayer.name) + TriggerClientEvent('esx:showNotification', _source, _U('yougave') .. ' ~g~x' .. itemCount .. ' ' .. ESX.Items[itemName].label .. _U('to') .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', target, _U('youreceived') .. ' ~g~x' .. itemCount .. ' ' .. ESX.Items[itemName].label .. _U('by') .. sourceXPlayer.name) end else - TriggerClientEvent('esx:showNotification', target, 'Action impossible, ~r~quantité invalide') + TriggerClientEvent('esx:showNotification', target, _U('imp_invalid_quantity')) end elseif type == 'item_money' then @@ -322,11 +322,11 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo sourceXPlayer.removeMoney(itemCount) targetXPlayer.addMoney(itemCount) - TriggerClientEvent('esx:showNotification', _source, 'Vous avez donné ~g~$' .. itemCount .. '~s~ à ~b~' .. targetXPlayer.name) - TriggerClientEvent('esx:showNotification', target, 'Vous avez reçu ~g~$' .. itemCount .. '~s~ par ~b~' .. sourceXPlayer.name) + TriggerClientEvent('esx:showNotification', _source, _U('yougave') .. ' ~g~$' .. itemCount .. _U('to') .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', target, _U('youreceived') .. ' ~g~$' .. itemCount .. _U('by') .. sourceXPlayer.name) else - TriggerClientEvent('esx:showNotification', target, 'Action impossible, ~r~montant invalide') + TriggerClientEvent('esx:showNotification', target, _U('imp_invalid_amount')) end elseif type == 'item_account' then @@ -336,11 +336,11 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo sourceXPlayer.removeAccountMoney(itemName, itemCount) targetXPlayer.addAccountMoney(itemName, itemCount) - TriggerClientEvent('esx:showNotification', _source, 'Vous avez donné [' .. Config.AccountLabels[itemName] .. '] ~g~$' .. itemCount .. '~s~ à ~b~' .. targetXPlayer.name) - TriggerClientEvent('esx:showNotification', target, 'Vous avez reçu [' .. Config.AccountLabels[itemName] .. '] ~g~$' .. itemCount .. '~s~ par ~b~' .. sourceXPlayer.name) + TriggerClientEvent('esx:showNotification', _source, _U('yougave') .. ' [' .. Config.AccountLabels[itemName] .. '] ~g~$' .. itemCount .. _U('to') .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', target, _U('youreceived') .. ' [' .. Config.AccountLabels[itemName] .. '] ~g~$' .. itemCount .. _U('by') .. sourceXPlayer.name) else - TriggerClientEvent('esx:showNotification', target, 'Action impossible, ~r~montant invalide') + TriggerClientEvent('esx:showNotification', target, _U('imp_invalid_amount')) end elseif type == 'item_weapon' then @@ -357,8 +357,8 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo end end - TriggerClientEvent('esx:showNotification', _source, 'Vous avez donné x1 ' .. ' ~g~' .. weaponLabel .. '~s~ à ~b~' .. targetXPlayer.name) - TriggerClientEvent('esx:showNotification', target, 'Vous avez reçu x1 ' .. ' ~g~' .. weaponLabel .. '~s~ par ~b~' .. sourceXPlayer.name) + TriggerClientEvent('esx:showNotification', _source, _U('yougave') .. ' x1 ~g~' .. weaponLabel .. _U('to') .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', target, _U('youreceived') .. ' x1 ~g~' .. weaponLabel .. _U('by') .. sourceXPlayer.name) end end) @@ -371,7 +371,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if type == 'item_standard' then if itemCount == nil or itemCount <= 0 then - TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~quantité invalide') + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) else local xPlayer = ESX.GetPlayerFromId(source) @@ -384,10 +384,10 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) end if itemCount > foundItem.count then - TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~quantité invalide') + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) else - TriggerClientEvent('esx:showNotification', _source, '~r~Suppression~s~ dans 5 minutes') + TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) SetTimeout(Config.RemoveInventoryItemDelay, function() @@ -400,7 +400,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if total > 0 then xPlayer.removeInventoryItem(itemName, total) - TriggerClientEvent('esx:showNotification', _source, 'Vous avez ~r~jeté~s~ ' .. foundItem.label .. ' x' .. total) + TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' ' .. foundItem.label .. ' x' .. total) end end) @@ -412,16 +412,16 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) elseif type == 'item_money' then if itemCount == nil or itemCount <= 0 then - TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~montant invalide') + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) else local xPlayer = ESX.GetPlayerFromId(source) if itemCount > xPlayer.player.get('money') then - TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~montant invalide') + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) else - TriggerClientEvent('esx:showNotification', _source, '~r~Suppression~s~ dans 5 minutes') + TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) SetTimeout(Config.RemoveInventoryItemDelay, function() @@ -434,7 +434,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if total > 0 then xPlayer.removeMoney(total) - TriggerClientEvent('esx:showNotification', _source, 'Vous avez ~r~jeté~s~ [Cash] $' .. total) + TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) end end) @@ -446,16 +446,16 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) elseif type == 'item_account' then if itemCount == nil or itemCount <= 0 then - TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~montant invalide') + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) else local xPlayer = ESX.GetPlayerFromId(source) if itemCount > xPlayer.getAccount(itemName).money then - TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~montant invalide') + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) else - TriggerClientEvent('esx:showNotification', _source, '~r~Suppression~s~ dans 5 minutes') + TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) SetTimeout(Config.RemoveInventoryItemDelay, function() @@ -468,7 +468,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if total > 0 then xPlayer.removeAccountMoney(itemName, total) - TriggerClientEvent('esx:showNotification', _source, 'Vous avez ~r~jeté~s~ [Cash] $' .. total) + TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) end end) @@ -501,7 +501,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, weaponName) end - TriggerClientEvent('esx:showNotification', _source, 'Vous avez ~r~jeté~s~ x1 ' .. ' ~g~' .. weaponLabel) + TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' x1 ~g~' .. weaponLabel) end) @@ -518,7 +518,7 @@ AddEventHandler('esx:useItem', function(itemName) if count > 0 then ESX.UseItem(source, itemName) else - TriggerClientEvent('esx:showNotification', xPlayer.source, 'Action impossible') + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('act_imp')) end end) From 5dcdff19e0200f12c9a984f67b62ab0377e98ea1 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 15 Aug 2017 12:59:15 -0400 Subject: [PATCH 0368/3224] Grammatical fix (en) Fixed a slight grammar mistake. --- locales/en.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/en.lua b/locales/en.lua index 45358ed9..843bec03 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,6 +1,6 @@ Locales['en'] = { ['invalid_amount'] = '~r~invalid amount', ['deposit_money'] = 'you have deposited ~g~$', - ['withdraw_money'] = 'you withdrawn ~g~$', + ['withdraw_money'] = 'you have withdrawn ~g~$', ['press_e_atm'] = 'press ~INPUT_PICKUP~ for deposit or withdrawal from ~g~ATM~s~.', } From 40bc44774777ee400a19c978fb6d5a1368077d5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 15 Aug 2017 19:05:31 +0200 Subject: [PATCH 0369/3224] Set fr as default locale --- resources/[essential]/es_extended/config.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua index 51392295..8b280075 100644 --- a/resources/[essential]/es_extended/config.lua +++ b/resources/[essential]/es_extended/config.lua @@ -8,4 +8,4 @@ Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true Config.RemoveInventoryItemDelay = 5 * 60000 Config.EnableWeaponPickup = false -Config.Locale = 'en' +Config.Locale = 'fr' From 79eae03965e7b3be44103d7a9b81972db3e87a1b Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 15 Aug 2017 14:53:40 -0400 Subject: [PATCH 0370/3224] Multi-language support --- __resource.lua | 6 ++++++ client/main.lua | 18 +++++++++--------- config.lua | 1 + locales/en.lua | 10 ++++++++++ locales/fr.lua | 10 ++++++++++ server/main.lua | 2 +- 6 files changed, 37 insertions(+), 10 deletions(-) create mode 100644 locales/en.lua create mode 100644 locales/fr.lua diff --git a/__resource.lua b/__resource.lua index e16934cb..a04ea924 100644 --- a/__resource.lua +++ b/__resource.lua @@ -3,12 +3,18 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ESX BarberShop' server_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', '@mysql-async/lib/MySQL.lua', 'config.lua', 'server/main.lua' } client_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', 'config.lua', 'client/main.lua' } diff --git a/client/main.lua b/client/main.lua index 150032c8..6fbf62b9 100644 --- a/client/main.lua +++ b/client/main.lua @@ -37,11 +37,11 @@ function OpenShopMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'shop_confirm', { - title = 'Valider cet achat ?', + title = _U('valid_purchase'), align = 'top-left', elements = { - {label = 'Oui', value = 'yes'}, - {label = 'Non', value = 'no'}, + {label = _U('yes'), value = 'yes'}, + {label = _U('no'), value = 'no'}, } }, function(data, menu) @@ -65,7 +65,7 @@ function OpenShopMenu() TriggerEvent('skinchanger:loadSkin', skin) end) - ESX.ShowNotification('Vous n\'avez pas assez d\'argent') + ESX.ShowNotification(_U('not_enough_money')) end @@ -82,7 +82,7 @@ function OpenShopMenu() end CurrentAction = 'shop_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('press_access') CurrentActionData = {} end, @@ -91,7 +91,7 @@ function OpenShopMenu() menu.close() CurrentAction = 'shop_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('press_access') CurrentActionData = {} end @@ -102,7 +102,7 @@ function OpenShopMenu() menu.close() CurrentAction = 'shop_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('press_access') CurrentActionData = {} end, { @@ -134,7 +134,7 @@ end AddEventHandler('esx_barbershop:hasEnteredMarker', function(zone) CurrentAction = 'shop_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('press_access') CurrentActionData = {} end) @@ -156,7 +156,7 @@ Citizen.CreateThread(function() SetBlipAsShortRange(blip, true) BeginTextCommandSetBlipName("STRING") - AddTextComponentString("Coiffeur / Barbier") + AddTextComponentString(_U('barber_blip')) EndTextCommandSetBlipName(blip) end diff --git a/config.lua b/config.lua index 290e2aec..07171ad3 100644 --- a/config.lua +++ b/config.lua @@ -6,6 +6,7 @@ Config.DrawDistance = 100.0 Config.MarkerSize = {x = 1.5, y = 1.5, z = 1.0} Config.MarkerColor = {r = 102, g = 102, b = 204} Config.MarkerType = 1 +Config.Locale = 'fr' Config.Zones = {} diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..c961e3df --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,10 @@ +Locales['en'] = { + + ['valid_purchase'] = 'validate this purchase?', + ['yes'] = 'yes', + ['no'] = 'no', + ['not_enough_money'] = 'you do not have enough money', + ['press_access'] = 'press ~INPUT_CONTENT~ to access the menu', + ['barber_blip'] = 'barber shop', + ['you_paid'] = 'you paid ', +} \ No newline at end of file diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..22b95b74 --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,10 @@ +Locales['fr'] = { + + ['valid_purchase'] = 'valider cet achat ?', + ['yes'] = 'oui', + ['no'] = 'non', + ['not_enough_money'] = 'vous n\'avez pas assez d\'argent', + ['press_access'] = 'appuez sur ~INPUT_CONTENT~ pour accéder au menu', + ['barber_blip'] = 'barbier', + ['you_paid'] = 'vous avez payé ', +} \ No newline at end of file diff --git a/server/main.lua b/server/main.lua index ea58941f..450983d5 100644 --- a/server/main.lua +++ b/server/main.lua @@ -9,7 +9,7 @@ AddEventHandler('esx_barbershop:pay', function() xPlayer.removeMoney(Config.Price) - TriggerClientEvent('esx:showNotification', source, 'Vous avez payé $' .. Config.Price) + TriggerClientEvent('esx:showNotification', source, _U('you_paid') .. '$' .. Config.Price) end) From d95ac08d0ab0361a5bb072e039dce84996b15506 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 15 Aug 2017 14:59:46 -0400 Subject: [PATCH 0371/3224] Multi-language support Updated readme with proper clone link, and moved it to the front directory. --- esx_weashops/LICENSE.txt => LICENSE.txt | 0 esx_weashops/README.md => README.md | 2 +- esx_weashops/__resource.lua => __resource.lua | 6 ++++++ {esx_weashops/client => client}/main.lua | 8 ++++---- esx_weashops/config.lua => config.lua | 1 + esx_weashops/esx_weashops.sql => esx_weashops.sql | 0 locales/en.lua | 10 ++++++++++ locales/fr.lua | 10 ++++++++++ {esx_weashops/server => server}/main.lua | 10 +++++----- 9 files changed, 37 insertions(+), 10 deletions(-) rename esx_weashops/LICENSE.txt => LICENSE.txt (100%) rename esx_weashops/README.md => README.md (74%) rename esx_weashops/__resource.lua => __resource.lua (55%) rename {esx_weashops/client => client}/main.lua (94%) rename esx_weashops/config.lua => config.lua (95%) rename esx_weashops/esx_weashops.sql => esx_weashops.sql (100%) create mode 100644 locales/en.lua create mode 100644 locales/fr.lua rename {esx_weashops/server => server}/main.lua (76%) diff --git a/esx_weashops/LICENSE.txt b/LICENSE.txt similarity index 100% rename from esx_weashops/LICENSE.txt rename to LICENSE.txt diff --git a/esx_weashops/README.md b/README.md similarity index 74% rename from esx_weashops/README.md rename to README.md index cecf1651..284f1eb0 100644 --- a/esx_weashops/README.md +++ b/README.md @@ -6,7 +6,7 @@ FXServer ESX Weapon Shops 1) CD in your resources/[esx] folder 2) Clone the repository ``` - +git clone https://github.com/FXServer-ESX/fxserver-esx_weashops.git esx_weashops ``` 3) Import esx_weashops.sql in your database 4) Add this in your server.cfg : diff --git a/esx_weashops/__resource.lua b/__resource.lua similarity index 55% rename from esx_weashops/__resource.lua rename to __resource.lua index 47caca54..34c968b5 100644 --- a/esx_weashops/__resource.lua +++ b/__resource.lua @@ -1,11 +1,17 @@ description 'ESX Mecano Job' client_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', 'config.lua', 'client/main.lua' } server_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', '@mysql-async/lib/MySQL.lua', 'config.lua', 'server/main.lua' diff --git a/esx_weashops/client/main.lua b/client/main.lua similarity index 94% rename from esx_weashops/client/main.lua rename to client/main.lua index fc3ac617..e07aca95 100644 --- a/esx_weashops/client/main.lua +++ b/client/main.lua @@ -45,7 +45,7 @@ function OpenShopMenu(zone) ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'shop', { - title = 'Magasin', + title = _U('shop'), elements = elements }, function(data, menu) @@ -56,7 +56,7 @@ function OpenShopMenu(zone) menu.close() CurrentAction = 'shop_menu' - CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au magasin.' + CurrentActionMsg = _U('shop_menu') CurrentActionData = {zone = zone} end ) @@ -65,7 +65,7 @@ end AddEventHandler('esx_weashop:hasEnteredMarker', function(zone) CurrentAction = 'shop_menu' - CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au magasin.' + CurrentActionMsg = _U('shop_menu') CurrentActionData = {zone = zone} end) @@ -89,7 +89,7 @@ Citizen.CreateThread(function() SetBlipColour (blip, 2) SetBlipAsShortRange(blip, true) BeginTextCommandSetBlipName("STRING") - AddTextComponentString("GunShop") + AddTextComponentString(_U('map_blip')) EndTextCommandSetBlipName(blip) end end diff --git a/esx_weashops/config.lua b/config.lua similarity index 95% rename from esx_weashops/config.lua rename to config.lua index 5006a708..e4e843fd 100644 --- a/esx_weashops/config.lua +++ b/config.lua @@ -4,6 +4,7 @@ Config.DrawDistance = 100 Config.Size = {x = 1.5, y = 1.5, z = 1.5} Config.Color = {r = 0, g = 128, b = 255} Config.Type = 1 +Config.Locale = 'en' Config.Zones = { diff --git a/esx_weashops/esx_weashops.sql b/esx_weashops.sql similarity index 100% rename from esx_weashops/esx_weashops.sql rename to esx_weashops.sql diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..a833c4cf --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,10 @@ +Locales ['en'] = { + + ['buy'] = 'you bought', + ['not_enough_black'] = 'you do not have enough dirty money', + ['not_enough'] = 'you do not have enough money', + ['shop'] = 'shop', + ['shop_menu'] = 'Press ~INPUT_CONTENT~ to access the shop.', + ['map_blip'] = 'gun shop', + +} \ No newline at end of file diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..1b3b5ca1 --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,10 @@ +Locales ['fr'] = { + + ['buy'] = 'vous avez acheté ~b~1x ', + ['not_enough_black'] = 'Vous n\'avez ~r~pas assez~s~ d\'argent sale', + ['not_enough'] = 'vous n\'avez ~r~pas assez~s~ d\'argent', + ['shop'] = 'magasin', + ['shop_menu'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder au magasin.', + ['map_blip'] = 'armurerie', + +} \ No newline at end of file diff --git a/esx_weashops/server/main.lua b/server/main.lua similarity index 76% rename from esx_weashops/server/main.lua rename to server/main.lua index ae222d5f..56b81495 100644 --- a/esx_weashops/server/main.lua +++ b/server/main.lua @@ -50,7 +50,7 @@ ESX.RegisterServerCallback('esx_weashop:requestDBItems', function(source, cb) end) RegisterServerEvent('esx_weashop:buyItem') -AddEventHandler('esx_weashop:buyItem', function(itemName, price,zone) +AddEventHandler('esx_weashop:buyItem', function(itemName, price, zone) local _source = source local xPlayer = ESX.GetPlayerFromId(source) @@ -61,10 +61,10 @@ AddEventHandler('esx_weashop:buyItem', function(itemName, price,zone) xPlayer.removeAccountMoney('black_money', price) xPlayer.addWeapon(itemName, 42) - TriggerClientEvent('esx:showNotification', _source, 'Vous avez acheté ~b~1x ' .. ItemsLabels[itemName]) + TriggerClientEvent('esx:showNotification', _source, _U('buy') .. ItemsLabels[itemName]) else - TriggerClientEvent('esx:showNotification', _source, 'Vous n\'avez ~r~pas assez~s~ d\'argent sale') + TriggerClientEvent('esx:showNotification', _source, _U('not_enough_black')) end else if xPlayer.get('money') >= price then @@ -72,10 +72,10 @@ AddEventHandler('esx_weashop:buyItem', function(itemName, price,zone) xPlayer.removeMoney(price) xPlayer.addWeapon(itemName, 42) - TriggerClientEvent('esx:showNotification', _source, 'Vous avez acheté ~b~1x ' .. ItemsLabels[itemName]) + TriggerClientEvent('esx:showNotification', _source, _U('buy') .. ItemsLabels[itemName]) else - TriggerClientEvent('esx:showNotification', _source, 'Vous n\'avez ~r~pas assez~s~ d\'argent.') + TriggerClientEvent('esx:showNotification', _source, _U('not_enough')) end end From ff2613c551d914b34fbe7c46b82872be9bcd0b2d Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 15 Aug 2017 15:42:51 -0400 Subject: [PATCH 0372/3224] Grammatical fix (en) --- resources/[essential]/es_extended/config.lua | 2 +- resources/[essential]/es_extended/locales/en.lua | 6 +++--- resources/[essential]/es_extended/locales/fr.lua | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua index 51392295..8b280075 100644 --- a/resources/[essential]/es_extended/config.lua +++ b/resources/[essential]/es_extended/config.lua @@ -8,4 +8,4 @@ Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true Config.RemoveInventoryItemDelay = 5 * 60000 Config.EnableWeaponPickup = false -Config.Locale = 'en' +Config.Locale = 'fr' diff --git a/resources/[essential]/es_extended/locales/en.lua b/resources/[essential]/es_extended/locales/en.lua index b1f3aa26..0a059de2 100644 --- a/resources/[essential]/es_extended/locales/en.lua +++ b/resources/[essential]/es_extended/locales/en.lua @@ -20,11 +20,11 @@ Locales['en'] = { ['act_imp'] = 'action impossible', -- Commands ['setjob'] = 'assign a job to a user', - ['id_param'] = 'the id of the player', + ['id_param'] = 'the ID of the player', ['setjob_param2'] = 'the job you wish to assign', ['setjob_param3'] = 'the job level', - ['load_ipl'] = 'load ipl', - ['unload_ipl'] = 'unload ipl', + ['load_ipl'] = 'load IPL', + ['unload_ipl'] = 'unload IPL', ['play_anim'] = 'play animation', ['play_emote'] = 'play emote', ['spawn_car'] = 'spawn a car', diff --git a/resources/[essential]/es_extended/locales/fr.lua b/resources/[essential]/es_extended/locales/fr.lua index fa699bf5..e5af7b97 100644 --- a/resources/[essential]/es_extended/locales/fr.lua +++ b/resources/[essential]/es_extended/locales/fr.lua @@ -23,8 +23,8 @@ Locales['fr'] = { ['id_param'] = 'identification du joueur', ['setjob_param2'] = 'le travail que vous souhaitez assigner', ['setjob_param3'] = 'le niveau d\'emploi', - ['load_ipl'] = 'charger ipl', - ['unload_ipl'] = 'décharger ipl', + ['load_ipl'] = 'charger IPL', + ['unload_ipl'] = 'décharger IPL', ['play_anim'] = 'jouer animation', ['play_emote'] = 'jouer emote', ['spawn_car'] = 'spawn un véhicule', From 4e791afe0e893e135c6e8a61164dac5984c8170b Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 15 Aug 2017 15:53:47 -0400 Subject: [PATCH 0373/3224] Grammatical fix (en) --- locales/en.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/locales/en.lua b/locales/en.lua index 0ad97fbe..4f0a9562 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -15,7 +15,7 @@ Locales['en'] = { ['vehicle_out'] = 'there is already a car out of the garage', ['vehicle_spawner'] = 'press ~INPUT_CONTEXT~ to take out a vehicle', ['store_vehicle'] = 'press ~INPUT_CONTEXT~ to store the vehicle', - ['service_max'] = 'Max officers in service : ', + ['service_max'] = 'Max officers in service: ', --Action Menu ['citizen_interaction'] = 'citizen Interaction', ['vehicle_interaction'] = 'vehicle Interaction', @@ -42,7 +42,7 @@ Locales['en'] = { ['name'] = 'name : ', ['bac'] = 'bAC : ', --Body Search Menu - ['confiscate_dirty'] = 'confiscate dirty money : $', + ['confiscate_dirty'] = 'confiscate dirty money: $', ['guns_label'] = '--- Guns ---', ['confiscate'] = 'confiscate ', ['inventory_label'] = '--- Inventory ---', @@ -52,11 +52,11 @@ Locales['en'] = { ['minor_offense'] = 'minor Offense', ['average_offense'] = 'average Offense', ['major_offense'] = 'major Offense', - ['fine_total'] = 'fine : ', + ['fine_total'] = 'fine: ', --Vehicle Info Menu ['plate'] = 'Plate: ', - ['owner_unknown'] = 'owner : Unknown', - ['owner'] = 'owner : ', + ['owner_unknown'] = 'owner: Unknown', + ['owner'] = 'owner: ', --Weapons Menus ['get_weapon_menu'] = 'armory - Take Weapon', ['put_weapon_menu'] = 'armory - Put Weapon', From 78259fcdb86e1079969bc8d5b48450c54ca30b44 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 15 Aug 2017 18:17:17 -0400 Subject: [PATCH 0374/3224] Multi-language support --- __resource.lua | 6 ++++++ client/main.lua | 54 ++++++++++++++++++++++++------------------------- config.lua | 1 + locales/en.lua | 23 +++++++++++++++++++++ locales/fr.lua | 23 +++++++++++++++++++++ 5 files changed, 80 insertions(+), 27 deletions(-) create mode 100644 locales/en.lua create mode 100644 locales/fr.lua diff --git a/__resource.lua b/__resource.lua index 9d54ef92..7a339a1a 100644 --- a/__resource.lua +++ b/__resource.lua @@ -3,12 +3,18 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ESX RealestateAgentJob' server_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', '@mysql-async/lib/MySQL.lua', 'config.lua', 'server/main.lua' } client_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', 'config.lua', 'client/main.lua' } \ No newline at end of file diff --git a/client/main.lua b/client/main.lua index c5c126b1..853d98ef 100644 --- a/client/main.lua +++ b/client/main.lua @@ -30,14 +30,14 @@ end) function OpenRealestateAgentMenu() local elements = { - {label = 'Propriétés', value = 'properties'}, - {label = 'Clients', value = 'customers'}, + {label = _U('properties'), value = 'properties'}, + {label = _U('clients'), value = 'customers'}, } if PlayerData.job ~= nil and PlayerData.job.name == 'realestateagent' and PlayerData.job.grade_name == 'boss' then - table.insert(elements, {label = 'Retirer argent société', value = 'withdraw_society_money'}) - table.insert(elements, {label = 'Déposer argent ', value = 'deposit_money'}) - table.insert(elements, {label = 'Blanchir argent', value = 'wash_money'}) + table.insert(elements, {label = _U('remove_comp_money'), value = 'withdraw_society_money'}) + table.insert(elements, {label = _U('dep_money'), value = 'deposit_money'}) + table.insert(elements, {label = _U('wash_money'), value = 'wash_money'}) end ESX.UI.Menu.CloseAll() @@ -45,7 +45,7 @@ function OpenRealestateAgentMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'realestateagent', { - title = 'Agent Immobilier', + title = _U('realtor'), elements = elements }, function(data, menu) @@ -63,14 +63,14 @@ function OpenRealestateAgentMenu() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'withdraw_society_money_amount', { - title = 'Montant du retrait' + title = _U('amount_withdraw') }, function(data, menu) local amount = tonumber(data.value) if amount == nil then - ESX.ShowNotification('Montant invalide') + ESX.ShowNotification(_U('invalid_amount')) else menu.close() TriggerServerEvent('esx_society:withdrawMoney', 'realestateagent', amount) @@ -89,14 +89,14 @@ function OpenRealestateAgentMenu() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'deposit_money_amount', { - title = 'Montant du dépôt' + title = _('amount_deposit') }, function(data, menu) local amount = tonumber(data.value) if amount == nil then - ESX.ShowNotification('Montant invalide') + ESX.ShowNotification(_U('invalid_amount')) else menu.close() TriggerServerEvent('esx_society:depositMoney', 'realestateagent', amount) @@ -115,14 +115,14 @@ function OpenRealestateAgentMenu() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'wash_money_amount', { - title = 'Montant à blanchir' + title = _U('amount_wash') }, function(data, menu) local amount = tonumber(data.value) if amount == nil then - ESX.ShowNotification('Montant invalide') + ESX.ShowNotification(_U('invalid_amount')) else menu.close() TriggerServerEvent('esx_society:washMoney', 'realestateagent', amount) @@ -142,7 +142,7 @@ function OpenRealestateAgentMenu() menu.close() CurrentAction = 'realestateagent_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('press_to_access') CurrentActionData = {} end @@ -155,7 +155,7 @@ function OpenPropertyMenu() TriggerEvent('esx_property:getProperties', function(properties) local elements = { - head = {'Propriété', 'Actions'}, + head = {_U('property'), 'Actions'}, rows = {} } @@ -164,7 +164,7 @@ function OpenPropertyMenu() data = properties[i], cols = { properties[i].label, - '{{Assigner [vente]|sell}} {{Assigner [Location]|rent}} {{GPS|gps}}' + _U('property_actions') } }) end @@ -181,14 +181,14 @@ function OpenPropertyMenu() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'sell_property_amount', { - title = 'Montant' + title = _U('amount') }, function(data2, menu) local amount = tonumber(data2.value) if amount == nil then - ESX.ShowNotification('Montant invalide') + ESX.ShowNotification(_U('invalid_amount')) else menu.close() @@ -196,7 +196,7 @@ function OpenPropertyMenu() local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification('Aucun joueur à proximité') + ESX.ShowNotification(_U('no_play_near')) else TriggerServerEvent('esx_realestateagentjob:sell', GetPlayerServerId(closestPlayer), data.data.name, amount) end @@ -220,14 +220,14 @@ function OpenPropertyMenu() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'rent_property_amount', { - title = 'Montant' + title = _U('amount') }, function(data2, menu) local amount = tonumber(data2.value) if amount == nil then - ESX.ShowNotification('Montant invalide') + ESX.ShowNotification(_U('invalid_amount')) else menu.close() @@ -235,7 +235,7 @@ function OpenPropertyMenu() local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification('Aucun joueur à proximité') + ESX.ShowNotification(_U('no_play_near')) else TriggerServerEvent('esx_realestateagentjob:rent', GetPlayerServerId(closestPlayer), data.data.name, amount) end @@ -283,7 +283,7 @@ function OpenCustomersMenu() ESX.TriggerServerCallback('esx_realestateagentjob:getCustomers', function(customers) local elements = { - head = {'Client', 'Propriété', 'Type', 'Actions'}, + head = {'Client', _U('property'), 'Type', 'Actions'}, rows = {} } @@ -293,8 +293,8 @@ function OpenCustomersMenu() cols = { customers[i].name, customers[i].propertyName, - (customers[i].rented and 'Location' or 'Vente'), - '{{Révoquer contrat|revoke}} {{GPS|gps}}' + (customers[i].rented and _U('rent') or _U('sell')), + _U('contract') } }) end @@ -375,7 +375,7 @@ AddEventHandler('esx_realestateagentjob:hasEnteredMarker', function(zone) if zone == 'OfficeActions' and PlayerData.job ~= nil and PlayerData.job.name == 'realestateagent' then CurrentAction = 'realestateagent_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('press_to_access') CurrentActionData = {} end @@ -389,7 +389,7 @@ RegisterNetEvent('esx_phone:loaded') AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) local specialContact = { - name = 'Agent immobilier', + name = _U('realtor'), number = 'realestateagent', base64Icon = 'data:image/png;base64,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' } @@ -410,7 +410,7 @@ Citizen.CreateThread(function() SetBlipAsShortRange(blip, true) BeginTextCommandSetBlipName("STRING") - AddTextComponentString("Agents Immobilier") + AddTextComponentString(_U('realtors')) EndTextCommandSetBlipName(blip) end) diff --git a/config.lua b/config.lua index bb654350..559ada37 100644 --- a/config.lua +++ b/config.lua @@ -1,6 +1,7 @@ Config = {} Config.DrawDistance = 100.0 Config.MarkerColor = {r = 120, g = 120, b = 240} +Config.Locale = 'fr' Config.Zones = { diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..76658a0f --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,23 @@ +Locales['en'] = { + + ['properties'] = 'properties', + ['property'] = 'property', + ['clients'] = 'clients', + ['remove_comp_money'] = 'remove company money', + ['dep_money'] = 'deposit money', + ['wash_money'] = 'wash money', + ['realtor'] = 'real Estate Agent', + ['amount_withdraw'] = 'amount of withdrawal', + ['invalid_amount'] = 'invalid amount', + ['amount_deposit'] = 'deposit amount', + ['amount_wash'] = 'amount to bleach', + ['press_to_access'] = 'press ~INPUT_CONTEXT~ to access the menu', + ['property_actions'] = '{{Assign [Sell]|sell}} {{Assign [Rent]|rent}} {{GPS|gps}}', + ['amount'] = 'amount', + ['no_play_near'] = 'no players nearby', + ['contract'] = '{{Revoke contract|revoke}} {{GPS|gps}}', + ['rent'] = 'rent', + ['sell'] = 'sell', + ['realtors'] = 'real Estate Agents', + +} \ No newline at end of file diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..f98c888e --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,23 @@ +Locales['fr'] = { + + ['properties'] = 'propriétés', + ['property'] = 'propriété', + ['clients'] = 'clients', + ['remove_comp_money'] = 'retirer argent société', + ['dep_money'] = 'déposer argent', + ['wash_money'] = 'blanchir argent', + ['realtor'] = 'agent Immobilier', + ['amount_withdraw'] = 'montant du retrait', + ['invalid_amount'] = 'montant invalide', + ['amount_deposit'] = 'montant du dépôt', + ['amount_wash'] = 'montant à blanchir', + ['press_to_access'] = 'appuez sur ~INPUT_CONTEXT~ pour accéder au menu', + ['property_actions'] = '{{Assigner [Vente]|sell}} {{Assigner [Location]|rent}} {{GPS|gps}}', + ['amount'] = 'montant', + ['no_play_near'] = 'aucun joueur à proximité', + ['contract'] = '{{Révoquer contrat|revoke}} {{GPS|gps}}', + ['rent'] = 'location', + ['sell'] = 'vente', + ['realtors'] = 'agents Immobilier', + +} \ No newline at end of file From 235a2636521dfd711e781de5c6cca5e8fe7a07d9 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 15 Aug 2017 18:28:07 -0400 Subject: [PATCH 0375/3224] Update __resource.lua Changed '_script {' to '_scripts' --- __resource.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/__resource.lua b/__resource.lua index 024bfe07..a061ec00 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,4 +1,4 @@ -server_script{ +server_scripts { '@es_extended/locale.lua', 'locales/en.lua', 'locales/fr.lua', @@ -6,7 +6,7 @@ server_script{ 'server/esx_atm_sv.lua' } -client_script{ +client_scripts { '@es_extended/locale.lua', 'locales/en.lua', 'locales/fr.lua', @@ -16,10 +16,10 @@ client_script{ ui_page 'html/ui.html' -files{ +files { 'html/ui.html', 'html/pdown.ttf', 'html/img/cursor.png', 'html/css/app.css', 'html/scripts/app.js' -} \ No newline at end of file +} From 917da362b85eeb7918ebde2ac9dff302221d3512 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 15 Aug 2017 19:28:06 -0400 Subject: [PATCH 0376/3224] Multi-language support --- __resource.lua | 22 +++++++-- client/esx_drugs_cl.lua | 18 ++++---- config.lua | 1 + locales/en.lua | 29 ++++++++++++ locales/fr.lua | 29 ++++++++++++ server/esx_drugs_sv.lua | 98 ++++++++++++++++++++--------------------- 6 files changed, 135 insertions(+), 62 deletions(-) create mode 100644 locales/en.lua create mode 100644 locales/fr.lua diff --git a/__resource.lua b/__resource.lua index 12628236..47bf7078 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,7 +1,21 @@ description 'esx_drugs' -server_script 'server/esx_drugs_sv.lua' -server_script 'config.lua' +server_scripts { -client_script 'config.lua' -client_script 'client/esx_drugs_cl.lua' \ No newline at end of file + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', + 'server/esx_drugs_sv.lua', + 'config.lua' + +} + +client_scripts { + + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', + 'config.lua', + 'client/esx_drugs_cl.lua' + +} \ No newline at end of file diff --git a/client/esx_drugs_cl.lua b/client/esx_drugs_cl.lua index 1eafc49f..001da77a 100644 --- a/client/esx_drugs_cl.lua +++ b/client/esx_drugs_cl.lua @@ -43,7 +43,7 @@ AddEventHandler('esx_drugs:hasEnteredMarker', function(zone) if zone == 'CokeFarm' then if myJob ~= "police" then CurrentAction = 'coke_harvest' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour récolter la coke' + CurrentActionMsg = _U('press_collect_coke') CurrentActionData = {} end end @@ -52,7 +52,7 @@ AddEventHandler('esx_drugs:hasEnteredMarker', function(zone) if myJob ~= "police" then if cokeQTE >= 5 then CurrentAction = 'coke_treatment' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour traiter la coke' + CurrentActionMsg = _U('press_process_coke') CurrentActionData = {} end end @@ -62,7 +62,7 @@ AddEventHandler('esx_drugs:hasEnteredMarker', function(zone) if myJob ~= "police" then if coke_poochQTE >= 1 then CurrentAction = 'coke_resell' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour vendre la coke' + CurrentActionMsg = _U('press_sell_coke') CurrentActionData = {} end end @@ -71,7 +71,7 @@ AddEventHandler('esx_drugs:hasEnteredMarker', function(zone) if zone == 'MethFarm' then if myJob ~= "police" then CurrentAction = 'meth_harvest' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour récolter la meth' + CurrentActionMsg = _U('press_collect_meth') CurrentActionData = {} end end @@ -80,7 +80,7 @@ AddEventHandler('esx_drugs:hasEnteredMarker', function(zone) if myJob ~= "police" then if methQTE >= 5 then CurrentAction = 'meth_treatment' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour traiter la meth' + CurrentActionMsg = _U('press_process_meth') CurrentActionData = {} end end @@ -90,7 +90,7 @@ AddEventHandler('esx_drugs:hasEnteredMarker', function(zone) if myJob ~= "police" then if meth_poochQTE >= 1 then CurrentAction = 'meth_resell' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour vendre la meth' + CurrentActionMsg = _U('press_sell_meth') CurrentActionData = {} end end @@ -99,7 +99,7 @@ AddEventHandler('esx_drugs:hasEnteredMarker', function(zone) if zone == 'WeedFarm' then if myJob ~= "police" then CurrentAction = 'weed_harvest' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour récolter la weed' + CurrentActionMsg = _U('press_collect_weed') CurrentActionData = {} end end @@ -108,7 +108,7 @@ AddEventHandler('esx_drugs:hasEnteredMarker', function(zone) if myJob ~= "police" then if weedQTE >= 5 then CurrentAction = 'weed_treatment' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour traiter la weed' + CurrentActionMsg = _U('press_process_weed') CurrentActionData = {} end end @@ -118,7 +118,7 @@ AddEventHandler('esx_drugs:hasEnteredMarker', function(zone) if myJob ~= "police" then if weed_poochQTE >= 1 then CurrentAction = 'weed_resell' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour vendre la weed' + CurrentActionMsg = _U('press_sell_weed') CurrentActionData = {} end end diff --git a/config.lua b/config.lua index 6699d8ca..f277af23 100644 --- a/config.lua +++ b/config.lua @@ -6,6 +6,7 @@ Config.ZoneSize = {x = 5.0, y = 5.0, z = 3.0} Config.RequiredCopsCoke = 2 Config.RequiredCopsMeth = 2 Config.RequiredCopsWeed = 0 +Config.Locale = 'fr' Config.Zones = { CokeFarm = {x=2448.9228515625, y=-1836.8076171875, z=51.953701019287}, diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..a3013aaa --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,29 @@ +Locales['en'] = { + + ['press_collect_coke'] = 'press ~INPUT_CONTEXT~ to collect coke', + ['press_process_coke'] = 'press ~INPUT_CONTEXT~ to process coke', + ['press_sell_coke'] = 'press ~INPUT_CONTEXT~ to sell coke', + ['press_collect_meth'] = 'press ~INPUT_CONTEXT~ to collect meth', + ['press_process_meth'] = 'press ~INPUT_CONTEXT~ to process meth', + ['press_sell_meth'] = 'press ~INPUT_CONTEXT~ to sell meth', + ['press_collect_weed'] = 'press ~INPUT_CONTEXT~ to collect weed', + ['press_process_weed'] = 'press ~INPUT_CONTEXT~ to process weed', + ['press_sell_weed'] = 'press ~INPUT_CONTEXT~ to sell weed', + ['act_imp_police'] = 'action ~r~impossible~s~, ~b~police~s~: ', + ['inv_full_coke'] = 'you can no longer collect Cocaine, your inventory is ~r~full~s~', + ['pickup_in_prog'] = '~y~Pickup in progress~s~...', + ['too_many_pouches'] = 'you have too many pouches', + ['not_enough_coke'] = 'you do not have enough coca leaf to ~r~pack~s~', + ['packing_in_prog'] = '~y~Packaging in progress~s~...', + ['no_pouchs_sale'] = 'You have no more pouches for ~r~sale~s~', + ['sold_one_coke'] = 'you\'ve sold ~g~x1 Coke Pouch~s~', + ['sale_in_prog'] = '~g~Sale in progress~s~...', + ['inv_full_meth'] = 'you can no longer collect Meth, your inventory is ~r~full~s~', + ['not_enough_meth'] = 'you do not have enough Meth to ~r~pack~s~', + ['sold_one_meth'] = 'you\'ve sold ~g~x1 Meth Pouch~s~', + ['inv_full_weed'] = 'you can no longer collect Weed, your inventory is ~r~full~s~', + ['not_enough_weed'] = 'you do not have enough Weed to ~r~pack~s~', + ['sold_one_weed'] = 'you\'ve sold ~g~x1 Weed Pouch~s~', + ['used_one_weed'] = 'you used 1 pouch of ~b~weed', + +} \ No newline at end of file diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..e182eb55 --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,29 @@ +Locales['fr'] = { + + ['press_collect_coke'] = 'appuyez sur ~INPUT_CONTEXT~ pour récolter la coke', + ['press_process_coke'] = 'appuyez sur ~INPUT_CONTEXT~ pour traiter la coke', + ['press_sell_coke'] = 'appuyez sur ~INPUT_CONTEXT~ pour vendre la coke', + ['press_collect_meth'] = 'appuyez sur ~INPUT_CONTEXT~ pour récolter la meth', + ['press_process_meth'] = 'appuyez sur ~INPUT_CONTEXT~ pour traiter la meth', + ['press_sell_meth'] = 'appuyez sur ~INPUT_CONTEXT~ pour vendre la meth', + ['press_collect_weed'] = 'appuyez sur ~INPUT_CONTEXT~ pour récolter la weed', + ['press_process_weed'] = 'appuyez sur ~INPUT_CONTEXT~ pour traiter la weed', + ['press_sell_weed'] = 'appuyez sur ~INPUT_CONTEXT~ pour vendre la weed', + ['act_imp_police'] = 'action ~r~impossible~s~, ~b~policiers~s~: ', + ['inv_full_coke'] = 'vous ne pouvez plus ramasser de Cocaine, votre inventaire est ~r~plein~s~', + ['pickup_in_prog'] = '~y~Ramassage en cours~s~...', + ['too_many_pouches'] = 'vous avez trop de pochons', + ['not_enough_coke'] = 'vous n\'avez pas assez de feuille de coca à ~r~conditionner~s~', + ['packing_in_prog'] = '~y~Conditonnement en cours~s~...', + ['no_pouches_sale'] = 'vous n\'avez plus de pochons à ~r~vendre~s~', + ['sold_one_coke'] = 'vous avez vendu ~g~x1 Pochon de coke~s~', + ['sale_in_prog'] = '~g~Vente en cours~s~...', + ['inv_full_meth'] = 'vous ne pouvez plus ramasser de Meth, votre inventaire est ~r~plein~s~', + ['not_enough_meth'] = 'vous n\'avez pas assez de Meth à ~r~conditionner~s~', + ['sold_one_meth'] = 'vous avez vendu ~g~x1 Pochon de meth~s~', + ['inv_full_weed'] = 'vous ne pouvez plus ramasser de weed, votre inventair est ~r~plein~s~', + ['not_enough_weed'] = 'vous n\'avez pas assez de weed à ~r~conditionner~s~', + ['sold_one_weed'] = 'vous avez vendu ~g~x1 Pochon de weed~s~', + ['used_one_weed'] = 'Vous avez utilisé 1 Pochon de ~b~weed', + +} \ No newline at end of file diff --git a/server/esx_drugs_sv.lua b/server/esx_drugs_sv.lua index 87cbff66..867a0bc5 100644 --- a/server/esx_drugs_sv.lua +++ b/server/esx_drugs_sv.lua @@ -33,7 +33,7 @@ CountCops() local function HarvestCoke(source) if CopsConnected < Config.RequiredCopsCoke then - TriggerClientEvent('esx:showNotification', source, 'Action ~r~impossible~s~, ~b~policiers~s~: ' .. CopsConnected .. '/' .. Config.RequiredCopsCoke) + TriggerClientEvent('esx:showNotification', source, _U('act_imp_police') .. CopsConnected .. '/' .. Config.RequiredCopsCoke) return end @@ -46,7 +46,7 @@ local function HarvestCoke(source) local coke = xPlayer.getInventoryItem('coke') if coke.limit ~= -1 and coke.count >= coke.limit then - TriggerClientEvent('esx:showNotification', source, 'Vous ne pouvez plus ramasser de Cocaine, votre inventaire est ~r~plein~s~') + TriggerClientEvent('esx:showNotification', source, _U('inv_full_coke')) else xPlayer.addInventoryItem('coke', 1) HarvestCoke(source) @@ -63,7 +63,7 @@ AddEventHandler('esx_drugs:startHarvestCoke', function() PlayersHarvestingCoke[_source] = true - TriggerClientEvent('esx:showNotification', _source, '~y~Ramassage en cours~s~...') + TriggerClientEvent('esx:showNotification', _source, _U('pickup_in_prog')) HarvestCoke(source) @@ -81,7 +81,7 @@ end) local function TransformCoke(source) if CopsConnected < Config.RequiredCopsCoke then - TriggerClientEvent('esx:showNotification', source, 'Action ~r~impossible~s~, ~b~policiers~s~: ' .. CopsConnected .. '/' .. Config.RequiredCopsCoke) + TriggerClientEvent('esx:showNotification', source, _U('act_imp_police') .. CopsConnected .. '/' .. Config.RequiredCopsCoke) return end @@ -95,9 +95,9 @@ local function TransformCoke(source) local poochQuantity = xPlayer.getInventoryItem('coke_pooch').count if poochQuantity > 35 then - TriggerClientEvent('esx:showNotification', source, 'Vous avez trop de pochons') + TriggerClientEvent('esx:showNotification', source, _U('too_many_pouches')) elseif cokeQuantity < 5 then - TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez pas assez de feuille de coca à ~r~conditionner~s~') + TriggerClientEvent('esx:showNotification', source, _U('not_enough_coke')) else xPlayer.removeInventoryItem('coke', 5) xPlayer.addInventoryItem('coke_pooch', 1) @@ -116,7 +116,7 @@ AddEventHandler('esx_drugs:startTransformCoke', function() PlayersTransformingCoke[_source] = true - TriggerClientEvent('esx:showNotification', _source, '~y~Conditonnement en cours~s~...') + TriggerClientEvent('esx:showNotification', _source, _U('packing_in_prog')) TransformCoke(source) @@ -134,7 +134,7 @@ end) local function SellCoke(source) if CopsConnected < Config.RequiredCopsCoke then - TriggerClientEvent('esx:showNotification', source, 'Action ~r~impossible~s~, ~b~policiers~s~: ' .. CopsConnected .. '/' .. Config.RequiredCopsCoke) + TriggerClientEvent('esx:showNotification', source, _U('act_imp_police') .. CopsConnected .. '/' .. Config.RequiredCopsCoke) return end @@ -147,27 +147,27 @@ local function SellCoke(source) local poochQuantity = xPlayer.getInventoryItem('coke_pooch').count if poochQuantity == 0 then - TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez plus de pochons à ~r~vendre~s~') + TriggerClientEvent('esx:showNotification', source, _U('no_pouches_sale')) else xPlayer.removeInventoryItem('coke_pooch', 1) if CopsConnected == 0 then xPlayer.addAccountMoney('black_money', 198) - TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de coke~s~') + TriggerClientEvent('esx:showNotification', source, _U('sold_one_coke')) elseif CopsConnected == 1 then xPlayer.addAccountMoney('black_money', 258) - TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de coke~s~') + TriggerClientEvent('esx:showNotification', source, _U('sold_one_coke')) elseif CopsConnected == 2 then xPlayer.addAccountMoney('black_money', 308) - TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de coke~s~') + TriggerClientEvent('esx:showNotification', source, _U('sold_one_coke')) elseif CopsConnected == 3 then xPlayer.addAccountMoney('black_money', 358) - TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de coke~s~') + TriggerClientEvent('esx:showNotification', source, _U('sold_one_coke')) elseif CopsConnected == 4 then xPlayer.addAccountMoney('black_money', 396) - TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de coke~s~') + TriggerClientEvent('esx:showNotification', source, _U('sold_one_coke')) elseif CopsConnected >= 5 then xPlayer.addAccountMoney('black_money', 428) - TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de coke~s~') + TriggerClientEvent('esx:showNotification', source, _U('sold_one_coke')) end SellCoke(source) @@ -184,7 +184,7 @@ AddEventHandler('esx_drugs:startSellCoke', function() PlayersSellingCoke[_source] = true - TriggerClientEvent('esx:showNotification', _source, '~g~Vente en cours~s~...') + TriggerClientEvent('esx:showNotification', _source, _U('sale_in_prog')) SellCoke(source) @@ -202,7 +202,7 @@ end) local function HarvestMeth(source) if CopsConnected < Config.RequiredCopsMeth then - TriggerClientEvent('esx:showNotification', source, 'Action ~r~impossible~s~, ~b~policiers~s~: ' .. CopsConnected .. '/' .. Config.RequiredCopsMeth) + TriggerClientEvent('esx:showNotification', source, _U('act_imp_police') .. CopsConnected .. '/' .. Config.RequiredCopsMeth) return end @@ -215,7 +215,7 @@ local function HarvestMeth(source) local meth = xPlayer.getInventoryItem('meth') if meth.limit ~= -1 and meth.count >= meth.limit then - TriggerClientEvent('esx:showNotification', source, 'Vous ne pouvez plus ramasser de Meth, votre inventaire est ~r~plein~s~') + TriggerClientEvent('esx:showNotification', source, _U('inv_full_meth')) else xPlayer.addInventoryItem('meth', 1) HarvestMeth(source) @@ -232,7 +232,7 @@ AddEventHandler('esx_drugs:startHarvestMeth', function() PlayersHarvestingMeth[_source] = true - TriggerClientEvent('esx:showNotification', _source, '~y~Ramassage en cours~s~...') + TriggerClientEvent('esx:showNotification', _source, _U('pickup_in_prog')) HarvestMeth(source) @@ -250,7 +250,7 @@ end) local function TransformMeth(source) if CopsConnected < Config.RequiredCopsMeth then - TriggerClientEvent('esx:showNotification', source, 'Action ~r~impossible~s~, ~b~policiers~s~: ' .. CopsConnected .. '/' .. Config.RequiredCopsMeth) + TriggerClientEvent('esx:showNotification', source, _U('act_imp_police') .. CopsConnected .. '/' .. Config.RequiredCopsMeth) return end @@ -264,9 +264,9 @@ local function TransformMeth(source) local pochonQuantity = xPlayer.getInventoryItem('meth_pooch').count if pochonQuantity > 35 then - TriggerClientEvent('esx:showNotification', source, 'Vous avez trop de pochons') + TriggerClientEvent('esx:showNotification', source, _U('too_many_pouches')) elseif methQuantity < 5 then - TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez pas assez de Meth à ~r~conditionner~s~') + TriggerClientEvent('esx:showNotification', source, _U('not_enough_meth')) else xPlayer.removeInventoryItem('meth', 5) xPlayer.addInventoryItem('meth_pochon', 1) @@ -285,7 +285,7 @@ AddEventHandler('esx_drugs:startTransformMeth', function() PlayersTransformingMeth[_source] = true - TriggerClientEvent('esx:showNotification', _source, '~y~Conditonnement en cours~s~...') + TriggerClientEvent('esx:showNotification', _source, _U('packing_in_prog')) TransformMeth(source) @@ -303,7 +303,7 @@ end) local function SellMeth(source) if CopsConnected < Config.RequiredCopsMeth then - TriggerClientEvent('esx:showNotification', source, 'Action ~r~impossible~s~, ~b~policiers~s~: ' .. CopsConnected .. '/' .. Config.RequiredCopsMeth) + TriggerClientEvent('esx:showNotification', source, _U('act_imp_police') .. CopsConnected .. '/' .. Config.RequiredCopsMeth) return end @@ -316,30 +316,30 @@ local function SellMeth(source) local pochonQuantity = xPlayer.getInventoryItem('meth_pooch').count if pochonQuantity == 0 then - TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez plus de pochons à ~r~vendre~s~') + TriggerClientEvent('esx:showNotification', source, _U('no_pouches_sale')) else xPlayer.removeInventoryItem('meth_pochon', 1) if CopsConnected == 0 then xPlayer.addAccountMoney('black_money', 276) - TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de meth~s~') + TriggerClientEvent('esx:showNotification', source, _U('sold_one_meth')) elseif CopsConnected == 1 then xPlayer.addAccountMoney('black_money', 374) - TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de meth~s~') + TriggerClientEvent('esx:showNotification', source, _U('sold_one_meth')) elseif CopsConnected == 2 then xPlayer.addAccountMoney('black_money', 474) - TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de meth~s~') + TriggerClientEvent('esx:showNotification', source, _U('sold_one_meth')) elseif CopsConnected == 3 then xPlayer.addAccountMoney('black_money', 552) - TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de meth~s~') + TriggerClientEvent('esx:showNotification', source, _U('sold_one_meth')) elseif CopsConnected == 4 then xPlayer.addAccountMoney('black_money', 616) - TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de meth~s~') + TriggerClientEvent('esx:showNotification', source, _U('sold_one_meth')) elseif CopsConnected == 5 then xPlayer.addAccountMoney('black_money', 654) - TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de meth~s~') + TriggerClientEvent('esx:showNotification', source, _U('sold_one_meth')) elseif CopsConnected >= 6 then xPlayer.addAccountMoney('black_money', 686) - TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de meth~s~') + TriggerClientEvent('esx:showNotification', source, _U('sold_one_meth')) end SellMeth(source) @@ -356,7 +356,7 @@ AddEventHandler('esx_drugs:startSellMeth', function() PlayersSellingMeth[_source] = true - TriggerClientEvent('esx:showNotification', _source, '~g~Vente en cours~s~...') + TriggerClientEvent('esx:showNotification', _source, _U('sale_in_prog')) SellMeth(source) @@ -374,7 +374,7 @@ end) local function HarvestWeed(source) if CopsConnected < Config.RequiredCopsWeed then - TriggerClientEvent('esx:showNotification', source, 'Action ~r~impossible~s~, ~b~policiers~s~: ' .. CopsConnected .. '/' .. Config.RequiredCopsWeed) + TriggerClientEvent('esx:showNotification', source, _U('act_imp_police') .. CopsConnected .. '/' .. Config.RequiredCopsWeed) return end @@ -387,7 +387,7 @@ local function HarvestWeed(source) local weed = xPlayer.getInventoryItem('weed') if weed.limit ~= -1 and weed.count >= weed.limit then - TriggerClientEvent('esx:showNotification', source, 'Vous ne pouvez plus ramasser de weed, votre inventaire est ~r~plein~s~') + TriggerClientEvent('esx:showNotification', source, _U('inv_full_weed')) else xPlayer.addInventoryItem('weed', 1) HarvestWeed(source) @@ -404,7 +404,7 @@ AddEventHandler('esx_drugs:startHarvestWeed', function() PlayersHarvestingWeed[_source] = true - TriggerClientEvent('esx:showNotification', _source, '~y~Ramassage en cours~s~...') + TriggerClientEvent('esx:showNotification', _source, _U('pickup_in_prog')) HarvestWeed(source) @@ -422,7 +422,7 @@ end) local function TransformWeed(source) if CopsConnected < Config.RequiredCopsWeed then - TriggerClientEvent('esx:showNotification', source, 'Action ~r~impossible~s~, ~b~policiers~s~: ' .. CopsConnected .. '/' .. Config.RequiredCopsWeed) + TriggerClientEvent('esx:showNotification', source, _U('act_imp_police') .. CopsConnected .. '/' .. Config.RequiredCopsWeed) return end @@ -436,9 +436,9 @@ local function TransformWeed(source) local poochQuantity = xPlayer.getInventoryItem('weed_pooch').count if poochQuantity > 35 then - TriggerClientEvent('esx:showNotification', source, 'Vous avez trop de pochons') + TriggerClientEvent('esx:showNotification', source, _U('too_many_pouches')) elseif weedQuantity < 5 then - TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez pas assez de weed à ~r~conditionner~s~') + TriggerClientEvent('esx:showNotification', source, _U('not_enough_weed')) else xPlayer.removeInventoryItem('weed', 5) xPlayer.addInventoryItem('weed_pooch', 1) @@ -457,7 +457,7 @@ AddEventHandler('esx_drugs:startTransformWeed', function() PlayersTransformingWeed[_source] = true - TriggerClientEvent('esx:showNotification', _source, '~y~Conditonnement en cours~s~...') + TriggerClientEvent('esx:showNotification', _source, _U('packing_in_prog')) TransformWeed(source) @@ -475,7 +475,7 @@ end) local function SellWeed(source) if CopsConnected < Config.RequiredCopsWeed then - TriggerClientEvent('esx_weedjob:showNotification', source, 'Action ~r~impossible~s~, ~b~policiers~s~: ' .. CopsConnected .. '/' .. Config.RequiredCopsWeed) + TriggerClientEvent('esx_weedjob:showNotification', source, _U('act_imp_police') .. CopsConnected .. '/' .. Config.RequiredCopsWeed) return end @@ -488,24 +488,24 @@ local function SellWeed(source) local poochQuantity = xPlayer.getInventoryItem('weed_pooch').count if poochQuantity == 0 then - TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez plus de pochons à ~r~vendre~s~') + TriggerClientEvent('esx:showNotification', source, _U('no_pouches_sale')) else xPlayer:removeInventoryItem('weed_pooch', 1) if CopsConnected == 0 then xPlayer.addAccountMoney('black_money', 108) - TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de weed~s~') + TriggerClientEvent('esx:showNotification', source, _U('sold_one_weed')) elseif CopsConnected == 1 then xPlayer.addAccountMoney('black_money', 128) - TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de weed~s~') + TriggerClientEvent('esx:showNotification', source, _U('sold_one_weed')) elseif CopsConnected == 2 then xPlayer.addAccountMoney('black_money', 152) - TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de weed~s~') + TriggerClientEvent('esx:showNotification', source, _U('sold_one_weed')) elseif CopsConnected == 3 then xPlayer.addAccountMoney('black_money', 165) - TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de weed~s~') + TriggerClientEvent('esx:showNotification', source, _U('sold_one_weed')) elseif CopsConnected >= 4 then xPlayer.addAccountMoney('black_money', 180) - TriggerClientEvent('esx:showNotification', source, 'Vous avez vendu ~g~x1 Pochon de weed~s~') + TriggerClientEvent('esx:showNotification', source, _U('sold_one_weed')) end SellWeed(source) @@ -522,7 +522,7 @@ AddEventHandler('esx_drugs:startSellWeed', function() PlayersSellingWeed[_source] = true - TriggerClientEvent('esx:showNotification', _source, '~g~Vente en cours~s~...') + TriggerClientEvent('esx:showNotification', _source, _U('sale_in_prog')) SellWeed(source) @@ -556,6 +556,6 @@ ESX.RegisterUsableItem('weed', function(source) xPlayer.removeInventoryItem('weed', 1) TriggerClientEvent('esx_drugs:onPot', _source) - TriggerClientEvent('esx:showNotification', _source, 'Vous avez utilisé 1 de ~b~Weed') + TriggerClientEvent('esx:showNotification', _source, _U('used_one_weed')) end) \ No newline at end of file From 8b8fcb532f377bb7e1e5ce8560020221b4829145 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 15 Aug 2017 21:22:19 -0400 Subject: [PATCH 0377/3224] Multi-language support --- __resource.lua | 6 ++++++ config.lua | 3 ++- locales/en.lua | 6 ++++++ locales/fr.lua | 6 ++++++ server/main.lua | 12 ++++++------ 5 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 locales/en.lua create mode 100644 locales/fr.lua diff --git a/__resource.lua b/__resource.lua index 70b8e086..c5f72096 100644 --- a/__resource.lua +++ b/__resource.lua @@ -3,11 +3,17 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ESX Basic Needs' server_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', 'config.lua', 'server/main.lua' } client_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', 'config.lua', 'client/main.lua' } diff --git a/config.lua b/config.lua index db3c2fca..673e6276 100644 --- a/config.lua +++ b/config.lua @@ -1,4 +1,5 @@ Config = {} +Config.Locale = 'fr' Config.TickTime = 100 -Config.UpdateClientTime = 5000 \ No newline at end of file +Config.UpdateClientTime = 5000 diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..f5e83c22 --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,6 @@ +Locales['en'] = { + + ['used_bread'] = 'you have used 1x bread', + ['used_water'] = 'you have used 1x water', + +} diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..3cdfd767 --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,6 @@ +Locales['fr'] = { + + ['used_bread'] = 'vous avez utilisé 1x pain', + ['used_water'] = 'vous avez utilisé 1x eau', + +} diff --git a/server/main.lua b/server/main.lua index ac790c30..09655337 100644 --- a/server/main.lua +++ b/server/main.lua @@ -2,7 +2,7 @@ ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) -TriggerEvent('esx_status:registerStatus', 'hunger', 1000000, '#CFAD0F', +TriggerEvent('esx_status:registerStatus', 'hunger', 1000000, '#CFAD0F', function(status) return true end, @@ -12,7 +12,7 @@ TriggerEvent('esx_status:registerStatus', 'hunger', 1000000, '#CFAD0F', {remove = 200} ) -TriggerEvent('esx_status:registerStatus', 'thirst', 1000000, '#0C98F1', +TriggerEvent('esx_status:registerStatus', 'thirst', 1000000, '#0C98F1', function(status) return true end, @@ -50,9 +50,9 @@ ESX.RegisterUsableItem('bread', function(source) status.add(200000) status.updateClient() - + TriggerClientEvent('esx_basicneeds:onEat', _source) - TriggerClientEvent('esx:showNotification', _source, 'Vous avez utilisé 1x pain') + TriggerClientEvent('esx:showNotification', _source, _U('used_bread')) end) @@ -71,8 +71,8 @@ ESX.RegisterUsableItem('water', function(source) status.updateClient() TriggerClientEvent('esx_basicneeds:onDrink', _source) - TriggerClientEvent('esx:showNotification', _source, 'Vous avez utilisé 1x Eau') + TriggerClientEvent('esx:showNotification', _source, _U('used_water')) end) -end) \ No newline at end of file +end) From 8ac2871af9875f78178ba36523caa45024689d62 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 15 Aug 2017 21:38:47 -0400 Subject: [PATCH 0378/3224] Multi-language support --- __resource.lua | 10 ++++++++-- client/main.lua | 42 +++++++++++++++++++++--------------------- config.lua | 5 +++-- locales/en.lua | 9 +++++++++ locales/fr.lua | 9 +++++++++ server/main.lua | 12 ++++++------ 6 files changed, 56 insertions(+), 31 deletions(-) create mode 100644 locales/en.lua create mode 100644 locales/fr.lua diff --git a/__resource.lua b/__resource.lua index 47caca54..539fbeb3 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,12 +1,18 @@ -description 'ESX Mecano Job' +description 'ESX Shops' client_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', 'config.lua', 'client/main.lua' } server_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', '@mysql-async/lib/MySQL.lua', 'config.lua', 'server/main.lua' -} \ No newline at end of file +} diff --git a/client/main.lua b/client/main.lua index fe65c57f..733a499c 100644 --- a/client/main.lua +++ b/client/main.lua @@ -4,7 +4,7 @@ local LastZone = nil local CurrentAction = nil local CurrentActionMsg = '' local CurrentActionData = {} - + Citizen.CreateThread(function() while ESX == nil do TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) @@ -13,7 +13,7 @@ Citizen.CreateThread(function() end) AddEventHandler('onClientMapStart', function() - + ESX.TriggerServerCallback('esx_shop:requestDBItems', function(ShopItems) for k,v in pairs(ShopItems) do Config.Zones[k].Items = v @@ -45,27 +45,27 @@ function OpenShopMenu(zone) ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'shop', { - title = 'Magasin', + title = _U('shop'), elements = elements }, - function(data, menu) + function(data, menu) TriggerServerEvent('esx_shop:buyItem', data.current.value, data.current.price) end, function(data, menu) - + menu.close() - + CurrentAction = 'shop_menu' - CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au magasin.' + CurrentActionMsg = _U('press_menu') CurrentActionData = {zone = zone} end ) end AddEventHandler('esx_shop:hasEnteredMarker', function(zone) - + CurrentAction = 'shop_menu' - CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au magasin.' + CurrentActionMsg = _U('press_menu') CurrentActionData = {zone = zone} end) @@ -88,7 +88,7 @@ Citizen.CreateThread(function() SetBlipColour (blip, 2) SetBlipAsShortRange(blip, true) BeginTextCommandSetBlipName("STRING") - AddTextComponentString("Magasins") + AddTextComponentString(_U('shops')) EndTextCommandSetBlipName(blip) end end @@ -96,15 +96,15 @@ end) -- Display markers Citizen.CreateThread(function() - while true do + while true do Wait(0) - local coords = GetEntityCoords(GetPlayerPed(-1)) + local coords = GetEntityCoords(GetPlayerPed(-1)) for k,v in pairs(Config.Zones) do for i = 1, #v.Pos, 1 do if(Config.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos[i].x, v.Pos[i].y, v.Pos[i].z, true) < Config.DrawDistance) then DrawMarker(Config.Type, v.Pos[i].x, v.Pos[i].y, v.Pos[i].z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.Size.x, Config.Size.y, Config.Size.z, Config.Color.r, Config.Color.g, Config.Color.b, 100, false, true, 2, false, false, false, false) end - end + end end end end) @@ -143,21 +143,21 @@ Citizen.CreateThread(function() while true do Citizen.Wait(0) if CurrentAction ~= nil then - + SetTextComponentFormat('STRING') AddTextComponentString(CurrentActionMsg) DisplayHelpTextFromStringLabel(0, 0, 1, -1) - - if IsControlJustReleased(0, 38) then - + + if IsControlJustReleased(0, 38) then + if CurrentAction == 'shop_menu' then OpenShopMenu(CurrentActionData.zone) end - - CurrentAction = nil - + + CurrentAction = nil + end end end -end) \ No newline at end of file +end) diff --git a/config.lua b/config.lua index 6c7dd251..8fbe526e 100644 --- a/config.lua +++ b/config.lua @@ -4,6 +4,7 @@ Config.DrawDistance = 100 Config.Size = {x = 1.5, y = 1.5, z = 1.5} Config.Color = {r = 0, g = 128, b = 255} Config.Type = 1 +Config.Locale = 'fr' Config.Zones = { @@ -35,7 +36,7 @@ Config.Zones = { {x = -559.906, y = 287.093, z = 82.176} --Bahamamas } }, - + LTDgasoline = { Items = {}, Pos = { @@ -46,4 +47,4 @@ Config.Zones = { {x = 1698.388, y = 4924.404, z = 41.063} } } -} \ No newline at end of file +} diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..35ff8cd0 --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,9 @@ +Locales['en'] = { + + ['shop'] = 'shop', + ['shops'] = 'shops', + ['press_menu'] = 'press ~INPUT_CONTEXT~ to access the store.', + ['bought'] = 'you bought ~b~1x ', + ['not_enough'] = 'you do not ~r~have enough~s~ money.' + +} diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..14e9ca67 --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,9 @@ +Locales['fr'] = { + + ['shop'] = 'magasin', + ['shops'] = 'magasins', + ['press_menu'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder au magasin.', + ['bought'] = 'vous avez acheté ~b~1x ', + ['not_enough'] = 'vous n\'avez ~r~pas assez~s~ d\'argent.', + +} diff --git a/server/main.lua b/server/main.lua index 9d80efbe..4ef9dfcb 100644 --- a/server/main.lua +++ b/server/main.lua @@ -9,10 +9,10 @@ AddEventHandler('onMySQLReady', function() 'SELECT * FROM items', {}, function(result) - + for i=1, #result, 1 do ItemsLabels[result[i].name] = result[i].label - end-- + end-- end ) @@ -25,7 +25,7 @@ ESX.RegisterServerCallback('esx_shop:requestDBItems', function(source, cb) 'SELECT * FROM shops', {}, function(result) - + local shopItems = {} for i=1, #result, 1 do @@ -51,7 +51,7 @@ end) RegisterServerEvent('esx_shop:buyItem') AddEventHandler('esx_shop:buyItem', function(itemName, price) - + local _source = source local xPlayer = ESX.GetPlayerFromId(source) @@ -60,10 +60,10 @@ AddEventHandler('esx_shop:buyItem', function(itemName, price) xPlayer.removeMoney(price) xPlayer.addInventoryItem(itemName, 1) - TriggerClientEvent('esx:showNotification', _source, 'Vous avez acheté ~b~1x ' .. ItemsLabels[itemName]) + TriggerClientEvent('esx:showNotification', _source, _U('bought') .. ItemsLabels[itemName]) else - TriggerClientEvent('esx:showNotification', _source, 'Vous n\'avez ~r~pas assez~s~ d\'argent.') + TriggerClientEvent('esx:showNotification', _source, _U('not_enough')) end end) From 9b317e558217ca02cbfba102330b7a6bf66a2034 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 15 Aug 2017 21:53:10 -0400 Subject: [PATCH 0379/3224] Multi-language support --- __resource.lua | 6 ++++++ config.lua | 3 ++- locales/en.lua | 6 ++++++ locales/fr.lua | 6 ++++++ server/main.lua | 6 +++--- 5 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 locales/en.lua create mode 100644 locales/fr.lua diff --git a/__resource.lua b/__resource.lua index 40b44860..d6d3babb 100644 --- a/__resource.lua +++ b/__resource.lua @@ -3,12 +3,18 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ESX Garage' server_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', '@mysql-async/lib/MySQL.lua', 'config.lua', 'server/main.lua' } client_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', 'config.lua', 'client/main.lua' } diff --git a/config.lua b/config.lua index 234498f1..6cfd1130 100644 --- a/config.lua +++ b/config.lua @@ -5,11 +5,12 @@ Config.MarkerSize = {x = 2.0, y = 2.0, z = 1.0} Config.MarkerColor = {r = 204, g = 204, b = 0} Config.ParkingMarkerSize = {x = 3.0, y = 3.0, z = 2.0} Config.ParkingMarkerColor = {r = 102, g = 102, b = 204} +Config.Locale = 'fr' Config.Zones = {} Config.Garages = { - + MiltonDrive = { IsClosed = true, diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..6c670be0 --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,6 @@ +Locales['en'] = { + + ['veh_released'] = 'vehicle ~g~released', + ['veh_stored'] = 'vehicle ~g~stored', + +} diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..576dfa41 --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,6 @@ +Locales['fr'] = { + + ['veh_released'] = 'véhicule ~g~sorti', + ['veh_stored'] = 'véhicule ~g~rangé', + +} diff --git a/server/main.lua b/server/main.lua index b4d1f90c..458539bb 100644 --- a/server/main.lua +++ b/server/main.lua @@ -16,7 +16,7 @@ AddEventHandler('esx_garage:setParking', function(garage, zone, vehicleProps) ['@garage'] = garage; ['@zone'] = zone }, function(rowsChanged) - TriggerClientEvent('esx:showNotification', xPlayer.source, 'Véhicule ~g~sorti') + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('veh_released')) end ) @@ -30,7 +30,7 @@ AddEventHandler('esx_garage:setParking', function(garage, zone, vehicleProps) ['@zone'] = zone, ['vehicle'] = json.encode(vehicleProps) }, function(rowsChanged) - TriggerClientEvent('esx:showNotification', xPlayer.source, 'Véhicule ~g~rangé') + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('veh_stored')) end ) @@ -64,4 +64,4 @@ ESX.RegisterServerCallback('esx_vehicleshop:getVehiclesInGarage', function(sourc end ) -end) \ No newline at end of file +end) From 4201f4a7359baed13d1ee3e3c18a4279e66e54bd Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 15 Aug 2017 22:39:52 -0400 Subject: [PATCH 0380/3224] Multi-language support --- __resource.lua | 8 +++- client/main.lua | 104 ++++++++++++++++++++++++------------------------ config.lua | 3 +- locales/en.lua | 32 +++++++++++++++ locales/fr.lua | 32 +++++++++++++++ server/main.lua | 16 ++++---- 6 files changed, 133 insertions(+), 62 deletions(-) create mode 100644 locales/en.lua create mode 100644 locales/fr.lua diff --git a/__resource.lua b/__resource.lua index d8e5a59d..83660fa5 100644 --- a/__resource.lua +++ b/__resource.lua @@ -3,11 +3,17 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ESX Taxi Job' client_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', 'config.lua', 'client/main.lua' } server_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', 'config.lua', 'server/main.lua' -} \ No newline at end of file +} diff --git a/client/main.lua b/client/main.lua index 5d5df427..13944ad3 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,10 +1,10 @@ local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 @@ -93,8 +93,8 @@ function ClearCurrentMission() end function StartTaxiJob() - - ShowLoadingPromt('Prise de service : Taxi/Uber', 5000, 3) + + ShowLoadingPromt(_U('taking_service') .. 'Taxi/Uber', 5000, 3) ClearCurrentMission() OnJob = true @@ -102,7 +102,7 @@ function StartTaxiJob() end function StopTaxiJob() - + local playerPed = GetPlayerPed(-1) if IsPedInAnyVehicle(playerPed, false) and CurrentCustomer ~= nil then @@ -126,13 +126,13 @@ end function OpenTaxiActionsMenu() local elements = { - {label = 'Sortir Véhicule', value = 'spawn_vehicle'} + {label = _U('spawn_veh'), value = 'spawn_vehicle'} } if Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.grade_name == 'boss' then - table.insert(elements, {label = 'Retirer argent société', value = 'withdraw_society_money'}) - table.insert(elements, {label = 'Déposer argent ', value = 'deposit_money'}) - table.insert(elements, {label = 'Blanchir argent', value = 'wash_money'}) + table.insert(elements, {label = _U('remove_comp_money'), value = 'withdraw_society_money'}) + table.insert(elements, {label = _U('deposit_money'), value = 'deposit_money'}) + table.insert(elements, {label = _U('launder_money'), value = 'wash_money'}) end ESX.UI.Menu.CloseAll() @@ -173,7 +173,7 @@ function OpenTaxiActionsMenu() else - ESX.ShowNotification('Service complet : ' .. inServiceCount .. '/' .. maxInService) + ESX.ShowNotification(_U('full_service') .. inServiceCount .. '/' .. maxInService) end @@ -188,14 +188,14 @@ function OpenTaxiActionsMenu() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'withdraw_society_money_amount', { - title = 'Montant du retrait' + title = _U('withdraw_amount') }, function(data, menu) local amount = tonumber(data.value) if amount == nil then - ESX.ShowNotification('Montant invalide') + ESX.ShowNotification(_U('amount_invalid')) else menu.close() TriggerServerEvent('esx_society:withdrawMoney', 'taxi', amount) @@ -214,14 +214,14 @@ function OpenTaxiActionsMenu() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'deposit_money_amount', { - title = 'Montant du dépôt' + title = _U('deposit_amount') }, function(data, menu) local amount = tonumber(data.value) if amount == nil then - ESX.ShowNotification('Montant invalide') + ESX.ShowNotification(_U('amount_invalid')) else menu.close() TriggerServerEvent('esx_society:depositMoney', 'taxi', amount) @@ -240,14 +240,14 @@ function OpenTaxiActionsMenu() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'wash_money_amount', { - title = 'Montant à blanchir' + title = _U('launder_amount') }, function(data, menu) local amount = tonumber(data.value) if amount == nil then - ESX.ShowNotification('Montant invalide') + ESX.ShowNotification(_U('amount_invalid')) else menu.close() TriggerServerEvent('esx_society:washMoney', 'taxi', amount) @@ -267,7 +267,7 @@ function OpenTaxiActionsMenu() menu.close() CurrentAction = 'taxi_actions_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('press_to_open') CurrentActionData = {} end @@ -284,7 +284,7 @@ function OpenMobileTaxiActionsMenu() { title = 'Taxi', elements = { - {label = 'Facuration', value = 'billing'} + {label = _U('billing'), value = 'billing'} } }, function(data, menu) @@ -294,22 +294,22 @@ function OpenMobileTaxiActionsMenu() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'billing', { - title = 'Montant de la facture' + title = _U('invoice_amount') }, function(data, menu) local amount = tonumber(data.value) if amount == nil then - ESX.ShowNotification('Montant invalide') + ESX.ShowNotification(_U('amount_invalid')) else - + menu.close() - + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification('Aucun joueur à proximité') + ESX.ShowNotification(_U('no_players_near')) else TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_taxi', 'Taxi', amount) end @@ -346,7 +346,7 @@ AddEventHandler('esx_taxijob:hasEnteredMarker', function(zone) if zone == 'TaxiActions' then CurrentAction = 'taxi_actions_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('press_to_open') CurrentActionData = {} end @@ -356,7 +356,7 @@ AddEventHandler('esx_taxijob:hasEnteredMarker', function(zone) if IsPedInAnyVehicle(playerPed, false) then CurrentAction = 'delete_vehicle' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour ranger le véhicule' + CurrentActionMsg = _U('store_veh') CurrentActionData = {} end @@ -383,7 +383,7 @@ end) -- Create Blips Citizen.CreateThread(function() - + local blip = AddBlipForCoord(Config.Zones.TaxiActions.Pos.x, Config.Zones.TaxiActions.Pos.y, Config.Zones.TaxiActions.Pos.z) SetBlipSprite (blip, 198) @@ -401,13 +401,13 @@ end) -- Display markers Citizen.CreateThread(function() while true do - + Wait(0) - + if PlayerData.job ~= nil and PlayerData.job.name == 'taxi' then local coords = GetEntityCoords(GetPlayerPed(-1)) - + for k,v in pairs(Config.Zones) do if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) @@ -422,9 +422,9 @@ end) -- Enter / Exit marker events Citizen.CreateThread(function() while true do - + Wait(0) - + if PlayerData.job ~= nil and PlayerData.job.name == 'taxi' then local coords = GetEntityCoords(GetPlayerPed(-1)) @@ -467,12 +467,12 @@ Citizen.CreateThread(function() if CurrentCustomer == nil then - DrawSub('Conduisez à la recherche de ~y~passagers', 5000) + DrawSub(_U('drive_search_pass'), 5000) if IsPedInAnyVehicle(playerPed, false) and GetEntitySpeed(playerPed) > 0 then local waitUntil = GetGameTimer() + GetRandomIntInRange(1000, 120000) - + while OnJob and waitUntil > GetGameTimer() do Citizen.Wait(0) end @@ -504,7 +504,7 @@ Citizen.CreateThread(function() TaskStandStill(CurrentCustomer, standTime) - ESX.ShowNotification('Vous avez ~g~trouvé~s~ un client, conduisez jusqu\'à ce dernier') + ESX.ShowNotification(_U('customer_found')) end @@ -514,7 +514,7 @@ Citizen.CreateThread(function() if IsPedFatallyInjured(CurrentCustomer) then - ESX.ShowNotification('Votre client est ~r~inconscient~w~. Cherchez-en un autre.') + ESX.ShowNotification(_U('client_unconcious')) if DoesBlipExist(CurrentCustomerBlip) then RemoveBlip(CurrentCustomerBlip) @@ -542,7 +542,7 @@ Citizen.CreateThread(function() local playerCoords = GetEntityCoords(playerPed) local customerCoords = GetEntityCoords(CurrentCustomer) local customerDistance = GetDistanceBetweenCoords(playerCoords.x, playerCoords.y, playerCoords.z, customerCoords.x, customerCoords.y, customerCoords.z) - + if IsPedSittingInVehicle(CurrentCustomer, vehicle) then if CustomerEnteredVehicle then @@ -553,7 +553,7 @@ Citizen.CreateThread(function() TaskLeaveVehicle(CurrentCustomer, vehicle, 0) - ESX.ShowNotification('Vous êtes ~g~arrivé~s~ à destination') + ESX.ShowNotification(_U('arrive_dest')) TaskGoStraightToCoord(CurrentCustomer, TargetCoords.x, TargetCoords.y, TargetCoords.z, 1.0, -1, 0.0, 0.0) SetEntityAsMissionEntity(CurrentCustomer, false) @@ -586,9 +586,9 @@ Citizen.CreateThread(function() local msg = nil if street[2] ~= 0 and street[2] ~= nil then - msg = string.format("~w~Emmenez-moi à~y~ %s~w~, près de~y~ %s", GetStreetNameFromHashKey(street[1]),GetStreetNameFromHashKey(street[2])) + msg = string.format(_U('take_me_to_near'), GetStreetNameFromHashKey(street[1]),GetStreetNameFromHashKey(street[2])) else - msg = string.format("~w~Emmenez-moi à~y~ %s", GetStreetNameFromHashKey(street[1])) + msg = string.format(_U('take_me_to'), GetStreetNameFromHashKey(street[1])) end ESX.ShowNotification(msg) @@ -616,7 +616,7 @@ Citizen.CreateThread(function() if customerDistance <= 30.0 then if not IsNearCustomer then - ESX.ShowNotification('Vous êtes à proximité du client, approchez-vous de lui') + ESX.ShowNotification(_U('close_to_client')) IsNearCustomer = true end @@ -625,7 +625,7 @@ Citizen.CreateThread(function() if customerDistance <= 10.0 then if not CustomerIsEnteringVehicle then - + ClearPedTasksImmediately(CurrentCustomer) local seat = 0 @@ -638,7 +638,7 @@ Citizen.CreateThread(function() end TaskEnterVehicle(CurrentCustomer, vehicle, -1, seat, 2.0, 1) - + CustomerIsEnteringVehicle = true end @@ -651,7 +651,7 @@ Citizen.CreateThread(function() else - DrawSub('Veuillez remonter dans votre véhicule pour continuer la mission', 5000) + DrawSub(_U('return_to_veh'), 5000) end @@ -675,7 +675,7 @@ Citizen.CreateThread(function() DisplayHelpTextFromStringLabel(0, 0, 1, -1) if IsControlPressed(0, Keys['E']) and PlayerData.job ~= nil and PlayerData.job.name == 'taxi' and (GetGameTimer() - GUI.Time) > 300 then - + if CurrentAction == 'taxi_actions_menu' then OpenTaxiActionsMenu() end @@ -690,17 +690,17 @@ Citizen.CreateThread(function() if Config.MaxInService ~= -1 then TriggerServerEvent('esx_service:disableService', 'taxi') end - + DeleteVehicle(vehicle) else - ESX.ShowNotification('Vous ne pouvez ranger que les taxi') + ESX.ShowNotification(_U('only_taxi')) end end CurrentAction = nil GUI.Time = GetGameTimer() - + end end @@ -730,16 +730,16 @@ Citizen.CreateThread(function() if GetEntityModel(vehicle) == GetHashKey('taxi') then StartTaxiJob() else - ESX.ShowNotification('Vous devez être dans un taxi pour commencer la mission') + ESX.ShowNotification(_U('must_in_taxi')) end end else if PlayerData.job.grade >= 3 then - ESX.ShowNotification('Vous devez être dans un véhicule pour commencer la mission') + ESX.ShowNotification(_U('must_in_vehicle')) else - ESX.ShowNotification('Vous devez être dans un taxi pour commencer la mission') + ESX.ShowNotification(_U('must_in_taxi')) end end @@ -753,4 +753,4 @@ Citizen.CreateThread(function() end end -end) \ No newline at end of file +end) diff --git a/config.lua b/config.lua index 2f19dd8b..343775de 100644 --- a/config.lua +++ b/config.lua @@ -3,6 +3,7 @@ Config.DrawDistance = 100.0 Config.NPCJobEarnings = {min = 15, max = 40} Config.MaxInService = 2 Config.EnablePlayerManagement = false +Config.Locale = 'fr' Config.Zones = { @@ -121,4 +122,4 @@ Config.JobLocations = { {x = -1645.546, y = 144.571, z = 61.664}, {x = -1160.618, y = 744.418, z = 154.571}, {x = -798.09, y = 831.699, z = 204.351}, -} \ No newline at end of file +} diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..3e1d049f --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,32 @@ +Locales['en'] = { + + ['taking_service'] = 'taking service: ', + ['spawn_veh'] = 'spawn vehicle', + ['remove_comp_money'] = 'remove company money', + ['deposit_money'] = 'deposit money', + ['launder_money'] = 'launder money', + ['full_service'] = 'full service: ', + ['withdraw_amount'] = 'amount of withdrawal', + ['amount_invalid'] = 'amount invalid', + ['deposit_amount'] = 'amount to deposit', + ['launder_amount'] = 'amount to launder', + ['press_to_open'] = 'press ~INPUT_CONTEXT~ to access the menu' + ['billing'] = 'billing', + ['invoice_amount'] = 'invoice amount', + ['no_players_near'] = 'no players nearby', + ['store_veh'] = 'press ~INPUT_CONTEXT~ to store the vehicle', + ['drive_search_pass'] = 'driving in search of ~y~passengers', + ['customer_found'] = 'you have ~g~found~s~ a customer, drive until last', + ['client_unconcious'] = 'your client is ~r~unconscious~w~. Look for another one.', + ['arrive_dest'] = 'you have ~g~arrived~s~ at your destination', + ['take_me_to_near'] = '~w~Take me to~y~ %s~w~, near~y~ %s', + ['take_me_to'] = '~w~Take me to~y~ %s', + ['close_to_client'] = 'you are close to the client, get close to them', + ['return_to_veh'] = 'please return to your vehicle to continue the mission', + ['only_taxi'] = 'you can only storee taxis.', + ['must_in_taxi'] = 'you must be in a taxi to start the mission', + ['must_in_vehicle'] = 'you must be in a vehicle to begin the mission', + ['have_earned'] = 'you have earned ~g~$', + ['comp_earned'] = 'your company has earned ~g~$', + +} diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..18347d4f --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,32 @@ +Locales['fr'] = { + + ['taking_service'] = 'prise de service : ', + ['spawn_veh'] = 'vortir véhicule', + ['remove_comp_money'] = 'retirer argent société', + ['deposit_money'] = 'déposer argent', + ['launder_money'] = 'blanchir argent', + ['full_service'] = 'service complet : ', + ['withdraw_amount'] = 'montant du retrait', + ['amount_invalid'] = 'montant invalide', + ['deposit_amount'] = 'montant du dépôt', + ['launder_amount'] = 'montant à blanchir', + ['press_to_open'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder au menu', + ['billing'] = 'facuration', + ['invoice_amount'] = 'montant de la facture', + ['no_players_near'] = 'aucun joueur à proximité', + ['store_veh'] = 'appuyez sur ~INPUT_CONTEXT~ pour ranger le véhicule', + ['drive_search_pass'] = 'conduisez à la recherche de ~y~passagers', + ['customer_found'] = 'vous avez ~g~trouvé~s~ un client, conduisez jusqu\'à ce dernier', + ['client_unconcious'] = 'votre client est ~r~inconscient~w~. Cherchez-en un autre.', + ['arrive_dest'] = 'vous êtes ~g~arrivé~s~ à destination', + ['take_me_to_near'] = '~w~Emmenez-moi à~y~ %s~w~, près de~y~ %s', + ['take_me_to'] = '~w~Emmenez-moi à~y~ %s', + ['close_to_client'] = 'vous êtes à proximité du client, approchez-vous de lui', + ['return_to_veh'] = 'veuillez remonter dans votre véhicule pour continuer la mission', + ['only_taxi'] = 'vous ne pouvez ranger que les taxi', + ['must_in_taxi'] = 'vous devez être dans un taxi pour commencer la mission', + ['must_in_vehicle'] = 'vous devez être dans un véhicule pour commencer la mission', + ['have_earned'] = 'vous avez gagné ~g~$', + ['comp_earned'] = 'votre société a gagné ~g~$', + +} diff --git a/server/main.lua b/server/main.lua index 335362cc..e92e5745 100644 --- a/server/main.lua +++ b/server/main.lua @@ -8,7 +8,7 @@ end RegisterServerEvent('esx_taxijob:success') AddEventHandler('esx_taxijob:success', function() - + local xPlayer = ESX.GetPlayerFromId(source) local total = math.random(Config.NPCJobEarnings.min, Config.NPCJobEarnings.max); local societyAccount = nil @@ -29,16 +29,16 @@ AddEventHandler('esx_taxijob:success', function() xPlayer.addMoney(playerMoney) societyAccount.addMoney(societyMoney) - TriggerClientEvent('esx:showNotification', xPlayer.source, 'Vous avez gagné ~g~$'.. playerMoney) - TriggerClientEvent('esx:showNotification', xPlayer.source, 'Votre société a gagné ~g~$'.. societyMoney) + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('have_earned') .. playerMoney) + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('comp_earned') .. societyMoney) else xPlayer.addMoney(total) - TriggerClientEvent('esx:showNotification', xPlayer.source, 'Vous avez gagné ~g~$'.. total) - + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('have_earned') .. total) + end - + end) TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) @@ -55,5 +55,5 @@ TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message end end end - -end) \ No newline at end of file + +end) From 0c9dd94263dd1158b77be15365f55bfebd8ff2a3 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 15 Aug 2017 22:42:34 -0400 Subject: [PATCH 0381/3224] Translation adjustment --- client/main.lua | 2 +- locales/en.lua | 2 +- locales/fr.lua | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/main.lua b/client/main.lua index 853d98ef..3ec41e19 100644 --- a/client/main.lua +++ b/client/main.lua @@ -115,7 +115,7 @@ function OpenRealestateAgentMenu() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'wash_money_amount', { - title = _U('amount_wash') + title = _U('amount_launder') }, function(data, menu) diff --git a/locales/en.lua b/locales/en.lua index 76658a0f..dc80a778 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -10,7 +10,7 @@ Locales['en'] = { ['amount_withdraw'] = 'amount of withdrawal', ['invalid_amount'] = 'invalid amount', ['amount_deposit'] = 'deposit amount', - ['amount_wash'] = 'amount to bleach', + ['amount_launder'] = 'amount to launder', ['press_to_access'] = 'press ~INPUT_CONTEXT~ to access the menu', ['property_actions'] = '{{Assign [Sell]|sell}} {{Assign [Rent]|rent}} {{GPS|gps}}', ['amount'] = 'amount', diff --git a/locales/fr.lua b/locales/fr.lua index f98c888e..27e43c05 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -10,7 +10,7 @@ Locales['fr'] = { ['amount_withdraw'] = 'montant du retrait', ['invalid_amount'] = 'montant invalide', ['amount_deposit'] = 'montant du dépôt', - ['amount_wash'] = 'montant à blanchir', + ['amount_launder'] = 'montant à blanchir', ['press_to_access'] = 'appuez sur ~INPUT_CONTEXT~ pour accéder au menu', ['property_actions'] = '{{Assigner [Vente]|sell}} {{Assigner [Location]|rent}} {{GPS|gps}}', ['amount'] = 'montant', From 6b1014063c5a422b274e61826764ace8fd6a7103 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 15 Aug 2017 23:00:02 -0400 Subject: [PATCH 0382/3224] Multi-language support --- __resource.lua | 6 ++++++ client/main.lua | 28 ++++++++++++++-------------- config.lua | 2 ++ locales/en.lua | 7 +++++++ locales/fr.lua | 7 +++++++ server/main.lua | 6 +++--- 6 files changed, 39 insertions(+), 17 deletions(-) create mode 100644 config.lua create mode 100644 locales/en.lua create mode 100644 locales/fr.lua diff --git a/__resource.lua b/__resource.lua index ae7fbeac..68e653d5 100644 --- a/__resource.lua +++ b/__resource.lua @@ -3,10 +3,16 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ESX Skin' server_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', '@mysql-async/lib/MySQL.lua', 'server/main.lua' } client_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', 'client/main.lua' } diff --git a/client/main.lua b/client/main.lua index 94e89424..70fd3420 100644 --- a/client/main.lua +++ b/client/main.lua @@ -53,10 +53,10 @@ function OpenMenu(submitCb, cancelCb, restrict) -- Insert elements for i=1, #_components, 1 do - + local value = _components[i].value local componentId = _components[i].componentId - + if componentId == 0 then value = GetPedPropIndex(playerPed, _components[i].componentId) end @@ -89,7 +89,7 @@ function OpenMenu(submitCb, cancelCb, restrict) ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'skin', { - title = 'Skin Menu', + title = _U('skin_menu'), align = 'top-left', elements = elements }, @@ -98,7 +98,7 @@ function OpenMenu(submitCb, cancelCb, restrict) DeleteSkinCam() end, function(data, menu) - + menu.close() DeleteSkinCam() @@ -116,7 +116,7 @@ function OpenMenu(submitCb, cancelCb, restrict) zoomOffset = data.current.zoomOffset camOffset = data.current.camOffset - + if skin[data.current.name] ~= data.current.value then -- Change skin element @@ -124,10 +124,10 @@ function OpenMenu(submitCb, cancelCb, restrict) -- Update max values TriggerEvent('skinchanger:getData', function(components, maxVals) - + for i=1, #elements, 1 do if elements[i].textureof ~= nil then - + local newData = {max = maxVals[elements[i].name]} if data.current.name == elements[i].textureof then @@ -135,7 +135,7 @@ function OpenMenu(submitCb, cancelCb, restrict) end menu.update({name = elements[i].name}, newData) - + end end @@ -219,7 +219,7 @@ Citizen.CreateThread(function() PointCamAtCoord(cam, posToLook.x, posToLook.y, coords.z + camOffset) SetTextComponentFormat("STRING") - AddTextComponentString("Utilisez ~INPUT_VEH_FLY_ROLL_LEFT_ONLY~ et ~INPUT_VEH_FLY_ROLL_RIGHT_ONLY~ pour tourner la vue.") + AddTextComponentString(_U('use_rotate_view')) DisplayHelpTextFromStringLabel(0, 0, 0, -1) end end @@ -305,9 +305,9 @@ AddEventHandler('esx_skin:openSaveableRestrictedMenu', function(submitCb, cancel end) AddEventHandler('skinchanger:modelLoaded', function() - + if not HasLoadedModel then - + Citizen.CreateThread(function() while not PlayerLoaded do @@ -333,9 +333,9 @@ end) Citizen.CreateThread(function() while true do - + Citizen.Wait(0) - + local playerPed = GetPlayerPed(-1) if IsEntityDead(playerPed) then @@ -343,4 +343,4 @@ Citizen.CreateThread(function() end end -end) \ No newline at end of file +end) diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..56a8b5e9 --- /dev/null +++ b/config.lua @@ -0,0 +1,2 @@ +Config = {} +Config.Locale = 'fr' diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..5ea05c28 --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,7 @@ +Locales['en'] = { + + ['skin_menu'] = 'Skin Menu', + ['use_rotate_view'] = 'use ~INPUT_VEH_FLY_ROLL_LEFT_ONLY~ and ~INPUT_VEH_FLY_ROLL_RIGHT_ONLY~ to rotate the view.', + + +} diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..450e67b0 --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,7 @@ +Locales['fr'] = { + + ['skin_menu'] = 'Skin Menu', + ['use_rotate_view'] = 'utilisez ~INPUT_VEH_FLY_ROLL_LEFT_ONLY~ et ~INPUT_VEH_FLY_ROLL_RIGHT_ONLY~ pour tourner la vue.', + + +} diff --git a/server/main.lua b/server/main.lua index 708f9fbb..2e6c464d 100644 --- a/server/main.lua +++ b/server/main.lua @@ -30,7 +30,7 @@ ESX.RegisterServerCallback('esx_skin:getPlayerSkin', function(source, cb) local user = users[1] local skin = nil - + local jobSkin = { skin_male = xPlayer.job.skin_male, skin_female = xPlayer.job.skin_female @@ -51,5 +51,5 @@ end) TriggerEvent('es:addGroupCommand', 'skin', "admin", function(source, args, user) TriggerClientEvent('esx_skin:openSaveableMenu', source) end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, 'Insufficienct permissions!') -end) \ No newline at end of file + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, 'Insufficient permissions!') +end) From 64f61da31e3822450146f3359d62e8d4859a38a8 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 15 Aug 2017 23:17:28 -0400 Subject: [PATCH 0383/3224] Multi-language support --- __resource.lua | 8 +++++++- client/esx_joblisting_cl.lua | 20 ++++++++++---------- config.lua | 1 + locales/en.lua | 7 +++++++ locales/fr.lua | 7 +++++++ 5 files changed, 32 insertions(+), 11 deletions(-) create mode 100644 locales/en.lua create mode 100644 locales/fr.lua diff --git a/__resource.lua b/__resource.lua index 7993f10f..30e27ff6 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,9 +1,15 @@ server_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', '@mysql-async/lib/MySQL.lua', 'server/esx_joblisting_sv.lua' } client_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', 'config.lua', 'client/esx_joblisting_cl.lua' -} \ No newline at end of file +} diff --git a/client/esx_joblisting_cl.lua b/client/esx_joblisting_cl.lua index e782aa7e..2ae6c0a0 100644 --- a/client/esx_joblisting_cl.lua +++ b/client/esx_joblisting_cl.lua @@ -21,7 +21,7 @@ function ShowJobListingMenu(data) local elements = {} for i = 1, #data, 1 do table.insert( - elements, + elements, {label = data[i].label, value = data[i].value} ) end @@ -36,7 +36,7 @@ function ShowJobListingMenu(data) }, function(data, menu) TriggerServerEvent('esx_joblisting:setJob', data.current.value) - ESX.ShowNotification('Vous avez un nouveau job !') + ESX.ShowNotification(_U('new_job')) menu.close() end, function(data, menu) @@ -53,9 +53,9 @@ end) -- Display markers Citizen.CreateThread(function() - while true do - Wait(0) - local coords = GetEntityCoords(GetPlayerPed(-1)) + while true do + Wait(0) + local coords = GetEntityCoords(GetPlayerPed(-1)) for i=1, #Config.Zones, 1 do if(GetDistanceBetweenCoords(coords, Config.Zones[i].x, Config.Zones[i].y, Config.Zones[i].z, true) < Config.DrawDistance) then DrawMarker(Config.MarkerType, Config.Zones[i].x, Config.Zones[i].y, Config.Zones[i].z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.ZoneSize.x, Config.ZoneSize.y, Config.ZoneSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) @@ -66,7 +66,7 @@ end) -- Activate menu when player is inside marker Citizen.CreateThread(function() - while true do + while true do Wait(0) local coords = GetEntityCoords(GetPlayerPed(-1)) isInJoblistingMarker = false @@ -75,7 +75,7 @@ Citizen.CreateThread(function() if(GetDistanceBetweenCoords(coords, Config.Zones[i].x, Config.Zones[i].y, Config.Zones[i].z, true) < Config.ZoneSize.x / 2) then isInJoblistingMarker = true SetTextComponentFormat('STRING') - AddTextComponentString('Appuyez sur ~INPUT_PICKUP~ pour \naccéder au ~b~Pôle Emploi~s~.') + AddTextComponentString(_U('access_job_center')) DisplayHelpTextFromStringLabel(0, 0, 1, -1) end end @@ -92,14 +92,14 @@ end) -- Create blips Citizen.CreateThread(function() for i=1, #Config.Zones, 1 do - local blip = AddBlipForCoord(Config.Zones[i].x, Config.Zones[i].y, Config.Zones[i].z) + local blip = AddBlipForCoord(Config.Zones[i].x, Config.Zones[i].y, Config.Zones[i].z) SetBlipSprite (blip, 407) SetBlipDisplay(blip, 4) SetBlipScale (blip, 1.2) SetBlipColour (blip, 27) SetBlipAsShortRange(blip, true) BeginTextCommandSetBlipName("STRING") - AddTextComponentString("Pôle-Emploi") + AddTextComponentString(_U('job_center')) EndTextCommandSetBlipName(blip) end end) @@ -112,4 +112,4 @@ Citizen.CreateThread(function() ShowJobListingMenu() end end -end) \ No newline at end of file +end) diff --git a/config.lua b/config.lua index 876c8df9..8648b3db 100644 --- a/config.lua +++ b/config.lua @@ -3,6 +3,7 @@ Config.DrawDistance = 100.0 Config.ZoneSize = {x = 3.0, y = 3.0, z = 2.0} Config.MarkerColor = {r = 100, g = 100, b = 204} Config.MarkerType = 1 +Config.Locale = 'fr' Config.Zones = { {x = -265.036, y = -963.630, z = 30.223} diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..a07a80a2 --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,7 @@ +Locales['en'] = { + + ['new_job'] = 'you have a new job!', + ['access_job_center'] = 'press ~INPUT_PICKUP~ to access the ~b~job center~s~.', + ['job_center'] = 'job Center', + +} diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..60217531 --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,7 @@ +Locales['fr'] = { + + ['new_job'] = 'vous avez nouveau job !', + ['access_job_center'] = 'appuyez sur ~INPUT_PICKUP~ pour \naccéder au ~b~Pôle Emploi~s~.', + ['job_center'] = 'pôle-Emploi', + +} From 17d588c2e65530420f0652433b712127d6c4e7e6 Mon Sep 17 00:00:00 2001 From: Don Date: Thu, 17 Aug 2017 00:10:07 -0700 Subject: [PATCH 0384/3224] Fixed SQL, Fixed INPUT_CONTEXT Fixed SQL, Fixed INPUT_CONTEXT, Fixed Readme --- README.md | 2 +- config.lua | 2 +- esx_weashops.sql | 10 +++++----- locales/en.lua | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 284f1eb0..add5c390 100644 --- a/README.md +++ b/README.md @@ -12,5 +12,5 @@ git clone https://github.com/FXServer-ESX/fxserver-esx_weashops.git esx_weashops 4) Add this in your server.cfg : ``` -start esx_shops +start esx_weashops ``` diff --git a/config.lua b/config.lua index e4e843fd..cc22dc28 100644 --- a/config.lua +++ b/config.lua @@ -4,7 +4,7 @@ Config.DrawDistance = 100 Config.Size = {x = 1.5, y = 1.5, z = 1.5} Config.Color = {r = 0, g = 128, b = 255} Config.Type = 1 -Config.Locale = 'en' +Config.Locale = 'fr' Config.Zones = { diff --git a/esx_weashops.sql b/esx_weashops.sql index 15819db8..9e4ef2d2 100644 --- a/esx_weashops.sql +++ b/esx_weashops.sql @@ -6,12 +6,12 @@ CREATE TABLE `weashops` ( `name` varchar(255) NOT NULL, `item` varchar(255) NOT NULL, `price` int(11) NOT NULL, + `label` varchar(255) NOT NULL, PRIMARY KEY (`id`) ); - -INSERT INTO `weashops` (name, item, price) VALUES - ('GunShop','WEAPON_Pistol',300), - ('blackweashop','WEAPON_Pistol',500) -; +INSERT INTO `weashops` (name, item, price, label) VALUES + ('GunShop','WEAPON_Pistol',300, 'pistol'), + ('blackweashop','WEAPON_Pistol',500, 'pistol') +; \ No newline at end of file diff --git a/locales/en.lua b/locales/en.lua index a833c4cf..e52445a0 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -4,7 +4,7 @@ Locales ['en'] = { ['not_enough_black'] = 'you do not have enough dirty money', ['not_enough'] = 'you do not have enough money', ['shop'] = 'shop', - ['shop_menu'] = 'Press ~INPUT_CONTENT~ to access the shop.', + ['shop_menu'] = 'Press ~INPUT_CONTEXT~ to access the shop.', ['map_blip'] = 'gun shop', } \ No newline at end of file From 7e7136498d141e6b1e162067cee25531ea92389b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 16 Aug 2017 11:15:22 +0200 Subject: [PATCH 0385/3224] Fix config + add saveskin command --- __resource.lua | 4 +++- client/main.lua | 7 +++++++ locales/en.lua | 3 ++- locales/fr.lua | 3 ++- server/main.lua | 21 +++++++++++++++++++-- 5 files changed, 33 insertions(+), 5 deletions(-) diff --git a/__resource.lua b/__resource.lua index 68e653d5..3dd25881 100644 --- a/__resource.lua +++ b/__resource.lua @@ -3,10 +3,11 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ESX Skin' server_scripts { + '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', 'locales/en.lua', 'locales/fr.lua', - '@mysql-async/lib/MySQL.lua', + 'config.lua', 'server/main.lua' } @@ -14,5 +15,6 @@ client_scripts { '@es_extended/locale.lua', 'locales/en.lua', 'locales/fr.lua', + 'config.lua', 'client/main.lua' } diff --git a/client/main.lua b/client/main.lua index 70fd3420..f3860f18 100644 --- a/client/main.lua +++ b/client/main.lua @@ -304,6 +304,13 @@ AddEventHandler('esx_skin:openSaveableRestrictedMenu', function(submitCb, cancel OpenSaveableMenu(submitCb, cancelCb, restrict) end) +RegisterNetEvent('esx_skin:requestSaveSkin') +AddEventHandler('esx_skin:requestSaveSkin', function() + TriggerEvent('skinchanger:getSkin', function(skin) + TriggerServerEvent('esx_skin:responseSaveSkin', skin) + end) +end) + AddEventHandler('skinchanger:modelLoaded', function() if not HasLoadedModel then diff --git a/locales/en.lua b/locales/en.lua index 5ea05c28..7609234d 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -2,6 +2,7 @@ Locales['en'] = { ['skin_menu'] = 'Skin Menu', ['use_rotate_view'] = 'use ~INPUT_VEH_FLY_ROLL_LEFT_ONLY~ and ~INPUT_VEH_FLY_ROLL_RIGHT_ONLY~ to rotate the view.', - + ['skin'] = 'change skin', + ['saveskin'] = 'save skin to a file', } diff --git a/locales/fr.lua b/locales/fr.lua index 450e67b0..e20a772e 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -2,6 +2,7 @@ Locales['fr'] = { ['skin_menu'] = 'Skin Menu', ['use_rotate_view'] = 'utilisez ~INPUT_VEH_FLY_ROLL_LEFT_ONLY~ et ~INPUT_VEH_FLY_ROLL_RIGHT_ONLY~ pour tourner la vue.', - + ['skin'] = 'changer de skin', + ['saveskin'] = 'sauvegarder skin dans un fichier', } diff --git a/server/main.lua b/server/main.lua index 2e6c464d..1c259e71 100644 --- a/server/main.lua +++ b/server/main.lua @@ -17,6 +17,17 @@ AddEventHandler('esx_skin:save', function(skin) end) +RegisterServerEvent('esx_skin:responseSaveSkin') +AddEventHandler('esx_skin:responseSaveSkin', function(skin) + + local file = io.open('resources/[esx]/esx_skin/skins.txt', "a") + + file:write(json.encode(skin) .. "\n\n") + file:flush() + file:close() + +end) + ESX.RegisterServerCallback('esx_skin:getPlayerSkin', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) @@ -48,8 +59,14 @@ ESX.RegisterServerCallback('esx_skin:getPlayerSkin', function(source, cb) end) -- Commands -TriggerEvent('es:addGroupCommand', 'skin', "admin", function(source, args, user) +TriggerEvent('es:addGroupCommand', 'skin', 'admin', function(source, args, user) TriggerClientEvent('esx_skin:openSaveableMenu', source) end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, 'Insufficient permissions!') -end) +end, {help = _U('skin')}) + +TriggerEvent('es:addGroupCommand', 'saveskin', 'admin', function(source, args, user) + TriggerClientEvent('esx_skin:requestSaveSkin', source) +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end, {help = _U('saveskin')}) \ No newline at end of file From 2ff5d6f680099f6501073f9ae3fa8531efb6cc48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 16 Aug 2017 11:16:01 +0200 Subject: [PATCH 0386/3224] Fix locale file --- locales/en.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/en.lua b/locales/en.lua index 3e1d049f..754bf8af 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -10,7 +10,7 @@ Locales['en'] = { ['amount_invalid'] = 'amount invalid', ['deposit_amount'] = 'amount to deposit', ['launder_amount'] = 'amount to launder', - ['press_to_open'] = 'press ~INPUT_CONTEXT~ to access the menu' + ['press_to_open'] = 'press ~INPUT_CONTEXT~ to access the menu', ['billing'] = 'billing', ['invoice_amount'] = 'invoice amount', ['no_players_near'] = 'no players nearby', From e3da0a3c1bf21150970f010f280e9645686c318d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 16 Aug 2017 14:08:47 +0200 Subject: [PATCH 0387/3224] Try fix phone --- server/main.lua | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/server/main.lua b/server/main.lua index e7b50eac..ccc53a15 100644 --- a/server/main.lua +++ b/server/main.lua @@ -129,7 +129,8 @@ end) RegisterServerEvent('esx_phone:reload') AddEventHandler('esx_phone:reload', function(phoneNumber) - local xPlayer = ESX.GetPlayerFromId(source) + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) local contacts = {} MySQL.Async.fetchAll( @@ -159,7 +160,7 @@ AddEventHandler('esx_phone:reload', function(phoneNumber) xPlayer.set('contacts', contacts) - TriggerClientEvent('esx_phone:loaded', source, phoneNumber, contacts) + TriggerClientEvent('esx_phone:loaded', _source, phoneNumber, contacts) end ) @@ -173,8 +174,11 @@ end) RegisterServerEvent('esx_phone:send') AddEventHandler('esx_phone:send', function(phoneNumber, message, anon) + + local _source = source + for i=1, #RegisteredCallbacks, 1 do - RegisteredCallbacks[i](source, phoneNumber, message, anon) + RegisteredCallbacks[i](_source, phoneNumber, message, anon) end end) From d68812a929bd962accf0a2aeafedf2068e037de2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 16 Aug 2017 15:58:55 +0200 Subject: [PATCH 0388/3224] Close menus when exiting markers --- client/main.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/client/main.lua b/client/main.lua index 13944ad3..9669386e 100644 --- a/client/main.lua +++ b/client/main.lua @@ -365,6 +365,7 @@ AddEventHandler('esx_taxijob:hasEnteredMarker', function(zone) end) AddEventHandler('esx_taxijob:hasExitedMarker', function(zone) + ESX.UI.Menu.CloseAll() CurrentAction = nil end) From b02abda2e5f52f207b434da08848c941ace0db2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 16 Aug 2017 15:59:31 +0200 Subject: [PATCH 0389/3224] Close menus when exiting markers --- client/main.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/client/main.lua b/client/main.lua index de821b93..7560c250 100644 --- a/client/main.lua +++ b/client/main.lua @@ -767,6 +767,7 @@ AddEventHandler('esx_vehicleshop:hasEnteredMarker', function(zone) end) AddEventHandler('esx_vehicleshop:hasExitedMarker', function(zone) + ESX.UI.Menu.CloseAll() CurrentAction = nil end) From d68694beda60b9e35b20f7d21ba72671c9cf7e6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 16 Aug 2017 16:00:09 +0200 Subject: [PATCH 0390/3224] Close menus when exiting markers --- client/main.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/client/main.lua b/client/main.lua index 3ec41e19..5a57ff0e 100644 --- a/client/main.lua +++ b/client/main.lua @@ -382,6 +382,7 @@ AddEventHandler('esx_realestateagentjob:hasEnteredMarker', function(zone) end) AddEventHandler('esx_realestateagentjob:hasExitedMarker', function(zone) + ESX.UI.Menu.CloseAll() CurrentAction = nil end) From 007eef76d594b42d0860b87d81a34be4c6032d45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 16 Aug 2017 16:01:36 +0200 Subject: [PATCH 0391/3224] Close menus when exiting markers --- client/main.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/client/main.lua b/client/main.lua index f72efb78..92f01616 100644 --- a/client/main.lua +++ b/client/main.lua @@ -162,6 +162,7 @@ AddEventHandler('esx_clotheshop:hasEnteredMarker', function(zone) end) AddEventHandler('esx_clotheshop:hasExitedMarker', function(zone) + ESX.UI.Menu.CloseAll() CurrentAction = nil end) From 5da1121666e021f64aba2f969b87813d21135d3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 16 Aug 2017 16:02:00 +0200 Subject: [PATCH 0392/3224] Close menus when exiting markers --- client/main.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/client/main.lua b/client/main.lua index c7b67f96..0e262bd4 100644 --- a/client/main.lua +++ b/client/main.lua @@ -571,6 +571,7 @@ AddEventHandler('esx_ambulancejob:hasEnteredMarker', function(zone) end) AddEventHandler('esx_ambulancejob:hasExitedMarker', function(zone) + ESX.UI.Menu.CloseAll() CurrentAction = nil end) From 9b06e8d1f909ef59ecba9d209a7dfd195c9b030e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 16 Aug 2017 16:07:29 +0200 Subject: [PATCH 0393/3224] Fix VehicleDeleter --- client/main.lua | 4 ++-- config.lua | 13 ++++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/client/main.lua b/client/main.lua index 0e262bd4..418ea4b3 100644 --- a/client/main.lua +++ b/client/main.lua @@ -602,7 +602,7 @@ Citizen.CreateThread(function() for k,v in pairs(Config.Zones) do if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then - DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.MarkerSize.x, Config.MarkerSize.y, Config.MarkerSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) end end @@ -620,7 +620,7 @@ Citizen.CreateThread(function() local currentZone = nil for k,v in pairs(Config.Zones) do - if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.MarkerSize.x) then + if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then isInMarker = true currentZone = k end diff --git a/config.lua b/config.lua index f41fe565..209fef42 100644 --- a/config.lua +++ b/config.lua @@ -1,7 +1,6 @@ Config = {} Config.DrawDistance = 100.0 Config.MarkerColor = {r = 102, g = 0, b = 102} -Config.MarkerSize = {x = 1.5, y = 1.5, z = 1.0} Config.RespawnDelayAfterRPDeath = 10 * 60 * 1000 Config.RemoveWeaponsAfterRPDeath = true Config.RemoveCashAfterRPDeath = true @@ -14,61 +13,73 @@ Config.Zones = { HospitalInteriorEntering1 = { Pos = {x = 1151.447, y = -1529.491, z = 34.375}, + Size = {x = 1.5, y = 1.5, z = 1.0}, Type = 1 }, HospitalInteriorInside1 = { Pos = {x = 251.464, y = -1369.770, z = 28.648}, + Size = {x = 1.5, y = 1.5, z = 1.0}, Type = -1 }, HospitalInteriorOutside1 = { Pos = {x = 1153.364, y = -1525.731, z = 33.843}, + Size = {x = 1.5, y = 1.5, z = 1.0}, Type = -1 }, HospitalInteriorExit1 = { Pos = {x = 253.612, y = -1371.66, z = 28.647}, + Size = {x = 1.5, y = 1.5, z = 1.0}, Type = 1 }, HospitalInteriorEntering2 = { Pos = {x = 1137.181, y = -1597.504, z = 33.692}, + Size = {x = 1.5, y = 1.5, z = 1.0}, Type = 1 }, HospitalInteriorInside2 = { Pos = {x = 240.508, y = -1360.565, z = 28.647}, + Size = {x = 1.5, y = 1.5, z = 1.0}, Type = -1 }, HospitalInteriorOutside2 = { Pos = {x = 1137.922, y = -1601.434, z = 33.692}, + Size = {x = 1.5, y = 1.5, z = 1.0}, Type = -1 }, HospitalInteriorExit2 = { Pos = {x = 238.587, y = -1359.113, z = 28.647}, + Size = {x = 1.5, y = 1.5, z = 1.0}, Type = 1 }, AmbulanceActions = { Pos = {x = 244.048, y = -1366.330, z = 28.647}, + Size = {x = 1.5, y = 1.5, z = 1.0}, Type = 1 }, VehicleSpawner = { Pos = {x = 1128.290, y = -1601.451, z = 33.893}, + Size = {x = 1.5, y = 1.5, z = 1.0}, Type = 1 }, VehicleSpawnPoint = { Pos = {x = 1138.061, y = -1607.882, z = 34.692}, + Size = {x = 1.5, y = 1.5, z = 1.0}, Type = -1 }, VehicleDeleter = { Pos = {x = 1122.436, y = -1617.600, z = 33.692}, + Size = {x = 3.0, y = 3.0, z = 2.0}, Type = 1 } From c83be9168749a11f8953b3a66e3190ea3bab1d90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 16 Aug 2017 16:33:25 +0200 Subject: [PATCH 0394/3224] Fix vehicle detection --- client/main.lua | 60 ++++++++++++++++--------------------------------- 1 file changed, 19 insertions(+), 41 deletions(-) diff --git a/client/main.lua b/client/main.lua index 374949a2..cd8846fc 100644 --- a/client/main.lua +++ b/client/main.lua @@ -211,13 +211,9 @@ function OpenVehicleSpawnerMenu(station, partNum) local model = data.current.value - local vehicle, distance = ESX.Game.GetClosestVehicle({ - x = vehicles[partNum].SpawnPoint.x, - y = vehicles[partNum].SpawnPoint.y, - z = vehicles[partNum].SpawnPoint.z - }) + local vehicle = GetClosestVehicle(vehicles[partNum].SpawnPoint.x, vehicles[partNum].SpawnPoint.y, vehicles[partNum].SpawnPoint.z, 3.0, 0, 71) - if distance > 3.0 then + if DoesEntityExist(vehicle) then local playerPed = GetPlayerPed(-1) @@ -357,9 +353,11 @@ function OpenPoliceActionsMenu() }, function(data2, menu2) - local vehicle, distance = ESX.Game.GetClosestVehicle() + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + local vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 3.0, 0, 71) - if distance ~= -1 and distance <= 3.0 then + if DoesEntityExist(vehicle) then local vehicleData = ESX.Game.GetVehicleProperties(vehicle) @@ -372,14 +370,10 @@ function OpenPoliceActionsMenu() local playerPed = GetPlayerPed(-1) local coords = GetEntityCoords(playerPed) - if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then - - local vehicle, distance = ESX.Game.GetClosestVehicle({ - x = coords.x, - y = coords.y, - z = coords.z - }) + if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 3.0) then + local vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 3.0, 0, 71) + if DoesEntityExist(vehicle) then Citizen.CreateThread(function() @@ -960,14 +954,9 @@ AddEventHandler('esx_policejob:hasEnteredMarker', function(station, part, partNu if part == 'HelicopterSpawner' then local helicopters = Config.PoliceStations[station].Helicopters - - local vehicle, distance = ESX.Game.GetClosestVehicle({ - x = helicopters[partNum].SpawnPoint.x, - y = helicopters[partNum].SpawnPoint.y, - z = helicopters[partNum].SpawnPoint.z - }) + local vehicle = GetClosestVehicle(helicopters[partNum].SpawnPoint.x, helicopters[partNum].SpawnPoint.y, helicopters[partNum].SpawnPoint.z, 3.0, 0, 71) - if distance > 3.0 then + if DoesEntityExist(vehicle) then ESX.Game.SpawnVehicle('polmav', { x = helicopters[partNum].SpawnPoint.x, @@ -985,12 +974,13 @@ AddEventHandler('esx_policejob:hasEnteredMarker', function(station, part, partNu if part == 'VehicleDeleter' then local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) if IsPedInAnyVehicle(playerPed, false) then - local vehicle, distance = ESX.Game.GetClosestVehicle() + local vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 3.0, 0, 71) - if distance <= 2.0 then + if DoesEntityExist(vehicle) then CurrentAction = 'delete_vehicle' CurrentActionMsg = _U('store_vehicle') CurrentActionData = {vehicle = vehicle} @@ -1029,18 +1019,10 @@ AddEventHandler('esx_policejob:hasEnteredEntityZone', function(entity) if IsPedInAnyVehicle(playerPed, false) then - local vehicle, distance = ESX.Game.GetClosestVehicle({ - x = coords.x, - y = coords.y, - z = coords.z - }) - - if distance <= 1.0 then - - for i=0, 7, 1 do - SetVehicleTyreBurst(vehicle, i, true, 1000) - end + local vehicle = GetVehiclePedIsIn(playerPed) + for i=0, 7, 1 do + SetVehicleTyreBurst(vehicle, i, true, 1000) end end @@ -1098,12 +1080,8 @@ AddEventHandler('esx_policejob:putInVehicle', function() if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then - local vehicle, distance = ESX.Game.GetClosestVehicle({ - x = coords.x, - y = coords.y, - z = coords.z - }) - + local vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) + if DoesEntityExist(vehicle) then local maxSeats = GetVehicleMaxNumberOfPassengers(vehicle) From 0677f16990cbd8419a6c2a74007ac06d65adbd1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 16 Aug 2017 16:39:51 +0200 Subject: [PATCH 0395/3224] Fix wrong arguments --- client/main.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/main.lua b/client/main.lua index 9669386e..867c067b 100644 --- a/client/main.lua +++ b/client/main.lua @@ -472,7 +472,7 @@ Citizen.CreateThread(function() if IsPedInAnyVehicle(playerPed, false) and GetEntitySpeed(playerPed) > 0 then - local waitUntil = GetGameTimer() + GetRandomIntInRange(1000, 120000) + local waitUntil = GetGameTimer() + GetRandomIntInRange(1000, 30000) while OnJob and waitUntil > GetGameTimer() do Citizen.Wait(0) @@ -587,9 +587,9 @@ Citizen.CreateThread(function() local msg = nil if street[2] ~= 0 and street[2] ~= nil then - msg = string.format(_U('take_me_to_near'), GetStreetNameFromHashKey(street[1]),GetStreetNameFromHashKey(street[2])) + msg = string.format(_U('take_me_to_near', GetStreetNameFromHashKey(street[1]),GetStreetNameFromHashKey(street[2]))) else - msg = string.format(_U('take_me_to'), GetStreetNameFromHashKey(street[1])) + msg = string.format(_U('take_me_to', GetStreetNameFromHashKey(street[1]))) end ESX.ShowNotification(msg) From 2214ff975bf63ea737c87c9006ad5ca67ade656f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 16 Aug 2017 16:46:30 +0200 Subject: [PATCH 0396/3224] Fix ear accessories (can remove now) --- client/main.lua | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index 69edcafa..5428b3a5 100644 --- a/client/main.lua +++ b/client/main.lua @@ -24,7 +24,7 @@ local Components = { {label = 'Epaisseur Lipstick', name = 'lipstick_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- {label = 'Couleur Lipstick 1', name = 'lipstick_3', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- {label = 'Couleur Lipstick 2', name = 'lipstick_4', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = 'Accessoire Oreilles',name = 'ears_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = 'Accessoire Oreilles',name = 'ears_1', value = -1, min = -1, zoomOffset = 0.4, camOffset = 0.65}, -- {label = 'Couleur Accessoire', name = 'ears_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65, textureof = 'ears_1'}, -- {label = 'T-Shirt 1', name = 'tshirt_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- {label = 'T-Shirt 2', name = 'tshirt_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'tshirt_1'}, -- @@ -211,7 +211,13 @@ function ApplySkin(skin, clothes) SetPedHeadOverlayColor(playerPed, 2, 1, Character['lipstick_3'], Character['lipstick_4']) -- Lipstick Color SetPedComponentVariation(playerPed, 2, Character['hair_1'], Character['hair_2'], 2) -- Hair SetPedHairColor(playerPed, Character['hair_color_1'], Character['hair_color_2']) -- Hair Color - SetPedPropIndex(playerPed, 2, Character['ears_1'], Character['ears_2'], 2) -- Ears Accessories + + if Character['ears_1'] == -1 then + ClearPedProp(playerPed, 2) + else + SetPedPropIndex(playerPed, 2, Character['ears_1'], Character['ears_2'], 2) -- Ears Accessories + end + SetPedComponentVariation(playerPed, 8, Character['tshirt_1'],Character['tshirt_2'], 2) -- Tshirt SetPedComponentVariation(playerPed, 11, Character['torso_1'], Character['torso_2'], 2) -- torso parts SetPedComponentVariation(playerPed, 3, Character['arms'], 0, 2) -- torso @@ -222,11 +228,13 @@ function ApplySkin(skin, clothes) SetPedComponentVariation(playerPed, 9, Character['bproof_1'], Character['bproof_2'], 2) -- bulletproof SetPedComponentVariation(playerPed, 7, Character['chain_1'], Character['chain_2'], 2) -- chain SetPedComponentVariation(playerPed, 5, Character['bags_1'], Character['bags_2'], 2) -- Bag + if Character['helmet_1'] == -1 then ClearPedProp(playerPed, 0) else SetPedPropIndex(playerPed, 0, Character['helmet_1'], Character['helmet_2'], 2) -- Helmet end + SetPedPropIndex(playerPed, 1, Character['glasses_1'], Character['glasses_2'], 2) -- Glasses end From 9f73945dc6e94aff57c0ee35f3f131b289848d60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 16 Aug 2017 16:48:00 +0200 Subject: [PATCH 0397/3224] Fix local type --- locales/fr.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/fr.lua b/locales/fr.lua index 18347d4f..cad6a5ff 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,7 +1,7 @@ Locales['fr'] = { ['taking_service'] = 'prise de service : ', - ['spawn_veh'] = 'vortir véhicule', + ['spawn_veh'] = 'sortir véhicule', ['remove_comp_money'] = 'retirer argent société', ['deposit_money'] = 'déposer argent', ['launder_money'] = 'blanchir argent', From 4b0173ff82ef840b9b1803ce2b71d60425b88a5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 16 Aug 2017 16:55:24 +0200 Subject: [PATCH 0398/3224] Fix condition --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index cd8846fc..585a8036 100644 --- a/client/main.lua +++ b/client/main.lua @@ -213,7 +213,7 @@ function OpenVehicleSpawnerMenu(station, partNum) local vehicle = GetClosestVehicle(vehicles[partNum].SpawnPoint.x, vehicles[partNum].SpawnPoint.y, vehicles[partNum].SpawnPoint.z, 3.0, 0, 71) - if DoesEntityExist(vehicle) then + if not DoesEntityExist(vehicle) then local playerPed = GetPlayerPed(-1) From 6300cd1d8b12ab8de6448ffd8f8dcaa331f8bdc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 16 Aug 2017 16:59:38 +0200 Subject: [PATCH 0399/3224] Fix delete vehicle --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 585a8036..f731549a 100644 --- a/client/main.lua +++ b/client/main.lua @@ -978,7 +978,7 @@ AddEventHandler('esx_policejob:hasEnteredMarker', function(station, part, partNu if IsPedInAnyVehicle(playerPed, false) then - local vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 3.0, 0, 71) + local vehicle = GetVehicelPedIsIn(playerPed, false) if DoesEntityExist(vehicle) then CurrentAction = 'delete_vehicle' From 4116611330a6fdf2dbf2d2550f6ce0a663b55da3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 16 Aug 2017 17:04:16 +0200 Subject: [PATCH 0400/3224] Fix typo --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index f731549a..83f7ffba 100644 --- a/client/main.lua +++ b/client/main.lua @@ -978,7 +978,7 @@ AddEventHandler('esx_policejob:hasEnteredMarker', function(station, part, partNu if IsPedInAnyVehicle(playerPed, false) then - local vehicle = GetVehicelPedIsIn(playerPed, false) + local vehicle = GetVehiclePedIsIn(playerPed, false) if DoesEntityExist(vehicle) then CurrentAction = 'delete_vehicle' From e6dd9bfa2b426d22ac09c465031c4b8b436df819 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Wed, 16 Aug 2017 11:32:40 -0400 Subject: [PATCH 0401/3224] Multi-language support --- __resource.lua | 6 ++ client/main.lua | 182 ++++++++++++++++++++++++------------------------ config.lua | 1 + locales/en.lua | 30 ++++++++ locales/fr.lua | 30 ++++++++ server/main.lua | 62 ++++++++--------- 6 files changed, 189 insertions(+), 122 deletions(-) create mode 100644 locales/en.lua create mode 100644 locales/fr.lua diff --git a/__resource.lua b/__resource.lua index 5660501e..473a6ccf 100644 --- a/__resource.lua +++ b/__resource.lua @@ -3,12 +3,18 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ESX Property' server_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', '@mysql-async/lib/MySQL.lua', 'config.lua', 'server/main.lua' } client_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', 'config.lua', 'client/main.lua' } diff --git a/client/main.lua b/client/main.lua index cd7194dd..36f260bd 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,10 +1,10 @@ local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 @@ -41,14 +41,14 @@ function CreateBlips() if property.entering ~= nil then Blips[property.name] = AddBlipForCoord(property.entering.x, property.entering.y, property.entering.z) - + SetBlipSprite (Blips[property.name], 369) SetBlipDisplay(Blips[property.name], 4) SetBlipScale (Blips[property.name], 1.0) SetBlipAsShortRange(Blips[property.name], true) - + BeginTextCommandSetBlipName("STRING") - AddTextComponentString("Propriété libre") + AddTextComponentString(_U('free_prop')) EndTextCommandSetBlipName(Blips[property.name]) end @@ -127,9 +127,9 @@ function EnterProperty(name) end for i=1, #property.ipls, 1 do - + RequestIpl(property.ipls[i]) - + while not IsIplActive(property.ipls[i]) do Citizen.Wait(0) end @@ -215,9 +215,9 @@ function SetPropertyOwned(name, owned) SetBlipSprite(Blips[enteringName], 357) SetBlipAsShortRange(Blips[enteringName], true) - + BeginTextCommandSetBlipName("STRING") - AddTextComponentString("Propriété") + AddTextComponentString(_U('property')) EndTextCommandSetBlipName(Blips[enteringName]) else @@ -232,7 +232,7 @@ function SetPropertyOwned(name, owned) local _gateway = GetGateway(_property) if _gateway ~= nil then - + if _gateway.name == enteringName then found = true break @@ -251,7 +251,7 @@ function SetPropertyOwned(name, owned) SetBlipAsShortRange(Blips[enteringName], true) BeginTextCommandSetBlipName("STRING") - AddTextComponentString("Propriété libre") + AddTextComponentString(_U('free_prop')) EndTextCommandSetBlipName(Blips[enteringName]) end @@ -269,22 +269,22 @@ function OpenPropertyMenu(property) local elements = {} if PropertyIsOwned(property) then - - table.insert(elements, {label = 'Entrer', value = 'enter'}) + + table.insert(elements, {label = _U('enter'), value = 'enter'}) if not Config.EnablePlayerManagement then - table.insert(elements, {label = 'Rendre', value = 'leave'}) + table.insert(elements, {label = _U('leave'), value = 'leave'}) end else if not Config.EnablePlayerManagement then - table.insert(elements, {label = 'Acheter', value = 'buy'}) - table.insert(elements, {label = 'Louer', value = 'rent'}) + table.insert(elements, {label = _U('buy'), value = 'buy'}) + table.insert(elements, {label = _U('rent'), value = 'rent'}) end - table.insert(elements, {label = 'Visiter', value = 'visit'}) - + table.insert(elements, {label = _U('visit'), value = 'visit'}) + end ESX.UI.Menu.Open( @@ -295,9 +295,9 @@ function OpenPropertyMenu(property) elements = elements, }, function(data2, menu) - + menu.close() - + if data2.current.value == 'enter' then EnterProperty(property.name) end @@ -324,7 +324,7 @@ function OpenPropertyMenu(property) menu.close() CurrentAction = 'property_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('press_to_menu') CurrentActionData = {property = property} end ) @@ -332,7 +332,7 @@ function OpenPropertyMenu(property) end function OpenGatewayMenu(property) - + if Config.EnablePlayerManagement then OpenGatewayOwnedPropertiesMenu(gatewayProperties) else @@ -343,8 +343,8 @@ function OpenGatewayMenu(property) title = property.name, align = 'top-left', elements = { - {label = 'Propriétés acquises', value = 'owned_properties'}, - {label = 'Propriétés disponibles', value = 'available_properties'}, + {label = _U('owned_properties'), value = 'owned_properties'}, + {label = _U('available_properties'), value = 'available_properties'}, } }, function(data, menu) @@ -359,11 +359,11 @@ function OpenGatewayMenu(property) end, function(data, menu) - + menu.close() CurrentAction = 'gateway_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('press_to_menu') CurrentActionData = {property = property} end @@ -379,7 +379,7 @@ function OpenGatewayOwnedPropertiesMenu(property) local elements = {} for i=1, #gatewayProperties, 1 do - + if PropertyIsOwned(gatewayProperties[i]) then table.insert(elements, { label = gatewayProperties[i].label, @@ -392,20 +392,20 @@ function OpenGatewayOwnedPropertiesMenu(property) ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'gateway_owned_properties', { - title = property.name .. ' - Propriétés Acquises', + title = property.name .. ' - ' .. _U('owned_properties'), align = 'top-left', elements = elements, }, function(data, menu) - + menu.close() local elements = { - {label = 'Entrer', value = 'enter'} + {label = _U('enter'), value = 'enter'} } if not Config.EnablePlayerManagement then - table.insert(elements, {label = 'Rendre', value = 'leave'}) + table.insert(elements, {label = _U('leave'), value = 'leave'}) end ESX.UI.Menu.Open( @@ -416,9 +416,9 @@ function OpenGatewayOwnedPropertiesMenu(property) elements = elements, }, function(data2, menu) - + menu.close() - + if data2.current.value == 'enter' then EnterProperty(data.current.value) end @@ -442,12 +442,12 @@ function OpenGatewayOwnedPropertiesMenu(property) end function OpenGatewayAvailablePropertiesMenu(property) - + local gatewayProperties = GetGatewayProperties(property) local elements = {} for i=1, #gatewayProperties, 1 do - + if not PropertyIsOwned(gatewayProperties[i]) then table.insert(elements, { label = gatewayProperties[i].label .. ' $' .. gatewayProperties[i].price, @@ -461,12 +461,12 @@ function OpenGatewayAvailablePropertiesMenu(property) ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'gateway_available_properties', { - title = property.name.. ' - Propriétés Disponbibles', + title = property.name.. ' - ' .. _U('available_properties'), align = 'top-left', elements = elements, }, function(data, menu) - + menu.close() ESX.UI.Menu.Open( @@ -475,9 +475,9 @@ function OpenGatewayAvailablePropertiesMenu(property) title = property.name, align = 'top-left', elements = { - {label = 'Acheter', value = 'buy'}, - {label = 'Louer', value = 'rent'}, - {label = 'Visiter', value = 'visit'}, + {label = _U('buy'), value = 'buy'}, + {label = _U('rent'), value = 'rent'}, + {label = _U('visit'), value = 'visit'}, }, }, function(data2, menu) @@ -526,14 +526,14 @@ function OpenRoomMenu(property) title = property.label, align = 'top-left', elements = { - {label = 'Inviter un joueur', value = 'invite_player'}, - {label = 'Dressing', value = 'player_dressing'}, - {label = 'Retirer objet', value = 'room_inventory'}, - {label = 'Déposer objet', value = 'player_inventory'}, + {label = _U('invite_player'), value = 'invite_player'}, + {label = _U('player_clothes'), value = 'player_dressing'}, + {label = _U('remove_object'), value = 'room_inventory'}, + {label = _U('deposit_object'), value = 'player_inventory'}, }, }, function(data, menu) - + if data.current.value == 'invite_player' then local playersInArea = ESX.Game.GetPlayersInArea(entering, 10.0) @@ -548,7 +548,7 @@ function OpenRoomMenu(property) ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'room_invite', { - title = property.label .. ' - Invite', + title = property.label .. ' - ' .. _U('invite'), align = 'top-left', elements = elements, }, @@ -563,7 +563,7 @@ function OpenRoomMenu(property) end if data.current.value == 'player_dressing' then - + ESX.TriggerServerCallback('esx_property:getPlayerDressing', function(dressing) local elements = {} @@ -575,14 +575,14 @@ function OpenRoomMenu(property) ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'player_dressing', { - title = property.label .. ' - Dressing', + title = property.label .. ' - ' .. _U('player_clothes'), align = 'top-left', elements = elements, }, function(data, menu) TriggerEvent('skinchanger:getSkin', function(skin) - + TriggerEvent('skinchanger:loadClothes', skin, data.current.value) TriggerEvent('skinchanger:getSkin', function(skin) @@ -615,7 +615,7 @@ function OpenRoomMenu(property) menu.close() CurrentAction = 'room_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('press_to_menu') CurrentActionData = {property = property} end ) @@ -628,10 +628,10 @@ function OpenRoomInventoryMenu(property) local elements = {} - table.insert(elements, {label = 'Argent sale $' .. inventory.blackMoney, type = 'item_account', value = 'black_money'}) + table.insert(elements, {label = _U('dirty_money') .. inventory.blackMoney, type = 'item_account', value = 'black_money'}) for i=1, #inventory.items, 1 do - + local item = inventory.items[i] if item.count > 0 then @@ -648,18 +648,18 @@ function OpenRoomInventoryMenu(property) ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'room_inventory', { - title = property.label .. ' - Inventaire', + title = property.label .. ' - ' .. _U('inventory'), align = 'top-left', elements = elements, }, function(data, menu) if data.current.type == 'item_weapon' then - + menu.close() TriggerServerEvent('esx_property:getItem', data.current.type, data.current.value, data.current.ammo) - + ESX.SetTimeout(300, function() OpenRoomInventoryMenu(property) end) @@ -669,20 +669,20 @@ function OpenRoomInventoryMenu(property) ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'get_item_count', { - title = 'Quantité ?', + title = _U('amount'), }, function(data2, menu) - + local quantity = tonumber(data2.value) if quantity == nil then - ESX.ShowNotification('Montant invalide') + ESX.ShowNotification(_U('amount_invalid')) else - + menu.close() TriggerServerEvent('esx_property:getItem', data.current.type, data.current.value, quantity) - + ESX.SetTimeout(300, function() OpenRoomInventoryMenu(property) end) @@ -713,16 +713,16 @@ function OpenPlayerInventoryMenu(property) local elements = {} - table.insert(elements, {label = 'Argent sale $' .. inventory.blackMoney, type = 'item_account', value = 'black_money'}) + table.insert(elements, {label = _U('dirty_money') .. inventory.blackMoney, type = 'item_account', value = 'black_money'}) for i=1, #inventory.items, 1 do - + local item = inventory.items[i] - + if item.count > 0 then table.insert(elements, {label = item.label .. ' x' .. item.count, type = 'item_standard', value = item.name}) end - + end local playerPed = GetPlayerPed(-1) @@ -742,35 +742,35 @@ function OpenPlayerInventoryMenu(property) ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'player_inventory', { - title = property.label .. ' - Inventaire', + title = property.label .. ' - ' .. _U('inventory'), align = 'top-left', elements = elements, }, function(data, menu) - + if data.current.type == 'item_weapon' then - + menu.close() TriggerServerEvent('esx_property:putItem', data.current.type, data.current.value, data.current.ammo) - + ESX.SetTimeout(300, function() OpenPlayerInventoryMenu(property) end) - + else ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'put_item_count', { - title = 'Quantité ?', + title = _U('amount'), }, function(data2, menu) - + menu.close() TriggerServerEvent('esx_property:putItem', data.current.type, data.current.value, tonumber(data2.value)) - + ESX.SetTimeout(300, function() OpenPlayerInventoryMenu(property) end) @@ -840,7 +840,7 @@ end) RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) - + ESX.TriggerServerCallback('esx_property:getOwnedProperties', function(ownedProperties) for i=1, #ownedProperties, 1 do SetPropertyOwned(ownedProperties[i], true) @@ -850,18 +850,18 @@ AddEventHandler('esx:playerLoaded', function(xPlayer) end) AddEventHandler('esx_property:hasEnteredMarker', function(name, part) - + local property = GetProperty(name) if part == 'entering' then if property.isSingle then CurrentAction = 'property_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('press_to_menu') CurrentActionData = {property = property} else CurrentAction = 'gateway_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('press_to_menu') CurrentActionData = {property = property} end @@ -869,13 +869,13 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part) if part == 'exit' then CurrentAction = 'room_exit' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour sortir de la propriété' + CurrentActionMsg = _U('press_to_exit') CurrentActionData = {propertyName = name} end if part == 'roomMenu' then CurrentAction = 'room_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('press_to_menu') CurrentActionData = {property = property} end @@ -888,7 +888,7 @@ end) -- Init Citizen.CreateThread(function() - + while ESX == nil do TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) Citizen.Wait(0) @@ -904,11 +904,11 @@ end) -- Display markers Citizen.CreateThread(function() while true do - + Wait(0) - + local coords = GetEntityCoords(GetPlayerPed(-1)) - + for i=1, #Config.Properties, 1 do local property = Config.Properties[i] @@ -933,7 +933,7 @@ end) -- Enter / Exit marker events Citizen.CreateThread(function() while true do - + Wait(0) local coords = GetEntityCoords(GetPlayerPed(-1)) @@ -978,18 +978,18 @@ Citizen.CreateThread(function() end if isInMarker and not HasAlreadyEnteredMarker or (isInMarker and (LastProperty ~= currentProperty or LastPart ~= currentPart) ) then - + HasAlreadyEnteredMarker = true LastProperty = currentProperty LastPart = currentPart - + TriggerEvent('esx_property:hasEnteredMarker', currentProperty, currentPart) end if not isInMarker and HasAlreadyEnteredMarker then - + HasAlreadyEnteredMarker = false - + TriggerEvent('esx_property:hasExitedMarker', LastProperty, LastPart) end @@ -1009,7 +1009,7 @@ Citizen.CreateThread(function() DisplayHelpTextFromStringLabel(0, 0, 1, -1) if IsControlPressed(0, Keys['E']) and (GetGameTimer() - GUI.Time) > 300 then - + if CurrentAction == 'property_menu' then OpenPropertyMenu(CurrentActionData.property) end @@ -1034,10 +1034,10 @@ Citizen.CreateThread(function() CurrentAction = nil GUI.Time = GetGameTimer() - + end end end -end) \ No newline at end of file +end) diff --git a/config.lua b/config.lua index 25c717f8..dcb4bb17 100644 --- a/config.lua +++ b/config.lua @@ -7,3 +7,4 @@ Config.MarkerType = 1 Config.Zones = {} Config.Properties = {} Config.EnablePlayerManagement = false -- If set to true you need esx_realestateagentjob +Config.Locale = 'fr' diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..ce700925 --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,30 @@ +Locales['en'] = { + + ['free_prop'] = 'free property', + ['property'] = 'property', + ['enter'] = 'enter', + ['leave'] = 'leave', + ['buy'] = 'buy', + ['rent'] = 'rent', + ['visit'] = 'visit', + ['press_to_menu'] = 'press ~INPUT_CONTEXT~ to access the menu', + ['owned_properties'] = 'acquired properties', + ['available_properties'] = 'available properties', + ['invite_player'] = 'invite a player', + ['player_clothes'] = 'clothes', + ['remove_object'] = 'remove object', + ['deposit_object'] = 'deposit object', + ['invite'] = 'invite', + ['dirty_money'] = 'dirty money $', + ['inventory'] = 'inventory', + ['amount'] = 'amount?', + ['amount_invalid'] = 'invalid amount', + ['press_to_exit'] = 'press ~INPUT_CONTEXT~ to exit the property', + ['rented_for'] = 'you rented a property for $', + ['purchased_for'] = 'you purchased a property for $', + ['made_property'] = 'you have made a property', + ['not_enough'] = 'you do not have enough money', + ['invalid_quantity'] = 'invalid quantity', + ['paid_rent'] = 'you ~g~paid~s~ your rent: ~g~$', + +} diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..2123dcb1 --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,30 @@ +Locales['fr'] = { + + ['free_prop'] = 'propriété libre', + ['property'] = 'propriété', + ['enter'] = 'entrer', + ['leave'] = 'rendre', + ['buy'] = 'acheter', + ['rent'] = 'louer', + ['visit'] = 'visiter', + ['press_to_menu'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder au menu', + ['owned_properties'] = 'propriétés acquises', + ['available_properties'] = 'propriétés disponibles', + ['invite_player'] = 'inviter un joueur', + ['player_clothes'] = 'vêtements', + ['remove_object'] = 'retirer objet', + ['deposit_object'] = 'déposer objet', + ['invite'] = 'inviter', + ['dirty_money'] = 'argent sale $', + ['inventory'] = 'inventaire', + ['amount'] = 'quantité ?', + ['amount_invalid'] = 'montant invalide', + ['press_to_exit'] = 'appuyez sur ~INPUT_CONTEXT~ pour sortir de la propriété', + ['rented_for'] = 'vous avez loué une propriété pour $', + ['purchased_for'] = 'vous avez acheté une propriété pour $', + ['made_property'] = 'vous avez rendu une propriété', + ['not_enough'] = 'vous n\'avez pas assez d\'argent', + ['invalid_quantity'] = 'quantité invalide', + ['paid_rent'] = 'vous avez ~g~payé~s~ votre loyer : ~g~$', + +} diff --git a/server/main.lua b/server/main.lua index cff86548..8652a2c3 100644 --- a/server/main.lua +++ b/server/main.lua @@ -15,7 +15,7 @@ end function SetPropertyOwned(name, price, rented, owner) MySQL.Async.execute( - 'INSERT INTO owned_properties (name, price, rented, owner) VALUES (@name, @price, @rented, @owner)', + 'INSERT INTO owned_properties (name, price, rented, owner) VALUES (@name, @price, @rented, @owner)', { ['@name'] = name, ['@price'] = price, @@ -28,13 +28,13 @@ function SetPropertyOwned(name, price, rented, owner) for k,v in pairs(xPlayers) do if v.identifier == owner then - + TriggerClientEvent('esx_property:setPropertyOwned', v.source, name, true) if rented then - TriggerClientEvent('esx:showNotification', v.source, 'Vous avez loué une propriété pour $' .. price) + TriggerClientEvent('esx:showNotification', v.source, _U('rented_for') .. price) else - TriggerClientEvent('esx:showNotification', v.source, 'Vous avez acheté une propriété pour $' .. price) + TriggerClientEvent('esx:showNotification', v.source, _U('purchased_for') .. price) end break @@ -61,7 +61,7 @@ function RemoveOwnedProperty(name, owner) for k,v in pairs(xPlayers) do if v.identifier == owner then TriggerClientEvent('esx_property:setPropertyOwned', v.source, name, false) - TriggerClientEvent('esx:showNotification', v.source, 'Vous avez rendu une propriété') + TriggerClientEvent('esx:showNotification', v.source, _U('made_property')) break end end @@ -74,7 +74,7 @@ end AddEventHandler('onMySQLReady', function () MySQL.Async.fetchAll('SELECT * FROM properties', {}, function(properties) - + for i=1, #properties, 1 do local entering = nil @@ -183,10 +183,10 @@ end) RegisterServerEvent('esx_property:rentProperty') AddEventHandler('esx_property:rentProperty', function(propertyName) - + local xPlayer = ESX.GetPlayerFromId(source) local property = GetProperty(propertyName) - + SetPropertyOwned(propertyName, property.price / 200, true, xPlayer.identifier) end) @@ -203,16 +203,16 @@ AddEventHandler('esx_property:buyProperty', function(propertyName) SetPropertyOwned(propertyName, property.price, false, xPlayer.identifier) else - TriggerClientEvent('esx:showNotification', source, 'Vous n\'avez pas assez d\'argent') + TriggerClientEvent('esx:showNotification', source, _U('not_enough')) end end) RegisterServerEvent('esx_property:removeOwnedProperty') AddEventHandler('esx_property:removeOwnedProperty', function(propertyName) - + local xPlayer = ESX.GetPlayerFromId(source) - + RemoveOwnedProperty(propertyName, xPlayer.identifier) end) @@ -223,9 +223,9 @@ end) RegisterServerEvent('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', { @@ -239,7 +239,7 @@ end) RegisterServerEvent('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', { @@ -256,14 +256,14 @@ AddEventHandler('esx_property:getItem', function(type, item, count) if type == 'item_standard' then TriggerEvent('esx_addoninventory:getInventory', 'property', xPlayer.identifier, function(inventory) - + local roomItemCount = inventory.getItem(item).count - + if roomItemCount >= count then inventory.removeItem(item, count) xPlayer.addInventoryItem(item, count) else - TriggerClientEvent('esx:showNotification', source, 'Quantité invalide') + TriggerClientEvent('esx:showNotification', source, _U('invalid_quantity')) end end) @@ -273,14 +273,14 @@ AddEventHandler('esx_property:getItem', function(type, item, count) if type == 'item_account' then TriggerEvent('esx_addonaccount:getAccount', 'property_' .. item, xPlayer.identifier, function(account) - + local roomAccountMoney = account.money - + if roomAccountMoney >= count then account.removeMoney(count) xPlayer.addAccountMoney(item, count) else - TriggerClientEvent('esx:showNotification', source, 'Montant invalide') + TriggerClientEvent('esx:showNotification', source, _U('amount_invalid')) end end) @@ -290,7 +290,7 @@ AddEventHandler('esx_property:getItem', function(type, item, count) if type == 'item_weapon' then TriggerEvent('esx_datastore:getDataStore', 'property', xPlayer.identifier, function(store) - + local storeWeapons = store.get('weapons') if storeWeapons == nil then @@ -302,12 +302,12 @@ AddEventHandler('esx_property:getItem', function(type, item, count) for i=1, #storeWeapons, 1 do if storeWeapons[i].name == item then - + weaponName = storeWeapons[i].name ammo = storeWeapons[i].ammo - + table.remove(storeWeapons, i) - + break end end @@ -340,7 +340,7 @@ AddEventHandler('esx_property:putItem', function(type, item, count) end) else - TriggerClientEvent('esx:showNotification', source, 'Quantité invalide') + TriggerClientEvent('esx:showNotification', source, _U('invalid_quantity')) end end @@ -358,7 +358,7 @@ AddEventHandler('esx_property:putItem', function(type, item, count) end) else - TriggerClientEvent('esx:showNotification', source, 'Montant invalide') + TriggerClientEvent('esx:showNotification', source, _U('amount_invalid')) end end @@ -366,7 +366,7 @@ AddEventHandler('esx_property:putItem', function(type, item, count) if type == 'item_weapon' then TriggerEvent('esx_datastore:getDataStore', 'property', xPlayer.identifier, function(store) - + local storeWeapons = store.get('weapons') if storeWeapons == nil then @@ -447,7 +447,7 @@ ESX.RegisterServerCallback('esx_property:getPropertyInventory', function(source, end) TriggerEvent('esx_datastore:getDataStore', 'property', xPlayer.identifier, function(store) - + local storeWeapons = store.get('weapons') if storeWeapons ~= nil then @@ -520,8 +520,8 @@ function PayRent(d, h, m) if foundPlayer then xPlayer.removeMoney(result[i].price) - TriggerClientEvent('esx:showNotification', xPlayer.source, 'Vous avez ~g~payé~s~ votre loyer : ~g~$' .. result[i].price) - + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('paid_rent') .. result[i].price) + else MySQL.Async.fetchAll( @@ -557,4 +557,4 @@ function PayRent(d, h, m) end -TriggerEvent('cron:runAt', 22, 0, PayRent) \ No newline at end of file +TriggerEvent('cron:runAt', 22, 0, PayRent) From 4e4927dcfd7cf29cb4fc6965ef199a7313c45bb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 16 Aug 2017 19:21:07 +0200 Subject: [PATCH 0402/3224] Add condition to close menu --- client/main.lua | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 7560c250..883501a0 100644 --- a/client/main.lua +++ b/client/main.lua @@ -19,6 +19,7 @@ local PlayerData = {} local CurrentAction = nil local CurrentActionMsg = '' local CurrentActionData = {} +local IsInShopMenu = false local Categories = {} local Vehicles = {} local LastVehicles = {} @@ -53,6 +54,8 @@ end function OpenShopMenu() + IsInShopMenu = true + ESX.UI.Menu.CloseAll() local playerPed = GetPlayerPed(-1) @@ -148,6 +151,8 @@ function OpenShopMenu() if hasEnoughMoney then + IsInShopMenu = false + menu2.close() menu.close() @@ -212,6 +217,8 @@ function OpenShopMenu() SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos.x, Config.Zones.ShopEntering.Pos.y, Config.Zones.ShopEntering.Pos.z) end + IsInShopMenu = false + end, function(data, menu) @@ -767,7 +774,11 @@ AddEventHandler('esx_vehicleshop:hasEnteredMarker', function(zone) end) AddEventHandler('esx_vehicleshop:hasExitedMarker', function(zone) - ESX.UI.Menu.CloseAll() + + if not IsInShopMenu then + ESX.UI.Menu.CloseAll() + end + CurrentAction = nil end) From 08086be4f7b1dba70b91311abb4a4c1eb2540c54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 16 Aug 2017 20:59:32 +0200 Subject: [PATCH 0403/3224] Fix delete vehicle issue + spawn a little upper --- client/main.lua | 15 +++++++++------ config.lua | 2 ++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/client/main.lua b/client/main.lua index 4a9b9e77..cb4e7f0a 100644 --- a/client/main.lua +++ b/client/main.lua @@ -29,7 +29,7 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) local spawnCoords = { x = garage.InteriorSpawnPoint.Pos.x, y = garage.InteriorSpawnPoint.Pos.y, - z = garage.InteriorSpawnPoint.Pos.z + z = garage.InteriorSpawnPoint.Pos.z + Config.ZDiff } ESX.Game.DeleteVehicle(vehicle) @@ -217,10 +217,11 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) if part == 'Parking' then - local playerPed = GetPlayerPed(-1) - local garage = Config.Garages[name] + local playerPed = GetPlayerPed(-1) + local garage = Config.Garages[name] + local parkingPos = garage.Parkings[parking].Pos - if IsPedInAnyVehicle(playerPed, false) then + if IsPedInAnyVehicle(playerPed, false) and not IsAnyVehicleNearPoint(parkingPos.x, parkingPos.y, parkingPos.z, 1.0) then local vehicle = GetVehiclePedIsIn(playerPed, false) local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) @@ -237,9 +238,11 @@ AddEventHandler('esx_property:hasExitedMarker', function(name, part, parking) if part == 'Parking' then - local playerPed = GetPlayerPed(-1) + local playerPed = GetPlayerPed(-1) + local garage = Config.Garages[name] + local parkingPos = garage.Parkings[parking].Pos - if IsPedInAnyVehicle(playerPed, false) then + if IsPedInAnyVehicle(playerPed, false) and not IsAnyVehicleNearPoint(parkingPos.x, parkingPos.y, parkingPos.z, 1.0) then TriggerServerEvent('esx_garage:setParking', name, parking, false) end diff --git a/config.lua b/config.lua index 6cfd1130..f53456ad 100644 --- a/config.lua +++ b/config.lua @@ -5,6 +5,8 @@ Config.MarkerSize = {x = 2.0, y = 2.0, z = 1.0} Config.MarkerColor = {r = 204, g = 204, b = 0} Config.ParkingMarkerSize = {x = 3.0, y = 3.0, z = 2.0} Config.ParkingMarkerColor = {r = 102, g = 102, b = 204} +Config.ZDiff = 0.5 + Config.Locale = 'fr' Config.Zones = {} From 9b2852dc684ef5f6e9c17191c675be9f30893afe Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 16 Aug 2017 15:30:22 -0400 Subject: [PATCH 0404/3224] Multi-language support --- __resource.lua | 8 ++++++++ config.lua | 2 ++ locales/en.lua | 9 +++++++++ locales/fr.lua | 9 +++++++++ server/main.lua | 24 ++++++++++++------------ 5 files changed, 40 insertions(+), 12 deletions(-) create mode 100644 config.lua create mode 100644 locales/en.lua create mode 100644 locales/fr.lua diff --git a/__resource.lua b/__resource.lua index 479a2226..543ec253 100644 --- a/__resource.lua +++ b/__resource.lua @@ -4,9 +4,17 @@ description 'ESX Billing' server_scripts { '@mysql-async/lib/MySQL.lua', + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', + 'config.lua', 'server/main.lua' } client_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', + 'config.lua', 'client/main.lua' } diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..56a8b5e9 --- /dev/null +++ b/config.lua @@ -0,0 +1,2 @@ +Config = {} +Config.Locale = 'fr' diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..5271005b --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,9 @@ +Locales['en'] = { + + ['invoices'] = 'invoices', + ['received_invoice'] = 'you ~r~received~s~ an invoice', + ['paid_invoice'] = 'you ~g~paid~s~ an invoice of ~r~$', + ['received_payment'] = 'you ~g~received~s~ a payment of ~r~$', + ['player_not_logged'] = 'the player is not logged in', + +} diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..46f14598 --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,9 @@ +Locales['fr'] = { + + ['invoices'] = 'factures', + ['received_invoice'] = 'vous avez ~r~reçu~s~ une facture', + ['paid_invoice'] = 'vous avez ~g~payé~s~ une facture de ~r~$', + ['received_payment'] = 'vous avez ~g~reçu~s~ un paiement de ~g~$', + ['player_not_logged'] = 'le joueur n\'est pas connecté', + +} diff --git a/server/main.lua b/server/main.lua index 75c5a788..213da1e7 100644 --- a/server/main.lua +++ b/server/main.lua @@ -26,7 +26,7 @@ AddEventHandler('esx_billing:sendBill', function(playerId, sharedAccountName, la ['@amount'] = amount }, function(rowsChanged) - TriggerClientEvent('esx:showNotification', v.source, 'Vous avez ~r~reçu~s~ une facture') + TriggerClientEvent('esx:showNotification', v.source, _U('received_invoice')) end ) @@ -51,7 +51,7 @@ AddEventHandler('esx_billing:sendBill', function(playerId, sharedAccountName, la ['@amount'] = amount }, function(rowsChanged) - TriggerClientEvent('esx:showNotification', v.source, 'Vous avez ~r~reçu~s~ une facture') + TriggerClientEvent('esx:showNotification', v.source, _U('received_invoice')) end ) @@ -114,7 +114,7 @@ ESX.RegisterServerCallback('esx_billing:payBill', function(source, cb, id) local target = result[1].target local amount = result[1].amount local xPlayers = ESX.GetPlayers() - local foundPlayer = nil + local foundPlayer = nil for k,v in pairs(xPlayers) do if v.identifier == sender then @@ -126,7 +126,7 @@ ESX.RegisterServerCallback('esx_billing:payBill', function(source, cb, id) if targetType == 'player' then if foundPlayer ~= nil then - + if xPlayer.get('money') >= amount then MySQL.Async.execute( @@ -139,8 +139,8 @@ ESX.RegisterServerCallback('esx_billing:payBill', function(source, cb, id) xPlayer.removeMoney(amount) foundPlayer.addMoney(amount) - TriggerClientEvent('esx:showNotification', xPlayer.source, 'Vous avez ~g~payé~s~ une facture de ~r~$' .. amount) - TriggerClientEvent('esx:showNotification', foundPlayer.source, 'Vous avez ~g~reçu~s~ un paiement de ~g~$' .. amount) + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('paid_invoice') .. amount) + TriggerClientEvent('esx:showNotification', foundPlayer.source, _U('received_payment') .. amount) cb() @@ -148,7 +148,7 @@ ESX.RegisterServerCallback('esx_billing:payBill', function(source, cb, id) ) else - TriggerClientEvent('esx:showNotification', _source, 'Le joueur n\'est pas connecté') + TriggerClientEvent('esx:showNotification', _source, _U('player_not_logged')) cb() end @@ -168,17 +168,17 @@ ESX.RegisterServerCallback('esx_billing:payBill', function(source, cb, id) xPlayer.removeMoney(amount) account.addMoney(amount) - TriggerClientEvent('esx:showNotification', xPlayer.source, 'Vous avez ~g~payé~s~ une facture de ~r~$' .. amount) - + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('paid_invoice') .. amount) + if foundPlayer ~= nil then - TriggerClientEvent('esx:showNotification', foundPlayer.source, 'Vous avez ~g~reçu~s~ un paiement de ~g~$' .. amount) + TriggerClientEvent('esx:showNotification', foundPlayer.source, _U('received_payment') .. amount) end cb() end ) - + end) end @@ -186,4 +186,4 @@ ESX.RegisterServerCallback('esx_billing:payBill', function(source, cb, id) end ) -end) \ No newline at end of file +end) From 0df0ee8273b0fd949563c38db82d071b85ca3a8a Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Wed, 16 Aug 2017 18:16:10 -0400 Subject: [PATCH 0405/3224] Multi-language support --- __resource.lua | 6 ++- client/main.lua | 132 ++++++++++++++++++++++++------------------------ config.lua | 2 + locales/en.lua | 53 +++++++++++++++++++ locales/fr.lua | 54 ++++++++++++++++++++ 5 files changed, 180 insertions(+), 67 deletions(-) create mode 100644 config.lua create mode 100644 locales/en.lua create mode 100644 locales/fr.lua diff --git a/__resource.lua b/__resource.lua index 5afa8772..472826ea 100644 --- a/__resource.lua +++ b/__resource.lua @@ -3,5 +3,9 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'SkinChanger' client_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', + 'config.lua', 'client/main.lua' -} \ No newline at end of file +} diff --git a/client/main.lua b/client/main.lua index 5428b3a5..e1cfabac 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,54 +1,54 @@ local Components = { - {label = 'Sexe', name = 'sex', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- - {label = 'Visage', name = 'face', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- - {label = 'Peau', name = 'skin', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- - {label = 'Rides', name = 'age_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = 'Epaisseur rides', name = 'age_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = 'Type Barbe', name = 'beard_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = 'Taille barbe', name = 'beard_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = 'Couleur barbe 1', name = 'beard_3', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = 'Couleur barbe 2', name = 'beard_4', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = 'Cheveux 1', name = 'hair_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- - {label = 'Cheveux 2', name = 'hair_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- - {label = 'Couleur cheveux 1', name = 'hair_color_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- - {label = 'Couleur cheveux 2', name = 'hair_color_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- - {label = 'Type Sourcils', name = 'eyebrows_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = 'Taille Sourcils', name = 'eyebrows_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = 'Couleur Sourcils 1', name = 'eyebrows_3', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = 'Couleur Sourcils 2', name = 'eyebrows_4', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = 'Type Maquillage', name = 'makeup_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = 'Epaisseur Maquillage', name = 'makeup_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = 'Couleur Maquillage 1', name = 'makeup_3', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = 'Couleur Maquillage 2', name = 'makeup_4', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = 'Type Lipstick', name = 'lipstick_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = 'Epaisseur Lipstick', name = 'lipstick_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = 'Couleur Lipstick 1', name = 'lipstick_3', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = 'Couleur Lipstick 2', name = 'lipstick_4', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = 'Accessoire Oreilles',name = 'ears_1', value = -1, min = -1, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = 'Couleur Accessoire', name = 'ears_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65, textureof = 'ears_1'}, -- - {label = 'T-Shirt 1', name = 'tshirt_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- - {label = 'T-Shirt 2', name = 'tshirt_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'tshirt_1'}, -- - {label = 'Torse 1', name = 'torso_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- - {label = 'Torse 2', name = 'torso_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'torso_1'}, -- - {label = 'Calques 1', name = 'decals_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- - {label = 'Calques 2', name = 'decals_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'decals_1'}, -- - {label = 'Bras', name = 'arms', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- - {label = 'Jambes 1', name = 'pants_1', value = 0, min = 0, zoomOffset = 0.8, camOffset = -0.5}, -- - {label = 'Jambes 2', name = 'pants_2', value = 0, min = 0, zoomOffset = 0.8, camOffset = -0.5, textureof = 'pants_1'}, -- - {label = 'Chaussures 1', name = 'shoes_1', value = 0, min = 0, zoomOffset = 0.8, camOffset = -0.8}, - {label = 'Chaussures 2', name = 'shoes_2', value = 0, min = 0, zoomOffset = 0.8, camOffset = -0.8, textureof = 'shoes_1'}, - {label = 'Masque 1', name = 'mask_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- - {label = 'Masque 2', name = 'mask_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65, textureof = 'mask_1'}, -- - {label = 'Gilet pare-balle 1', name = 'bproof_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- - {label = 'Gilet pare-balle 2', name = 'bproof_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'bproof_1'}, -- - {label = 'Chaine 1', name = 'chain_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- - {label = 'Chaine 2', name = 'chain_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65, textureof = 'chain_1'}, -- - {label = 'Casque 1', name = 'helmet_1', value = -1, min = -1, componentId = 0, zoomOffset = 0.6, camOffset = 0.65}, -- - {label = 'Casque 2', name = 'helmet_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65, textureof = 'helmet_1'}, -- - {label = 'Lunettes 1', name = 'glasses_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- - {label = 'Lunettes 2', name = 'glasses_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65, textureof = 'glasses_1'}, -- - {label = 'Sac', name = 'bags_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, - {label = 'Couleur Sac', name = 'bags_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'bags_1'} + {label = _U('sex'), name = 'sex', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = _U('face'), name = 'face', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = _U('skin'), name = 'skin', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = _U('wrinkles'), name = 'age_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('wrinkle_thickness'), name = 'age_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('beard_type'), name = 'beard_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('beard_size'), name = 'beard_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('beard_color_1'), name = 'beard_3', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('beard_color_2'), name = 'beard_4', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('hair_1'), name = 'hair_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = _U('hair_2'), name = 'hair_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = _U('hair_color_1'), name = 'hair_color_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = _U('hair_color_2'), name = 'hair_color_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = _U('eyebrow_type'), name = 'eyebrows_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('eyebrow_size'), name = 'eyebrows_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('eyebrow_color_1'), name = 'eyebrows_3', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('eyebrow_color_2'), name = 'eyebrows_4', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('makeup_type'), name = 'makeup_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('makeup_thickness'), name = 'makeup_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('makeup_color_1'), name = 'makeup_3', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('makeup_color_2'), name = 'makeup_4', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('lipstick_type'), name = 'lipstick_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('lipstick_thickness'), name = 'lipstick_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('lipstick_color_1'), name = 'lipstick_3', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('lipstick_color_2'), name = 'lipstick_4', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('ear_accessories'), name = 'ears_1', value = -1, min = -1, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('ear_accessories_color'), name = 'ears_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65, textureof = 'ears_1'}, -- + {label = _U('tshirt_1'), name = 'tshirt_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- + {label = _U('tshirt_2'), name = 'tshirt_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'tshirt_1'}, -- + {label = _U('torso_1'), name = 'torso_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- + {label = _U('torso_2'), name = 'torso_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'torso_1'}, -- + {label = _U('decals_1'), name = 'decals_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- + {label = _U('decals_2'), name = 'decals_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'decals_1'}, -- + {label = _('arms'), name = 'arms', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- + {label = _U('pants_1'), name = 'pants_1', value = 0, min = 0, zoomOffset = 0.8, camOffset = -0.5}, -- + {label = _U('pants_2'), name = 'pants_2', value = 0, min = 0, zoomOffset = 0.8, camOffset = -0.5, textureof = 'pants_1'}, -- + {label = _U('shoes_1'), name = 'shoes_1', value = 0, min = 0, zoomOffset = 0.8, camOffset = -0.8}, + {label = _U('shoes_2'), name = 'shoes_2', value = 0, min = 0, zoomOffset = 0.8, camOffset = -0.8, textureof = 'shoes_1'}, + {label = _U('mask_1'), name = 'mask_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = _U('mask_2'), name = 'mask_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65, textureof = 'mask_1'}, -- + {label = _U('bproof_1'), name = 'bproof_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- + {label = _U('bproof_2'), name = 'bproof_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'bproof_1'}, -- + {label = U('chain_1'), name = 'chain_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = _U('chain_2'), name = 'chain_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65, textureof = 'chain_1'}, -- + {label = _U('helmet_1'), name = 'helmet_1', value = -1, min = -1, componentId = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = _U('helmet_2'), name = 'helmet_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65, textureof = 'helmet_1'}, -- + {label = _U('glasses_1'), name = 'glasses_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = _U('glasses_2'), name = 'glasses_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65, textureof = 'glasses_1'}, -- + {label = _U('bag'), name = 'bags_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, + {label = _U('bag_color'), name = 'bags_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'bags_1'} } local LastSex = 0 @@ -122,7 +122,7 @@ function GetMaxVals() lipstick_1 = GetNumHeadOverlayValues(8)-1, lipstick_2 = 10, lipstick_3 = 9, - lipstick_4 = 9, + lipstick_4 = 9, ears_1 = GetNumberOfPedPropDrawableVariations(playerPed, 1) - 1, ears_2 = GetNumberOfPedPropTextureVariations(playerPed, 1, Character['ears_1'] - 1), tshirt_1 = GetNumberOfPedDrawableVariations(playerPed, 8) - 1, @@ -155,13 +155,13 @@ function GetMaxVals() end function ApplySkin(skin, clothes) - + local playerPed = GetPlayerPed(-1) for k,v in pairs(skin) do Character[k] = v end - + if clothes ~= nil then for k,v in pairs(clothes) do @@ -199,10 +199,10 @@ function ApplySkin(skin, clothes) end SetPedHeadBlendData(playerPed, Character['face'], Character['face'], Character['face'], Character['skin'], Character['skin'], Character['skin'], 1.0, 1.0, 1.0, true) - + SetPedHeadOverlay(playerPed, 3, Character['age_1'], (Character['age_2'] / 10) + 0.0) -- Age + opacity SetPedHeadOverlay(playerPed, 1, Character['beard_1'], (Character['beard_2'] / 10) + 0.0) -- Beard + opacity - SetPedHeadOverlayColor(playerPed, 1, 1, Character['beard_3'], Character['beard_4']) -- Beard Color + SetPedHeadOverlayColor(playerPed, 1, 1, Character['beard_3'], Character['beard_4']) -- Beard Color SetPedHeadOverlay(playerPed, 2, Character['eyebrows_1'], (Character['eyebrows_2'] / 10) + 0.0) -- Eyebrows + opacity SetPedHeadOverlayColor(playerPed, 1, 1, Character['eyebrows_3'], Character['eyebrows_4']) -- Eyebrows Color SetPedHeadOverlay(playerPed, 4, Character['makeup_1'], (Character['makeup_2'] / 10) + 0.0) -- Makeup + opacity @@ -211,13 +211,13 @@ function ApplySkin(skin, clothes) SetPedHeadOverlayColor(playerPed, 2, 1, Character['lipstick_3'], Character['lipstick_4']) -- Lipstick Color SetPedComponentVariation(playerPed, 2, Character['hair_1'], Character['hair_2'], 2) -- Hair SetPedHairColor(playerPed, Character['hair_color_1'], Character['hair_color_2']) -- Hair Color - + if Character['ears_1'] == -1 then ClearPedProp(playerPed, 2) else SetPedPropIndex(playerPed, 2, Character['ears_1'], Character['ears_2'], 2) -- Ears Accessories end - + SetPedComponentVariation(playerPed, 8, Character['tshirt_1'],Character['tshirt_2'], 2) -- Tshirt SetPedComponentVariation(playerPed, 11, Character['torso_1'], Character['torso_2'], 2) -- torso parts SetPedComponentVariation(playerPed, 3, Character['arms'], 0, 2) -- torso @@ -228,13 +228,13 @@ function ApplySkin(skin, clothes) SetPedComponentVariation(playerPed, 9, Character['bproof_1'], Character['bproof_2'], 2) -- bulletproof SetPedComponentVariation(playerPed, 7, Character['chain_1'], Character['chain_2'], 2) -- chain SetPedComponentVariation(playerPed, 5, Character['bags_1'], Character['bags_2'], 2) -- Bag - + if Character['helmet_1'] == -1 then ClearPedProp(playerPed, 0) else SetPedPropIndex(playerPed, 0, Character['helmet_1'], Character['helmet_2'], 2) -- Helmet end - + SetPedPropIndex(playerPed, 1, Character['glasses_1'], Character['glasses_2'], 2) -- Glasses end @@ -244,7 +244,7 @@ AddEventHandler('skinchanger:loadDefaultModel', function(loadMale) end) AddEventHandler('skinchanger:getData', function(cb) - + local components = json.decode(json.encode(Components)) for k,v in pairs(Character) do @@ -284,11 +284,11 @@ AddEventHandler('skinchanger:modelLoaded', function() ApplySkin(LoadSkin) LoadSkin = nil - + end if LoadClothes ~= nil then - + ApplySkin(LoadClothes.playerSkin, LoadClothes.clothesSkin) LoadClothes = nil @@ -298,7 +298,7 @@ end) RegisterNetEvent('skinchanger:loadSkin') AddEventHandler('skinchanger:loadSkin', function(skin) - + LoadSkin = skin if skin['sex'] == 0 then @@ -306,14 +306,14 @@ AddEventHandler('skinchanger:loadSkin', function(skin) else TriggerEvent('skinchanger:loadDefaultModel', false) end - + LastSex = skin['sex'] end) RegisterNetEvent('skinchanger:loadClothes') AddEventHandler('skinchanger:loadClothes', function(playerSkin, clothesSkin) - + LoadClothes = { playerSkin = playerSkin, clothesSkin = clothesSkin @@ -327,4 +327,4 @@ AddEventHandler('skinchanger:loadClothes', function(playerSkin, clothesSkin) LastSex = playerSkin['sex'] -end) \ No newline at end of file +end) diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..56a8b5e9 --- /dev/null +++ b/config.lua @@ -0,0 +1,2 @@ +Config = {} +Config.Locale = 'fr' diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..b3eee58b --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,53 @@ +Locales['en'] = { + + ['sex'] = 'sex', + ['face'] = 'face', + ['skin'] = 'skin', + ['wrinkles'] = 'wrinkles', + ['wrinkle_thickness'] = 'wrinkle thickness', + ['beard_type'] = 'beard type', + ['beard_size'] = 'beard size', + ['beard_color_1'] = 'beard color 1', + ['beard_color_2'] = 'beard color 2', + ['hair_1'] = 'hair 1', + ['hair_2'] = 'hair 2', + ['hair_color_1'] = 'hair color 1', + ['hair_color_2'] = 'hair color 2', + ['eyebrow_type'] = 'eyebrow type', + ['eyebrow_size'] = 'eyebrow size', + ['eyebrow_color_1'] = 'eyebrow color 1', + ['eyebrow_color_2'] = 'eyebrow color 2', + ['makeup_type'] = 'makeup type', + ['makeup_thickness'] = 'makeup thickness', + ['makeup_color_1'] = 'makeup color 1', + ['makeup_color_2'] = 'makeup color 2', + ['lipstick_type'] = 'lipstick type', + ['lipstick_thickness'] = 'lipstick thickness', + ['lipstick_color_1'] = 'lipstick color 1', + ['lipstick_color_2'] = 'lipstick color 2', + ['ear_accessories'] = 'ear accessories', + ['ear_accessories_color'] = 'ear accessories color', + ['tshirt_1'] = 't-Shirt 1', + ['tshirt_2'] = 't-Shirt 2', + ['torso_1'] = 'torso 1', + ['torso_2'] = 'torso 2', + ['decals_1'] = 'decals 1', + ['decals_2'] = 'decals 2', + ['arms'] = 'arms', + ['pants_1'] = 'pants 1', + ['pants_2'] = 'pants 2', + ['shoes_1'] = 'shoes 1', + ['shoes_2'] = 'shoes 2', + ['mask_1'] = 'mask 1', + ['mask_2'] = 'mask 2', + ['bproof_1'] = 'bulletproof vest 1', + ['bproof_2'] = 'bulletproof vest 2', + ['chain_1'] = 'chain 1', + ['chain_2'] = 'chain 2', + ['helmet_1'] = 'helmet 1', + ['helmet_2'] = 'helmet 2', + ['glasses_1'] = 'glasses 1', + ['glasses_2'] = 'glasses 2', + ['bag'] = 'bag', + ['bag_color'] = 'bag color', +} diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..61cec30c --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,54 @@ +Locales['fr'] = { + + ['sex'] = 'sexe', + ['face'] = 'visage', + ['skin'] = 'peau', + ['wrinkles'] = 'rides', + ['wrinkle_thickness'] = 'épaisseur rides', + ['beard_type'] = 'type barbe', + ['beard_size'] = 'taille barbe', + ['beard_color_1'] = 'couleur barbe 1', + ['beard_color_2'] = 'couleur barbe 2', + ['hair_1'] = 'cheveux 1', + ['hair_2'] = 'cheveux 2', + ['hair_color_1'] = 'couleur cheveux 1', + ['hair_color_2'] = 'couleur cheveux 2', + ['eyebrow_type'] = 'type sourcils', + ['eyebrow_size'] = 'taille sourcils', + ['eyebrow_color_1'] = 'couleur sourcils 1', + ['eyebrow_color_2'] = 'couleur sourcils 2', + ['makeup_type'] = 'type maquillage', + ['makeup_thickness'] = 'épaisseur maquillage', + ['makeup_color_1'] = 'couleur maquillage 1', + ['makeup_color_2'] = 'couleur maquillage 2', + ['lipstick_type'] = 'type lipstick', + ['lipstick_thickness'] = 'épaisseur lipstick', + ['lipstick_color_1'] = 'couleur lipstick 1', + ['lipstick_color_2'] = 'couleur lipstick 2', + ['ear_accessories'] = 'accessoire oreilles', + ['ear_accessories_color'] = 'couleur accessoire', + ['tshirt_1'] = 't-Shirt 1', + ['tshirt_2'] = 't-Shirt 2', + ['torso_1'] = 'torse 1', + ['torso_2'] = 'torse 2', + ['decals_1'] = 'calques 1', + ['decals_2'] = 'calques 2', + ['arms'] = 'bras', + ['pants_1'] = 'jambes 1', + ['pants_2'] = 'jambes 2', + ['shoes_1'] = 'chaussures 1', + ['shoes_2'] = 'chaussures 2', + ['mask_1'] = 'masque 1', + ['mask_2'] = 'masque 2', + ['bproof_1'] = 'gilet pare-balle 1', + ['bproof_2'] = 'gilet pare-balle 2', + ['chain_1'] = 'chaine 1', + ['chain_2'] = 'chaine 2', + ['helmet_1'] = 'casque 1', + ['helmet_2'] = 'casque 2', + ['glasses_1'] = 'lunettes 1', + ['glasses_2'] = 'lunettes 2', + ['bag'] = 'sac', + ['bag_color'] = 'couleur sac', + +} From 6fb9541854366def76a76b667c1339b2daaa8bcc Mon Sep 17 00:00:00 2001 From: Wesley Moura <14825927+wesleymoura@users.noreply.github.com> Date: Wed, 16 Aug 2017 19:39:24 -0300 Subject: [PATCH 0406/3224] Update __resource.lua Multi-Language support --- __resource.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/__resource.lua b/__resource.lua index a061ec00..c2a4388e 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,5 +1,6 @@ server_scripts { '@es_extended/locale.lua', + 'locales/ptbr.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', @@ -8,6 +9,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/ptbr.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', From 1d1cda05e25a3ac3c743e00c7add09ee7a9f4d74 Mon Sep 17 00:00:00 2001 From: Wesley Moura <14825927+wesleymoura@users.noreply.github.com> Date: Wed, 16 Aug 2017 19:40:04 -0300 Subject: [PATCH 0407/3224] Create ptbr Multi-Language support --- locales/ptbr | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 locales/ptbr diff --git a/locales/ptbr b/locales/ptbr new file mode 100644 index 00000000..cf9b5e4b --- /dev/null +++ b/locales/ptbr @@ -0,0 +1,6 @@ +Locales['ptbr'] = { + ['invalid_amount'] = '~r~Quantidade inválida', + ['deposit_money'] = 'Você depósitou ~g~$', + ['withdraw_money'] = 'Você retirou ~g~$', + ['press_e_atm'] = 'Pressione ~INPUT_PICKUP~ para depósitos ou retiradas do ~g~ATM~s~.', +} From f25c679e764cccb9c5fa883da0ca47ce1dc1372a Mon Sep 17 00:00:00 2001 From: renaiku Date: Thu, 17 Aug 2017 01:30:29 +0200 Subject: [PATCH 0408/3224] MOAR helmets, caps and glasses colors --- client/main.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index e1cfabac..3c81a518 100644 --- a/client/main.lua +++ b/client/main.lua @@ -145,9 +145,9 @@ function GetMaxVals() bags_1 = GetNumberOfPedDrawableVariations(playerPed, 5) - 1, bags_2 = GetNumberOfPedTextureVariations(playerPed, 5, Character['bags_1']) - 1, helmet_1 = GetNumberOfPedPropDrawableVariations(playerPed, 0) - 1, - helmet_2 = GetNumberOfPedTextureVariations(playerPed, 0, Character['helmet_1']) - 1, + helmet_2 = GetNumberOfPedPropTextureVariations(playerPed, 0, Character['helmet_1']) - 1, glasses_1 = GetNumberOfPedPropDrawableVariations(playerPed, 1) - 1, - glasses_2 = GetNumberOfPedTextureVariations(playerPed, 1, Character['glasses_1'] - 1), + glasses_2 = GetNumberOfPedPropTextureVariations(playerPed, 1, Character['glasses_1'] - 1), } return data From 2d25448c5ff43d04b47ab90efc2a81c64f4c2c3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 17 Aug 2017 01:41:50 +0200 Subject: [PATCH 0409/3224] fix filename --- locales/{ptbr => ptbr.lua} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename locales/{ptbr => ptbr.lua} (100%) diff --git a/locales/ptbr b/locales/ptbr.lua similarity index 100% rename from locales/ptbr rename to locales/ptbr.lua From 1f8c37fd0a22a1b01ccd1b9441ad17c736abe884 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Wed, 16 Aug 2017 20:08:14 -0400 Subject: [PATCH 0410/3224] Multi-language support --- __resource.lua | 22 ++++++++++++++++++++-- client/main.lua | 32 ++++++++++++++++---------------- config.lua | 2 ++ locales/en.lua | 8 ++++++++ locales/fr.lua | 8 ++++++++ 5 files changed, 54 insertions(+), 18 deletions(-) create mode 100644 config.lua create mode 100644 locales/en.lua create mode 100644 locales/fr.lua diff --git a/__resource.lua b/__resource.lua index 4b1f559e..3bcf89ea 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,5 +2,23 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'Instance' -server_script 'server/main.lua' -client_script 'client/main.lua' +server_scripts { + + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', + 'config.lua', + 'server/main.lua' + +} + + +client_scripts { + + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', + 'config.lua', + 'client/main.lua' + +} diff --git a/client/main.lua b/client/main.lua index d61a7d0a..80989c6d 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,10 +1,10 @@ local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 @@ -41,9 +41,9 @@ end function LeaveInstance() if Instance.host ~= nil then - + if #Instance.players > 1 then - TriggerEvent('esx:showNotification', 'Vous avez quitté l\'instance') + TriggerEvent('esx:showNotification', _U('left_instance')) end TriggerServerEvent('instance:leave', Instance.host) @@ -91,18 +91,18 @@ end) RegisterNetEvent('instance:onInvite') AddEventHandler('instance:onInvite', function(instance, pos) - + InstanceInvite = { host = instance, pos = pos } Citizen.CreateThread(function() - + Citizen.Wait(10000) if InstanceInvite ~= nil then - ShowNotification('Invitation expirée') + ShowNotification(_U('invite_expired')) InstanceInvite = nil end @@ -118,7 +118,7 @@ Citizen.CreateThread(function() if InstanceInvite ~= nil then SetTextComponentFormat('STRING') - AddTextComponentString('Appuyez sur ~INPUT_CONTEXT~ pour entrer dans l\'instance') + AddTextComponentString(_U('press_to_enter')) DisplayHelpTextFromStringLabel(0, 0, 1, -1) end @@ -139,8 +139,8 @@ Citizen.CreateThread(function() SetEntityCoords(playerPed, InstanceInvite.pos.x, InstanceInvite.pos.y, InstanceInvite.pos.z) - ShowNotification('Vous êtes entré dans l\'instance') - + ShowNotification(_U('entered_instance')) + InstanceInvite = nil GUI.Time = GetGameTimer() @@ -162,11 +162,11 @@ Citizen.CreateThread(function() local playerPed = GetPlayerPed(-1) for i=0, 32, 1 do - + local found = false for j=1, #Instance.players, 1 do - + instancePlayer = GetPlayerFromServerId(Instance.players[j]) if i == instancePlayer then @@ -190,11 +190,11 @@ Citizen.CreateThread(function() local playerPed = GetPlayerPed(-1) for i=0, 32, 1 do - + local found = false for j=1, #InstancedPlayers, 1 do - + instancePlayer = GetPlayerFromServerId(InstancedPlayers[j]) if i == instancePlayer then @@ -217,4 +217,4 @@ Citizen.CreateThread(function() end -end) \ No newline at end of file +end) diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..56a8b5e9 --- /dev/null +++ b/config.lua @@ -0,0 +1,2 @@ +Config = {} +Config.Locale = 'fr' diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..2ba5f274 --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,8 @@ +Locales['en'] = { + + ['left_instance'] = 'you have left the instance', + ['invite_expired'] = 'invite expired', + ['press_to_enter'] = 'press ~INPUT_CONTEXT~ to enter the instance', + ['entered_instance'] = 'you entered the instance', + +} diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..83f595e9 --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,8 @@ +Locales['fr'] = { + + ['left_instance'] = 'vous avez quitté l\'instance', + ['invite_expired'] = 'invitation expirée', + ['press_to_enter'] = 'appuyez sur ~INPUT_CONTEXT~ pour entrer dans l\'instance', + ['entered_instance'] = 'vous êtes entré dans l\'instance', + +} From cdab4fb686cd757af6583444a546d198aa92e078 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Wed, 16 Aug 2017 20:50:15 -0400 Subject: [PATCH 0411/3224] Multi-language support --- __resource.lua | 8 ++++++++ config.lua | 2 ++ locales/en.lua | 9 +++++++++ locales/fr.lua | 9 +++++++++ server/main.lua | 16 ++++++++-------- 5 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 config.lua create mode 100644 locales/en.lua create mode 100644 locales/fr.lua diff --git a/__resource.lua b/__resource.lua index 9287ed13..bf87ae44 100644 --- a/__resource.lua +++ b/__resource.lua @@ -4,9 +4,17 @@ description 'ESX Society' server_scripts { '@mysql-async/lib/MySQL.lua', + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', + 'config.lua', 'server/main.lua' } client_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', + 'config.lua', 'client/main.lua' } diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..56a8b5e9 --- /dev/null +++ b/config.lua @@ -0,0 +1,2 @@ +Config = {} +Config.Locale = 'fr' diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..90ecab88 --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,9 @@ +Locales['en'] = { + + ['have_withdrawn'] = 'you have withdrawn ~g~$', + ['invalid_amount'] = 'invalid amount', + ['have_deposited'] = 'you have deposited ~r~$', + ['you_have'] = 'you have ~g~$', + ['you_have_laundered'] = 'you have ~r~laundered~s~ your money: ~g~$', + +} diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..6004ee9b --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,9 @@ +Locales['fr'] = { + + ['have_withdrawn'] = 'vous avez retiré ~g~$', + ['invalid_amount'] = 'montant invalide', + ['have_deposited'] = 'vous avez déposé ~r~$', + ['you_have'] = 'vous avez ~g~$', + ['you_have_laundered'] = 'Vous avez ~r~blanchi~s~ votre argent : ~g~$', + +} diff --git a/server/main.lua b/server/main.lua index 0e30cf2e..29726b19 100644 --- a/server/main.lua +++ b/server/main.lua @@ -14,10 +14,10 @@ AddEventHandler('esx_society:withdrawMoney', function(society, amount) account.removeMoney(amount) xPlayer.addMoney(amount) - TriggerClientEvent('esx:showNotification', xPlayer.source, 'Vous avez retiré ~g~$' .. amount) + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('have_withdrawn') .. amount) else - TriggerClientEvent('esx:showNotification', xPlayer.source, 'Montant invalide') + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('invalid_amount')) end end) @@ -36,10 +36,10 @@ AddEventHandler('esx_society:depositMoney', function(society, amount) account.addMoney(amount) end) - TriggerClientEvent('esx:showNotification', xPlayer.source, 'Vous avez déposé ~r~$' .. amount) + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('have_deposited') .. amount) else - TriggerClientEvent('esx:showNotification', xPlayer.source, 'Montant invalide') + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('invalid_amount')) end end) @@ -62,12 +62,12 @@ AddEventHandler('esx_society:washMoney', function(society, amount) ['@amount'] = amount }, function(rowsChanged) - TriggerClientEvent('esx:showNotification', xPlayer.source, 'Vous avez ~g~$' .. amount .. '~s~ en attente de ~r~blanchiement~s~ (24h)') + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('you_have') .. amount .. '~s~ en attente de ~r~blanchiement~s~ (24h)') end ) else - TriggerClientEvent('esx:showNotification', xPlayer.source, 'Montant invalide') + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('invalid_amount')) end end) @@ -104,7 +104,7 @@ function WashMoneyCRON(d, h, m) end) if foundPlayer then - TriggerClientEvent('esx:showNotification', xPlayer.source, 'Vous avez ~r~blanchi~s~ votre argent : ~g~$' .. result[i].amount) + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('you_have_laundered') .. result[i].amount) end MySQL.Async.execute( @@ -121,4 +121,4 @@ function WashMoneyCRON(d, h, m) end -TriggerEvent('cron:runAt', 3, 0, WashMoneyCRON) \ No newline at end of file +TriggerEvent('cron:runAt', 3, 0, WashMoneyCRON) From 61b65663a44b35c3914fa393e5f083ed4dd35de2 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Wed, 16 Aug 2017 21:44:39 -0400 Subject: [PATCH 0412/3224] Multi-language support --- __resource.lua | 10 ++++++-- client/esx_holdup_cl.lua | 14 +++++------ config.lua | 3 +++ locales/en.lua | 23 ++++++++++++++++++ locales/fr.lua | 23 ++++++++++++++++++ server/esx_holdup_sv.lua | 52 ++++++++++++++++++++-------------------- 6 files changed, 90 insertions(+), 35 deletions(-) create mode 100644 locales/en.lua create mode 100644 locales/fr.lua diff --git a/__resource.lua b/__resource.lua index 6bc532a3..1ea8c6b8 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,11 +1,17 @@ dependency 'essentialmode' -client_script { +client_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', 'config.lua', 'client/esx_holdup_cl.lua' } -server_script { +server_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', 'config.lua', 'server/esx_holdup_sv.lua' } diff --git a/client/esx_holdup_cl.lua b/client/esx_holdup_cl.lua index 684625bd..059b8fda 100644 --- a/client/esx_holdup_cl.lua +++ b/client/esx_holdup_cl.lua @@ -57,7 +57,7 @@ end) RegisterNetEvent('esx_holdup:toofarlocal') AddEventHandler('esx_holdup:toofarlocal', function(robb) holdingup = false - ESX.ShowNotification('Le braquage vas être annulé, vous ne gagnerez rien!') + ESX.ShowNotification(_U('robbery_cancelled')) robbingName = "" secondsRemaining = 0 incircle = false @@ -67,7 +67,7 @@ end) RegisterNetEvent('esx_holdup:robberycomplete') AddEventHandler('esx_holdup:robberycomplete', function(robb) holdingup = false - ESX.ShowNotification('Braquage réussi vous avez gagné ~g~$' .. Stores[store].reward) + ESX.ShowNotification(_U('robbery_cancelled') .. Stores[store].reward) store = "" secondsRemaining = 0 incircle = false @@ -94,7 +94,7 @@ Citizen.CreateThread(function() SetBlipScale(blip, 0.8) SetBlipAsShortRange(blip, true) BeginTextCommandSetBlipName("STRING") - AddTextComponentString("Braquage magasin") + AddTextComponentString(_U('shop_robbery')) EndTextCommandSetBlipName(blip) end end) @@ -110,10 +110,10 @@ Citizen.CreateThread(function() if(Vdist(pos.x, pos.y, pos.z, pos2.x, pos2.y, pos2.z) < 15.0)then if not holdingup then DrawMarker(1, v.position.x, v.position.y, v.position.z - 1, 0, 0, 0, 0, 0, 0, 1.0001, 1.0001, 1.5001, 1555, 0, 0,255, 0, 0, 0,0) - + if(Vdist(pos.x, pos.y, pos.z, pos2.x, pos2.y, pos2.z) < 1.0)then if (incircle == false) then - DisplayHelpText("Appuyer sur ~INPUT_CONTEXT~ pour braquer ~b~" .. v.nameofstore) + DisplayHelpText(_U('press_to_rob') .. v.nameofstore) end incircle = true if IsControlJustReleased(1, 51) then @@ -128,8 +128,8 @@ Citizen.CreateThread(function() if holdingup then - drawTxt(0.66, 1.44, 1.0,1.0,0.4, "Braquage de magasin: ~r~" .. secondsRemaining .. "~w~ secondes restantes", 255, 255, 255, 255) - + drawTxt(0.66, 1.44, 1.0,1.0,0.4, _U('robbery_of') .. secondsRemaining .. _U('seconds_remaining'), 255, 255, 255, 255) + local pos2 = Stores[store].position if(Vdist(pos.x, pos.y, pos.z, pos2.x, pos2.y, pos2.z) > 7.5)then diff --git a/config.lua b/config.lua index 36d3e732..2ac8d1c9 100644 --- a/config.lua +++ b/config.lua @@ -1,3 +1,6 @@ +Config = {} +Config.Locale = 'fr' + Stores = { --[["paleto_twentyfourseven"] = { position = { ['x'] = 1736.32092285156, ['y'] = 6419.4970703125, ['z'] = 35.037223815918 }, diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..6e6ce02d --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,23 @@ +Locales['en'] = { + + ['robbery_cancelled'] = 'the robbery will be cancelled, you will gain nothing!', + ['robbery_successful'] = 'successful robbery you have gained ~g~$', + ['shop_robbery'] = 'shop Robbery', + ['press_to_rob'] = 'press ~INPUT_CONTEXT~ to rob ~b~', + ['robbery_of'] = 'store robbery: ~r~', + ['seconds_remaining'] = '~w~ seconds remaning', + ['robbery_cancelled_at'] = '~r~ Robbery cancelled at: ~b~', + ['robbery_has_cancelled'] = '~r~ robbery has been cancelled: ~b~', + ['already_robbed'] = 'this store has already been robbed. Please wait: ', + ['seconds'] = 'seconds.', + ['rob_in_prog'] = '~r~ robbery in progress at: ~b~', + ['started_to_rob'] = 'you started to rob ', + ['do_not_move'] = ', do not move away!', + ['alarm_triggered'] = 'the alarm has been triggered', + ['hold_pos'] = 'hold for 5 minutes and the money is yours!', + ['robbery_complete'] = '~r~ Robbery complete.~s~ ~h~ Run!', + ['robbery_complete_at'] = '~r~ Robbery complete at: ~b~', + ['min_two_police'] = 'there must be at least ~b~2 policemen~s~ in town to rob.', + ['robbery_already'] = '~r~A robbery is already in progress.', + +} diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..ceb928af --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,23 @@ +Locales['fr'] = { + + ['robbery_cancelled'] = 'le braquage vas être annulé, vous ne gagnerez rien!', + ['robbery_successful'] = 'braquage réussi vous avez gagné ~g~$', + ['shop_robbery'] = 'braquage magasin', + ['press_to_rob'] = 'appuyer sur ~INPUT_CONTEXT~ pour braquer ~b~', + ['robbery_of'] = 'braquage de magasin: ~r~', + ['seconds_remaining'] = '~w~ secondes restantes', + ['robbery_cancelled_at'] = '~r~ Braquage annulé à: ~b~', + ['robbery_has_cancelled'] = '~r~ le braquage à été annulé: ~b~', + ['already_robbed'] = 'ce magasin a déjà été braqué. Veuillez attendre: ', + ['seconds'] = 'secondes.', + ['rob_in_prog'] = '~r~ braquage en cours à: ~b~', + ['started_to_rob'] = 'vous avez commencé à braquer ', + ['do_not_move'] = ', ne vous éloignez pas!', + ['alarm_triggered'] = 'l\'alarme à été déclenché', + ['hold_pos'] = 'tenez la position pendant 5min et l\'argent est à vous!', + ['robbery_complete'] = '~r~ Braquage terminé.~s~ ~h~ Fuie!', + ['robbery_complete_at'] = '~r~ Braquage terminé à: ~b~' + ['min_two_police'] = 'il faut minimum ~b~2 policiers~s~ en ville pour braquer.', + ['robbery_already'] = '~r~Un braquage est déjà en cours.', + +} diff --git a/server/esx_holdup_sv.lua b/server/esx_holdup_sv.lua index f58e3f49..721ef341 100644 --- a/server/esx_holdup_sv.lua +++ b/server/esx_holdup_sv.lua @@ -15,36 +15,36 @@ AddEventHandler('esx_holdup:toofar', function(robb) rob = false for k, v in pairs(xPlayers) do if v.job.name == 'police' then - TriggerClientEvent('esx:showNotification', k, '~r~ Braquage annulé à: ~b~' .. Stores[robb].nameofstore) + TriggerClientEvent('esx:showNotification', k, _U('robbery_cancelled_at') .. Stores[robb].nameofstore) TriggerClientEvent('esx_holdup:killblip', k) end end if(robbers[source])then TriggerClientEvent('esx_holdup:toofarlocal', source) robbers[source] = nil - TriggerClientEvent('esx:showNotification', source, '~r~ Le braquage à été annulé: ~b~' .. Stores[robb].nameofstore) + TriggerClientEvent('esx:showNotification', source, _U('robbery_has_cancelled') .. Stores[robb].nameofstore) end end) RegisterServerEvent('esx_holdup:rob') AddEventHandler('esx_holdup:rob', function(robb) - + local source = source local xPlayer = ESX.GetPlayerFromId(source) local xPlayers = ESX.GetPlayers() - + if Stores[robb] then - + local store = Stores[robb] if (os.time() - store.lastrobbed) < 600 and store.lastrobbed ~= 0 then - - TriggerClientEvent('esx:showNotification', source, 'Ce magasin a déjà été braqué. Veuillez attendre: ' .. (1800 - (os.time() - store.lastrobbed)) .. "secondes.") + + TriggerClientEvent('esx:showNotification', source, _U('already_robbed') .. (1800 - (os.time() - store.lastrobbed)) .. _U('seconds')) return end - + local cops = 0 for k, v in pairs(xPlayers) do if v.job.name == 'police' then @@ -52,51 +52,51 @@ AddEventHandler('esx_holdup:rob', function(robb) end end - + if rob == false then - + if(cops > 1)then - + rob = true for k, v in pairs(xPlayers) do if v.job.name == 'police' then - TriggerClientEvent('esx:showNotification', k, '~r~ Braquage en cours à: ~b~' .. store.nameofstore) + TriggerClientEvent('esx:showNotification', k, _U('rob_in_prog') .. store.nameofstore) TriggerClientEvent('esx_holdup:setblip', k, Stores[robb].position) end - end - - TriggerClientEvent('esx:showNotification', source, 'Vous avez commencé à braquer ' .. store.nameofstore .. ', ne vous éloignez pas!') - TriggerClientEvent('esx:showNotification', source, 'L\'alarme à été déclenché ') - TriggerClientEvent('esx:showNotification', source, 'Tenez la position pendant 5min et l\'argent est à vous! ') + end + + TriggerClientEvent('esx:showNotification', source, _U('started_to_rob') .. store.nameofstore .. _U('do_not_move')) + TriggerClientEvent('esx:showNotification', source, _U('alarm_triggered')) + TriggerClientEvent('esx:showNotification', source, _U('hold_pos')) TriggerClientEvent('esx_holdup:currentlyrobbing', source, robb) Stores[robb].lastrobbed = os.time() robbers[source] = robb local savedSource = source SetTimeout(300000, function() - + if(robbers[savedSource])then - + rob = false TriggerClientEvent('esx_holdup:robberycomplete', savedSource, job) - if(xPlayer)then - + if(xPlayer)then + xPlayer.addAccountMoney('black_money', store.reward) - TriggerClientEvent('esx:showNotification', source, '~r~ Braquage terminé.~s~ ~h~ Fuie!') + TriggerClientEvent('esx:showNotification', source, _U('robbery_complete')) for k, v in pairs(xPlayers) do if v.job.name == 'police' then - TriggerClientEvent('esx:showNotification', k, '~r~ Braquage terminé à: ~b~' .. store.nameofstore) + TriggerClientEvent('esx:showNotification', k, _U('robbery_complete_at') .. store.nameofstore) TriggerClientEvent('esx_holdup:killblip', k) end end - + end end end) else - TriggerClientEvent('esx:showNotification', source, 'Il faut minimum ~b~2 policiers~s~ en ville pour braquer.') + TriggerClientEvent('esx:showNotification', source, _U('min_two_police')) end else - TriggerClientEvent('esx:showNotification', source, '~r~Un braquage est déjà en cours.') + TriggerClientEvent('esx:showNotification', source, _U('robbery_already')) end end end) From 9390b2f8b046dd34355312117fced990855343ce Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Wed, 16 Aug 2017 23:13:40 -0400 Subject: [PATCH 0413/3224] Multi-language support --- __resource.lua | 6 ++++++ client/main.lua | 54 ++++++++++++++++++++++++------------------------- config.lua | 3 ++- locales/en.lua | 12 +++++++++++ locales/fr.lua | 12 +++++++++++ server/main.lua | 6 +++--- 6 files changed, 62 insertions(+), 31 deletions(-) create mode 100644 locales/en.lua create mode 100644 locales/fr.lua diff --git a/__resource.lua b/__resource.lua index f3483a9e..afef484e 100644 --- a/__resource.lua +++ b/__resource.lua @@ -4,11 +4,17 @@ description 'ESX ClotheShop' server_scripts { '@mysql-async/lib/MySQL.lua', + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', 'config.lua', 'server/main.lua' } client_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', 'config.lua', 'client/main.lua' } diff --git a/client/main.lua b/client/main.lua index 92f01616..8023038c 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,10 +1,10 @@ local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 @@ -37,11 +37,11 @@ function OpenShopMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'shop_confirm', { - title = 'Valider cet achat ?', + title = _U('valid_this_purchase'), align = 'top-left', elements = { - {label = 'Oui', value = 'yes'}, - {label = 'Non', value = 'no'}, + {label = _U('yes'), value = 'yes'}, + {label = _U('no'), value = 'no'}, } }, function(data, menu) @@ -67,10 +67,10 @@ function OpenShopMenu() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'outfit_name', { - title = 'Nom de la tenue ?', + title = _U('name_outfit'), }, function(data, menu) - + menu.close() TriggerEvent('skinchanger:getSkin', function(skin) @@ -93,8 +93,8 @@ function OpenShopMenu() TriggerEvent('skinchanger:loadSkin', skin) end) - ESX.ShowNotification('Vous n\'avez pas assez d\'argent') - + ESX.ShowNotification(_U('not_enough_money')) + end end) @@ -110,7 +110,7 @@ function OpenShopMenu() end CurrentAction = 'shop_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('press_menu') CurrentActionData = {} end, @@ -119,7 +119,7 @@ function OpenShopMenu() menu.close() CurrentAction = 'shop_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('press_menu') CurrentActionData = {} end @@ -130,7 +130,7 @@ function OpenShopMenu() menu.close() CurrentAction = 'shop_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('press_menu') CurrentActionData = {} end, { @@ -145,8 +145,8 @@ function OpenShopMenu() 'pants_2', 'shoes_1', 'shoes_2', - 'chain_1', - 'chain_2', + 'chain_1', + 'chain_2', 'helmet_1', 'helmet_2', 'glasses_1', @@ -157,7 +157,7 @@ end AddEventHandler('esx_clotheshop:hasEnteredMarker', function(zone) CurrentAction = 'shop_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('press_menu') CurrentActionData = {} end) @@ -168,9 +168,9 @@ end) -- Create Blips Citizen.CreateThread(function() - + for i=1, #Config.Shops, 1 do - + local blip = AddBlipForCoord(Config.Shops[i].x, Config.Shops[i].y, Config.Shops[i].z) SetBlipSprite (blip, 73) @@ -180,7 +180,7 @@ Citizen.CreateThread(function() SetBlipAsShortRange(blip, true) BeginTextCommandSetBlipName("STRING") - AddTextComponentString("Vêtements") + AddTextComponentString(_U('clothes')) EndTextCommandSetBlipName(blip) end @@ -189,11 +189,11 @@ end) -- Display markers Citizen.CreateThread(function() while true do - + Wait(0) - + local coords = GetEntityCoords(GetPlayerPed(-1)) - + for k,v in pairs(Config.Zones) do if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) @@ -206,9 +206,9 @@ end) -- Enter / Exit marker events Citizen.CreateThread(function() while true do - + Wait(0) - + local coords = GetEntityCoords(GetPlayerPed(-1)) local isInMarker = false local currentZone = nil @@ -247,17 +247,17 @@ Citizen.CreateThread(function() DisplayHelpTextFromStringLabel(0, 0, 1, -1) if IsControlPressed(0, Keys['E']) and (GetGameTimer() - GUI.Time) > 300 then - + if CurrentAction == 'shop_menu' then OpenShopMenu() end CurrentAction = nil GUI.Time = GetGameTimer() - + end end end -end) \ No newline at end of file +end) diff --git a/config.lua b/config.lua index 71e4491f..8d335bd7 100644 --- a/config.lua +++ b/config.lua @@ -1,4 +1,5 @@ Config = {} +Config.Locale = 'fr' Config.Price = 250 @@ -35,4 +36,4 @@ for i=1, #Config.Shops, 1 do Type = Config.MarkerType } -end \ No newline at end of file +end diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..a70acc6b --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,12 @@ +Locales['en'] = { + + ['valid_this_purchase'] = 'validate this purchase?', + ['yes'] = 'yes', + ['no'] = 'no', + ['name_outfit'] = 'name of the outfit?', + ['not_enough_money'] = 'you do not have enough money', + ['press_menu'] = 'press ~INPUT_CONTEXT~ to access the menu', + ['clothes'] = 'clothes', + ['you_paid'] = 'you paid $', + +} diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..433c1ab3 --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,12 @@ +Locales['fr'] = { + + ['valid_this_purchase'] = 'valider cet achat ?', + ['yes'] = 'oui', + ['no'] = 'non', + ['name_outfit'] = 'nom de la tenue ?', + ['not_enough_money'] = 'vous n\'avez pas assez d\'argent', + ['press_menu'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder au menu', + ['clothes'] = 'vêtements', + ['you_paid'] = 'vous avez payé $', + +} diff --git a/server/main.lua b/server/main.lua index 1c338a51..c71dd0f3 100644 --- a/server/main.lua +++ b/server/main.lua @@ -9,7 +9,7 @@ AddEventHandler('esx_clotheshop:pay', function() xPlayer.removeMoney(Config.Price) - TriggerClientEvent('esx:showNotification', source, 'Vous avez payé $' .. Config.Price) + TriggerClientEvent('esx:showNotification', source, _U('you_paid') .. Config.Price) end) @@ -19,7 +19,7 @@ AddEventHandler('esx_clotheshop:saveOutfit', function(label, skin) local xPlayer = ESX.GetPlayerFromId(source) TriggerEvent('esx_datastore:getDataStore', 'property', xPlayer.identifier, function(store) - + local dressing = store.get('dressing') if dressing == nil then @@ -60,4 +60,4 @@ ESX.RegisterServerCallback('esx_clotheshop:checkPropertyDataStore', function(sou cb(foundStore) -end) \ No newline at end of file +end) From 96651bf7991ccf85e2f08a550ea1c50709683798 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Wed, 16 Aug 2017 23:29:27 -0400 Subject: [PATCH 0414/3224] Fix error in fr.lua --- locales/fr.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/fr.lua b/locales/fr.lua index ceb928af..a88233ec 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -16,7 +16,7 @@ Locales['fr'] = { ['alarm_triggered'] = 'l\'alarme à été déclenché', ['hold_pos'] = 'tenez la position pendant 5min et l\'argent est à vous!', ['robbery_complete'] = '~r~ Braquage terminé.~s~ ~h~ Fuie!', - ['robbery_complete_at'] = '~r~ Braquage terminé à: ~b~' + ['robbery_complete_at'] = '~r~ Braquage terminé à: ~b~', ['min_two_police'] = 'il faut minimum ~b~2 policiers~s~ en ville pour braquer.', ['robbery_already'] = '~r~Un braquage est déjà en cours.', From f5040541305b8213561449455857edbe99054eb2 Mon Sep 17 00:00:00 2001 From: renaiku Date: Thu, 17 Aug 2017 07:50:12 +0200 Subject: [PATCH 0415/3224] Initial commit --- LICENSE | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 1 + 2 files changed, 675 insertions(+) create mode 100644 LICENSE create mode 100644 README.md diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..9cecc1d4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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/README.md b/README.md new file mode 100644 index 00000000..e16e7cbb --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# fxserver-esx_lscustom \ No newline at end of file From b18a0cbd753d79fa80297d3caa6a42ab1a8ac3d1 Mon Sep 17 00:00:00 2001 From: TakumiBR <31086346+TakumiBR@users.noreply.github.com> Date: Wed, 16 Aug 2017 22:52:56 -0700 Subject: [PATCH 0416/3224] Add files via upload --- locales/br.lua | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 locales/br.lua diff --git a/locales/br.lua b/locales/br.lua new file mode 100644 index 00000000..5bcb5db2 --- /dev/null +++ b/locales/br.lua @@ -0,0 +1,9 @@ +Locales['br'] = { + + ['invoices'] = 'Faturas', + ['received_invoice'] = 'Você ~r~recebeu~s~ uma fatura', + ['paid_invoice'] = 'Você ~g~pagou~s~ uma fatura de ~r~$', + ['received_payment'] = 'Você ~g~recebeu~s~ um pagamento de ~r~$', + ['player_not_logged'] = 'O jogador não está logado', + +} From 54ab2de4843d7d7970f173dddcb11eb957bc067d Mon Sep 17 00:00:00 2001 From: TakumiBR <31086346+TakumiBR@users.noreply.github.com> Date: Wed, 16 Aug 2017 22:53:29 -0700 Subject: [PATCH 0417/3224] Add files via upload --- __resource.lua | 2 ++ config.lua | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/__resource.lua b/__resource.lua index 543ec253..bfc3d345 100644 --- a/__resource.lua +++ b/__resource.lua @@ -5,6 +5,7 @@ description 'ESX Billing' server_scripts { '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', @@ -13,6 +14,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', diff --git a/config.lua b/config.lua index 56a8b5e9..99dea53b 100644 --- a/config.lua +++ b/config.lua @@ -1,2 +1,2 @@ Config = {} -Config.Locale = 'fr' +Config.Locale = 'br' From 34840960b9e92432e1f52a669f39db442ccf2bdf Mon Sep 17 00:00:00 2001 From: TakumiBR <31086346+TakumiBR@users.noreply.github.com> Date: Wed, 16 Aug 2017 22:55:45 -0700 Subject: [PATCH 0418/3224] Add files via upload --- config.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.lua b/config.lua index 99dea53b..56a8b5e9 100644 --- a/config.lua +++ b/config.lua @@ -1,2 +1,2 @@ Config = {} -Config.Locale = 'br' +Config.Locale = 'fr' From b291c1b95b38805e5772c5fc7d50f7be8fe0bcfb Mon Sep 17 00:00:00 2001 From: nearbyplayer <3721216+nearbyplayer@users.noreply.github.com> Date: Thu, 17 Aug 2017 02:12:36 -0400 Subject: [PATCH 0419/3224] Update main.lua Added missing underscore --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 3c81a518..8415cde1 100644 --- a/client/main.lua +++ b/client/main.lua @@ -41,7 +41,7 @@ local Components = { {label = _U('mask_2'), name = 'mask_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65, textureof = 'mask_1'}, -- {label = _U('bproof_1'), name = 'bproof_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- {label = _U('bproof_2'), name = 'bproof_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'bproof_1'}, -- - {label = U('chain_1'), name = 'chain_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = _U('chain_1'), name = 'chain_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- {label = _U('chain_2'), name = 'chain_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65, textureof = 'chain_1'}, -- {label = _U('helmet_1'), name = 'helmet_1', value = -1, min = -1, componentId = 0, zoomOffset = 0.6, camOffset = 0.65}, -- {label = _U('helmet_2'), name = 'helmet_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65, textureof = 'helmet_1'}, -- From f997a44b46dd505894c38ef598b35cc81c71bc78 Mon Sep 17 00:00:00 2001 From: renaiku Date: Thu, 17 Aug 2017 08:16:53 +0200 Subject: [PATCH 0420/3224] Updating functions to be ready for lscutsom --- resources/[essential]/es_extended/client/functions.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 8a33b9eb..5e85b674 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -608,6 +608,7 @@ ESX.Game.GetVehicleProperties = function(vehicle) }, neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), + tyreSmokeColor = table.pack(GetVehicleTyreSmokeColor(vehicle)), modSpoilers = GetVehicleMod(vehicle, 0), modFrontBumper = GetVehicleMod(vehicle, 1), @@ -629,6 +630,7 @@ ESX.Game.GetVehicleProperties = function(vehicle) modArmor = GetVehicleMod(vehicle, 16), modTurbo = IsToggleModOn(vehicle, 18), + modSmokeEnabled = IsToggleModOn(vehicle, 20), modXenon = IsToggleModOn(vehicle, 22), modFrontWheels = GetVehicleMod(vehicle, 23), @@ -696,6 +698,14 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) end + if props.modSmokeEnabled ~= nil then + ToggleVehicleMod(vehicle, 20, true) + end + + if props.tyreSmokeColor ~= nil then + SetVehicleTyreSmokeColor(vehicle, props.tyreSmokeColor[1], props.tyreSmokeColor[2], props.tyreSmokeColor[3]) + end + if props.modSpoilers ~= nil then SetVehicleMod(vehicle, 0, props.modSpoilers, false) end From 6d69f2182eb3065ab3792265e1d31fbe6eee6602 Mon Sep 17 00:00:00 2001 From: renaiku Date: Thu, 17 Aug 2017 08:21:01 +0200 Subject: [PATCH 0421/3224] Add files --- README.md | 6 +- __resource.lua | 8 + client/main.lua | 338 +++++++++++++++++++++++ config.lua | 696 ++++++++++++++++++++++++++++++++++++++++++++++++ server/main.lua | 17 ++ 5 files changed, 1064 insertions(+), 1 deletion(-) create mode 100644 __resource.lua create mode 100644 client/main.lua create mode 100644 config.lua create mode 100644 server/main.lua diff --git a/README.md b/README.md index e16e7cbb..46bec25c 100644 --- a/README.md +++ b/README.md @@ -1 +1,5 @@ -# fxserver-esx_lscustom \ No newline at end of file +# fxserver-esx_lscustom + +[DESCRIPTION] + +The best LS Custom out there for FX. \ No newline at end of file diff --git a/__resource.lua b/__resource.lua new file mode 100644 index 00000000..1baf6c0a --- /dev/null +++ b/__resource.lua @@ -0,0 +1,8 @@ +server_scripts { + 'server/main.lua' +} + +client_scripts { + 'config.lua', + 'client/main.lua' +} \ No newline at end of file diff --git a/client/main.lua b/client/main.lua new file mode 100644 index 00000000..423eb5b4 --- /dev/null +++ b/client/main.lua @@ -0,0 +1,338 @@ +ESX = nil + +Citizen.CreateThread(function() + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end +end) + +local lsMenuIsShowed = false +local isInLSMarker = false +local myCar = {} + +RegisterNetEvent('esx_lscustom:installMod') +AddEventHandler('esx_lscustom:installMod', function() + local vehicle = GetVehiclePedIsIn(GetPlayerPed(-1), false) + myCar = ESX.Game.GetVehicleProperties(vehicle) +end) + +RegisterNetEvent('esx_lscustom:cancelInstallMod') +AddEventHandler('esx_lscustom:cancelInstallMod', function() + local vehicle = GetVehiclePedIsIn(GetPlayerPed(-1), false) + ESX.Game.SetVehicleProperties(vehicle, myCar) +end) + +function OpenLSMenu(elems, menuname, menutitle, parent) + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), menuname, + { + title = menutitle, + align = 'top-left', + elements = elems + }, + function(data, menu) -- on validate + local isRimMod = false + if data.current.modType == "modFrontWheels" then + isRimMod = true + end + local found = false + for k,v in pairs(Config.Menus) do + if k == data.current.modType or isRimMod then + if data.current.label == "Par défaut" or string.match(data.current.label, "Installé") then + ESX.ShowNotification("Vous possédez déjà: ~b~" .. data.current.label) + else + if isRimMod then + TriggerServerEvent("esx_lscustom:buyMod", data.current.price) + else + TriggerServerEvent("esx_lscustom:buyMod", v.price) + end + end + menu.close() + found = true + break + end + end + if not found then + GetAction(data.current) + end + end, + function(data, menu) -- on cancel + menu.close() + TriggerEvent('esx_lscustom:cancelInstallMod') + if parent == nil then + lsMenuIsShowed = false + local vehicle = GetVehiclePedIsIn(GetPlayerPed(-1), false) + FreezeEntityPosition(vehicle, false) + myCar = nil + end + end, + function(data, menu) -- on change + UpdateMods(data.current) + end + ) +end + +function UpdateMods(data) + if data.modType ~= nil then + local vehicle = GetVehiclePedIsIn(GetPlayerPed(-1), false) + local props = {} + + --Citizen.Trace('modType: ' .. data.modType) + --Citizen.Trace('modNum: ' .. json.encode(data.modNum)) + + if data.wheelType ~= nil then + props['wheels'] = data.wheelType + ESX.Game.SetVehicleProperties(vehicle, props) + props = {} + elseif data.modType == 'neonColor' then + props['neonEnabled'] = {true, true, true, true} + ESX.Game.SetVehicleProperties(vehicle, props) + props = {} + elseif data.modType == 'tyreSmokeColor' then + props['modSmokeEnabled'] = true + ESX.Game.SetVehicleProperties(vehicle, props) + props = {} + end + props[data.modType] = data.modNum + ESX.Game.SetVehicleProperties(vehicle, props) + end +end + +function GetAction(data) + local elements = {} + local menuname = '' + local menutitle = '' + local parent = nil + + local playerPed = GetPlayerPed(-1) + local vehicle = GetVehiclePedIsIn(playerPed, false) + local currentMods = ESX.Game.GetVehicleProperties(vehicle) + + for k,v in pairs(Config + .Menus) do + + if data.value == k then + + menuname = k + menutitle = v.label + parent = v.parent + + if v.modType ~= nil then + + if v.modType == 22 then + table.insert(elements, {label = " Par défaut", modType = k, modNum = false}) + else + table.insert(elements, {label = " Par défaut", modType = k, modNum = -1}) + end + + if v.modType == 14 then -- HORNS + for j = 0, 51, 1 do + local _label = '' + if j == currentMods.modHorns then + _label = GetHornName(j) .. ' - Installé' + else + _label = GetHornName(j) .. ' - $' .. v.price .. ' ' + end + table.insert(elements, {label = _label, modType = k, modNum = j}) + end + elseif v.modType == 'plateIndex' then -- PLATES + for j = 0, 4, 1 do + local _label = '' + if j == currentMods.plateIndex then + _label = GetPlatesName(j) .. ' - Installé' + else + _label = GetPlatesName(j) .. ' - $' .. v.price .. ' ' + end + table.insert(elements, {label = _label, modType = k, modNum = j}) + end + elseif v.modType == 22 then -- XENON + local _label = '' + if currentMods.modXenon then + _label = 'Xénon - Installé' + else + _label = 'Xénon - $' .. v.price .. ' ' + end + table.insert(elements, {label = _label, modType = k, modNum = true}) + elseif v.modType == 'neonColor' or v.modType == 'tyreSmokeColor' then -- NEON & SMOKE COLOR + local neons = GetNeons() + for i=1, #neons, 1 do + table.insert(elements, + { + label = '' .. neons[i].label .. ' ', + modType = k, + modNum = { neons[i].r, neons[i].g, neons[i].b } + } + ) + end + elseif v.modType == 'color1' or v.modType == 'color2' or v.modType == 'pearlescentColor' or v.modType == 'wheelColor' then -- RESPRAYS + local colors = GetColors(data.color) + for j = 1, #colors, 1 do + local _label = '' + _label = colors[j].label .. ' - $' .. v.price .. ' ' + table.insert(elements, {label = _label, modType = k, modNum = colors[j].index}) + end + elseif v.modType == 'windowTint' then -- WINDOWS TINT + for j = 1, 5, 1 do + local _label = '' + if j == currentMods.modHorns then + _label = GetWindowName(j) .. ' - Installé' + else + _label = GetWindowName(j) .. ' - $' .. v.price .. ' ' + end + table.insert(elements, {label = _label, modType = k, modNum = j}) + end + elseif v.modType == 23 then -- WHEELS RIM & TYPE + local props = {} + + props['wheels'] = v.wheelType + ESX.Game.SetVehicleProperties(vehicle, props) + + local modCount = GetNumVehicleMods(vehicle, v.modType) + for j = 0, modCount, 1 do + local modName = GetModTextLabel(vehicle, v.modType, j) + if modName ~= nil then + local _label = '' + if j == currentMods.modFrontWheels then + _label = GetLabelText(modName) .. ' - Installé' + else + _label = GetLabelText(modName) .. ' - $' .. v.price .. ' ' + end + table.insert(elements, {label = _label, modType = 'modFrontWheels', modNum = j, wheelType = v.wheelType, price = v.price}) + end + end + elseif v.modType == 11 or v.modType == 12 or v.modType == 13 or v.modType == 15 or v.modType == 16 or v.modType == 18 then + local modCount = GetNumVehicleMods(vehicle, v.modType) -- UPGRADES + for j = 0, modCount-1, 1 do + local _label = '' + if j == currentMods[k] then + _label = 'Niveau ' .. j .. ' - Installé' + else + _label = 'Niveau ' .. j .. ' - $' .. v.price .. ' ' + end + table.insert(elements, {label = _label, modType = k, modNum = j}) + end + else + local modCount = GetNumVehicleMods(vehicle, v.modType) -- BODYPARTS + for j = 0, modCount, 1 do + local modName = GetModTextLabel(vehicle, v.modType, j) + if modName ~= nil then + local _label = '' + if j == currentMods[k] then + _label = GetLabelText(modName) .. ' - Installé' + else + _label = GetLabelText(modName) .. ' - $' .. v.price .. ' ' + end + table.insert(elements, {label = _label, modType = k, modNum = j}) + end + end + end + else + if data.value == 'primaryRespray' or data.value == 'secondaryRespray' or data.value == 'pearlescentRespray' or data.value == 'modFrontWheelsColor' then + for i=1, #Config.Colors, 1 do + if data.value == 'primaryRespray' then + table.insert(elements, {label = Config.Colors[i].label, value = 'color1', color = Config.Colors[i].value}) + elseif data.value == 'secondaryRespray' then + table.insert(elements, {label = Config.Colors[i].label, value = 'color2', color = Config.Colors[i].value}) + elseif data.value == 'pearlescentRespray' then + table.insert(elements, {label = Config.Colors[i].label, value = 'pearlescentColor', color = Config.Colors[i].value}) + elseif data.value == 'modFrontWheelsColor' then + table.insert(elements, {label = Config.Colors[i].label, value = 'wheelColor', color = Config.Colors[i].value}) + end + end + else + for l,w in pairs(v) do + if l ~= 'label' and l ~= 'parent' then + table.insert(elements, {label = w, value = l}) + end + end + end + end + break + end + end + + table.sort(elements, function(a, b) + return a.label < b.label + end) + + OpenLSMenu(elements, menuname, menutitle, parent) +end + +-- Blips +Citizen.CreateThread(function() + for k,v in pairs(Config.Zones)do + local blip = AddBlipForCoord(v.Pos.x, v.Pos.y, v.Pos.z) + SetBlipSprite(blip, 72) + SetBlipScale(blip, 0.8) + SetBlipAsShortRange(blip, true) + BeginTextCommandSetBlipName("STRING") + AddTextComponentString(v.Name) + EndTextCommandSetBlipName(blip) + end +end) + +-- Activate menu when player is inside marker +Citizen.CreateThread(function() + while true do + Wait(0) + local playerPed = GetPlayerPed(-1) + if IsPedInAnyVehicle(playerPed, false) then + local coords = GetEntityCoords(GetPlayerPed(-1)) + local currentZone = nil + local zone = nil + local lastZone = nil + + for k,v in pairs(Config.Zones) do + if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then + isInLSMarker = true + + SetTextComponentFormat("STRING") + AddTextComponentString(v.Hint) + DisplayHelpTextFromStringLabel(0, 0, 1, -1) + + break + else + isInLSMarker = false + end + end + + if IsControlJustReleased(0, 38) and not lsMenuIsShowed and isInLSMarker then + lsMenuIsShowed = true + + local vehicle = GetVehiclePedIsIn(playerPed, false) + + --SetVehicleUndriveable(vehicle, true) + FreezeEntityPosition(vehicle, true) + + myCar = ESX.Game.GetVehicleProperties(vehicle) + + ESX.UI.Menu.CloseAll() + GetAction({value = 'main'}) + end + + if isInLSMarker and not hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = true + end + + if not isInLSMarker and hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = false + --lsMenuIsShowed = false + --ESX.UI.Menu.CloseAll() + end + + end + end +end) + +--char GET_MOD_SLOT_NAME(Vehicle vehicle, int modType) + +--int GET_NUM_VEHICLE_MODS(Vehicle vehicle, int modType) + +--char *GET_MOD_TEXT_LABEL(Vehicle vehicle, int modType, int modValue) + + --_GET_LABEL_TEXT to get the part name in the games language + +--local Veh = GetVehiclePedIsIn(GetPlayerPed(-1), true) +--local VehType = GetLabelText(GetDisplayNameFromVehicleModel(GetEntityModel(Veh))) \ No newline at end of file diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..2866bc18 --- /dev/null +++ b/config.lua @@ -0,0 +1,696 @@ +Config = {} +Config.DrawDistance = 100.0 + +Config.Zones = { + ls1 = { + Pos = { x = -362.7962, y = -132.4005, z = 38.25239}, + Size = {x = 3.0, y = 3.0, z = 0.2}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Name = "LS CUSTOM", + Hint = "Appuyez sur ~INPUT_PICKUP~ pour personnaliser le véhicule." + } +} + +Config.Colors = { + { label = 'Noir', value = 'black'}, + { label = 'Blanc', value = 'white'}, + { label = 'Gris', value = 'grey'}, + { label = 'Rouge', value = 'red'}, + { label = 'Rose', value = 'pink'}, + { label = 'Bleu', value = 'blue'}, + { label = 'Jaune', value = 'yellow'}, + { label = 'Vert', value = 'green'}, + { label = 'Orange', value = 'orange'}, + { label = 'Marron', value = 'brown'}, + { label = 'Violet', value = 'purple'}, + { label = 'Chrome', value = 'chrome'}, + { label = 'Or', value = 'gold'}, +} + +function GetColors(color) + local colors = {} + if color == 'black' then + colors = { + { index = 0, label = 'Noir'}, + { index = 1, label = 'Graphite'}, + { index = 2, label = 'Noir Métallisé'}, + { index = 3, label = 'Acier Fondu'}, + { index = 11, label = 'Noir Anthracite'}, + { index = 12, label = 'Noir Mat'}, + { index = 15, label = 'Nuit Sombre'}, + { index = 16, label = 'Noir Profond'}, + { index = 21, label = 'Pétrol'}, + { index = 147, label = 'Carbon'} + } + elseif color == 'white' then + colors = { + { index = 106, label = 'Vanille'}, + { index = 107, label = 'Crème'}, + { index = 111, label = 'Blanc'}, + { index = 112, label = 'Blanc Polair'}, + { index = 113, label = 'Beige'}, + { index = 121, label = 'Blanc Mat'}, + { index = 122, label = 'Neige'}, + { index = 131, label = 'Coton'}, + { index = 132, label = 'Albâtre'}, + { index = 134, label = 'Blanc Pure'} + } + elseif color == 'grey' then + colors = { + { index = 4, label = 'Argenté'}, + { index = 5, label = 'Gris Métallisé'}, + { index = 6, label = 'Acier Laminé'}, + { index = 7, label = 'Gris Foncé'}, + { index = 8, label = 'Gris Rocheux'}, + { index = 9, label = 'Gris Nuit'}, + { index = 10, label = 'Aluminium'}, + { index = 13, label = 'Gris Mat'}, + { index = 14, label = 'Gris Clair'}, + { index = 17, label = 'Gris Bitume'}, + { index = 18, label = 'Gris Béton'}, + { index = 19, label = 'Argent Sombre'}, + { index = 20, label = 'Magnésite'}, + { index = 22, label = 'Nickel'}, + { index = 23, label = 'Zinc'}, + { index = 24, label = 'Dolomite'}, + { index = 25, label = 'Argent Bleuté'}, + { index = 26, label = 'Titane'}, + { index = 66, label = 'Acier Bleui'}, + { index = 93, label = 'Champagne'}, + { index = 144, label = 'Gris Chasseur'}, + { index = 156, label = 'Gris'} + } + elseif color == 'red' then + colors = { + { index = 27, label = 'Rouge'}, + { index = 28, label = 'Rouge Turin'}, + { index = 29, label = 'Coquelicot'}, + { index = 30, label = 'Rouge Cuivré'}, + { index = 31, label = 'Rouge Cardinal'}, + { index = 32, label = 'Rouge Brique'}, + { index = 33, label = 'Grenat'}, + { index = 34, label = 'Pourpre'}, + { index = 35, label = 'Framboise'}, + { index = 39, label = 'Rouge Mat'}, + { index = 40, label = 'Rouge Foncé'}, + { index = 43, label = 'Rouge Pulpeux'}, + { index = 44, label = 'Rouge Brillant'}, + { index = 46, label = 'Rouge Pale'}, + { index = 143, label = 'Rouge Vin'}, + { index = 150, label = 'Volcano'} + } + elseif color == 'pink' then + colors = { + { index = 135, label = 'Rose Electrique'}, + { index = 136, label = 'Rose Saumon'}, + { index = 137, label = 'Rose Dragée'} + } + elseif color == 'blue' then + colors = { + { index = 54, label = 'Topaze'}, + { index = 60, label = 'Bleu Clair'}, + { index = 61, label = 'Bleu Galaxy'}, + { index = 62, label = 'Bleu Foncé'}, + { index = 63, label = 'Bleu Azur'}, + { index = 64, label = 'Bleu Marine'}, + { index = 65, label = 'Lapis Lazuli'}, + { index = 67, label = 'Bleu Diamant'}, + { index = 68, label = 'Surfer'}, + { index = 69, label = 'Pastel'}, + { index = 70, label = 'Bleu Celeste'}, + { index = 73, label = 'Bleu Rally'}, + { index = 74, label = 'Bleu Paradis'}, + { index = 75, label = 'Bleu Nuit'}, + { index = 77, label = 'Bleu Cyan'}, + { index = 78, label = 'Cobalt'}, + { index = 79, label = 'Bleu Electrique'}, + { index = 80, label = 'Bleu Horizon'}, + { index = 82, label = 'Bleu Métallisé'}, + { index = 83, label = 'Aigue Marine '}, + { index = 84, label = 'Bleu Agathe'}, + { index = 85, label = 'Zirconium'}, + { index = 86, label = 'Spinelle'}, + { index = 87, label = 'Tourmaline'}, + { index = 127, label = 'Paradis'}, + { index = 140, label = 'Bubble Gum'}, + { index = 141, label = 'Bleu Minuit'}, + { index = 146, label = 'Bleu Interdit'}, + { index = 157, label = 'Bleu Glacier'} + } + elseif color == 'yellow' then + colors = { + { index = 42, label = 'Jaune'}, + { index = 88, label = 'Jaune Blé'}, + { index = 89, label = 'Jaune Rally'}, + { index = 91, label = 'Jaune Clair'}, + { index = 126, label = 'Jaune Pale'} + } + elseif color == 'green' then + colors = { + { index = 49, label = 'Vert Foncé'}, + { index = 50, label = 'Vert Rally'}, + { index = 51, label = 'Vert Sapin'}, + { index = 52, label = 'Vert Olive'}, + { index = 53, label = 'Vert Clair'}, + { index = 55, label = 'Vert Lime'}, + { index = 56, label = 'Vert Forêt'}, + { index = 57, label = 'Vert Pelouse'}, + { index = 58, label = 'Vert Impérial'}, + { index = 59, label = 'Vert Bouteille'}, + { index = 92, label = 'Vert Citrus'}, + { index = 125, label = 'Vert Anis'}, + { index = 128, label = 'Kaki'}, + { index = 133, label = 'Vert Army'}, + { index = 151, label = 'Vert Sombre'}, + { index = 152, label = 'Vert Chasseur'}, + { index = 155, label = 'Amarylisse'} + } + elseif color == 'orange' then + colors = { + { index = 36, label = 'Tangerine'}, + { index = 38, label = 'Orange'}, + { index = 41, label = 'Orange Mat'}, + { index = 123, label = 'Orange Clair'}, + { index = 124, label = 'Pèche'}, + { index = 130, label = 'Citrouille'}, + { index = 138, label = 'Orange Lambo'} + } + elseif color == 'brown' then + colors = { + { index = 45, label = 'Cuivre'}, + { index = 47, label = 'Marron clair'}, + { index = 48, label = 'Marron Foncé'}, + { index = 90, label = 'Bronze'}, + { index = 94, label = 'Marron Métallisé'}, + { index = 95, label = 'Expresso'}, + { index = 96, label = 'Chocolat'}, + { index = 97, label = 'Terre Cuite'}, + { index = 98, label = 'Marbre'}, + { index = 99, label = 'Sable'}, + { index = 100, label = 'Sépia'}, + { index = 101, label = 'Bison'}, + { index = 102, label = 'Palmier'}, + { index = 103, label = 'Caramel'}, + { index = 104, label = 'Rouille'}, + { index = 105, label = 'Chataigne'}, + { index = 108, label = 'Brun'}, + { index = 109, label = 'Noisette'}, + { index = 110, label = 'Coquillage'}, + { index = 114, label = 'Acajou'}, + { index = 115, label = 'Chaudron'}, + { index = 116, label = 'Blond'}, + { index = 129, label = 'Gravillon'}, + { index = 153, label = 'Terre Foncé'}, + { index = 154, label = 'Désert'} + } + elseif color == 'purple' then + colors = { + { index = 71, label = 'Indigo'}, + { index = 72, label = 'Violet Profond'}, + { index = 76, label = 'Violet Foncé'}, + { index = 81, label = 'Améthyste'}, + { index = 142, label = 'Violet Mystique'}, + { index = 145, label = 'Violet Métallisé'}, + { index = 148, label = 'Vilot Mat'}, + { index = 149, label = 'Violet Profond Mat'} + } + elseif color == 'chrome' then + colors = { + { index = 117, label = 'Chrome Brossé'}, + { index = 118, label = 'Chrome Noir'}, + { index = 119, label = 'Aluminum Brossé'}, + { index = 120, label = 'Chrome'} + } + elseif color == 'gold' then + colors = { + { index = 37, label = 'Or'}, + { index = 158, label = 'Or Pure'}, + { index = 159, label = 'Or Brossé'}, + { index = 160, label = 'Or Clair'} + } + end + return colors +end + +function GetWindowName(index) + if (index == 1) then + return "Pure Black" + elseif (index == 2) then + return "Darksmoke" + elseif (index == 3) then + return "Lightsmoke" + elseif (index == 4) then + return "Limo" + elseif (index == 5) then + return "Green" + else + return "Unknown" + end +end + +function GetHornName(index) + if (index == 0) then + return "Truck Horn" + elseif (index == 1) then + return "Cop Horn" + elseif (index == 2) then + return "Clown Horn" + elseif (index == 3) then + return "Musical Horn 1" + elseif (index == 4) then + return "Musical Horn 2" + elseif (index == 5) then + return "Musical Horn 3" + elseif (index == 6) then + return "Musical Horn 4" + elseif (index == 7) then + return "Musical Horn 5" + elseif (index == 8) then + return "Sad Trombone" + elseif (index == 9) then + return "Classical Horn 1" + elseif (index == 10) then + return "Classical Horn 2" + elseif (index == 11) then + return "Classical Horn 3" + elseif (index == 12) then + return "Classical Horn 4" + elseif (index == 13) then + return "Classical Horn 5" + elseif (index == 14) then + return "Classical Horn 6" + elseif (index == 15) then + return "Classical Horn 7" + elseif (index == 16) then + return "Scale - Do" + elseif (index == 17) then + return "Scale - Re" + elseif (index == 18) then + return "Scale - Mi" + elseif (index == 19) then + return "Scale - Fa" + elseif (index == 20) then + return "Scale - Sol" + elseif (index == 21) then + return "Scale - La" + elseif (index == 22) then + return "Scale - Ti" + elseif (index == 23) then + return "Scale - Do" + elseif (index == 24) then + return "Jazz Horn 1" + elseif (index == 25) then + return "Jazz Horn 2" + elseif (index == 26) then + return "Jazz Horn 3" + elseif (index == 27) then + return "Jazz Horn Loop" + elseif (index == 28) then + return "Star Spangled Banner 1" + elseif (index == 29) then + return "Star Spangled Banner 2" + elseif (index == 30) then + return "Star Spangled Banner 3" + elseif (index == 31) then + return "Star Spangled Banner 4" + elseif (index == 32) then + return "Classical Horn 8 Loop" + elseif (index == 33) then + return "Classical Horn 9 Loop" + elseif (index == 34) then + return "Classical Horn 10 Loop" + elseif (index == 35) then + return "Classical Horn 8" + elseif (index == 36) then + return "Classical Horn 9" + elseif (index == 37) then + return "Classical Horn 10" + elseif (index == 38) then + return "Funeral Loop" + elseif (index == 39) then + return "Funeral" + elseif (index == 40) then + return "Spooky Loop" + elseif (index == 41) then + return "Spooky" + elseif (index == 42) then + return "San Andreas Loop" + elseif (index == 43) then + return "San Andreas" + elseif (index == 44) then + return "Liberty City Loop" + elseif (index == 45) then + return "Liberty City" + elseif (index == 46) then + return "Festive 1 Loop" + elseif (index == 47) then + return "Festive 1" + elseif (index == 48) then + return "Festive 2 Loop" + elseif (index == 49) then + return "Festive 2" + elseif (index == 50) then + return "Festive 3 Loop" + elseif (index == 51) then + return "Festive 3" + else + return "Unknown Horn" + end +end + +function GetNeons() + local neons = { + { label = "white", r = 255, g = 255, b = 255}, + { label = "slate_gray", r = 112, g = 128, b = 144}, + { label = "blue", r = 0, g = 0, b = 255}, + { label = "light_blue", r = 0, g = 150, b = 255}, + { label = "navy_blue", r = 0, g = 0, b = 128}, + { label = "sky_blue", r = 135, g = 206, b = 235}, + { label = "turquoise", r = 0, g = 245, b = 255}, + { label = "mint_green", r = 50, g = 255, b = 155}, + { label = "lime_green", r = 0, g = 255, b = 0}, + { label = "olive", r = 128, g = 128, b = 0}, + { label = "yellow", r = 255, g = 255, b = 0}, + { label = "gold", r = 255, g = 215, b = 0}, + { label = "orange", r = 255, g = 165, b = 0}, + { label = "wheat", r = 245, g = 222, b = 179}, + { label = "red", r = 255, g = 0, b = 0}, + { label = "pink", r = 255, g = 161, b = 211}, + { label = "bright_pink", r = 255, g = 0, b = 255}, + { label = "purple", r = 153, g = 0, b = 153}, + { label = "ivory", r = 41, g = 36, b = 33} + } + return neons +end + +function GetPlatesName(index) + if (index == 0) then + return "Bleu sur fond Blanc 1" + elseif (index == 1) then + return "Jaune sur fond Noir" + elseif (index == 2) then + return "Jaune sur fond Bleu" + elseif (index == 3) then + return "Bleu sur fond Blanc 2" + elseif (index == 4) then + return "Bleu sur fond Blanc 3" + end +end + +Config.Menus = { + main = { + label = 'LS CUSTOM', + parent = nil, + upgrades = 'Upgrades', + cosmetics = 'Cosmétiques' + }, + upgrades = { + label = 'Upgrades', + parent = 'main', + modEngine = "Moteur", + modBrakes = "Freins", + modTransmission = "Transmission", + modSuspension = "Suspension", + modArmor = "Armure", + modTurbo = "Turbo" + }, + modEngine = { + label = 'Moteur', + parent = 'modEngine', + modType = 11, + price = 500 + }, + modBrakes = { + label = 'Freins', + parent = 'modBrakes', + modType = 12, + price = 500 + }, + modTransmission = { + label = 'Transmission', + parent = 'modTransmission', + modType = 13, + price = 500 + }, + modSuspension = { + label = 'Suspension', + parent = 'modSuspension', + modType = 15, + price = 500 + }, + modArmor = { + label = 'Armure', + parent = 'modArmor', + modType = 16, + price = 500 + }, + modTurbo = { + label = 'Turbo', + parent = 'modTurbo', + modType = 18, + price = 500 + }, + cosmetics = { + label = 'Cosmétiques', + parent = 'main', + bodyparts = 'Carosserie', -- + windowTint = 'Fenêtres', -- + modHorns = 'Klaxon', -- + neonColor = "Néons", -- + resprays = 'Peinture', -- + modXenon = 'Phares', -- + plateIndex = 'Plaque', -- + wheels = 'Roues' -- + }, + wheels = { + label = 'Roues', + parent = 'cosmetics', + modFrontWheelsTypes = "Types de Jantes", + modFrontWheelsColor = "Couleurs jantes", + tyreSmokeColor = "Fumée des pneus" + }, + modFrontWheelsTypes = { + label = 'Types de Jantes', + parent = 'wheels', + modFrontWheelsType0 = 'Jantes Sport', + modFrontWheelsType1 = 'Jantes Muscle', + modFrontWheelsType2 = 'Jantes Lowrider', + modFrontWheelsType3 = 'Jantes SUV', + modFrontWheelsType4 = 'Jantes Tout-terrain', + modFrontWheelsType5 = 'Jantes Tuning', + modFrontWheelsType6 = 'Jantes Moto', + modFrontWheelsType7 = 'Jantes Haut de gamme' + }, + modFrontWheelsType0 = { + label = 'Jantes Sport', + parent = 'modFrontWheelsTypes', + modType = 23, + wheelType = 0, + price = 500 + }, + modFrontWheelsType1 = { + label = 'Jantes Muscle', + parent = 'modFrontWheelsTypes', + modType = 23, + wheelType = 1, + price = 500 + }, + modFrontWheelsType2 = { + label = 'Jantes Lowrider', + parent = 'modFrontWheelsTypes', + modType = 23, + wheelType = 2, + price = 500 + }, + modFrontWheelsType3 = { + label = 'Jantes SUV', + parent = 'modFrontWheelsTypes', + modType = 23, + wheelType = 3, + price = 500 + }, + modFrontWheelsType4 = { + label = 'Jantes Tout-terrain', + parent = 'modFrontWheelsTypes', + modType = 23, + wheelType = 4, + price = 500 + }, + modFrontWheelsType5 = { + label = 'Jantes Tuning', + parent = 'modFrontWheelsTypes', + modType = 23, + wheelType = 5, + price = 500 + }, + modFrontWheelsType6 = { + label = 'Jantes Moto', + parent = 'modFrontWheelsTypes', + modType = 23, + wheelType = 6, + price = 500 + }, + modFrontWheelsType7 = { + label = 'Jantes Haut de gamme', + parent = 'modFrontWheelsTypes', + modType = 23, + wheelType = 7, + price = 500 + }, + modFrontWheelsColor = { + label = 'Peinture Jantes', + parent = 'wheels' + }, + wheelColor = { + label = 'Peinture Jantes', + parent = 'modFrontWheelsColor', + modType = 'wheelColor', + price = 500 + }, + plateIndex = { + label = 'Plaque', + parent = 'cosmetics', + modType = 'plateIndex', + price = 500 + }, + resprays = { + label = 'Peinture', + parent = 'cosmetics', + primaryRespray = 'Primaire', + secondaryRespray = 'Secondaire', + pearlescentRespray = 'Nacré', + }, + primaryRespray = { + label = 'Primaire', + parent = 'resprays', + }, + secondaryRespray = { + label = 'Secondaire', + parent = 'resprays', + }, + pearlescentRespray = { + label = 'Nacré', + parent = 'resprays', + }, + color1 = { + label = 'Primaire', + parent = 'primaryRespray', + modType = 'color1', + price = 500 + }, + color2 = { + label = 'Secondaire', + parent = 'secondaryRespray', + modType = 'color2', + price = 500 + }, + pearlescentColor = { + label = 'Nacré', + parent = 'pearlescentRespray', + modType = 'pearlescentColor', + price = 500 + }, + modXenon = { + label = 'Phares', + parent = 'cosmetics', + modType = 22, + price = 500 + }, + bodyparts = { + label = 'Carosserie', + parent = 'cosmetics', + modFender = 'Aile gauche', + modRightFender = 'Aile droite', + modSpoilers = 'Aileron', + modSideSkirt = 'Bas de caisse', + modFrame = 'Cage', + modHood = 'Capot', + modGrille = 'Grille', + modRearBumper = 'Pare-choc arrière', + modFrontBumper = 'Pare-choc avant', + modExhaust = 'Pot d\'échappement', + modRoof = 'Toit' + }, + modSpoilers = { + label = 'Aileron', + parent = 'bodyparts', + modType = 0, + price = 500 + }, + modFrontBumper = { + label = 'Pare-choc avant', + modType = 1, + price = 500 + }, + modRearBumper = { + label = 'Pare-choc arrière', + modType = 2, + price = 500 + }, + modSideSkirt = { + label = 'Bas de caisse', + modType = 3, + price = 500 + }, + modExhaust = { + label = 'Pot d\'échappement', + modType = 4, + price = 500 + }, + modFrame = { + label = 'Cage', + modType = 5, + price = 500 + }, + modGrille = { + label = 'Grille', + modType = 6, + price = 500 + }, + modHood = { + label = 'Capot', + modType = 7, + price = 500 + }, + modFender = { + label = 'Aile gauche', + modType = 8, + price = 500 + }, + modRightFender = { + label = 'Aile droite', + modType = 9, + price = 500 + }, + modRoof = { + label = 'Toit', + modType = 10, + price = 500 + }, + windowTint = { + label = 'Fenêtres', + parent = 'cosmetics', + modType = 'windowTint', + price = 500 + }, + modHorns = { + label = 'Klaxon', + parent = 'cosmetics', + modType = 14, + price = 500 + }, + neonColor = { + label = 'Néons', + parent = 'cosmetics', + modType = 'neonColor', + price = 500 + }, + tyreSmokeColor = { + label = 'Fumée des pneus', + parent = 'wheels', + modType = 'tyreSmokeColor', + price = 500 + } + +} \ No newline at end of file diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 00000000..991c4ed9 --- /dev/null +++ b/server/main.lua @@ -0,0 +1,17 @@ +ESX = nil +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + +RegisterServerEvent('esx_lscustom:buyMod') +AddEventHandler('esx_lscustom:buyMod', function(price) + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) + price = tonumber(price) + if price > xPlayer.getMoney() then + TriggerClientEvent('esx_lscustom:cancelInstallMod', _source) + TriggerClientEvent('esx:showNotification', _source, "Vous n'avez pas assez d'argent !") + else + xPlayer.removeMoney(price) + TriggerClientEvent('esx_lscustom:installMod', _source) + TriggerClientEvent('esx:showNotification', _source, "Achat effectué !") + end +end) From c7f0dce0c874f7be900d3e95650c18718037e899 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Thu, 17 Aug 2017 02:57:06 -0400 Subject: [PATCH 0422/3224] Multi-language support --- __resource.lua | 12 +++++++-- client/main.lua | 68 ++++++++++++++++++++++++------------------------- config.lua | 2 ++ locales/en.lua | 13 ++++++++++ locales/fr.lua | 13 ++++++++++ server/main.lua | 68 ++++++++++++++++++++++++------------------------- 6 files changed, 106 insertions(+), 70 deletions(-) create mode 100644 config.lua create mode 100644 locales/en.lua create mode 100644 locales/fr.lua diff --git a/__resource.lua b/__resource.lua index c7e09045..b01f9752 100644 --- a/__resource.lua +++ b/__resource.lua @@ -4,10 +4,18 @@ description 'ESX Phone' server_scripts { '@mysql-async/lib/MySQL.lua', + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', 'server/main.lua' } -client_script 'client/main.lua' +client_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', + 'client/main.lua' +} ui_page 'html/ui.html' @@ -32,4 +40,4 @@ files { 'html/img/icons/write.png', 'html/img/icons/edit.png', 'html/img/icons/location.png' -} \ No newline at end of file +} diff --git a/client/main.lua b/client/main.lua index be5ca732..652a7a17 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,10 +1,10 @@ local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 @@ -25,7 +25,7 @@ local CurrentActionData = {} local CurrentDispatchRequestId = -1 Citizen.CreateThread(function() - + while ESX == nil do TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) Citizen.Wait(0) @@ -38,12 +38,12 @@ end) function OpenPhone() TriggerServerEvent('esx_phone:reload', PhoneData.phoneNumber) - + SendNUIMessage({ showPhone = true, phoneData = PhoneData }) - + GUI.PhoneIsShowed = true ESX.SetTimeout(200, function() @@ -59,21 +59,21 @@ function ClosePhone() }) SetNuiFocus(false) - + GUI.PhoneIsShowed = false end RegisterNetEvent('esx_phone:loaded') AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) - + PhoneData.phoneNumber = phoneNumber PhoneData.contacts = {} - + for i=1, #contacts, 1 do table.insert(PhoneData.contacts, contacts[i]) end - + SendNUIMessage({ reloadPhone = true, phoneData = PhoneData @@ -83,7 +83,7 @@ end) RegisterNetEvent('esx_phone:addContact') AddEventHandler('esx_phone:addContact', function(name, phoneNumber, isOnline) - + table.insert(PhoneData.contacts, { name = name, number = phoneNumber, @@ -98,7 +98,7 @@ end) RegisterNetEvent('esx_phone:addSpecialContact') AddEventHandler('esx_phone:addSpecialContact', function(name, phoneNumber, base64Icon) - + SendNUIMessage({ addSpecialContact = true, name = name, @@ -110,7 +110,7 @@ end) RegisterNetEvent('esx_phone:removeSpecialContact') AddEventHandler('esx_phone:removeSpecialContact', function(phoneNumber) - + SendNUIMessage({ removeSpecialContact = true, number = phoneNumber @@ -119,10 +119,10 @@ AddEventHandler('esx_phone:removeSpecialContact', function(phoneNumber) end) RegisterNUICallback('add_contact', function(data, cb) - + local phoneNumber = tonumber(data.phoneNumber) local contactName = tostring(data.contactName) - + if phoneNumber then TriggerServerEvent('esx_phone:addPlayerContact', phoneNumber, contactName) end @@ -132,9 +132,9 @@ end) RegisterNetEvent('esx_phone:onMessage') AddEventHandler('esx_phone:onMessage', function(phoneNumber, message, position, anon, job, dispatchRequestId) - - ESX.ShowNotification('~b~Nouveau message') - + + ESX.ShowNotification(_U('new_message')) + SendNUIMessage({ newMessage = true, phoneNumber = phoneNumber, @@ -147,9 +147,9 @@ AddEventHandler('esx_phone:onMessage', function(phoneNumber, message, position, if dispatchRequestId then CurrentAction = 'dispatch' - CurrentActionMsg = job .. ' - Appuez sur ~INPUT_CONTEXT~ pour prendre l\'appel' + CurrentActionMsg = job .. _U('press_take_call') CurrentDispatchRequestId = dispatchRequestId - + CurrentActionData = { phoneNumber = phoneNumber, message = message, @@ -172,31 +172,31 @@ AddEventHandler('esx_phone:stopDispatch', function(dispatchRequestId, playerName if CurrentDispatchRequestId == dispatchRequestId and CurrentAction == 'dispatch' then CurrentAction = nil - ESX.ShowNotification(playerName .. ' a pris l\'appel') + ESX.ShowNotification(playerName .. _U('taken_call')) end end) RegisterNUICallback('setGPS', function(data) SetNewWaypoint(data.x, data.y) - ESX.ShowNotification('Position entrée dans le GPS') + ESX.ShowNotification(_U('gps_position')) end) -RegisterNUICallback('send', function(data) - +RegisterNUICallback('send', function(data) + local phoneNumber = data.number if tonumber(phoneNumber) ~= nil then phoneNumber = tonumber(phoneNumber) end - TriggerServerEvent('esx_phone:send', phoneNumber, data.message, data.anonyme) - + TriggerServerEvent('esx_phone:send', phoneNumber, data.message, data.anonyme) + SendNUIMessage({ showMessageEditor = false }) - ESX.ShowNotification('Message envoyé') + ESX.ShowNotification(_U('message_sent')) end) @@ -206,9 +206,9 @@ end) Citizen.CreateThread(function() while true do - + Wait(0) - + if GUI.PhoneIsShowed then -- codes here: https://pastebin.com/guYd0ht4 DisableControlAction(0, 1, true) -- LookLeftRight DisableControlAction(0, 2, true) -- LookUpDown @@ -221,7 +221,7 @@ Citizen.CreateThread(function() DisableControlAction(0, 142, true) -- Melee Attack Alternate DisableControlAction(0, 257, true) -- Input Attack 2 DisableControlAction(0, 263, true) -- Input Melee Attack - DisableControlAction(0, 264, true) -- Input Melee Attack 2 + DisableControlAction(0, 264, true) -- Input Melee Attack 2 DisableControlAction(0, 12, true) -- Weapon Wheel Up Down DisableControlAction(0, 14, true) -- Weapon Wheel Next @@ -231,7 +231,7 @@ Citizen.CreateThread(function() else if IsControlPressed(0, Keys['F1']) and (GetGameTimer() - GUI.Time) > 150 then - + if not ESX.UI.Menu.IsOpen('phone', GetCurrentResourceName(), 'main') then ESX.UI.Menu.CloseAll() ESX.UI.Menu.Open('phone', GetCurrentResourceName(), 'main') @@ -258,7 +258,7 @@ Citizen.CreateThread(function() DisplayHelpTextFromStringLabel(0, 0, 1, -1) if IsControlPressed(0, Keys['E']) and (GetGameTimer() - GUI.Time) > 300 then - + if CurrentAction == 'dispatch' then TriggerServerEvent('esx_phone:stopDispatch', CurrentDispatchRequestId) SetNewWaypoint(CurrentActionData.position.x, CurrentActionData.position.y) @@ -266,10 +266,10 @@ Citizen.CreateThread(function() CurrentAction = nil GUI.Time = GetGameTimer() - + end end end -end) \ No newline at end of file +end) diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..56a8b5e9 --- /dev/null +++ b/config.lua @@ -0,0 +1,2 @@ +Config = {} +Config.Locale = 'fr' diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..7d7393f8 --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,13 @@ +Locales['en'] = { + + ['new_message'] = '~b~New message', + ['press_take_call'] = ' - Press to take the call', + ['taken_call'] = ' has taken the call', + ['gps_position'] = 'destination entered into the GPS', + ['message_sent'] = 'message sent', + ['cannot_add_self'] = 'you can not add yourself', + ['number_in_contacts'] = 'this number is alraedy in your contact list', + ['contact_added'] = 'contact added', + ['number_not_assigned'] = 'this number is not assigned...', + +} diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..4927ec7c --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,13 @@ +Locales['fr'] = { + + ['new_message'] = '~b~Nouveau message', + ['press_take_call'] = ' - Appuyez sur ~INPUT_CONTEXT~ pour prendre l\'appel', + ['taken_call'] = ' a pris l\'appel', + ['gps_position'] = 'position entrée dans le GPS', + ['message_sent'] = 'message envoyé', + ['cannot_add_self'] = 'vous ne pouvez pas vous ajouter vous-même', + ['number_in_contacts'] = 'ce numéro est déja dans votre liste de contacts', + ['contact_added'] = 'contact ajouté', + ['number_not_assigned'] = 'ce numéro n\'est pas attribué...', + +} diff --git a/server/main.lua b/server/main.lua index ccc53a15..b1555710 100644 --- a/server/main.lua +++ b/server/main.lua @@ -8,14 +8,14 @@ local RegisteredCallbacks = {} local DisptachRequestId = 0 function GenerateUniquePhoneNumber() - + local foundNumber = false local phoneNumber = nil - + while not foundNumber do - + phoneNumber = math.random(10000, 99999) - + local result = MySQL.Sync.fetchAll( 'SELECT COUNT(*) as count FROM users WHERE phone_number = @phoneNumber', { @@ -24,7 +24,7 @@ function GenerateUniquePhoneNumber() ) local count = tonumber(result[1].count) - + if count == 0 then foundNumber = true end @@ -72,9 +72,9 @@ AddEventHandler('esx:playerLoaded', function(source) local phoneNumber = result[1].phone_number if phoneNumber == nil then - + phoneNumber = GenerateUniquePhoneNumber() - + MySQL.Async.execute( 'UPDATE users SET phone_number = @phone_number WHERE identifier = @identifier', { @@ -83,9 +83,9 @@ AddEventHandler('esx:playerLoaded', function(source) } ) end - + xPlayer.set('phoneNumber', phoneNumber) - + local contacts = {} MySQL.Async.fetchAll( @@ -96,13 +96,13 @@ AddEventHandler('esx:playerLoaded', function(source) function(result2) for i=1, #result2, 1 do - + table.insert(contacts, { name = result2[i].name, number = result2[i].number, online = false }) - + local xPlayers = ESX.GetPlayers() for k, v in pairs(xPlayers) do @@ -112,9 +112,9 @@ AddEventHandler('esx:playerLoaded', function(source) end end - + xPlayer.set('contacts', contacts) - + TriggerClientEvent('esx_phone:loaded', source, phoneNumber, contacts) end @@ -141,13 +141,13 @@ AddEventHandler('esx_phone:reload', function(phoneNumber) function(result2) for i=1, #result2, 1 do - + table.insert(contacts, { name = result2[i].name, number = result2[i].number, online = false }) - + local xPlayers = ESX.GetPlayers() for k, v in pairs(xPlayers) do @@ -157,7 +157,7 @@ AddEventHandler('esx_phone:reload', function(phoneNumber) end end - + xPlayer.set('contacts', contacts) TriggerClientEvent('esx_phone:loaded', _source, phoneNumber, contacts) @@ -192,7 +192,7 @@ AddEventHandler('esx_phone:addPlayerContact', function(phoneNumber, contactName) local foundPlayer = nil MySQL.Async.fetchAll( - 'SELECT phone_number FROM users WHERE phone_number = @number', + 'SELECT phone_number FROM users WHERE phone_number = @number', { ['@number'] = phoneNumber }, @@ -203,14 +203,14 @@ AddEventHandler('esx_phone:addPlayerContact', function(phoneNumber, contactName) end if foundNumber then - + if phoneNumber == xPlayer.get('phoneNumber') then - TriggerClientEvent('esx:showNotification', _source, 'Vous ne pouvez pas vous ajouter vous-même') + TriggerClientEvent('esx:showNotification', _source, _U('cannot_add_self')) else local hasAlreadyAdded = false local contacts = xPlayer.get('contacts') - + for i=1, #contacts, 1 do if contacts[i].number == phoneNumber then hasAlreadyAdded = true @@ -218,9 +218,9 @@ AddEventHandler('esx_phone:addPlayerContact', function(phoneNumber, contactName) end if hasAlreadyAdded then - TriggerClientEvent('esx:showNotification', _source, 'Ce numéro est déja dans votre liste de contacts') + TriggerClientEvent('esx:showNotification', _source, _U('number_in_contacts')) else - + table.insert(contacts, { name = contactName, number = phoneNumber, @@ -237,27 +237,27 @@ AddEventHandler('esx_phone:addPlayerContact', function(phoneNumber, contactName) }, function(rowsChanged) - TriggerClientEvent('esx:showNotification', _source, 'Contact ajouté') - + TriggerClientEvent('esx:showNotification', _source, _U('contact_added')) + local xPlayers = ESX.GetPlayers() local isOnline = false - + for k,v in pairs(xPlayers) do if v.get('phoneNumber') == phoneNumber then isOnline = true break end end - + TriggerClientEvent('esx_phone:addContact', _source, contactName, phoneNumber, isOnline) end ) - + end end else - TriggerClientEvent('esx:showNotification', source, 'Ce numéro n\'est pas attribué...') + TriggerClientEvent('esx:showNotification', source, _U('number_not_assigned')) end end @@ -267,17 +267,17 @@ end) AddEventHandler('esx_phone:ready', function() TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) - + local xPlayer = ESX.GetPlayerFromId(source) local xPlayers = ESX.GetPlayers() print('MESSAGE => ' .. xPlayer.name .. '@' .. phoneNumber .. ' : ' .. message) for k, v in pairs(xPlayers) do - if v.get('phoneNumber') == phoneNumber then - TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, job, false) - end - end + if v.get('phoneNumber') == phoneNumber then + TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, job, false) + end + end end) end) @@ -285,4 +285,4 @@ end) RegisterServerEvent('esx_phone:stopDispatch') AddEventHandler('esx_phone:stopDispatch', function(dispatchRequestId) TriggerClientEvent('esx_phone:stopDispatch', -1, dispatchRequestId, GetPlayerName(source)) -end) \ No newline at end of file +end) From a9b49b616b7f9f630925ac35ab3b0c6659638adc Mon Sep 17 00:00:00 2001 From: Don Date: Fri, 18 Aug 2017 00:28:15 -0700 Subject: [PATCH 0423/3224] fixed missing translation fixed missing translation in client\main.lua invoices --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 99e7a4e4..7183a639 100644 --- a/client/main.lua +++ b/client/main.lua @@ -36,7 +36,7 @@ function ShowBillsMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'billing', { - title = 'Factures', + title = _U('invoices'), elements = elements }, function(data, menu) From 8015a0620cf1b960350e7ffdce3837b3fef9a12f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 17 Aug 2017 09:43:41 +0200 Subject: [PATCH 0424/3224] Fix taxi mission crash --- client/main.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 867c067b..3ad129c7 100644 --- a/client/main.lua +++ b/client/main.lua @@ -573,7 +573,9 @@ Citizen.CreateThread(function() end - DrawMarker(1, TargetCoords.x, TargetCoords.y, TargetCoords.z - 1.0, 0, 0, 0, 0, 0, 0, 4.0, 4.0, 2.0, 178, 236, 93, 155, 0, 0, 2, 0, 0, 0, 0) + if TargetCoords ~= nil then + DrawMarker(1, TargetCoords.x, TargetCoords.y, TargetCoords.z - 1.0, 0, 0, 0, 0, 0, 0, 4.0, 4.0, 2.0, 178, 236, 93, 155, 0, 0, 2, 0, 0, 0, 0) + end else From e5391453cefb0a7f02c79838ef03c4c04b9b4bf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 17 Aug 2017 10:23:37 +0200 Subject: [PATCH 0425/3224] Add math.randomseed --- server/main.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/main.lua b/server/main.lua index e92e5745..4a33fc76 100644 --- a/server/main.lua +++ b/server/main.lua @@ -9,6 +9,8 @@ end RegisterServerEvent('esx_taxijob:success') AddEventHandler('esx_taxijob:success', function() + math.randomseed(os.time()) + local xPlayer = ESX.GetPlayerFromId(source) local total = math.random(Config.NPCJobEarnings.min, Config.NPCJobEarnings.max); local societyAccount = nil From 4cbfc6cd72151863f773e3d650e4f935f61e56c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 17 Aug 2017 10:53:08 +0200 Subject: [PATCH 0426/3224] Fix typo + weapon labels (you need to recreate the SQL table --- config.lua | 3 ++- esx_weashops.sql | 7 +++---- server/main.lua | 20 ++------------------ 3 files changed, 7 insertions(+), 23 deletions(-) diff --git a/config.lua b/config.lua index cc22dc28..f072bfbb 100644 --- a/config.lua +++ b/config.lua @@ -16,7 +16,8 @@ Config.Zones = { } }, - blackweashop = { + + BlackWeashop = { legal=1, Items = {}, Pos = { diff --git a/esx_weashops.sql b/esx_weashops.sql index 9e4ef2d2..a7a907cd 100644 --- a/esx_weashops.sql +++ b/esx_weashops.sql @@ -6,12 +6,11 @@ CREATE TABLE `weashops` ( `name` varchar(255) NOT NULL, `item` varchar(255) NOT NULL, `price` int(11) NOT NULL, - `label` varchar(255) NOT NULL, PRIMARY KEY (`id`) ); -INSERT INTO `weashops` (name, item, price, label) VALUES - ('GunShop','WEAPON_Pistol',300, 'pistol'), - ('blackweashop','WEAPON_Pistol',500, 'pistol') +INSERT INTO `weashops` (name, item, price) VALUES + ('GunShop','WEAPON_PISTOL',300), + ('BlackWeashop','WEAPON_PISTOL',500) ; \ No newline at end of file diff --git a/server/main.lua b/server/main.lua index 56b81495..9fe64e37 100644 --- a/server/main.lua +++ b/server/main.lua @@ -3,22 +3,6 @@ local ItemsLabels = {} TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) -AddEventHandler('onMySQLReady', function() - - MySQL.Async.fetchAll( - 'SELECT * FROM items', - {}, - function(result) - - for i=1, #result, 1 do - ItemsLabels[result[i].name] = result[i].label - end-- - - end - ) - -end) - ESX.RegisterServerCallback('esx_weashop:requestDBItems', function(source, cb) MySQL.Async.fetchAll( @@ -61,7 +45,7 @@ AddEventHandler('esx_weashop:buyItem', function(itemName, price, zone) xPlayer.removeAccountMoney('black_money', price) xPlayer.addWeapon(itemName, 42) - TriggerClientEvent('esx:showNotification', _source, _U('buy') .. ItemsLabels[itemName]) + TriggerClientEvent('esx:showNotification', _source, _U('buy') .. ESX.GetWeaponLabel(itemName)) else TriggerClientEvent('esx:showNotification', _source, _U('not_enough_black')) @@ -72,7 +56,7 @@ AddEventHandler('esx_weashop:buyItem', function(itemName, price, zone) xPlayer.removeMoney(price) xPlayer.addWeapon(itemName, 42) - TriggerClientEvent('esx:showNotification', _source, _U('buy') .. ItemsLabels[itemName]) + TriggerClientEvent('esx:showNotification', _source, _U('buy') .. ESX.GetWeaponLabel(itemName)) else TriggerClientEvent('esx:showNotification', _source, _U('not_enough')) From 170eb71587c1293458287253587e6cf97b0c15cd Mon Sep 17 00:00:00 2001 From: Don <30905704+ddh3@users.noreply.github.com> Date: Thu, 17 Aug 2017 02:49:58 -0700 Subject: [PATCH 0427/3224] Update en.lua --- locales/en.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/en.lua b/locales/en.lua index 7d7393f8..94bf3a54 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,7 +1,7 @@ Locales['en'] = { ['new_message'] = '~b~New message', - ['press_take_call'] = ' - Press to take the call', + ['press_take_call'] = ' - Press ~INPUT_CONTEXT~ to take the call', ['taken_call'] = ' has taken the call', ['gps_position'] = 'destination entered into the GPS', ['message_sent'] = 'message sent', From 3c433f1f722e8c576b246001d008a9da1d993498 Mon Sep 17 00:00:00 2001 From: TakumiBR <31086346+TakumiBR@users.noreply.github.com> Date: Thu, 17 Aug 2017 08:03:13 -0700 Subject: [PATCH 0428/3224] Add files via upload --- __resource.lua | 2 ++ locales/br.lua | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 locales/br.lua diff --git a/__resource.lua b/__resource.lua index 473a6ccf..b0b274a4 100644 --- a/__resource.lua +++ b/__resource.lua @@ -4,6 +4,7 @@ description 'ESX Property' server_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', '@mysql-async/lib/MySQL.lua', @@ -13,6 +14,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', diff --git a/locales/br.lua b/locales/br.lua new file mode 100644 index 00000000..b08da2f1 --- /dev/null +++ b/locales/br.lua @@ -0,0 +1,30 @@ +Locales['br'] = { + + ['free_prop'] = 'Propriedade gratuita', + ['property'] = 'Propriedade', + ['enter'] = 'Entrar', + ['leave'] = 'Sair', + ['buy'] = 'Comprar', + ['rent'] = 'Alugar', + ['visit'] = 'Visitar', + ['press_to_menu'] = 'Pressione ~INPUT_CONTEXT~ para acessar o menu', + ['owned_properties'] = 'Propriedades adquiridas', + ['available_properties'] = 'Propriedades disponíveis', + ['invite_player'] = 'Convidar um jogador', + ['player_clothes'] = 'Roupas', + ['remove_object'] = 'Remover objeto', + ['deposit_object'] = 'Depositar objeto', + ['invite'] = 'Convidar', + ['dirty_money'] = 'Dinheiro sujo $', + ['inventory'] = 'Inventário', + ['amount'] = 'valor?', + ['amount_invalid'] = 'quantidade inválida', + ['press_to_exit'] = 'Pressione ~INPUT_CONTEXT~ para sair da propriedade', + ['rented_for'] = 'Você alugou uma propriedade por $', + ['purchased_for'] = 'Você comprou uma propriedade por $', + ['made_property'] = 'Você criou uma propriedade', + ['not_enough'] = 'Você não tem dinheiro suficiente', + ['invalid_quantity'] = 'Quantidade inválida', + ['paid_rent'] = 'Você ~g~pagou~s~ seu aluguel: ~g~$', + +} From 24c6decac1d828f25ea36e53be47b613612eac3d Mon Sep 17 00:00:00 2001 From: TakumiBR <31086346+TakumiBR@users.noreply.github.com> Date: Thu, 17 Aug 2017 08:11:21 -0700 Subject: [PATCH 0429/3224] Add files via upload --- __resource.lua | 2 ++ locales/br.lua | 10 ++++++++++ 2 files changed, 12 insertions(+) create mode 100644 locales/br.lua diff --git a/__resource.lua b/__resource.lua index 34c968b5..239daaed 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,6 +2,7 @@ description 'ESX Mecano Job' client_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', @@ -10,6 +11,7 @@ client_scripts { server_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', '@mysql-async/lib/MySQL.lua', diff --git a/locales/br.lua b/locales/br.lua new file mode 100644 index 00000000..86c0b715 --- /dev/null +++ b/locales/br.lua @@ -0,0 +1,10 @@ +Locales ['br'] = { + + ['buy'] = 'Você comprou', + ['not_enough_black'] = 'Você não tem dinheiro sujo suficiente', + ['not_enough'] = 'você não tem dinheiro suficiente', + ['shop'] = 'Comprar', + ['shop_menu'] = 'Pressione ~INPUT_CONTEXT~ para comprar armas.', + ['map_blip'] = 'Loja de Armas', + +} \ No newline at end of file From 67ac40adfb4ac44bf151c6c98295db77263f25f1 Mon Sep 17 00:00:00 2001 From: TakumiBR <31086346+TakumiBR@users.noreply.github.com> Date: Thu, 17 Aug 2017 08:17:45 -0700 Subject: [PATCH 0430/3224] Add files via upload --- __resource.lua | 2 ++ locales/br.lua | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 locales/br.lua diff --git a/__resource.lua b/__resource.lua index 83660fa5..2f98bcc3 100644 --- a/__resource.lua +++ b/__resource.lua @@ -4,6 +4,7 @@ description 'ESX Taxi Job' client_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', @@ -12,6 +13,7 @@ client_scripts { server_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', diff --git a/locales/br.lua b/locales/br.lua new file mode 100644 index 00000000..bcd578e0 --- /dev/null +++ b/locales/br.lua @@ -0,0 +1,32 @@ +Locales['br'] = { + + ['taking_service'] = 'Pegando serviço: ', + ['spawn_veh'] = 'pegar veículo', + ['remove_comp_money'] = 'Remover dinheiro da empresa', + ['deposit_money'] = 'Depositar dinheiro', + ['launder_money'] = 'Lavar dinheiro', + ['full_service'] = 'Serviço completo: ', + ['withdraw_amount'] = 'Valor do saque', + ['amount_invalid'] = 'Valor inválido', + ['deposit_amount'] = 'Valor para deposito', + ['launder_amount'] = 'Valor para lavagem', + ['press_to_open'] = 'Pressione ~INPUT_CONTEXT~ para acessar o menu', + ['billing'] = 'Faturamento', + ['invoice_amount'] = 'Valor da fatura', + ['no_players_near'] = 'Nenhum jogador nas proximidades', + ['store_veh'] = 'Pressione ~INPUT_CONTEXT~ para guardar o veículo', + ['drive_search_pass'] = 'Dirigindo em busca de ~y~passageiros', + ['customer_found'] = 'Você ~g~encontrou~s~ um passageiro, dirija até o destino', + ['client_unconcious'] = 'Seu passageiro está ~r~insconsciente~w~. Procure por outro.', + ['arrive_dest'] = 'Você ~g~chegou~s~ ao seu destino', + ['take_me_to_near'] = '~w~Leve me para~y~ %s~w~, perto~y~ %s', + ['take_me_to'] = '~w~Leve me para~y~ %s', + ['close_to_client'] = 'Você está perto do passageiro, aproximisse dele', + ['return_to_veh'] = 'Volte para o seu veículo para continuar a missão', + ['only_taxi'] = 'Você só pode guardar taxis.', + ['must_in_taxi'] = 'Você deve estar em um táxi para começar a missão', + ['must_in_vehicle'] = 'Você deve estar em um veículo para começar a missão', + ['have_earned'] = 'Você ganhou ~g~$', + ['comp_earned'] = 'Sua empresa ganhou ~g~$', + +} From fa4909f580d01faf500d4b125913f6ffb5ca0926 Mon Sep 17 00:00:00 2001 From: TakumiBR <31086346+TakumiBR@users.noreply.github.com> Date: Thu, 17 Aug 2017 08:21:18 -0700 Subject: [PATCH 0431/3224] Add files via upload --- locales/br.lua | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 locales/br.lua diff --git a/locales/br.lua b/locales/br.lua new file mode 100644 index 00000000..6baa2746 --- /dev/null +++ b/locales/br.lua @@ -0,0 +1,7 @@ +Locales['br'] = { + + ['skin_menu'] = 'Skin Menu', + ['use_rotate_view'] = 'Use ~INPUT_VEH_FLY_ROLL_LEFT_ONLY~ e ~INPUT_VEH_FLY_ROLL_RIGHT_ONLY~ para girar a visão.', + + +} From 89832c68a815688b65535e2a0668416251356744 Mon Sep 17 00:00:00 2001 From: TakumiBR <31086346+TakumiBR@users.noreply.github.com> Date: Thu, 17 Aug 2017 08:22:15 -0700 Subject: [PATCH 0432/3224] Add files via upload --- __resource.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/__resource.lua b/__resource.lua index 3dd25881..91ad7337 100644 --- a/__resource.lua +++ b/__resource.lua @@ -3,18 +3,18 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ESX Skin' server_scripts { - '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', - 'config.lua', + '@mysql-async/lib/MySQL.lua', 'server/main.lua' } client_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', - 'config.lua', 'client/main.lua' } From c521b15ed6e40ca370610e15661a036f734975f9 Mon Sep 17 00:00:00 2001 From: TakumiBR <31086346+TakumiBR@users.noreply.github.com> Date: Thu, 17 Aug 2017 08:27:27 -0700 Subject: [PATCH 0433/3224] Multi-language support Brazilian Portuguese translation. --- __resource.lua | 2 ++ locales/br.lua | 9 +++++++++ 2 files changed, 11 insertions(+) create mode 100644 locales/br.lua diff --git a/__resource.lua b/__resource.lua index 539fbeb3..def8a634 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,6 +2,7 @@ description 'ESX Shops' client_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', @@ -10,6 +11,7 @@ client_scripts { server_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', '@mysql-async/lib/MySQL.lua', diff --git a/locales/br.lua b/locales/br.lua new file mode 100644 index 00000000..a24a0645 --- /dev/null +++ b/locales/br.lua @@ -0,0 +1,9 @@ +Locales['br'] = { + + ['shop'] = 'Comprar', + ['shops'] = 'Lojas', + ['press_menu'] = 'Pressione ~INPUT_CONTEXT~ para acessar a loja.', + ['bought'] = 'você comprou ~b~1x ', + ['not_enough'] = 'você não tem ~r~dinheiro suficiente~s~.' + +} From fbbf0e0800a7f3b437c116e0708c3f01666690ff Mon Sep 17 00:00:00 2001 From: TakumiBR <31086346+TakumiBR@users.noreply.github.com> Date: Thu, 17 Aug 2017 08:33:20 -0700 Subject: [PATCH 0434/3224] Multi-language support Brazilian Portuguese translation. --- __resource.lua | 2 ++ locales/br.lua | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 locales/br.lua diff --git a/__resource.lua b/__resource.lua index 7a339a1a..37b6b8ba 100644 --- a/__resource.lua +++ b/__resource.lua @@ -4,6 +4,7 @@ description 'ESX RealestateAgentJob' server_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', '@mysql-async/lib/MySQL.lua', @@ -13,6 +14,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', diff --git a/locales/br.lua b/locales/br.lua new file mode 100644 index 00000000..e1f9bba9 --- /dev/null +++ b/locales/br.lua @@ -0,0 +1,23 @@ +Locales['br'] = { + + ['properties'] = 'Propriedades', + ['property'] = 'Propriedade', + ['clients'] = 'Clientes', + ['remove_comp_money'] = 'Remover dinheiro da empresa', + ['dep_money'] = 'Depositar dinheiro', + ['wash_money'] = 'Lavagem de dinheiro', + ['realtor'] = 'Corretor de imóveis', + ['amount_withdraw'] = 'Quantidade de retirada', + ['invalid_amount'] = 'Quantidade inválida', + ['amount_deposit'] = 'Valor do depósito', + ['amount_wash'] = 'Quantidade para lavagem', + ['press_to_access'] = 'Pressione ~INPUT_CONTEXT~ para abrir o menu', + ['property_actions'] = '{{Assign [Sell]|sell}} {{Assign [Rent]|rent}} {{GPS|gps}}', + ['amount'] = 'Quantidade', + ['no_play_near'] = 'Nenhum jogador nas proximidades', + ['contract'] = '{{Revoke contract|revoke}} {{GPS|gps}}', + ['rent'] = 'Alugar', + ['sell'] = 'Vender', + ['realtors'] = 'Agente Imobiliário', + +} \ No newline at end of file From 08af39980f251611d7d618a8455c22ee5e40895e Mon Sep 17 00:00:00 2001 From: TakumiBR <31086346+TakumiBR@users.noreply.github.com> Date: Thu, 17 Aug 2017 08:36:40 -0700 Subject: [PATCH 0435/3224] Multi-language support Brazilian Portuguese translation. --- __resource.lua | 2 ++ locales/br.lua | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 locales/br.lua diff --git a/__resource.lua b/__resource.lua index a5448753..184ac3ec 100644 --- a/__resource.lua +++ b/__resource.lua @@ -4,6 +4,7 @@ description 'ESX Police Job' server_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', '@mysql-async/lib/MySQL.lua', @@ -13,6 +14,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', diff --git a/locales/br.lua b/locales/br.lua new file mode 100644 index 00000000..e8e67d9e --- /dev/null +++ b/locales/br.lua @@ -0,0 +1,91 @@ +Locales['br'] = { + --Cloackroom + ['cloakroom'] = 'Vestiário', + ['citizen_wear'] = 'Roupa casual', + ['police_wear'] = 'Uniforme da Polícia', + ['open_cloackroom'] = 'Pressione ~INPUT_CONTEXT~ para se trocar', + --Armory + ['get_weapon'] = 'Pegar arma', + ['put_weapon'] = 'Entregar arma', + ['buy_weapons'] = 'Comprar armas', + ['armory'] = 'Arsenal', + ['open_armory'] = 'Pressione ~INPUT_CONTEXT~ para acessar o arsenal', + --Vehicles + ['vehicle_menu'] = 'Veículo', + ['vehicle_out'] = 'Já existe um carro fora da garagem', + ['vehicle_spawner'] = 'Pressione ~INPUT_CONTEXT~ para escolher um veículo', + ['store_vehicle'] = 'Pressione ~INPUT_CONTEXT~ para guardar o veículo', + ['service_max'] = 'Maximo de oficiais em serviço : ', + --Action Menu + ['citizen_interaction'] = 'Interagir com o cidadão', + ['vehicle_interaction'] = 'Interagir com o veículo', + ['object_spawner'] = 'Interagir com as rodovias', + + ['id_card'] = 'Carteira de identidade', + ['search'] = 'Procurar', + ['handcuff'] = 'Algemar / Soltar', + ['put_in_vehicle'] = 'Colocar no veículo', + ['fine'] = 'Multa', + ['no_players_nearby'] = 'Nenhum jogador nas proximidades', + + ['vehicle_info'] = 'Informações', + ['pick_lock'] = 'Trancar veículo', + ['vehicle_unlocked'] = 'Veículo ~g~destravado~s~', + ['no_vehicles_nearby'] = 'Nenhum veículo nas proximidades', + ['traffic_interaction'] = 'Interagir com as rodovias', + ['cone'] = 'Cones', + ['barrier'] = 'Barreira', + ['spikestrips'] = 'Fita de pregos', + ['box'] = 'Caixa', + ['cash'] = 'Caixa de dinheiro', + --ID Card Menu + ['name'] = 'Nome : ', + ['bac'] = 'bAC : ', + --Body Search Menu + ['confiscate_dirty'] = 'Confiscar dinheiro sujo : $', + ['guns_label'] = '--- Armas ---', + ['confiscate'] = 'Confiscar ', + ['inventory_label'] = '--- Inventário ---', + ['confiscate_inv'] = 'Confiscar x', + + ['traffic_offense'] = 'Infrações de transito', + ['minor_offense'] = 'Infração leve', + ['average_offense'] = 'Infração média', + ['major_offense'] = 'Infração grave', + ['fine_total'] = 'Multa : ', + --Vehicle Info Menu + ['plate'] = 'Placa: ', + ['owner_unknown'] = 'Proprietário : Desconhecido', + ['owner'] = 'Proprietário : ', + --Weapons Menus + ['get_weapon_menu'] = 'Arsenal - Pegar arma', + ['put_weapon_menu'] = 'Arsenal - Entregar arma', + ['buy_weapon_menu'] = 'Arsenal - Comprar armas', + ['not_enough_money'] = 'Você não tem dinheiro suficiente', + --Boss Menu + ['take_company_money'] = 'Retirar o dinheiro da empresa', + ['deposit_money'] = 'Depositar dinheiro', + ['amount_of_withdrawal'] = 'Quantidade de retirada', + ['invalid_amount'] = 'Quantidade inválida', + ['amount_of_deposit'] = 'Quantidade de depósito', + ['open_bossmenu'] = 'Pressione ~INPUT_CONTEXT~ para abrir o menu', + --Misc + ['remove_object'] = 'Pressione ~INPUT_CONTEXT~ para remover o objeto', + ['map_blip'] = 'Departamento de Polícia', + --Notifications + ['from'] = '~s~ de ~b~', + ['you_have_confinv'] = 'Você confiscou ~y~x', + ['confinv'] = '~s~ confiscado de você ~y~x', + ['you_have_confdm'] = 'Você confiscou ~y~$', + ['confdm'] = '~s~ confiscado de você ~y~$', + ['you_have_confweapon'] = 'Você confiscou ~y~x1 ', + ['confweapon'] = '~s~ confiscado de você ~y~x1 ', + ['alert_police'] = 'Alerta da Polícia', + --Authorized Vehicles + ['police'] = 'Viatura - Blazer', + ['police2'] = 'Viatura - Parati', + ['police3'] = 'viatura - Fluence', + ['police4'] = 'Viatura - Blazer cinza', + ['policeb'] = 'Moto da Polícia', + ['policet'] = 'Van de Transporte', +} \ No newline at end of file From 40ffe31324b3f8765c06ac18791b60410f718cdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 17 Aug 2017 17:40:47 +0200 Subject: [PATCH 0436/3224] New instance code --- client/main.lua | 97 +++++++++++++++++++++++++++++++++++++------------ server/main.lua | 91 ++++++++++++++++++++++++---------------------- 2 files changed, 122 insertions(+), 66 deletions(-) diff --git a/client/main.lua b/client/main.lua index 80989c6d..bea70293 100644 --- a/client/main.lua +++ b/client/main.lua @@ -10,32 +10,40 @@ local Keys = { ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 } -local GUI = {} -GUI.Time = 0 -local Instance = {} -local InstanceInvite = nil -local InstancedPlayers = {} +local GUI = {} +GUI.Time = 0 +local Instance = {} +local InstanceInvite = nil +local InstancedPlayers = {} +local RegisteredInstanceTypes = {} function ShowNotification(msg) SetNotificationTextEntry('STRING') AddTextComponentString(msg) - DrawNotification(0,1) + DrawNotification(0, 1) end function GetInstance() return Instance end -function CreateInstance() - TriggerServerEvent('instance:create') +function CreateInstance(type, data) + TriggerServerEvent('instance:create', type, data) end function CloseInstance() + Instance = {} TriggerServerEvent('instance:close') end function EnterInstance(instance) - TriggerServerEvent('instance:enter', InstanceInvite.host) + + TriggerServerEvent('instance:enter', instance.host) + + if RegisteredInstanceTypes[instance.type].enter ~= nil then + RegisteredInstanceTypes[instance.type].enter(instance) + end + end function LeaveInstance() @@ -46,21 +54,32 @@ function LeaveInstance() TriggerEvent('esx:showNotification', _U('left_instance')) end + if RegisteredInstanceTypes[Instance.type].exit ~= nil then + RegisteredInstanceTypes[Instance.type].exit(Instance) + end + TriggerServerEvent('instance:leave', Instance.host) end end -function InviteToInstance(player, pos) - TriggerServerEvent('instance:invite', Instance.host, player, pos) +function InviteToInstance(type, player, pos) + TriggerServerEvent('instance:invite', Instance.host, type, player, pos) +end + +function RegisterInstanceType(type, enter, exit) + RegisteredInstanceTypes[type] = { + enter = enter, + exit = exit + } end AddEventHandler('instance:get', function(cb) cb(GetInstance()) end) -AddEventHandler('instance:create', function() - CreateInstance() +AddEventHandler('instance:create', function(type, data) + CreateInstance(type, data) end) AddEventHandler('instance:close', function() @@ -75,13 +94,12 @@ AddEventHandler('instance:leave', function() LeaveInstance() end) -AddEventHandler('instance:invite', function(player, pos) - InviteToInstance(player, pos) +AddEventHandler('instance:invite', function(type, player, pos) + InviteToInstance(type, player, pos) end) -RegisterNetEvent('instance:onData') -AddEventHandler('instance:onData', function(instance) - Instance = instance +AddEventHandler('instance:registerType', function(name, enter, exit) + RegisterInstanceType(name, enter, exit) end) RegisterNetEvent('instance:onInstancedPlayersData') @@ -89,12 +107,45 @@ AddEventHandler('instance:onInstancedPlayersData', function(instancedPlayers) InstancedPlayers = instancedPlayers end) +RegisterNetEvent('instance:onCreate') +AddEventHandler('instance:onCreate', function(instance) + Instance = {} +end) + +RegisterNetEvent('instance:onEnter') +AddEventHandler('instance:onEnter', function(instance) + Instance = instance +end) + +RegisterNetEvent('instance:onLeave') +AddEventHandler('instance:onClose', function(instance) + Instance = {} +end) + +RegisterNetEvent('instance:onClose') +AddEventHandler('instance:onClose', function(instance) + Instance = {} +end) + +RegisterNetEvent('instance:onPlayerEntered') +AddEventHandler('instance:onPlayerEntered', function(instance, player) + Instance = instance + ShowNotification(GetPlayerName(GetPlayerFromServerId(player)) .. ' est entré dans l\'instance') +end) + +RegisterNetEvent('instance:onPlayerLeft') +AddEventHandler('instance:onPlayerLeft', function(instance, player) + Instance = instance + ShowNotification(GetPlayerName(GetPlayerFromServerId(player)) .. ' est sorti dans l\'instance') +end) + RegisterNetEvent('instance:onInvite') -AddEventHandler('instance:onInvite', function(instance, pos) +AddEventHandler('instance:onInvite', function(instance, type, data) InstanceInvite = { + type = type, host = instance, - pos = pos + data = data } Citizen.CreateThread(function() @@ -110,6 +161,8 @@ AddEventHandler('instance:onInvite', function(instance, pos) end) +RegisterInstanceType('default') + -- Input invites Citizen.CreateThread(function() while true do @@ -135,9 +188,7 @@ Citizen.CreateThread(function() local playerPed = GetPlayerPed(-1) - EnterInstance(InstanceInvite.host) - - SetEntityCoords(playerPed, InstanceInvite.pos.x, InstanceInvite.pos.y, InstanceInvite.pos.z) + EnterInstance(InstanceInvite) ShowNotification(_U('entered_instance')) diff --git a/server/main.lua b/server/main.lua index d8309566..47dd9cc4 100644 --- a/server/main.lua +++ b/server/main.lua @@ -14,14 +14,16 @@ function GetInstancedPlayers() end -function CreateInstance(player) - +function CreateInstance(type, player, data) + Instances[player] = { + type = type, host = player, - players = {player} + players = {}, + data = data } - TriggerClientEvent('instance:onData', player, Instances[player]) + TriggerClientEvent('instance:onCreate', player, Instances[player]) TriggerClientEvent('instance:onInstancedPlayersData', -1, GetInstancedPlayers()) end @@ -29,7 +31,7 @@ end function CloseInstance(instance) for i=1, #Instances[instance].players, 1 do - TriggerClientEvent('instance:onData', Instances[instance].players[i], {}) + TriggerClientEvent('instance:onClose', Instances[instance].players[i]) end Instances[instance] = nil @@ -53,8 +55,13 @@ function AddPlayerToInstance(instance, player) table.insert(Instances[instance].players, player) end + TriggerClientEvent('instance:onEnter', player, Instances[instance]) + for i=1, #Instances[instance].players, 1 do - TriggerClientEvent('instance:onData', Instances[instance].players[i], Instances[instance]) + if Instances[instance].players[i] ~= player then + TriggerClientEvent('instance:onPlayerEntered', Instances[instance].players[i], Instances[instance], player) + end + end TriggerClientEvent('instance:onInstancedPlayersData', -1, GetInstancedPlayers()) @@ -63,37 +70,50 @@ end function RemovePlayerFromInstance(instance, player) - if Instances[instance].host == player then - - CloseInstance(instance) - - else + if Instances[instance] ~= nil then - for i=1, #Instances[instance].players, 1 do - if Instances[instance].players[i] == player then - Instances[instance].players[i] = nil + TriggerClientEvent('instance:onLeave', player, Instances[instance]) + + if Instances[instance].host == player then + + for i=1, #Instances[instance].players, 1 do + if Instances[instance].players[i] ~= player then + TriggerClientEvent('instance:onPlayerLeft', Instances[instance].players[i], Instances[instance], player) + end end + + CloseInstance(instance) + + else + + for i=1, #Instances[instance].players, 1 do + if Instances[instance].players[i] == player then + Instances[instance].players[i] = nil + end + end + + for i=1, #Instances[instance].players, 1 do + if Instances[instance].players[i] ~= player then + TriggerClientEvent('instance:onPlayerLeft', Instances[instance].players[i], Instances[instance], player) + end + + end + + TriggerClientEvent('instance:onInstancedPlayersData', -1, GetInstancedPlayers()) + end - TriggerClientEvent('instance:onData', player, {}) - - for i=1, #Instances[instance].players, 1 do - TriggerClientEvent('instance:onData', Instances[instance].players[i], Instances[instance]) - end - - TriggerClientEvent('instance:onInstancedPlayersData', -1, GetInstancedPlayers()) - end end -function InvitePlayerToInstance(instance, player, pos) - TriggerClientEvent('instance:onInvite', player, instance, pos) +function InvitePlayerToInstance(instance, type, player, data) + TriggerClientEvent('instance:onInvite', player, instance, type, data) end RegisterServerEvent('instance:create') -AddEventHandler('instance:create', function() - CreateInstance(source) +AddEventHandler('instance:create', function(type, data) + CreateInstance(type, source, data) end) RegisterServerEvent('instance:close') @@ -112,22 +132,7 @@ AddEventHandler('instance:leave', function(instance) end) RegisterServerEvent('instance:invite') -AddEventHandler('instance:invite', function(instance, player, pos) - InvitePlayerToInstance(instance, player, pos) +AddEventHandler('instance:invite', function(instance, type, player, data) + InvitePlayerToInstance(instance, type, player, data) end) -TriggerEvent('es:addCommand', 'instance_create', function(source, args, user) - CreateInstance(source) -end) - -TriggerEvent('es:addCommand', 'instance_invite', function(source, args, user) - InvitePlayerToInstance(tonumber(args[2]), tonumber(args[3]), { - x = tonumber(args[4]), - y = tonumber(args[5]), - z = tonumber(args[6]), - }) -end) - -TriggerEvent('es:addCommand', 'instance_enter', function(source, args, user) - AddPlayerToInstance(source, tonumber(args[2])) -end) From 83b8ddec5e4d7efef82aff4085fc2558816cc337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 17 Aug 2017 17:41:42 +0200 Subject: [PATCH 0437/3224] Use new instance code --- __resource.lua | 4 ++++ client/main.lua | 55 ++++++++++++++++++++++++++++++++----------------- locales/en.lua | 1 + locales/fr.lua | 1 + 4 files changed, 42 insertions(+), 19 deletions(-) diff --git a/__resource.lua b/__resource.lua index 473a6ccf..948dceff 100644 --- a/__resource.lua +++ b/__resource.lua @@ -18,3 +18,7 @@ client_scripts { 'config.lua', 'client/main.lua' } + +dependencies { + 'instance' +} \ No newline at end of file diff --git a/client/main.lua b/client/main.lua index 36f260bd..7867679a 100644 --- a/client/main.lua +++ b/client/main.lua @@ -24,6 +24,7 @@ local CurrentActionMsg = '' local CurrentActionData = {} local FirstSpawn = true local PlayerLoaded = false +local Instance = {} function DrawSub(text, time) ClearPrints() @@ -112,12 +113,6 @@ function EnterProperty(name) TriggerServerEvent('esx_property:saveLastProperty', name) - TriggerEvent('instance:get', function(instance) - if instance.host == nil then - TriggerEvent('instance:create') - end - end) - Citizen.CreateThread(function() DoScreenFadeOut(800) @@ -170,12 +165,6 @@ function ExitProperty(name) SetEntityCoords(playerPed, outside.x, outside.y, outside.z) - TriggerEvent('instance:get', function(instance) - if instance.host ~= nil then - TriggerEvent('instance:leave') - end - end) - for i=1, #property.ipls, 1 do RemoveIpl(property.ipls[i]) end @@ -299,7 +288,7 @@ function OpenPropertyMenu(property) menu.close() if data2.current.value == 'enter' then - EnterProperty(property.name) + TriggerEvent('instance:create', 'property', {property = property.name}) end if data2.current.value == 'leave' then @@ -315,7 +304,7 @@ function OpenPropertyMenu(property) end if data2.current.value == 'visit' then - EnterProperty(property.name) + TriggerEvent('instance:create', 'property', {property = property.name}) end end, @@ -420,7 +409,7 @@ function OpenGatewayOwnedPropertiesMenu(property) menu.close() if data2.current.value == 'enter' then - EnterProperty(data.current.value) + TriggerEvent('instance:create', 'property', {property = data.current.value}) end if data2.current.value == 'leave' then @@ -492,7 +481,7 @@ function OpenGatewayAvailablePropertiesMenu(property) end if data2.current.value == 'visit' then - EnterProperty(data.current.value) + TriggerEvent('instance:create', 'property', {property = data.current.value}) end end, @@ -553,7 +542,8 @@ function OpenRoomMenu(property) elements = elements, }, function(data, menu) - TriggerEvent('instance:invite', GetPlayerServerId(data.current.value), property.inside) + TriggerEvent('instance:invite', 'property', GetPlayerServerId(data.current.value), {property = property.name}) + ESX.ShowNotification(_U('you_invited', GetPlayerName(data.current.value))) end, function(data, menu) menu.close() @@ -793,6 +783,15 @@ function OpenPlayerInventoryMenu(property) end +TriggerEvent('instance:registerType', 'property', + function(instance) + EnterProperty(instance.data.property) + end, + function(instance) + ExitProperty(instance.data.property) + end +) + AddEventHandler('playerSpawned', function() if FirstSpawn then @@ -805,7 +804,7 @@ AddEventHandler('playerSpawned', function() ESX.TriggerServerCallback('esx_property:getLastProperty', function(propertyName) if propertyName ~= nil then - EnterProperty(propertyName) + TriggerEvent('instance:create', 'property', {property = propertyName}) end end) @@ -849,6 +848,22 @@ AddEventHandler('esx:playerLoaded', function(xPlayer) end) +RegisterNetEvent('instance:onCreate') +AddEventHandler('instance:onCreate', function(instance) + + if instance.type == 'property' then + TriggerEvent('instance:enter', instance) + end + +end) + +RegisterNetEvent('instance:onPlayerLeft') +AddEventHandler('instance:onPlayerLeft', function(instance, player) + if player == instance.host then + ExitProperty(instance.data.property) + end +end) + AddEventHandler('esx_property:hasEnteredMarker', function(name, part) local property = GetProperty(name) @@ -1029,7 +1044,9 @@ Citizen.CreateThread(function() end if CurrentAction == 'room_exit' then - ExitProperty(CurrentActionData.propertyName) + TriggerEvent('instance:get', function(instance) + TriggerEvent('instance:leave') + end) end CurrentAction = nil diff --git a/locales/en.lua b/locales/en.lua index ce700925..133b42d1 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -11,6 +11,7 @@ Locales['en'] = { ['owned_properties'] = 'acquired properties', ['available_properties'] = 'available properties', ['invite_player'] = 'invite a player', + ['you_invited'] = 'you invited %s', ['player_clothes'] = 'clothes', ['remove_object'] = 'remove object', ['deposit_object'] = 'deposit object', diff --git a/locales/fr.lua b/locales/fr.lua index 2123dcb1..3b7a3567 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -11,6 +11,7 @@ Locales['fr'] = { ['owned_properties'] = 'propriétés acquises', ['available_properties'] = 'propriétés disponibles', ['invite_player'] = 'inviter un joueur', + ['you_invited'] = 'vous avez invité %s', ['player_clothes'] = 'vêtements', ['remove_object'] = 'retirer objet', ['deposit_object'] = 'déposer objet', From 9c033dcc91e6d8a432eb7f74bd8cff42da84355b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 17 Aug 2017 17:42:24 +0200 Subject: [PATCH 0438/3224] Use new instance code --- __resource.lua | 4 ++++ client/main.lua | 17 ++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/__resource.lua b/__resource.lua index d6d3babb..af0cdd5c 100644 --- a/__resource.lua +++ b/__resource.lua @@ -18,3 +18,7 @@ client_scripts { 'config.lua', 'client/main.lua' } + +dependencies { + 'instance' +} \ No newline at end of file diff --git a/client/main.lua b/client/main.lua index cb4e7f0a..3caf6ded 100644 --- a/client/main.lua +++ b/client/main.lua @@ -10,6 +10,17 @@ Citizen.CreateThread(function() end end) +TriggerEvent('instance:registerType', 'garage') + +RegisterNetEvent('instance:onCreate') +AddEventHandler('instance:onCreate', function(instance) + + if instance.type == 'garage' then + TriggerEvent('instance:enter', instance) + end + +end) + AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) if part == 'ExteriorEntryPoint' then @@ -36,7 +47,7 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) ESX.Game.Teleport(playerPed, spawnCoords, function() - TriggerEvent('instance:create') + TriggerEvent('instance:create', 'garage') ESX.Game.SpawnLocalVehicle(vehicleProps.model, spawnCoords, garage.InteriorSpawnPoint.Heading, function(vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) @@ -81,7 +92,7 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) z = garage.InteriorSpawnPoint.Pos.z }, function() - TriggerEvent('instance:create') + TriggerEvent('instance:create', 'garage') ESX.TriggerServerCallback('esx_vehicleshop:getVehiclesInGarage', function(vehicles) @@ -124,7 +135,7 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) z = garage.InteriorSpawnPoint.Pos.z }, function() - TriggerEvent('instance:create') + TriggerEvent('instance:create', 'garage') ESX.TriggerServerCallback('esx_vehicleshop:getVehiclesInGarage', function(vehicles) From 9f380ad8d35a307c79a0886d5ff3c8d1989ddbd4 Mon Sep 17 00:00:00 2001 From: TakumiBR <31086346+TakumiBR@users.noreply.github.com> Date: Thu, 17 Aug 2017 08:43:24 -0700 Subject: [PATCH 0439/3224] Multi-language support Brazilian Portuguese translation. --- __resource.lua | 2 ++ locales/br.lua | 7 +++++++ 2 files changed, 9 insertions(+) create mode 100644 locales/br.lua diff --git a/__resource.lua b/__resource.lua index 30e27ff6..dfec33a0 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,5 +1,6 @@ server_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', '@mysql-async/lib/MySQL.lua', @@ -8,6 +9,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', diff --git a/locales/br.lua b/locales/br.lua new file mode 100644 index 00000000..993f1630 --- /dev/null +++ b/locales/br.lua @@ -0,0 +1,7 @@ +Locales['br'] = { + + ['new_job'] = 'Você agora tem um novo emprego!', + ['access_job_center'] = 'Pressione ~INPUT_PICKUP~ para acessar a ~b~Lista de Empregos~s~.', + ['job_center'] = 'Agência de Empregos', + +} From afdebe587697fef4ef992470e20f4dc15c17e807 Mon Sep 17 00:00:00 2001 From: TakumiBR <31086346+TakumiBR@users.noreply.github.com> Date: Thu, 17 Aug 2017 08:46:05 -0700 Subject: [PATCH 0440/3224] Multi-language support Brazilian Portuguese translation. --- __resource.lua | 2 ++ locales/br.lua | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 locales/br.lua diff --git a/__resource.lua b/__resource.lua index 1ea8c6b8..87810e29 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,6 +2,7 @@ dependency 'essentialmode' client_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', @@ -10,6 +11,7 @@ client_scripts { server_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', diff --git a/locales/br.lua b/locales/br.lua new file mode 100644 index 00000000..f6c50ecb --- /dev/null +++ b/locales/br.lua @@ -0,0 +1,23 @@ +Locales['br'] = { + + ['robbery_cancelled'] = 'O roubo será cancelado, você não ganhará nada!', + ['robbery_successful'] = 'O roubo foi um sucesso. Você ganhou ~g~$', + ['shop_robbery'] = 'Loja roubavel', + ['press_to_rob'] = 'Pressione ~INPUT_CONTEXT~ para roubar ~b~', + ['robbery_of'] = 'Loja roubavel: ~r~', + ['seconds_remaining'] = '~w~ segundos restantes', + ['robbery_cancelled_at'] = '~r~ Roubo cancelado em: ~b~', + ['robbery_has_cancelled'] = '~r~ O assalto foi cancelado: ~b~', + ['already_robbed'] = 'Esta loja já foi roubada. Por favor, espere: ', + ['seconds'] = 'segundos.', + ['rob_in_prog'] = '~r~ Assalto em curso em: ~b~', + ['started_to_rob'] = 'Você começou a roubar ', + ['do_not_move'] = ', Não se afaste!', + ['alarm_triggered'] = 'O alarme foi disparado', + ['hold_pos'] = 'Segure por 5 minutos e o dinheiro é seu!', + ['robbery_complete'] = '~r~ Roubo completo.~s~ ~h~ Corre!', + ['robbery_complete_at'] = '~r~ Roubo completo em: ~b~', + ['min_two_police'] = 'Deve haver pelo menos ~b~2 policiais~s~ na cidade para roubar.', + ['robbery_already'] = '~r~Um assalto já está em andamento.', + +} From cce446bbaa1a6cb285b795eb5ed12d01713ff113 Mon Sep 17 00:00:00 2001 From: TakumiBR <31086346+TakumiBR@users.noreply.github.com> Date: Thu, 17 Aug 2017 08:48:48 -0700 Subject: [PATCH 0441/3224] Multi-language support Brazilian Portuguese translation. --- __resource.lua | 6 ++---- locales/br.lua | 6 ++++++ 2 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 locales/br.lua diff --git a/__resource.lua b/__resource.lua index af0cdd5c..698b69ec 100644 --- a/__resource.lua +++ b/__resource.lua @@ -4,6 +4,7 @@ description 'ESX Garage' server_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', '@mysql-async/lib/MySQL.lua', @@ -13,12 +14,9 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', 'client/main.lua' } - -dependencies { - 'instance' -} \ No newline at end of file diff --git a/locales/br.lua b/locales/br.lua new file mode 100644 index 00000000..3c7dccc4 --- /dev/null +++ b/locales/br.lua @@ -0,0 +1,6 @@ +Locales['br'] = { + + ['veh_released'] = 'Veículo ~g~já está disponivel', + ['veh_stored'] = 'Veículo ~g~guardado', + +} From 0a9da2b42683a36c114e25c99d4b5e42b15204c4 Mon Sep 17 00:00:00 2001 From: pixinc Date: Fri, 18 Aug 2017 02:53:09 +1100 Subject: [PATCH 0442/3224] Fix SellWeed xPlayer:removeInventoryItem replaced by xPlayer.removeInventoryItem --- server/esx_drugs_sv.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/esx_drugs_sv.lua b/server/esx_drugs_sv.lua index 867a0bc5..00417a88 100644 --- a/server/esx_drugs_sv.lua +++ b/server/esx_drugs_sv.lua @@ -490,7 +490,7 @@ local function SellWeed(source) if poochQuantity == 0 then TriggerClientEvent('esx:showNotification', source, _U('no_pouches_sale')) else - xPlayer:removeInventoryItem('weed_pooch', 1) + xPlayer.removeInventoryItem('weed_pooch', 1) if CopsConnected == 0 then xPlayer.addAccountMoney('black_money', 108) TriggerClientEvent('esx:showNotification', source, _U('sold_one_weed')) @@ -558,4 +558,4 @@ ESX.RegisterUsableItem('weed', function(source) TriggerClientEvent('esx_drugs:onPot', _source) TriggerClientEvent('esx:showNotification', _source, _U('used_one_weed')) -end) \ No newline at end of file +end) From 97fe7507eac836335a1668d8f57ead5324887c7a Mon Sep 17 00:00:00 2001 From: TakumiBR <31086346+TakumiBR@users.noreply.github.com> Date: Thu, 17 Aug 2017 08:53:20 -0700 Subject: [PATCH 0443/3224] Multi-language support Brazilian Portuguese translation --- __resource.lua | 2 ++ locales/br.lua | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 locales/br.lua diff --git a/__resource.lua b/__resource.lua index 47bf7078..53c16c00 100644 --- a/__resource.lua +++ b/__resource.lua @@ -3,6 +3,7 @@ description 'esx_drugs' server_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'server/esx_drugs_sv.lua', @@ -13,6 +14,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', diff --git a/locales/br.lua b/locales/br.lua new file mode 100644 index 00000000..23afcbb4 --- /dev/null +++ b/locales/br.lua @@ -0,0 +1,29 @@ +Locales['br'] = { + + ['press_collect_coke'] = 'Pressione ~INPUT_CONTEXT~ para coletar coca', + ['press_process_coke'] = 'Pressione ~INPUT_CONTEXT~ para processar a coca', + ['press_sell_coke'] = 'Pressione ~INPUT_CONTEXT~ para vender coca', + ['press_collect_meth'] = 'Pressione ~INPUT_CONTEXT~ para coletar metanfetamina', + ['press_process_meth'] = 'Pressione ~INPUT_CONTEXT~ para processar metanfetamina', + ['press_sell_meth'] = 'Pressione ~INPUT_CONTEXT~ para vender metanfetamina', + ['press_collect_weed'] = 'Pressione ~INPUT_CONTEXT~ para coletar erva', + ['press_process_weed'] = 'Pressione ~INPUT_CONTEXT~ para processar erva', + ['press_sell_weed'] = 'Pressione ~INPUT_CONTEXT~ para vender erva', + ['act_imp_police'] = 'Ação ~r~impossivel~s~, ~b~polícia~s~: ', + ['inv_full_coke'] = 'Você não pode mais coletar a Cocaína, seu estoque está ~r~cheio~s~', + ['pickup_in_prog'] = '~y~Colheita em progresso~s~...', + ['too_many_pouches'] = 'Você tem muitas trouxinhas', + ['not_enough_coke'] = 'Você não tem folha de coca suficiente para ~r~empacotar~s~', + ['packing_in_prog'] = '~y~Empacotamento em progresso~s~...', + ['no_pouchs_sale'] = 'Você não tem mais trouxinhas para ~r~vender~s~', + ['sold_one_coke'] = 'Você vendeu ~g~x1 Trouxinha de Cocaína~s~', + ['sale_in_prog'] = '~g~Venda em progresso~s~...', + ['inv_full_meth'] = 'Você não pode mais coletar metanfetamina, seu inventário está ~r~cheio~s~', + ['not_enough_meth'] = 'Você não tem metanfetamina suficiente para ~r~embalar~s~', + ['sold_one_meth'] = 'Você vendeu ~g~x1 Trouxinha de Metanfetamina~s~', + ['inv_full_weed'] = 'Você não pode mais coletar erva, seu inventário está ~r~cheio~s~', + ['not_enough_weed'] = 'Você não tem erva suficiente para ~r~embalar~s~', + ['sold_one_weed'] = 'Você vendeu ~g~x1 Trouxinha de erva~s~', + ['used_one_weed'] = 'Você usou 1 trouxinha de ~b~erva', + +} \ No newline at end of file From dd16aafa4b543164a0ba00d18f6d21ffc9b173c8 Mon Sep 17 00:00:00 2001 From: TakumiBR <31086346+TakumiBR@users.noreply.github.com> Date: Thu, 17 Aug 2017 08:57:45 -0700 Subject: [PATCH 0444/3224] Multi-language support Brazilian Portuguese translation. --- __resource.lua | 2 ++ locales/br.lua | 6 ++++++ 2 files changed, 8 insertions(+) create mode 100644 locales/br.lua diff --git a/__resource.lua b/__resource.lua index c5f72096..f0e0b5b1 100644 --- a/__resource.lua +++ b/__resource.lua @@ -4,6 +4,7 @@ description 'ESX Basic Needs' server_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', @@ -12,6 +13,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', diff --git a/locales/br.lua b/locales/br.lua new file mode 100644 index 00000000..22625651 --- /dev/null +++ b/locales/br.lua @@ -0,0 +1,6 @@ +Locales['br'] = { + + ['used_bread'] = 'Você comeu 1x pão', + ['used_water'] = 'Você tomou 1x água', + +} From 9d320fc84fd15a1a4b7637541e57ac7b32262265 Mon Sep 17 00:00:00 2001 From: TakumiBR <31086346+TakumiBR@users.noreply.github.com> Date: Thu, 17 Aug 2017 09:01:34 -0700 Subject: [PATCH 0445/3224] Multi-language support Brazilian Portuguese translation. --- __resource.lua | 2 ++ locales/br.lua | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 locales/br.lua diff --git a/__resource.lua b/__resource.lua index 9d745423..80f8453a 100644 --- a/__resource.lua +++ b/__resource.lua @@ -6,6 +6,7 @@ server_scripts { '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', 'config.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'server/main.lua' @@ -14,6 +15,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', 'config.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'client/main.lua' diff --git a/locales/br.lua b/locales/br.lua new file mode 100644 index 00000000..b663a74a --- /dev/null +++ b/locales/br.lua @@ -0,0 +1,21 @@ +Locales['br'] = { + ['actions'] = 'Ações', + ['amount'] = 'Quantidade', + ['balance'] = 'Saldo', + ['bank'] = 'Banco', + ['bill_amount'] = 'Montante de dinheiro', + ['billing'] = 'Faturamento', + ['customer'] = 'Cliente', + ['customers'] = 'Clientes', + ['deposit'] = 'Depositar', + ['deposit_amount'] = 'Quantidade para depositar', + ['deposit_society_money'] = 'Depositar dinheiro da sociedade', + ['invalid_amount'] = 'Quantidade inválida', + ['no_player_nearby'] = 'Nenhum jogador nas proximidades', + ['press_input_context_to_open_menu'] = 'Pressione ~INPUT_CONTEXT~ para abrir o menu', + ['property'] = 'Propriedade', + ['wash_money'] = 'Lavagem de dinheiro', + ['withdraw'] = 'Sacar', + ['withdraw_amount'] = 'Quantidade para sacar', + ['withdraw_society_money'] = 'Sacar dinheiro da sociedade', +} \ No newline at end of file From 2e4c14ea58281094aeea09f96ca3e675ef9dcc0f Mon Sep 17 00:00:00 2001 From: TakumiBR <31086346+TakumiBR@users.noreply.github.com> Date: Thu, 17 Aug 2017 09:04:56 -0700 Subject: [PATCH 0446/3224] Multi-language support Brazilian Portuguese translation. --- __resource.lua | 4 +++- locales/br.lua | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 locales/br.lua diff --git a/__resource.lua b/__resource.lua index 507ade9c..1a7000ed 100644 --- a/__resource.lua +++ b/__resource.lua @@ -5,7 +5,8 @@ description 'ESX Ambulance Job' server_scripts { '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', - 'locales/en.lua', + 'locales/br.lua', + 'locales/en.lua', 'locales/fr.lua', 'config.lua', 'server/main.lua' @@ -13,6 +14,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', diff --git a/locales/br.lua b/locales/br.lua new file mode 100644 index 00000000..3cc3d33c --- /dev/null +++ b/locales/br.lua @@ -0,0 +1,33 @@ +Locales['br'] = { + --Cloakroom + ['cloakroom'] = 'Vestiario', + ['ems_clothes_civil'] = 'Roupa casual', + ['ems_clothes_ems'] = 'Uniforme paramedico', + --Vehicles + ['veh_menu'] = 'Veículo', + ['veh_spawn'] = 'Pressione ~INPUT_CONTEXT~ para escolher veículo ou helicoptero', + ['store_veh'] = 'Pressione ~INPUT_CONTEXT~ para gaurdar o veículo', + ['ambulance'] = 'Ambulância', + ['helicopter'] = 'Helicoptero', + --Action Menu + ['hospital'] = 'Hospital', + ['revive_inprogress'] = 'Reanimação em progresso', + ['revive_complete'] = 'Você reviveu', + ['no_players'] = 'Nenhum jogador nas proximidades', + ['no_vehicles'] = 'Nenhum veículo nas proximidades', + ['isdead'] = 'esta morto', + ['unconscious'] = 'Não está inconsciente', + --Boss Menu + ['deposit_society'] = 'eMS Depositou', + ['withdraw_society'] = 'eMS Sacou', + --Misc + ['invalid_amount'] = '~r~quantidade inválida', + ['open_menu'] = 'Pressione ~INPUT_CONTEXT~ para abrir o menu', + ['deposit_amount'] = 'Quantidade para deposito', + ['money_withdraw'] = 'Quantidade para sacar', + -- F6 Menu + ['ems_menu'] = 'eMS Menu', + ['ems_menu_title'] = 'Paramedico - EMS Menu', + ['ems_menu_revive'] = 'Reviver jogador', + ['ems_menu_putincar'] = 'Colocar no veículo', +} \ No newline at end of file From 5d491d357cbed0cdb55cb06b3f811959b4b57804 Mon Sep 17 00:00:00 2001 From: TakumiBR <31086346+TakumiBR@users.noreply.github.com> Date: Thu, 17 Aug 2017 09:08:30 -0700 Subject: [PATCH 0447/3224] Multi-language support Brazilian Portuguese translation. --- .../[essential]/es_extended/__resource.lua | 2 + .../[essential]/es_extended/locales/br.lua | 121 ++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 resources/[essential]/es_extended/locales/br.lua diff --git a/resources/[essential]/es_extended/__resource.lua b/resources/[essential]/es_extended/__resource.lua index 84a0f8dc..396a1e69 100644 --- a/resources/[essential]/es_extended/__resource.lua +++ b/resources/[essential]/es_extended/__resource.lua @@ -7,6 +7,7 @@ server_scripts { '@mysql-async/lib/MySQL.lua', 'config.lua', 'locale.lua', + 'locales/br.lua', 'locales/fr.lua', 'locales/en.lua', 'config.weapons.lua', @@ -20,6 +21,7 @@ server_scripts { client_scripts { 'config.lua', 'locale.lua', + 'locales/br.lua', 'locales/fr.lua', 'locales/en.lua', 'config.weapons.lua', diff --git a/resources/[essential]/es_extended/locales/br.lua b/resources/[essential]/es_extended/locales/br.lua new file mode 100644 index 00000000..db4e39aa --- /dev/null +++ b/resources/[essential]/es_extended/locales/br.lua @@ -0,0 +1,121 @@ +Locales['br'] = { + ['inventory'] = 'inventário', + ['use'] = 'usar', + ['give'] = 'dar', + ['remove'] = 'remover', + ['return'] = 'voltar', + ['amount'] = 'quantidade', + ['amount_invalid'] = 'quantidade inválida', + ['players_nearby'] = 'nenhum jogador nas proximidades', + ['ex_inv_lim'] = 'Esta ação não é possível, supera o limite do inventário para ~b~', + ['yougave'] = 'você deu', + ['youreceived'] = 'você recebeu', + ['to'] = '~s~ para ~b~', + ['by'] = '~s~ por ~b~', + ['imp_invalid_quantity'] = 'ação impossível, quantidade inválida', + ['imp_invalid_amount'] = 'ação impossível, valor inválido', + ['delete_five_min'] = '~r~deleta~s~ em 5 minutos', + ['threw'] = 'você ~r~jogou~s~', + ['rec_salary'] = 'você recebeu seu salário: ', + ['act_imp'] = 'ação impossível', + -- Commands + ['setjob'] = 'atribuir um emprego a um usuário', + ['id_param'] = 'o id do jogador', + ['setjob_param2'] = 'o trabalho que você deseja atribuir', + ['setjob_param3'] = 'o nível de trabalho', + ['load_ipl'] = 'carregando ipl', + ['unload_ipl'] = 'descarregando ipl', + ['play_anim'] = 'reproduzir animação', + ['play_emote'] = 'reproduzir emote', + ['spawn_car'] = 'fazer aparecer um carro', + ['spawn_car_param'] = 'nome do carro', + ['givemoney'] = 'dar dinheiro', + ['money_amount'] = 'quantia do dinheiro', + ['invalid_account'] = 'conta inválida', + ['account'] = 'conta', + ['giveaccountmoney'] = 'dar dinheiro em conta', + ['invalid_item'] = 'item inválido', + ['item'] = 'item', + ['giveitem'] = 'dar item', + ['weapon'] = 'arma', + ['giveweapon'] = 'dar arma', + -- Weapons + ['weapon_knife'] = 'ffaca', + ['weapon_nightstick'] = 'cacetete', + ['weapon_hammer'] = 'martelo', + ['weapon_bat'] = 'bastão', + ['weapon_golfclub'] = 'golf club', + ['weapon_crowbar'] = 'pé de cabra', + ['weapon_pistol'] = 'pistola', + ['weapon_combatpistol'] = 'pistola de combate', + ['weapon_appistol'] = 'ap pistola', + ['weapon_pistol50'] = 'pistola .50', + ['weapon_microsmg'] = 'micro smg', + ['weapon_smg'] = 'smg', + ['weapon_assaultsmg'] = 'assault smg', + ['weapon_assaultrifle'] = 'assault rifle', + ['weapon_carbinerifle'] = 'carbine rifle', + ['weapon_advancedrifle'] = 'advanced rifle', + ['weapon_mg'] = 'mg', + ['weapon_combatmg'] = 'combat mg', + ['weapon_pumpshotgun'] = 'espingarda', + ['weapon_sawnoffshotgun'] = 'sawed off shotgun', + ['weapon_assaultshotgun'] = 'assault shotgun', + ['weapon_bullpupshotgun'] = 'bullpup shotgun', + ['weapon_stungun'] = 'arma de choque', + ['weapon_sniperrifle'] = 'sniper rifle', + ['weapon_heavysniper'] = 'heavy sniper', + ['weapon_remotesniper'] = 'remote sniper', + ['weapon_grenadelauncher'] = 'lançador de granada', + ['weapon_rpg'] = 'lançador de foguetes', + ['weapon_stinger'] = 'stinger', + ['weapon_minigun'] = 'minigun', + ['weapon_grenade'] = 'granada', + ['weapon_stickybomb'] = 'bomba pegajosa', + ['weapon_smokegrenade'] = 'granada de fumaça', + ['weapon_bzgas'] = 'bz gas', + ['weapon_molotov'] = 'coquetel molotov', + ['weapon_fireextinguisher'] = 'extintor', + ['weapon_petrolcan'] = 'galão de combustivel', + ['weapon_digiscanner'] = 'digiscanner', + ['weapon_ball'] = 'bola', + ['weapon_snspistol'] = 'sns pistol', + ['weapon_bottle'] = 'garrafa', + ['weapon_gusenberg'] = 'gusenberg sweeper', + ['weapon_specialcarbine'] = 'carabina especial', + ['weapon_heavypistol'] = 'heavy pistol', + ['weapon_bullpuprifle'] = 'bullpup rifle', + ['weapon_dagger'] = 'punhal', + ['weapon_vintagepistol'] = 'vintage pistol', + ['weapon_firework'] = 'fogos de artifício', + ['weapon_musket'] = 'mosquete', + ['weapon_heavyshotgun'] = 'heavy shotgun', + ['weapon_marksmanrifle'] = 'marksman rifle', + ['weapon_hominglauncher'] = 'homing launcher', + ['weapon_proxmine'] = 'mina de proximidade', + ['weapon_snowball'] = 'bola de neve', + ['weapon_flaregun'] = 'sinalizador', + ['weapon_garbagebag'] = 'saco de lixo', + ['weapon_handcuffs'] = 'algemas', + ['weapon_combatpdw'] = 'combat pdw', + ['weapon_marksmanpistol'] = 'marksman pistol', + ['weapon_knuckle'] = 'soco inglês', + ['weapon_hatchet'] = 'machado', + ['weapon_railgun'] = 'railgun', + ['weapon_machete'] = 'facão', + ['weapon_machinepistol'] = 'machine pistol', + ['weapon_switchblade'] = 'canivete', + ['weapon_revolver'] = 'heavy revolver', + ['weapon_dbshotgun'] = 'espingarda de cano duplo', + ['weapon_compactrifle'] = 'compact rifle', + ['weapon_autoshotgun'] = 'auto shotgun', + ['weapon_battleaxe'] = 'battle axe', + ['weapon_compactlauncher'] = 'compact launcher', + ['weapon_minismg'] = 'mini smg', + ['weapon_pipebomb'] = 'bomba caseira', + ['weapon_poolcue'] = 'taco de sinuca', + ['weapon_wrench'] = 'chave de cano', + ['weapon_flashlight'] = 'laterna', + ['gadget_nightvision'] = 'visão noturna', + ['gadget_parachute'] = 'paraquedas', +} \ No newline at end of file From d210c5ef4ad15bd383611ac7f3d38a58b6571cfb Mon Sep 17 00:00:00 2001 From: TakumiBR <31086346+TakumiBR@users.noreply.github.com> Date: Thu, 17 Aug 2017 09:17:25 -0700 Subject: [PATCH 0448/3224] Multi-language support Brazilian Portuguese translation. --- __resource.lua | 2 ++ locales/br.lua | 9 +++++++++ 2 files changed, 11 insertions(+) create mode 100644 locales/br.lua diff --git a/__resource.lua b/__resource.lua index bf87ae44..ec0d70a4 100644 --- a/__resource.lua +++ b/__resource.lua @@ -5,6 +5,7 @@ description 'ESX Society' server_scripts { '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', @@ -13,6 +14,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', diff --git a/locales/br.lua b/locales/br.lua new file mode 100644 index 00000000..db67419b --- /dev/null +++ b/locales/br.lua @@ -0,0 +1,9 @@ +Locales['br'] = { + + ['have_withdrawn'] = 'Você sacou ~g~$', + ['invalid_amount'] = 'Quantidade inválida', + ['have_deposited'] = 'Você depositou ~r~$', + ['you_have'] = 'Você tem ~g~$', + ['you_have_laundered'] = 'Você ~r~lavou~s~ seu dinheiro: ~g~$', + +} From e5ac0dceacee1f8f918287ffcd78c81e275ac206 Mon Sep 17 00:00:00 2001 From: Wesley Moura <14825927+wesleymoura@users.noreply.github.com> Date: Thu, 17 Aug 2017 13:30:09 -0300 Subject: [PATCH 0449/3224] Update __resource.lua Changed ptbr to br to standardize with other translations --- __resource.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/__resource.lua b/__resource.lua index c2a4388e..43e598eb 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,6 +1,6 @@ server_scripts { '@es_extended/locale.lua', - 'locales/ptbr.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', @@ -9,7 +9,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', - 'locales/ptbr.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', From 7998a2a9a4d61dec6534a611cac4d10da3d62087 Mon Sep 17 00:00:00 2001 From: Wesley Moura <14825927+wesleymoura@users.noreply.github.com> Date: Thu, 17 Aug 2017 13:30:48 -0300 Subject: [PATCH 0450/3224] Update and rename ptbr.lua to br.lua Changed ptbr to br to standardize with other translations --- locales/{ptbr.lua => br.lua} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename locales/{ptbr.lua => br.lua} (92%) diff --git a/locales/ptbr.lua b/locales/br.lua similarity index 92% rename from locales/ptbr.lua rename to locales/br.lua index cf9b5e4b..04bd0cb8 100644 --- a/locales/ptbr.lua +++ b/locales/br.lua @@ -1,4 +1,4 @@ -Locales['ptbr'] = { +Locales['br'] = { ['invalid_amount'] = '~r~Quantidade inválida', ['deposit_money'] = 'Você depósitou ~g~$', ['withdraw_money'] = 'Você retirou ~g~$', From 4466e0ec204bb9446ea72ad7c9ccc0e4d30f62b4 Mon Sep 17 00:00:00 2001 From: Don <30905704+ddh3@users.noreply.github.com> Date: Thu, 17 Aug 2017 09:33:20 -0700 Subject: [PATCH 0451/3224] Update __resource.lua Missing config.lua in resource.lua file --- __resource.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/__resource.lua b/__resource.lua index 91ad7337..eff9b223 100644 --- a/__resource.lua +++ b/__resource.lua @@ -4,6 +4,7 @@ description 'ESX Skin' server_scripts { '@es_extended/locale.lua', + 'config.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', @@ -13,6 +14,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'config.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', From 61bbb536a1e0ff1b1efefb8024a55f0cde82f7d2 Mon Sep 17 00:00:00 2001 From: TakumiBR <31086346+TakumiBR@users.noreply.github.com> Date: Thu, 17 Aug 2017 09:39:57 -0700 Subject: [PATCH 0452/3224] Multi-language support Brazilian Portuguese translation. --- __resource.lua | 2 ++ locales/br.lua | 8 ++++++++ 2 files changed, 10 insertions(+) create mode 100644 locales/br.lua diff --git a/__resource.lua b/__resource.lua index 3bcf89ea..8321f96c 100644 --- a/__resource.lua +++ b/__resource.lua @@ -5,6 +5,7 @@ description 'Instance' server_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', @@ -16,6 +17,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', diff --git a/locales/br.lua b/locales/br.lua new file mode 100644 index 00000000..47c85b40 --- /dev/null +++ b/locales/br.lua @@ -0,0 +1,8 @@ +Locales['br'] = { + + ['left_instance'] = 'Você deixou a instância', + ['invite_expired'] = 'Convite expirado', + ['press_to_enter'] = 'Pressione ~INPUT_CONTEXT~ para entrar na instância', + ['entered_instance'] = 'Você entrou na instância', + +} From c25a32e6deef54b85d926c06c651d86b1041c055 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Thu, 17 Aug 2017 12:51:41 -0400 Subject: [PATCH 0453/3224] Updated multi-language support --- client/main.lua | 6 +++--- locales/en.lua | 2 ++ locales/fr.lua | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/client/main.lua b/client/main.lua index bea70293..7852e340 100644 --- a/client/main.lua +++ b/client/main.lua @@ -37,7 +37,7 @@ function CloseInstance() end function EnterInstance(instance) - + TriggerServerEvent('instance:enter', instance.host) if RegisteredInstanceTypes[instance.type].enter ~= nil then @@ -130,13 +130,13 @@ end) RegisterNetEvent('instance:onPlayerEntered') AddEventHandler('instance:onPlayerEntered', function(instance, player) Instance = instance - ShowNotification(GetPlayerName(GetPlayerFromServerId(player)) .. ' est entré dans l\'instance') + ShowNotification(GetPlayerName(GetPlayerFromServerId(player)) .. _U('entered_into')) end) RegisterNetEvent('instance:onPlayerLeft') AddEventHandler('instance:onPlayerLeft', function(instance, player) Instance = instance - ShowNotification(GetPlayerName(GetPlayerFromServerId(player)) .. ' est sorti dans l\'instance') + ShowNotification(GetPlayerName(GetPlayerFromServerId(player)) .. _U('left_out')) end) RegisterNetEvent('instance:onInvite') diff --git a/locales/en.lua b/locales/en.lua index 2ba5f274..41f01dcb 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -4,5 +4,7 @@ Locales['en'] = { ['invite_expired'] = 'invite expired', ['press_to_enter'] = 'press ~INPUT_CONTEXT~ to enter the instance', ['entered_instance'] = 'you entered the instance', + ['entered_into'] = ' entered the instance', + ['left_out'] = ' left the instance', } diff --git a/locales/fr.lua b/locales/fr.lua index 83f595e9..02a2f407 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -4,5 +4,7 @@ Locales['fr'] = { ['invite_expired'] = 'invitation expirée', ['press_to_enter'] = 'appuyez sur ~INPUT_CONTEXT~ pour entrer dans l\'instance', ['entered_instance'] = 'vous êtes entré dans l\'instance', + ['entered_into'] = ' est entré dans l\'instance', + ['left_out'] = ' est sorti dans l\'instance', } From a0f435e389132bb72067db678f1023acfc4f7d4d Mon Sep 17 00:00:00 2001 From: nearbyplayer <3721216+nearbyplayer@users.noreply.github.com> Date: Thu, 17 Aug 2017 14:03:04 -0400 Subject: [PATCH 0454/3224] Update __resource.lua --- __resource.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/__resource.lua b/__resource.lua index dfec33a0..d6f3bb27 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,9 +1,10 @@ server_scripts { + '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', - '@mysql-async/lib/MySQL.lua', + 'config.lua', 'server/esx_joblisting_sv.lua' } From fa85f47fd69fa2c5bf61dd2d25503e9db57cc7b8 Mon Sep 17 00:00:00 2001 From: nearbyplayer <3721216+nearbyplayer@users.noreply.github.com> Date: Thu, 17 Aug 2017 14:11:50 -0400 Subject: [PATCH 0455/3224] Update __resource.lua Add missing resource_manifest_version --- __resource.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/__resource.lua b/__resource.lua index d6f3bb27..58be36f8 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,3 +1,5 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + server_scripts { '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', From f588707547f4af2c80dab793bd552e472a19d74f Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Thu, 17 Aug 2017 14:17:32 -0400 Subject: [PATCH 0456/3224] Update multi-language support --- __resource.lua | 4 ++-- client/esx_joblisting_cl.lua | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/__resource.lua b/__resource.lua index 58be36f8..d63e1497 100644 --- a/__resource.lua +++ b/__resource.lua @@ -3,18 +3,18 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' server_scripts { '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', + 'config.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', - 'config.lua', 'server/esx_joblisting_sv.lua' } client_scripts { '@es_extended/locale.lua', + 'config.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', - 'config.lua', 'client/esx_joblisting_cl.lua' } diff --git a/client/esx_joblisting_cl.lua b/client/esx_joblisting_cl.lua index 2ae6c0a0..d4560005 100644 --- a/client/esx_joblisting_cl.lua +++ b/client/esx_joblisting_cl.lua @@ -31,7 +31,7 @@ function ShowJobListingMenu(data) ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'joblisting', { - title = 'POLE EMPLOI', + title = _U('job_center'), elements = elements }, function(data, menu) From eb3b8f86a311c684fc17e66fe5229cbd60c15d61 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Thu, 17 Aug 2017 14:19:08 -0400 Subject: [PATCH 0457/3224] Update __resource.lua Removes resource_manifest_version --- __resource.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/__resource.lua b/__resource.lua index d63e1497..4c7f041d 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,5 +1,3 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' - server_scripts { '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', From b28e5324dcd131fac744733dbf5c2cc49ba69f3a Mon Sep 17 00:00:00 2001 From: Allan <31086346+TakumiBR@users.noreply.github.com> Date: Thu, 17 Aug 2017 12:07:45 -0700 Subject: [PATCH 0458/3224] Multi-language support Brazilian Portuguese translation. --- locales/br.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index 6baa2746..554f392c 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,7 +1,8 @@ Locales['br'] = { ['skin_menu'] = 'Skin Menu', - ['use_rotate_view'] = 'Use ~INPUT_VEH_FLY_ROLL_LEFT_ONLY~ e ~INPUT_VEH_FLY_ROLL_RIGHT_ONLY~ para girar a visão.', - + ['use_rotate_view'] = 'Use as setas ~INPUT_VEH_FLY_ROLL_LEFT_ONLY~ ~INPUT_VEH_FLY_ROLL_RIGHT_ONLY~ para girar a visão.', + ['skin'] = 'Trocar', + ['saveskin'] = 'Salvar', } From 668758fe422d9998c4c83030619ef4ff1eb20f8a Mon Sep 17 00:00:00 2001 From: Allan <31086346+TakumiBR@users.noreply.github.com> Date: Thu, 17 Aug 2017 12:09:33 -0700 Subject: [PATCH 0459/3224] Multi-language support Brazilian Portuguese translation. --- locales/br.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/br.lua b/locales/br.lua index 554f392c..f35e7998 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,7 +1,7 @@ Locales['br'] = { ['skin_menu'] = 'Skin Menu', - ['use_rotate_view'] = 'Use as setas ~INPUT_VEH_FLY_ROLL_LEFT_ONLY~ ~INPUT_VEH_FLY_ROLL_RIGHT_ONLY~ para girar a visão.', + ['use_rotate_view'] = 'Use ~INPUT_VEH_FLY_ROLL_LEFT_ONLY~ e ~INPUT_VEH_FLY_ROLL_RIGHT_ONLY~ para girar a visão.', ['skin'] = 'Trocar', ['saveskin'] = 'Salvar', From a99e47718f7ff44b09f01cd50067afb1af8258d9 Mon Sep 17 00:00:00 2001 From: nlmarcio Date: Thu, 17 Aug 2017 23:45:38 +0200 Subject: [PATCH 0460/3224] Phone image modification --- html/img/phone.png | Bin 18906 -> 19471 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/html/img/phone.png b/html/img/phone.png index 47f6f82fcb850b516b76a137c3a99e6137146760..2c2c8adb63ec344b9fe8b789df021478909de7c7 100644 GIT binary patch literal 19471 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 XPCnY@+C~`#4(+hAu!q%{UrYEmIL@=p literal 18906 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 Date: Thu, 17 Aug 2017 22:44:04 -0400 Subject: [PATCH 0461/3224] Add missing translation --- locales/br.lua | 2 ++ locales/en.lua | 2 ++ locales/fr.lua | 2 ++ server/main.lua | 6 +++--- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index 3cc3d33c..b90a21b8 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -30,4 +30,6 @@ Locales['br'] = { ['ems_menu_title'] = 'Paramedico - EMS Menu', ['ems_menu_revive'] = 'Reviver jogador', ['ems_menu_putincar'] = 'Colocar no veículo', + -- Phone + ['alert_ambulance'] = 'ambulância de alerta', } \ No newline at end of file diff --git a/locales/en.lua b/locales/en.lua index 26d663dd..80573437 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -30,4 +30,6 @@ Locales['en'] = { ['ems_menu_title'] = 'ambulance - EMS Menu', ['ems_menu_revive'] = 'revive Player', ['ems_menu_putincar'] = 'put in Vehicle', + -- Phone + ['alert_ambulance'] = 'alert Ambulance', } \ No newline at end of file diff --git a/locales/fr.lua b/locales/fr.lua index da7d1d2e..dc9819e1 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -30,4 +30,6 @@ Locales['fr'] = { ['ems_menu_title'] = 'ambulance - Interactions Citoyen', ['ems_menu_revive'] = 'réanimer', ['ems_menu_putincar'] = 'mettre dans véhicule', + -- Phone + ['alert_ambulance'] = 'alerte Ambulance', } \ No newline at end of file diff --git a/server/main.lua b/server/main.lua index 7d4555fc..923cc28b 100644 --- a/server/main.lua +++ b/server/main.lua @@ -43,10 +43,10 @@ TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message for k, v in pairs(xPlayers) do if v.job.name == 'ambulance' then TriggerEvent('esx_phone:getDistpatchRequestId', function(requestId) - TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'Alerte Ambulance', requestId) + TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, _U('alert_ambulance'), requestId) end) end end end - -end) \ No newline at end of file + +end) From a5c420e05e852b86f6e80b969b77d569de6044be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 18 Aug 2017 10:17:47 +0200 Subject: [PATCH 0462/3224] Fix give weapon --- .../[essential]/es_extended/client/functions.lua | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 5e85b674..f9d3b60f 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -463,11 +463,11 @@ ESX.Game.GetClosestPlayer = function(coords) local closestPlayer = -1 local coords = coords local usePlayerPed = false - local playerPed = nil + local playerPed = GetPlayerPed(-1) + local playerId = PlayerId() if coords == nil then usePlayerPed = true - playerPed = GetPlayerPed(-1) coords = GetEntityCoords(playerPed) end @@ -475,7 +475,7 @@ ESX.Game.GetClosestPlayer = function(coords) local target = GetPlayerPed(players[i]) - if not usePlayerPed or (usePlayerPed and target ~= playerPed) then + if not usePlayerPed or (usePlayerPed and players[i] ~= playerId) then local targetCoords = GetEntityCoords(target) local distance = GetDistanceBetweenCoords(targetCoords.x, targetCoords.y, targetCoords.z, coords.x, coords.y, coords.z, true) @@ -944,7 +944,15 @@ ESX.ShowInventory = function() if data.current.action == 'give' then if type == 'item_weapon' then - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 1) + + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(_U('players_nearby')) + else + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 1) + end + else ESX.UI.Menu.Open( From 5a54dd83cf4b8f559c252ea376d6d1c3bd4909aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 18 Aug 2017 10:20:54 +0200 Subject: [PATCH 0463/3224] Fix find ped --- client/main.lua | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/client/main.lua b/client/main.lua index 3ad129c7..d7409c27 100644 --- a/client/main.lua +++ b/client/main.lua @@ -484,28 +484,32 @@ Citizen.CreateThread(function() local ped = GetRandomPed() - if IsPedHuman(ped) and IsPedWalking(ped) then + if DoesEntityExist(ped) IsPedHuman(ped) and IsPedWalking(ped) and not IsPedAPlayer(ped) then CurrentCustomer = ped end end - CurrentCustomerBlip = AddBlipForEntity(CurrentCustomer) + if DoesEntityExist(ped) then - SetBlipAsFriendly(CurrentCustomerBlip, 1) - SetBlipColour(CurrentCustomerBlip, 2) - SetBlipCategory(CurrentCustomerBlip, 3) - SetBlipRoute(CurrentCustomerBlip, true) + CurrentCustomerBlip = AddBlipForEntity(CurrentCustomer) - SetEntityAsMissionEntity(CurrentCustomer, true) - ClearPedTasksImmediately(CurrentCustomer) - SetBlockingOfNonTemporaryEvents(CurrentCustomer, 1) + SetBlipAsFriendly(CurrentCustomerBlip, 1) + SetBlipColour(CurrentCustomerBlip, 2) + SetBlipCategory(CurrentCustomerBlip, 3) + SetBlipRoute(CurrentCustomerBlip, true) - local standTime = GetRandomIntInRange(60000, 180000) + SetEntityAsMissionEntity(CurrentCustomer, true, false) + ClearPedTasksImmediately(CurrentCustomer) + SetBlockingOfNonTemporaryEvents(CurrentCustomer, 1) - TaskStandStill(CurrentCustomer, standTime) + local standTime = GetRandomIntInRange(60000, 180000) - ESX.ShowNotification(_U('customer_found')) + TaskStandStill(CurrentCustomer, standTime) + + ESX.ShowNotification(_U('customer_found')) + + end end @@ -525,7 +529,7 @@ Citizen.CreateThread(function() RemoveBlip(DestinationBlip) end - SetEntityAsMissionEntity(CurrentCustomer, false) + SetEntityAsMissionEntity(CurrentCustomer, false, true) CurrentCustomer = nil CurrentCustomerBlip = nil @@ -557,7 +561,7 @@ Citizen.CreateThread(function() ESX.ShowNotification(_U('arrive_dest')) TaskGoStraightToCoord(CurrentCustomer, TargetCoords.x, TargetCoords.y, TargetCoords.z, 1.0, -1, 0.0, 0.0) - SetEntityAsMissionEntity(CurrentCustomer, false) + SetEntityAsMissionEntity(CurrentCustomer, false, true) TriggerServerEvent('esx_taxijob:success') From 912ab6185b76fdd900fd3d66912565f0b1b5a4a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 18 Aug 2017 10:23:00 +0200 Subject: [PATCH 0464/3224] Fix playername not showing + remove gps for players --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index b1555710..9fecf1a7 100644 --- a/server/main.lua +++ b/server/main.lua @@ -275,7 +275,7 @@ AddEventHandler('esx_phone:ready', function() for k, v in pairs(xPlayers) do if v.get('phoneNumber') == phoneNumber then - TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, job, false) + TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, false, anon, 'player', false) end end From cea123213c1bf78ce8ea1ba2b90c7dbcda07eb27 Mon Sep 17 00:00:00 2001 From: ultratm Date: Fri, 18 Aug 2017 11:09:03 +0200 Subject: [PATCH 0465/3224] Add German language --- __resource.lua | 2 ++ locales/de.lua | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index 2f98bcc3..9a4b5b29 100644 --- a/__resource.lua +++ b/__resource.lua @@ -4,6 +4,7 @@ description 'ESX Taxi Job' client_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', @@ -13,6 +14,7 @@ client_scripts { server_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..dbf231cd --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,32 @@ +Locales['de'] = { + + ['taking_service'] = 'Service annehmen: ', + ['spawn_veh'] = 'Fahrzeug spawnen', + ['remove_comp_money'] = 'Firmengeld abheben', + ['deposit_money'] = 'Geld einzahlen', + ['launder_money'] = 'Geld waschen', + ['full_service'] = 'Voller Service: ', + ['withdraw_amount'] = 'Betrag zum abheben', + ['amount_invalid'] = 'Betrag ungültig', + ['deposit_amount'] = 'Betrag zum einzahlen', + ['launder_amount'] = 'Betrag zum waschen', + ['press_to_open'] = 'Drücke ~INPUT_CONTEXT~ um das Menü zu öffnen', + ['billing'] = 'Rechnung', + ['invoice_amount'] = 'Rechnugsbetrag', + ['no_players_near'] = 'Kein Spieler in der Nähe', + ['store_veh'] = 'Drücke ~INPUT_CONTEXT~ um das Fahrzeug zu parken', + ['drive_search_pass'] = 'Auf der Suche nach ~y~Passagieren', + ['customer_found'] = 'du hast einen Passagier ~g~gefunden~s~ , Fahre in zum Ziel', + ['client_unconcious'] = 'dein Passagier ist ~r~bewusstlos~w~. Suche nach einem anderen.', + ['arrive_dest'] = 'du bist an deinem Ziel ~g~angekommen~s~', + ['take_me_to_near'] = '~w~Bring mich nach~y~ %s~w~, in der Nähe von~y~ %s', + ['take_me_to'] = '~w~Bring mich nach~y~ %s', + ['close_to_client'] = 'du bist nahe an dem Passagier, du musst noch näher ran', + ['return_to_veh'] = 'bitte kehre zu deinem Fahezeug zurück umd die Mission fortzuführen', + ['only_taxi'] = 'Du kannst nur Taxis parken.', + ['must_in_taxi'] = 'Du musst in einem Taxis sein umd die Mission starten zu können', + ['must_in_vehicle'] = 'Du musst in einem Fahrzeug sein um die Mission starten zu können', + ['have_earned'] = 'verdient ~g~$', + ['comp_earned'] = 'Die Firma verdient ~g~$', + +} From dd8d0a01d8b0c3d65ce86ad40ef7eed7ad3413f3 Mon Sep 17 00:00:00 2001 From: ultratm Date: Fri, 18 Aug 2017 11:22:54 +0200 Subject: [PATCH 0466/3224] Add German language --- __resource.lua | 2 ++ locales/de.lua | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index f60e45be..38393945 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,6 +1,7 @@ server_scripts { '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', + 'locales/de.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', @@ -9,6 +10,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..f0979b94 --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,39 @@ +Locales['de'] = { + --Global menus + ['bank_deposit'] = 'eine Kaution von ~g~', + ['bank_deposit_r'] = 'eine Kaution von ~g~$', + ['bank_deposit2'] = '$ ~s~wurde nach deiner Ohmacht getätigt.', + ['bank_nodeposit'] = "du hast keine Sicherheiten", + ['foot_work'] = 'du musst zu Fuß sein um arbeiten zu können.', + ['next_point'] = 'gehe zum nächsten Schritt wenn du hier fertig bist.', + ['security_deposit'] = 'die Kaution beträgt ~g~$', + ['not_your_vehicle'] = "Das ist nicht dein Fahrzeug oder du musst der Fahrer sein.", + ['in_vehicle'] = 'du musst in einem Fahrzeug sein.', + ['wrong_point'] = "Du bist nicht am richtigen Punkt zum liefern.", + ['max_limit'] = 'Du hast das Maximum: ', + ['not_enough'] = "du hast nicht genug", + ['not_enough2'] = ' umd die Aktion fortzuführen.', + ['caution_taken'] = ' ~s~wurde von dir abgezogen.', + ['caution_returned'] = ' ~s~wurde dir zurück gegeben.', + + --Lumber Jack job + ['lj_cr_title'] = 'Garderobe', + ['lj_cloakroom'] = 'Drücke ~INPUT_PICKUP~ um dich umzuziehen.', + ['lj_mapblip'] = 'Holzstappel', + ['lj_wood'] = 'Holz', + ['lj_pickup'] = 'Drücke ~INPUT_PICKUP~ um Holz zu bekommen.', + ['lj_cutwood'] = 'schlage Holz', + ['lj_cutwood_button'] = 'Drücke ~INPUT_PICKUP~ um Bäume zu fällen.', + ['lj_board'] = 'Bretter', + ['lj_planks'] = 'Bretterpaket', + ['lj_delivery'] = 'liefern', + ['lj_cutwood'] = 'Holz schneiden', + ['lj_pick_boards'] = 'Drücke ~INPUT_PICKUP~ um Bretter zu erhalten.', + ['lj_spawn_veh'] = 'Fahrzeug spawnen', + ['lj_spawn_veh_button'] = 'Drücke ~INPUT_PICKUP~ um das Lieferfahrzeug zu rufen.', + ['lj_service_vh'] = 'Service Fahrzeug', + ['lj_return_vh'] = 'Fahrzeug parken', + ['lj_delivery_point'] = 'Lieferpunkt', + ['lj_return_vh_button'] = 'Drücke ~INPUT_PICKUP~ um das Fahrzeug zu parken.', + ['lj_deliver_button'] = 'Drücke ~INPUT_PICKUP~ um die Bretter zu liefern.' +} From 351e288b513f5ba58f6da635f0f01b8cbe39455e Mon Sep 17 00:00:00 2001 From: ultratm Date: Fri, 18 Aug 2017 11:30:45 +0200 Subject: [PATCH 0467/3224] Add german config and SQL --- de_config.lua | 45 +++++++++++++++++++++++++++++++++++++++++++++ de_esx_jobs.sql | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 de_config.lua create mode 100644 de_esx_jobs.sql diff --git a/de_config.lua b/de_config.lua new file mode 100644 index 00000000..aa13284a --- /dev/null +++ b/de_config.lua @@ -0,0 +1,45 @@ +Config = {} +Config.DrawDistance = 1000.0 +Config.Locale = 'de' + +Config.Plates = { + taxi = "TAXI", + fisherman = "FISH", + cop = "LSPD", + ambulance = "EMS", + depanneur = "MECA", + fuel = "FUEL", + lumberjack = "BUCH", + miner = "MINE", + reporter = "JOUR", + slaughterer = "ABAT", + textil = "COUT" +} + +Config.Jobs = {} + +Config.PublicZones = { + EnterBuilding = { + Pos = { x = -118.21381378174, y = -607.14227294922, z = 35.280723571777 }, + Size = {x = 3.0, y = 3.0, z = 0.2}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = false, + Name = "Arbeitsamt", + Type = "teleport", + Hint = "Drücke ~INPUT_PICKUP~ um das Gebäude zu betreten.", + Teleport = { x = -139.09838867188, y = -620.74865722656, z = 167.82052612305 } + }, + + ExitBuilding = { + Pos = { x = -139.45831298828, y = -617.32312011719, z = 167.82052612305 }, + Size = {x = 3.0, y = 3.0, z = 0.2}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = false, + Name = "Arbeitsamt", + Type = "teleport", + Hint = "Drücke ~INPUT_PICKUP~ um das Gebäude zu verlassen.", + Teleport = { x = -113.07, y = -604.93, z = 35.28 }, + }, +} diff --git a/de_esx_jobs.sql b/de_esx_jobs.sql new file mode 100644 index 00000000..6b099cc5 --- /dev/null +++ b/de_esx_jobs.sql @@ -0,0 +1,47 @@ +USE `essentialmode`; + +INSERT INTO `addon_account` (name, label, shared) VALUES + ('caution', 'Caution', 0) +; + +INSERT INTO `jobs` (name, label) VALUES + ('slaughterer', 'Schlachterei'), + ('fisherman', 'Fischerei'), + ('miner', 'Bergbau'), + ('lumberjack', 'Holzbetrieb'), + ('fuel', 'Raffinerie'), + ('reporter', 'Kanal 7'), + ('textil', 'Schneiderei') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('lumberjack', 0, 'interim', 'Mitarbeiter', 0, '{}', '{}'), + ('fisherman', 0, 'interim', 'Mitarbeiter', 0, '{}', '{}'), + ('fuel', 0, 'interim', 'Mitarbeiter', 0, '{}', '{}'), + ('reporter', 0, 'employee', 'Mitarbeiter', 0, '{}', '{}'), + ('textil', 0, 'interim', 'Mitarbeiter', 0, '{}', '{}'), + ('miner', 0, 'interim', 'Mitarbeiter', 0, '{}', '{}'), + ('slaughterer', 0, 'interim', 'Mitarbeiter', 0, '{}', '{}') +; + +INSERT INTO `items` (`name`, `label`) VALUES + ('alive_chicken', 'lebendes Huhn'), + ('slaughtered_chicken', 'geschlachtetes Huhn'), + ('packaged_chicken', 'Hähnchenfilet'), + ('fish', 'Fisch'), + ('stone', 'Felsbrocken'), + ('washed_stone', 'gewaschener Felsbrocken'), + ('copper', 'Kupfer'), + ('iron', 'Eisen'), + ('gold', 'Gold'), + ('diamond', 'Diamant'), + ('wood', 'Holz'), + ('cutted_wood', 'Holzstämme'), + ('packaged_plank', 'Bretterpaket'), + ('petrol', 'Öl'), + ('petrol_raffin', 'bearbeitetes Öl'), + ('essence', 'Benzin'), + ('whool', 'Wolle'), + ('fabric', 'Tuch'), + ('clothe', 'Kleidung') +; \ No newline at end of file From 2055280cc357d35f9a5859099b0d393c236c4a34 Mon Sep 17 00:00:00 2001 From: ultratm Date: Fri, 18 Aug 2017 11:35:02 +0200 Subject: [PATCH 0468/3224] add sql and config --- de_config.lua | 125 +++++++++++++++++++++++++++++++++++++ de_esx_taxijob_full.sql | 17 +++++ de_esx_taxijob_minimal.sql | 13 ++++ 3 files changed, 155 insertions(+) create mode 100644 de_config.lua create mode 100644 de_esx_taxijob_full.sql create mode 100644 de_esx_taxijob_minimal.sql diff --git a/de_config.lua b/de_config.lua new file mode 100644 index 00000000..eb2f05ce --- /dev/null +++ b/de_config.lua @@ -0,0 +1,125 @@ +Config = {} +Config.DrawDistance = 100.0 +Config.NPCJobEarnings = {min = 15, max = 40} +Config.MaxInService = 2 +Config.EnablePlayerManagement = false +Config.Locale = 'de' + +Config.Zones = { + + TaxiActions = { + Pos = {x = 915.039, y = -162.187, z = 73.684}, + Size = {x = 1.5, y = 1.5, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Type = 1 + }, + + VehicleSpawnPoint = { + Pos = {x = 911.108, y = -177.867, z = 74.283}, + Size = {x = 1.5, y = 1.5, z = 1.0}, + Type = -1 + }, + + VehicleDeleter = { + Pos = {x = 908.317, y = -183.070, z = 73.201}, + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Type = 1 + } + +} + +Config.JobLocations = { + {x = 293.476, y = -590.163, z = 42.7371}, + {x = 253.404, y = -375.86, z = 44.0819}, + {x = 120.808, y = -300.416, z = 45.1399}, + {x = -38.4132, y = -381.576, z = 38.3456}, + {x = -107.442, y = -614.377, z = 35.6703}, + {x = -252.292, y = -856.474, z = 30.5626}, + {x = -236.138, y = -988.382, z = 28.7749}, + {x = -276.989, y = -1061.18, z = 25.6853}, + {x = -576.451, y = -998.989, z = 21.785}, + {x = -602.798, y = -952.63, z = 21.6353}, + {x = -790.653, y = -961.855, z = 14.8932}, + {x = -912.588, y = -864.756, z = 15.0057}, + {x = -1069.77, y = -792.513, z = 18.8075}, + {x = -1306.94, y = -854.085, z = 15.0959}, + {x = -1468.51, y = -681.363, z = 26.178}, + {x = -1380.89, y = -452.7, z = 34.0843}, + {x = -1326.35, y = -394.81, z = 36.0632}, + {x = -1383.68, y = -269.985, z = 42.4878}, + {x = -1679.61, y = -457.339, z = 39.4048}, + {x = -1812.45, y = -416.917, z = 43.6734}, + {x = -2043.64, y = -268.291, z = 22.9927}, + {x = -2186.45, y = -421.595, z = 12.6776}, + {x = -1862.08, y = -586.528, z = 11.1747}, + {x = -1859.5, y = -617.563, z = 10.8788}, + {x = -1634.95, y = -988.302, z = 12.6241}, + {x = -1283.99, y = -1154.16, z = 5.30998}, + {x = -1126.47, y = -1338.08, z = 4.63434}, + {x = -867.907, y = -1159.67, z = 5.00795}, + {x = -847.55, y = -1141.38, z = 6.27591}, + {x = -722.625, y = -1144.6, z = 10.2176}, + {x = -575.503, y = -318.446, z = 34.5273}, + {x = -592.309, y = -224.853, z = 36.1209}, + {x = -559.594, y = -162.873, z = 37.7547}, + {x = -534.992, y = -65.6695, z = 40.634}, + {x = -758.234, y = -36.6906, z = 37.2911}, + {x = -1375.88, y = 20.9516, z = 53.2255}, + {x = -1320.25, y = -128.018, z = 48.097}, + {x = -1285.71, y = 294.287, z = 64.4619}, + {x = -1245.67, y = 386.533, z = 75.0908}, + {x = -760.355, y = 285.015, z = 85.0667}, + {x = -626.786, y = 254.146, z = 81.0964}, + {x = -563.609, y = 267.962, z = 82.5116}, + {x = -486.806, y = 271.977, z = 82.8187}, + {x = 88.295, y = 250.867, z = 108.188}, + {x = 234.087, y = 344.678, z = 105.018}, + {x = 434.963, y = 96.707, z = 99.1713}, + {x = 482.617, y = -142.533, z = 58.1936}, + {x = 762.651, y = -786.55, z = 25.8915}, + {x = 809.06, y = -1290.8, z = 25.7946}, + {x = 490.819, y = -1751.37, z = 28.0987}, + {x = 432.351, y = -1856.11, z = 27.0352}, + {x = 164.348, y = -1734.54, z = 28.8982}, + {x = -57.6909, y = -1501.4, z = 31.1084}, + {x = 52.2241, y = -1566.65, z = 29.006}, + {x = 310.222, y = -1376.76, z = 31.4442}, + {x = 181.967, y = -1332.79, z = 28.8773}, + {x = -74.6091, y = -1100.64, z = 25.738}, + {x = -887.045, y = -2187.46, z = 8.13248}, + {x = -749.584, y = -2296.59, z = 12.4627}, + {x = -1064.83, y = -2560.66, z = 19.6811}, + {x = -1033.44, y = -2730.24, z = 19.6868}, + {x = -1018.67, y = -2732, z = 13.2687}, + {x = 797.354, y = -174.423, z = 72.708}, + {x = 508.156, y = -117.908, z = 60.78}, + {x = 159.458, y = -27.555, z = 67.38}, + {x = -36.382, y = -106.912, z = 56.982}, + {x = -355.801, y = -270.404, z = 33.011}, + {x = -831.196, y = -76.871, z = 37.323}, + {x = -1038.707, y = -214.593, z = 37}, + {x = 1918.448, y = 3691.41, z = 32.261}, + {x = 1820.217, y = 3697.115, z = 33.493}, + {x = 1619.323, y = 3827.162, z = 34.482}, + {x = 1418.628, y = 3602.243, z = 34.511}, + {x = 1944.858, y = 3856.252, z = 31.741}, + {x = 2285.278, y = 3839.444, z = 34.023}, + {x = 2760.945, y = 3387.813, z = 55.659}, + {x = 1952.819, y = 2627.731, z = 45.368}, + {x = 1051.414, y = 474.833, z = 93.653}, + {x = 866.393, y = 17.635, z = 78.654}, + {x = 318.985, y = 167.41, z = 103.335}, + {x = 88.836, y = 254.054, z = 108.236}, + {x = -44.852, y = 70.414, z = 72.437}, + {x = -115.496, y = 84.333, z = 70.792}, + {x = -384.806, y = 226.868, z = 83.548}, + {x = -578.669, y = 139.085, z = 61.337}, + {x = -651.334, y = -584.879, z = 34.116}, + {x = -571.847, y = -1195.648, z = 17.869}, + {x = -1513.271, y = -670.039, z = 28.362}, + {x = -1297.484, y = -654.913, z = 26.123}, + {x = -1645.546, y = 144.571, z = 61.664}, + {x = -1160.618, y = 744.418, z = 154.571}, + {x = -798.09, y = 831.699, z = 204.351}, +} diff --git a/de_esx_taxijob_full.sql b/de_esx_taxijob_full.sql new file mode 100644 index 00000000..4c4d9be6 --- /dev/null +++ b/de_esx_taxijob_full.sql @@ -0,0 +1,17 @@ +USE `essentialmode`; + +INSERT INTO `addon_account` (name, label, shared) VALUES + ('society_taxi','Taxi',1) +; + +INSERT INTO `jobs` (name, label) VALUES + ('taxi','Taxi') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('taxi',0,'recrue','Rekrut',12,'{}','{}'), + ('taxi',1,'novice','Anfänger',24,'{}','{}'), + ('taxi',2,'experimente','Experte',36,'{}','{}'), + ('taxi',3,'uber','Schichtführer',48,'{}','{}'), + ('taxi',4,'boss','Chef',0,'{}','{}') +; diff --git a/de_esx_taxijob_minimal.sql b/de_esx_taxijob_minimal.sql new file mode 100644 index 00000000..c625becc --- /dev/null +++ b/de_esx_taxijob_minimal.sql @@ -0,0 +1,13 @@ +USE `essentialmode`; + +INSERT INTO `jobs` (name, label) VALUES + ('taxi','Taxi') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('taxi',0,'recrue','Rekrut',12,'{}','{}'), + ('taxi',1,'novice','Anfänger',24,'{}','{}'), + ('taxi',2,'experimente','Experte',36,'{}','{}'), + ('taxi',3,'uber','Schichtführer',48,'{}','{}'), + ('taxi',4,'boss','Chef',0,'{}','{}') +; From 47af486268144fad19e277d8f5c71b3070176a8b Mon Sep 17 00:00:00 2001 From: Don Date: Sat, 19 Aug 2017 01:55:21 -0700 Subject: [PATCH 0469/3224] Multi-language support Currently only esx_jobs and lumberjack have been translated. --- __resource.lua | 9 +++++++- client/esx_jobs_cl.lua | 38 ++++++++++++++++---------------- config.lua | 5 +++-- jobs/lumberjack.lua | 50 +++++++++++++++++++++--------------------- locales/en.lua | 39 ++++++++++++++++++++++++++++++++ locales/fr.lua | 39 ++++++++++++++++++++++++++++++++ server/esx_jobs_sv.lua | 16 +++++++------- 7 files changed, 141 insertions(+), 55 deletions(-) create mode 100644 locales/en.lua create mode 100644 locales/fr.lua diff --git a/__resource.lua b/__resource.lua index a13546f2..f60e45be 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,9 +1,16 @@ server_scripts { '@mysql-async/lib/MySQL.lua', + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', + 'config.lua', 'server/esx_jobs_sv.lua' } client_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', 'config.lua', 'jobs/fisherman.lua', 'jobs/fuel.lua', @@ -26,4 +33,4 @@ files { 'html/scripts/app.js', 'html/img/keys/enter.png', 'html/img/keys/return.png' -} \ No newline at end of file +} diff --git a/client/esx_jobs_cl.lua b/client/esx_jobs_cl.lua index 0f787a9c..45129934 100644 --- a/client/esx_jobs_cl.lua +++ b/client/esx_jobs_cl.lua @@ -1,10 +1,10 @@ local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 @@ -68,17 +68,17 @@ end) AddEventHandler('esx_jobs:action', function(job, zone) menuIsShowed = true - if zone.Type == "cloakroom" then + if zone.Type == "cloakroom" then SendNUIMessage({ showMenu = true, menu = 'cloakroom' - }) + }) elseif zone.Type == "work" then hintToDisplay = "no hint to display" hintIsShowed = false local playerPed = GetPlayerPed(-1) if IsPedInAnyVehicle(playerPed, 0) then - TriggerEvent('esx:showNotification', 'Vous devez être à pied pour pouvoir travailler.') + TriggerEvent('esx:showNotification', _U('foot_work')) else TriggerServerEvent('esx_jobs:startWork', zone.Item) end @@ -187,7 +187,7 @@ function nextStep(gps) end Blips['delivery'] = AddBlipForCoord(gps.x, gps.y, gps.z) SetBlipRoute(Blips['delivery'], true) - TriggerEvent('esx:showNotification', 'Rendez-vous à la prochaine étape après avoir complété celle-ci.') + TriggerEvent('esx:showNotification', _U('next_point')) end end @@ -319,7 +319,7 @@ AddEventHandler('esx_jobs:spawnJobVehicle', function(spawnPoint, vehicle) table.insert(myPlate, plate) plate = string.gsub(plate, " ", "") TriggerEvent('esx_vehiclelock:updatePlayerCars', "add", plate) - SetVehRadioStation(veh, "OFF") + SetVehRadioStation(veh, "OFF") TaskWarpPedIntoVehicle(playerPed, veh, -1) isJobVehicleDestroyed = false @@ -360,10 +360,10 @@ Citizen.CreateThread(function() local coords = GetEntityCoords(GetPlayerPed(-1)) for k,v in pairs(zones) do if onDuty or v.Type == "cloakroom" or PlayerData.job.name == "reporter" then - if(v.Marker ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then + if(v.Marker ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then DrawMarker(v.Marker, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) end - end + end end end end @@ -375,16 +375,16 @@ Citizen.CreateThread(function() Wait(0) local coords = GetEntityCoords(GetPlayerPed(-1)) for k,v in pairs(Config.PublicZones) do - if(v.Marker ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then + if(v.Marker ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then DrawMarker(v.Marker, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) - end + end end end end) -- Activate public marker Citizen.CreateThread(function() - while true do + while true do Wait(0) local coords = GetEntityCoords(GetPlayerPed(-1)) local position = nil @@ -420,7 +420,7 @@ end) -- Activate menu when player is inside marker Citizen.CreateThread(function() - while true do + while true do Wait(0) if PlayerData.job ~= nil and PlayerData.job.name ~= 'unemployed' then @@ -473,20 +473,20 @@ Citizen.CreateThread(function() for i=1, #myPlate, 1 do Citizen.Trace(myPlate[i]) if (myPlate[i] == plate) and (playerPed == driverPed) then - hintToDisplay = zone.Hint .. "\n" .. "La caution rendue sera de ~g~" .. cautionVehicleInCaseofDrop .. "$~s~." + hintToDisplay = zone.Hint .. "\n" .. _U('security_deposit') .. cautionVehicleInCaseofDrop .. "~s~." isVehicleOwner = true break end end if not isVehicleOwner then - hintToDisplay = "Ce n'est pas votre véhicule ou vous devez être conducteur." + hintToDisplay = _U('not_your_vehicle') end else - hintToDisplay = "Vous devez être dans un véhicule." + hintToDisplay = _U('in_vehicle') end hintIsShowed = true elseif onDuty and zone.Spawner ~= spawner then - hintToDisplay = "Vous n'êtes pas au bon point de livraison." + hintToDisplay = _U('wrong_point') hintIsShowed = true else if not isInPublicMarker then @@ -558,4 +558,4 @@ Citizen.CreateThread(function() SendNUIMessage({ move = 'DOWN' }) end end -end) \ No newline at end of file +end) diff --git a/config.lua b/config.lua index fe37a95a..89682111 100644 --- a/config.lua +++ b/config.lua @@ -1,5 +1,6 @@ Config = {} Config.DrawDistance = 1000.0 +Config.Locale = 'fr' Config.Plates = { taxi = "TAXI", @@ -17,7 +18,7 @@ Config.Plates = { Config.Jobs = {} -Config.PublicZones = { +Config.PublicZones = { EnterBuilding = { Pos = { x = -118.21381378174, y = -607.14227294922, z = 35.280723571777 }, Size = {x = 3.0, y = 3.0, z = 0.2}, @@ -41,4 +42,4 @@ Config.PublicZones = { Hint = "Appuyez sur ~INPUT_PICKUP~ pour aller à l'entrée de l'immeuble.", Teleport = { x = -113.07, y = -604.93, z = 35.28 }, }, -} \ No newline at end of file +} diff --git a/jobs/lumberjack.lua b/jobs/lumberjack.lua index 07a0f96d..4ecaead1 100644 --- a/jobs/lumberjack.lua +++ b/jobs/lumberjack.lua @@ -18,9 +18,9 @@ Config.Jobs.lumberjack = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = "Vestiaire", + Name = _U('lj_cr_title'), Type = "cloakroom", - Hint = "Appuyez sur ~INPUT_PICKUP~ pour vous changer." + Hint = _U('lj_cloakroom') }, Wood = { @@ -29,11 +29,11 @@ Config.Jobs.lumberjack = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = "Tas de bois", + Name = _U('lj_mapblip'), Type = "work", Item = { { - name = "Bois", + name = _U('lj_wood'), db_name= "wood", time = 3000, max = 20, @@ -44,7 +44,7 @@ Config.Jobs.lumberjack = { drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour récupérer du bois." + Hint = _U('lj_pickup') }, CuttedWood = { @@ -53,22 +53,22 @@ Config.Jobs.lumberjack = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = false, - Name = "Découpe du bois", + Name = _U('lj_cutwood'), Type = "work", Item = { { - name = "Bois coupé", + name = _U('lj_cutwood'), db_name= "cutted_wood", time = 5000, max = 20, add = 1, remove = 1, requires = "wood", - requires_name = "Bois", + requires_name = _U('lj_wood'), drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour couper du bois." + Hint = _U('lj_cutwood_button') }, Planks = { @@ -77,22 +77,22 @@ Config.Jobs.lumberjack = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = false, - Name = "Planches", + Name = _U('lj_board'), Type = "work", Item = { { - name = "Paquet de planche", + name = _U('lj_planks'), db_name= "packaged_plank", time = 4000, max = 100, add = 5, remove = 1, requires = "cutted_wood", - requires_name = "Bois coupé", + requires_name = _U('lj_cutwood'), drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour récupérer des planches." + Hint = _U('lj_pick_boards') }, VehicleSpawner = { @@ -101,10 +101,10 @@ Config.Jobs.lumberjack = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = false, - Name = "Spawner véhicule de fonction", + Name = _U('lj_spawn_veh'), Type = "vehspawner", Spawner = 1, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour appeler le véhicule de livraison.", + Hint = _U('lj_spawn_veh_button'), Caution = 2000 }, @@ -113,21 +113,21 @@ Config.Jobs.lumberjack = { Size = {x = 3.0, y = 3.0, z = 1.0}, Marker= -1, Blip = false, - Name = "Véhicule de fonction", + Name = _U('lj_service_vh'), Type = "vehspawnpt", Spawner = 1, Heading = 285.1 }, - + VehicleDeletePoint = { Pos = {x = 1216.8983154297, y = -1229.2396240234, z = 34.403507232666}, Size = {x = 5.0, y = 5.0, z = 1.0}, Color = {r = 255, g = 0, b = 0}, Marker= 1, Blip = false, - Name = "Supression du véhicule", + Name = _U('lj_return_vh'), Type = "vehdelete", - Hint = "Appuyez sur ~INPUT_PICKUP~ pour rendre le véhicule.", + Hint = _U('lj_return_vh_button'), Spawner = 1, Caution = 2000, GPS = 0, @@ -140,22 +140,22 @@ Config.Jobs.lumberjack = { Size = {x = 5.0, y = 5.0, z = 3.0}, Marker= 1, Blip = true, - Name = "Point de livraison", - Type = "delivery", + Name = _U('lj_delivery_point'), + Type = "delivery", Spawner = 1, Item = { { - name = "Livraison", + name = _U('lj_delivery'), time = 500, remove = 1, max = 100, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 13, requires = "packaged_plank", - requires_name = "Paquet de planche", + requires_name = _U('lj_planks'), drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour livrer les planches." + Hint = _U('lj_deliver_button') } } -} \ No newline at end of file +} diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..04403eb9 --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,39 @@ +Locales['en'] = { + --Global menus + ['bank_deposit'] = 'a security deposit of ~g~', + ['bank_deposit_r'] = 'a security deposit of ~g~$', + ['bank_deposit2'] = '$ ~s~was made to you after your fainting.', + ['bank_nodeposit'] = "you did not have a surety", + ['foot_work'] = 'you have to be on foot to be able to work.', + ['next_point'] = 'go to the next step after completing this one.', + ['security_deposit'] = 'the security given will be ~g~$', + ['not_your_vehicle'] = "this is not your vehicle or you must be a driver.", + ['in_vehicle'] = 'you must be in a vehicle.', + ['wrong_point'] = "you are not at the right point of delivery.", + ['max_limit'] = 'you have the maximum: ', + ['not_enough'] = "you do not have enough", + ['not_enough2'] = ' to continue this task.', + ['caution_taken'] = ' ~s~was taken from you.', + ['caution_returned'] = ' ~s~was returned to you.', + + --Lumber Jack job + ['lj_cr_title'] = 'cloakroom', + ['lj_cloakroom'] = 'press ~INPUT_PICKUP~ to change clothes.', + ['lj_mapblip'] = 'wood pile', + ['lj_wood'] = 'wood', + ['lj_pickup'] = 'press ~INPUT_PICKUP~ to retrieve wood.', + ['lj_cutwood'] = 'cutting wood', + ['lj_cutwood_button'] = 'press ~INPUT_PICKUP~ to cut wood.', + ['lj_board'] = 'boards', + ['lj_planks'] = 'board package', + ['lj_delivery'] = 'delivery', + ['lj_cutwood'] = 'wood cut', + ['lj_pick_boards'] = 'press ~INPUT_PICKUP~ to retrieve boards.', + ['lj_spawn_veh'] = 'spawn vehicle', + ['lj_spawn_veh_button'] = 'press ~INPUT_PICKUP~ to call the delivery vehicle.', + ['lj_service_vh'] = 'service vehicle', + ['lj_return_vh'] = 'return vehicle', + ['lj_delivery_point'] = 'delivery point', + ['lj_return_vh_button'] = 'press ~INPUT_PICKUP~ to return the vehicle.', + ['lj_deliver_button'] = 'press ~INPUT_PICKUP~ to deliver the boards.' +} diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..3bbe4dcb --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,39 @@ +Locales['fr'] = { + --Global menus + ['bank_deposit'] = 'une caution de ~g~', + ['bank_deposit_r'] = 'une caution de ~g~$', + ['bank_deposit2'] = '$ ~s~vous a été rendue suite à votre évanouissment.', + ['bank_nodeposit'] = "vous n'aviez pas de caution", + ['foot_work'] = 'vous devez être à pied pour pouvoir travailler.', + ['next_point'] = 'rendez-vous à la prochaine étape après avoir complété celle-ci.', + ['security_deposit'] = 'la caution rendue sera de ~g~$', + ['not_your_vehicle'] = "ce n'est pas votre véhicule ou vous devez être conducteur.", + ['in_vehicle'] = 'vous devez être dans un véhicule.', + ['wrong_point'] = "vous n'êtes pas au bon point de livraison.", + ['max_limit'] = 'vous avez le maximum de: ', + ['not_enough'] = "vous n'avez plus assez de", + ['not_enough2'] = ' pour continuer cette tâche.', + ['caution_taken'] = ' ~s~vous a été prélevée.', + ['caution_returned'] = ' ~s~vous a été rendue.', + + --Lumber Jack job + ['lj_cr_title'] = 'vestiaire', + ['lj_cloakroom'] = 'appuyez sur ~INPUT_PICKUP~ pour vous changer.', + ['lj_mapblip'] = 'tas de bois', + ['lj_wood'] = 'bois', + ['lj_pickup'] = 'appuyez sur ~INPUT_PICKUP~ pour récupérer du bois.', + ['lj_cutwood'] = 'découpe du bois', + ['lj_cutwood_button'] = 'appuyez sur ~INPUT_PICKUP~ pour couper du bois.', + ['lj_board'] = 'planches', + ['lj_planks'] = 'paquet de planche', + ['lj_delivery'] = 'livraison', + ['lj_cutwood'] = 'bois coupé', + ['lj_pick_boards'] = 'appuyez sur ~INPUT_PICKUP~ pour récupérer des planches.', + ['lj_spawn_veh'] = 'spawner véhicule de fonction', + ['lj_spawn_veh_button'] = 'appuyez sur ~INPUT_PICKUP~ pour appeler le véhicule de livraison.', + ['lj_service_vh'] = 'véhicule de fonction', + ['lj_return_vh'] = 'supression du véhicule', + ['lj_delivery_point'] = 'Point de livraison', + ['lj_return_vh_button'] = 'appuyez sur ~INPUT_PICKUP~ pour rendre le véhicule.', + ['lj_deliver_button'] = 'appuyez sur ~INPUT_PICKUP~ pour livrer les planches.' +} diff --git a/server/esx_jobs_sv.lua b/server/esx_jobs_sv.lua index 2cec943a..f47c4a56 100644 --- a/server/esx_jobs_sv.lua +++ b/server/esx_jobs_sv.lua @@ -38,9 +38,9 @@ AddEventHandler('esx_jobs:giveBackCautionInCaseOfDrop', function() if caution > 0 then xPlayer.addAccountMoney('bank', value) - TriggerClientEvent('esx:showNotification', _source, 'Une caution de ~g~'.. value .. '$ ~s~vous a été rendue suite à votre évanouissment.') + TriggerClientEvent('esx:showNotification', _source, _U('bank_deposit_g').. value .. _U('bank_deposit2')) else - TriggerClientEvent('esx:showNotification', _source, "Vous n'aviez pas de caution") + TriggerClientEvent('esx:showNotification', _source, _U('bank_nodeposit')) end end) @@ -53,7 +53,7 @@ local function Work(source, item) for i=1, #item, 1 do local itemQtty = 0 - if item[i].name ~= "Livraison" then + if item[i].name ~= _U('lj_delivery') then itemQtty = xPlayer.getInventoryItem(item[i].db_name).count end @@ -62,10 +62,10 @@ local function Work(source, item) requiredItemQtty = xPlayer.getInventoryItem(item[1].requires).count end - if item[i].name ~= "Livraison" and itemQtty >= item[i].max then - TriggerClientEvent('esx:showNotification', source, 'Vous avez le maximum de: ' .. item[i].name) + if item[i].name ~= _U('lj_delivery') and itemQtty >= item[i].max then + TriggerClientEvent('esx:showNotification', source, _U('max_limit') .. item[i].name) elseif item[i].requires ~= "nothing" and requiredItemQtty <= 0 then - TriggerClientEvent('esx:showNotification', source, "Vous n'avez plus assez de " .. item[1].requires_name .. " pour continuer cette tâche.") + TriggerClientEvent('esx:showNotification', source, _U('not_enough') .. item[1].requires_name .. _U('not_enough2')) else if item[i].name ~= "Livraison" then -- Chances to drop the item @@ -116,11 +116,11 @@ AddEventHandler('esx_jobs:caution', function(cautionType, cautionAmount, spawnPo if cautionType == "take" then xPlayer.removeAccountMoney('bank', cautionAmount) xPlayer.set('caution', cautionAmount) - TriggerClientEvent('esx:showNotification', source, 'Une caution de ~r~'.. cautionAmount .. '$ ~s~vous a été prélevée.') + TriggerClientEvent('esx:showNotification', source, _U('bank_deposit_r') .. cautionAmount .. _U('caution_taken')) TriggerClientEvent('esx_jobs:spawnJobVehicle', source, spawnPoint, vehicle) elseif cautionType == "give_back" then xPlayer.addAccountMoney('bank', cautionAmount) xPlayer.set('caution', 0) - TriggerClientEvent('esx:showNotification', source, 'Une caution de ~g~'.. cautionAmount .. '$ ~s~vous a été rendue.') + TriggerClientEvent('esx:showNotification', source, _U('bank_deposit_g') .. cautionAmount .. _U('caution_returned')) end end) From b51b7e213f062faaa9893fa8fd0667494c91e821 Mon Sep 17 00:00:00 2001 From: pixinc Date: Sat, 19 Aug 2017 01:53:07 +1100 Subject: [PATCH 0470/3224] Miner Outfit --- esx_jobs.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esx_jobs.sql b/esx_jobs.sql index 511ffd9d..fb356df6 100644 --- a/esx_jobs.sql +++ b/esx_jobs.sql @@ -20,7 +20,7 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ('fuel', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), ('reporter', 0, 'employee', 'Intérimaire', 0, '{}', '{}'), ('textil', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), - ('miner', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), + ('miner', 0, 'interim', 'Intérimaire', 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}', '{}'), ('slaughterer', 0, 'interim', 'Intérimaire', 0, '{}', '{}') ; @@ -44,4 +44,4 @@ INSERT INTO `items` (`name`, `label`) VALUES ('whool', 'Laine'), ('fabric', 'Tissu'), ('clothe', 'Vêtement') -; \ No newline at end of file +; From 2bb542cba22b427db1f86c93942f7abe4a44dd3c Mon Sep 17 00:00:00 2001 From: Allan <31086346+TakumiBR@users.noreply.github.com> Date: Fri, 18 Aug 2017 12:07:23 -0700 Subject: [PATCH 0471/3224] Multi-language support Brazilian Portuguese translation. [ATTENTION] The ui_br.html file that is in the html folder must be renamed to ui.html to run the translation. --- __resource.lua | 2 ++ html/ui_br.html | 82 +++++++++++++++++++++++++++++++++++++++++++++++++ locales/br.lua | 13 ++++++++ 3 files changed, 97 insertions(+) create mode 100644 html/ui_br.html create mode 100644 locales/br.lua diff --git a/__resource.lua b/__resource.lua index b01f9752..1283b1cc 100644 --- a/__resource.lua +++ b/__resource.lua @@ -5,6 +5,7 @@ description 'ESX Phone' server_scripts { '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'server/main.lua' @@ -12,6 +13,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'client/main.lua' diff --git a/html/ui_br.html b/html/ui_br.html new file mode 100644 index 00000000..9a28cd97 --- /dev/null +++ b/html/ui_br.html @@ -0,0 +1,82 @@ + + + + + + + + +
+ +
+ +
+ + #123456 +
+ + + +
+ +
Agenda
+
+
+
+

Nenhum contato

+
+
+
+
+ +
+
Mensagens
+
+
+
+

Nenhuma mensagem

+
+
+
+
+ +
+
+
+
+ + + + + +
+
+
+ +
+
Adicionar contato
+
+
+ + + + +
+
+
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/locales/br.lua b/locales/br.lua new file mode 100644 index 00000000..3017ac44 --- /dev/null +++ b/locales/br.lua @@ -0,0 +1,13 @@ +Locales['br'] = { + + ['new_message'] = '~b~Nova mensagem', + ['press_take_call'] = ' - Pressione ~INPUT_CONTEXT~ para aceitar a chamada', + ['taken_call'] = ' recebeu uma chamada', + ['gps_position'] = 'Destino inserido no GPS', + ['message_sent'] = 'mensagem enviada', + ['cannot_add_self'] = 'Você não pode se adicionar', + ['number_in_contacts'] = 'Este número já está na sua lista de contatos', + ['contact_added'] = 'Contato adicionado', + ['number_not_assigned'] = 'Este número não foi atribuído...', + +} From 3d889be1a3d7afc376ea7ce414e68d216351f4bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 19 Aug 2017 00:28:56 +0200 Subject: [PATCH 0472/3224] Fix spawn local vehicle --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 883501a0..0ef4b841 100644 --- a/client/main.lua +++ b/client/main.lua @@ -431,7 +431,7 @@ function OpenPersonnalVehicleMenu() menu.close() - ESX.Game.SpawnLocalVehicle(vehicleData.model, { + ESX.Game.SpawnVehicle(vehicleData.model, { x = coords.x, y = coords.y, z = coords.z From 71c8a2c526f027a3c7dfe450c12566a99ba31274 Mon Sep 17 00:00:00 2001 From: renaiku Date: Sat, 19 Aug 2017 01:13:33 +0200 Subject: [PATCH 0473/3224] Add a menu to ask the player if he wants to be respawned at the hospital. --- client/main.lua | 58 +++++++++++++++++++++++++++++++++++++++++++++++++ config.lua | 1 + locales/fr.lua | 2 ++ 3 files changed, 61 insertions(+) diff --git a/client/main.lua b/client/main.lua index 418ea4b3..82f8a623 100644 --- a/client/main.lua +++ b/client/main.lua @@ -37,6 +37,63 @@ function RespawnPed(ped, coords) SetPlayerInvincible(ped, false) TriggerEvent('playerSpawned', coords.x, coords.y, coords.z, coords.heading) ClearPedBloodDamage(ped) + ESX.UI.Menu.CloseAll() +end + +function StartRespawnToHospitalMenuTimer() + Citizen.Trace('starting timer') + ESX.SetTimeout(Config.MenuRespawnToHospitalDelay, function() + + Citizen.Trace('menu should appear') + + if IsDead then + + local elements = {} + + table.insert(elements, {label = 'OUI', value = 'yes'}) + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'menuName', + { + title = _U('respawn_at_hospital'), + align = 'top-left', + elements = elements + }, + function(data, menu) --Submit Cb + menu.close() + + Citizen.CreateThread(function() + + DoScreenFadeOut(800) + + while not IsScreenFadedOut() do + Citizen.Wait(0) + end + + ESX.TriggerServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function() + + TriggerServerEvent('esx:updateLastPosition', Config.Zones.HospitalInteriorInside1.Pos) + + RespawnPed(GetPlayerPed(-1), Config.Zones.HospitalInteriorInside1.Pos) + StopScreenEffect('DeathFailOut') + DoScreenFadeIn(800) + end) + + end) + end, + function(data, menu) --Cancel Cb + --menu.close() + end, + function(data, menu) --Change Cb + --print(data.current.value) + end + ) + + + end + + end) + end function StartRespawnTimer() @@ -475,6 +532,7 @@ AddEventHandler('esx_ambulancejob:onPlayerDeath', function() IsDead = true StartRespawnTimer() + StartRespawnToHospitalMenuTimer() StartScreenEffect('DeathFailOut', 0, false) end) diff --git a/config.lua b/config.lua index 209fef42..8e1b8a90 100644 --- a/config.lua +++ b/config.lua @@ -2,6 +2,7 @@ Config = {} Config.DrawDistance = 100.0 Config.MarkerColor = {r = 102, g = 0, b = 102} Config.RespawnDelayAfterRPDeath = 10 * 60 * 1000 +Config.MenuRespawnToHospitalDelay= 1 * 60 * 1000 Config.RemoveWeaponsAfterRPDeath = true Config.RemoveCashAfterRPDeath = true Config.RemoveItemsAfterRPDeath = true diff --git a/locales/fr.lua b/locales/fr.lua index dc9819e1..44cf4e5c 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -32,4 +32,6 @@ Locales['fr'] = { ['ems_menu_putincar'] = 'mettre dans véhicule', -- Phone ['alert_ambulance'] = 'alerte Ambulance', + -- Death + ['respawn_at_hospital'] = 'voulez-vous être transporté à l\'hôpital ?', } \ No newline at end of file From 4a723faf853bded359f2bdc73e6d6362cfda62fa Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Fri, 18 Aug 2017 19:27:05 -0400 Subject: [PATCH 0474/3224] Update multi-language support --- client/main.lua | 82 ++++++++++++++++++++++++------------------------- locales/en.lua | 5 ++- locales/fr.lua | 3 +- 3 files changed, 47 insertions(+), 43 deletions(-) diff --git a/client/main.lua b/client/main.lua index 82f8a623..cc574eb7 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,12 +1,12 @@ DoScreenFadeIn(0) local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 @@ -33,8 +33,8 @@ end) function RespawnPed(ped, coords) SetEntityCoordsNoOffset(ped, coords.x, coords.y, coords.z, false, false, false, true) - NetworkResurrectLocalPlayer(coords.x, coords.y, coords.z, coords.heading, true, false) - SetPlayerInvincible(ped, false) + NetworkResurrectLocalPlayer(coords.x, coords.y, coords.z, coords.heading, true, false) + SetPlayerInvincible(ped, false) TriggerEvent('playerSpawned', coords.x, coords.y, coords.z, coords.heading) ClearPedBloodDamage(ped) ESX.UI.Menu.CloseAll() @@ -45,12 +45,12 @@ function StartRespawnToHospitalMenuTimer() ESX.SetTimeout(Config.MenuRespawnToHospitalDelay, function() Citizen.Trace('menu should appear') - + if IsDead then local elements = {} - table.insert(elements, {label = 'OUI', value = 'yes'}) + table.insert(elements, {label = _U('yes'), value = 'yes'}) ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'menuName', @@ -63,13 +63,13 @@ function StartRespawnToHospitalMenuTimer() menu.close() Citizen.CreateThread(function() - + DoScreenFadeOut(800) - + while not IsScreenFadedOut() do Citizen.Wait(0) end - + ESX.TriggerServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function() TriggerServerEvent('esx:updateLastPosition', Config.Zones.HospitalInteriorInside1.Pos) @@ -88,8 +88,8 @@ function StartRespawnToHospitalMenuTimer() --print(data.current.value) end ) - - + + end end) @@ -99,17 +99,17 @@ end function StartRespawnTimer() ESX.SetTimeout(Config.RespawnDelayAfterRPDeath, function() - + if IsDead then - + Citizen.CreateThread(function() - + DoScreenFadeOut(800) - + while not IsScreenFadedOut() do Citizen.Wait(0) end - + ESX.TriggerServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function() TriggerServerEvent('esx:updateLastPosition', Config.Zones.HospitalInteriorInside1.Pos) @@ -129,9 +129,9 @@ end function TeleportFadeEffect(entity, coords) Citizen.CreateThread(function() - + DoScreenFadeOut(800) - + while not IsScreenFadedOut() do Citizen.Wait(0) end @@ -255,7 +255,7 @@ function OpenAmbulanceActionsMenu() end, function(data, menu) - + menu.close() CurrentAction = 'ambulance_actions_menu' @@ -313,7 +313,7 @@ function OpenMobileAmbulanceActionsMenu() local closestPlayerPed = GetPlayerPed(closestPlayer) Citizen.CreateThread(function() - + ESX.ShowNotification(_U('revive_inprogress')) TaskStartScenarioInPlace(playerPed, 'CODE_HUMAN_MEDIC_TEND_TO_DEAD', 0, true) @@ -334,7 +334,7 @@ function OpenMobileAmbulanceActionsMenu() end end - + end if data.current.value == 'put_in_vehicle' then @@ -371,11 +371,11 @@ function OpenCloakroomMenu() }, }, function(data, menu) - + menu.close() if data.current.value == 'citizen_wear' then - + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) TriggerEvent('skinchanger:loadSkin', skin) end) @@ -391,7 +391,7 @@ function OpenCloakroomMenu() else TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_female) end - + end) end @@ -421,7 +421,7 @@ function OpenVehicleSpawnerMenu() }, }, function(data, menu) - + menu.close() local model = data.current.value @@ -441,7 +441,7 @@ function OpenVehicleSpawnerMenu() end, function(data, menu) - + menu.close() CurrentAction = 'vehicle_spawner_menu' @@ -544,13 +544,13 @@ AddEventHandler('esx_ambulancejob:revive', function() local coords = GetEntityCoords(playerPed) Citizen.CreateThread(function() - + DoScreenFadeOut(800) - + while not IsScreenFadedOut() do Citizen.Wait(0) end - + TriggerServerEvent('esx:updateLastPosition', { x = coords.x, y = coords.y, @@ -602,7 +602,7 @@ AddEventHandler('esx_ambulancejob:hasEnteredMarker', function(zone) end if zone == 'VehicleDeleter' and PlayerData.job ~= nil and PlayerData.job.name == 'ambulance' then - + local playerPed = GetPlayerPed(-1) local coords = GetEntityCoords(playerPed) @@ -637,12 +637,12 @@ end) Citizen.CreateThread(function() local blip = AddBlipForCoord(Config.Zones.HospitalInteriorOutside1.Pos.x, Config.Zones.HospitalInteriorOutside1.Pos.y, Config.Zones.HospitalInteriorOutside1.Pos.z) - + SetBlipSprite (blip, 61) SetBlipDisplay(blip, 4) SetBlipScale (blip, 1.2) SetBlipAsShortRange(blip, true) - + BeginTextCommandSetBlipName("STRING") AddTextComponentString(_U('hospital')) EndTextCommandSetBlipName(blip) @@ -652,11 +652,11 @@ end) -- Display markers Citizen.CreateThread(function() while true do - + Wait(0) - + local coords = GetEntityCoords(GetPlayerPed(-1)) - + for k,v in pairs(Config.Zones) do if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then @@ -670,8 +670,8 @@ end) -- Activate menu when player is inside marker Citizen.CreateThread(function() while true do - - Wait(0) + + Wait(0) local coords = GetEntityCoords(GetPlayerPed(-1)) local isInMarker = false @@ -711,7 +711,7 @@ Citizen.CreateThread(function() DisplayHelpTextFromStringLabel(0, 0, 1, -1) if IsControlPressed(0, Keys['E']) and PlayerData.job ~= nil and PlayerData.job.name == 'ambulance' and (GetGameTimer() - GUI.Time) > 150 then - + if CurrentAction == 'ambulance_actions_menu' then OpenAmbulanceActionsMenu() end @@ -726,7 +726,7 @@ Citizen.CreateThread(function() CurrentAction = nil GUI.Time = GetGameTimer() - + end end @@ -744,4 +744,4 @@ Citizen.CreateThread(function() LoadMpDlcMaps() EnableMpDlcMaps(true) RequestIpl('Coroner_Int_on') -- Morgue -end) \ No newline at end of file +end) diff --git a/locales/en.lua b/locales/en.lua index 80573437..73d76553 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -32,4 +32,7 @@ Locales['en'] = { ['ems_menu_putincar'] = 'put in Vehicle', -- Phone ['alert_ambulance'] = 'alert Ambulance', -} \ No newline at end of file + -- Death + ['respawn_at_hospital'] = 'do you want to be tranported to the hospital?', + ['yes'] = 'yes', +} diff --git a/locales/fr.lua b/locales/fr.lua index 44cf4e5c..c276c069 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -34,4 +34,5 @@ Locales['fr'] = { ['alert_ambulance'] = 'alerte Ambulance', -- Death ['respawn_at_hospital'] = 'voulez-vous être transporté à l\'hôpital ?', -} \ No newline at end of file + ['yes'] = 'oui', +} From 76f24ff53166fbb9eb978cc22bae9d97def383ee Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Sat, 19 Aug 2017 00:34:50 -0400 Subject: [PATCH 0475/3224] Update multi-language support --- locales/br.lua | 5 ++++- locales/en.lua | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index b90a21b8..a56396c1 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -32,4 +32,7 @@ Locales['br'] = { ['ems_menu_putincar'] = 'Colocar no veículo', -- Phone ['alert_ambulance'] = 'ambulância de alerta', -} \ No newline at end of file + -- Death + ['respawn_at_hospital'] = 'você quer ser transportado para o hospital?', + ['yes'] = 'sim', +} diff --git a/locales/en.lua b/locales/en.lua index 73d76553..fa8ddfce 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -33,6 +33,6 @@ Locales['en'] = { -- Phone ['alert_ambulance'] = 'alert Ambulance', -- Death - ['respawn_at_hospital'] = 'do you want to be tranported to the hospital?', + ['respawn_at_hospital'] = 'do you want to be transported to the hospital?', ['yes'] = 'yes', } From 4e4bc821c8eb221af02bcbaf56f55396ab083a3a Mon Sep 17 00:00:00 2001 From: renaiku Date: Sat, 19 Aug 2017 08:19:06 +0200 Subject: [PATCH 0476/3224] update GetVehicleProperties and SetVehicleProperties --- .../es_extended/client/functions.lua | 118 +++++++++++++++++- 1 file changed, 117 insertions(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index f9d3b60f..792495f0 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -634,7 +634,31 @@ ESX.Game.GetVehicleProperties = function(vehicle) modXenon = IsToggleModOn(vehicle, 22), modFrontWheels = GetVehicleMod(vehicle, 23), - modBackWheels = GetVehicleMod(vehicle, 24) + modBackWheels = GetVehicleMod(vehicle, 24), + + modPlateHolder = GetVehicleMod(vehicle, 25), + modVanityPlate = GetVehicleMod(vehicle, 26), + modTrimA = GetVehicleMod(vehicle, 27), + modOrnaments = GetVehicleMod(vehicle, 28), + modDashboard = GetVehicleMod(vehicle, 29), + modDial = GetVehicleMod(vehicle, 30), + modDoorSpeaker = GetVehicleMod(vehicle, 31), + modSeats = GetVehicleMod(vehicle, 32), + modSteeringWheel = GetVehicleMod(vehicle, 33), + modShifterLeavers = GetVehicleMod(vehicle, 34), + modAPlate = GetVehicleMod(vehicle, 35), + modSpeakers = GetVehicleMod(vehicle, 36), + modTrunk = GetVehicleMod(vehicle, 37), + modHydrolic = GetVehicleMod(vehicle, 38), + modEngineBlock = GetVehicleMod(vehicle, 39), + modAirFilter = GetVehicleMod(vehicle, 40), + modStruts = GetVehicleMod(vehicle, 41), + modArchCover = GetVehicleMod(vehicle, 42), + modAerials = GetVehicleMod(vehicle, 43), + modTrimB = GetVehicleMod(vehicle, 44), + modTank = GetVehicleMod(vehicle, 45), + modWindows = GetVehicleMod(vehicle, 46), + modLivery = GetVehicleMod(vehicle, 48) } end @@ -790,6 +814,98 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) SetVehicleMod(vehicle, 24, props.modBackWheels, false) end + if props.modPlateHolder ~= nil then + SetVehicleMod(vehicle, 25, props.modPlateHolder , false) + end + + if props.modVanityPlate ~= nil then + SetVehicleMod(vehicle, 26, props.modVanityPlate , false) + end + + if props.modTrimA ~= nil then + SetVehicleMod(vehicle, 27, props.modTrimA , false) + end + + if props.modOrnaments ~= nil then + SetVehicleMod(vehicle, 28, props.modOrnaments , false) + end + + if props.modDashboard ~= nil then + SetVehicleMod(vehicle, 29, props.modDashboard , false) + end + + if props.modDial ~= nil then + SetVehicleMod(vehicle, 30, props.modDial , false) + end + + if props.modDoorSpeaker ~= nil then + SetVehicleMod(vehicle, 31, props.modDoorSpeaker , false) + end + + if props.modSeats ~= nil then + SetVehicleMod(vehicle, 32, props.modSeats , false) + end + + if props.modSteeringWheel ~= nil then + SetVehicleMod(vehicle, 33, props.modSteeringWheel , false) + end + + if props.modShifterLeavers ~= nil then + SetVehicleMod(vehicle, 34, props.modShifterLeavers , false) + end + + if props.modAPlate ~= nil then + SetVehicleMod(vehicle, 35, props.modAPlate , false) + end + + if props.modSpeakers ~= nil then + SetVehicleMod(vehicle, 36, props.modSpeakers , false) + end + + if props.modTrunk ~= nil then + SetVehicleMod(vehicle, 37, props.modTrunk , false) + end + + if props.modHydrolic ~= nil then + SetVehicleMod(vehicle, 38, props.modHydrolic , false) + end + + if props.modEngineBlock ~= nil then + SetVehicleMod(vehicle, 39, props.modEngineBlock , false) + end + + if props.modAirFilter ~= nil then + SetVehicleMod(vehicle, 40, props.modAirFilter , false) + end + + if props.modStruts ~= nil then + SetVehicleMod(vehicle, 41, props.modStruts , false) + end + + if props.modArchCover ~= nil then + SetVehicleMod(vehicle, 42, props.modArchCover , false) + end + + if props.modAerials ~= nil then + SetVehicleMod(vehicle, 43, props.modAerials , false) + end + + if props.modTrimB ~= nil then + SetVehicleMod(vehicle, 44, props.modTrimB , false) + end + + if props.modTank ~= nil then + SetVehicleMod(vehicle, 45, props.modTank , false) + end + + if props.modWindows ~= nil then + SetVehicleMod(vehicle, 46, props.modWindows , false) + end + + if props.modLivery ~= nil then + SetVehicleMod(vehicle, 48, props.modLivery , false) + end + end ESX.Game.TeleportEntity = function(entity, coords, cb) From 3f1438a12e533aaf37d83dcfd2de458f8ba1fc44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 19 Aug 2017 09:38:40 +0200 Subject: [PATCH 0477/3224] Fix outfit gone where dead --- client/main.lua | 63 +++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/client/main.lua b/client/main.lua index f3860f18..f6e1e557 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,12 +1,12 @@ ESX = nil -local HasLoadedModel = false +local FirstSpawn = true local LastSkin = nil local PlayerLoaded = false -local cam = nil +local cam = nil local isCameraActive = false -local zoomOffset = 0.0 -local camOffset = 0.0 -local heading = 90.0 +local zoomOffset = 0.0 +local camOffset = 0.0 +local heading = 90.0 Citizen.CreateThread(function() while ESX == nil do @@ -272,7 +272,31 @@ function OpenSaveableMenu(submitCb, cancelCb, restrict) end AddEventHandler('playerSpawned', function() - TriggerEvent('skinchanger:loadDefaultModel', true) + + Citizen.CreateThread(function() + + while not PlayerLoaded do + Citizen.Wait(0) + end + + if FirstSpawn then + + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) + + if skin == nil then + OpenSaveableMenu(nil, nil, nil) + else + TriggerEvent('skinchanger:loadSkin', skin) + end + + end) + + FirstSpawn = false + + end + + end) + end) RegisterNetEvent('esx:playerLoaded') @@ -311,33 +335,6 @@ AddEventHandler('esx_skin:requestSaveSkin', function() end) end) -AddEventHandler('skinchanger:modelLoaded', function() - - if not HasLoadedModel then - - Citizen.CreateThread(function() - - while not PlayerLoaded do - Citizen.Wait(0) - end - - ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) - - HasLoadedModel = true - - if skin == nil then - OpenSaveableMenu(nil, nil, nil) - else - TriggerEvent('skinchanger:loadSkin', skin) - end - - end) - - end) - - end -end) - Citizen.CreateThread(function() while true do From 71150e91e469510bb6bd659492a0f9733f854f1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 19 Aug 2017 11:24:14 +0200 Subject: [PATCH 0478/3224] Add missing config.lua in __resource.lua --- __resource.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/__resource.lua b/__resource.lua index 1283b1cc..4f737ba0 100644 --- a/__resource.lua +++ b/__resource.lua @@ -4,8 +4,8 @@ description 'ESX Phone' server_scripts { '@mysql-async/lib/MySQL.lua', + 'config.lua', '@es_extended/locale.lua', - 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'server/main.lua' @@ -13,7 +13,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', - 'locales/br.lua', + 'config.lua', 'locales/en.lua', 'locales/fr.lua', 'client/main.lua' From 8c74011b397337e3c24bb716f133039ac32ad90a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 19 Aug 2017 11:28:19 +0200 Subject: [PATCH 0479/3224] Add fallback cases --- resources/[essential]/es_extended/locale.lua | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/locale.lua b/resources/[essential]/es_extended/locale.lua index c8b11067..03e2271f 100644 --- a/resources/[essential]/es_extended/locale.lua +++ b/resources/[essential]/es_extended/locale.lua @@ -1,7 +1,19 @@ Locales = {} function _(str, ...) -- Translate string - return string.format(Locales[Config.Locale][str], ...) + + if Locales[Config.Locale] ~= nil then + + if Locales[Config.Locale][str] ~= nil then + return string.format(Locales[Config.Locale][str], ...) + else + return 'Translation [' .. Config.Locale .. '][' .. str .. '] does not exists' + end + + else + return 'Locale [' .. Config.Locale .. '] does not exists' + end + end function _U(str, ...) -- Translate string first char uppercase From ec1e8c0852b7461472dc9c332464ad55c81682e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 19 Aug 2017 13:14:04 +0200 Subject: [PATCH 0480/3224] Add rare and canRemove flags on items --- es_extended.sql | 17 +++--- .../es_extended/client/functions.lua | 55 +++++++++++-------- .../[essential]/es_extended/server/common.lua | 6 +- .../[essential]/es_extended/server/main.lua | 24 ++++---- 4 files changed, 61 insertions(+), 41 deletions(-) diff --git a/es_extended.sql b/es_extended.sql index 834a229c..15ce8398 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -1,12 +1,13 @@ USE `essentialmode`; ALTER TABLE `users` -ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, -ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, -ADD COLUMN `job` varchar(255) NULL DEFAULT 'unemployed' AFTER `skin`, -ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, -ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, -ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout`; + ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, + ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, + ADD COLUMN `job` varchar(255) NULL DEFAULT 'unemployed' AFTER `skin`, + ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, + ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, + ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout` +; CREATE TABLE `items` ( @@ -14,7 +15,9 @@ CREATE TABLE `items` ( `name` varchar(255) NOT NULL, `label` varchar(255) NOT NULL, `limit` int(11) NOT NULL DEFAULT '-1', - + `rare` int(11) NOT NULL DEFAULT '0', + `can_remove` int(11) NOT NULL DEFAULT '1', + PRIMARY KEY (`id`) ); diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 792495f0..d9680031 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -972,20 +972,24 @@ ESX.ShowInventory = function() local elements = {} table.insert(elements, { - label = '[Cash] $' .. data.money, - count = data.money, - type = 'item_money', - value = 'money', - usable = false + label = '[Cash] $' .. data.money, + count = data.money, + type = 'item_money', + value = 'money', + usable = false, + rare = false, + canRemove = true }) for i=1, #data.accounts, 1 do table.insert(elements, { - label = '[' .. data.accounts[i].label .. '] $' .. data.accounts[i].money, - count = data.accounts[i].money, - type = 'item_account', - value = data.accounts[i].name, - usable = false + label = '[' .. data.accounts[i].label .. '] $' .. data.accounts[i].money, + count = data.accounts[i].money, + type = 'item_account', + value = data.accounts[i].name, + usable = false, + rare = false, + canRemove = true }) end @@ -993,11 +997,13 @@ ESX.ShowInventory = function() if data.inventory[i].count > 0 then table.insert(elements, { - label = data.inventory[i].label .. ' x' .. data.inventory[i].count, - count = data.inventory[i].count, - type = 'item_standard', - value = data.inventory[i].name, - usable = data.inventory[i].usable + label = data.inventory[i].label .. ' x' .. data.inventory[i].count, + count = data.inventory[i].count, + type = 'item_standard', + value = data.inventory[i].name, + usable = data.inventory[i].usable, + rare = data.inventory[i].rare, + canRemove = data.inventory[i].canRemove, }) end @@ -1012,11 +1018,13 @@ ESX.ShowInventory = function() local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) table.insert(elements, { - label = Config.Weapons[i].label .. ' x1 [' .. ammo .. ']', - count = 1, - type = 'item_weapon', - value = Config.Weapons[i].name, - usable = false + label = Config.Weapons[i].label .. ' x1 [' .. ammo .. ']', + count = 1, + type = 'item_weapon', + value = Config.Weapons[i].name, + usable = false, + rare = false, + canRemove = true }) end @@ -1041,8 +1049,11 @@ ESX.ShowInventory = function() table.insert(elements, {label = _U('use'), action = 'use', type = data.current.type, value = data.current.value}) end - table.insert(elements, {label = _U('give'), action = 'give', type = data.current.type, value = data.current.value}) - table.insert(elements, {label = _U('remove'), action = 'remove', type = data.current.type, value = data.current.value}) + if data.current.canRemove then + table.insert(elements, {label = _U('give'), action = 'give', type = data.current.type, value = data.current.value}) + table.insert(elements, {label = _U('remove'), action = 'remove', type = data.current.type, value = data.current.value}) + end + table.insert(elements, {label = _U('return'), action = 'return'}) ESX.UI.Menu.Open( diff --git a/resources/[essential]/es_extended/server/common.lua b/resources/[essential]/es_extended/server/common.lua index ffadee09..5e6a1042 100644 --- a/resources/[essential]/es_extended/server/common.lua +++ b/resources/[essential]/es_extended/server/common.lua @@ -22,8 +22,10 @@ AddEventHandler('onMySQLReady', function () for i=1, #result, 1 do ESX.Items[result[i].name] = { - label = result[i].label, - limit = result[i].limit + label = result[i].label, + limit = result[i].limit, + rare = (result[i].rare == 1 and true or false), + canRemove = (result[i].can_remove == 1 and true or false), } end diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index 6d56ac13..23bab0e4 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -71,11 +71,13 @@ AddEventHandler('es:playerLoaded', function(source, _player) for i=1, #inventory, 1 do table.insert(userData.inventory, { - name = inventory[i].item, - count = inventory[i].count, - label = ESX.Items[inventory[i].item].label, - limit = ESX.Items[inventory[i].item].limit, - usable = ESX.UsableItemsCallbacks[inventory[i].item] ~= nil + name = inventory[i].item, + count = inventory[i].count, + label = ESX.Items[inventory[i].item].label, + limit = ESX.Items[inventory[i].item].limit, + usable = ESX.UsableItemsCallbacks[inventory[i].item] ~= nil, + rare = ESX.Items[inventory[i].item].rare, + canRemove = ESX.Items[inventory[i].item].canRemove, }) end @@ -93,11 +95,13 @@ AddEventHandler('es:playerLoaded', function(source, _player) if not found then table.insert(userData.inventory, { - name = k, - count = 0, - label = ESX.Items[k].label, - limit = ESX.Items[k].limit, - usable = ESX.UsableItemsCallbacks[k] ~= nil + name = k, + count = 0, + label = ESX.Items[k].label, + limit = ESX.Items[k].limit, + usable = ESX.UsableItemsCallbacks[k] ~= nil, + rare = ESX.Items[k].rare, + canRemove = ESX.Items[k].canRemove, }) MySQL.Async.execute( From cb3533925167546bfd75c09adbbf42429c502efc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 19 Aug 2017 13:15:55 +0200 Subject: [PATCH 0481/3224] Update README.md --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index b827b23e..38dfcb62 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,16 @@ # fxserver-es_extended [WIP] FXServer ES Extended +[UPDATE] + +Since commit : https://github.com/FXServer-ESX/fxserver-es_extended/commit/ec1e8c0852b7461472dc9c332464ad55c81682e7 you have to add this SQL if you have already installed es_extended : +```sql +ALTER TABLE `items` + ADD COLUMN `rare` int(11) NOT NULL DEFAULT '0', + ADD COLUMN `can_remove` int(11) NOT NULL DEFAULT '1' +; +``` + [DISCORD] https://discord.me/fivem_esx From b2a93ea5de5cf9b428bc3d6cdc896c9afeea95fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 19 Aug 2017 18:00:13 +0200 Subject: [PATCH 0482/3224] Add ESX.SpawnLocalObject --- .../es_extended/client/functions.lua | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index d9680031..6e01a4fb 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -293,6 +293,28 @@ ESX.Game.SpawnObject = function(model, coords, radius, cb) end +ESX.Game.SpawnLocalObject = function(model, coords, radius, cb) + + local model = (type(model) == 'number' and model or GetHashKey(model)) + + Citizen.CreateThread(function() + + RequestModel(model) + + while not HasModelLoaded(model) do + Citizen.Wait(0) + end + + local obj = CreateObject(model, coords.x, coords.y, coords.z, false, true, true) + + if cb ~= nil then + cb(obj) + end + + end) + +end + ESX.Game.DeleteVehicle = function(vehicle) SetEntityAsMissionEntity(vehicle, false, true) DeleteVehicle(vehicle) From 79a3c83b6a9dbf9ed3252c77b89b13ac7dda8643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 19 Aug 2017 18:02:52 +0200 Subject: [PATCH 0483/3224] Fix SpawnOBject arguments --- resources/[essential]/es_extended/client/functions.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 6e01a4fb..61580780 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -271,7 +271,7 @@ ESX.Game.Teleport = function(entity, coords, cb) end -ESX.Game.SpawnObject = function(model, coords, radius, cb) +ESX.Game.SpawnObject = function(model, coords, cb) local model = (type(model) == 'number' and model or GetHashKey(model)) @@ -293,7 +293,7 @@ ESX.Game.SpawnObject = function(model, coords, radius, cb) end -ESX.Game.SpawnLocalObject = function(model, coords, radius, cb) +ESX.Game.SpawnLocalObject = function(model, coords, cb) local model = (type(model) == 'number' and model or GetHashKey(model)) From 0f31acb47887be54c026c47cccbae601e1e169f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 19 Aug 2017 18:03:45 +0200 Subject: [PATCH 0484/3224] Fix SpawnOBject arguments --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index a96d1225..000797c4 100644 --- a/client/main.lua +++ b/client/main.lua @@ -511,7 +511,7 @@ function OpenMobileMecanoActionsMenu() x = x, y = y, z = z - }, 3.0, function(obj) + }, function(obj) SetEntityHeading(obj, GetEntityHeading(playerPed)) PlaceObjectOnGroundProperly(obj) end) From 862e35fcab5c8c263a401b8189ce54f1397fd86c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 19 Aug 2017 18:04:28 +0200 Subject: [PATCH 0485/3224] Fix SpawnOBject arguments --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 83f7ffba..d8bebf5d 100644 --- a/client/main.lua +++ b/client/main.lua @@ -441,7 +441,7 @@ function OpenPoliceActionsMenu() x = x, y = y, z = z - }, 3.0, function(obj) + }, function(obj) SetEntityHeading(obj, GetEntityHeading(playerPed)) PlaceObjectOnGroundProperly(obj) end) From 44db2b5471427fd59419864ad3909f0d0dc599ba Mon Sep 17 00:00:00 2001 From: renaiku Date: Sat, 19 Aug 2017 21:02:16 +0200 Subject: [PATCH 0486/3224] Fix colors for hairs, beards, lipstick, eyebrows, makeup --- client/main.lua | 206 ++++++++++++++++++++++++------------------------ 1 file changed, 103 insertions(+), 103 deletions(-) diff --git a/client/main.lua b/client/main.lua index 8415cde1..86194fc9 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,54 +1,54 @@ local Components = { - {label = _U('sex'), name = 'sex', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- - {label = _U('face'), name = 'face', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- - {label = _U('skin'), name = 'skin', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- - {label = _U('wrinkles'), name = 'age_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = _U('wrinkle_thickness'), name = 'age_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = _U('beard_type'), name = 'beard_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = _U('beard_size'), name = 'beard_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = _U('beard_color_1'), name = 'beard_3', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = _U('beard_color_2'), name = 'beard_4', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = _U('hair_1'), name = 'hair_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- - {label = _U('hair_2'), name = 'hair_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- - {label = _U('hair_color_1'), name = 'hair_color_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- - {label = _U('hair_color_2'), name = 'hair_color_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- - {label = _U('eyebrow_type'), name = 'eyebrows_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = _U('eyebrow_size'), name = 'eyebrows_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = _U('eyebrow_color_1'), name = 'eyebrows_3', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = _U('eyebrow_color_2'), name = 'eyebrows_4', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = _U('makeup_type'), name = 'makeup_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = _U('makeup_thickness'), name = 'makeup_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = _U('makeup_color_1'), name = 'makeup_3', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = _U('makeup_color_2'), name = 'makeup_4', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = _U('lipstick_type'), name = 'lipstick_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = _U('lipstick_thickness'), name = 'lipstick_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = _U('lipstick_color_1'), name = 'lipstick_3', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = _U('lipstick_color_2'), name = 'lipstick_4', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = _U('ear_accessories'), name = 'ears_1', value = -1, min = -1, zoomOffset = 0.4, camOffset = 0.65}, -- - {label = _U('ear_accessories_color'), name = 'ears_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65, textureof = 'ears_1'}, -- - {label = _U('tshirt_1'), name = 'tshirt_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- - {label = _U('tshirt_2'), name = 'tshirt_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'tshirt_1'}, -- - {label = _U('torso_1'), name = 'torso_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- - {label = _U('torso_2'), name = 'torso_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'torso_1'}, -- - {label = _U('decals_1'), name = 'decals_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- - {label = _U('decals_2'), name = 'decals_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'decals_1'}, -- - {label = _('arms'), name = 'arms', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- - {label = _U('pants_1'), name = 'pants_1', value = 0, min = 0, zoomOffset = 0.8, camOffset = -0.5}, -- - {label = _U('pants_2'), name = 'pants_2', value = 0, min = 0, zoomOffset = 0.8, camOffset = -0.5, textureof = 'pants_1'}, -- - {label = _U('shoes_1'), name = 'shoes_1', value = 0, min = 0, zoomOffset = 0.8, camOffset = -0.8}, - {label = _U('shoes_2'), name = 'shoes_2', value = 0, min = 0, zoomOffset = 0.8, camOffset = -0.8, textureof = 'shoes_1'}, - {label = _U('mask_1'), name = 'mask_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- - {label = _U('mask_2'), name = 'mask_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65, textureof = 'mask_1'}, -- - {label = _U('bproof_1'), name = 'bproof_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- - {label = _U('bproof_2'), name = 'bproof_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'bproof_1'}, -- - {label = _U('chain_1'), name = 'chain_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- - {label = _U('chain_2'), name = 'chain_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65, textureof = 'chain_1'}, -- - {label = _U('helmet_1'), name = 'helmet_1', value = -1, min = -1, componentId = 0, zoomOffset = 0.6, camOffset = 0.65}, -- - {label = _U('helmet_2'), name = 'helmet_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65, textureof = 'helmet_1'}, -- - {label = _U('glasses_1'), name = 'glasses_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- - {label = _U('glasses_2'), name = 'glasses_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65, textureof = 'glasses_1'}, -- - {label = _U('bag'), name = 'bags_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, - {label = _U('bag_color'), name = 'bags_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'bags_1'} + {label = _U('sex'), name = 'sex', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = _U('face'), name = 'face', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = _U('skin'), name = 'skin', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = _U('wrinkles'), name = 'age_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('wrinkle_thickness'), name = 'age_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('beard_type'), name = 'beard_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('beard_size'), name = 'beard_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('beard_color_1'), name = 'beard_3', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('beard_color_2'), name = 'beard_4', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('hair_1'), name = 'hair_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = _U('hair_2'), name = 'hair_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = _U('hair_color_1'), name = 'hair_color_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = _U('hair_color_2'), name = 'hair_color_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = _U('eyebrow_type'), name = 'eyebrows_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('eyebrow_size'), name = 'eyebrows_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('eyebrow_color_1'), name = 'eyebrows_3', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('eyebrow_color_2'), name = 'eyebrows_4', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('makeup_type'), name = 'makeup_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('makeup_thickness'), name = 'makeup_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('makeup_color_1'), name = 'makeup_3', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('makeup_color_2'), name = 'makeup_4', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('lipstick_type'), name = 'lipstick_1', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('lipstick_thickness'), name = 'lipstick_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('lipstick_color_1'), name = 'lipstick_3', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('lipstick_color_2'), name = 'lipstick_4', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('ear_accessories'), name = 'ears_1', value = -1, min = -1, zoomOffset = 0.4, camOffset = 0.65}, -- + {label = _U('ear_accessories_color'), name = 'ears_2', value = 0, min = 0, zoomOffset = 0.4, camOffset = 0.65, textureof = 'ears_1'}, -- + {label = _U('tshirt_1'), name = 'tshirt_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- + {label = _U('tshirt_2'), name = 'tshirt_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'tshirt_1'}, -- + {label = _U('torso_1'), name = 'torso_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- + {label = _U('torso_2'), name = 'torso_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'torso_1'}, -- + {label = _U('decals_1'), name = 'decals_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- + {label = _U('decals_2'), name = 'decals_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'decals_1'}, -- + {label = _U('arms'), name = 'arms', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- + {label = _U('pants_1'), name = 'pants_1', value = 0, min = 0, zoomOffset = 0.8, camOffset = -0.5}, -- + {label = _U('pants_2'), name = 'pants_2', value = 0, min = 0, zoomOffset = 0.8, camOffset = -0.5, textureof = 'pants_1'}, -- + {label = _U('shoes_1'), name = 'shoes_1', value = 0, min = 0, zoomOffset = 0.8, camOffset = -0.8}, + {label = _U('shoes_2'), name = 'shoes_2', value = 0, min = 0, zoomOffset = 0.8, camOffset = -0.8, textureof = 'shoes_1'}, + {label = _U('mask_1'), name = 'mask_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = _U('mask_2'), name = 'mask_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65, textureof = 'mask_1'}, -- + {label = _U('bproof_1'), name = 'bproof_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, -- + {label = _U('bproof_2'), name = 'bproof_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'bproof_1'}, -- + {label = _U('chain_1'), name = 'chain_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = _U('chain_2'), name = 'chain_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65, textureof = 'chain_1'}, -- + {label = _U('helmet_1'), name = 'helmet_1', value = -1, min = -1, componentId = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = _U('helmet_2'), name = 'helmet_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65, textureof = 'helmet_1'}, -- + {label = _U('glasses_1'), name = 'glasses_1', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65}, -- + {label = _U('glasses_2'), name = 'glasses_2', value = 0, min = 0, zoomOffset = 0.6, camOffset = 0.65, textureof = 'glasses_1'}, -- + {label = _U('bag'), name = 'bags_1', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15}, + {label = _U('bag_color'), name = 'bags_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'bags_1'} } local LastSex = 0 @@ -117,37 +117,37 @@ function GetMaxVals() eyebrows_4 = GetNumHairColors()-1, makeup_1 = GetNumHeadOverlayValues(4)-1, makeup_2 = 10, - makeup_3 = 74, - makeup_4 = 74, + makeup_3 = GetNumHairColors()-1, + makeup_4 = GetNumHairColors()-1, lipstick_1 = GetNumHeadOverlayValues(8)-1, lipstick_2 = 10, - lipstick_3 = 9, - lipstick_4 = 9, - ears_1 = GetNumberOfPedPropDrawableVariations(playerPed, 1) - 1, - ears_2 = GetNumberOfPedPropTextureVariations(playerPed, 1, Character['ears_1'] - 1), - tshirt_1 = GetNumberOfPedDrawableVariations(playerPed, 8) - 1, - tshirt_2 = GetNumberOfPedTextureVariations(playerPed, 8, Character['tshirt_1']) - 1, - torso_1 = GetNumberOfPedDrawableVariations(playerPed, 11) - 1, - torso_2 = GetNumberOfPedTextureVariations(playerPed, 11, Character['torso_1']) - 1, - decals_1 = GetNumberOfPedDrawableVariations(playerPed, 10) - 1, - decals_2 = GetNumberOfPedTextureVariations(playerPed, 10, Character['decals_1']) - 1, - arms = GetNumberOfPedDrawableVariations(playerPed, 3) - 1, - pants_1 = GetNumberOfPedDrawableVariations(playerPed, 4) - 1, - pants_2 = GetNumberOfPedTextureVariations(playerPed, 4, Character['pants_1']) - 1, - shoes_1 = GetNumberOfPedDrawableVariations(playerPed, 6) - 1, - shoes_2 = GetNumberOfPedTextureVariations(playerPed, 6, Character['shoes_1']) - 1, - mask_1 = GetNumberOfPedDrawableVariations(playerPed, 1) - 1, - mask_2 = GetNumberOfPedTextureVariations(playerPed, 1, Character['mask_1']) - 1, - bproof_1 = GetNumberOfPedDrawableVariations(playerPed, 9) - 1, - bproof_2 = GetNumberOfPedTextureVariations(playerPed, 9, Character['bproof_1']) - 1, - chain_1 = GetNumberOfPedDrawableVariations(playerPed, 7) - 1, - chain_2 = GetNumberOfPedTextureVariations(playerPed, 7, Character['chain_1']) - 1, - bags_1 = GetNumberOfPedDrawableVariations(playerPed, 5) - 1, - bags_2 = GetNumberOfPedTextureVariations(playerPed, 5, Character['bags_1']) - 1, - helmet_1 = GetNumberOfPedPropDrawableVariations(playerPed, 0) - 1, - helmet_2 = GetNumberOfPedPropTextureVariations(playerPed, 0, Character['helmet_1']) - 1, - glasses_1 = GetNumberOfPedPropDrawableVariations(playerPed, 1) - 1, - glasses_2 = GetNumberOfPedPropTextureVariations(playerPed, 1, Character['glasses_1'] - 1), + lipstick_3 = GetNumHairColors()-1, + lipstick_4 = GetNumHairColors()-1, + ears_1 = GetNumberOfPedPropDrawableVariations(playerPed, 1) - 1, + ears_2 = GetNumberOfPedPropTextureVariations(playerPed, 1, Character['ears_1'] - 1), + tshirt_1 = GetNumberOfPedDrawableVariations(playerPed, 8) - 1, + tshirt_2 = GetNumberOfPedTextureVariations(playerPed, 8, Character['tshirt_1']) - 1, + torso_1 = GetNumberOfPedDrawableVariations(playerPed, 11) - 1, + torso_2 = GetNumberOfPedTextureVariations(playerPed, 11, Character['torso_1']) - 1, + decals_1 = GetNumberOfPedDrawableVariations(playerPed, 10) - 1, + decals_2 = GetNumberOfPedTextureVariations(playerPed, 10, Character['decals_1']) - 1, + arms = GetNumberOfPedDrawableVariations(playerPed, 3) - 1, + pants_1 = GetNumberOfPedDrawableVariations(playerPed, 4) - 1, + pants_2 = GetNumberOfPedTextureVariations(playerPed, 4, Character['pants_1']) - 1, + shoes_1 = GetNumberOfPedDrawableVariations(playerPed, 6) - 1, + shoes_2 = GetNumberOfPedTextureVariations(playerPed, 6, Character['shoes_1']) - 1, + mask_1 = GetNumberOfPedDrawableVariations(playerPed, 1) - 1, + mask_2 = GetNumberOfPedTextureVariations(playerPed, 1, Character['mask_1']) - 1, + bproof_1 = GetNumberOfPedDrawableVariations(playerPed, 9) - 1, + bproof_2 = GetNumberOfPedTextureVariations(playerPed, 9, Character['bproof_1']) - 1, + chain_1 = GetNumberOfPedDrawableVariations(playerPed, 7) - 1, + chain_2 = GetNumberOfPedTextureVariations(playerPed, 7, Character['chain_1']) - 1, + bags_1 = GetNumberOfPedDrawableVariations(playerPed, 5) - 1, + bags_2 = GetNumberOfPedTextureVariations(playerPed, 5, Character['bags_1']) - 1, + helmet_1 = GetNumberOfPedPropDrawableVariations(playerPed, 0) - 1, + helmet_2 = GetNumberOfPedPropTextureVariations(playerPed, 0, Character['helmet_1']) - 1, + glasses_1 = GetNumberOfPedPropDrawableVariations(playerPed, 1) - 1, + glasses_2 = GetNumberOfPedPropTextureVariations(playerPed, 1, Character['glasses_1'] - 1), } return data @@ -200,42 +200,42 @@ function ApplySkin(skin, clothes) SetPedHeadBlendData(playerPed, Character['face'], Character['face'], Character['face'], Character['skin'], Character['skin'], Character['skin'], 1.0, 1.0, 1.0, true) - SetPedHeadOverlay(playerPed, 3, Character['age_1'], (Character['age_2'] / 10) + 0.0) -- Age + opacity - SetPedHeadOverlay(playerPed, 1, Character['beard_1'], (Character['beard_2'] / 10) + 0.0) -- Beard + opacity - SetPedHeadOverlayColor(playerPed, 1, 1, Character['beard_3'], Character['beard_4']) -- Beard Color - SetPedHeadOverlay(playerPed, 2, Character['eyebrows_1'], (Character['eyebrows_2'] / 10) + 0.0) -- Eyebrows + opacity - SetPedHeadOverlayColor(playerPed, 1, 1, Character['eyebrows_3'], Character['eyebrows_4']) -- Eyebrows Color - SetPedHeadOverlay(playerPed, 4, Character['makeup_1'], (Character['makeup_2'] / 10) + 0.0) -- Makeup + opacity - SetPedHeadOverlayColor(playerPed, 1, 1, Character['makeup_3'], Character['makeup_4']) -- Makeup Color - SetPedHeadOverlay(playerPed, 8, Character['lipstick_1'], (Character['lipstick_2'] / 10) + 0.0) -- Lipstick + opacity - SetPedHeadOverlayColor(playerPed, 2, 1, Character['lipstick_3'], Character['lipstick_4']) -- Lipstick Color - SetPedComponentVariation(playerPed, 2, Character['hair_1'], Character['hair_2'], 2) -- Hair - SetPedHairColor(playerPed, Character['hair_color_1'], Character['hair_color_2']) -- Hair Color + SetPedHeadOverlay(playerPed, 3, Character['age_1'], (Character['age_2'] / 10) + 0.0) -- Age + opacity + SetPedHeadOverlay(playerPed, 1, Character['beard_1'], (Character['beard_2'] / 10) + 0.0) -- Beard + opacity + SetPedHeadOverlayColor(playerPed, 1, 1, Character['beard_3'], Character['beard_4']) -- Beard Color + SetPedHeadOverlay(playerPed, 2, Character['eyebrows_1'], (Character['eyebrows_2'] / 10) + 0.0) -- Eyebrows + opacity + SetPedHeadOverlayColor(playerPed, 2, 1, Character['eyebrows_3'], Character['eyebrows_4']) -- Eyebrows Color + SetPedHeadOverlay(playerPed, 4, Character['makeup_1'], (Character['makeup_2'] / 10) + 0.0) -- Makeup + opacity + SetPedHeadOverlayColor(playerPed, 4, 1, Character['makeup_3'], Character['makeup_4']) -- Makeup Color + SetPedHeadOverlay(playerPed, 8, Character['lipstick_1'], (Character['lipstick_2'] / 10) + 0.0) -- Lipstick + opacity + SetPedHeadOverlayColor(playerPed, 8, 1, Character['lipstick_3'], Character['lipstick_4']) -- Lipstick Color + SetPedComponentVariation(playerPed, 2, Character['hair_1'], Character['hair_2'], 2) -- Hair + SetPedHairColor(playerPed, Character['hair_color_1'], Character['hair_color_2']) -- Hair Color if Character['ears_1'] == -1 then ClearPedProp(playerPed, 2) else - SetPedPropIndex(playerPed, 2, Character['ears_1'], Character['ears_2'], 2) -- Ears Accessories + SetPedPropIndex(playerPed, 2, Character['ears_1'], Character['ears_2'], 2) -- Ears Accessories end - SetPedComponentVariation(playerPed, 8, Character['tshirt_1'],Character['tshirt_2'], 2) -- Tshirt - SetPedComponentVariation(playerPed, 11, Character['torso_1'], Character['torso_2'], 2) -- torso parts - SetPedComponentVariation(playerPed, 3, Character['arms'], 0, 2) -- torso - SetPedComponentVariation(playerPed, 10, Character['decals_1'], Character['decals_2'], 2) -- decals - SetPedComponentVariation(playerPed, 4, Character['pants_1'], Character['pants_2'], 2) -- pants - SetPedComponentVariation(playerPed, 6, Character['shoes_1'], Character['shoes_2'], 2) -- shoes - SetPedComponentVariation(playerPed, 1, Character['mask_1'], Character['mask_2'], 2) -- mask - SetPedComponentVariation(playerPed, 9, Character['bproof_1'], Character['bproof_2'], 2) -- bulletproof - SetPedComponentVariation(playerPed, 7, Character['chain_1'], Character['chain_2'], 2) -- chain - SetPedComponentVariation(playerPed, 5, Character['bags_1'], Character['bags_2'], 2) -- Bag + SetPedComponentVariation(playerPed, 8, Character['tshirt_1'],Character['tshirt_2'], 2) -- Tshirt + SetPedComponentVariation(playerPed, 11, Character['torso_1'], Character['torso_2'], 2) -- torso parts + SetPedComponentVariation(playerPed, 3, Character['arms'], 0, 2) -- torso + SetPedComponentVariation(playerPed, 10, Character['decals_1'], Character['decals_2'], 2) -- decals + SetPedComponentVariation(playerPed, 4, Character['pants_1'], Character['pants_2'], 2) -- pants + SetPedComponentVariation(playerPed, 6, Character['shoes_1'], Character['shoes_2'], 2) -- shoes + SetPedComponentVariation(playerPed, 1, Character['mask_1'], Character['mask_2'], 2) -- mask + SetPedComponentVariation(playerPed, 9, Character['bproof_1'], Character['bproof_2'], 2) -- bulletproof + SetPedComponentVariation(playerPed, 7, Character['chain_1'], Character['chain_2'], 2) -- chain + SetPedComponentVariation(playerPed, 5, Character['bags_1'], Character['bags_2'], 2) -- Bag if Character['helmet_1'] == -1 then ClearPedProp(playerPed, 0) else - SetPedPropIndex(playerPed, 0, Character['helmet_1'], Character['helmet_2'], 2) -- Helmet + SetPedPropIndex(playerPed, 0, Character['helmet_1'], Character['helmet_2'], 2) -- Helmet end - SetPedPropIndex(playerPed, 1, Character['glasses_1'], Character['glasses_2'], 2) -- Glasses + SetPedPropIndex(playerPed, 1, Character['glasses_1'], Character['glasses_2'], 2) -- Glasses end From d301d8d2b4617173a1a4dae067f478d9c870e95b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 19 Aug 2017 09:38:40 +0200 Subject: [PATCH 0487/3224] Fix outfit gone when dead --- client/main.lua | 63 +++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/client/main.lua b/client/main.lua index f3860f18..f6e1e557 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,12 +1,12 @@ ESX = nil -local HasLoadedModel = false +local FirstSpawn = true local LastSkin = nil local PlayerLoaded = false -local cam = nil +local cam = nil local isCameraActive = false -local zoomOffset = 0.0 -local camOffset = 0.0 -local heading = 90.0 +local zoomOffset = 0.0 +local camOffset = 0.0 +local heading = 90.0 Citizen.CreateThread(function() while ESX == nil do @@ -272,7 +272,31 @@ function OpenSaveableMenu(submitCb, cancelCb, restrict) end AddEventHandler('playerSpawned', function() - TriggerEvent('skinchanger:loadDefaultModel', true) + + Citizen.CreateThread(function() + + while not PlayerLoaded do + Citizen.Wait(0) + end + + if FirstSpawn then + + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) + + if skin == nil then + OpenSaveableMenu(nil, nil, nil) + else + TriggerEvent('skinchanger:loadSkin', skin) + end + + end) + + FirstSpawn = false + + end + + end) + end) RegisterNetEvent('esx:playerLoaded') @@ -311,33 +335,6 @@ AddEventHandler('esx_skin:requestSaveSkin', function() end) end) -AddEventHandler('skinchanger:modelLoaded', function() - - if not HasLoadedModel then - - Citizen.CreateThread(function() - - while not PlayerLoaded do - Citizen.Wait(0) - end - - ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) - - HasLoadedModel = true - - if skin == nil then - OpenSaveableMenu(nil, nil, nil) - else - TriggerEvent('skinchanger:loadSkin', skin) - end - - end) - - end) - - end -end) - Citizen.CreateThread(function() while true do From b415047b1dea4dc87bcff4777b7f7b2ae65ca98a Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Sat, 19 Aug 2017 19:15:38 -0400 Subject: [PATCH 0488/3224] Added English HTML / JS variants --- __resource.lua | 6 +- html/scripts/app_en.js | 489 +++++++++++++++++++++++++++++++++++++++++ html/ui_en.html | 82 +++++++ 3 files changed, 575 insertions(+), 2 deletions(-) create mode 100644 html/scripts/app_en.js create mode 100644 html/ui_en.html diff --git a/__resource.lua b/__resource.lua index 4f737ba0..226a9dc4 100644 --- a/__resource.lua +++ b/__resource.lua @@ -22,12 +22,14 @@ client_scripts { ui_page 'html/ui.html' files { - 'html/ui.html', + 'html/ui.html', -- FR + --'html/ui_en.html', -- EN 'html/bankgothic.ttf', 'html/pdown.ttf', 'html/css/app.css', 'html/scripts/mustache.min.js', - 'html/scripts/app.js', + 'html/scripts/app.js', -- FR + --'html/scripts/app_en.js', -- EN 'html/img/cursor.png', 'html/img/keys/enter.png', 'html/img/keys/return.png', diff --git a/html/scripts/app_en.js b/html/scripts/app_en.js new file mode 100644 index 00000000..cd4ef5c2 --- /dev/null +++ b/html/scripts/app_en.js @@ -0,0 +1,489 @@ +(function(){ + + let ContactTpl = + '
' + + '
' + + '
' + + '{{sender}}
#{{phoneNumber}}' + + '
' + + '
' + + '
' + + '
' + ; + + let MessageTpl = + '
' + + '
' + + '
' + + '{{sender}}
#{{phoneNumber}}' + + '
' + + '
' + + '
{{message}}
' + + '
' + + '
' + ; + + let SpecialContactTpl = '
  • {{name}}
  • '; + + let contacts = []; + let specialContacts = []; + let menu = []; + let currentItem = 0; + let currentVal = null; + let isMessageEditorOpen = false; + let isMessagesOpen = false; + let isPhoneShowed = false; + + let showMain = function() { + $('.screen').removeClass('active'); + } + + let showRepertoire = function() { + $('#repertoire').addClass('active'); + } + + let hideRepertoire = function() { + $('#repertoire').removeClass('active'); + } + + let showMessages = function(){ + $('#messages').addClass('active'); + isMessagesOpen = true; + } + + let hideMessages = function(){ + $('#messages').removeClass('active'); + isMessagesOpen = false; + } + + let showAddContact = function() { + $('#contact').addClass('active'); + } + + let hideAddContact = function() { + $('#contact').removeClass('active'); + $('#contact_name').val(''); + $('#contact_number').val(''); + } + + let showNewMessage = function(cnum, cname) { + $('#writer').addClass('active'); + $('#writer_number').val(cnum); + $('#writer .header-title').html(cname); + } + + let hideNewMessage = function() { + $('#writer').removeClass('active'); + $('#writer_number').val(''); + $('#writer_message').val(''); + $('#writer .header-title').html(''); + } + + let showGPS = function(xPos, yPos) { + $.post('http://esx_phone/setGPS', JSON.stringify({ + x: parseFloat(xPos), + y: parseFloat(yPos) + } + )); + } + + let renderContacts = function(){ + + let contactHTML = ''; + + if(contacts.length > 0) { + + for(let i=0; i 0) { + + for(let i=0; i { + return a.name.localeCompare(b.name); + }); + + renderSpecialContacts(); + + } + + } + + let removeSpecialContact = function(number){ + + for(let i=0; iHome' + + '
  • Messages
  • ' + ); + + for(let i=0; i + + + + + + + +
    + +
    + +
    + + #123456 +
    + + + +
    + +
    Home
    +
    +
    +
    +

    No contacts

    +
    +
    +
    +
    + +
    +
    Messages
    +
    +
    +
    +

    No messages

    +
    +
    +
    +
    + +
    +
    +
    +
    + + + + + +
    +
    +
    + +
    +
    Add a contact
    +
    +
    + + + + +
    +
    +
    + +
    +
    + + + + + + + + From b0d8604e96688d3e56405c32e494d8ef25bc062c Mon Sep 17 00:00:00 2001 From: MagnanQC Date: Sun, 20 Aug 2017 00:06:04 -0400 Subject: [PATCH 0489/3224] Removed duplicate --- esx_phone.sql | 3 --- 1 file changed, 3 deletions(-) diff --git a/esx_phone.sql b/esx_phone.sql index 62842ccc..521f074a 100644 --- a/esx_phone.sql +++ b/esx_phone.sql @@ -8,6 +8,3 @@ CREATE TABLE user_contacts ( ALTER TABLE `users` ADD COLUMN `phone_number` INT NULL; - -ALTER TABLE `users` -ADD COLUMN `phone_number` INT NULL; From c5079b1dec64fda79c2d6a65306bed819572e8db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 20 Aug 2017 10:59:46 +0200 Subject: [PATCH 0490/3224] Fix boss menu not closing + billing --- client/main.lua | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 0ef4b841..adf3f888 100644 --- a/client/main.lua +++ b/client/main.lua @@ -135,6 +135,20 @@ function OpenShopMenu() if hasEnoughMoney then + IsInShopMenu = false + + DeleteShopInsideVehicles() + + local playerPed = GetPlayerPed(-1) + + CurrentAction = 'shop_menu' + CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionData = {} + + FreezeEntityPosition(playerPed, false) + SetEntityVisible(playerPed, true) + SetEntityCoords(playerPed, Config.Zones.BossActions.Pos.x, Config.Zones.BossActions.Pos.y, Config.Zones.BossActions.Pos.z) + menu2.close() menu.close() @@ -304,7 +318,7 @@ function OpenResellerMenu() if closestPlayer == -1 or closestDistance > 3.0 then ESX.ShowNotification('Aucun joueur à proximité') else - TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_realestateagent', 'Concessionnaire', tonumber(data2.value)) + TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_cardealer', 'Concessionnaire', tonumber(data2.value)) end end From 78dd0583fb5f7764312067cb27c1da81a20ee835 Mon Sep 17 00:00:00 2001 From: Don Date: Sun, 20 Aug 2017 03:28:37 -0700 Subject: [PATCH 0491/3224] Update Multi-language support Update Multi-language support --- config.lua | 2 +- jobs/fisherman.lua | 42 ++++++++++---------- jobs/lumberjack.lua | 18 ++++----- jobs/miner.lua | 94 ++++++++++++++++++++++---------------------- jobs/reporter.lua | 12 +++--- jobs/slaughterer.lua | 52 ++++++++++++------------ jobs/textil.lua | 52 ++++++++++++------------ locales/en.lua | 87 +++++++++++++++++++++++++++++++++------- locales/fr.lua | 77 +++++++++++++++++++++++++++++++----- 9 files changed, 275 insertions(+), 161 deletions(-) diff --git a/config.lua b/config.lua index 89682111..392a3499 100644 --- a/config.lua +++ b/config.lua @@ -1,6 +1,6 @@ Config = {} Config.DrawDistance = 1000.0 -Config.Locale = 'fr' +Config.Locale = 'en' Config.Plates = { taxi = "TAXI", diff --git a/jobs/fisherman.lua b/jobs/fisherman.lua index e8af59c0..eca1756d 100644 --- a/jobs/fisherman.lua +++ b/jobs/fisherman.lua @@ -24,9 +24,9 @@ Config.Jobs.fisherman = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = "Vestiaire", + Name = _U('cloakroom'), Type = "cloakroom", - Hint = "Appuyez sur ~INPUT_PICKUP~ pour vous changer.", + Hint = _U('cloak_change'), GPS = {x = 880.74462890625, y = -1663.9635009766, z = 29.370491027832} }, @@ -36,11 +36,11 @@ Config.Jobs.fisherman = { Size = {x = 110.0, y = 110.0, z = 10.0}, Marker= 1, Blip = true, - Name = "Zone de pêche", + Name = _U('fm_fish_area'), Type = "work", Item = { { - name = "Poisson", + name = _U('fm_fish'), db_name= "fish", time = 2000, max = 100, @@ -51,7 +51,7 @@ Config.Jobs.fisherman = { drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour pêcher.", + Hint = _U('fm_fish_button'), GPS = {x = 3859.43, y = 4448.83, z = 0.39994} }, @@ -61,10 +61,10 @@ Config.Jobs.fisherman = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = "Spawner bateau", + Name = _U('fm_spawnboat_title'), Type = "vehspawner", Spawner = 2, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour appeler le bateau.", + Hint = _U('fm_spawnboat'), Caution = 0, GPS = {x = 4435.21, y = 4829.6, z = 0.3439} }, @@ -74,7 +74,7 @@ Config.Jobs.fisherman = { Size = {x = 3.0, y = 3.0, z = 1.0}, Marker= -1, Blip = false, - Name = "Bateau", + Name = _U('fm_boat_title'), Type = "vehspawnpt", Spawner = 2, GPS = 0, @@ -87,9 +87,9 @@ Config.Jobs.fisherman = { Color = {r = 255, g = 0, b = 0}, Marker= 1, Blip = false, - Name = "Supression du bateau", + Name = _U('fm_boat_return_title'), Type = "vehdelete", - Hint = "Appuyez sur ~INPUT_PICKUP~ pour rendre le bateau.", + Hint = _U('fm_boat_return_button'), Spawner = 2, Caution = 0, GPS = {x = -1012.64758300781, y = -1354.62634277344, z = 5.54292726516724}, @@ -103,10 +103,10 @@ Config.Jobs.fisherman = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = false, - Name = "Spawner véhicule de fonction", + Name = _U('spawn_veh'), Type = "vehspawner", Spawner = 1, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour appeler le véhicule de livraison.", + Hint = _U('spawn_veh_button'), Caution = 2000, GPS = {x = 3867.44, y = 4463.62, z = 1.72386} }, @@ -116,7 +116,7 @@ Config.Jobs.fisherman = { Size = {x = 3.0, y = 3.0, z = 1.0}, Marker= -1, Blip = false, - Name = "Véhicule de fonction", + Name = _U('service_vh'), Type = "vehspawnpt", Spawner = 1, GPS = 0, @@ -129,9 +129,9 @@ Config.Jobs.fisherman = { Color = {r = 255, g = 0, b = 0}, Marker= 1, Blip = false, - Name = "Supression du véhicule", + Name = _U('return_vh'), Type = "vehdelete", - Hint = "Appuyez sur ~INPUT_PICKUP~ pour rendre le véhicule.", + Hint = _U('return_vh_button'), Spawner = 1, Caution = 2000, GPS = 0, @@ -145,23 +145,23 @@ Config.Jobs.fisherman = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = "Point de livraison", - Type = "delivery", + Name = _U('delivery_point'), + Type = "delivery", Spawner = 2, Item = { { - name = "Livraison", + name = _U('delivery'), time = 500, remove = 1, max = 100, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 11, requires = "fish", - requires_name = "Poisson", + requires_name = _U('fm_fish'), drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour livrer le poisson.", + Hint = _U('fm_deliver_fish'), GPS = {x = 3867.44, y = 4463.62, z = 1.72386} } } -} \ No newline at end of file +} diff --git a/jobs/lumberjack.lua b/jobs/lumberjack.lua index 4ecaead1..8cd21380 100644 --- a/jobs/lumberjack.lua +++ b/jobs/lumberjack.lua @@ -18,9 +18,9 @@ Config.Jobs.lumberjack = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = _U('lj_cr_title'), + Name = _U('cloakroom'), Type = "cloakroom", - Hint = _U('lj_cloakroom') + Hint = _U('cloak_change'), }, Wood = { @@ -101,10 +101,10 @@ Config.Jobs.lumberjack = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = false, - Name = _U('lj_spawn_veh'), + Name = _U('spawn_veh'), Type = "vehspawner", Spawner = 1, - Hint = _U('lj_spawn_veh_button'), + Hint = _U('spawn_veh_button'), Caution = 2000 }, @@ -113,7 +113,7 @@ Config.Jobs.lumberjack = { Size = {x = 3.0, y = 3.0, z = 1.0}, Marker= -1, Blip = false, - Name = _U('lj_service_vh'), + Name = _U('service_vh'), Type = "vehspawnpt", Spawner = 1, Heading = 285.1 @@ -125,9 +125,9 @@ Config.Jobs.lumberjack = { Color = {r = 255, g = 0, b = 0}, Marker= 1, Blip = false, - Name = _U('lj_return_vh'), + Name = _U('return_vh'), Type = "vehdelete", - Hint = _U('lj_return_vh_button'), + Hint = _U('return_vh_button'), Spawner = 1, Caution = 2000, GPS = 0, @@ -140,12 +140,12 @@ Config.Jobs.lumberjack = { Size = {x = 5.0, y = 5.0, z = 3.0}, Marker= 1, Blip = true, - Name = _U('lj_delivery_point'), + Name = _U('delivery_point'), Type = "delivery", Spawner = 1, Item = { { - name = _U('lj_delivery'), + name = _U('delivery'), time = 500, remove = 1, max = 100, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua diff --git a/jobs/miner.lua b/jobs/miner.lua index 52fde249..04f96390 100644 --- a/jobs/miner.lua +++ b/jobs/miner.lua @@ -18,9 +18,9 @@ Config.Jobs.miner = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = "Vestiaire", + Name = _U('cloakroom'), Type = "cloakroom", - Hint = "Appuyez sur ~INPUT_PICKUP~ pour vous changer.", + Hint = _U('cloak_change'), GPS = {x = 884.86889648438, y = -2176.5102539063, z = 29.519346237183} }, @@ -30,11 +30,11 @@ Config.Jobs.miner = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = "Rocher", + Name = _U('m_rock'), Type = "work", Item = { { - name = "Rocher", + name = _U('m_rock'), db_name= "stone", time = 3000, max = 7, @@ -45,7 +45,7 @@ Config.Jobs.miner = { drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour récupérer des rochers.", + Hint = _U('m_pickrocks'), GPS = {x = 289.244, y = 2862.9, z = 42.6424} }, @@ -55,22 +55,22 @@ Config.Jobs.miner = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = "Roche lavé", + Name = _U('m_washrock'), Type = "work", - Item = { + Item = { { - name = "Roche lavé", + name = _U('m_washrock'), db_name= "washed_stone", time = 5000, max = 7, add = 1, remove = 1, requires = "stone", - requires_name = "Rocher", + requires_name = _U('m_rock'), drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour laver les roches.", + Hint = _U('m_rock_button'), GPS = {x = 1109.14, y = -2007.87, z = 30.0188} }, @@ -80,43 +80,43 @@ Config.Jobs.miner = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = "Fonderie", + Name = _U('m_rock_smelting'), Type = "work", Item = { { - name = "Cuivre", + name = _U('m_copper'), db_name= "copper", time = 4000, max = 56, add = 8, remove = 1, requires = "washed_stone", - requires_name = "Roche lavé", + requires_name = _U('m_washrock'), drop = 100 }, { - name = "Fer", + name = _U('m_iron'), db_name= "iron", max = 42, add = 6, drop = 100 }, { - name = "Or", + name = _U('m_gold'), db_name= "gold", max = 21, add = 3, drop = 100 }, { - name = "Diamant", + name = _U('m_diamond'), db_name= "diamond", max = 50, add = 1, drop = 5 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour fondre les roches.", + Hint = _U('m_melt_button'), GPS = {x = -169.481, y = -2659.16, z = 5.00103} }, @@ -126,10 +126,10 @@ Config.Jobs.miner = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = false, - Name = "Spawner véhicule de fonction", + Name = _U('spawn_veh'), Type = "vehspawner", Spawner = 1, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour appeler le véhicule de livraison.", + Hint = _U('spawn_veh_button'), Caution = 2000, GPS = {x = 2962.4, y = 2746.2, z = 42.398} }, @@ -139,22 +139,22 @@ Config.Jobs.miner = { Size = {x = 5.0, y = 5.0, z = 1.0}, Marker= -1, Blip = false, - Name = "Véhicule de fonction", - Type = "vehspawnpt", + Name = _U('service_vh'), + Type = "vehspawnpt", Spawner = 1, Heading = 90.1, GPS = 0 }, - + VehicleDeletePoint = { Pos = {x = 881.93725585938, y = -2198.0151367188, z = 29.519351959229}, Size = {x = 5.0, y = 5.0, z = 1.0}, Color = {r = 255, g = 0, b = 0}, Marker= 1, Blip = false, - Name = "Supression du véhicule", + Name = _U('return_vh'), Type = "vehdelete", - Hint = "Appuyez sur ~INPUT_PICKUP~ pour rendre le véhicule.", + Hint = _U('return_vh_button'), Spawner = 1, Caution = 2000, GPS = 0, @@ -167,22 +167,22 @@ Config.Jobs.miner = { Size = {x = 5.0, y = 5.0, z = 3.0}, Marker= 1, Blip = true, - Name = "Revente de cuivre", - Type = "delivery", + Name = _U('m_sell_copper'), + Type = "delivery", Spawner = 1, Item = { { - name = "Livraison", + name = _U('delivery'), time = 500, remove = 1, max = 56, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 5, requires = "copper", - requires_name = "Cuivre", + requires_name = _U('m_copper'), drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour livrer le cuivre.", + Hint = _U('m_deliver_copper'), GPS = {x = -148.782, y = -1040.38, z = 26.2736} }, @@ -193,25 +193,25 @@ Config.Jobs.miner = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = "Revente de fer", - Type = "delivery", + Name = _U('m_sell_iron'), + Type = "delivery", Spawner = 1, Item = { { - name = "Livraison", + name = _U('delivery'), time = 500, remove = 1, max = 42, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 9, requires = "iron", - requires_name = "Fer", + requires_name = _U('m_iron'), drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour livrer le fer.", + Hint = _U('m_deliver_iron'), GPS = {x = 261.487, y = 207.354, z = 109.287} }, - + GoldDelivery = { Pos = {x = 261.487, y = 207.354, z = 109.287}, Color = {r = 204, g = 204, b = 0}, @@ -219,25 +219,25 @@ Config.Jobs.miner = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = "Revente d'or", - Type = "delivery", + Name = _U('m_sell_gold'), + Type = "delivery", Spawner = 1, Item = { { - name = "Livraison", + name = _U('delivery'), time = 500, remove = 1, max = 21, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 25, requires = "gold", - requires_name = "Or", + requires_name = _U('m_gold'), drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour livrer l'or'.", + Hint = _U('m_deliver_gold'), GPS = {x = -621.046, y = -228.532, z = 37.0571} }, - + DiamondDelivery = { Pos = {x = -621.046, y = -228.532, z = 37.0571}, Color = {r = 204, g = 204, b = 0}, @@ -245,23 +245,23 @@ Config.Jobs.miner = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = "Revente de diamants", - Type = "delivery", + Name = _U('m_sell_diamond'), + Type = "delivery", Spawner = 1, Item = { { - name = "Livraison", + name = _U('delivery'), time = 500, remove = 1, max = 50, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 250, requires = "diamond", - requires_name = "Diamant", + requires_name = _U('m_diamond'), drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour livrer les diamants.", + Hint = _U('m_deliver_diamond'), GPS = {x = 2962.4, y = 2746.2, z = 42.398} } } -} \ No newline at end of file +} diff --git a/jobs/reporter.lua b/jobs/reporter.lua index a2750f36..1a3b98d2 100644 --- a/jobs/reporter.lua +++ b/jobs/reporter.lua @@ -18,10 +18,10 @@ Config.Jobs.reporter = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = "Le Maclerait Libéré", + Name = _U('reporter_name'), Type = "vehspawner", Spawner = 1, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour descendre au garage.", + Hint = _U('reporter_garage'), Caution = 2000 }, @@ -30,7 +30,7 @@ Config.Jobs.reporter = { Size = {x = 3.0, y = 3.0, z = 1.0}, Marker= -1, Blip = false, - Name = "Véhicule de fonction", + Name = _U('service_vh'), Type = "vehspawnpt", Spawner = 1, Heading = 200.1 @@ -42,13 +42,13 @@ Config.Jobs.reporter = { Color = {r = 255, g = 0, b = 0}, Marker= 1, Blip = false, - Name = "Supression du véhicule", + Name = _U('return_vh'), Type = "vehdelete", - Hint = "Appuyez sur ~INPUT_PICKUP~ pour rendre le véhicule.", + Hint = _U('return_vh_button'), Spawner = 1, Caution = 2000, GPS = 0, Teleport = { x = -139.09838867188, y = -620.74865722656, z = 167.82052612305 } } } -} \ No newline at end of file +} diff --git a/jobs/slaughterer.lua b/jobs/slaughterer.lua index 7b923303..9e468819 100644 --- a/jobs/slaughterer.lua +++ b/jobs/slaughterer.lua @@ -18,9 +18,9 @@ Config.Jobs.slaughterer = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = "Vestiaire", + Name = _U('cloakroom'), Type = "cloakroom", - Hint = "Appuyez sur ~INPUT_PICKUP~ pour vous changer." + Hint = _U('cloak_change'), }, AliveChicken = { @@ -29,11 +29,11 @@ Config.Jobs.slaughterer = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = "Poulailler", + Name = _U('s_hen'), Type = "work", Item = { { - name = "Poulet vivant", + name = _U('s_alive_chicken'), db_name= "alive_chicken", time = 3000, max = 20, @@ -44,7 +44,7 @@ Config.Jobs.slaughterer = { drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour attrapper des poulets vivants." + Hint = _U('s_catch_hen') }, SlaughterHouse = { @@ -53,22 +53,22 @@ Config.Jobs.slaughterer = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = false, - Name = "Abattoir", + Name = _U('s_slaughtered'), Type = "work", Item = { { - name = "Poulet à conditionner", + name = _U('s_slaughtered_chicken'), db_name= "slaughtered_chicken", time = 5000, max = 20, add = 1, remove = 1, requires = "alive_chicken", - requires_name = "Poulet vivant", + requires_name = _U('s_alive_chicken'), drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour dépecer les poulets." + Hint = _U('s_chop_animal') }, Packaging = { @@ -77,22 +77,22 @@ Config.Jobs.slaughterer = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = false, - Name = "Emballage", + Name = _U('s_package'), Type = "work", - Item = { + Item = { { - name = "Poulet en barquette", + name = _U('s_packagechicken'), db_name= "packaged_chicken", time = 4000, max = 100, add = 5, remove = 1, requires = "slaughtered_chicken", - requires_name = "Poulet à conditionner", + requires_name = _U('s_unpackaged'), drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour conditionner le poulet en barquette." + Hint = _U('s_unpackaged_button') }, VehicleSpawner = { @@ -101,10 +101,10 @@ Config.Jobs.slaughterer = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = false, - Name = "Spawner véhicule de fonction", + Name = _U('spawn_veh'), Type = "vehspawner", Spawner = 1, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour appeler le véhicule de livraison.", + Hint = _U('spawn_veh_button'), Caution = 2000 }, @@ -113,21 +113,21 @@ Config.Jobs.slaughterer = { Size = {x = 3.0, y = 3.0, z = 1.0}, Marker= -1, Blip = false, - Name = "Véhicule de fonction", + Name = _U('service_vh'), Type = "vehspawnpt", Spawner = 1, Heading = 130.1 }, - + VehicleDeletePoint = { Pos = {x = -1061.5164794922, y = -2008.3552246094, z = 12.161584854126}, Size = {x = 5.0, y = 5.0, z = 1.0}, Color = {r = 255, g = 0, b = 0}, Marker= 1, Blip = false, - Name = "Supression du véhicule", + Name = _U('return_vh'), Type = "vehdelete", - Hint = "Appuyez sur ~INPUT_PICKUP~ pour rendre le véhicule.", + Hint = _U('return_vh_button'), Spawner = 1, Caution = 2000, GPS = 0, @@ -140,22 +140,22 @@ Config.Jobs.slaughterer = { Size = {x = 5.0, y = 5.0, z = 1.0}, Marker= 1, Blip = true, - Name = "Point de livraison", - Type = "delivery", + Name = _U('delivery_point'), + Type = "delivery", Spawner = 1, Item = { { - name = "Livraison", + name = _U('delivery'), time = 500, remove = 1, max = 100, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 11, requires = "packaged_chicken", - requires_name = "Poulet en barquette", + requires_name = _U('s_packagechicken'), drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour livrer les barquettes de poulet." + Hint = _U('s_deliver') } } -} \ No newline at end of file +} diff --git a/jobs/textil.lua b/jobs/textil.lua index affcae2b..f12e6d9a 100644 --- a/jobs/textil.lua +++ b/jobs/textil.lua @@ -18,9 +18,9 @@ Config.Jobs.textil = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = "Vestiaire", + Name = _U('cloakroom'), Type = "cloakroom", - Hint = "Appuyez sur ~INPUT_PICKUP~ pour vous changer.", + Hint = _U('cloak_change'), GPS = {x = 740.808776855469, y = -970.066650390625, z = 23.4693908691406} }, @@ -30,11 +30,11 @@ Config.Jobs.textil = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = "Laine", + Name = _U('dd_wool'), Type = "work", Item = { { - name = "Laine", + name = _U('dd_wool'), db_name= "whool", time = 3000, max = 40, @@ -45,7 +45,7 @@ Config.Jobs.textil = { drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour récupérer de la laine.", + Hint = _U('dd_pickup'), GPS = {x = 715.954650878906, y = -959.639587402344, z = 29.3953247070313} }, @@ -55,22 +55,22 @@ Config.Jobs.textil = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = false, - Name = "Tissu", + Name = _U('dd_fabric'), Type = "work", Item = { { - name = "Tissu", + name = _U('dd_fabric'), db_name= "fabric", time = 5000, max = 80, add = 2, remove = 1, requires = "whool", - requires_name = "Laine", + requires_name = _U('dd_wool'), drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour fabriquer du tissu.", + Hint = _U('dd_makefabric'), GPS = {x = 712.928283691406, y = -970.5869140625, z = 29.3953247070313} }, @@ -80,22 +80,22 @@ Config.Jobs.textil = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = false, - Name = "Vêtement", + Name = _U('dd_clothing'), Type = "work", Item = { { - name = "Vêtement", + name = _U('dd_clothing'), db_name= "clothe", time = 4000, max = 40, add = 1, remove = 2, - requires = "fabric", + requires = _U('dd_fabric'), requires_name = "Tissu", drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour récupérer des vêtements.", + Hint = _U('dd_makeclothing'), GPS = {x = 429.595855712891, y = -807.341613769531, z = 28.4911441802979} }, @@ -105,10 +105,10 @@ Config.Jobs.textil = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = false, - Name = "Spawner véhicule de fonction", + Name = _U('spawn_veh'), Type = "vehspawner", Spawner = 1, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour appeler le véhicule de livraison.", + Hint = _U('spawn_veh_button'), Caution = 2000, GPS = {x = 1978.92407226563, y = 5171.70166015625, z = 46.6391181945801} }, @@ -118,22 +118,22 @@ Config.Jobs.textil = { Size = {x = 3.0, y = 3.0, z = 1.0}, Marker= -1, Blip = false, - Name = "Véhicule de fonction", + Name = _U('service_vh'), Type = "vehspawnpt", Spawner = 1, Heading = 270.1, GPS = 0 }, - + VehicleDeletePoint = { Pos = {x = 693.796325683594, y = -963.010498046875, z = 22.8247337341309}, Size = {x = 3.0, y = 3.0, z = 1.0}, Color = {r = 255, g = 0, b = 0}, Marker= 1, Blip = false, - Name = "Supression du véhicule", + Name = _U('return_vh'), Type = "vehdelete", - Hint = "Appuyez sur ~INPUT_PICKUP~ pour rendre le véhicule.", + Hint = _U('return_vh_button'), Spawner = 1, Caution = 2000, GPS = 0, @@ -146,23 +146,23 @@ Config.Jobs.textil = { Size = {x = 5.0, y = 5.0, z = 3.0}, Marker= 1, Blip = true, - Name = "Point de livraison", - Type = "delivery", + Name = _U('delivery_point'), + Type = "delivery", Spawner = 1, - Item = { + Item = { { - name = "Livraison", + name = _U('delivery'), time = 500, remove = 1, max = 100, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 40, requires = "clothe", - requires_name = "Vêtement", + requires_name = _U('dd_clothing') drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour livrer les vêtements.", + Hint = _U('dd_deliver_clothes'), GPS = {x = 1978.92407226563, y = 5171.70166015625, z = 46.6391181945801} } } -} \ No newline at end of file +} diff --git a/locales/en.lua b/locales/en.lua index 04403eb9..add423f5 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,5 +1,7 @@ Locales['en'] = { --Global menus + ['cloakroom'] = 'Locker Room', + ['cloak_change'] = 'Press ~INPUT_PICKUP~ to change clothes.', ['bank_deposit'] = 'a security deposit of ~g~', ['bank_deposit_r'] = 'a security deposit of ~g~$', ['bank_deposit2'] = '$ ~s~was made to you after your fainting.', @@ -15,25 +17,80 @@ Locales['en'] = { ['not_enough2'] = ' to continue this task.', ['caution_taken'] = ' ~s~was taken from you.', ['caution_returned'] = ' ~s~was returned to you.', + ['spawn_veh'] = 'spawn vehicle', + ['spawn_veh_button'] = 'press ~INPUT_PICKUP~ to call the delivery vehicle.', + ['service_vh'] = 'service vehicle', + ['return_vh'] = 'vehicle return', + ['return_vh_button'] = 'press ~INPUT_PICKUP~ to return the vehicle.', + ['delivery_point'] = 'delivery point', + ['delivery'] = 'delivery', --Lumber Jack job - ['lj_cr_title'] = 'cloakroom', - ['lj_cloakroom'] = 'press ~INPUT_PICKUP~ to change clothes.', - ['lj_mapblip'] = 'wood pile', + ['lj_mapblip'] = 'Wood pile', ['lj_wood'] = 'wood', ['lj_pickup'] = 'press ~INPUT_PICKUP~ to retrieve wood.', - ['lj_cutwood'] = 'cutting wood', + ['lj_cutwood'] = 'Wood cutting', ['lj_cutwood_button'] = 'press ~INPUT_PICKUP~ to cut wood.', ['lj_board'] = 'boards', - ['lj_planks'] = 'board package', - ['lj_delivery'] = 'delivery', - ['lj_cutwood'] = 'wood cut', + ['lj_planks'] = 'package board', + ['lj_cutwood'] = 'cut wood', ['lj_pick_boards'] = 'press ~INPUT_PICKUP~ to retrieve boards.', - ['lj_spawn_veh'] = 'spawn vehicle', - ['lj_spawn_veh_button'] = 'press ~INPUT_PICKUP~ to call the delivery vehicle.', - ['lj_service_vh'] = 'service vehicle', - ['lj_return_vh'] = 'return vehicle', - ['lj_delivery_point'] = 'delivery point', - ['lj_return_vh_button'] = 'press ~INPUT_PICKUP~ to return the vehicle.', - ['lj_deliver_button'] = 'press ~INPUT_PICKUP~ to deliver the boards.' -} + ['lj_deliver_button'] = 'press ~INPUT_PICKUP~ to deliver the boards.', + + --fisherman + ['fm_fish'] = 'fish', + ['fm_fish_area'] = 'fishing area', + ['fm_fish_button'] = 'press ~INPUT_PICKUP~ to fish.', + ['fm_spawnboat_title'] = 'spawn boat', + ['fm_spawnboat'] = 'press ~INPUT_PICKUP~ to call the boat.', + ['fm_boat_title'] = 'boat', + ['fm_boat_return_title'] = 'boat return', + ['fm_boat_return_button'] = 'Press ~INPUT_PICKUP~ to return the boat.', + ['fm_deliver_fish'] = 'press ~INPUT_PICKUP~ to deliver the fish.', + + --miner + ['m_rock'] = 'rock', + ['m_pickrocks'] = 'press ~INPUT_PICKUP~ to retrieve rocks.', + ['m_washrock'] = 'rock washed', + ['m_rock_button'] = 'press ~INPUT_PICKUP~ to wash the rocks.', + ['m_rock_smelting'] = 'smelthing', + ['m_copper'] = 'copper', + ['m_sell_copper'] = 'sell copper', + ['m_deliver_copper'] = 'Press ~INPUT_PICKUP~ to deliver the copper.', + ['m_iron'] = 'Fer', + ['m_sell_iron'] = 'sell iron', + ['m_deliver_iron'] = 'press ~INPUT_PICKUP~ to deliver the iron.', + ['m_gold'] = 'gold', + ['m_sell_gold'] = "sell gold", + ['m_deliver_gold'] = "press ~INPUT_PICKUP~ to deliver the gold.", + ['m_diamond'] = 'diamond', + ['m_sell_diamond'] = "sell diamond", + ['m_deliver_diamond'] = 'press ~INPUT_PICKUP~ to deliver the diamonds.', + ['m_melt_button'] = 'press ~INPUT_PICKUP~ to melt the rocks.', + + --reporter + ['reporter_name'] = 'san Andreas Times', + ['reporter_garage'] = 'Press ~INPUT_PICKUP~ to go down to the garage.', + + --slaughterer + ['s_hen'] = 'chicken coop', + ['s_alive_chicken'] = 'live Chicken', + ['s_catch_hen'] = 'press ~INPUT_PICKUP~ to catch live chickens.', + ['s_slaughtered_chicken'] = 'chicken to be packed', + ['s_chop_animal'] = 'press ~INPUT_PICKUP~ to chop the chickens.', + ['s_slaughtered'] = 'slaughter house', + ['s_package'] = 'packaging', + ['s_packagechicken'] = 'chicken in tray', + ['s_unpackaged'] = 'chicken to be packed', + ['s_unpackaged_button'] = 'press ~INPUT_PICKUP~ to set the chicken in a tray.', + ['s_deliver'] = 'press ~INPUT_PICKUP~ to deliver the chicken trays.', + + --Dress Designer + ['dd_wool'] = 'wool', + ['dd_pickup'] = 'Press ~INPUT_PICKUP~ to retrieve wool.', + ['dd_fabric'] = 'fabric', + ['dd_makefabric'] = 'Press ~INPUT_PICKUP~ to make fabric.', + ['dd_clothing'] = 'clothing', + ['dd_makeclothing'] = 'press ~INPUT_PICKUP~ to retrieve clothing.', + ['dd_deliver_clothes'] = 'press ~INPUT_PICKUP~ to deliver the clothes.', + } diff --git a/locales/fr.lua b/locales/fr.lua index 3bbe4dcb..d2cc73b1 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,5 +1,7 @@ Locales['fr'] = { --Global menus + ['cloakroom'] = 'vestiaire', + ['cloak_change'] = 'appuyez sur ~INPUT_PICKUP~ pour vous changer.', ['bank_deposit'] = 'une caution de ~g~', ['bank_deposit_r'] = 'une caution de ~g~$', ['bank_deposit2'] = '$ ~s~vous a été rendue suite à votre évanouissment.', @@ -15,10 +17,15 @@ Locales['fr'] = { ['not_enough2'] = ' pour continuer cette tâche.', ['caution_taken'] = ' ~s~vous a été prélevée.', ['caution_returned'] = ' ~s~vous a été rendue.', + ['spawn_veh'] = 'spawner véhicule de fonction', + ['spawn_veh_button'] = 'appuyez sur ~INPUT_PICKUP~ pour appeler le véhicule de livraison.', + ['service_vh'] = 'véhicule de fonction', + ['return_vh'] = 'supression du véhicule', + ['return_vh_button'] = 'appuyez sur ~INPUT_PICKUP~ pour rendre le véhicule.', + ['delivery_point'] = 'point de livraison', + ['delivery'] = 'livraison', --Lumber Jack job - ['lj_cr_title'] = 'vestiaire', - ['lj_cloakroom'] = 'appuyez sur ~INPUT_PICKUP~ pour vous changer.', ['lj_mapblip'] = 'tas de bois', ['lj_wood'] = 'bois', ['lj_pickup'] = 'appuyez sur ~INPUT_PICKUP~ pour récupérer du bois.', @@ -26,14 +33,64 @@ Locales['fr'] = { ['lj_cutwood_button'] = 'appuyez sur ~INPUT_PICKUP~ pour couper du bois.', ['lj_board'] = 'planches', ['lj_planks'] = 'paquet de planche', - ['lj_delivery'] = 'livraison', ['lj_cutwood'] = 'bois coupé', ['lj_pick_boards'] = 'appuyez sur ~INPUT_PICKUP~ pour récupérer des planches.', - ['lj_spawn_veh'] = 'spawner véhicule de fonction', - ['lj_spawn_veh_button'] = 'appuyez sur ~INPUT_PICKUP~ pour appeler le véhicule de livraison.', - ['lj_service_vh'] = 'véhicule de fonction', - ['lj_return_vh'] = 'supression du véhicule', - ['lj_delivery_point'] = 'Point de livraison', - ['lj_return_vh_button'] = 'appuyez sur ~INPUT_PICKUP~ pour rendre le véhicule.', - ['lj_deliver_button'] = 'appuyez sur ~INPUT_PICKUP~ pour livrer les planches.' + ['lj_deliver_button'] = 'appuyez sur ~INPUT_PICKUP~ pour livrer les planches.', + + --fisherman + ['fm_fish'] = 'poisson', + ['fm_fish_area'] = 'zone de pêche', + ['fm_fish_button'] = 'appuyez sur ~INPUT_PICKUP~ pour pêcher.', + ['fm_spawnboat_title'] = 'spawner bateau', + ['fm_spawnboat'] = 'appuyez sur ~INPUT_PICKUP~ pour appeler le bateau.', + ['fm_boat_title'] = 'bateau', + ['fm_boat_return_title'] = 'supression du bateau', + ['fm_boat_return_button'] = 'appuyez sur ~INPUT_PICKUP~ pour rendre le bateau.', + ['fm_deliver_fish'] = 'Appuyez sur ~INPUT_PICKUP~ pour livrer le poisson.', + + --miner + ['m_rock'] = 'Rocher', + ['m_pickrocks'] = 'Appuyez sur ~INPUT_PICKUP~ pour récupérer des rochers.', + ['m_washrock'] = 'Roche lavé', + ['m_rock_button'] = 'Appuyez sur ~INPUT_PICKUP~ pour laver les roches.', + ['m_rock_smelting'] = 'Fonderie', + ['m_copper'] = 'cuivre', + ['m_sell_copper'] = 'Revente de cuivre', + ['m_deliver_copper'] = 'Appuyez sur ~INPUT_PICKUP~ pour livrer le cuivre.', + ['m_iron'] = 'Fer', + ['m_sell_iron'] = 'Revente de fer', + ['m_deliver_iron'] = 'Appuyez sur ~INPUT_PICKUP~ pour livrer le fer.', + ['m_gold'] = 'Or', + ['m_sell_gold'] = "Revente d'or", + ['m_deliver_gold'] = "Appuyez sur ~INPUT_PICKUP~ pour livrer l'or'.", + ['m_diamond'] = 'Diamant', + ['m_sell_diamond'] = "Revente de diamants", + ['m_deliver_diamond'] = 'Appuyez sur ~INPUT_PICKUP~ pour livrer les diamants.', + ['m_melt_button'] = 'Appuyez sur ~INPUT_PICKUP~ pour fondre les roches.', + + --reporter + ['reporter_name'] = 'Le Maclerait Libéré', + ['reporter_garage'] = 'Appuyez sur ~INPUT_PICKUP~ pour descendre au garage.', + + --slaughterer + ['s_hen'] = 'Poulailler', + ['s_alive_chicken'] = 'Poulet vivant', + ['s_catch_hen'] = 'Appuyez sur ~INPUT_PICKUP~ pour attrapper des poulets vivants.', + ['s_slaughtered_chicken'] = 'Poulet à conditionner', + ['s_chop_animal'] = 'Appuyez sur ~INPUT_PICKUP~ pour dépecer les poulets.', + ['s_slaughtered'] = 'Abattoir', + ['s_package'] = 'Emballage', + ['s_packagechicken'] = 'Poulet en barquette', + ['s_unpackaged'] = 'Poulet à conditionner', + ['s_unpackaged_button'] = 'Appuyez sur ~INPUT_PICKUP~ pour conditionner le poulet en barquette.', + ['s_deliver'] = 'Appuyez sur ~INPUT_PICKUP~ pour livrer les barquettes de poulet.', + + --Dress Designer + ['dd_wool'] = 'Laine', + ['dd_pickup'] = 'Appuyez sur ~INPUT_PICKUP~ pour récupérer de la laine.', + ['dd_fabric'] = 'Tissu', + ['dd_makefabric'] = 'Appuyez sur ~INPUT_PICKUP~ pour fabriquer du tissu.', + ['dd_clothing'] = 'Vêtement', + ['dd_makeclothing'] = 'Appuyez sur ~INPUT_PICKUP~ pour récupérer des vêtements.', + ['dd_deliver_clothes'] = 'Appuyez sur ~INPUT_PICKUP~ pour livrer les vêtements.', } From 6f44b050e79307425cb0c8f7bd93e781af4055cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 20 Aug 2017 13:03:43 +0200 Subject: [PATCH 0492/3224] Add automatic rent function every 24 hours --- server/main.lua | 75 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 2c31860c..e827d0b8 100644 --- a/server/main.lua +++ b/server/main.lua @@ -416,4 +416,77 @@ if Config.EnablePvCommand then TriggerClientEvent('esx_vehicleshop:openPersonnalVehicleMenu', source) end, {help = 'Sortir un véhicule personnel'}) -end \ No newline at end of file +end + +function PayRent(d, h, m) + + MySQL.Async.fetchAll( + 'SELECT * FROM users', + {}, + function(_users) + + local prevMoney = {} + local newMoney = {} + + for i=1, #_users, 1 do + prevMoney[_users[i].identifier] = _users[i].money + newMoney[_users[i].identifier] = _users[i].money + end + + MySQL.Async.fetchAll( + 'SELECT * FROM rented_vehicles', + {}, + function(result) + + local xPlayers = ESX.GetPlayers() + + for i=1, #result, 1 do + + local foundPlayer = false + local xPlayer = nil + + for k,v in pairs(xPlayers) do + if v.identifier == result[i].owner then + foundPlayer = true + xPlayer = v + end + end + + if foundPlayer then + + xPlayer.removeMoney(result[i].rent_price) + TriggerClientEvent('esx:showNotification', xPlayer.source, 'Vous avez ~g~payé~s~ votre location de véhicule : ~g~$' .. result[i].rent_price) + + else + newMoney[result[i].owner] = newMoney[result[i].owner] - result[i].rent_price + end + + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_cardealer', function(account) + account.addMoney(result[i].rent_price) + end) + + end + + for k,v in pairs(prevMoney) do + if v ~= newMoney[k] then + + MySQL.Async.execute( + 'UPDATE users SET money = @money WHERE identifier = @identifier', + { + ['@money'] = newMoney[k], + ['@identifier'] = k + } + ) + + end + end + + end + ) + + end + ) + +end + +TriggerEvent('cron:runAt', 22, 00, PayRent) From 7c91651df417d7b3b9843f86e77844d2dc6f9159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 20 Aug 2017 13:15:31 +0200 Subject: [PATCH 0493/3224] Fix PayRent --- server/main.lua | 85 ++++++++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 36 deletions(-) diff --git a/server/main.lua b/server/main.lua index 8652a2c3..c8ff535d 100644 --- a/server/main.lua +++ b/server/main.lua @@ -499,58 +499,68 @@ end) function PayRent(d, h, m) MySQL.Async.fetchAll( - 'SELECT * FROM owned_properties WHERE rented = 1', + 'SELECT * FROM users', {}, - function(result) + function(_users) - local xPlayers = ESX.GetPlayers() + local prevMoney = {} + local newMoney = {} - for i=1, #result, 1 do + for i=1, #_users, 1 do + prevMoney[_users[i].identifier] = _users[i].money + newMoney[_users[i].identifier] = _users[i].money + end - local foundPlayer = false - local xPlayer = nil + MySQL.Async.fetchAll( + 'SELECT * FROM owned_properties WHERE rented = 1', + {}, + function(result) + + local xPlayers = ESX.GetPlayers() + + for i=1, #result, 1 do + + local foundPlayer = false + local xPlayer = nil + + for k,v in pairs(xPlayers) do + if v.identifier == result[i].owner then + foundPlayer = true + xPlayer = v + end + end + + if foundPlayer then + + xPlayer.removeMoney(result[i].price) + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('paid_rent') .. result[i].price) + + else + newMoney[result[i].owner] = newMoney[result[i].owner] - result[i].price + end + + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_realestateagent', function(account) + account.addMoney(result[i].price) + end) - for k,v in pairs(xPlayers) do - if v.identifier == result[i].owner then - foundPlayer = true - xPlayer = v end - end - if foundPlayer then - - xPlayer.removeMoney(result[i].price) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('paid_rent') .. result[i].price) - - else - - MySQL.Async.fetchAll( - 'SELECT * FROM users WHERE identifier = @identifier', - { - ['@identifier'] = result[i].owner - }, - function(result2) - - local money = result2[1].money - money = money - result[i].price + for k,v in pairs(prevMoney) do + if v ~= newMoney[k] then MySQL.Async.execute( 'UPDATE users SET money = @money WHERE identifier = @identifier', { - ['@money'] = money, - ['@identifier'] = result[i].owner + ['@money'] = newMoney[k], + ['@identifier'] = k } ) + end - ) + end end - - TriggerEvent('esx_addonaccount:getSharedAccount', 'society_realestateagent', function(account) - account.addMoney(result[i].price) - end) - - end + ) end ) @@ -558,3 +568,6 @@ function PayRent(d, h, m) end TriggerEvent('cron:runAt', 22, 0, PayRent) + + +AddEventHandler('onMySQLReady', PayRent) \ No newline at end of file From 43626c1576e355970ad7247acdeeef3d67c520c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 20 Aug 2017 13:24:12 +0200 Subject: [PATCH 0494/3224] Remove dev function --- server/main.lua | 3 --- 1 file changed, 3 deletions(-) diff --git a/server/main.lua b/server/main.lua index c8ff535d..b7f1d9fe 100644 --- a/server/main.lua +++ b/server/main.lua @@ -568,6 +568,3 @@ function PayRent(d, h, m) end TriggerEvent('cron:runAt', 22, 0, PayRent) - - -AddEventHandler('onMySQLReady', PayRent) \ No newline at end of file From fdad0691cd05dc40eac9b79e137e8924d77fb194 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 20 Aug 2017 13:31:20 +0200 Subject: [PATCH 0495/3224] Add /respawn command --- server/main.lua | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 923cc28b..7b9b4870 100644 --- a/server/main.lua +++ b/server/main.lua @@ -48,5 +48,17 @@ TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message end end end - + end) + +TriggerEvent('es:addGroupCommand', 'respawn', 'admin', function(source, args, user) + + if args[2] ~= nil then + TriggerClientEvent('esx_ambulancejob:revive', tonumber(args[2])) + else + TriggerClientEvent('esx_ambulancejob:revive', source) + end + +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end, {help = 'Respawn', params = {{name = 'id'}}}) \ No newline at end of file From 5f7188b760ecc8f963427e952a80a5a4e012d592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 20 Aug 2017 19:43:59 +0200 Subject: [PATCH 0496/3224] Fix hacky methods --- resources/[essential]/es_extended/client/functions.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 61580780..1ae278af 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -1195,8 +1195,8 @@ ESX.ShowInventory = function() end RegisterNetEvent('esx:serverCallback') -AddEventHandler('esx:serverCallback', function(requestId, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z) - ESX.ServerCallbacks[requestId](a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z) +AddEventHandler('esx:serverCallback', function(requestId, ...) + ESX.ServerCallbacks[requestId](...) ESX.ServerCallbacks[requestId] = nil end) From 9edebd8776e74ef4b8f1e6719215a64446472721 Mon Sep 17 00:00:00 2001 From: Pgmbru Date: Sun, 20 Aug 2017 21:04:26 +0200 Subject: [PATCH 0497/3224] esx_drugs_cl.lua FIX by Pgmbru Changement du pochonQuantity vers poochQuantity Changement du meth_pochon vers meth_pooch --- server/esx_drugs_sv.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/server/esx_drugs_sv.lua b/server/esx_drugs_sv.lua index 00417a88..82de1a90 100644 --- a/server/esx_drugs_sv.lua +++ b/server/esx_drugs_sv.lua @@ -261,15 +261,15 @@ local function TransformMeth(source) local xPlayer = ESX.GetPlayerFromId(source) local methQuantity = xPlayer.getInventoryItem('meth').count - local pochonQuantity = xPlayer.getInventoryItem('meth_pooch').count + local poochQuantity = xPlayer.getInventoryItem('meth_pooch').count - if pochonQuantity > 35 then + if poochQuantity > 35 then TriggerClientEvent('esx:showNotification', source, _U('too_many_pouches')) elseif methQuantity < 5 then TriggerClientEvent('esx:showNotification', source, _U('not_enough_meth')) else xPlayer.removeInventoryItem('meth', 5) - xPlayer.addInventoryItem('meth_pochon', 1) + xPlayer.addInventoryItem('meth_pooch', 1) TransformMeth(source) end @@ -313,12 +313,12 @@ local function SellMeth(source) local xPlayer = ESX.GetPlayerFromId(source) - local pochonQuantity = xPlayer.getInventoryItem('meth_pooch').count + local poochQuantity = xPlayer.getInventoryItem('meth_pooch').count - if pochonQuantity == 0 then + if poochQuantity == 0 then TriggerClientEvent('esx:showNotification', source, _U('no_pouches_sale')) else - xPlayer.removeInventoryItem('meth_pochon', 1) + xPlayer.removeInventoryItem('meth_pooch', 1) if CopsConnected == 0 then xPlayer.addAccountMoney('black_money', 276) TriggerClientEvent('esx:showNotification', source, _U('sold_one_meth')) From 34853e0ea8815064890c451e9dec4204c9c22742 Mon Sep 17 00:00:00 2001 From: Pgmbru Date: Sun, 20 Aug 2017 21:08:17 +0200 Subject: [PATCH 0498/3224] esx_drugs_cl.lua FIX by Pgmbru Changement du ('esx_drugs:startSellCoke') vers ('esx_drugs:startSellMeth') --- client/esx_drugs_cl.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/esx_drugs_cl.lua b/client/esx_drugs_cl.lua index 001da77a..ae97c58c 100644 --- a/client/esx_drugs_cl.lua +++ b/client/esx_drugs_cl.lua @@ -255,7 +255,7 @@ Citizen.CreateThread(function() TriggerServerEvent('esx_drugs:startTransformMeth') end if CurrentAction == 'meth_resell' then - TriggerServerEvent('esx_drugs:startSellCoke') + TriggerServerEvent('esx_drugs:startSellMeth') end if CurrentAction == 'weed_harvest' then TriggerServerEvent('esx_drugs:startHarvestWeed') From 932abda6e148e5b9edcaa4f5c6cd7813d601a05b Mon Sep 17 00:00:00 2001 From: nearbyplayer <3721216+nearbyplayer@users.noreply.github.com> Date: Sun, 20 Aug 2017 15:48:26 -0400 Subject: [PATCH 0499/3224] Update config.lua Changed default language back to fr --- config.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.lua b/config.lua index 392a3499..89682111 100644 --- a/config.lua +++ b/config.lua @@ -1,6 +1,6 @@ Config = {} Config.DrawDistance = 1000.0 -Config.Locale = 'en' +Config.Locale = 'fr' Config.Plates = { taxi = "TAXI", From 2bdf2f16049d5e7a0f209e398d6e71041da0ab75 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Sun, 20 Aug 2017 21:23:40 -0400 Subject: [PATCH 0500/3224] Update English HTML UI --- __resource.lua | 6 ++---- html/ui_en.html | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/__resource.lua b/__resource.lua index 226a9dc4..4f737ba0 100644 --- a/__resource.lua +++ b/__resource.lua @@ -22,14 +22,12 @@ client_scripts { ui_page 'html/ui.html' files { - 'html/ui.html', -- FR - --'html/ui_en.html', -- EN + 'html/ui.html', 'html/bankgothic.ttf', 'html/pdown.ttf', 'html/css/app.css', 'html/scripts/mustache.min.js', - 'html/scripts/app.js', -- FR - --'html/scripts/app_en.js', -- EN + 'html/scripts/app.js', 'html/img/cursor.png', 'html/img/keys/enter.png', 'html/img/keys/return.png', diff --git a/html/ui_en.html b/html/ui_en.html index cac0462b..b5227c83 100644 --- a/html/ui_en.html +++ b/html/ui_en.html @@ -17,14 +17,14 @@
    + +
    +
    Dodaj kontakt
    +
    +
    + + + + +
    +
    +
    + + + + + + + + + + + diff --git a/locales/pl.lua b/locales/pl.lua new file mode 100644 index 00000000..c658c8be --- /dev/null +++ b/locales/pl.lua @@ -0,0 +1,13 @@ +Locales['en'] = { + ['new_message'] = '~b~Masz nową wiadomość:~s~ %s', + ['press_take_call'] = '%s - Wciśnij ~INPUT_CONTEXT~ aby odebrać telefon', + ['taken_call'] = '~y~%s~s~ odebrał telefon', + ['gps_position'] = 'Cel podróży został dodany do GPS\'a', + ['message_sent'] = 'Wiadomość wysłana', + ['cannot_add_self'] = 'Nie możesz dodać samego siebie!', + ['number_in_contacts'] = 'Ten numer jest już na twojej liście kontaktów', + ['contact_added'] = 'Kontakt dodany!', + ['contact_removed'] = 'Kontakt usunięty!', + ['number_not_assigned'] = 'Numer nie jest przypisany!', + ['invalid_number'] = 'To nie jest prawidłowy numer telefonu!', +} \ No newline at end of file From bafce42446dfb9102bb58cda0c3d130820bb2631 Mon Sep 17 00:00:00 2001 From: deviljin112 <39461646+deviljin112@users.noreply.github.com> Date: Mon, 23 Jul 2018 17:48:56 +0100 Subject: [PATCH 1607/3224] Update pl.lua lower case change --- locales/pl.lua | 122 ++++++++++++++++++++++++------------------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/locales/pl.lua b/locales/pl.lua index 91ff39de..5d436141 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -1,64 +1,64 @@ Locales['pl'] = { -- Menu Salonu - ['not_enough_in_society'] = 'Brak tego ~r~przedmiotu~s~ w firmie!', - ['player_cannot_hold'] = '~r~Nie masz~s~ wystarczająco ~y~wolnego~s~ miejsca w ekwipunku!', - ['vehicle_belongs'] = 'Pojazd z rejestracją ~y~%s~s~ teraz należy do ~b~ciebie~s~', - ['bleach amount'] = 'Ilosc do wyprania', - ['broke_company'] = 'Twoja firma nie ma wystarczająco pieniedzy', - ['purchase_type'] = 'Rodzaj zakupu', - ['society_type'] = 'Firma', - ['staff_type'] = 'Pracownicy', - ['buy_vehicle_shop'] = 'Czy chcesz kupić %s za $%s?', - ['buy_vehicle'] = 'Kup pojazd', - ['car_dealer'] = 'Sprzedawca Aut', - ['create_bill'] = 'Stwórz fakture', - ['dealer_boss'] = 'Salon samochodowy - Szef', - ['delivered'] = 'Pojazd został ~g~dostarczony~s~ do salonu', - ['depop_vehicle'] = 'Oddaj pojazd', - ['deposit_amount'] = 'Deponuj ilość', - ['deposit_money'] = 'Deponuj pieniądze', - ['experianced'] = 'Doświadczony', - ['get_rented_vehicles'] = 'Pojazdy do wynajęcia', - ['invalid_amount'] = 'Nieprawidłowa ilość', - ['invoice_amount'] = 'Suma faktury', - ['leaving'] = 'Zostawiasz swój prywatny samochód', - ['no'] = 'Nie', - ['no_players'] = 'Brak graczy w pobliżu', - ['not_enough_money'] = 'Nie masz wystarczająco pieniędzy', - ['not_rental'] = 'To nie jest ~r~wypożyczone auto~s~', - ['not_yours'] = 'Ten pojazd nie należy do ciebie', - ['paid_rental'] = '~g~Zapłaciłeś/aś~s~ za wynajęcie auta: ~g~$%s~s~', - ['personal_vehicle'] = 'Prywatne auto', - ['pop_vehicle'] = 'Wyciągnij auto do sprzedaży', - ['recruit'] = 'Zatrudnij', - ['rent_vehicle'] = 'Salon samochodowy - Pojazdy do wynajęcia', - ['rental_amount'] = 'Suma wynajęcia', - ['sell_menu'] = 'Wcisnij ~INPUT_CONTEXT~ aby sprzedać ~y~%s~s~ za ~g~$%s~s~', - ['set_vehicle_owner_rent'] = 'Zarejestruj pojazd [Wynajem]', - ['set_vehicle_owner_sell'] = 'Zarejestruj pojazd [Kupno]', - ['set_vehicle_owner_sell_society'] = 'Zarejestruj pojazd [Firmowe]', - ['shop_menu'] = 'Wcisnij ~INPUT_CONTEXT~ aby wejść do menu', - ['the_boss'] = 'Szef', - ['vehicle_dealer'] = 'Pojazdy - Sprzedawca aut', - ['vehicle_menu'] = 'Wcisnij ~INPUT_CONTEXT~ aby wyjąć pojazd', - ['vehicle_purchased'] = 'Kupiłeś/aś pojazd', - ['vehicle_set_owned'] = 'Pojazd ~y~%s~s~ został zarejestrowany na ~b~%s~s~', - ['vehicle_set_rented'] = 'Pojazd ~y~%s~s~ został wynajęty przez ~b~%s~s~', - ['vehicle_sold'] = 'Pojazd został ~g~sprzedany~s~', - ['vehicle_sold_to'] = 'Pojazd ~y~%s~s~ został sprzedany do ~b~%s~s~', - ['wash_money'] = 'Pranie pieniędzy', - ['withdraw_amount'] = 'Suma do wyciągnięcia', - ['withdraw_money'] = 'Wyjmij pieniądze firmy', - ['yes'] = 'Tak', - ['deposit_stock'] = 'Deponuj przedmioty', - ['take_stock'] = 'Wyciągnij przedmioty', - ['dealership_stock'] = 'Zaopatrzenie salonu', - ['amount'] = 'Suma', - ['quantity_invalid'] = 'Nieprawidłowa ilość', - ['inventory'] = 'Ekwipunek', - ['dealership'] = 'Sprzedawca Aut', - ['dealer_customers'] = 'Klienci salonu', - ['have_withdrawn'] = 'Wyciągnałeś/aś ~y~x%s~s~ ~b~%s~s~', - ['have_deposited'] = 'Zdeponowałeś/aś ~y~x%s~s~ ~b~%s~s~', - ['boss_actions'] = 'Akcje szefa', + ['not_enough_in_society'] = 'brak tego ~r~przedmiotu~s~ w firmie!', + ['player_cannot_hold'] = '~r~nie masz~s~ wystarczająco ~y~wolnego~s~ miejsca w ekwipunku!', + ['vehicle_belongs'] = 'pojazd z rejestracją ~y~%s~s~ teraz należy do ~b~ciebie~s~', + ['bleach amount'] = 'ilosc do wyprania', + ['broke_company'] = 'twoja firma nie ma wystarczająco pieniedzy', + ['purchase_type'] = 'rodzaj zakupu', + ['society_type'] = 'firma', + ['staff_type'] = 'pracownicy', + ['buy_vehicle_shop'] = 'czy chcesz kupić %s za $%s?', + ['buy_vehicle'] = 'kup pojazd', + ['car_dealer'] = 'sprzedawca Aut', + ['create_bill'] = 'stwórz fakture', + ['dealer_boss'] = 'salon samochodowy - Szef', + ['delivered'] = 'pojazd został ~g~dostarczony~s~ do salonu', + ['depop_vehicle'] = 'oddaj pojazd', + ['deposit_amount'] = 'deponuj ilość', + ['deposit_money'] = 'deponuj pieniądze', + ['experianced'] = 'doświadczony', + ['get_rented_vehicles'] = 'pojazdy do wynajęcia', + ['invalid_amount'] = 'nieprawidłowa ilość', + ['invoice_amount'] = 'suma faktury', + ['leaving'] = 'zostawiasz swój prywatny samochód', + ['no'] = 'nie', + ['no_players'] = 'brak graczy w pobliżu', + ['not_enough_money'] = 'nie masz wystarczająco pieniędzy', + ['not_rental'] = 'to nie jest ~r~wypożyczone auto~s~', + ['not_yours'] = 'ten pojazd nie należy do ciebie', + ['paid_rental'] = '~g~zapłaciłeś/aś~s~ za wynajęcie auta: ~g~$%s~s~', + ['personal_vehicle'] = 'prywatne auto', + ['pop_vehicle'] = 'wyciągnij auto do sprzedaży', + ['recruit'] = 'zatrudnij', + ['rent_vehicle'] = 'salon samochodowy - Pojazdy do wynajęcia', + ['rental_amount'] = 'suma wynajęcia', + ['sell_menu'] = 'wcisnij ~INPUT_CONTEXT~ aby sprzedać ~y~%s~s~ za ~g~$%s~s~', + ['set_vehicle_owner_rent'] = 'zarejestruj pojazd [Wynajem]', + ['set_vehicle_owner_sell'] = 'zarejestruj pojazd [Kupno]', + ['set_vehicle_owner_sell_society'] = 'zarejestruj pojazd [Firmowe]', + ['shop_menu'] = 'wcisnij ~INPUT_CONTEXT~ aby wejść do menu', + ['the_boss'] = 'szef', + ['vehicle_dealer'] = 'pojazdy - Sprzedawca aut', + ['vehicle_menu'] = 'wcisnij ~INPUT_CONTEXT~ aby wyjąć pojazd', + ['vehicle_purchased'] = 'kupiłeś/aś pojazd', + ['vehicle_set_owned'] = 'pojazd ~y~%s~s~ został zarejestrowany na ~b~%s~s~', + ['vehicle_set_rented'] = 'pojazd ~y~%s~s~ został wynajęty przez ~b~%s~s~', + ['vehicle_sold'] = 'pojazd został ~g~sprzedany~s~', + ['vehicle_sold_to'] = 'pojazd ~y~%s~s~ został sprzedany do ~b~%s~s~', + ['wash_money'] = 'pranie pieniędzy', + ['withdraw_amount'] = 'suma do wyciągnięcia', + ['withdraw_money'] = 'wyjmij pieniądze firmy', + ['yes'] = 'tak', + ['deposit_stock'] = 'deponuj przedmioty', + ['take_stock'] = 'wyciągnij przedmioty', + ['dealership_stock'] = 'zaopatrzenie salonu', + ['amount'] = 'suma', + ['quantity_invalid'] = 'nieprawidłowa ilość', + ['inventory'] = 'ekwipunek', + ['dealership'] = 'sprzedawca Aut', + ['dealer_customers'] = 'klienci salonu', + ['have_withdrawn'] = 'wyciągnałeś/aś ~y~x%s~s~ ~b~%s~s~', + ['have_deposited'] = 'zdeponowałeś/aś ~y~x%s~s~ ~b~%s~s~', + ['boss_actions'] = 'akcje szefa', } From edb4df88b9a53ebe123712727d9980c429d84d31 Mon Sep 17 00:00:00 2001 From: deviljin112 <39461646+deviljin112@users.noreply.github.com> Date: Mon, 23 Jul 2018 18:03:52 +0100 Subject: [PATCH 1608/3224] Update pl.lua lower case change --- locales/pl.lua | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/locales/pl.lua b/locales/pl.lua index c658c8be..6e95c436 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -1,13 +1,13 @@ Locales['en'] = { - ['new_message'] = '~b~Masz nową wiadomość:~s~ %s', - ['press_take_call'] = '%s - Wciśnij ~INPUT_CONTEXT~ aby odebrać telefon', + ['new_message'] = '~b~masz nową wiadomość:~s~ %s', + ['press_take_call'] = '%s - wciśnij ~INPUT_CONTEXT~ aby odebrać telefon', ['taken_call'] = '~y~%s~s~ odebrał telefon', - ['gps_position'] = 'Cel podróży został dodany do GPS\'a', - ['message_sent'] = 'Wiadomość wysłana', - ['cannot_add_self'] = 'Nie możesz dodać samego siebie!', - ['number_in_contacts'] = 'Ten numer jest już na twojej liście kontaktów', - ['contact_added'] = 'Kontakt dodany!', - ['contact_removed'] = 'Kontakt usunięty!', - ['number_not_assigned'] = 'Numer nie jest przypisany!', - ['invalid_number'] = 'To nie jest prawidłowy numer telefonu!', -} \ No newline at end of file + ['gps_position'] = 'cel podróży został dodany do GPS\'a', + ['message_sent'] = 'wiadomość wysłana', + ['cannot_add_self'] = 'nie możesz dodać samego siebie!', + ['number_in_contacts'] = 'ten numer jest już na twojej liście kontaktów', + ['contact_added'] = 'kontakt dodany!', + ['contact_removed'] = 'kontakt usunięty!', + ['number_not_assigned'] = 'numer nie jest przypisany!', + ['invalid_number'] = 'to nie jest prawidłowy numer telefonu!', +} From b3a8b6ddb51a1c835534be7781fbadcd18c7ec1c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 23 Jul 2018 20:31:39 +0200 Subject: [PATCH 1609/3224] Fixed restarting resource without esx_service enabled --- client/main.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 6298ec26..9e7ebbce 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1992,7 +1992,10 @@ AddEventHandler('onResourceStop', function(resource) if resource == GetCurrentResourceName() then TriggerEvent('esx_policejob:unrestrain') TriggerEvent('esx_phone:removeSpecialContact', 'police') - TriggerServerEvent('esx_service:disableService', 'police') + + if Config.MaxInService ~= -1 then + TriggerServerEvent('esx_service:disableService', 'police') + end if Config.EnableHandcuffTimer and HandcuffTimer.Active then ESX.ClearTimeout(HandcuffTimer.Task) From d9c74a7dd0eeceff6b8c208e9636871c728762c9 Mon Sep 17 00:00:00 2001 From: deviljin112 <39461646+deviljin112@users.noreply.github.com> Date: Mon, 23 Jul 2018 19:32:55 +0100 Subject: [PATCH 1610/3224] Update pl.lua Fixed small error --- locales/pl.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/pl.lua b/locales/pl.lua index 6e95c436..ca85a4c2 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -1,4 +1,4 @@ -Locales['en'] = { +Locales['pl'] = { ['new_message'] = '~b~masz nową wiadomość:~s~ %s', ['press_take_call'] = '%s - wciśnij ~INPUT_CONTEXT~ aby odebrać telefon', ['taken_call'] = '~y~%s~s~ odebrał telefon', From 66e9021854545efa689554eed90f999f1cc572d4 Mon Sep 17 00:00:00 2001 From: deviljin112 <39461646+deviljin112@users.noreply.github.com> Date: Mon, 23 Jul 2018 21:41:06 +0100 Subject: [PATCH 1611/3224] Polish translation --- __resource.lua | 2 + locales/pl.lua | 85 +++++++++++++++++++++++++++++++ localization/esx_mecanojob_pl.sql | 30 +++++++++++ 3 files changed, 117 insertions(+) create mode 100644 locales/pl.lua create mode 100644 localization/esx_mecanojob_pl.sql diff --git a/__resource.lua b/__resource.lua index 636d536a..4e772a80 100644 --- a/__resource.lua +++ b/__resource.lua @@ -11,6 +11,7 @@ client_scripts { 'locales/fr.lua', 'locales/br.lua', 'locales/sv.lua', + 'locales/pl.lua', 'config.lua', 'client/main.lua' } @@ -22,6 +23,7 @@ server_scripts { 'locales/fr.lua', 'locales/br.lua', 'locales/sv.lua', + 'locales/pl.lua', 'config.lua', 'server/main.lua' } diff --git a/locales/pl.lua b/locales/pl.lua new file mode 100644 index 00000000..2454b9cc --- /dev/null +++ b/locales/pl.lua @@ -0,0 +1,85 @@ +Locales['pl'] = { + ['mechanic'] = 'mechanik', + ['drive_to_indicated'] = '~y~Jedz~s~ do wskazanej lokalizacji.', + ['mission_canceled'] = 'misja ~r~anulowana~s~', + ['vehicle_list'] = 'lista pojazdów', + ['work_wear'] = 'ubrania robocze', + ['civ_wear'] = 'ubrania cywilne', + ['deposit_stock'] = 'deponuj przedmioty', + ['withdraw_stock'] = 'wyciągnij przedmioty', + ['boss_actions'] = 'akcje szefa', + ['service_vehicle'] = 'serwisuj pojazd', + ['flat_bed'] = 'laweta', + ['tow_truck'] = 'holownik', + ['service_full'] = 'serwis pełny: ', + ['open_actions'] = 'wciśnij ~INPUT_CONTEXT~ aby otworzyć menu.', + ['harvest'] = 'zbieraj', + ['harvest_menu'] = 'wcisnij ~INPUT_CONTEXT~ aby otworzyć menu zbierania.', + ['not_experienced_enough'] = 'nie jesteś wystarczająco ~r~doświadczony~s~ aby zrobić tą akcję.', + ['gas_can'] = 'kanister z paliwem', + ['repair_tools'] = 'zestaw do naprawy', + ['body_work_tools'] = 'zestaw blacharski', + ['blowtorch'] = 'palnik', + ['repair_kit'] = 'narzedzia naprawcze', + ['body_kit'] = 'karoseria', + ['craft'] = 'twórz', + ['craft_menu'] = 'wcisnij ~INPUT_CONTEXT~ aby otworzyc menu tworzenia.', + ['billing'] = 'faktury', + ['hijack'] = 'forsowanie', + ['repair'] = 'naprawa', + ['clean'] = 'wyczyść', + ['imp_veh'] = 'odholowywanie', + ['place_objects'] = 'połóż objekt', + ['invoice_amount'] = 'suma faktury', + ['amount_invalid'] = 'nieprawidłowa suma', + ['no_players_nearby'] = 'brak gracza w pobliżu', + ['no_vehicle_nearby'] = 'brak pojazdu w pobliżu', + ['inside_vehicle'] = 'nie możesz tego zrobić z środka pojazdu!', + ['vehicle_unlocked'] = 'pojazd został ~g~odblokowany', + ['vehicle_repaired'] = 'pojazd został ~g~naprawiony', + ['vehicle_cleaned'] = 'pojazd został ~g~umyty', + ['vehicle_impounded'] = 'pojazd został ~r~odholowany', + ['must_seat_driver'] = 'musisz być na siedzeniu kierowcy!', + ['must_near'] = 'musisz być ~r~blisko pojazdu~s~ aby go odholować.', + ['vehicle_success_attached'] = 'pojazd ~b~przyłączony~s~', + ['please_drop_off'] = 'proszę odstawić pojazd w garażu', + ['cant_attach_own_tt'] = '~r~nie możesz~s~ podłączyć własnego holwnika', + ['no_veh_att'] = 'nie ma ~r~pojazdu~s~ do podłączenia', + ['not_right_veh'] = 'to nie jest prawidłowy pojazd', + ['veh_det_succ'] = 'pojazd ~b~odłączony~s~!', + ['imp_flatbed'] = '~r~Akcja niemożliwa!~s~ Potrzebujesz ~b~lawety~s~ aby załadować pojazd', + ['objects'] = 'objekty', + ['roadcone'] = 'pachołek', + ['toolbox'] = 'skrzynka z narzędziami', + ['mechanic_stock'] = 'magazyn mechanika', + ['quantity'] = 'ilość', + ['invalid_quantity'] = 'nieprawidłowa ilość', + ['inventory'] = 'ekwipunek', + ['veh_unlocked'] = '~g~Pojazd odblokowany', + ['hijack_failed'] = '~r~Forsowanie nie udane', + ['body_repaired'] = '~g~Karoseria naprawiona', + ['veh_repaired'] = '~g~Pojazd naprawiony', + ['veh_stored'] = 'wcisnij ~INPUT_CONTEXT~ aby schować pojazd.', + ['press_remove_obj'] = 'wcisnij ~INPUT_CONTEXT~ aby usunąć objekt', + ['please_tow'] = 'proszę ~y~odholować~s~ pojazd', + ['wait_five'] = 'musisz ~r~poczekać~s~ 5 minut', + ['must_in_flatbed'] = 'musisz być w lawecie aby rozpocząć misje', + ['mechanic_customer'] = 'klient mechanika', + ['you_do_not_room'] = '~r~Nie masz wiecej miejsca', + ['recovery_gas_can'] = 'odzyskiwanie ~b~Kanistra z paliwem~s~...', + ['recovery_repair_tools'] = 'odzyskiwanie ~b~Części naprawczych~s~...', + ['recovery_body_tools'] = 'odzyskiwanie ~b~Części blacharskich~s~...', + ['not_enough_gas_can'] = 'nie posiadasz ~r~wystarczająco~s~ paliwa w kanistrze.', + ['assembling_blowtorch'] = 'składanie ~b~Palnika~s~...', + ['not_enough_repair_tools'] = 'nie posiadasz ~r~wystarczająco~s~ częsci naprawczych.', + ['assembling_repair_kit'] = 'składanie ~b~częsci naprawczych~s~...', + ['not_enough_body_tools'] = 'nie posiadasz ~r~wystarczająco~s~ częsci blacharskich.', + ['assembling_body_kit'] = 'składanie ~b~częsci blacharskich~s~...', + ['your_comp_earned'] = 'twoja firma ~g~zarobiła~s~ ~g~$', + ['you_used_blowtorch'] = 'użyłeś ~b~palnik', + ['you_used_repair_kit'] = 'użyłeś ~b~częsci naprawczych', + ['you_used_body_kit'] = 'użyłeś ~b~częsci blacharskich', + ['have_withdrawn'] = 'wyciągnąłeś ~y~x%s~s~ ~b~%s~s~', + ['have_deposited'] = 'zdeponowałeś ~y~x%s~s~ ~b~%s~s~', + ['player_cannot_hold'] = '~r~nie masz~w~ wystarczająco ~y~wolnego~w~ miejsca w ekwipunku!', +} diff --git a/localization/esx_mecanojob_pl.sql b/localization/esx_mecanojob_pl.sql new file mode 100644 index 00000000..b8c9f819 --- /dev/null +++ b/localization/esx_mecanojob_pl.sql @@ -0,0 +1,30 @@ +USE `essentialmode`; + +INSERT INTO `addon_account` (name, label, shared) VALUES + ('society_mecano', 'Mechanik', 1) +; + +INSERT INTO `addon_inventory` (name, label, shared) VALUES + ('society_mecano', 'Mechanik', 1) +; + +INSERT INTO `jobs` (name, label) VALUES + ('mecano', 'Mechanik') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('mecano',0,'recrue','Praktykant',12,'{}','{}'), + ('mecano',1,'novice','Nowicjusz',24,'{}','{}'), + ('mecano',2,'experimente','Doświadczony',36,'{}','{}'), + ('mecano',3,'chief','Kierownik',48,'{}','{}'), + ('mecano',4,'boss','Szef',0,'{}','{}') +; + +INSERT INTO `items` (name, label, `limit`) VALUES + ('gazbottle', 'Butelka z gazem', 11), + ('fixtool', 'Zestaw do naprawy', 6), + ('carotool', 'Częsci naprawcze', 4), + ('blowpipe', 'Palnik', 10), + ('fixkit', 'Narzedzia naprawcze', 5), + ('carokit', 'Części blacharskie', 3) +; From f315be9369065243ac8a7ffce03d9d1ad1179096 Mon Sep 17 00:00:00 2001 From: deviljin112 <39461646+deviljin112@users.noreply.github.com> Date: Mon, 23 Jul 2018 21:49:11 +0100 Subject: [PATCH 1612/3224] Polish Translation --- __resource.lua | 2 ++ locales/pl.lua | 13 +++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 locales/pl.lua diff --git a/__resource.lua b/__resource.lua index 3b1adb8c..e61bc142 100644 --- a/__resource.lua +++ b/__resource.lua @@ -12,6 +12,7 @@ client_scripts { 'locales/fi.lua', 'locales/fr.lua', 'locales/es.lua', + 'locales/pl.lua', 'config.lua', 'client/main.lua' } @@ -24,6 +25,7 @@ server_scripts { 'locales/fi.lua', 'locales/fr.lua', 'locales/es.lua', + 'locales/pl.lua', '@mysql-async/lib/MySQL.lua', 'config.lua', 'server/main.lua' diff --git a/locales/pl.lua b/locales/pl.lua new file mode 100644 index 00000000..26b33140 --- /dev/null +++ b/locales/pl.lua @@ -0,0 +1,13 @@ +Locales ['pl'] = { + + ['buy_license'] = 'czy chcesz kupić licencję?', + ['yes'] = 'tak', + ['no'] = 'nie', + ['buy'] = 'kupiłeś', + ['not_enough_black'] = 'nie masz wystarczająco brudnej kasy', + ['not_enough'] = 'nie masz wystarczająco pieniędzy', + ['shop'] = 'sklep', + ['shop_menu'] = 'Wciśnij ~INPUT_CONTEXT~ aby otworzyć sklep.', + ['map_blip'] = 'sklep z bronią', + +} From d5a0a91def73d54a628da04e57600690881301c4 Mon Sep 17 00:00:00 2001 From: deviljin112 <39461646+deviljin112@users.noreply.github.com> Date: Mon, 23 Jul 2018 22:26:44 +0100 Subject: [PATCH 1613/3224] Polish Translation --- __resource.lua | 2 ++ locales/pl.lua | 4 ++++ localization/pl_esx_basicneeds.sql | 6 ++++++ 3 files changed, 12 insertions(+) create mode 100644 locales/pl.lua create mode 100644 localization/pl_esx_basicneeds.sql diff --git a/__resource.lua b/__resource.lua index 87d08362..7f6be01c 100644 --- a/__resource.lua +++ b/__resource.lua @@ -12,6 +12,7 @@ server_scripts { 'locales/fi.lua', 'locales/fr.lua', 'locales/sv.lua', + 'locales/pl.lua', 'config.lua', 'server/main.lua' } @@ -24,6 +25,7 @@ client_scripts { 'locales/fi.lua', 'locales/fr.lua', 'locales/sv.lua', + 'locales/pl.lua', 'config.lua', 'client/main.lua' } diff --git a/locales/pl.lua b/locales/pl.lua new file mode 100644 index 00000000..2ff3fa3d --- /dev/null +++ b/locales/pl.lua @@ -0,0 +1,4 @@ +Locales['pl'] = { + ['used_bread'] = 'zjadłeś/aś ~y~1x~s~ ~b~chleb~s~', + ['used_water'] = 'wypiłeś/aś ~y~1x~s~ ~b~woda~s~', +} \ No newline at end of file diff --git a/localization/pl_esx_basicneeds.sql b/localization/pl_esx_basicneeds.sql new file mode 100644 index 00000000..dab8eeb7 --- /dev/null +++ b/localization/pl_esx_basicneeds.sql @@ -0,0 +1,6 @@ +USE `essentialmode`; + +INSERT INTO `items` (`name`, `label`, `limit`) VALUES + ('bread', 'Chleb', 10), + ('water', 'Woda', 5) +; \ No newline at end of file From a8f5adbf18eca906c3dfc3f86ab602df21e9b9f1 Mon Sep 17 00:00:00 2001 From: deviljin112 <39461646+deviljin112@users.noreply.github.com> Date: Mon, 23 Jul 2018 22:27:44 +0100 Subject: [PATCH 1614/3224] Update pl.lua quick fix --- locales/pl.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/pl.lua b/locales/pl.lua index 26b33140..bdbe4278 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -3,7 +3,7 @@ Locales ['pl'] = { ['buy_license'] = 'czy chcesz kupić licencję?', ['yes'] = 'tak', ['no'] = 'nie', - ['buy'] = 'kupiłeś', + ['buy'] = 'kupiłeś/aś', ['not_enough_black'] = 'nie masz wystarczająco brudnej kasy', ['not_enough'] = 'nie masz wystarczająco pieniędzy', ['shop'] = 'sklep', From e086f7de4576041e1d2c709a9371199f5a6a580a Mon Sep 17 00:00:00 2001 From: deviljin112 <39461646+deviljin112@users.noreply.github.com> Date: Mon, 23 Jul 2018 22:30:17 +0100 Subject: [PATCH 1615/3224] Polish Translation --- __resource.lua | 2 ++ locales/pl.lua | 7 +++++++ 2 files changed, 9 insertions(+) create mode 100644 locales/pl.lua diff --git a/__resource.lua b/__resource.lua index a29f912f..8d8c4b39 100644 --- a/__resource.lua +++ b/__resource.lua @@ -15,6 +15,7 @@ server_scripts { 'locales/fr.lua', 'locales/es.lua', 'locales/sv.lua', + 'locales/pl.lua', 'server/main.lua' } @@ -28,5 +29,6 @@ client_scripts { 'locales/fr.lua', 'locales/es.lua', 'locales/sv.lua', + 'locales/pl.lua', 'client/main.lua' } diff --git a/locales/pl.lua b/locales/pl.lua new file mode 100644 index 00000000..b32cf870 --- /dev/null +++ b/locales/pl.lua @@ -0,0 +1,7 @@ +Locales['pl'] = { + + ['new_job'] = 'masz nową pracę!', + ['access_job_center'] = 'wciśnij ~INPUT_PICKUP~ aby otworzyć ~b~urząd pracy~s~.', + ['job_center'] = 'urząd Pracy', + +} From 53f45db40113d6d28370c023c7e073fe22db435e Mon Sep 17 00:00:00 2001 From: deviljin112 <39461646+deviljin112@users.noreply.github.com> Date: Mon, 23 Jul 2018 22:47:40 +0100 Subject: [PATCH 1616/3224] Polish Translation --- __resource.lua | 2 + locales/pl.lua | 35 ++++++++++++ localization/pl_esx_property.sql | 94 ++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+) create mode 100644 locales/pl.lua create mode 100644 localization/pl_esx_property.sql diff --git a/__resource.lua b/__resource.lua index 1ace3383..a5b84ec4 100644 --- a/__resource.lua +++ b/__resource.lua @@ -14,6 +14,7 @@ server_scripts { 'locales/fr.lua', 'locales/es.lua', 'locales/sv.lua', + 'locales/pl.lua', 'config.lua', 'server/main.lua' } @@ -27,6 +28,7 @@ client_scripts { 'locales/fr.lua', 'locales/es.lua', 'locales/sv.lua', + 'locales/pl.lua', 'config.lua', 'client/main.lua' } diff --git a/locales/pl.lua b/locales/pl.lua new file mode 100644 index 00000000..e79f2ba2 --- /dev/null +++ b/locales/pl.lua @@ -0,0 +1,35 @@ +Locales['pl'] = { + ['have_withdrawn'] = 'wyciągnąłeś/aś ~y~x%s~s~ ~b~%s~s~', + ['have_deposited'] = 'zdeponowałeś/aś ~y~x%s~s~ ~b~%s~s~', + ['free_prop'] = 'wolne mieszkanie', + ['property'] = 'mieszkanie', + ['enter'] = 'wejdz', + ['leave'] = 'sprzedzaj', + ['buy'] = 'kup', + ['rent'] = 'wynajmij', + ['visit'] = 'odwiedz', + ['press_to_menu'] = 'wciśnij ~INPUT_CONTEXT~ aby otworzyć menu', + ['owned_properties'] = 'twoje mieszkania', + ['available_properties'] = 'dostępne mieszkania', + ['invite_player'] = 'zaproś gracza', + ['you_invited'] = 'zaprosiłeś/aś ~y~%s~s~ do swojego mieszkania', + ['player_clothes'] = 'ubrania', + ['remove_cloth'] = 'usuń ubrania', + ['removed_cloth'] = 'te ubrania zostały usunięte z twojej garderoby!', + ['remove_object'] = 'usuń objekt', + ['deposit_object'] = 'deponuj objekt', + ['invite'] = 'zaproś', + ['dirty_money'] = 'brudne pieniądze $', + ['inventory'] = 'ekwipunek', + ['amount'] = 'suma?', + ['amount_invalid'] = 'nieprawidłowa suma', + ['press_to_exit'] = 'wciśnij ~INPUT_CONTEXT~ aby wyjść z mieszkania', + ['rented_for'] = 'wynająłeś/aś mieszkanie za $', + ['purchased_for'] = 'kupiłeś/aś mieszkanie za $', + ['made_property'] = 'stworzyłeś/aś mieszkanie', + ['not_enough'] = 'nie posiadasz wystarczająco pieniędzy', + ['invalid_quantity'] = 'nieprawidłowa ilość', + ['paid_rent'] = '~g~zapłaciłeś/aś~s~ za wynajem: ~g~$%s~s~', + ['not_enough_in_property'] = 'nie ma wystarczająco ~r~tego przedmiotu~s~ w mieszkaniu!', + ['player_cannot_hold'] = '~r~nie masz~s~ wystarczająco ~y~wolnego~s~ miejsca w ekwipunku!', +} \ No newline at end of file diff --git a/localization/pl_esx_property.sql b/localization/pl_esx_property.sql new file mode 100644 index 00000000..4ec2f594 --- /dev/null +++ b/localization/pl_esx_property.sql @@ -0,0 +1,94 @@ +USE `essentialmode`; + +ALTER TABLE `users` + ADD COLUMN `last_property` VARCHAR(255) NULL +; + +INSERT INTO `addon_account` (name, label, shared) VALUES + ('property_black_money','Mieszkanie na sprzedaż',0) +; + +INSERT INTO `addon_inventory` (name, label, shared) VALUES + ('property','Mieszkanie',0) +; + +INSERT INTO `datastore` (name, label, shared) VALUES + ('property','Mieszkanie',0) +; + +CREATE TABLE `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`) +); + +CREATE TABLE `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`) +); + +INSERT INTO `properties` 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','Basic apartment','{\"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','Modern Apartment 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','Modern Apartment 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','Modern Apartment 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','Mody Apartment 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','Mody Apartment 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','Mody Apartment 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','Vibrant Apartment 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','Vibrant Apartment 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','Vibrant Apartment 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','Sharp Apartment 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','Sharp Apartment 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','Sharp Apartment 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','Monochrome Apartment 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','Monochrome Apartment 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','Monochrome Apartment 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','Seductive Apartment 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','Seductive Apartment 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','Seductive Apartment 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','Regal Apartment 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','Regal Apartment 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','Regal Apartment 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','Aqua Apartment 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','Aqua Apartment 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','Aqua Apartment 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) +; + From ba8109fbbcb9fe979c450997bf1317e9eb4b38bc Mon Sep 17 00:00:00 2001 From: deviljin112 <39461646+deviljin112@users.noreply.github.com> Date: Mon, 23 Jul 2018 23:17:38 +0100 Subject: [PATCH 1617/3224] Polish translation --- __resource.lua | 2 ++ locales/pl.lua | 9 +++++++++ 2 files changed, 11 insertions(+) create mode 100644 locales/pl.lua diff --git a/__resource.lua b/__resource.lua index 1936deea..d1e36309 100644 --- a/__resource.lua +++ b/__resource.lua @@ -13,6 +13,7 @@ server_scripts { 'locales/fi.lua', 'locales/fr.lua', 'locales/sv.lua', + 'locales/pl.lua', 'config.lua', 'server/main.lua' } @@ -25,6 +26,7 @@ client_scripts { 'locales/fi.lua', 'locales/fr.lua', 'locales/sv.lua', + 'locales/pl.lua', 'config.lua', 'client/main.lua' } diff --git a/locales/pl.lua b/locales/pl.lua new file mode 100644 index 00000000..173fad3e --- /dev/null +++ b/locales/pl.lua @@ -0,0 +1,9 @@ +Locales['pl'] = { + ['skin_menu'] = 'menu wyglądu', + ['use_rotate_view'] = 'użyj ~INPUT_VEH_FLY_ROLL_LEFT_ONLY~ i ~INPUT_VEH_FLY_ROLL_RIGHT_ONLY~ aby obrócić ekran.', + ['skin'] = 'zmien wygląd', + ['saveskin'] = 'zapisz wygląd do pliku', + ['confirm_escape'] = 'czy chcesz anulować zmianę wyglądu? Wszystkie zmiany zostaną utracone.', + ['no'] = 'nie', + ['yes'] = 'tak', +} From a00b76e3b762e76f7711c2969c8d5a693e3abb79 Mon Sep 17 00:00:00 2001 From: deviljin112 <39461646+deviljin112@users.noreply.github.com> Date: Mon, 23 Jul 2018 23:22:52 +0100 Subject: [PATCH 1618/3224] Polish Translation --- __resource.lua | 2 ++ locales/pl.lua | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 locales/pl.lua diff --git a/__resource.lua b/__resource.lua index 1b1a869d..1669eb52 100644 --- a/__resource.lua +++ b/__resource.lua @@ -12,6 +12,7 @@ client_scripts { 'locales/fi.lua', 'locales/fr.lua', 'locales/sv.lua', + 'locales/pl.lua', 'config.lua', 'client/main.lua' } @@ -24,6 +25,7 @@ server_scripts { 'locales/fi.lua', 'locales/fr.lua', 'locales/sv.lua', + 'locales/pl.lua', 'config.lua', 'server/main.lua' } diff --git a/locales/pl.lua b/locales/pl.lua new file mode 100644 index 00000000..1fea8ed6 --- /dev/null +++ b/locales/pl.lua @@ -0,0 +1,16 @@ +Locales['en'] = { + ['shop_robbery'] = 'napad Na Sklep', + ['press_to_rob'] = 'Wciśnij ~INPUT_CONTEXT~ aby ~o~napaść~s~ na ~b~%s~s~', + ['robbery_timer'] = 'napad na sklep: ~r~%s~s~ sekund do końca', + ['recently_robbed'] = 'ten sklep niedawno został obrabowany. Proszę poczekać ~y~%s~s~ sekund przed kolejnym napadem', + ['rob_in_prog'] = '~r~napad w toku w ~b~%s~s~', + ['started_to_rob'] = 'rozpoczałeś/aś napad ~y~%s~s~', + ['alarm_triggered'] = 'alarm został włączony', + ['robbery_complete'] = '~r~Napad udany~s~, ~o~obrabowałeś/aś~s~ ~g~$%s~s~', + ['robbery_complete_at'] = '~r~Napad udany w ~y~%s~s~', + ['robbery_cancelled'] = 'napad został anulowany!', + ['robbery_cancelled_at'] = '~r~Napad w ~b~%s~s~ został anulowany!', + ['min_police'] = 'minimalnie musi być ~b~%s policjantów~s~ w mieście aby obrabować.', + ['robbery_already'] = '~r~Napad jest już w toku.', + ['no_threat'] = 'nie tworzysz zagrożenia dla tego sklepu', +} From bd298d1680f9a8c20962b387daa49c7e095e4df2 Mon Sep 17 00:00:00 2001 From: deviljin112 <39461646+deviljin112@users.noreply.github.com> Date: Mon, 23 Jul 2018 23:23:24 +0100 Subject: [PATCH 1619/3224] Update pl.lua quick fix --- locales/pl.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/pl.lua b/locales/pl.lua index 1fea8ed6..3ceaf197 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -1,4 +1,4 @@ -Locales['en'] = { +Locales['pl'] = { ['shop_robbery'] = 'napad Na Sklep', ['press_to_rob'] = 'Wciśnij ~INPUT_CONTEXT~ aby ~o~napaść~s~ na ~b~%s~s~', ['robbery_timer'] = 'napad na sklep: ~r~%s~s~ sekund do końca', From ed8e3f0505cad401ef2ab0bf0542827c952fcd26 Mon Sep 17 00:00:00 2001 From: MajorMarcin Date: Tue, 24 Jul 2018 12:12:34 +0200 Subject: [PATCH 1620/3224] fix pl --- locales/pl.lua | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/locales/pl.lua b/locales/pl.lua index d7d2e2a6..4d4fd756 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -24,13 +24,13 @@ Locales['pl'] = { ['vehicle_spawner'] = 'naciśnij ~INPUT_CONTEXT~ żeby wziąć pojazd', ['store_vehicle'] = 'naciśnij ~INPUT_CONTEXT~ żeby przechować pojazd', -- Service - ['service_max'] = 'you cannot enter service, max officers in service: %s/%s', - ['service_not'] = 'you have not entered service! You\'ll have to get changed first.', - ['service_anonunce'] = 'service information', - ['service_in'] = 'you\'ve entered service, welcome!', - ['service_in_announce'] = 'operator ~y~%s~s~ has entered service!', - ['service_out'] = 'you have left service.', - ['service_out_announce'] = 'operator ~y~%s~s~ has left their service.', + ['service_max'] = 'nie możesz wejść do służby, maksymalna liczba oficerów w służbie: %s/%s', + ['service_not'] = 'nie rozpoczynasz służby! Najpierw musisz się przebrać.', + ['service_anonunce'] = 'informacje o służbie', + ['service_in'] = 'rozpoczynasz służbe, Witaj!', + ['service_in_announce'] = 'operator ~y~%s~s~ rozpoczyna służbę!', + ['service_out'] = 'opuszczasz służbę.', + ['service_out_announce'] = 'operator ~y~%s~s~ opuszcza służbe.', -- Action Menu ['citizen_interaction'] = 'interakcja z cywilami', ['vehicle_interaction'] = 'interakcja z pojazdami', @@ -47,7 +47,7 @@ Locales['pl'] = { ['license_check'] = 'zarządzaj licencjami', ['license_revoke'] = 'unieważnij licencje', ['license_revoked'] = 'twoja licencja ~b~%s~s~ została ~y~unieważniona~s~!', - ['licence_you_revoked'] = 'unieważniłeś ~b~%s~s~ które należały do ~y~%s~s~', + ['licence_you_revoked'] = 'unieważniasz ~b~%s~s~ które należały do ~y~%s~s~', ['no_players_nearby'] = 'brak graczy w pobliżu', -- Vehicle interaction ['vehicle_info'] = 'informacje o pojeździe', @@ -56,9 +56,9 @@ Locales['pl'] = { ['no_vehicles_nearby'] = 'brak pojazdu w pobliżu', ['impound'] = 'zajmij pojazd', ['impound_prompt'] = 'naciśnij ~INPUT_CONTEXT~ żeby unieważnić ~y~zajęcie~s~', - ['impound_canceled'] = 'unieważniłeś/aś zajęcie', + ['impound_canceled'] = 'unieważniasz zajęcie', ['impound_canceled_moved'] = 'zajęcie zostało anulowane, ponieważ pojazd przemieścił się', - ['impound_successful'] = 'zająłeś/aś pojazd', + ['impound_successful'] = 'zajmujesz pojazd', ['search_database'] = 'informacje o pojeździe', ['search_database_title'] = 'informacjeo pojeździe - przeszukaj używając numeru rejestracyjnego', ['search_database_error_invalid'] = 'to ~r~nie~s~ jest ~y~poprawny~s~ rnumer rejestracyjny', @@ -87,7 +87,7 @@ Locales['pl'] = { ['inventory_label'] = '--- Ekwipunek ---', ['license_label'] = ' --- Licenses ---', ['confiscate'] = 'skonfiskuj %s', - ['confiscate_weapon'] = 'skonfiskuj %s z %s bullets', + ['confiscate_weapon'] = 'skonfiskuj %s z %s kulami', ['confiscate_inv'] = 'skonfiskuj %s x %s', ['confiscate_dirty'] = 'skonfiskuj brudne pieniądze: $%s', ['you_confiscated'] = 'skonfiskowałeś ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', @@ -119,7 +119,7 @@ Locales['pl'] = { ['open_bossmenu'] = 'naciśnij ~INPUT_CONTEXT~ aby otworzyć menu', ['quantity_invalid'] = 'nieprawidłowa ilość', ['have_withdrawn'] = 'wyjmujesz z depozytu ~y~%sx~s~ ~b~%s~s~', - ['have_deposited'] = 'zdeponowałeś ~y~%sx~s~ ~b~%s~s~', + ['have_deposited'] = 'zeponujesz ~y~%sx~s~ ~b~%s~s~', ['quantity'] = 'ilość', ['inventory'] = 'ekwipunek', ['police_stock'] = 'zapasy policji', From d7158bf4e3a814c8902d132945278dfd4410a74d Mon Sep 17 00:00:00 2001 From: MajorMarcin Date: Tue, 24 Jul 2018 12:14:19 +0200 Subject: [PATCH 1621/3224] fix pl --- locales/pl.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/pl.lua b/locales/pl.lua index 4d4fd756..63cd16a8 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -119,7 +119,7 @@ Locales['pl'] = { ['open_bossmenu'] = 'naciśnij ~INPUT_CONTEXT~ aby otworzyć menu', ['quantity_invalid'] = 'nieprawidłowa ilość', ['have_withdrawn'] = 'wyjmujesz z depozytu ~y~%sx~s~ ~b~%s~s~', - ['have_deposited'] = 'zeponujesz ~y~%sx~s~ ~b~%s~s~', + ['have_deposited'] = 'zdeponowano ~y~%sx~s~ ~b~%s~s~', ['quantity'] = 'ilość', ['inventory'] = 'ekwipunek', ['police_stock'] = 'zapasy policji', From 079b9f7966819e6db67e4d117c5504df0bb3ffce Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 24 Jul 2018 13:35:46 +0200 Subject: [PATCH 1622/3224] Added missing locales --- locales/de.lua | 4 +++- locales/en.lua | 1 + locales/fr.lua | 3 ++- server/main.lua | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/locales/de.lua b/locales/de.lua index d7a1be95..b29f9cb1 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -1,11 +1,13 @@ Locales['de'] = { - ['by_default'] = 'default', ['installed'] = 'installiert', ['already_own'] = 'du besitzt bereits: ~b~', ['not_enough_money'] = 'du hast nicht genug Geld!', ['purchased'] = 'gekauft!', ['press_custom'] = 'Drücke ~INPUT_PICKUP~ um dein Fahrzeug zu modifizieren.', + ['open_command'] = 'open LS Customs', + ['level'] = 'level ', + ['neon'] = 'neon', -- Paint Colors -- Black ['black'] = 'black', diff --git a/locales/en.lua b/locales/en.lua index 1d779354..f6a46223 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -5,6 +5,7 @@ Locales['en'] = { ['not_enough_money'] = 'you do not have enough money!', ['purchased'] = 'you have purchased the mod!', ['press_custom'] = 'press ~INPUT_PICKUP~ to personalize your vehicle.', + ['open_command'] = 'open LS Customs', ['level'] = 'level ', ['neon'] = 'neon', -- Paint Colors diff --git a/locales/fr.lua b/locales/fr.lua index 6368fb8e..cb0a71b6 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,12 +1,13 @@ Locales['fr'] = { - ['by_default'] = 'par défaut', ['installed'] = 'installé', ['already_own'] = 'vous possédez déjà: ~b~', ['not_enough_money'] = 'vous n\'avez pas assez d\'argent !', ['purchased'] = 'achat effectué !', ['press_custom'] = 'appuyez sur ~INPUT_PICKUP~ pour personnaliser le véhicule.', + ['open_command'] = 'open LS Customs', ['level'] = 'niveau ', + ['neon'] = 'neon', -- Paint Colors -- Black ['black'] = 'noir', diff --git a/server/main.lua b/server/main.lua index 4d7c4a71..263539ca 100644 --- a/server/main.lua +++ b/server/main.lua @@ -37,7 +37,7 @@ end) RegisterServerEvent('esx_lscustom:refreshOwnedVehicle') AddEventHandler('esx_lscustom:refreshOwnedVehicle', function(myCar) MySQL.Async.execute( - 'UPDATE `owned_vehicles` SET `vehicle` = @vehicle WHERE `vehicle` LIKE "%' .. myCar['plate'] .. '%"', + 'UPDATE `owned_vehicles` SET `vehicle` = @vehicle WHERE `vehicle` LIKE "%' .. myCar.plate .. '%"', { ['@vehicle'] = json.encode(myCar) } From bb44db07ecef3ad85f0daf148adfa3c96ec038d5 Mon Sep 17 00:00:00 2001 From: deviljin112 <39461646+deviljin112@users.noreply.github.com> Date: Tue, 24 Jul 2018 13:26:10 +0100 Subject: [PATCH 1623/3224] Update pl.lua Capital first line --- locales/pl.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/pl.lua b/locales/pl.lua index ca85a4c2..b3218307 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -1,5 +1,5 @@ Locales['pl'] = { - ['new_message'] = '~b~masz nową wiadomość:~s~ %s', + ['new_message'] = '~b~Masz nową wiadomość:~s~ %s', ['press_take_call'] = '%s - wciśnij ~INPUT_CONTEXT~ aby odebrać telefon', ['taken_call'] = '~y~%s~s~ odebrał telefon', ['gps_position'] = 'cel podróży został dodany do GPS\'a', From cb94b283f3b80675cccc083040523b1f804994db Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 24 Jul 2018 14:43:04 +0200 Subject: [PATCH 1624/3224] Update to support the new vehicle system, make sure you've ran esx_migrate!! --- config.lua | 2 +- server/main.lua | 498 +++++++++++++++++++++--------------------------- 2 files changed, 215 insertions(+), 285 deletions(-) diff --git a/config.lua b/config.lua index 6180e830..aac0ae8e 100644 --- a/config.lua +++ b/config.lua @@ -46,6 +46,6 @@ Config.Zones = { Pos = { x = -44.630, y = -1080.738, z = 25.683 }, Size = { x = 3.0, y = 3.0, z = 1.0 }, Type = 1, - } + }, } diff --git a/server/main.lua b/server/main.lua index 9fb3e8fd..95b907e5 100644 --- a/server/main.lua +++ b/server/main.lua @@ -8,143 +8,121 @@ TriggerEvent('esx_phone:registerNumber', 'cardealer', _U('dealer_customers'), fa TriggerEvent('esx_society:registerSociety', 'cardealer', _U('car_dealer'), 'society_cardealer', 'society_cardealer', 'society_cardealer', {type = 'private'}) function RemoveOwnedVehicle (plate) - MySQL.Async.fetchAll( - 'SELECT * FROM owned_vehicles', - {}, - function (result) - for i=1, #result, 1 do - local vehicleProps = json.decode(result[i].vehicle) - - if vehicleProps.plate == plate then - MySQL.Async.execute( - 'DELETE FROM owned_vehicles WHERE id = @id', - { ['@id'] = result[i].id } - ) - end - end - end - ) + MySQL.Async.execute('DELETE FROM owned_vehicles WHERE plate = @plate', + { + ['@plate'] = plate + }) end AddEventHandler('onMySQLReady', function () - Categories = MySQL.Sync.fetchAll('SELECT * FROM vehicle_categories') - local vehicles = MySQL.Sync.fetchAll('SELECT * FROM vehicles') + Categories = MySQL.Sync.fetchAll('SELECT * FROM vehicle_categories') + local vehicles = MySQL.Sync.fetchAll('SELECT * FROM vehicles') - for i=1, #vehicles, 1 do - local vehicle = vehicles[i] + for i=1, #vehicles, 1 do + local vehicle = vehicles[i] - for j=1, #Categories, 1 do - if Categories[j].name == vehicle.category then - vehicle.categoryLabel = Categories[j].label - end - end + for j=1, #Categories, 1 do + if Categories[j].name == vehicle.category then + vehicle.categoryLabel = Categories[j].label + break --todo confirm + end + end - table.insert(Vehicles, vehicle) - end + table.insert(Vehicles, vehicle) + end end) RegisterServerEvent('esx_vehicleshop:setVehicleOwned') AddEventHandler('esx_vehicleshop:setVehicleOwned', function (vehicleProps) - local _source = source - local xPlayer = ESX.GetPlayerFromId(source) + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) - MySQL.Async.execute( - 'INSERT INTO owned_vehicles (vehicle, owner) VALUES (@vehicle, @owner)', - { - ['@vehicle'] = json.encode(vehicleProps), - ['@owner'] = xPlayer.identifier, - }, - function (rowsChanged) - TriggerClientEvent('esx:showNotification', _source, _U('vehicle_belongs', vehicleProps.plate)) - end - ) + MySQL.Async.execute('INSERT INTO owned_vehicles (owner, plate, vehicle) VALUES (@owner, @plate, @vehicle)', + { + ['@owner'] = xPlayer.identifier, + ['@plate'] = vehicleProps.plate, + ['@vehicle'] = json.encode(vehicleProps) + }, + function (rowsChanged) + TriggerClientEvent('esx:showNotification', _source, _U('vehicle_belongs', vehicleProps.plate)) + end) end) RegisterServerEvent('esx_vehicleshop:setVehicleOwnedPlayerId') AddEventHandler('esx_vehicleshop:setVehicleOwnedPlayerId', function (playerId, vehicleProps) - local xPlayer = ESX.GetPlayerFromId(playerId) + local xPlayer = ESX.GetPlayerFromId(playerId) - MySQL.Async.execute( - 'INSERT INTO owned_vehicles (vehicle, owner) VALUES (@vehicle, @owner)', - { - ['@vehicle'] = json.encode(vehicleProps), - ['@owner'] = xPlayer.identifier, - }, - function (rowsChanged) - TriggerClientEvent('esx:showNotification', playerId, _U('vehicle_belongs', vehicleProps.plate)) - end - ) + MySQL.Async.execute('INSERT INTO owned_vehicles (owner, plate, vehicle) VALUES (@owner, @plate, @vehicle)', + { + ['@owner'] = xPlayer.identifier, + ['@plate'] = vehicleProps.plate, + ['@vehicle'] = json.encode(vehicleProps) + }, + function (rowsChanged) + TriggerClientEvent('esx:showNotification', playerId, _U('vehicle_belongs', vehicleProps.plate)) + end) end) RegisterServerEvent('esx_vehicleshop:setVehicleOwnedSociety') AddEventHandler('esx_vehicleshop:setVehicleOwnedSociety', function (society, vehicleProps) - local _source = source - local xPlayer = ESX.GetPlayerFromId(source) + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) - MySQL.Async.execute( - 'INSERT INTO owned_vehicles (vehicle, owner) VALUES (@vehicle, @owner)', - { - ['@vehicle'] = json.encode(vehicleProps), - ['@owner'] = 'society:' .. society, - }, - function (rowsChanged) + MySQL.Async.execute('INSERT INTO owned_vehicles (owner, plate, vehicle) VALUES (@owner, @plate, @vehicle)', + { + ['@owner'] = 'society:' .. society, + ['@plate'] = vehicleProps.plate, + ['@vehicle'] = json.encode(vehicleProps), + }, + function (rowsChanged) - end - ) + end) end) RegisterServerEvent('esx_vehicleshop:sellVehicle') AddEventHandler('esx_vehicleshop:sellVehicle', function (vehicle) - MySQL.Async.fetchAll( - 'SELECT * FROM cardealer_vehicles WHERE vehicle = @vehicle LIMIT 1', - { ['@vehicle'] = vehicle }, - function (result) - local id = result[1].id - local price = result[1].price + MySQL.Async.fetchAll('SELECT * FROM cardealer_vehicles WHERE vehicle = @vehicle LIMIT 1', { + ['@vehicle'] = vehicle + }, function (result) + local id = result[1].id - MySQL.Async.execute( - 'DELETE FROM cardealer_vehicles WHERE id = @id', - { ['@id'] = id } - ) - end - ) + MySQL.Async.execute('DELETE FROM cardealer_vehicles WHERE id = @id', { + ['@id'] = id + }) + end) end) RegisterServerEvent('esx_vehicleshop:rentVehicle') AddEventHandler('esx_vehicleshop:rentVehicle', function (vehicle, plate, playerName, basePrice, rentPrice, target) - local xPlayer = ESX.GetPlayerFromId(target) + local xPlayer = ESX.GetPlayerFromId(target) - MySQL.Async.fetchAll( - 'SELECT * FROM cardealer_vehicles WHERE vehicle = @vehicle LIMIT 1', - { ['@vehicle'] = vehicle }, - function (result) - local id = result[1].id - local price = result[1].price - local owner = xPlayer.identifier + MySQL.Async.fetchAll('SELECT * FROM cardealer_vehicles WHERE vehicle = @vehicle LIMIT 1', { + ['@vehicle'] = vehicle + }, function (result) + local id = result[1].id + local price = result[1].price + local owner = xPlayer.identifier - MySQL.Async.execute( - 'DELETE FROM cardealer_vehicles WHERE id = @id', - { ['@id'] = id } - ) + MySQL.Async.execute('DELETE FROM cardealer_vehicles WHERE id = @id', { + ['@id'] = id + }) - 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'] = playerName, - ['@base_price'] = basePrice, - ['@rent_price'] = rentPrice, - ['@owner'] = owner, - } - ) - end - ) + 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'] = playerName, + ['@base_price'] = basePrice, + ['@rent_price'] = rentPrice, + ['@owner'] = owner, + }) + end) end) +-- unused? RegisterServerEvent('esx_vehicleshop:setVehicleForAllPlayers') AddEventHandler('esx_vehicleshop:setVehicleForAllPlayers', function (props, x, y, z, radius) - TriggerClientEvent('esx_vehicleshop:setVehicle', -1, props, x, y, z, radius) + TriggerClientEvent('esx_vehicleshop:setVehicle', -1, props, x, y, z, radius) end) RegisterServerEvent('esx_vehicleshop:getStockItem') @@ -192,234 +170,189 @@ AddEventHandler('esx_vehicleshop:putStockItems', function (itemName, count) end) ESX.RegisterServerCallback('esx_vehicleshop:getCategories', function (source, cb) - cb(Categories) + cb(Categories) end) ESX.RegisterServerCallback('esx_vehicleshop:getVehicles', function (source, cb) - cb(Vehicles) + cb(Vehicles) end) ESX.RegisterServerCallback('esx_vehicleshop:buyVehicle', function (source, cb, vehicleModel) - local xPlayer = ESX.GetPlayerFromId(source) - local vehicleData = nil + local xPlayer = ESX.GetPlayerFromId(source) + local vehicleData = nil - for i=1, #Vehicles, 1 do - if Vehicles[i].model == vehicleModel then - vehicleData = Vehicles[i] - break - end - end + for i=1, #Vehicles, 1 do + if Vehicles[i].model == vehicleModel then + vehicleData = Vehicles[i] + break + end + end - if xPlayer.get('money') >= vehicleData.price then - xPlayer.removeMoney(vehicleData.price) - cb(true) - else - cb(false) - end + if xPlayer.getMoney() >= vehicleData.price then + xPlayer.removeMoney(vehicleData.price) + cb(true) + else + cb(false) + end end) ESX.RegisterServerCallback('esx_vehicleshop:buyVehicleSociety', function (source, cb, society, vehicleModel) - local vehicleData = nil + local vehicleData = nil - for i=1, #Vehicles, 1 do - if Vehicles[i].model == vehicleModel then - vehicleData = Vehicles[i] - break - end - end + for i=1, #Vehicles, 1 do + if Vehicles[i].model == vehicleModel then + vehicleData = Vehicles[i] + break + end + end - TriggerEvent('esx_addonaccount:getSharedAccount', 'society_' .. society, function (account) - if account.money >= vehicleData.price then + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_' .. society, function (account) + if account.money >= vehicleData.price then - account.removeMoney(vehicleData.price) + account.removeMoney(vehicleData.price) + MySQL.Async.execute('INSERT INTO cardealer_vehicles (vehicle, price) VALUES (@vehicle, @price)', + { + ['@vehicle'] = vehicleData.model, + ['@price'] = vehicleData.price, + }) - MySQL.Async.execute( - 'INSERT INTO cardealer_vehicles (vehicle, price) VALUES (@vehicle, @price)', - { - ['@vehicle'] = vehicleData.model, - ['@price'] = vehicleData.price, - } - ) - - cb(true) - else - cb(false) - end - end) + cb(true) + else + cb(false) + end + end) end) ESX.RegisterServerCallback('esx_vehicleshop:getPersonnalVehicles', function (source, cb) - local xPlayer = ESX.GetPlayerFromId(source) + local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.fetchAll( - 'SELECT * FROM owned_vehicles WHERE owner = @owner', - { ['@owner'] = xPlayer.identifier }, - function (result) - local vehicles = {} + MySQL.Async.fetchAll('SELECT * FROM owned_vehicles WHERE owner = @owner', { + ['@owner'] = xPlayer.identifier + }, function (result) + local vehicles = {} - for i=1, #result, 1 do - local vehicleData = json.decode(result[i].vehicle) - table.insert(vehicles, vehicleData) - end + for i=1, #result, 1 do + local vehicleData = json.decode(result[i].vehicle) + table.insert(vehicles, vehicleData) + end - cb(vehicles) - end - ) + cb(vehicles) + end) end) ESX.RegisterServerCallback('esx_vehicleshop:getCommercialVehicles', function (source, cb) - MySQL.Async.fetchAll( - 'SELECT * FROM cardealer_vehicles ORDER BY vehicle ASC', - {}, - function (result) - local vehicles = {} + MySQL.Async.fetchAll('SELECT * FROM cardealer_vehicles ORDER BY vehicle ASC', {}, function (result) + local vehicles = {} - for i=1, #result, 1 do - table.insert(vehicles, { - name = result[i].vehicle, - price = result[i].price - }) - end + for i=1, #result, 1 do + table.insert(vehicles, { + name = result[i].vehicle, + price = result[i].price + }) + end - cb(vehicles) - end - ) + cb(vehicles) + end) end) ESX.RegisterServerCallback('esx_vehicleshop:getRentedVehicles', function (source, cb) - MySQL.Async.fetchAll( - 'SELECT * FROM rented_vehicles ORDER BY player_name ASC', - {}, - function (result) - local vehicles = {} + MySQL.Async.fetchAll('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 - }) - end + for i=1, #result, 1 do + table.insert(vehicles, { + name = result[i].vehicle, + plate = result[i].plate, + playerName = result[i].player_name + }) + end - cb(vehicles) - end - ) + cb(vehicles) + end) end) ESX.RegisterServerCallback('esx_vehicleshop:giveBackVehicle', function (source, cb, plate) - MySQL.Async.fetchAll( - 'SELECT * FROM rented_vehicles WHERE plate = @plate LIMIT 1', - { ['@plate'] = plate }, - function (result) - if #result > 0 then - local id = result[1].id - local vehicle = result[1].vehicle - local plate = result[1].plate - local basePrice = result[1].base_price + MySQL.Async.fetchAll('SELECT * FROM rented_vehicles WHERE plate = @plate', { + ['@plate'] = plate + }, function (result) + if result[1] ~= nil then + local vehicle = result[1].vehicle + local basePrice = result[1].base_price - MySQL.Async.execute( - 'INSERT INTO cardealer_vehicles (vehicle, price) VALUES (@vehicle, @price)', - { - ['@vehicle'] = vehicle, - ['@price'] = basePrice, - } - ) + MySQL.Async.execute('INSERT INTO cardealer_vehicles (vehicle, price) VALUES (@vehicle, @price)', + { + ['@vehicle'] = vehicle, + ['@price'] = basePrice + }) - MySQL.Async.execute( - 'DELETE FROM rented_vehicles WHERE id = @id', - { ['@id'] = id } - ) + MySQL.Async.execute('DELETE FROM rented_vehicles WHERE plate = @plate',{ + ['@plate'] = plate + }) - RemoveOwnedVehicle(plate) - - cb(true) - else - cb(false) - end - end - ) + RemoveOwnedVehicle(plate) + cb(true) + else + cb(false) + end + end) end) ESX.RegisterServerCallback('esx_vehicleshop:resellVehicle', function (source, cb, plate, price) - MySQL.Async.fetchAll( - 'SELECT * FROM rented_vehicles WHERE plate = @plate LIMIT 1', - { ['@plate'] = plate }, - function (result) - if #result > 0 then - cb(false) - else - local xPlayer = ESX.GetPlayerFromId(source) + MySQL.Async.fetchAll('SELECT * FROM rented_vehicles WHERE plate = @plate', { + ['@plate'] = plate + }, function (result) + if result[1] ~= nil then -- is it a rented vehicle? + cb(false) -- it is, don't let the player sell it since he doesn't own it + else + local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.fetchAll( - 'SELECT * FROM owned_vehicles WHERE owner = @owner', - { ['@owner'] = xPlayer.identifier }, - function (result) - local found = false + MySQL.Async.fetchAll('SELECT * FROM owned_vehicles WHERE owner = @owner AND @plate = plate', + { + ['@owner'] = xPlayer.identifier, + ['@plate'] = plate + }, function (result) - for i=1, #result, 1 do - local vehicleProps = json.decode(result[i].vehicle) - - if vehicleProps.plate == plate then - found = true - break - end - end - - if found then - xPlayer.addMoney(price) - RemoveOwnedVehicle(plate) - - cb(true) - else - if xPlayer.job.grade_name == 'boss' then - MySQL.Async.fetchAll( - 'SELECT * FROM owned_vehicles WHERE owner = @owner', - { ['@owner'] = 'society:' .. xPlayer.job.name }, - function (result) - local found = false - - for i=1, #result, 1 do - local vehicleProps = json.decode(result[i].vehicle) - - if vehicleProps.plate == plate then - found = true - break - end - end - - if found then - xPlayer.addMoney(price) - RemoveOwnedVehicle(plate) - - cb(true) - else - cb(false) - end - end - ) - else - cb(false) - end - end - end - ) - end - end - ) + -- does the owner match? + if result[1] ~= nil then + xPlayer.addMoney(price) + RemoveOwnedVehicle(plate) + cb(true) + else + if xPlayer.job.grade_name == 'boss' then + MySQL.Async.fetchAll('SELECT * FROM owned_vehicles WHERE owner = @owner AND @plate = plate', + { + ['@owner'] = 'society:' .. xPlayer.job.name, + ['@plate'] = plate + }, function (result) + if result[1] ~= nil then + xPlayer.addMoney(price) + RemoveOwnedVehicle(plate) + cb(true) + else + cb(false) + end + end) + else + cb(false) + end + end + end) + end + end) end) ESX.RegisterServerCallback('esx_vehicleshop:getStockItems', function (source, cb) - TriggerEvent('esx_addoninventory:getSharedInventory', 'society_cardealer', function(inventory) - cb(inventory.items) - end) + TriggerEvent('esx_addoninventory:getSharedInventory', 'society_cardealer', function(inventory) + cb(inventory.items) + end) end) ESX.RegisterServerCallback('esx_vehicleshop:getPlayerInventory', function (source, cb) - local xPlayer = ESX.GetPlayerFromId(source) - local items = xPlayer.inventory + local xPlayer = ESX.GetPlayerFromId(source) + local items = xPlayer.inventory - cb({ items = items }) + cb({ items = items }) end) if Config.EnablePvCommand then @@ -428,20 +361,17 @@ if Config.EnablePvCommand then end, {help = _U('leaving')}) end -function PayRent() - MySQL.Async.fetchAll( - 'SELECT * FROM rented_vehicles', {}, - function (result) +function PayRent(d, h, m) + MySQL.Async.fetchAll('SELECT * FROM rented_vehicles', {}, function (result) for i=1, #result, 1 do local xPlayer = ESX.GetPlayerFromIdentifier(result[i].owner) -- message player if connected if xPlayer ~= nil then - xPlayer.removeBank(result[i].rent_price) + xPlayer.removeAccountMoney('bank', result[i].rent_price) TriggerClientEvent('esx:showNotification', xPlayer.source, _U('paid_rental', result[i].rent_price)) else -- pay rent either way - MySQL.Sync.execute( - 'UPDATE users SET bank = bank - @bank WHERE identifier = @identifier', + MySQL.Sync.execute('UPDATE users SET bank = bank - @bank WHERE identifier = @identifier', { ['@bank'] = result[i].rent_price, ['@identifier'] = result[i].owner From 2f0fcbceaaeaf8d8d8e104b0e8b745fb301e92cd Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 24 Jul 2018 15:08:51 +0200 Subject: [PATCH 1625/3224] Fixed #53, minor improvements --- client/main.lua | 148 ++++++++++++++++++++---------------------------- server/main.lua | 18 +++++- 2 files changed, 78 insertions(+), 88 deletions(-) diff --git a/client/main.lua b/client/main.lua index e25650bc..d742cbe9 100644 --- a/client/main.lua +++ b/client/main.lua @@ -13,7 +13,6 @@ local Keys = { local GUI = {} local HasAlreadyEnteredMarker = false local LastZone = nil -local PlayerData = {} local CurrentAction = nil local CurrentActionMsg = '' local CurrentActionData = {} @@ -27,18 +26,34 @@ ESX = nil GUI.Time = 0 Citizen.CreateThread(function () - while ESX == nil do - TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) - Citizen.Wait(0) - end + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end - ESX.TriggerServerCallback('esx_vehicleshop:getCategories', function (categories) - Categories = categories - end) + Citizen.Wait(300) - ESX.TriggerServerCallback('esx_vehicleshop:getVehicles', function (vehicles) - Vehicles = vehicles - end) + ESX.TriggerServerCallback('esx_vehicleshop:getCategories', function (categories) + Categories = categories + end) + + ESX.TriggerServerCallback('esx_vehicleshop:getVehicles', function (vehicles) + Vehicles = vehicles + end) + + if Config.EnablePlayerManagement then + if ESX.PlayerData.job.name == 'cardealer' then + Config.Zones.ShopEntering.Type = 1 + + if ESX.PlayerData.job.grade_name == 'boss' then + Config.Zones.BossActions.Type = 1 + end + + else + Config.Zones.ShopEntering.Type = -1 + Config.Zones.BossActions.Type = -1 + end + end end) function DeleteShopInsideVehicles () @@ -84,7 +99,7 @@ function OpenShopMenu () firstVehicleData = vehicle end - table.insert(options, vehicle.name .. ' $' .. vehicle.price) + table.insert(options, vehicle.name .. ' $' .. vehicle.price .. '') end table.insert(elements, { @@ -172,11 +187,7 @@ function OpenShopMenu () DeleteShopInsideVehicles() - ESX.Game.SpawnVehicle(vehicleData.model, { - x = Config.Zones.ShopOutside.Pos.x, - y = Config.Zones.ShopOutside.Pos.y, - z = Config.Zones.ShopOutside.Pos.z - }, Config.Zones.ShopOutside.Heading, function (vehicle) + ESX.Game.SpawnVehicle(vehicleData.model, Config.Zones.ShopOutside.Pos, Config.Zones.ShopOutside.Heading, function (vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) @@ -209,11 +220,7 @@ function OpenShopMenu () DeleteShopInsideVehicles() - ESX.Game.SpawnVehicle(vehicleData.model, { - x = Config.Zones.ShopOutside.Pos.x, - y = Config.Zones.ShopOutside.Pos.y, - z = Config.Zones.ShopOutside.Pos.z - }, Config.Zones.ShopOutside.Heading, function (vehicle) + ESX.Game.SpawnVehicle(vehicleData.model, Config.Zones.ShopOutside.Pos, Config.Zones.ShopOutside.Heading, function (vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) @@ -248,11 +255,7 @@ function OpenShopMenu () DeleteShopInsideVehicles() - ESX.Game.SpawnVehicle(vehicleData.model, { - x = Config.Zones.ShopOutside.Pos.x, - y = Config.Zones.ShopOutside.Pos.y, - z = Config.Zones.ShopOutside.Pos.z - }, Config.Zones.ShopOutside.Heading, function (vehicle) + ESX.Game.SpawnVehicle(vehicleData.model, Config.Zones.ShopOutside.Pos, Config.Zones.ShopOutside.Heading, function (vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) @@ -311,11 +314,7 @@ function OpenShopMenu () DeleteShopInsideVehicles() - ESX.Game.SpawnLocalVehicle(vehicleData.model, { - x = Config.Zones.ShopInside.Pos.x, - y = Config.Zones.ShopInside.Pos.y, - z = Config.Zones.ShopInside.Pos.z - }, Config.Zones.ShopInside.Heading, function(vehicle) + ESX.Game.SpawnLocalVehicle(firstVehicleData.model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function (vehicle) table.insert(LastVehicles, vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) FreezeEntityPosition(vehicle, true) @@ -325,11 +324,7 @@ function OpenShopMenu () DeleteShopInsideVehicles() - ESX.Game.SpawnLocalVehicle(firstVehicleData.model, { - x = Config.Zones.ShopInside.Pos.x, - y = Config.Zones.ShopInside.Pos.y, - z = Config.Zones.ShopInside.Pos.z - }, Config.Zones.ShopInside.Heading, function (vehicle) + ESX.Game.SpawnLocalVehicle(firstVehicleData.model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function (vehicle) table.insert(LastVehicles, vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) FreezeEntityPosition(vehicle, true) @@ -526,7 +521,7 @@ function OpenPersonnalVehicleMenu () end for i=1, #vehicles, 1 do - table.insert(elements, {label = vehicles[i].name .. ' [' .. vehicles[i].plate .. ']', value = vehicles[i]}) + table.insert(elements, {label = vehicles[i].name .. ' [' .. vehicles[i].plate .. ']', value = vehicles[i]}) end ESX.UI.Menu.Open( @@ -544,11 +539,11 @@ function OpenPersonnalVehicleMenu () menu.close() - ESX.Game.SpawnVehicle(vehicleData.model, { - x = coords.x, - y = coords.y, - z = coords.z - }, heading, function (vehicle) + ESX.Game.SpawnVehicle(vehicleData.model, { + x = coords.x, + y = coords.y, + z = coords.z + }, heading, function (vehicle) ESX.Game.SetVehicleProperties(vehicle, vehicleData) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) end) @@ -565,7 +560,7 @@ function OpenPopVehicleMenu () local elements = {} for i=1, #vehicles, 1 do - table.insert(elements, {label = vehicles[i].name .. ' $' .. vehicles[i].price, value = vehicles[i].name}) + table.insert(elements, {label = vehicles[i].name .. ' [MSRP $' .. vehicles[i].price .. ']', value = vehicles[i].name}) end ESX.UI.Menu.Open( @@ -580,11 +575,7 @@ function OpenPopVehicleMenu () DeleteShopInsideVehicles() - ESX.Game.SpawnVehicle(model, { - x = Config.Zones.ShopInside.Pos.x, - y = Config.Zones.ShopInside.Pos.y, - z = Config.Zones.ShopInside.Pos.z - }, Config.Zones.ShopInside.Heading, function (vehicle) + ESX.Game.SpawnVehicle(model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function (vehicle) table.insert(LastVehicles, vehicle) @@ -667,7 +658,8 @@ function OpenGetStocksMenu () 'default', GetCurrentResourceName(), 'stocks_menu', { title = _U('dealership_stock'), - elements = elements, + align = 'top-left', + elements = elements }, function (data, menu) local itemName = data.current.value @@ -683,11 +675,12 @@ function OpenGetStocksMenu () if count == nil then ESX.ShowNotification(_U('quantity_invalid')) else + TriggerServerEvent('esx_vehicleshop:getStockItem', itemName, count) menu2.close() menu.close() OpenGetStocksMenu() - TriggerServerEvent('esx_vehicleshop:getStockItem', itemName, count) + end end, function (data2, menu2) @@ -718,7 +711,8 @@ function OpenPutStocksMenu () 'default', GetCurrentResourceName(), 'stocks_menu', { title = _U('inventory'), - elements = elements, + align = 'top-left', + elements = elements }, function (data, menu) local itemName = data.current.value @@ -734,11 +728,10 @@ function OpenPutStocksMenu () if count == nil then ESX.ShowNotification(_U('quantity_invalid')) else + TriggerServerEvent('esx_vehicleshop:putStockItems', itemName, count) menu2.close() menu.close() OpenPutStocksMenu() - - TriggerServerEvent('esx_vehicleshop:putStockItems', itemName, count) end end, @@ -754,42 +747,23 @@ function OpenPutStocksMenu () end) end - -RegisterNetEvent('esx:playerLoaded') -AddEventHandler('esx:playerLoaded', function (xPlayer) - PlayerData = xPlayer - - if Config.EnablePlayerManagement then - if PlayerData.job.name == 'cardealer' then - Config.Zones.ShopEntering.Type = 1 - - if PlayerData.job.grade_name == 'boss' then - Config.Zones.BossActions.Type = 1 - end - else - Config.Zones.ShopEntering.Type = -1 - Config.Zones.BossActions.Type = -1 - end - end -end) - RegisterNetEvent('esx:setJob') AddEventHandler('esx:setJob', function (job) - PlayerData.job = job + ESX.PlayerData.job = job - if Config.EnablePlayerManagement then - if PlayerData.job.name == 'cardealer' then - Config.Zones.ShopEntering.Type = 1 + if Config.EnablePlayerManagement then + if ESX.PlayerData.job.name == 'cardealer' then + Config.Zones.ShopEntering.Type = 1 - if PlayerData.job.grade_name == 'boss' then - Config.Zones.BossActions.Type = 1 - end + if ESX.PlayerData.job.grade_name == 'boss' then + Config.Zones.BossActions.Type = 1 + end - else - Config.Zones.ShopEntering.Type = -1 - Config.Zones.BossActions.Type = -1 - end - end + else + Config.Zones.ShopEntering.Type = -1 + Config.Zones.BossActions.Type = -1 + end + end end) RegisterNetEvent('esx_vehicleshop:openPersonnalVehicleMenu') @@ -800,7 +774,7 @@ end) AddEventHandler('esx_vehicleshop:hasEnteredMarker', function (zone) if zone == 'ShopEntering' then if Config.EnablePlayerManagement then - if PlayerData.job ~= nil and PlayerData.job.name == 'cardealer' then + if ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'cardealer' then CurrentAction = 'reseller_menu' CurrentActionMsg = _U('shop_menu') CurrentActionData = {} @@ -853,7 +827,7 @@ AddEventHandler('esx_vehicleshop:hasEnteredMarker', function (zone) end end - if zone == 'BossActions' and Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.name == 'cardealer' and PlayerData.job.grade_name == 'boss' then + if zone == 'BossActions' and Config.EnablePlayerManagement and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'cardealer' and ESX.PlayerData.job.grade_name == 'boss' then CurrentAction = 'boss_actions_menu' CurrentActionMsg = _U('shop_menu') CurrentActionData = {} diff --git a/server/main.lua b/server/main.lua index 95b907e5..19c4ee3f 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,6 +1,7 @@ ESX = nil local Categories = {} local Vehicles = {} +local hasSqlRun = false TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) @@ -14,7 +15,13 @@ function RemoveOwnedVehicle (plate) }) end -AddEventHandler('onMySQLReady', function () +AddEventHandler('onMySQLReady', function() + LoadVehicles() +end) + +function LoadVehicles() + hasSqlRun = true + Categories = MySQL.Sync.fetchAll('SELECT * FROM vehicle_categories') local vehicles = MySQL.Sync.fetchAll('SELECT * FROM vehicles') @@ -30,6 +37,15 @@ AddEventHandler('onMySQLReady', function () table.insert(Vehicles, vehicle) end +end + +-- extremely useful when restarting script mid-game +Citizen.CreateThread(function() + Citizen.Wait(100) -- hopefully enough for connection to the SQL server + + if not hasSqlRun then + LoadVehicles() + end end) RegisterServerEvent('esx_vehicleshop:setVehicleOwned') From f62fd2c75a3d3cf3192303bd1d96de7f2c84d9a6 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 24 Jul 2018 15:19:12 +0200 Subject: [PATCH 1626/3224] Tab indent, further cleanup --- client/main.lua | 212 +++++++++++++++++++++++------------------------- locales/en.lua | 6 +- 2 files changed, 105 insertions(+), 113 deletions(-) diff --git a/client/main.lua b/client/main.lua index d742cbe9..f4336760 100644 --- a/client/main.lua +++ b/client/main.lua @@ -69,7 +69,7 @@ function OpenShopMenu () ESX.UI.Menu.CloseAll() - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() FreezeEntityPosition(playerPed, true) SetEntityVisible(playerPed, false) @@ -141,7 +141,7 @@ function OpenShopMenu () DeleteShopInsideVehicles() - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() CurrentAction = 'shop_menu' CurrentActionMsg = _U('shop_menu') @@ -295,7 +295,7 @@ function OpenShopMenu () DeleteShopInsideVehicles() - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() CurrentAction = 'shop_menu' CurrentActionMsg = _U('shop_menu') @@ -310,7 +310,7 @@ function OpenShopMenu () end, function (data, menu) local vehicleData = vehiclesByCategory[data.current.name][data.current.value + 1] - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() DeleteShopInsideVehicles() @@ -532,7 +532,7 @@ function OpenPersonnalVehicleMenu () elements = elements, }, function (data, menu) - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) local heading = GetEntityHeading(playerPed) local vehicleData = data.current.value @@ -787,7 +787,7 @@ AddEventHandler('esx_vehicleshop:hasEnteredMarker', function (zone) end if zone == 'GiveBackVehicle' and Config.EnablePlayerManagement then - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() if IsPedInAnyVehicle(playerPed, false) then local vehicle = GetVehiclePedIsIn(playerPed, false) @@ -802,7 +802,7 @@ AddEventHandler('esx_vehicleshop:hasEnteredMarker', function (zone) end if zone == 'ResellVehicle' then - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() if IsPedInAnyVehicle(playerPed, false) then local vehicle = GetVehiclePedIsIn(playerPed, false) @@ -835,144 +835,136 @@ AddEventHandler('esx_vehicleshop:hasEnteredMarker', function (zone) end) AddEventHandler('esx_vehicleshop:hasExitedMarker', function (zone) - if not IsInShopMenu then - ESX.UI.Menu.CloseAll() - end + if not IsInShopMenu then + ESX.UI.Menu.CloseAll() + end - CurrentAction = nil + CurrentAction = nil end) if Config.EnablePlayerManagement then - RegisterNetEvent('esx_phone:loaded') - AddEventHandler('esx_phone:loaded', function (phoneNumber, contacts) - local specialContact = { - name = _U('dealership'), - number = 'cardealer', - base64Icon = 'data:image/x-icon;base64,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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroMD5K6G8+SuinPkro2z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87Rt3/Mzy+/zI7u+AyPLysMju7cjI7vDUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SuhcPkropz5K6O8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTW/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uvEyPLysMju7YDI7uxYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroDD5K6GQ+Sui7Pkro+z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zZBy/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/DI7vMEyO7tnMju7DgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroOD5K6J8+Suj3Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zxI4/80PsP/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r4Mjy9ozI7vD0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugEPkroXD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87Rt3/Mzy+/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u9MyO7tgMju8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugIPkrobz5K6N8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTW/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7vfMjy9dDI7vAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugEPkroYD5K6N8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zZBy/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju73zI8vWQyO7wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroPD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zxI4/80PsT/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u9MyO7tAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroFD5K6KM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R97/Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yPL2oMju7FgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6GA+SujvPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTW/zI7u/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7rxMjy9ZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SuivPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzf8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy9sDI7uxYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhEPkro4z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zxI4/80PsX/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju65jI8vUgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkrodz5K6Ps+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R97/Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/DI7vH0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroDD5K6Kc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTW/zI7u/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI8vawyO7sOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Bg+SujLPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzf8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u84yO7sbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugoPkro3z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zxI4/80PsX/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uuIyO7orAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6Oc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R97/Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uuoyO7orAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Dw+SujzPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTW/zI7u/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uvUzPL8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugoPkro8z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzf8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uvEyO7orAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6Oc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1I5P80PsX/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uuoyO7orAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Bg+SujfPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R9//Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uuIyO7sbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugMPkroyz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTX/zI7vP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u84yO7sOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Kc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI8vawAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+Suh3Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1I5P81P8X/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7vH0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroRD5K6Ps+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R9//Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/DI8vUgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTX/zI7vP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju65jI7uxYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkrorz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy9swAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6GA+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1I5P81P8X/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy9ZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugUPkro7z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R9//Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7rxMju7FgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6KM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTX/zI7vP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yPL2oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+Sug8Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7tAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroBD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1J5f81P8X/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u9MyO7wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhgPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R+D/Mz3A/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI8vWQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroCD5K6N8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OkXY/zI7vP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju73zI7vAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhvPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdC0P8yO7r/Mju6/zI7uv8yO7r/Mju6/zI6uP8yOqn/Mjqp/zI6q/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI6qf8yOqn/Mjqp/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/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Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/MjVa/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8yNVj/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7vD0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6J8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1J5f81P8b/Mju6/zI7uv8yO7r/Mju6/zI7uv8yN37/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjmY/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI4jf8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8yN4n/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy9owAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugMPkro9z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R+D/Mz3A/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zMzQf8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8yNVv/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/MjRO/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zI0Tv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r4Mju7DgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6GQ+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OkXY/zI7vP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yOZ7/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzN/8yOrP/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI6rf8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zI6qf8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7tn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MjVl/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zI3fv8yO7r/IILV/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/H4fW/zI7uv8yNnD/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjZt/zI7uv8oY8n/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8nZcr/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI8vTUAAAAAAAAAAD5K6G8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/xyi6/8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Ho3Z/zI7uv8yOqn/MzM5/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zNEP/Mjq1/zI7uv8XqOP/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Vr+b/Mju6/zI6sf8zMz3/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzPf8yOq//Mju6/x+H1v8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yJ60v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy+cgAAAAAAAAAAPkropz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Kn7q/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Tuen/MEO9/zI7uv8yN4n/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzM5/zI5nv8yO7r/K1TD/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8pXcb/Mju6/zI4lv8zMzX/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzX/MjiU/zI7uv8xP7v/E7fp/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8RwOz/Lkm//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv81P8epAAAAAAAAAAA+SujbPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P86U+j/EcDt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8hgNT/Mju6/zI7uv8yN4f/MzM3/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzP/8yOJr/Mju6/zI7uv8anN7/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xii4f8yO7r/Mju6/zI4kv8zMzv/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzM5/zI4kv8yO7r/Mju6/yJ60v8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xuY3f8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/N0LP/z1J59sAAAAAPkroDD5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8fnOv/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHA7P8rVsT/Mju6/zI7uv8yOaX/MjVd/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzN/8yNmf/Mjqv/zI7uv8yO7r/JW/O/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yN20P8yO7r/Mju6/zI6qf8yNWX/MzM1/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzM1/zI1Yf8yOqn/Mju6/zI7uv8rVMP/Er7r/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/KV/H/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju8/zpF2P8+Suj/Pkro/zlF2Qw+Sug0Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/y9v6f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xS16P8sUML/Mju6/zI7uv8yO7r/Mjqr/zI3hf8yNnL/MjZl/zI2dP8yOIv/Mjqv/zI7uv8yO7r/Mju6/yhhyP8RwOz/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcDs/ydny/8yO7r/Mju6/zI7uv8yOq//MjiJ/zI2dP8yNmX/MjZ0/zI4if8yOq//Mju6/zI7uv8yO7r/LFDC/xS16P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xar5P8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zM9wf88R+D/Pkro/z5K6P8+Suj/PEfhND5K6Fw+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUzo/xS47P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xO36f8oYcj/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8kdM//EcDs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcDs/yN20P8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/ylcx/8Utej/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/JHTP/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv81P8j/PUnl/z5K6P8+Suj/Pkro/z5K6P88SONcPkrogz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/JI3r/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8ckdr/LFLC/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8pX8f/GKLh/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xik4v8oYcj/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yxQwv8dj9r/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xO56f8wQbz/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/OELR/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1J5oM+SuifPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P81YOn/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Fqvk/x+H1v8jdtD/JW7N/yN40f8ejdn/FLPn/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Us+f/HY/Z/yN40f8lbs3/JHTP/x+H1v8XqOP/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/H4fW/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy9/zpG2/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkronz5K6L8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8Yrez/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8sUML/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zQ+w/88SOL/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Sui/Pkro1z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/ymA6v8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Gpze/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv82QMv/PUnm/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Nc+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OVXo/xHA7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8oY8n/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/OUTW/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro4z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Hp7r/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/FbHm/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mzy//ztH3v8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8vcen/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8jeNH/Mju6/zI7uv8yO7r/Mju6/zQ+xf88SOP/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zxN6P8UuOz/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Er7r/zBDvf8yO7r/Mju6/zI7uv83Qc7/PUnn/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/ySP6/8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8ei9j/Mju6/zI7uv8yO7z/OUTY/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/LnPp/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yZpy/8yO7r/Mz3A/ztH4P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P85Vej/Er7s/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/F6jj/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/GKLh/xHC7f8Rwu3/EcLt/xyV3P8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/xat5f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Svuv/L0e+/zU/x/89SeX/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8td+r/EcDt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8ejdn/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8lbs3/EcLt/xHC7f8Rwu3/LkzA/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/G5jd/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcDt/yVuzv84QtH/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P81YOn/Jojq/yKV6/8ilev/IpXr/yKV6/8ilev/IpXr/yKV6/8ilev/HaLr/xHC7f8Rwu3/EcLt/x2P2v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yVuzf8Rwu3/EcLt/xHC7f8uTMD/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8WreX/EcLt/xHC7f8Vr+X/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/H5Hg/yKV6/8ilev/IpXr/yaK6v81Xeb/OkXa/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8yaOn/EcLt/xHC7f8Rwu3/HY/a/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/JW7N/xHC7f8Rwu3/EcLt/y5MwP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/MEG8/xHC7f8Rwu3/EcLt/yJ60v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zU/x/89SeX/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro4z5K6Nc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zJo6f8Rwu3/EcLt/xHC7f8dj9r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8lbs3/EcLt/xHC7f8Rwu3/LkzA/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8pXcb/EcLt/xHC7f8Rwu3/KV/H/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv83Qs7/PUnn/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujXPkrovz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/M2bp/xHC7f8Rwu3/EcLt/xqa3v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yVuzf8Rwu3/EcLt/xHC7f8uTMD/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yF+0/8Rwu3/EcLt/xK76v8xP7v/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/OUPV/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6L8+SuifPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P84Wej/EcLt/xHC7f8Rwu3/GaDg/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/JW7N/xHC7f8Rwu3/EcLt/y5MwP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Fqvk/xHC7f8Rwu3/HZHa/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju8/zpF2v8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkronz5K6IM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/ztR6P8Rwu3/EcLt/xHC7f8ZoOD/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8lbs3/EcLt/xHC7f8Rwu3/LkzA/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/ydnyv8Rwu3/EcLt/xHC7f8pXMb/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zM8v/87R+D/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuiDPkroXD5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/xO87P8Rwu3/EcLt/xWv5f8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yVuzf8Rwu3/EcLt/xHC7f8uTMD/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8xPbr/Fa/m/xHC7f8Rwu3/F6nj/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv80PsP/PEjj/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Fw+Sug0Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/GK3s/xHC7f8Rwu3/FbHm/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/JW7N/xHC7f8Rwu3/EcLt/y5MwP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yVtzf8Rwu3/EcLt/xHC7f8ma8z/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/NUDI/z1J5f8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroND5K6Aw+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8fnOv/EcLt/xHC7f8Rwu3/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8lbs3/EcLt/xHC7f8Rwu3/LkzA/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8xPbr/Fa/m/xHC7f8Rwu3/Fa/m/zE9uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zdCz/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SugMAAAAAD5K6Ns+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/yaI6v8Rwu3/EcLt/xHC7f8wQ73/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/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Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/ymA6v8TvOz/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHA7f8fnOv/N1vo/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6M8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroXD5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zlV6P8kjer/FLjs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xmr7P8nhur/OFno/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugEPkro4z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P88Tej/MWzp/yaK6v8cpOv/Fbbs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Svuz/FrPs/xum7P8gmOv/J4bq/y9v6f85Vej/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6N8+SugEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhvPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zhZ6P84Wej/OFno/zhZ6P84Wej/OFno/zhZ6P84Wej/OFno/zhZ6P88Tej/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkrobwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Ag+SujfPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6N8+SugIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6GA+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroBD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6M8+SugEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroPD5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkrooz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6KMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugUPkro7z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujvPkroFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhgPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuivPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuivAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro4z5K6BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6EQ+Suj7Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Ps+SuhEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Hc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkrodwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Kc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6KcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroDD5K6Ms+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujLPkroDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroGD5K6N8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro3z5K6BgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6Oc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Oc+SugoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6PM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujzPkroKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroPD5K6PM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro8z5K6DwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6Oc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Oc+SugoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6N8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujfPkroKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroGD5K6Ms+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkroyz5K6BgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroDD5K6Ks+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Kc+SugMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Hc+Suj7Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Ps+Suh3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6EQ+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujjPkroRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SuivPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkrorz5K6BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhgPkro7z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro7z5K6GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugUPkrooz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6KM+SugUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroPD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6M8+Sug8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroBD5K6GA+SujfPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6N8+SuhgPkroBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Ag+SuhvPkro3z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6N8+SuhvPkroCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugEPkroXD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6M8+SuhcPkroBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Dg+SuifPkro9z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro9z5K6J8+Sug4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugMPkroZD5K6Ls+Suj7Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj7Pkrouz5K6GQ+SugMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SuhcPkropz5K6O8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6O8+SuinPkroXD5K6BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6DA+SuhvPkropz5K6Ns+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujbPkropz5K6G8+SugwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Aw+Sug0PkroXD5K6IM+SuifPkrovz5K6Nc+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujjPkro1z5K6L8+SuifPkrogz5K6Fw+Sug0PkroDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD////////wAAAP////////////////AAAAAP//////////////8AAAAAAP/////////////4AAAAAAAf////////////4AAAAAAAB////////////wAAAAAAAAD///////////wAAAAAAAAAP//////////wAAAAAAAAAA//////////4AAAAAAAAAAH/////////4AAAAAAAAAAAf////////8AAAAAAAAAAAD////////8AAAAAAAAAAAAP///////+AAAAAAAAAAAAB////////AAAAAAAAAAAAAP///////AAAAAAAAAAAAAA///////gAAAAAAAAAAAAAH//////wAAAAAAAAAAAAAA//////4AAAAAAAAAAAAAAH/////8AAAAAAAAAAAAAAA/////+AAAAAAAAAAAAAAAH/////AAAAAAAAAAAAAAAA/////gAAAAAAAAAAAAAAAH////wAAAAAAAAAAAAAAAA////8AAAAAAAAAAAAAAAAP///+AAAAAAAAAAAAAAAAB////AAAAAAAAAAAAAAAAAP///gAAAAAAAAAAAAAAAAB///4AAAAAAAAAAAAAAAAAf//8AAAAAAAAAAAAAAAAAD//+AAAAAAAAAAAAAAAAAAf//gAAAAAAAAAAAAAAAAAH//wAAAAAAAAAAAAAAAAAA//4AAAAAAAAAAAAAAAAAAH/+AAAAAAAAAAAAAAAAAAB//AAAAAAAAAAAAAAAAAAAP/wAAAAAAAAAAAAAAAAAAD/4AAAAAAAAAAAAAAAAAAAf+AAAAAAAAAAAAAAAAAAAH/gAAAAAAAAAAAAAAAAAAB/wAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAD+AAAAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAAAAAAH4AAAAAAAAAAAAAAAAAAAB8AAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAPgAAAAAAAAAAAAAAAAAAAH4AAAAAAAAAAAAAAAAAAAB+AAAAAAAAAAAAAAAAAAAAfwAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAD/gAAAAAAAAAAAAAAAAAAB/4AAAAAAAAAAAAAAAAAAAf+AAAAAAAAAAAAAAAAAAAH/wAAAAAAAAAAAAAAAAAAD/8AAAAAAAAAAAAAAAAAAA//gAAAAAAAAAAAAAAAAAAf/4AAAAAAAAAAAAAAAAAAH//AAAAAAAAAAAAAAAAAAD//4AAAAAAAAAAAAAAAAAB//+AAAAAAAAAAAAAAAAAAf//wAAAAAAAAAAAAAAAAAP//+AAAAAAAAAAAAAAAAAH///gAAAAAAAAAAAAAAAAB///8AAAAAAAAAAAAAAAAA////gAAAAAAAAAAAAAAAAf///8AAAAAAAAAAAAAAAAP////AAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAB/////AAAAAAAAAAAAAAAA/////4AAAAAAAAAAAAAAAf/////AAAAAAAAAAAAAAAP/////4AAAAAAAAAAAAAAH//////AAAAAAAAAAAAAAD//////4AAAAAAAAAAAAAB///////AAAAAAAAAAAAAA///////8AAAAAAAAAAAAA////////gAAAAAAAAAAAAf///////8AAAAAAAAAAAAP////////wAAAAAAAAAAAP////////+AAAAAAAAAAAH/////////4AAAAAAAAAAH//////////AAAAAAAAAAD//////////8AAAAAAAAAD///////////wAAAAAAAAD////////////gAAAAAAAH////////////+AAAAAAAH/////////////8AAAAAAP//////////////8AAAAA////////////////8AAAD////////ygAAABgAAAAwAAAAAEAIAAAAAAAgJQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroCD5K6Ck9SedOPkrodz5K6Js9See9Pkro1j5K6Ok9Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89SefpPkro1j5K6L08SOSbO0fgdzdC0U4zPcEsMjy9CQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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Mju6/zE6uf4yO7r/Mju6/zI6sP4zMzb/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjL+MzMz/zMzM/8yNWL+Mjq5/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mjq5/zI1Wv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIzOv4yOrX/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uv0yO7srAAAAAAAAAAAAAAAAAAAAAD1J54A+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/O0fg/zQ9wv4yO7r/Mju6/zE6uf4yO7r/Mju6/zI4lf4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjL+MzMz/zMzM/8yNEj+Mjq0/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mjqx/zIzQ/4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4yOZ3/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7uDAAAAAAAAAAAAAAAAPUnnCD1J5809Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/46Rdn+Mjy9/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jI3h/4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yM0P+Mjqx/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+Mjqt/jIzO/4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yOJP+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4yO7rPMju6CQAAAAAAAAAAPkroKD1J5/g+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Suf+NGPp/yWI5/4ei9n/HovY/x6L2P4ei9j/HovY/x6L2P4ei9j/JmrM/zI4kv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjL+MzMz/zMzM/8yNEf+MD+1/yCB1P8ei9j+HovY/x6L2P8ei9j+HovY/x6L2P8ei9j+HovY/x6L2P8ei9j+HovY/x6L2P8ei9j+HovY/x6L2P8ei9j+HovY/x6L2P4fhdb/MEGz/zIzQf4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4yOZz/KGPJ/x6L2P4ei9j/HovY/x6L2P4ei9j/HovY/x6L2P4eitj/JHLO/zBDvf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r5Mju6KgAAAAAAAAAAPkroaT1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P8xa+n+E7vs/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/HY3Z/zI6rv4zMzX/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjL+MzMz/zMzM/8yNV7+L0a9/xO26P8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Suur/Lke9/zI0V/4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIzOP4yOrT/H4jX/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xmg4P4xPLr/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6awAAAAAAAAAAPUnnrD1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1K5/4couv+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+GKPh/jE7uv4yNWL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyM/4yOJf+K1TD/hHB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+KlfE/jI4jf4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jI2af4xOrn+GKHg/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4oX8f+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+Mju7sAAAAAA+SugIPkro4D1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P8enuv+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/Errq/y1Pwf4yOaX/MjNA/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjL+MzMz/zI1Yf8xOrn+IX3T/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/IIPV/zE6uP4yNVr/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MjNE/zI5qv4tTMD/E7np/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xHB7P4qWcX/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju84DQ+xgg+SugpPkro8z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P8udOn+EcHt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/x+H1v4yO7r/MjiW/zIzQP4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjP+MjVc/zI6sf8vRr7+FLLm/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/FLTo/y5Iv/4yOq3/MjRW/zIyM/4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4yM0P/Mjmd/zE6uf4ggtT/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xap4/4xO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7z/OUTW8zhD1Ck9SedOPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/46Uuj+FbXs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hHA7P4pX8f+MTq5/jI6rv4yNmv+MjND/jIzM/4yMjL+MjM3/jI0Tv4yN4f+MTq4/jE8uv4cktv+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/huW3P4xPbr+Mjq2/jI3hP4yNEz+MjM2/jIyMv4yMzT+MjRF/jI2b/4yOrD+MTq5/ildx/4Rv+z+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EcHs/iVvzf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jM9wP47R9/+PUnn/jtG3k0+Suh3Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+I5Hq/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Ttuj/KGHI/zE7uv4yOrn/Mjqx/zI5p/4yOZ7/Mjqq/zI6tf8xOrn+MEG8/x+G1v8Rwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xHB7P4eitj/MEG8/zE6uf4yOrX/Mjqq/zI5nv4yOaj/Mjqy/zE6uf4xO7r/KV/H/xO26P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/FLPn/y9Evf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/NT/I/zxI4/4+Suj/Pkro/zxI43c+SuibPkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+M2Xp/xHB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/Er3r/x+G1v4uSL7/Mju6/zE6uf4yO7r/Mju6/zI7uv8pX8f+GKLh/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/GKPh/yhgyP4yO7r/Mju6/zE6uf4yO7r/Mju6/y9Gvv4fhdb/Erzq/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/H4XW/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE7uv43QtD/PUnm/z1J5/4+Suj/Pkro/z1J5ps9See9PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PE7o/hmr6/4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Rv+z+GKLh/h6K1/4gg9X+HJLb/hWx5v4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Useb+HJLb/iCD1f4eidf+GaHg/hG/7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4SvOr+LFDB/jE6uf4xOrn+MTq5/jE6uf4xOrn+Mzy+/jpF2f49Sef+PUnn/j1J5/49Sef+PUnn/j1J570+SujWPkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/yiD6v4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4bmN3/MTy6/zE6uf4yO7r/Mju6/zE6uf40PsP/O0fg/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J59Y+SujpPkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/zhY6P4Rwe3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4oYcj/Mju6/zE6uf4yO7r/Mju6/zZAyf49SeX/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5+k9Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/4doev+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hWt5f4xOrn+MTq5/jE6uf4yO7v+OEPT/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4tden/EcHt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcHs/yN1z/4yO7r/Mju6/zM8v/46Rtv/PUnn/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/46U+j/Fbbs/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/E7bo/y5Hvv4yO7r/ND7E/zxH4f4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+HaHr/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+GZ3f/jE7uv43Qc7+PUnm/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/L3Hp/xK/7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/JmrM/ypYxf4qWMX/KljF/ypYxf8qWMX+KljF/ypYxf8qWMX+KljF/ypYxf8qWMX+KljF/yN20P8Qwez+EcLt/yJ80v8qWMX+KljF/ypYxf8qWMX+KljF/ypYxf8qWMX+KljF/ypYxf8qWMX+KljF/ypYxf4qWMX/KljF/ypYxf4qWMX/KljF/x6K2P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rvuz/J2jO/zlE1f49Sef/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUvo/zBu6f4gmOv/HaDr/x2g6/4doOv/HaDr/x2g6/4doOv/FLjs/xDB7P4Rwu3/KljF/zE6uf4yO7r/Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/x2O2f4Rwu3/Eb7r/xme3/4anN7/Gpze/xqc3v4anN7/Gpze/xqc3v4anN7/Gpze/xud4v4doOv/HaDr/yCa6/4ua+L/Okfe/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/49SefpPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+Hpzr/hDB7P4Qwez+KljF/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/ihhyP4Qwez+EMHs/iZpy/4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MT27/hel4v4Qwez+Fqrk/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+ND7E/jxI4v49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5+k+SujWPkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/H5zr/xDB7P4Rwu3/KlvG/zE6uf4yO7r/Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Lki//xO56f4Rwu3/HovY/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE7uv41QMn/PUjk/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J59Y+Sui9Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/IpPr/xDB7P4Rwu3/J2XK/zE6uf4yO7r/Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/J2bK/xDB7P4Rwu3/KGDI/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zZBzf49Seb/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5709SeebPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+JYrq/hDB7P4Qwez+JmfK/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/ihhyP4Qwez+EMHs/iZpy/4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4wP7v+GKXi/hDB7P4Wq+T+MEG8/jE6uf4xOrn+MTq5/jE6uf4yO7v+OEPU/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J55s+Suh3Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/K3zq/xDB7P4Rwu3/JHHO/zE6uf4yO7r/Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mju6/zE6uf4masz/EcDs/xDB7P4jdtD/Mju6/zE6uf4yO7r/Mju6/zI8vf46Rdr/PUnn/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J53c9SedOPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+MWzp/hDB7P4Qwez+InvS/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/ihhyP4Qwez+EMHs/iZpy/4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE8uv4WquT+EMHs/hO36P4wQrz+MTq5/jE6uf4xOrn+MzzA/jtG3v49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+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Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj4PkroKAAAAAAAAAAAPUnnCD1J5809Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/4kjOr+EMHs/hem4v4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/ihhyP4Qwez+EMHs/iZpy/4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/iRxzv4Qwez+EMHs/h2N2P4zPcD+O0fe/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49SefNPUnnCAAAAAAAAAAAAAAAAD1J538+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/44WOj/FLfs/xDB7P4nZ8v/Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+JmrL/xK96/4Rwu3/GKTh/zJGyP48SOP/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suh/AAAAAAAAAAAAAAAAAAAAAD1J5yg+Suj9Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Kn3q/xHA7P4Vsuf/LVHF/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE+u/8iedH+Erzq/xDB7P4WrOX/MVPR/z1J5f4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/0+SugoAAAAAAAAAAAAAAAAAAAAAAAAAAA9SefGPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PEzo/iKT6v4Qwez+FbHo/ihmzf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/ihhyP4Qwez+EMHs/iZpy/4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xPbr+KGLJ/hmf4P4Qwez+EMHs/hes6P4zVNj+PUnm/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J58YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhdPkro/j1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1L5/4jkev/EcDt/xHC7f8UtOj+GZ7f/xqc3v8anN7+Gpze/xqc3v8anN7+Gpze/xem4v8Qwez+EcLt/xep4/8anN7+HJLa/x2P2f8fiNf+HY7Z/xqb3v8Tt+n+EcLt/xHC7f8Svuz+IpLr/zpS6P4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/j1J510AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugQPkro3z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/49TOj/L3Hp/xms7P8RwOz+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Rwez+Fbfs/yGW6/80Y+n+PUvo/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro3z1J5w8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnnfj1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/jxO6P4xa+n+JYzq/hqo6/4Tu+z+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EcHs/hS47P4Zq+z+H5zr/iaH6v4wben+OlTo/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnnewAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroGD1J5+g+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+O0/o/zlV6P85Vej+OVXo/zlV6P85Vej+OVXo/zlV6P89TOj+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+SujoPkroGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J53g+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suh4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J5w49SefkPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5+Q9SecOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhaPkro+z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro+z1J51oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugFPkrouD1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/PkrouD1J5wUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnnLj1J5/A9Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49SefwPUnnLgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J52o+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+SuhqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J5wM+SuixPkro/j5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/j1J57A+SugDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SecaPUnn2j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn2j1J5xoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroND5K6Ow9Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+SujsPkroNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6FM9Sef5Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/k+SuhTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SedxPUnn+j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn+j1J53EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkrodz1J5/w+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj8PkrodwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroBD1J53c+Suj6Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/o+Suh3PkroBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SedxPUnn+T1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn+T1J53EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroUz1J5+0+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+SujsPkroUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J5zU+SujaPkro/j1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/j1J59o+Sug0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SecaPUnnsT1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnnsD1J5xoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroAz1J52o+SujwPkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/A+SuhqPkroAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuguPkrouD1J5/s+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj7PkrouD1J5y4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnnBj1J51o9SefkPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5+Q9SedaPUnnBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugOPkroeD1J5+g+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+SujoPkroeD1J5w4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J5xg+Suh8Pkro3z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj+Pkro3z1J53s+SugYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnnDz1J5109SefGPUnn/T1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/T1J58Y9SeddPUnnDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6IA9SefNPkro+D5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro+D1J580+Suh/PkroKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SecIPkroKD5K6Gk9SeesPkro4D5K6PM9Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+SujzPkro4D1J56w+SuhpPkroKD1J5wgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnnBz1J5yk9SedNPUnndz1J55s9See9PUnn1j1J5+k9Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49SefpPUnn1j1J5709SeebPUnndz1J5009SecpPUnnBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////+AAAH///////////gAAAAf/////////+AAAAAH/////////wAAAAAA/////////AAAAAAAP///////8AAAAAAAD///////wAAAAAAAA///////gAAAAAAAAf/////+AAAAAAAAAH/////8AAAAAAAAAD/////4AAAAAAAAAB/////wAAAAAAAAAA/////gAAAAAAAAAAf///+AAAAAAAAAAAH///+AAAAAAAAAAAH///8AAAAAAAAAAAD///4AAAAAAAAAAAB///wAAAAAAAAAAAA///gAAAAAAAAAAAAf//AAAAAAAAAAAAAP//AAAAAAAAAAAAAP/+AAAAAAAAAAAAAH/8AAAAAAAAAAAAAD/8AAAAAAAAAAAAAD/4AAAAAAAAAAAAAB/4AAAAAAAAAAAAAB/wAAAAAAAAAAAAAA/wAAAAAAAAAAAAAA/gAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAfAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAPgAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAfwAAAAAAAAAAAAAA/wAAAAAAAAAAAAAA/4AAAAAAAAAAAAAB/4AAAAAAAAAAAAAB/8AAAAAAAAAAAAAD/8AAAAAAAAAAAAAD/+AAAAAAAAAAAAAH//AAAAAAAAAAAAAP//AAAAAAAAAAAAAP//gAAAAAAAAAAAAf//wAAAAAAAAAAAA///4AAAAAAAAAAAB///8AAAAAAAAAAAD///+AAAAAAAAAAAH///+AAAAAAAAAAAH////gAAAAAAAAAAf////wAAAAAAAAAA/////4AAAAAAAAAB/////8AAAAAAAAAD/////+AAAAAAAAAH//////gAAAAAAAAf//////wAAAAAAAA///////8AAAAAAAD////////AAAAAAAP////////wAAAAAA/////////+AAAAAH//////////gAAAAf//////////+AAAH/////8oAAAASAAAAJAAAAABACAAAAAAAGBUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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Pkro/z5K6P8+Suj/Pkro/zlV6P8wW9X/K1XE/ytVxP8rVcT/K1XE/yxSw/8yOZf/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjVb/y9Hvv8rVcT/K1XE/ytVxP8rVcT/K1XE/ytVxP8rVcT/K1XE/ytVxP8rVcT/K1XE/ytVxP8rVcT/K1XE/y5Iv/8yNFP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Mjmf/yxSwv8rVcT/K1XE/ytVxP8rVcT/K1XE/yxPwf8xPbr/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uoAAAAAAAAAAAD5K6MU+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/LnHp/xO77P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xO26P8wQK//MzM0/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjZw/yF90v8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yCC1P8yNmr/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzb/MT20/xSz5/8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHA7P8bl9z/MTu6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uscAAAAAPkroFz5K6PE9Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Suj/Gavs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hG+6/8tTsH/MjVf/jMzM/8yMjL+MzMz/zIyMv4zMzP/MjIy/jMzM/8zMzX/Mjml/huW3P8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hqZ3f8yOZ/+MzM0/zMzM/8yMjL+MzMz/zIyMv4zMzP/MjIy/jMzM/8yNWX+LUzA/xG96/8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Qwez+KljF/zI7uv8xOrn+Mju6/zE6uf4yO7r/MTq5/jI7uvIzPL8YPkroQz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/IJjr/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8hfNL/Mjmq/zI0Rf8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzNP8yN37/Lki+/xO56f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xK66v8uS8D/MjZ3/zMzNP8zMzP/MzMz/zMzM/8zMzP/MzMz/zI0Sf8yOq3/InnR/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8SvOr/L0O9/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI8vf82Qc1DPkrodD5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/MWvp/hHB7P8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Suur/LU/B/jI6rf8yNmb+MjM8/zIyMv4zMzX/MjRN/jI4kP8xO7r/HJLa/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8clNv+MTy6/zI4jP8yNEz+MzM1/zIyMv4yMz7/MjZp/jI6sP8tTsH+E7np/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8ei9j+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/ND7D/jxH4f87R990PkronT5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PE7o/xex7P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Fa/l/ytWxP8xO7n/Mjqy/zI5p/8yOq3/Mjq3/zBBvP8fiNf/EcHs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwez/HorY/zBBvP8yOrf/Mjqt/zI5p/8yOrP/MTu6/ytUw/8Vr+X/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xG/7P8rVcP/Mju6/zI7uv8yO7r/Mju6/zI7uv82QMv/PUnl/z5K6P89SeWdPkrowT5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/iaI6v8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hK96/8djdn+KGPJ/yxSwv4qWcX/I3fQ/hWt5f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Qwez+EcLt/xWu5f8iedH+KlnF/yxSwv4oYsn/HY3Z/hK86/8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hmf3/8xO7r+Mju6/zI7uv8xOrn+Mju7/zhD1P49Sef/PUnn/j5K6P89SefBPkro3j5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zZd6P8Rwez/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHA7P8Rwez/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcHs/xHA7P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/ydnyv8yO7r/Mju6/zI7uv8zPL//O0bc/z1J5/8+Suj/Pkro/z5K6P8+SujePkro8j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j1K6P8bp+v+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/FbHm/jE+u/8xOrn+Mju6/zQ+xf88SOL+Pkro/z1J5/4+Suj/PUnn/j5K6P89SefyPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8reur/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/InvS/zI7uv8yO7r/N0HO/z1J5v8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P85VOj/E7vs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Su+r/Lkm//zI7vP85RNb/PUnn/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+G6Tr/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+FLPn/xSy5/4Usuf/FLLn/hSy5/8Usuf/FLLn/hSy5/8Usuf+FLLn/xK96/4Rwu3/E7bo/hSy5/8Usuf/FLLn/hSy5/8Usuf+FLLn/xSy5/4Usuf/FLLn/hSy5/8Usuf+FLLn/xSz5/8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4YoeD/Mz3A/jtH3/89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/M2Xp/xaz7P8Sv+z/Er/s/xK/7P8Sv+z/Eb/s/xHB7f8Rwu3/LFPD/zE/u/8xP7v/MT+7/zE/u/8xP7v/MT+7/zE/u/8xP7v/MT+7/xqc3v8Rwu3/KGDI/zE/u/8xP7v/MT+7/zE/u/8xP7v/MT+7/zE/u/8xP7v/MT+7/zE/u/8xP7v/MT+7/yxTw/8Rwu3/EcHs/xG+6/8Rvuv/Eb7r/xG+6/8Rvuv/Eb7r/xG+6/8Sv+z/Er/s/xay7P8uXtT/PEjk/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro8j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1K5/47Uej/O1Ho/jtR6P87Uej/N1ro/hO77P8Qwez+LFHC/zE6uf4yO7r/MTq5/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/xqb3v4Rwu3/KV3H/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/zE6uf4yO7r/MTq5/jI7uv8xOrn+Mju6/ydnyv8Qwez+HJTb/y9Dvf4wQ73/L0O9/jBDvf8vQ73+MEO9/zVJ0P87Uef+O1Ho/z1L5/49Sef/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89SefyPkro3j5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OlLo/xO67P8Rwu3/K1XD/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/xqb3v8Rwu3/KV3H/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/x+G1v8Rwu3/JHLO/zI7uv8yO7r/Mju6/zI7uv8yO7r/OEPU/z1J5/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujePkrowT5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PE3o/hW17P8Qwez+KlrG/zE6uf4yO7r/MTq5/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/xqb3v4Rwu3/KV3H/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/zE6uf4yO7r/MTq5/jI7uv8xOrn+MEG8/xWw5v8Su+r+Lkm//zE6uf4yO7r/MTq5/jI8vf86Rdn+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89SefBPkronT5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/xit7P8Rwu3/KGPJ/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/xqb3v8Rwu3/KV3H/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/I3fQ/xHB7f8dkNr/MTu6/zI7uv8yO7r/Mzy//ztH3/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuidPkrodD5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/h6d6/8Qwez+JmvM/zE6uf4yO7r/MTq5/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/xqb3v4Rwu3/KV3H/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/zE6uf4yO7r/MTq5/jI7uv8wQLz+FLTo/xG/7P8rU8P+Mju6/zE6uf40PsP/PEji/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sed0PkroQz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/yeG6v8Rwu3/InnR/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/xqb3v8Rwu3/KV3H/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8ieNH/EcLt/xyU2/8xO7r/Mju6/zU/yP89SeX/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/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PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J54YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6A4+SujfPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro3z5K6A4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhVPkro/T5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj9PkroVQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugCPUnnpD5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89SeekPkroAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroEz5K6Nw+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Nw+SugTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Dc+SujxPUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro8T5K6DcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhYPkro+z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj7PkroWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnncz5K6Pw9Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6Pw9SedzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6H8+Suj8Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/D5K6H8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SedzPkro+z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj7PUnncwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroWD5K6PI+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6PE+SuhYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Dc+SujcPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro3D5K6DcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugTPUnnpD5K6P0+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/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AAAAAAAAAAAAAAAA////4AAH////AAAA///+AAAAf///AAAA///4AAAAH///AAAA///gAAAAB///AAAA//+AAAAAAf//AAAA//4AAAAAAH//AAAA//wAAAAAAD//AAAA//gAAAAAAB//AAAA//AAAAAAAA//AAAA/+AAAAAAAAf/AAAA/8AAAAAAAAP/AAAA/4AAAAAAAAH/AAAA/wAAAAAAAAD/AAAA/gAAAAAAAAB/AAAA/AAAAAAAAAA/AAAA+AAAAAAAAAAfAAAA+AAAAAAAAAAfAAAA8AAAAAAAAAAPAAAA8AAAAAAAAAAPAAAA4AAAAAAAAAAHAAAA4AAAAAAAAAAHAAAAwAAAAAAAAAADAAAAwAAAAAAAAAADAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAwAAAAAAAAAADAAAAwAAAAAAAAAADAAAA4AAAAAAAAAAHAAAA4AAAAAAAAAAHAAAA8AAAAAAAAAAPAAAA8AAAAAAAAAAPAAAA+AAAAAAAAAAfAAAA+AAAAAAAAAAfAAAA/AAAAAAAAAA/AAAA/gAAAAAAAAB/AAAA/wAAAAAAAAD/AAAA/4AAAAAAAAH/AAAA/8AAAAAAAAP/AAAA/+AAAAAAAAf/AAAA//AAAAAAAA//AAAA//gAAAAAAB//AAAA//wAAAAAAD//AAAA//4AAAAAAH//AAAA//+AAAAAAf//AAAA///gAAAAB///AAAA///4AAAAH///AAAA///+AAAAf///AAAA////4AAH////AAAAKAAAAEAAAACAAAAAAQAgAAAAAAAAQgAA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Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6vTI7ugYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6J8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P88R+H/ND3B/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7uiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6G0+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P86Rdr/Mjy8/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6DA+Suj4Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1J5/84QtH/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r4Mju7MgAAAAAAAAAAAAAAAAAAAAAAAAAA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EcLt/xHC7f8Rwu3/Fa7l/zI5pf8zMzX/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjVj/ypYxf8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/K1XE/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zM8vyk+SuhgPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/yGV6/8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8dkNr/Mjqt/zI0Sf8zMzP/MzMz/zMzM/8zMzP/MzM2/zI4i/8qWcX/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8pXcf/MjeF/zMzNf8zMzP/MzMz/zMzM/8zMzP/MjRM/zI6sP8ejNj/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/E7fo/zE+u/8yO7r/Mju6/zI7uv8yO7r/Mju6/zM8v/84QtJhPkrojz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8yaOn/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcHs/ydlyv8yOrT/Mjd9/zI1V/8yNFD/MjZp/zI5ov8vRL3/Fqzl/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Fa7l/y9Gvv8yOaD/MjZo/zI0UP8yNVj/Mjd//zI6tf8nZcn/EcHs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yCB1P8yO7r/Mju6/zI7uv8yO7r/Mju6/zU+xv89SOT/PEjijz5K6Lc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUro/xay7P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rv+z/InvS/zBAvP8yO7r/Mju6/zI7uv8pXcf/Fa7l/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8VruX/KV/H/zI7uv8yO7r/Mju6/zBAvP8ietL/Eb7r/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xG/7P8uSsD/Mju6/zI7uv8yO7r/Mju6/zdBzv89Sef/Pkro/z1J5rc+SujXPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8nhur/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8SvOr/GaDg/xqa3v8Vseb/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Vseb/Gpre/xmf4P8Su+r/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8bltz/Mju6/zI7uv8yO7r/Mju8/zpF2P8+Suj/Pkro/z5K6P8+SujXPkro7j5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/N1ro/xHB7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/KV3H/zI7uv8yO7r/Mz3B/zxH4P8+Suj/Pkro/z5K6P8+Suj/Pkro7j5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8bpev/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Fqvk/zI7uv8yO7r/NT/I/z1J5f8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/LHjp/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yRxzv8yO7r/OELS/z1J5/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zlX6P8Rwez/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Ervq/xeo4/8XqOP/F6jj/xeo4/8XqOP/F6jj/xeo4/8XqOP/Fq3l/xHC7f8Ttuj/F6jj/xeo4/8XqOP/F6jj/xeo4/8XqOP/F6jj/xeo4/8XqOP/F6jj/xeo4/8VsOb/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHB7P8vS8L/Okbb/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/LHjq/xqo6/8Zq+z/Gavs/xmr7P8Yruz/EcLt/xeo4/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/ytUw/8Rwu3/H4fW/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/JW7N/xHC7f8VsOb/F6jj/xeo4/8XqOP/F6jj/xeo4/8XqeX/Gavs/xqo6/8pdN//PEji/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujuPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OFno/xHC7f8XqOP/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8rVMP/EcLt/x+H1v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/x+I1/8Rwu3/K1PD/zI7uv8yO7r/Mju6/zI7uv8zPL//O0ff/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujuPkro1z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zlU6P8Rwu3/Fa/m/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/K1TD/xHC7f8fh9b/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8Wq+T/FLTn/zE8uv8yO7r/Mju6/zI7uv80PcL/PEjj/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro1z5K6Lc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P89S+j/EcDs/xS06P8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/ytUw/8Rwu3/H4fW/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8oY8n/EcLt/yGA1P8yO7r/Mju6/zI7uv81P8f/PUnm/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Lc+SuiPPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/xaz7P8Svev/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8rVMP/EcLt/x+H1v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8xO7r/F6jj/xK96/8uR77/Mju6/zI7uv83Qc7/PUnn/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuiPPkroYD5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8enuv/EcLt/zBCvP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/K1TD/xHC7f8fh9b/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/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Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Pc+SugYAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuiVPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/O1Ho/ztR6P87Uej/O1Ho/ztR6P89Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuiVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroGT5K6PM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujzPkroGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+Suh3Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkrodwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroBT5K6NM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro0z5K6AUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugwPkro+D5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro+D5K6DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6G0+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6G0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkronz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6J8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6AY+Sui7Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Ls+SugGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroCj5K6Mg+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Mg+SugKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugKPkrouz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Ls+SugKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6AY+SuigPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6J8+SugGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6G0+Suj4Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro+D5K6G0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroMD5K6NM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro0z5K6DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugFPkrodz5K6PM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujzPkrodz5K6AUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugZPkrolT5K6Pc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Pc+SuiVPkroGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugYPkrogT5K6OU+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro5T5K6IE+SugYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugDPkroRz5K6Jo+SujlPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6OU+SuiaPkroRz5K6AMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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EMHs/hDB7P4Rwu3/EMHs/huV3P4yOZ3/MjRN/jMzM/8yMzj+MjVl/i9Dtv8Vseb+EMHs/hHC7f8Qwez+EMHs/hen4v8xO7r+MTq5/jI7uv8xOrn+NT7F/jpG3Jo+SujEPUnn/j1J5/4+Suj/PUnn/j1J5/40Yun/EcHs/hDB7P4Rwu3/EMHs/hHC7f8XpeL+LFHC/jI6s/4yOq//L0O8/h6L2P4Rwez/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hHB7P4ejNj/L0S8/jI6r/8yOrP+LFDC/hil4v8Qwez+EMHs/hHC7f8Qwez+EMHs/iVuzf8xOrn+MTq5/jI7uv83Qc7+PUnm/j1J5sQ+SujkPkro/z5K6P8+Suj/Pkro/z5K6P89S+j/GKzs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcHs/xas5P8XpuL/Er3r/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Eb7r/xem4v8Wq+T/EcHs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/E7bo/zBAvP8yO7r/Mju8/zlE2P8+Suj/Pkro/z5K6OQ+Suj5PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/KYHq/hDB7P4Rwu3/EMHs/hHC7f8Qwez+EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hHC7f8Qwez+EMHs/hHC7f8Qwez+EMHs/hHC7f8Qwez+IILV/jI7uv8zPcD+O0ff/j5K6P89Sef+PUnn/j1J5/k+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/OVfo/hK/7P4Rwu3/EMHs/hHC7f8Qwez+EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hHC7f8Qwez+EMHs/hHC7f8Qwez+EMHs/hHC7f8Rv+v+LUzA/jU/x/89SOT+PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/xul6/8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xyR2v8djdn/HY3Z/x2N2f8djdn/HY3Z/xyU2/8Rwu3/G5bc/x2N2f8djdn/HY3Z/x2N2f8djdn/HY3Z/x2N2f8djdn/FLTn/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8ZoeH/OELR/z1J5/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj5PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/jpT6P4uc+n/LXXp/i116f8jj+r+EMHs/i5Jv/4yO7r/MTq5/jE6uf4yO7r/MTq5/i1Owf4Rwu3/LFLC/jE6uf4yO7r/MTq5/jE6uf4yO7r/MTq5/jE6uf4xO7r/Fa7l/h2Q2v8ma8z+JmvM/iZrzP8mbM7+LHPl/i5z6f85UeT+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j1J5/k+SujkPUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P8vcOn+EMHs/i1Nwf4yO7r/MTq5/jE6uf4yO7r/MTq5/i1Owf4Rwu3/LFLC/jE6uf4yO7r/MTq5/jE6uf4yO7r/MTq5/jE6uf4uSb//Eb/s/ipYxf8xOrn+MTq5/jM8vv87R9/+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j1J5+Q+SujEPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8zZun/EcLt/ytTw/8yO7r/Mju6/zI7uv8yO7r/Mju6/y1Owf8Rwu3/LFLC/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8ghNX/F6nj/zE8uv8yO7r/ND7D/zxI4/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6MQ+SuiaPUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P85Vuj+EcHs/ildx/4yO7r/MTq5/jE6uf4yO7r/MTq5/i1Owf4Rwu3/LFLC/jE6uf4yO7r/MTq5/jE6uf4yO7r/MTq5/i5Hvv4SvOr/JmvM/jI7uv81P8j+PUnl/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j1J55o+SuhlPUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89S+j+FrLs/iVtzf4yO7r/MTq5/jE6uf4yO7r/MTq5/i1Owf4Rwu3/LFLC/jE6uf4yO7r/MTq5/jE6uf4yO7r/MTq5/h+I1/4WquT/MT27/jdBzv89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j1J52U+SugkPkro/T5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/I4/q/x2O2f8yO7r/Mju6/zI7uv8yO7r/Mju6/y1Owf8Rwu3/LFLC/zI7uv8yO7r/Mju6/zI7uv8yO7r/K1XD/xG+6/8oYsn/OUPV/z5J6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/T5K6CQ+SugCPUnn0j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+Nl7o/hO46v4vRr7/MTq5/jE6uf4yO7r/MTq5/i1Owf4Rwu3/LFLC/jE6uf4yO7r/MTq5/jE6uf4vRr7/Fqzk/h6O3P46Rdr/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn0j1J5wIAAAAAPkroez5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/yaH6v8aneD/L0a+/zI7uv8yO7r/Mju6/y1Owf8Rwu3/LFLC/zI7uv8yO7r/MTu6/ylfx/8VruX/HJvk/zpL4f8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroewAAAAAAAAAAPUnnGz1J5/Y+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1K5/4og+r/E7jr/hWv5v4Vr+X/Fa/l/hWx5v4Rwu3/FLLn/hep4/4XpuL/FLXo/ha07P4pf+r/PUzo/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef2PUnnGwAAAAAAAAAAAAAAAD1J558+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/OlPo/i5y6f4nher/JYvq/iWL6v4li+r/Jonq/iiD6v4tdun/NGLp/j1M6P4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89SeeeAAAAAAAAAAAAAAAAAAAAAD5K6CE+Suj4Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Pg+SughAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuiFPUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6IUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugLPUnn1j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn1j5K6AsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroMz5K6PU+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj1PkroMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J510+Suj9PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P09SeddAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+Suh4PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6HgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugBPkroeD5K6P0+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj9PkroeD5K6AEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J510+Suj1PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6PU9SeddAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuiTAAAAAAAAAAAAAAAAAAAAAD5K6Aw+SujYPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro2D5K6AwAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Ck+SujuPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6O4+SugpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Dc+SujuPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujuPkroNwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Ck+SujYPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro2D5K6CkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Aw+SuiTPkro/D5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/D5K6JM+SugMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugrPkrooz5K6Pg+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro+D5K6KM+SugrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroEj5K6F8+SuihPkro0T5K6PA+Suj/Pkro/z5K6PA+SujRPkrooT5K6F8+SugSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AA///AAD//AAAP/gAAB/wAAAP4AAAB8AAAAPAAAADgAAAAYAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABgAAAAcAAAAPAAAAD4AAAB/AAAA/4AAAf/AAAP/8AAP//wAP/KAAAABgAAAAwAAAAAQAgAAAAAABgCQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SeUlPUnnfT5K6L8+SujpPkro/T1J5/06RdnpMju8wDI7un4xO7omAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnmJD5K6K4+Suj8PUnn/j5K6P8+Suj/PUnn/zhC0f4yO7r/MTq5/jI7uv8yO7r9Mju6rjE7uiQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SedhPUnn9D1J5/49Sef+PUnn/j1J5/49SeX+NT/I/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jI7uvQyO7piAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Hw+Suj+PUnn/j5K6P8+Suj/PUnn/jxH4f8zPcH/Mju6/zE6uf4yO7r/MTq5/jI7uv8yO7r/MTq5/jI7uv8yO7r+Mju6fQAAAAAAAAAAAAAAAAAAAAAAAAAAPUnnYT5K6P4+Suj/PUnn/j5K6P8+Suj/OkXa/jI7vf8yO7r/Mju6/zE6uf4yO7r/MTq5/jI7uv8yO7r/MTq5/jI7uv8yO7r/Mju6/jI7umIAAAAAAAAAAAAAAAA9SeYkPUnn9D1J5/49Sef+PUnn/j1J5/44QtH+Mju6/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jI7uvUyO7skAAAAAAAAAAA+SuiuPUnn/j5K6P8+Suj/PUnl/jU/w/8yOJf/Mjqw/jI7uv8yO7r/Mju6/zE6uf4yO7r/MTq5/jI6r/8yOJf/Mjq1/jI7uv8yO7r/MTq5/jI7uv8yO7quAAAAAD1J5SU+Suj8PUnn/j5K6P88R+H/ND3B/jI0T/8zMzP/MjNB/jI6sv8yO7r/Mju6/zE6uf4yO7r/Mjqx/jIzQP8zMzP/MjRQ/jI6uf8yO7r/MTq5/jI7uv8yO7r9Mju6Jj1J5309Sef+PUnn/jBr5/4lcdH+KV2+/jIzM/4yMjL+MjIy/itTp/4kcM7+JHDO/iRwzv4kcM7+K1Sl/jIyMv4yMjL+MjMz/ilcwP4kcM7+JmjL/jE7uv4xOrn+Mju6fj5K6L8+Suj/PUnn/hex7P8Rwu3/Fqzk/jI4av8yMzT/MjVY/hqa2/8Rwu3/EcLt/xDB7P4Rwu3/Gpvb/jI1Vv8yMzT/Mjhs/har5P8Rwu3/Ervq/jA/u/8yO7r/NT/Gvz5K6Ok+Suj/PUnn/ieH6v8Rwu3/EMHs/hme3/8kccr/HJPb/hHB7f8Rwu3/EcLt/xDB7P4Rwu3/EcHs/hyU2/8kccr/GZ7f/hHC7f8Rwu3/HonX/jI7uv84QtL/PUnn6T5K6P0+Suj/PUnn/jdb6P8Rwez/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Rwu3/EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Rwez/LVLF/jpF2/8+Suj/PUnn/T1J5/09Sef+PUnn/j1J5/4li+r+H5vr/hW17P4maMv+J2TJ/idkyf4amd3+JmzM/idkyf4nZMn+J2TJ/h6K2P4ZoOD+G5bc/h2Z4/4kiuf+PEji/j1J5/49Sef+PUnn/T5K6Ok+Suj/PUnn/j5K6P8+Suj/PUnn/iGW6/8vRb7/MTq5/jI7uv8fiNf/L0a+/zE6uf4yO7r/MTq5/h2N2f8wQrz/NT/H/j1J5f8+Suj/PUnn/j5K6P8+Suj/PUnn6T1J5789Sef+PUnn/j1J5/49Sef+PUnn/ieF6v4sUML+MTq5/jE6uf4fiNf+L0a+/jE6uf4xOrn+LFHC/iCE1f43Qc7+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnnvz5K6H0+Suj/PUnn/j5K6P8+Suj/PUnn/jVg6P8kcs//MTq5/jI7uv8fiNf/L0a+/zE6uf4xPbv/HJPc/jZN2P8+Sej/PUnn/j5K6P8+Suj/PUnn/j5K6P8+Suj/PUnnfT1J5yU+Suj8PUnn/j5K6P8+Suj/PUnn/j5K6P8pfOf/InrS/iN1z/8ZoOD/InrR/yN0z/4fkOH/NF/l/j5K6P8+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P8+Suj8PUnnJQAAAAA9SeeuPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+OVbo/jJp6f4xaun+Mmjp/jdb6P49Suj+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49SeeuAAAAAAAAAAA9SeckPUnn9D5K6P8+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P8+Suj/Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6PQ+SugkAAAAAAAAAAAAAAAAPUnnYT5K6P4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P8+Suj/Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6GEAAAAAAAAAAAAAAAAAAAAAAAAAAD1J53w9Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnnfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhhPUnn9D5K6P8+Suj/PUnn/j5K6P8+Suj/Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6PQ+SuhhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnnJD5K6K4+Suj8PUnn/j5K6P8+Suj/Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj8PUnnrj5K6CQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SeclPUnnfT1J5789SefpPUnn/T1J5/09SefpPUnnvz1J5309SeclAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP4AfwD4AB8A8AAPAOAABwDAAAMAgAABAIAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAABAIAAAQDAAAMA4AAHAPAADwD4AB8A/gB/ACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANT/IMz5K6Jo+SujcPkro+ztH4PszPMDcMju6myw0pTQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApMZsKPkronT5K6P4+Suj/Pkro/zpF2P8yO7z/Mju6/zI7uv8yO7r+Mju6niQqhgoAAAAAAAAAAAAAAAApMZsKPkroxD5K6P8+Suj/PUnn/zdC0P8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7rFJCuICgAAAAAAAAAAPkronT5K6P8+Suj/PUnl/zU/x/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7up4AAAAANT/IMz5K6P4+Suj/O0fg/zQ6lf8yN4f/Mju6/zI7uv8yO7r/Mju6/zI3hv8yOI//Mju6/zI7uv8yO7r+LTWqND5K6Jo+Suj/MmHj/ytXwv8yMzT/MzMz/yxRsv8pXsf/KV7H/yxSsf8zMzP/MjM0/ytVwf8qW8b/MTu6/zI7ups+SujcPkro/xev7P8TuOn/LkZ9/zBAc/8VsOX/EcLt/xHC7f8VsOX/MEBy/y5Gfv8Tt+n/FLXo/zE8uv82QMvcPkro+z5K6P8ohOr/EcLt/xG/7P8Rvuv/EcLt/xHC7f8Rwu3/EcLt/xG+6/8Rv+z/EcLt/yGA1f85RNb/Pkro+z5K6Ps+Suj/OVXo/ymA6v8ek+D/K1bE/ypbxv8hgNT/K1bE/ytWxP8eitj/I3jR/yh+5f84U+T/Pkro/z5K6Ps+SujcPkro/z5K6P8+Suj/Jnzf/zI7uv8wQbz/JW/N/zI7uv8vRL3/JXDQ/zpF2v8+Suj/Pkro/z5K6P8+SujcPkromj5K6P8+Suj/Pkro/y9u5/8uSL//MEG8/yVvzf8xP7v/I33X/zpL4f8+Suj/Pkro/z5K6P8+Suj/PkromjZBzDM+Suj+Pkro/z5K6P89Suj/MG3o/yiB6P8oguj/LXTo/ztQ6P8+Suj/Pkro/z5K6P8+Suj/Pkro/jlE1jMAAAAAPkronT5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6J0AAAAAAAAAACw1pgo+SujEPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6MQvOLIKAAAAAAAAAAAAAAAALTWoCj5K6J0+Suj+Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/j5K6J0vOLIKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOEPTMz5K6Jo+SujcPkro+z5K6Ps+SujcPkromjlE1jMAAAAAAAAAAAAAAAAAAAAA8A8AAMADAACAAQAAgAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAEAAIABAADAAwAA8A8AAA==', - } + RegisterNetEvent('esx_phone:loaded') + AddEventHandler('esx_phone:loaded', function (phoneNumber, contacts) + local specialContact = { + name = _U('dealership'), + number = 'cardealer', + base64Icon = 'data:image/x-icon;base64,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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroMD5K6G8+SuinPkro2z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87Rt3/Mzy+/zI7u+AyPLysMju7cjI7vDUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SuhcPkropz5K6O8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTW/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uvEyPLysMju7YDI7uxYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroDD5K6GQ+Sui7Pkro+z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zZBy/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/DI7vMEyO7tnMju7DgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroOD5K6J8+Suj3Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zxI4/80PsP/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r4Mjy9ozI7vD0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugEPkroXD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87Rt3/Mzy+/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u9MyO7tgMju8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugIPkrobz5K6N8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTW/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7vfMjy9dDI7vAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugEPkroYD5K6N8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zZBy/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju73zI8vWQyO7wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroPD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zxI4/80PsT/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u9MyO7tAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroFD5K6KM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R97/Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yPL2oMju7FgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6GA+SujvPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTW/zI7u/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7rxMjy9ZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SuivPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzf8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy9sDI7uxYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhEPkro4z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zxI4/80PsX/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju65jI8vUgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkrodz5K6Ps+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R97/Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/DI7vH0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroDD5K6Kc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTW/zI7u/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI8vawyO7sOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Bg+SujLPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzf8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u84yO7sbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugoPkro3z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zxI4/80PsX/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uuIyO7orAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6Oc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R97/Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uuoyO7orAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Dw+SujzPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTW/zI7u/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uvUzPL8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugoPkro8z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzf8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uvEyO7orAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6Oc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1I5P80PsX/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uuoyO7orAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Bg+SujfPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R9//Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uuIyO7sbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugMPkroyz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTX/zI7vP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u84yO7sOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Kc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI8vawAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+Suh3Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1I5P81P8X/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7vH0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroRD5K6Ps+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R9//Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/DI8vUgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTX/zI7vP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju65jI7uxYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkrorz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy9swAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6GA+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1I5P81P8X/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy9ZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugUPkro7z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R9//Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7rxMju7FgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6KM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTX/zI7vP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yPL2oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+Sug8Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7tAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroBD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1J5f81P8X/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u9MyO7wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhgPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R+D/Mz3A/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI8vWQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroCD5K6N8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OkXY/zI7vP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju73zI7vAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhvPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdC0P8yO7r/Mju6/zI7uv8yO7r/Mju6/zI6uP8yOqn/Mjqp/zI6q/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI6qf8yOqn/Mjqp/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/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Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/MjVa/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8yNVj/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7vD0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6J8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1J5f81P8b/Mju6/zI7uv8yO7r/Mju6/zI7uv8yN37/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjmY/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI4jf8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8yN4n/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy9owAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugMPkro9z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R+D/Mz3A/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zMzQf8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8yNVv/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/MjRO/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zI0Tv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r4Mju7DgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6GQ+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OkXY/zI7vP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yOZ7/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzN/8yOrP/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI6rf8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zI6qf8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7tn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MjVl/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zI3fv8yO7r/IILV/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/H4fW/zI7uv8yNnD/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjZt/zI7uv8oY8n/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8nZcr/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI8vTUAAAAAAAAAAD5K6G8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/xyi6/8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Ho3Z/zI7uv8yOqn/MzM5/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zNEP/Mjq1/zI7uv8XqOP/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Vr+b/Mju6/zI6sf8zMz3/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzPf8yOq//Mju6/x+H1v8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yJ60v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy+cgAAAAAAAAAAPkropz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Kn7q/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Tuen/MEO9/zI7uv8yN4n/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzM5/zI5nv8yO7r/K1TD/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8pXcb/Mju6/zI4lv8zMzX/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzX/MjiU/zI7uv8xP7v/E7fp/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8RwOz/Lkm//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv81P8epAAAAAAAAAAA+SujbPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P86U+j/EcDt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8hgNT/Mju6/zI7uv8yN4f/MzM3/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzP/8yOJr/Mju6/zI7uv8anN7/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xii4f8yO7r/Mju6/zI4kv8zMzv/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzM5/zI4kv8yO7r/Mju6/yJ60v8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xuY3f8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/N0LP/z1J59sAAAAAPkroDD5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8fnOv/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHA7P8rVsT/Mju6/zI7uv8yOaX/MjVd/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzN/8yNmf/Mjqv/zI7uv8yO7r/JW/O/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yN20P8yO7r/Mju6/zI6qf8yNWX/MzM1/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzM1/zI1Yf8yOqn/Mju6/zI7uv8rVMP/Er7r/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/KV/H/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju8/zpF2P8+Suj/Pkro/zlF2Qw+Sug0Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/y9v6f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xS16P8sUML/Mju6/zI7uv8yO7r/Mjqr/zI3hf8yNnL/MjZl/zI2dP8yOIv/Mjqv/zI7uv8yO7r/Mju6/yhhyP8RwOz/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcDs/ydny/8yO7r/Mju6/zI7uv8yOq//MjiJ/zI2dP8yNmX/MjZ0/zI4if8yOq//Mju6/zI7uv8yO7r/LFDC/xS16P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xar5P8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zM9wf88R+D/Pkro/z5K6P8+Suj/PEfhND5K6Fw+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUzo/xS47P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xO36f8oYcj/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8kdM//EcDs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcDs/yN20P8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/ylcx/8Utej/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/JHTP/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv81P8j/PUnl/z5K6P8+Suj/Pkro/z5K6P88SONcPkrogz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/JI3r/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8ckdr/LFLC/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8pX8f/GKLh/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xik4v8oYcj/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yxQwv8dj9r/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xO56f8wQbz/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/OELR/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1J5oM+SuifPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P81YOn/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Fqvk/x+H1v8jdtD/JW7N/yN40f8ejdn/FLPn/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Us+f/HY/Z/yN40f8lbs3/JHTP/x+H1v8XqOP/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/H4fW/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy9/zpG2/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkronz5K6L8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8Yrez/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8sUML/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zQ+w/88SOL/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Sui/Pkro1z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/ymA6v8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Gpze/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv82QMv/PUnm/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Nc+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OVXo/xHA7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8oY8n/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/OUTW/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro4z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Hp7r/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/FbHm/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mzy//ztH3v8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8vcen/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8jeNH/Mju6/zI7uv8yO7r/Mju6/zQ+xf88SOP/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zxN6P8UuOz/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Er7r/zBDvf8yO7r/Mju6/zI7uv83Qc7/PUnn/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/ySP6/8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8ei9j/Mju6/zI7uv8yO7z/OUTY/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/LnPp/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yZpy/8yO7r/Mz3A/ztH4P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P85Vej/Er7s/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/F6jj/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/GKLh/xHC7f8Rwu3/EcLt/xyV3P8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/xat5f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Svuv/L0e+/zU/x/89SeX/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8td+r/EcDt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8ejdn/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8lbs3/EcLt/xHC7f8Rwu3/LkzA/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/G5jd/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcDt/yVuzv84QtH/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P81YOn/Jojq/yKV6/8ilev/IpXr/yKV6/8ilev/IpXr/yKV6/8ilev/HaLr/xHC7f8Rwu3/EcLt/x2P2v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yVuzf8Rwu3/EcLt/xHC7f8uTMD/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8WreX/EcLt/xHC7f8Vr+X/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/H5Hg/yKV6/8ilev/IpXr/yaK6v81Xeb/OkXa/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8yaOn/EcLt/xHC7f8Rwu3/HY/a/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/JW7N/xHC7f8Rwu3/EcLt/y5MwP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/MEG8/xHC7f8Rwu3/EcLt/yJ60v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zU/x/89SeX/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro4z5K6Nc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zJo6f8Rwu3/EcLt/xHC7f8dj9r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8lbs3/EcLt/xHC7f8Rwu3/LkzA/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8pXcb/EcLt/xHC7f8Rwu3/KV/H/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv83Qs7/PUnn/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujXPkrovz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/M2bp/xHC7f8Rwu3/EcLt/xqa3v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yVuzf8Rwu3/EcLt/xHC7f8uTMD/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yF+0/8Rwu3/EcLt/xK76v8xP7v/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/OUPV/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6L8+SuifPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P84Wej/EcLt/xHC7f8Rwu3/GaDg/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/JW7N/xHC7f8Rwu3/EcLt/y5MwP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Fqvk/xHC7f8Rwu3/HZHa/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju8/zpF2v8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkronz5K6IM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/ztR6P8Rwu3/EcLt/xHC7f8ZoOD/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8lbs3/EcLt/xHC7f8Rwu3/LkzA/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/ydnyv8Rwu3/EcLt/xHC7f8pXMb/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zM8v/87R+D/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuiDPkroXD5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/xO87P8Rwu3/EcLt/xWv5f8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yVuzf8Rwu3/EcLt/xHC7f8uTMD/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8xPbr/Fa/m/xHC7f8Rwu3/F6nj/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv80PsP/PEjj/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Fw+Sug0Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/GK3s/xHC7f8Rwu3/FbHm/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/JW7N/xHC7f8Rwu3/EcLt/y5MwP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yVtzf8Rwu3/EcLt/xHC7f8ma8z/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/NUDI/z1J5f8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroND5K6Aw+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8fnOv/EcLt/xHC7f8Rwu3/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8lbs3/EcLt/xHC7f8Rwu3/LkzA/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8xPbr/Fa/m/xHC7f8Rwu3/Fa/m/zE9uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zdCz/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SugMAAAAAD5K6Ns+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/yaI6v8Rwu3/EcLt/xHC7f8wQ73/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/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Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/ymA6v8TvOz/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHA7f8fnOv/N1vo/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6M8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroXD5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zlV6P8kjer/FLjs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xmr7P8nhur/OFno/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugEPkro4z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P88Tej/MWzp/yaK6v8cpOv/Fbbs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Svuz/FrPs/xum7P8gmOv/J4bq/y9v6f85Vej/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6N8+SugEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhvPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zhZ6P84Wej/OFno/zhZ6P84Wej/OFno/zhZ6P84Wej/OFno/zhZ6P88Tej/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkrobwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Ag+SujfPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6N8+SugIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6GA+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroBD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6M8+SugEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroPD5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkrooz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6KMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugUPkro7z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujvPkroFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhgPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuivPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuivAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro4z5K6BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6EQ+Suj7Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Ps+SuhEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Hc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkrodwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Kc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6KcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroDD5K6Ms+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujLPkroDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroGD5K6N8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro3z5K6BgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6Oc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Oc+SugoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6PM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujzPkroKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroPD5K6PM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro8z5K6DwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6Oc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Oc+SugoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6N8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujfPkroKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroGD5K6Ms+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkroyz5K6BgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroDD5K6Ks+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Kc+SugMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Hc+Suj7Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Ps+Suh3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6EQ+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujjPkroRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SuivPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkrorz5K6BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhgPkro7z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro7z5K6GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugUPkrooz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6KM+SugUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroPD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6M8+Sug8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroBD5K6GA+SujfPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6N8+SuhgPkroBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Ag+SuhvPkro3z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6N8+SuhvPkroCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugEPkroXD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6M8+SuhcPkroBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Dg+SuifPkro9z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro9z5K6J8+Sug4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugMPkroZD5K6Ls+Suj7Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj7Pkrouz5K6GQ+SugMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SuhcPkropz5K6O8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6O8+SuinPkroXD5K6BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6DA+SuhvPkropz5K6Ns+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujbPkropz5K6G8+SugwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Aw+Sug0PkroXD5K6IM+SuifPkrovz5K6Nc+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujjPkro1z5K6L8+SuifPkrogz5K6Fw+Sug0PkroDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD////////wAAAP////////////////AAAAAP//////////////8AAAAAAP/////////////4AAAAAAAf////////////4AAAAAAAB////////////wAAAAAAAAD///////////wAAAAAAAAAP//////////wAAAAAAAAAA//////////4AAAAAAAAAAH/////////4AAAAAAAAAAAf////////8AAAAAAAAAAAD////////8AAAAAAAAAAAAP///////+AAAAAAAAAAAAB////////AAAAAAAAAAAAAP///////AAAAAAAAAAAAAA///////gAAAAAAAAAAAAAH//////wAAAAAAAAAAAAAA//////4AAAAAAAAAAAAAAH/////8AAAAAAAAAAAAAAA/////+AAAAAAAAAAAAAAAH/////AAAAAAAAAAAAAAAA/////gAAAAAAAAAAAAAAAH////wAAAAAAAAAAAAAAAA////8AAAAAAAAAAAAAAAAP///+AAAAAAAAAAAAAAAAB////AAAAAAAAAAAAAAAAAP///gAAAAAAAAAAAAAAAAB///4AAAAAAAAAAAAAAAAAf//8AAAAAAAAAAAAAAAAAD//+AAAAAAAAAAAAAAAAAAf//gAAAAAAAAAAAAAAAAAH//wAAAAAAAAAAAAAAAAAA//4AAAAAAAAAAAAAAAAAAH/+AAAAAAAAAAAAAAAAAAB//AAAAAAAAAAAAAAAAAAAP/wAAAAAAAAAAAAAAAAAAD/4AAAAAAAAAAAAAAAAAAAf+AAAAAAAAAAAAAAAAAAAH/gAAAAAAAAAAAAAAAAAAB/wAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAD+AAAAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAAAAAAH4AAAAAAAAAAAAAAAAAAAB8AAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAPgAAAAAAAAAAAAAAAAAAAH4AAAAAAAAAAAAAAAAAAAB+AAAAAAAAAAAAAAAAAAAAfwAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAD/gAAAAAAAAAAAAAAAAAAB/4AAAAAAAAAAAAAAAAAAAf+AAAAAAAAAAAAAAAAAAAH/wAAAAAAAAAAAAAAAAAAD/8AAAAAAAAAAAAAAAAAAA//gAAAAAAAAAAAAAAAAAAf/4AAAAAAAAAAAAAAAAAAH//AAAAAAAAAAAAAAAAAAD//4AAAAAAAAAAAAAAAAAB//+AAAAAAAAAAAAAAAAAAf//wAAAAAAAAAAAAAAAAAP//+AAAAAAAAAAAAAAAAAH///gAAAAAAAAAAAAAAAAB///8AAAAAAAAAAAAAAAAA////gAAAAAAAAAAAAAAAAf///8AAAAAAAAAAAAAAAAP////AAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAB/////AAAAAAAAAAAAAAAA/////4AAAAAAAAAAAAAAAf/////AAAAAAAAAAAAAAAP/////4AAAAAAAAAAAAAAH//////AAAAAAAAAAAAAAD//////4AAAAAAAAAAAAAB///////AAAAAAAAAAAAAA///////8AAAAAAAAAAAAA////////gAAAAAAAAAAAAf///////8AAAAAAAAAAAAP////////wAAAAAAAAAAAP////////+AAAAAAAAAAAH/////////4AAAAAAAAAAH//////////AAAAAAAAAAD//////////8AAAAAAAAAD///////////wAAAAAAAAD////////////gAAAAAAAH////////////+AAAAAAAH/////////////8AAAAAAP//////////////8AAAAA////////////////8AAAD////////ygAAABgAAAAwAAAAAEAIAAAAAAAgJQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroCD5K6Ck9SedOPkrodz5K6Js9See9Pkro1j5K6Ok9Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89SefpPkro1j5K6L08SOSbO0fgdzdC0U4zPcEsMjy9CQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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Mju6/zE6uf4yO7r/Mju6/zI6sP4zMzb/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjL+MzMz/zMzM/8yNWL+Mjq5/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mjq5/zI1Wv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIzOv4yOrX/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uv0yO7srAAAAAAAAAAAAAAAAAAAAAD1J54A+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/O0fg/zQ9wv4yO7r/Mju6/zE6uf4yO7r/Mju6/zI4lf4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjL+MzMz/zMzM/8yNEj+Mjq0/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mjqx/zIzQ/4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4yOZ3/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7uDAAAAAAAAAAAAAAAAPUnnCD1J5809Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/46Rdn+Mjy9/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jI3h/4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yM0P+Mjqx/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+Mjqt/jIzO/4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yOJP+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4yO7rPMju6CQAAAAAAAAAAPkroKD1J5/g+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Suf+NGPp/yWI5/4ei9n/HovY/x6L2P4ei9j/HovY/x6L2P4ei9j/JmrM/zI4kv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjL+MzMz/zMzM/8yNEf+MD+1/yCB1P8ei9j+HovY/x6L2P8ei9j+HovY/x6L2P8ei9j+HovY/x6L2P8ei9j+HovY/x6L2P8ei9j+HovY/x6L2P8ei9j+HovY/x6L2P4fhdb/MEGz/zIzQf4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4yOZz/KGPJ/x6L2P4ei9j/HovY/x6L2P4ei9j/HovY/x6L2P4eitj/JHLO/zBDvf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r5Mju6KgAAAAAAAAAAPkroaT1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P8xa+n+E7vs/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/HY3Z/zI6rv4zMzX/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjL+MzMz/zMzM/8yNV7+L0a9/xO26P8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Suur/Lke9/zI0V/4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIzOP4yOrT/H4jX/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xmg4P4xPLr/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6awAAAAAAAAAAPUnnrD1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1K5/4couv+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+GKPh/jE7uv4yNWL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyM/4yOJf+K1TD/hHB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+KlfE/jI4jf4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jI2af4xOrn+GKHg/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4oX8f+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+Mju7sAAAAAA+SugIPkro4D1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P8enuv+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/Errq/y1Pwf4yOaX/MjNA/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjL+MzMz/zI1Yf8xOrn+IX3T/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/IIPV/zE6uP4yNVr/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MjNE/zI5qv4tTMD/E7np/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xHB7P4qWcX/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju84DQ+xgg+SugpPkro8z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P8udOn+EcHt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/x+H1v4yO7r/MjiW/zIzQP4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjP+MjVc/zI6sf8vRr7+FLLm/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/FLTo/y5Iv/4yOq3/MjRW/zIyM/4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4yM0P/Mjmd/zE6uf4ggtT/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xap4/4xO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7z/OUTW8zhD1Ck9SedOPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/46Uuj+FbXs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hHA7P4pX8f+MTq5/jI6rv4yNmv+MjND/jIzM/4yMjL+MjM3/jI0Tv4yN4f+MTq4/jE8uv4cktv+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/huW3P4xPbr+Mjq2/jI3hP4yNEz+MjM2/jIyMv4yMzT+MjRF/jI2b/4yOrD+MTq5/ildx/4Rv+z+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EcHs/iVvzf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jM9wP47R9/+PUnn/jtG3k0+Suh3Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+I5Hq/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Ttuj/KGHI/zE7uv4yOrn/Mjqx/zI5p/4yOZ7/Mjqq/zI6tf8xOrn+MEG8/x+G1v8Rwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xHB7P4eitj/MEG8/zE6uf4yOrX/Mjqq/zI5nv4yOaj/Mjqy/zE6uf4xO7r/KV/H/xO26P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/FLPn/y9Evf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/NT/I/zxI4/4+Suj/Pkro/zxI43c+SuibPkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+M2Xp/xHB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/Er3r/x+G1v4uSL7/Mju6/zE6uf4yO7r/Mju6/zI7uv8pX8f+GKLh/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/GKPh/yhgyP4yO7r/Mju6/zE6uf4yO7r/Mju6/y9Gvv4fhdb/Erzq/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/H4XW/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE7uv43QtD/PUnm/z1J5/4+Suj/Pkro/z1J5ps9See9PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PE7o/hmr6/4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Rv+z+GKLh/h6K1/4gg9X+HJLb/hWx5v4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Useb+HJLb/iCD1f4eidf+GaHg/hG/7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4SvOr+LFDB/jE6uf4xOrn+MTq5/jE6uf4xOrn+Mzy+/jpF2f49Sef+PUnn/j1J5/49Sef+PUnn/j1J570+SujWPkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/yiD6v4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4bmN3/MTy6/zE6uf4yO7r/Mju6/zE6uf40PsP/O0fg/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J59Y+SujpPkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/zhY6P4Rwe3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4oYcj/Mju6/zE6uf4yO7r/Mju6/zZAyf49SeX/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5+k9Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/4doev+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hWt5f4xOrn+MTq5/jE6uf4yO7v+OEPT/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4tden/EcHt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcHs/yN1z/4yO7r/Mju6/zM8v/46Rtv/PUnn/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/46U+j/Fbbs/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/E7bo/y5Hvv4yO7r/ND7E/zxH4f4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+HaHr/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+GZ3f/jE7uv43Qc7+PUnm/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/L3Hp/xK/7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/JmrM/ypYxf4qWMX/KljF/ypYxf8qWMX+KljF/ypYxf8qWMX+KljF/ypYxf8qWMX+KljF/yN20P8Qwez+EcLt/yJ80v8qWMX+KljF/ypYxf8qWMX+KljF/ypYxf8qWMX+KljF/ypYxf8qWMX+KljF/ypYxf4qWMX/KljF/ypYxf4qWMX/KljF/x6K2P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rvuz/J2jO/zlE1f49Sef/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUvo/zBu6f4gmOv/HaDr/x2g6/4doOv/HaDr/x2g6/4doOv/FLjs/xDB7P4Rwu3/KljF/zE6uf4yO7r/Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/x2O2f4Rwu3/Eb7r/xme3/4anN7/Gpze/xqc3v4anN7/Gpze/xqc3v4anN7/Gpze/xud4v4doOv/HaDr/yCa6/4ua+L/Okfe/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/49SefpPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+Hpzr/hDB7P4Qwez+KljF/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/ihhyP4Qwez+EMHs/iZpy/4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MT27/hel4v4Qwez+Fqrk/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+ND7E/jxI4v49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5+k+SujWPkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/H5zr/xDB7P4Rwu3/KlvG/zE6uf4yO7r/Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Lki//xO56f4Rwu3/HovY/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE7uv41QMn/PUjk/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J59Y+Sui9Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/IpPr/xDB7P4Rwu3/J2XK/zE6uf4yO7r/Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/J2bK/xDB7P4Rwu3/KGDI/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zZBzf49Seb/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5709SeebPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+JYrq/hDB7P4Qwez+JmfK/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/ihhyP4Qwez+EMHs/iZpy/4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4wP7v+GKXi/hDB7P4Wq+T+MEG8/jE6uf4xOrn+MTq5/jE6uf4yO7v+OEPU/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J55s+Suh3Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/K3zq/xDB7P4Rwu3/JHHO/zE6uf4yO7r/Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mju6/zE6uf4masz/EcDs/xDB7P4jdtD/Mju6/zE6uf4yO7r/Mju6/zI8vf46Rdr/PUnn/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J53c9SedOPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+MWzp/hDB7P4Qwez+InvS/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/ihhyP4Qwez+EMHs/iZpy/4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE8uv4WquT+EMHs/hO36P4wQrz+MTq5/jE6uf4xOrn+MzzA/jtG3v49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+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Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj4PkroKAAAAAAAAAAAPUnnCD1J5809Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/4kjOr+EMHs/hem4v4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/ihhyP4Qwez+EMHs/iZpy/4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/iRxzv4Qwez+EMHs/h2N2P4zPcD+O0fe/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49SefNPUnnCAAAAAAAAAAAAAAAAD1J538+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/44WOj/FLfs/xDB7P4nZ8v/Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+JmrL/xK96/4Rwu3/GKTh/zJGyP48SOP/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suh/AAAAAAAAAAAAAAAAAAAAAD1J5yg+Suj9Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Kn3q/xHA7P4Vsuf/LVHF/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE+u/8iedH+Erzq/xDB7P4WrOX/MVPR/z1J5f4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/0+SugoAAAAAAAAAAAAAAAAAAAAAAAAAAA9SefGPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PEzo/iKT6v4Qwez+FbHo/ihmzf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/ihhyP4Qwez+EMHs/iZpy/4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xPbr+KGLJ/hmf4P4Qwez+EMHs/hes6P4zVNj+PUnm/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J58YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhdPkro/j1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1L5/4jkev/EcDt/xHC7f8UtOj+GZ7f/xqc3v8anN7+Gpze/xqc3v8anN7+Gpze/xem4v8Qwez+EcLt/xep4/8anN7+HJLa/x2P2f8fiNf+HY7Z/xqb3v8Tt+n+EcLt/xHC7f8Svuz+IpLr/zpS6P4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/j1J510AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugQPkro3z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/49TOj/L3Hp/xms7P8RwOz+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Rwez+Fbfs/yGW6/80Y+n+PUvo/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro3z1J5w8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnnfj1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/jxO6P4xa+n+JYzq/hqo6/4Tu+z+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EcHs/hS47P4Zq+z+H5zr/iaH6v4wben+OlTo/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnnewAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroGD1J5+g+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+O0/o/zlV6P85Vej+OVXo/zlV6P85Vej+OVXo/zlV6P89TOj+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+SujoPkroGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J53g+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suh4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J5w49SefkPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5+Q9SecOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhaPkro+z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro+z1J51oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugFPkrouD1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/PkrouD1J5wUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnnLj1J5/A9Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49SefwPUnnLgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J52o+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+SuhqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J5wM+SuixPkro/j5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/j1J57A+SugDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SecaPUnn2j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn2j1J5xoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroND5K6Ow9Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+SujsPkroNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6FM9Sef5Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/k+SuhTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SedxPUnn+j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn+j1J53EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkrodz1J5/w+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj8PkrodwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroBD1J53c+Suj6Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/o+Suh3PkroBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SedxPUnn+T1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn+T1J53EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroUz1J5+0+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+SujsPkroUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J5zU+SujaPkro/j1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/j1J59o+Sug0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SecaPUnnsT1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnnsD1J5xoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroAz1J52o+SujwPkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/A+SuhqPkroAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuguPkrouD1J5/s+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj7PkrouD1J5y4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnnBj1J51o9SefkPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5+Q9SedaPUnnBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugOPkroeD1J5+g+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+SujoPkroeD1J5w4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J5xg+Suh8Pkro3z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj+Pkro3z1J53s+SugYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnnDz1J5109SefGPUnn/T1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/T1J58Y9SeddPUnnDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6IA9SefNPkro+D5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro+D1J580+Suh/PkroKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SecIPkroKD5K6Gk9SeesPkro4D5K6PM9Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+SujzPkro4D1J56w+SuhpPkroKD1J5wgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnnBz1J5yk9SedNPUnndz1J55s9See9PUnn1j1J5+k9Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49SefpPUnn1j1J5709SeebPUnndz1J5009SecpPUnnBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////+AAAH///////////gAAAAf/////////+AAAAAH/////////wAAAAAA/////////AAAAAAAP///////8AAAAAAAD///////wAAAAAAAA///////gAAAAAAAAf/////+AAAAAAAAAH/////8AAAAAAAAAD/////4AAAAAAAAAB/////wAAAAAAAAAA/////gAAAAAAAAAAf///+AAAAAAAAAAAH///+AAAAAAAAAAAH///8AAAAAAAAAAAD///4AAAAAAAAAAAB///wAAAAAAAAAAAA///gAAAAAAAAAAAAf//AAAAAAAAAAAAAP//AAAAAAAAAAAAAP/+AAAAAAAAAAAAAH/8AAAAAAAAAAAAAD/8AAAAAAAAAAAAAD/4AAAAAAAAAAAAAB/4AAAAAAAAAAAAAB/wAAAAAAAAAAAAAA/wAAAAAAAAAAAAAA/gAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAfAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAPgAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAfwAAAAAAAAAAAAAA/wAAAAAAAAAAAAAA/4AAAAAAAAAAAAAB/4AAAAAAAAAAAAAB/8AAAAAAAAAAAAAD/8AAAAAAAAAAAAAD/+AAAAAAAAAAAAAH//AAAAAAAAAAAAAP//AAAAAAAAAAAAAP//gAAAAAAAAAAAAf//wAAAAAAAAAAAA///4AAAAAAAAAAAB///8AAAAAAAAAAAD///+AAAAAAAAAAAH///+AAAAAAAAAAAH////gAAAAAAAAAAf////wAAAAAAAAAA/////4AAAAAAAAAB/////8AAAAAAAAAD/////+AAAAAAAAAH//////gAAAAAAAAf//////wAAAAAAAA///////8AAAAAAAD////////AAAAAAAP////////wAAAAAA/////////+AAAAAH//////////gAAAAf//////////+AAAH/////8oAAAASAAAAJAAAAABACAAAAAAAGBUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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Pkro/z5K6P8+Suj/Pkro/zlV6P8wW9X/K1XE/ytVxP8rVcT/K1XE/yxSw/8yOZf/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjVb/y9Hvv8rVcT/K1XE/ytVxP8rVcT/K1XE/ytVxP8rVcT/K1XE/ytVxP8rVcT/K1XE/ytVxP8rVcT/K1XE/y5Iv/8yNFP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Mjmf/yxSwv8rVcT/K1XE/ytVxP8rVcT/K1XE/yxPwf8xPbr/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uoAAAAAAAAAAAD5K6MU+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/LnHp/xO77P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xO26P8wQK//MzM0/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjZw/yF90v8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yCC1P8yNmr/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzb/MT20/xSz5/8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHA7P8bl9z/MTu6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uscAAAAAPkroFz5K6PE9Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Suj/Gavs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hG+6/8tTsH/MjVf/jMzM/8yMjL+MzMz/zIyMv4zMzP/MjIy/jMzM/8zMzX/Mjml/huW3P8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hqZ3f8yOZ/+MzM0/zMzM/8yMjL+MzMz/zIyMv4zMzP/MjIy/jMzM/8yNWX+LUzA/xG96/8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Qwez+KljF/zI7uv8xOrn+Mju6/zE6uf4yO7r/MTq5/jI7uvIzPL8YPkroQz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/IJjr/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8hfNL/Mjmq/zI0Rf8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzNP8yN37/Lki+/xO56f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xK66v8uS8D/MjZ3/zMzNP8zMzP/MzMz/zMzM/8zMzP/MzMz/zI0Sf8yOq3/InnR/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8SvOr/L0O9/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI8vf82Qc1DPkrodD5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/MWvp/hHB7P8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Suur/LU/B/jI6rf8yNmb+MjM8/zIyMv4zMzX/MjRN/jI4kP8xO7r/HJLa/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8clNv+MTy6/zI4jP8yNEz+MzM1/zIyMv4yMz7/MjZp/jI6sP8tTsH+E7np/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8ei9j+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/ND7D/jxH4f87R990PkronT5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PE7o/xex7P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Fa/l/ytWxP8xO7n/Mjqy/zI5p/8yOq3/Mjq3/zBBvP8fiNf/EcHs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwez/HorY/zBBvP8yOrf/Mjqt/zI5p/8yOrP/MTu6/ytUw/8Vr+X/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xG/7P8rVcP/Mju6/zI7uv8yO7r/Mju6/zI7uv82QMv/PUnl/z5K6P89SeWdPkrowT5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/iaI6v8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hK96/8djdn+KGPJ/yxSwv4qWcX/I3fQ/hWt5f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Qwez+EcLt/xWu5f8iedH+KlnF/yxSwv4oYsn/HY3Z/hK86/8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hmf3/8xO7r+Mju6/zI7uv8xOrn+Mju7/zhD1P49Sef/PUnn/j5K6P89SefBPkro3j5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zZd6P8Rwez/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHA7P8Rwez/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcHs/xHA7P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/ydnyv8yO7r/Mju6/zI7uv8zPL//O0bc/z1J5/8+Suj/Pkro/z5K6P8+SujePkro8j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j1K6P8bp+v+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/FbHm/jE+u/8xOrn+Mju6/zQ+xf88SOL+Pkro/z1J5/4+Suj/PUnn/j5K6P89SefyPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8reur/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/InvS/zI7uv8yO7r/N0HO/z1J5v8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P85VOj/E7vs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Su+r/Lkm//zI7vP85RNb/PUnn/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+G6Tr/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+FLPn/xSy5/4Usuf/FLLn/hSy5/8Usuf/FLLn/hSy5/8Usuf+FLLn/xK96/4Rwu3/E7bo/hSy5/8Usuf/FLLn/hSy5/8Usuf+FLLn/xSy5/4Usuf/FLLn/hSy5/8Usuf+FLLn/xSz5/8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4YoeD/Mz3A/jtH3/89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/M2Xp/xaz7P8Sv+z/Er/s/xK/7P8Sv+z/Eb/s/xHB7f8Rwu3/LFPD/zE/u/8xP7v/MT+7/zE/u/8xP7v/MT+7/zE/u/8xP7v/MT+7/xqc3v8Rwu3/KGDI/zE/u/8xP7v/MT+7/zE/u/8xP7v/MT+7/zE/u/8xP7v/MT+7/zE/u/8xP7v/MT+7/yxTw/8Rwu3/EcHs/xG+6/8Rvuv/Eb7r/xG+6/8Rvuv/Eb7r/xG+6/8Sv+z/Er/s/xay7P8uXtT/PEjk/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro8j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1K5/47Uej/O1Ho/jtR6P87Uej/N1ro/hO77P8Qwez+LFHC/zE6uf4yO7r/MTq5/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/xqb3v4Rwu3/KV3H/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/zE6uf4yO7r/MTq5/jI7uv8xOrn+Mju6/ydnyv8Qwez+HJTb/y9Dvf4wQ73/L0O9/jBDvf8vQ73+MEO9/zVJ0P87Uef+O1Ho/z1L5/49Sef/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89SefyPkro3j5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OlLo/xO67P8Rwu3/K1XD/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/xqb3v8Rwu3/KV3H/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/x+G1v8Rwu3/JHLO/zI7uv8yO7r/Mju6/zI7uv8yO7r/OEPU/z1J5/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujePkrowT5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PE3o/hW17P8Qwez+KlrG/zE6uf4yO7r/MTq5/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/xqb3v4Rwu3/KV3H/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/zE6uf4yO7r/MTq5/jI7uv8xOrn+MEG8/xWw5v8Su+r+Lkm//zE6uf4yO7r/MTq5/jI8vf86Rdn+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89SefBPkronT5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/xit7P8Rwu3/KGPJ/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/xqb3v8Rwu3/KV3H/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/I3fQ/xHB7f8dkNr/MTu6/zI7uv8yO7r/Mzy//ztH3/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuidPkrodD5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/h6d6/8Qwez+JmvM/zE6uf4yO7r/MTq5/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/xqb3v4Rwu3/KV3H/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/zE6uf4yO7r/MTq5/jI7uv8wQLz+FLTo/xG/7P8rU8P+Mju6/zE6uf40PsP/PEji/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sed0PkroQz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/yeG6v8Rwu3/InnR/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/xqb3v8Rwu3/KV3H/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8ieNH/EcLt/xyU2/8xO7r/Mju6/zU/yP89SeX/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/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PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J54YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6A4+SujfPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro3z5K6A4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhVPkro/T5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj9PkroVQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugCPUnnpD5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89SeekPkroAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroEz5K6Nw+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Nw+SugTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Dc+SujxPUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro8T5K6DcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhYPkro+z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj7PkroWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnncz5K6Pw9Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6Pw9SedzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6H8+Suj8Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/D5K6H8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SedzPkro+z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj7PUnncwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroWD5K6PI+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6PE+SuhYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Dc+SujcPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro3D5K6DcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugTPUnnpD5K6P0+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/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AAAAAAAAAAAAAAAA////4AAH////AAAA///+AAAAf///AAAA///4AAAAH///AAAA///gAAAAB///AAAA//+AAAAAAf//AAAA//4AAAAAAH//AAAA//wAAAAAAD//AAAA//gAAAAAAB//AAAA//AAAAAAAA//AAAA/+AAAAAAAAf/AAAA/8AAAAAAAAP/AAAA/4AAAAAAAAH/AAAA/wAAAAAAAAD/AAAA/gAAAAAAAAB/AAAA/AAAAAAAAAA/AAAA+AAAAAAAAAAfAAAA+AAAAAAAAAAfAAAA8AAAAAAAAAAPAAAA8AAAAAAAAAAPAAAA4AAAAAAAAAAHAAAA4AAAAAAAAAAHAAAAwAAAAAAAAAADAAAAwAAAAAAAAAADAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAwAAAAAAAAAADAAAAwAAAAAAAAAADAAAA4AAAAAAAAAAHAAAA4AAAAAAAAAAHAAAA8AAAAAAAAAAPAAAA8AAAAAAAAAAPAAAA+AAAAAAAAAAfAAAA+AAAAAAAAAAfAAAA/AAAAAAAAAA/AAAA/gAAAAAAAAB/AAAA/wAAAAAAAAD/AAAA/4AAAAAAAAH/AAAA/8AAAAAAAAP/AAAA/+AAAAAAAAf/AAAA//AAAAAAAA//AAAA//gAAAAAAB//AAAA//wAAAAAAD//AAAA//4AAAAAAH//AAAA//+AAAAAAf//AAAA///gAAAAB///AAAA///4AAAAH///AAAA///+AAAAf///AAAA////4AAH////AAAAKAAAAEAAAACAAAAAAQAgAAAAAAAAQgAA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Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6vTI7ugYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6J8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P88R+H/ND3B/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7uiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6G0+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P86Rdr/Mjy8/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6DA+Suj4Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1J5/84QtH/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r4Mju7MgAAAAAAAAAAAAAAAAAAAAAAAAAA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EcLt/xHC7f8Rwu3/Fa7l/zI5pf8zMzX/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjVj/ypYxf8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/K1XE/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zM8vyk+SuhgPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/yGV6/8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8dkNr/Mjqt/zI0Sf8zMzP/MzMz/zMzM/8zMzP/MzM2/zI4i/8qWcX/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8pXcf/MjeF/zMzNf8zMzP/MzMz/zMzM/8zMzP/MjRM/zI6sP8ejNj/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/E7fo/zE+u/8yO7r/Mju6/zI7uv8yO7r/Mju6/zM8v/84QtJhPkrojz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8yaOn/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcHs/ydlyv8yOrT/Mjd9/zI1V/8yNFD/MjZp/zI5ov8vRL3/Fqzl/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Fa7l/y9Gvv8yOaD/MjZo/zI0UP8yNVj/Mjd//zI6tf8nZcn/EcHs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yCB1P8yO7r/Mju6/zI7uv8yO7r/Mju6/zU+xv89SOT/PEjijz5K6Lc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUro/xay7P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rv+z/InvS/zBAvP8yO7r/Mju6/zI7uv8pXcf/Fa7l/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8VruX/KV/H/zI7uv8yO7r/Mju6/zBAvP8ietL/Eb7r/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xG/7P8uSsD/Mju6/zI7uv8yO7r/Mju6/zdBzv89Sef/Pkro/z1J5rc+SujXPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8nhur/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8SvOr/GaDg/xqa3v8Vseb/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Vseb/Gpre/xmf4P8Su+r/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8bltz/Mju6/zI7uv8yO7r/Mju8/zpF2P8+Suj/Pkro/z5K6P8+SujXPkro7j5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/N1ro/xHB7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/KV3H/zI7uv8yO7r/Mz3B/zxH4P8+Suj/Pkro/z5K6P8+Suj/Pkro7j5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8bpev/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Fqvk/zI7uv8yO7r/NT/I/z1J5f8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/LHjp/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yRxzv8yO7r/OELS/z1J5/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zlX6P8Rwez/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Ervq/xeo4/8XqOP/F6jj/xeo4/8XqOP/F6jj/xeo4/8XqOP/Fq3l/xHC7f8Ttuj/F6jj/xeo4/8XqOP/F6jj/xeo4/8XqOP/F6jj/xeo4/8XqOP/F6jj/xeo4/8VsOb/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHB7P8vS8L/Okbb/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/LHjq/xqo6/8Zq+z/Gavs/xmr7P8Yruz/EcLt/xeo4/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/ytUw/8Rwu3/H4fW/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/JW7N/xHC7f8VsOb/F6jj/xeo4/8XqOP/F6jj/xeo4/8XqeX/Gavs/xqo6/8pdN//PEji/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujuPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OFno/xHC7f8XqOP/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8rVMP/EcLt/x+H1v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/x+I1/8Rwu3/K1PD/zI7uv8yO7r/Mju6/zI7uv8zPL//O0ff/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujuPkro1z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zlU6P8Rwu3/Fa/m/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/K1TD/xHC7f8fh9b/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8Wq+T/FLTn/zE8uv8yO7r/Mju6/zI7uv80PcL/PEjj/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro1z5K6Lc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P89S+j/EcDs/xS06P8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/ytUw/8Rwu3/H4fW/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8oY8n/EcLt/yGA1P8yO7r/Mju6/zI7uv81P8f/PUnm/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Lc+SuiPPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/xaz7P8Svev/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8rVMP/EcLt/x+H1v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8xO7r/F6jj/xK96/8uR77/Mju6/zI7uv83Qc7/PUnn/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuiPPkroYD5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8enuv/EcLt/zBCvP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/K1TD/xHC7f8fh9b/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/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Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Pc+SugYAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuiVPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/O1Ho/ztR6P87Uej/O1Ho/ztR6P89Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuiVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroGT5K6PM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujzPkroGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+Suh3Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkrodwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroBT5K6NM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro0z5K6AUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugwPkro+D5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro+D5K6DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6G0+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6G0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkronz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6J8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6AY+Sui7Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Ls+SugGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroCj5K6Mg+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Mg+SugKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugKPkrouz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Ls+SugKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6AY+SuigPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6J8+SugGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6G0+Suj4Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro+D5K6G0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroMD5K6NM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro0z5K6DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugFPkrodz5K6PM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujzPkrodz5K6AUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugZPkrolT5K6Pc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Pc+SuiVPkroGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugYPkrogT5K6OU+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro5T5K6IE+SugYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugDPkroRz5K6Jo+SujlPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6OU+SuiaPkroRz5K6AMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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EMHs/hDB7P4Rwu3/EMHs/huV3P4yOZ3/MjRN/jMzM/8yMzj+MjVl/i9Dtv8Vseb+EMHs/hHC7f8Qwez+EMHs/hen4v8xO7r+MTq5/jI7uv8xOrn+NT7F/jpG3Jo+SujEPUnn/j1J5/4+Suj/PUnn/j1J5/40Yun/EcHs/hDB7P4Rwu3/EMHs/hHC7f8XpeL+LFHC/jI6s/4yOq//L0O8/h6L2P4Rwez/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hHB7P4ejNj/L0S8/jI6r/8yOrP+LFDC/hil4v8Qwez+EMHs/hHC7f8Qwez+EMHs/iVuzf8xOrn+MTq5/jI7uv83Qc7+PUnm/j1J5sQ+SujkPkro/z5K6P8+Suj/Pkro/z5K6P89S+j/GKzs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcHs/xas5P8XpuL/Er3r/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Eb7r/xem4v8Wq+T/EcHs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/E7bo/zBAvP8yO7r/Mju8/zlE2P8+Suj/Pkro/z5K6OQ+Suj5PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/KYHq/hDB7P4Rwu3/EMHs/hHC7f8Qwez+EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hHC7f8Qwez+EMHs/hHC7f8Qwez+EMHs/hHC7f8Qwez+IILV/jI7uv8zPcD+O0ff/j5K6P89Sef+PUnn/j1J5/k+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/OVfo/hK/7P4Rwu3/EMHs/hHC7f8Qwez+EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hHC7f8Qwez+EMHs/hHC7f8Qwez+EMHs/hHC7f8Rv+v+LUzA/jU/x/89SOT+PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/xul6/8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xyR2v8djdn/HY3Z/x2N2f8djdn/HY3Z/xyU2/8Rwu3/G5bc/x2N2f8djdn/HY3Z/x2N2f8djdn/HY3Z/x2N2f8djdn/FLTn/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8ZoeH/OELR/z1J5/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj5PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/jpT6P4uc+n/LXXp/i116f8jj+r+EMHs/i5Jv/4yO7r/MTq5/jE6uf4yO7r/MTq5/i1Owf4Rwu3/LFLC/jE6uf4yO7r/MTq5/jE6uf4yO7r/MTq5/jE6uf4xO7r/Fa7l/h2Q2v8ma8z+JmvM/iZrzP8mbM7+LHPl/i5z6f85UeT+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j1J5/k+SujkPUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P8vcOn+EMHs/i1Nwf4yO7r/MTq5/jE6uf4yO7r/MTq5/i1Owf4Rwu3/LFLC/jE6uf4yO7r/MTq5/jE6uf4yO7r/MTq5/jE6uf4uSb//Eb/s/ipYxf8xOrn+MTq5/jM8vv87R9/+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j1J5+Q+SujEPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8zZun/EcLt/ytTw/8yO7r/Mju6/zI7uv8yO7r/Mju6/y1Owf8Rwu3/LFLC/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8ghNX/F6nj/zE8uv8yO7r/ND7D/zxI4/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6MQ+SuiaPUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P85Vuj+EcHs/ildx/4yO7r/MTq5/jE6uf4yO7r/MTq5/i1Owf4Rwu3/LFLC/jE6uf4yO7r/MTq5/jE6uf4yO7r/MTq5/i5Hvv4SvOr/JmvM/jI7uv81P8j+PUnl/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j1J55o+SuhlPUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89S+j+FrLs/iVtzf4yO7r/MTq5/jE6uf4yO7r/MTq5/i1Owf4Rwu3/LFLC/jE6uf4yO7r/MTq5/jE6uf4yO7r/MTq5/h+I1/4WquT/MT27/jdBzv89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j1J52U+SugkPkro/T5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/I4/q/x2O2f8yO7r/Mju6/zI7uv8yO7r/Mju6/y1Owf8Rwu3/LFLC/zI7uv8yO7r/Mju6/zI7uv8yO7r/K1XD/xG+6/8oYsn/OUPV/z5J6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/T5K6CQ+SugCPUnn0j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+Nl7o/hO46v4vRr7/MTq5/jE6uf4yO7r/MTq5/i1Owf4Rwu3/LFLC/jE6uf4yO7r/MTq5/jE6uf4vRr7/Fqzk/h6O3P46Rdr/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn0j1J5wIAAAAAPkroez5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/yaH6v8aneD/L0a+/zI7uv8yO7r/Mju6/y1Owf8Rwu3/LFLC/zI7uv8yO7r/MTu6/ylfx/8VruX/HJvk/zpL4f8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroewAAAAAAAAAAPUnnGz1J5/Y+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1K5/4og+r/E7jr/hWv5v4Vr+X/Fa/l/hWx5v4Rwu3/FLLn/hep4/4XpuL/FLXo/ha07P4pf+r/PUzo/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef2PUnnGwAAAAAAAAAAAAAAAD1J558+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/OlPo/i5y6f4nher/JYvq/iWL6v4li+r/Jonq/iiD6v4tdun/NGLp/j1M6P4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89SeeeAAAAAAAAAAAAAAAAAAAAAD5K6CE+Suj4Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Pg+SughAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuiFPUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6IUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugLPUnn1j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn1j5K6AsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroMz5K6PU+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj1PkroMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J510+Suj9PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P09SeddAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+Suh4PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6HgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugBPkroeD5K6P0+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj9PkroeD5K6AEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J510+Suj1PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6PU9SeddAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuiTAAAAAAAAAAAAAAAAAAAAAD5K6Aw+SujYPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro2D5K6AwAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Ck+SujuPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6O4+SugpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Dc+SujuPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujuPkroNwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Ck+SujYPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro2D5K6CkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Aw+SuiTPkro/D5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/D5K6JM+SugMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugrPkrooz5K6Pg+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro+D5K6KM+SugrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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', + } - TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) - end) + TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) + end) end -- Create Blips Citizen.CreateThread(function () - local blip = AddBlipForCoord(Config.Zones.ShopEntering.Pos.x, Config.Zones.ShopEntering.Pos.y, Config.Zones.ShopEntering.Pos.z) + local blip = AddBlipForCoord(Config.Zones.ShopEntering.Pos.x, Config.Zones.ShopEntering.Pos.y, Config.Zones.ShopEntering.Pos.z) - SetBlipSprite (blip, 326) - SetBlipDisplay(blip, 4) - SetBlipScale (blip, 1.0) - SetBlipAsShortRange(blip, true) + SetBlipSprite (blip, 326) + SetBlipDisplay(blip, 4) + SetBlipScale (blip, 1.0) + SetBlipAsShortRange(blip, true) - BeginTextCommandSetBlipName("STRING") - AddTextComponentString(_U('car_dealer')) - EndTextCommandSetBlipName(blip) + BeginTextCommandSetBlipName("STRING") + AddTextComponentString(_U('car_dealer')) + EndTextCommandSetBlipName(blip) end) -- Display markers Citizen.CreateThread(function () - while true do - Citizen.Wait(0) + while true do + Citizen.Wait(0) - local coords = GetEntityCoords(GetPlayerPed(-1)) + local coords = GetEntityCoords(PlayerPedId()) - for k,v in pairs(Config.Zones) do - if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then - DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) - end - end - end + for k,v in pairs(Config.Zones) do + if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) + end + end + end end) -- Enter / Exit marker events Citizen.CreateThread(function () - while true do - Citizen.Wait(0) + while true do + Citizen.Wait(0) - local coords = GetEntityCoords(GetPlayerPed(-1)) - local isInMarker = false - local currentZone = nil + local coords = GetEntityCoords(PlayerPedId()) + local isInMarker = false + local currentZone = nil - for k,v in pairs(Config.Zones) do - if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then - isInMarker = true - currentZone = k - end - end + for k,v in pairs(Config.Zones) do + if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then + isInMarker = true + currentZone = k + end + end - if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then - HasAlreadyEnteredMarker = true - LastZone = currentZone - TriggerEvent('esx_vehicleshop:hasEnteredMarker', currentZone) - end + if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then + HasAlreadyEnteredMarker = true + LastZone = currentZone + TriggerEvent('esx_vehicleshop:hasEnteredMarker', currentZone) + end - if not isInMarker and HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = false - TriggerEvent('esx_vehicleshop:hasExitedMarker', LastZone) - end - end + if not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent('esx_vehicleshop:hasExitedMarker', LastZone) + end + end end) -- Key controls Citizen.CreateThread(function () - while true do - Citizen.Wait(10) + while true do + Citizen.Wait(10) - if CurrentAction ~= nil then - SetTextComponentFormat('STRING') - AddTextComponentString(CurrentActionMsg) - DisplayHelpTextFromStringLabel(0, 0, 1, -1) + if CurrentAction == nil then + Citizen.Wait(200) + else - if IsControlPressed(0, Keys['E']) and (GetGameTimer() - GUI.Time) > 300 then - if CurrentAction == 'shop_menu' then - OpenShopMenu() - end + ESX.ShowHelpNotification(CurrentActionMsg) - if CurrentAction == 'reseller_menu' then - OpenResellerMenu() - end + if IsControlJustReleased(0, Keys['E']) then + if CurrentAction == 'shop_menu' then + OpenShopMenu() + elseif CurrentAction == 'reseller_menu' then + OpenResellerMenu() + elseif CurrentAction == 'give_back_vehicle' then + ESX.TriggerServerCallback('esx_vehicleshop:giveBackVehicle', function (isRentedVehicle) + if isRentedVehicle then + ESX.Game.DeleteVehicle(CurrentActionData.vehicle) + ESX.ShowNotification(_U('delivered')) + else + ESX.ShowNotification(_U('not_rental')) + end + end, GetVehicleNumberPlateText(CurrentActionData.vehicle)) + elseif CurrentAction == 'resell_vehicle' then + ESX.TriggerServerCallback('esx_vehicleshop:resellVehicle', function (isOwnedVehicle) + if isOwnedVehicle then + ESX.Game.DeleteVehicle(CurrentActionData.vehicle) + ESX.ShowNotification(_U('vehicle_sold')) + else + ESX.ShowNotification(_U('not_yours')) + end + end, GetVehicleNumberPlateText(CurrentActionData.vehicle), CurrentActionData.price) + elseif CurrentAction == 'boss_actions_menu' then + OpenBossActionsMenu() + end - if CurrentAction == 'give_back_vehicle' then - ESX.TriggerServerCallback('esx_vehicleshop:giveBackVehicle', function (isRentedVehicle) - if isRentedVehicle then - DeleteVehicle(CurrentActionData.vehicle) - ESX.ShowNotification(_U('delivered')) - else - ESX.ShowNotification(_U('not_rental')) - end - end, GetVehicleNumberPlateText(CurrentActionData.vehicle)) - end - - if CurrentAction == 'resell_vehicle' then - ESX.TriggerServerCallback('esx_vehicleshop:resellVehicle', function (isOwnedVehicle) - if isOwnedVehicle then - DeleteVehicle(CurrentActionData.vehicle) - ESX.ShowNotification(_U('vehicle_sold')) - else - ESX.ShowNotification(_U('not_yours')) - end - end, GetVehicleNumberPlateText(CurrentActionData.vehicle), CurrentActionData.price) - end - - if CurrentAction == 'boss_actions_menu' then - OpenBossActionsMenu() - end - - CurrentAction = nil - GUI.Time = GetGameTimer() - end - end - end + CurrentAction = nil + end + end + end end) -- Load IPLS Citizen.CreateThread(function () - RemoveIpl('v_carshowroom') - RemoveIpl('shutter_open') - RemoveIpl('shutter_closed') - RemoveIpl('shr_int') - RemoveIpl('csr_inMission') - RequestIpl('v_carshowroom') - RequestIpl('shr_int') - RequestIpl('shutter_closed') + RemoveIpl('v_carshowroom') + RemoveIpl('shutter_open') + RemoveIpl('shutter_closed') + RemoveIpl('shr_int') + RemoveIpl('csr_inMission') + RequestIpl('v_carshowroom') + RequestIpl('shr_int') + RequestIpl('shutter_closed') end) diff --git a/locales/en.lua b/locales/en.lua index be11c973..dd68e130 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -37,15 +37,15 @@ Locales['en'] = { ['set_vehicle_owner_rent'] = 'assign vehicle [Location]', ['set_vehicle_owner_sell'] = 'Sell vehicle', ['set_vehicle_owner_sell_society'] = 'Assign Vehicle [Sale] [Society]', - ['shop_menu'] = 'press ~INPUT_CONTEXT~ to access the menu', + ['shop_menu'] = 'press ~INPUT_CONTEXT~ to access the menu2', ['the_boss'] = 'boss', ['vehicle_dealer'] = 'vehicle - Car Dealer', ['vehicle_menu'] = 'press ~INPUT_CONTEXT~ to make your vehicle', ['vehicle_purchased'] = 'you bought a vehicle', ['vehicle_set_owned'] = 'Vehicle ~y~%s~s~ has been assigned to ~b~%s~s~', ['vehicle_set_rented'] = 'Vehicle ~y~%s~s~ has been rented to ~b~%s~s~', - ['vehicle_sold'] = 'The vehicle has been ~g~sold~s~', - ['vehicle_sold_to'] = 'The vehicle has been ~y~%s~s~ sold to ~b~%s~s~', + ['vehicle_sold'] = 'the vehicle has been ~g~sold~s~', + ['vehicle_sold_to'] = 'the vehicle with plate ~y~%s~s~ has been sold to ~b~%s~s~', ['wash_money'] = 'money laundering', ['withdraw_amount'] = 'amount of withdrawal', ['withdraw_money'] = 'remove company money', From 60222d0a3c7b07a170aec19951a287296791a8d7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 24 Jul 2018 15:23:18 +0200 Subject: [PATCH 1627/3224] Updated to support new vehicle system --- client/main.lua | 2 +- server/main.lua | 125 +++++++++++++++--------------------------------- 2 files changed, 39 insertions(+), 88 deletions(-) diff --git a/client/main.lua b/client/main.lua index ab2e88f4..811f29ef 100644 --- a/client/main.lua +++ b/client/main.lua @@ -175,7 +175,7 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) ESX.Game.SpawnLocalVehicle(vehicles[j].vehicle.model, { x = garage.Parkings[i].Pos.x, y = garage.Parkings[i].Pos.y, - z = garage.Parkings[i].Pos.z + Config.ZDiff + z = garage.Parkings[i].Pos.z + Config.ZDiff }, garage.Parkings[i].Heading, function(vehicle) ESX.Game.SetVehicleProperties(vehicle, vehicles[j].vehicle) end) diff --git a/server/main.lua b/server/main.lua index 82a3e278..98106e6e 100644 --- a/server/main.lua +++ b/server/main.lua @@ -4,109 +4,60 @@ TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) RegisterServerEvent('esx_garage:setParking') AddEventHandler('esx_garage:setParking', function(garage, zone, vehicleProps) - local _source = source local xPlayer = ESX.GetPlayerFromId(_source) if vehicleProps == false then - MySQL.Async.execute( - 'DELETE FROM `user_parkings` WHERE `identifier` = @identifier AND `garage` = @garage AND zone = @zone', - { - ['@identifier'] = xPlayer.identifier, - ['@garage'] = garage; - ['@zone'] = zone - }, function(rowsChanged) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('veh_released')) - end - ) - + MySQL.Async.execute('DELETE FROM `user_parkings` WHERE `identifier` = @identifier AND `garage` = @garage AND zone = @zone', + { + ['@identifier'] = xPlayer.identifier, + ['@garage'] = garage; + ['@zone'] = zone + }, function(rowsChanged) + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('veh_released')) + end) else - - MySQL.Async.execute( - 'INSERT INTO `user_parkings` (`identifier`, `garage`, `zone`, `vehicle`) VALUES (@identifier, @garage, @zone, @vehicle)', - { - ['@identifier'] = xPlayer.identifier, - ['@garage'] = garage; - ['@zone'] = zone, - ['vehicle'] = json.encode(vehicleProps) - }, function(rowsChanged) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('veh_stored')) - end - ) - + MySQL.Async.execute('INSERT INTO `user_parkings` (`identifier`, `garage`, `zone`, `vehicle`) VALUES (@identifier, @garage, @zone, @vehicle)', + { + ['@identifier'] = xPlayer.identifier, + ['@garage'] = garage; + ['@zone'] = zone, + ['vehicle'] = json.encode(vehicleProps) + }, function(rowsChanged) + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('veh_stored')) + end) end - end) RegisterServerEvent('esx_garage:updateOwnedVehicle') - AddEventHandler('esx_garage:updateOwnedVehicle', function(vehicleProps) - - local _source = source - local xPlayer = ESX.GetPlayerFromId(source) - - MySQL.Async.fetchAll( - 'SELECT * FROM owned_vehicles WHERE owner = @owner', - { - ['@owner'] = xPlayer.identifier - }, - function(result) - - local foundVehicleId = nil - - for i=1, #result, 1 do - - local vehicle = json.decode(result[i].vehicle) - - if vehicle.plate == vehicleProps.plate then - foundVehicleId = result[i].id - break - end - - end - - if foundVehicleId ~= nil then - - MySQL.Async.execute( - 'UPDATE owned_vehicles SET vehicle = @vehicle WHERE id = @id', - { - ['@vehicle'] = json.encode(vehicleProps), - ['@id'] = foundVehicleId - } - ) - - end - - end - ) - - end) +AddEventHandler('esx_garage:updateOwnedVehicle', function(vehicleProps) + MySQL.Async.execute('UPDATE owned_vehicles SET vehicle = @vehicle WHERE plate = @plate', { + ['@plate'] = vehicleProps.plate, + ['@vehicle'] = json.encode(vehicleProps) + }) +end) ESX.RegisterServerCallback('esx_vehicleshop:getVehiclesInGarage', function(source, cb, garage) - local _source = source local xPlayer = ESX.GetPlayerFromId(_source) - MySQL.Async.fetchAll( - 'SELECT * FROM `user_parkings` WHERE `identifier` = @identifier AND garage = @garage', - { - ['@identifier'] = xPlayer.identifier, - ['@garage'] = garage - }, - function(result) - - local vehicles = {} - - for i=1, #result, 1 do - table.insert(vehicles, { - zone = result[i].zone, - vehicle = json.decode(result[i].vehicle) - }) - end - - cb(vehicles) + MySQL.Async.fetchAll('SELECT * FROM `user_parkings` WHERE `identifier` = @identifier AND garage = @garage', + { + ['@identifier'] = xPlayer.identifier, + ['@garage'] = garage + }, function(result) + local vehicles = {} + for i=1, #result, 1 do + table.insert(vehicles, { + zone = result[i].zone, + vehicle = json.decode(result[i].vehicle) + }) end - ) + + cb(vehicles) + + end) end) From 4331aabd2acf8c1035d48a259a69b0859dc24b55 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 24 Jul 2018 15:25:11 +0200 Subject: [PATCH 1628/3224] Update to support new vehicle db --- server/main.lua | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/server/main.lua b/server/main.lua index 263539ca..28a15c4f 100644 --- a/server/main.lua +++ b/server/main.lua @@ -36,12 +36,11 @@ end) RegisterServerEvent('esx_lscustom:refreshOwnedVehicle') AddEventHandler('esx_lscustom:refreshOwnedVehicle', function(myCar) - MySQL.Async.execute( - 'UPDATE `owned_vehicles` SET `vehicle` = @vehicle WHERE `vehicle` LIKE "%' .. myCar.plate .. '%"', - { - ['@vehicle'] = json.encode(myCar) - } - ) + MySQL.Async.execute('UPDATE `owned_vehicles` SET `vehicle` = @vehicle WHERE `plate` = @plate', + { + ['@plate'] = myCar.plate, + ['@vehicle'] = json.encode(myCar) + }) end) ESX.RegisterServerCallback('esx_lscustom:getVehiclesPrices', function(source, cb) From 1f6cbe9d8d75142b0d166fa514afc3d641d70986 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 24 Jul 2018 15:52:37 +0200 Subject: [PATCH 1629/3224] Fixed buying vehicles not changing vehicle, minor changes --- client/main.lua | 22 ++++++++++++---------- locales/en.lua | 2 +- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/client/main.lua b/client/main.lua index f4336760..63f8a844 100644 --- a/client/main.lua +++ b/client/main.lua @@ -117,7 +117,7 @@ function OpenShopMenu () { title = _U('car_dealer'), align = 'top-left', - elements = elements, + elements = elements }, function (data, menu) local vehicleData = vehiclesByCategory[data.current.name][data.current.value + 1] @@ -314,7 +314,7 @@ function OpenShopMenu () DeleteShopInsideVehicles() - ESX.Game.SpawnLocalVehicle(firstVehicleData.model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function (vehicle) + ESX.Game.SpawnLocalVehicle(vehicleData.model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function (vehicle) table.insert(LastVehicles, vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) FreezeEntityPosition(vehicle, true) @@ -375,7 +375,11 @@ function OpenResellerMenu () end if data.current.value == 'create_bill' then - + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(_U('no_players')) + return + end ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'set_vehicle_owner_sell_amount', { @@ -393,7 +397,7 @@ function OpenResellerMenu () local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(_U('invoice_amount')) + ESX.ShowNotification(_U('no_players')) else TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_cardealer', _U('car_dealer'), tonumber(data2.value)) end @@ -544,7 +548,7 @@ function OpenPersonnalVehicleMenu () y = coords.y, z = coords.z }, heading, function (vehicle) - ESX.Game.SetVehicleProperties(vehicle, vehicleData) + ESX.Game.SetVehicleProperties(vehicle, vehicleData) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) end) end, @@ -568,7 +572,7 @@ function OpenPopVehicleMenu () { title = _U('vehicle_dealer'), align = 'top-left', - elements = elements, + elements = elements }, function (data, menu) local model = data.current.value @@ -606,7 +610,7 @@ function OpenRentedVehiclesMenu () { title = _U('rent_vehicle'), align = 'top-left', - elements = elements, + elements = elements }, nil, function (data, menu) @@ -925,9 +929,7 @@ Citizen.CreateThread(function () ESX.ShowHelpNotification(CurrentActionMsg) if IsControlJustReleased(0, Keys['E']) then - if CurrentAction == 'shop_menu' then - OpenShopMenu() - elseif CurrentAction == 'reseller_menu' then + if CurrentAction == 'reseller_menu' then OpenResellerMenu() elseif CurrentAction == 'give_back_vehicle' then ESX.TriggerServerCallback('esx_vehicleshop:giveBackVehicle', function (isRentedVehicle) diff --git a/locales/en.lua b/locales/en.lua index dd68e130..c395fb23 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -37,7 +37,7 @@ Locales['en'] = { ['set_vehicle_owner_rent'] = 'assign vehicle [Location]', ['set_vehicle_owner_sell'] = 'Sell vehicle', ['set_vehicle_owner_sell_society'] = 'Assign Vehicle [Sale] [Society]', - ['shop_menu'] = 'press ~INPUT_CONTEXT~ to access the menu2', + ['shop_menu'] = 'press ~INPUT_CONTEXT~ to access the menu', ['the_boss'] = 'boss', ['vehicle_dealer'] = 'vehicle - Car Dealer', ['vehicle_menu'] = 'press ~INPUT_CONTEXT~ to make your vehicle', From 6a4ccf0cd7b95a8ae74286ac99927c1934ad3493 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 24 Jul 2018 16:20:52 +0200 Subject: [PATCH 1630/3224] Implemented plate generation from esx_migrate --- .editorconfig | 6 ++--- __resource.lua | 3 ++- client/main.lua | 17 +++++++++--- client/utils.lua | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ config.lua | 6 +++++ locales/en.lua | 6 ++--- server/main.lua | 10 ++++++- 7 files changed, 105 insertions(+), 12 deletions(-) create mode 100644 client/utils.lua diff --git a/.editorconfig b/.editorconfig index 4bfca33b..ecabf943 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,9 +1,9 @@ root = true [*] -indent_size = 2 -indent_style = space -end_of_line = lf +indent_size = 4 +indent_style = tab +end_of_line = crlf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true diff --git a/__resource.lua b/__resource.lua index 4d045a9b..758053e8 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,7 +2,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ESX Vehicle Shop' -version '1.1.0' +version '1.2.0' server_scripts { '@mysql-async/lib/MySQL.lua', @@ -26,5 +26,6 @@ client_scripts { 'locales/fr.lua', 'locales/sv.lua', 'config.lua', + 'client/utils.lua', 'client/main.lua' } diff --git a/client/main.lua b/client/main.lua index 63f8a844..d22227d0 100644 --- a/client/main.lua +++ b/client/main.lua @@ -419,9 +419,13 @@ function OpenResellerMenu () if closestPlayer == -1 or closestDistance > 3.0 then ESX.ShowNotification(_U('no_players')) else - SetVehicleNumberPlateText(LastVehicles[#LastVehicles], string.upper(ESX.GetRandomString(8))) + + local newPlate = GeneratePlate() local vehicleProps = ESX.Game.GetVehicleProperties(LastVehicles[#LastVehicles]) local model = CurrentVehicleData.model + vehicleProps.plate = newPlate + SetVehicleNumberPlateText(LastVehicles[#LastVehicles], newPlate) + TriggerServerEvent('esx_vehicleshop:sellVehicle', model) @@ -441,10 +445,12 @@ function OpenResellerMenu () ESX.ShowNotification(_U('no_players')) else ESX.TriggerServerCallback('esx:getOtherPlayerData', function (xPlayer) - SetVehicleNumberPlateText(LastVehicles[#LastVehicles], string.upper(ESX.GetRandomString(8))) + local newPlate = GeneratePlate() local vehicleProps = ESX.Game.GetVehicleProperties(LastVehicles[#LastVehicles]) local model = CurrentVehicleData.model - + vehicleProps.plate = newPlate + SetVehicleNumberPlateText(LastVehicles[#LastVehicles], newPlate) + TriggerServerEvent('esx_vehicleshop:sellVehicle', model) if Config.EnableSocietyOwnedVehicles then @@ -476,9 +482,12 @@ function OpenResellerMenu () if closestPlayer == -1 or closestDistance > 5.0 then ESX.ShowNotification(_U('no_players')) else - SetVehicleNumberPlateText(LastVehicles[#LastVehicles], 'RENT' .. string.upper(ESX.GetRandomString(4))) + + local newPlate = 'RENT' .. string.upper(ESX.GetRandomString(4)) local vehicleProps = ESX.Game.GetVehicleProperties(LastVehicles[#LastVehicles]) local model = CurrentVehicleData.model + vehicleProps.plate = newPlate + SetVehicleNumberPlateText(LastVehicles[#LastVehicles], newPlate) TriggerServerEvent('esx_vehicleshop:rentVehicle', model, vehicleProps.plate, GetPlayerName(closestPlayer), CurrentVehicleData.price, amount, GetPlayerServerId(closestPlayer)) diff --git a/client/utils.lua b/client/utils.lua new file mode 100644 index 00000000..ec8992de --- /dev/null +++ b/client/utils.lua @@ -0,0 +1,69 @@ +local NumberCharset = {} +local Charset = {} + +for i = 48, 57 do table.insert(NumberCharset, string.char(i)) end + +for i = 65, 90 do table.insert(Charset, string.char(i)) end +for i = 97, 122 do table.insert(Charset, string.char(i)) end + +function GeneratePlate() + local generatedPlate + local doBreak = false + + while true do + Citizen.Wait(2) + math.randomseed(GetGameTimer()) + if Config.PlateUseSpace then + generatedPlate = string.upper(GetRandomLetter(Config.PlateLetters) .. ' ' .. GetRandomNumber(Config.PlateNumbers)) + else + generatedPlate = string.upper(GetRandomLetter(Config.PlateLetters) .. GetRandomNumber(Config.PlateNumbers)) + end + + ESX.TriggerServerCallback('esx_vehicleshop:isPlateTaken', function (isPlateTaken) + if not isPlateTaken then + doBreak = true + end + end, generatedPlate) + + if doBreak then + break + end + end + + return generatedPlate +end + +-- mixing async with sync tasks +function IsPlateTaken(plate) + local callback = 'waiting' + + ESX.TriggerServerCallback('esx_vehicleshop:isPlateTaken', function (isPlateTaken) + callback = isPlateTaken + end, plate) + + while type(callback) == 'string' do + Citizen.Wait(0) + end + + return callback +end + +function GetRandomNumber(length) + Citizen.Wait(1) + math.randomseed(GetGameTimer()) + if length > 0 then + return GetRandomNumber(length - 1) .. NumberCharset[math.random(1, #NumberCharset)] + else + return '' + end +end + +function GetRandomLetter(length) + Citizen.Wait(1) + math.randomseed(GetGameTimer()) + if length > 0 then + return GetRandomLetter(length - 1) .. Charset[math.random(1, #Charset)] + else + return '' + end +end \ No newline at end of file diff --git a/config.lua b/config.lua index aac0ae8e..8458c0f3 100644 --- a/config.lua +++ b/config.lua @@ -8,6 +8,12 @@ Config.EnableSocietyOwnedVehicles = false Config.ResellPercentage = 50 Config.Locale = 'fr' +-- looks like this: 'LLL NNN' +-- The maximum plate length is 8 chars (including spaces & symbols), don't go past it! +Config.PlateLetters = 3 +Config.PlateNumbers = 3 +Config.PlateUseSpace = true + Config.Zones = { ShopEntering = { diff --git a/locales/en.lua b/locales/en.lua index c395fb23..be12da60 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -40,10 +40,10 @@ Locales['en'] = { ['shop_menu'] = 'press ~INPUT_CONTEXT~ to access the menu', ['the_boss'] = 'boss', ['vehicle_dealer'] = 'vehicle - Car Dealer', - ['vehicle_menu'] = 'press ~INPUT_CONTEXT~ to make your vehicle', + ['vehicle_menu'] = 'press ~INPUT_CONTEXT~ to give back the rented vehicle', ['vehicle_purchased'] = 'you bought a vehicle', - ['vehicle_set_owned'] = 'Vehicle ~y~%s~s~ has been assigned to ~b~%s~s~', - ['vehicle_set_rented'] = 'Vehicle ~y~%s~s~ has been rented to ~b~%s~s~', + ['vehicle_set_owned'] = 'vehicle ~y~%s~s~ has been assigned to ~b~%s~s~', + ['vehicle_set_rented'] = 'vehicle ~y~%s~s~ has been rented to ~b~%s~s~', ['vehicle_sold'] = 'the vehicle has been ~g~sold~s~', ['vehicle_sold_to'] = 'the vehicle with plate ~y~%s~s~ has been sold to ~b~%s~s~', ['wash_money'] = 'money laundering', diff --git a/server/main.lua b/server/main.lua index 19c4ee3f..e16dc1c2 100644 --- a/server/main.lua +++ b/server/main.lua @@ -31,7 +31,7 @@ function LoadVehicles() for j=1, #Categories, 1 do if Categories[j].name == vehicle.category then vehicle.categoryLabel = Categories[j].label - break --todo confirm + break end end @@ -371,6 +371,14 @@ ESX.RegisterServerCallback('esx_vehicleshop:getPlayerInventory', function (sourc cb({ items = items }) end) +ESX.RegisterServerCallback('esx_vehicleshop:isPlateTaken', function (source, cb, plate) + MySQL.Async.fetchAll('SELECT * FROM owned_vehicles WHERE @plate = plate', { + ['@plate'] = plate + }, function (result) + cb(result[1] ~= nil) + end) +end) + if Config.EnablePvCommand then TriggerEvent('es:addGroupCommand', 'pv', 'user', function(source, args, user) TriggerClientEvent('esx_vehicleshop:openPersonnalVehicleMenu', source) From a2f6061e3cad8c6ca61d1318ecc55a0eafc751e5 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 25 Jul 2018 11:38:35 +0200 Subject: [PATCH 1631/3224] Fixed #54, fixed starting script from server boot --- client/main.lua | 14 +++++++++++--- esx_vehicleshop.sql | 6 +++--- server/main.lua | 6 +++++- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/client/main.lua b/client/main.lua index d22227d0..7bf9e794 100644 --- a/client/main.lua +++ b/client/main.lua @@ -10,7 +10,6 @@ local Keys = { ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 } -local GUI = {} local HasAlreadyEnteredMarker = false local LastZone = nil local CurrentAction = nil @@ -23,7 +22,6 @@ local LastVehicles = {} local CurrentVehicleData = nil ESX = nil -GUI.Time = 0 Citizen.CreateThread(function () while ESX == nil do @@ -31,7 +29,7 @@ Citizen.CreateThread(function () Citizen.Wait(0) end - Citizen.Wait(300) + Citizen.Wait(5000) ESX.TriggerServerCallback('esx_vehicleshop:getCategories', function (categories) Categories = categories @@ -56,6 +54,16 @@ Citizen.CreateThread(function () end end) +RegisterNetEvent('esx_vehicleshop:sendCategories') +AddEventHandler('esx_vehicleshop:sendCategories', function (categories) + Categories = categories +end) + +RegisterNetEvent('esx_vehicleshop:sendVehicles') +AddEventHandler('esx_vehicleshop:sendVehicles', function (vehicles) + Vehicles = vehicles +end) + function DeleteShopInsideVehicles () while #LastVehicles > 0 do local vehicle = LastVehicles[1] diff --git a/esx_vehicleshop.sql b/esx_vehicleshop.sql index f380e4ca..de0f6f08 100644 --- a/esx_vehicleshop.sql +++ b/esx_vehicleshop.sql @@ -27,9 +27,9 @@ CREATE TABLE `cardealer_vehicles` ( ); CREATE TABLE `owned_vehicles` ( - `owner` varchar(30) DEFAULT NULL, - `plate` varchar(12) DEFAULT NULL, - `vehicle` longtext DEFAULT NULL, + `owner` varchar(30) NOT NULL, + `plate` varchar(12) NOT NULL, + `vehicle` longtext, PRIMARY KEY (`plate`) ); diff --git a/server/main.lua b/server/main.lua index e16dc1c2..d623d457 100644 --- a/server/main.lua +++ b/server/main.lua @@ -37,11 +37,15 @@ function LoadVehicles() table.insert(Vehicles, vehicle) end + + -- send information after db has loaded, making sure everyone gets vehicle information + TriggerClientEvent('esx_vehicleshop:sendCategories', -1, Categories) + TriggerClientEvent('esx_vehicleshop:sendVehicles', -1, Vehicles) end -- extremely useful when restarting script mid-game Citizen.CreateThread(function() - Citizen.Wait(100) -- hopefully enough for connection to the SQL server + Citizen.Wait(10000) -- hopefully enough for connection to the SQL server if not hasSqlRun then LoadVehicles() From 5926584595a935014c6f4e4637e72e85a9dc78bc Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 25 Jul 2018 12:11:04 +0200 Subject: [PATCH 1632/3224] Closes #130, updated to support new vehicle db system --- client/main.lua | 58 ++++++++++---------- config.lua | 12 ++++- locales/br.lua | 3 +- locales/de.lua | 3 +- locales/en.lua | 3 +- locales/es.lua | 3 +- locales/fi.lua | 1 + locales/fr.lua | 1 + locales/pl.lua | 1 + locales/sv.lua | 1 + server/main.lua | 140 ++++++++++++------------------------------------ 11 files changed, 83 insertions(+), 143 deletions(-) diff --git a/client/main.lua b/client/main.lua index 9e7ebbce..5d7652db 100644 --- a/client/main.lua +++ b/client/main.lua @@ -466,7 +466,7 @@ function OpenPoliceActionsMenu() elements = { {label = _U('citizen_interaction'), value = 'citizen_interaction'}, {label = _U('vehicle_interaction'), value = 'vehicle_interaction'}, - {label = _U('object_spawner'), value = 'object_spawner'}, + {label = _U('object_spawner'), value = 'object_spawner'} } }, function(data, menu) @@ -500,6 +500,7 @@ function OpenPoliceActionsMenu() if action == 'identity_card' then OpenIdentityCardMenu(closestPlayer) elseif action == 'body_search' then + TriggerServerEvent('esx_policejob:message', GetPlayerServerId(closestPlayer), _U('being_searched')) OpenBodySearchMenu(closestPlayer) elseif action == 'handcuff' then TriggerServerEvent('esx_policejob:handcuff', GetPlayerServerId(closestPlayer)) @@ -524,7 +525,7 @@ function OpenPoliceActionsMenu() menu2.close() end) elseif data.current.value == 'vehicle_interaction' then - local elements = {} + local elements = {} local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) local vehicle = ESX.Game.GetVehicleInDirection() @@ -535,7 +536,7 @@ function OpenPoliceActionsMenu() table.insert(elements, {label = _U('impound'), value = 'impound'}) end - --table.insert(elements, {label = _U('search_database'), value = 'search_database'}) + table.insert(elements, {label = _U('search_database'), value = 'search_database'}) ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'vehicle_interaction', @@ -544,9 +545,9 @@ function OpenPoliceActionsMenu() align = 'top-left', elements = elements }, function(data2, menu2) - coords = GetEntityCoords(playerPed) - vehicle = ESX.Game.GetVehicleInDirection() - action = data2.current.value + coords = GetEntityCoords(playerPed) + vehicle = ESX.Game.GetVehicleInDirection() + action = data2.current.value if action == 'search_database' then LookupVehicle() @@ -899,7 +900,7 @@ function LookupVehicle() title = _U('search_database_title'), }, function(data, menu) local length = string.len(data.value) - if data.value == nil or length < 8 or length > 13 then + if data.value == nil or length < 2 or length > 13 then ESX.ShowNotification(_U('search_database_error_invalid')) else ESX.TriggerServerCallback('esx_policejob:getVehicleFromPlate', function(owner, found) @@ -983,32 +984,28 @@ end function OpenVehicleInfosMenu(vehicleData) - ESX.TriggerServerCallback('esx_policejob:getVehicleInfos', function(infos) + ESX.TriggerServerCallback('esx_policejob:getVehicleInfos', function(retrivedInfo) - local elements = {} + local elements = {} - table.insert(elements, {label = _U('plate', infos.plate), value = nil}) + table.insert(elements, {label = _U('plate', retrivedInfo.plate), value = nil}) - if infos.owner == nil then - table.insert(elements, {label = _U('owner_unknown'), value = nil}) - else - table.insert(elements, {label = _U('owner', infos.owner), value = nil}) - end + if retrivedInfo.owner == nil then + table.insert(elements, {label = _U('owner_unknown'), value = nil}) + else + table.insert(elements, {label = _U('owner', retrivedInfo.owner), value = nil}) + end - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'vehicle_infos', - { - title = _U('vehicle_info'), - align = 'top-left', - elements = elements, - }, - nil, - function(data, menu) - menu.close() - end - ) + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_infos', + { + title = _U('vehicle_info'), + align = 'top-left', + elements = elements + }, nil, function(data, menu) + menu.close() + end) - end, vehicleData.plate) + end, vehicleData.plate) end @@ -1029,7 +1026,7 @@ function OpenGetWeaponMenu() { title = _U('get_weapon_menu'), align = 'top-left', - elements = elements, + elements = elements }, function(data, menu) @@ -1060,7 +1057,6 @@ function OpenPutWeaponMenu() local weaponHash = GetHashKey(weaponList[i].name) if HasPedGotWeapon(playerPed, weaponHash, false) and weaponList[i].name ~= 'WEAPON_UNARMED' then - --local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) table.insert(elements, {label = weaponList[i].label, value = weaponList[i].name}) end @@ -1071,7 +1067,7 @@ function OpenPutWeaponMenu() { title = _U('put_weapon_menu'), align = 'top-left', - elements = elements, + elements = elements }, function(data, menu) diff --git a/config.lua b/config.lua index f0c4f361..c78100c3 100644 --- a/config.lua +++ b/config.lua @@ -31,7 +31,7 @@ Config.PoliceStations = { Scale = 1.2, Colour = 29, }, - -- https://wiki.fivem.net/wiki/Weapons + -- https://wiki.rage.mp/index.php?title=Weapons AuthorizedWeapons = { { name = 'WEAPON_NIGHTSTICK', price = 200 }, { name = 'WEAPON_COMBATPISTOL', price = 300 }, @@ -83,7 +83,7 @@ Config.PoliceStations = { } --- https://wiki.fivem.net/wiki/Vehicles +-- https://wiki.rage.mp/index.php?title=Vehicles Config.AuthorizedVehicles = { Shared = { { @@ -118,6 +118,10 @@ Config.AuthorizedVehicles = { } }, + intendent = { + + }, + lieutenant = { { model = 'riot', @@ -129,6 +133,10 @@ Config.AuthorizedVehicles = { } }, + chef = { + + }, + boss = { } diff --git a/locales/br.lua b/locales/br.lua index 0523c396..fb3ea1a1 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -47,7 +47,8 @@ Locales['br'] = { ['license_revoke'] = 'revoke license', ['license_revoked'] = 'your ~b~%s~s~ has been ~y~revoked~s~!', ['licence_you_revoked'] = 'you revoked a ~b~%s~s~ which belonged to ~y~%s~s~', - ['no_players_nearby'] = 'Nenhum jogador nas proximidades', + ['no_players_nearby'] = 'nenhum jogador nas proximidades', + ['being_searched'] = 'you are being ~y~searched~s~ by the ~b~Police~s~', -- Vehicle interaction ['vehicle_info'] = 'Informações', ['pick_lock'] = 'Trancar veículo', diff --git a/locales/de.lua b/locales/de.lua index de79ebd8..310179f2 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -47,7 +47,8 @@ Locales['de'] = { ['license_revoke'] = 'revoke license', ['license_revoked'] = 'your ~b~%s~s~ has been ~y~revoked~s~!', ['licence_you_revoked'] = 'you revoked a ~b~%s~s~ which belonged to ~y~%s~s~', - ['no_players_nearby'] = 'Keine Spieler in der Nähe', + ['no_players_nearby'] = 'keine Spieler in der Nähe', + ['being_searched'] = 'you are being ~y~searched~s~ by the ~b~Police~s~', -- Vehicle interaction ['vehicle_info'] = 'Fahrzeug Info', ['pick_lock'] = 'Fahrzeug öffnen', diff --git a/locales/en.lua b/locales/en.lua index c376dd94..2c9003f9 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -47,7 +47,8 @@ Locales['en'] = { ['license_revoke'] = 'revoke license', ['license_revoked'] = 'your ~b~%s~s~ has been ~y~revoked~s~!', ['licence_you_revoked'] = 'you revoked a ~b~%s~s~ which belonged to ~y~%s~s~', - ['no_players_nearby'] = 'no players nearby', + ['no_players_nearby'] = 'there is no player(s) nearby!', + ['being_searched'] = 'you are being ~y~searched~s~ by the ~b~Police~s~', -- Vehicle interaction ['vehicle_info'] = 'vehicle Info', ['pick_lock'] = 'lockpick Vehicle', diff --git a/locales/es.lua b/locales/es.lua index d44c2295..5cbbfac9 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -47,7 +47,8 @@ Locales['es'] = { ['license_revoke'] = 'revoke license', ['license_revoked'] = 'your ~b~%s~s~ has been ~y~revoked~s~!', ['licence_you_revoked'] = 'you revoked a ~b~%s~s~ which belonged to ~y~%s~s~', - ['no_players_nearby'] = 'No hay jugadores cerca', + ['no_players_nearby'] = 'no hay jugadores cerca', + ['being_searched'] = 'you are being ~y~searched~s~ by the ~b~Police~s~', -- Vehicle interaction ['vehicle_info'] = 'Información del vehículo', ['pick_lock'] = 'Forzar coche', diff --git a/locales/fi.lua b/locales/fi.lua index 95fcce8f..b5b08d83 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -48,6 +48,7 @@ Locales['fi'] = { ['license_revoked'] = 'sinun ~b~%s~s~ ~y~kumottiin~s~!', ['licence_you_revoked'] = 'sinä kumosit ~b~%s~s~ mikä kuului henkilölle ~y~%s~s~', ['no_players_nearby'] = 'ei pelaajia lähettyvillä', + ['being_searched'] = 'you are being ~y~searched~s~ by the ~b~Police~s~', -- Vehicle interaction ['vehicle_info'] = 'ajoneuvon tiedot', ['pick_lock'] = 'tiirikoi ovet', diff --git a/locales/fr.lua b/locales/fr.lua index 9dbb382c..7ddf43d2 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -48,6 +48,7 @@ Locales['fr'] = { ['license_revoked'] = 'votre ~b~%s~s~ a été ~y~révoqué~s~!', ['licence_you_revoked'] = 'vous avez révoqué un ~b~%s~s~ qui appartenait à ~y~%s~s~', ['no_players_nearby'] = 'aucun joueur à proximité', + ['being_searched'] = 'you are being ~y~searched~s~ by the ~b~Police~s~', -- Vehicle interaction ['vehicle_info'] = 'infos véhicule', ['pick_lock'] = 'crocheter véhicule', diff --git a/locales/pl.lua b/locales/pl.lua index d7d2e2a6..0b98fc61 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -49,6 +49,7 @@ Locales['pl'] = { ['license_revoked'] = 'twoja licencja ~b~%s~s~ została ~y~unieważniona~s~!', ['licence_you_revoked'] = 'unieważniłeś ~b~%s~s~ które należały do ~y~%s~s~', ['no_players_nearby'] = 'brak graczy w pobliżu', + ['being_searched'] = 'you are being ~y~searched~s~ by the ~b~Police~s~', -- Vehicle interaction ['vehicle_info'] = 'informacje o pojeździe', ['pick_lock'] = 'odblokuj pojazd', diff --git a/locales/sv.lua b/locales/sv.lua index a5c8133c..0b13d8a3 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -48,6 +48,7 @@ Locales['sv'] = { ['license_revoked'] = 'Ditt ~b~%s~s~ har blivit ~y~återkallat~s~!', ['licence_you_revoked'] = 'du återkallade ett ~b~%s~s~ som tillhörde ~y~%s~s~', ['no_players_nearby'] = 'det finns ingen i närheten', + ['being_searched'] = 'du blir ~y~visiterad~s~ av ~b~Polisen~s~', -- Vehicle interaction ['vehicle_info'] = 'fordon', ['pick_lock'] = 'bryt upp fordon', diff --git a/server/main.lua b/server/main.lua index 59dfb92a..080333da 100644 --- a/server/main.lua +++ b/server/main.lua @@ -226,114 +226,32 @@ end) ESX.RegisterServerCallback('esx_policejob:getVehicleInfos', function(source, cb, plate) - if Config.EnableESXIdentity then + MySQL.Async.fetchAll('SELECT * FROM owned_vehicles WHERE @plate = plate', { + ['@plate'] = plate + }, function(result) - MySQL.Async.fetchAll( - 'SELECT * FROM owned_vehicles', - {}, - function(result) + local retrivedInfo = { + plate = plate + } - local foundIdentifier = nil + if result[1] then - for i=1, #result, 1 do + MySQL.Async.fetchAll('SELECT * FROM users WHERE identifier = @identifier', { + ['@identifier'] = result[1].owner + }, function(result2) - local vehicleData = json.decode(result[i].vehicle) - - if vehicleData.plate == plate then - foundIdentifier = result[i].owner - break - end - - end - - if foundIdentifier ~= nil then - - MySQL.Async.fetchAll( - 'SELECT * FROM users WHERE identifier = @identifier', - { - ['@identifier'] = foundIdentifier - }, - function(result) - - local ownerName = result[1].firstname .. " " .. result[1].lastname - - local infos = { - plate = plate, - owner = ownerName - } - - cb(infos) - - end - ) - - else - - local infos = { - plate = plate - } - - cb(infos) - - end - - end - ) - - else - - MySQL.Async.fetchAll( - 'SELECT * FROM owned_vehicles', - {}, - function(result) - - local foundIdentifier = nil - - for i=1, #result, 1 do - - local vehicleData = json.decode(result[i].vehicle) - - if vehicleData.plate == plate then - foundIdentifier = result[i].owner - break - end - - end - - if foundIdentifier ~= nil then - - MySQL.Async.fetchAll( - 'SELECT * FROM users WHERE identifier = @identifier', - { - ['@identifier'] = foundIdentifier - }, - function(result) - - local infos = { - plate = plate, - owner = result[1].name - } - - cb(infos) - - end - ) - - else - - local infos = { - plate = plate - } - - cb(infos) - - end - - end - ) - - end + if Config.EnableESXIdentity then + retrivedInfo.owner = result2[1].firstname .. ' ' .. result2[1].lastname + else + retrivedInfo.owner = result2[1].name + end + cb(retrivedInfo) + end) + else + cb(retrivedInfo) + end + end) end) ESX.RegisterServerCallback('esx_policejob:getVehicleFromPlate', function(source, cb, plate) @@ -344,10 +262,20 @@ ESX.RegisterServerCallback('esx_policejob:getVehicleFromPlate', function(source, }, function(result) if result[1] ~= nil then - local playerName = ESX.GetPlayerFromIdentifier(result[1].owner).name - cb(playerName, true) + + MySQL.Async.fetchAll('SELECT * FROM users WHERE identifier = @identifier', { + ['@identifier'] = result[1].owner + }, function(result2) + + if Config.EnableESXIdentity then + cb(result2[1].firstname .. ' ' .. result2[1].lastname, true) + else + cb(result2[1].name, true) + end + + end) else - cb('unknown', false) + cb(_U('unknown'), false) end end ) From dec706afed1a99f04ef1a4d7e0c45c7724cf6cdc Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 25 Jul 2018 12:35:38 +0200 Subject: [PATCH 1633/3224] Fixed yet again player data not loaded --- client/main.lua | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 7bf9e794..cc5e2af4 100644 --- a/client/main.lua +++ b/client/main.lua @@ -29,7 +29,7 @@ Citizen.CreateThread(function () Citizen.Wait(0) end - Citizen.Wait(5000) + Citizen.Wait(10000) ESX.TriggerServerCallback('esx_vehicleshop:getCategories', function (categories) Categories = categories @@ -54,6 +54,25 @@ Citizen.CreateThread(function () end end) +RegisterNetEvent('esx:playerLoaded') +AddEventHandler('esx:playerLoaded', function(xPlayer) + ESX.PlayerData = xPlayer + + if Config.EnablePlayerManagement then + if ESX.PlayerData.job.name == 'cardealer' then + Config.Zones.ShopEntering.Type = 1 + + if ESX.PlayerData.job.grade_name == 'boss' then + Config.Zones.BossActions.Type = 1 + end + + else + Config.Zones.ShopEntering.Type = -1 + Config.Zones.BossActions.Type = -1 + end + end +end) + RegisterNetEvent('esx_vehicleshop:sendCategories') AddEventHandler('esx_vehicleshop:sendCategories', function (categories) Categories = categories From 5bdb3e90ba3090e2f42bd973d8fc249debbffb1d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 25 Jul 2018 14:08:45 +0200 Subject: [PATCH 1634/3224] Implemented selling back vehicle to provider, closes #51 --- client/main.lua | 144 +++++++++++++++++++++++++++++------------------- config.lua | 6 +- locales/br.lua | 4 +- locales/de.lua | 4 +- locales/en.lua | 10 ++-- locales/fi.lua | 4 +- locales/fr.lua | 4 +- locales/sv.lua | 12 ++-- server/main.lua | 29 ++++++++++ 9 files changed, 144 insertions(+), 73 deletions(-) diff --git a/client/main.lua b/client/main.lua index cc5e2af4..bc5d6b2a 100644 --- a/client/main.lua +++ b/client/main.lua @@ -91,6 +91,38 @@ function DeleteShopInsideVehicles () end end +function ReturnVehicleProvider() + ESX.TriggerServerCallback('esx_vehicleshop:getCommercialVehicles', function (vehicles) + local elements = {} + local returnPrice + for i=1, #vehicles, 1 do + returnPrice = ESX.Round(vehicles[i].price * 0.75) + + table.insert(elements, { + label = vehicles[i].name .. ' [$' .. returnPrice .. ']', + value = vehicles[i].name + }) + end + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'return_provider_menu', + { + title = _U('return_provider_menu'), + align = 'top-left', + elements = elements + }, function (data, menu) + TriggerServerEvent('esx_vehicleshop:returnProvider', data.current.value) + + Citizen.Wait(300) + menu.close() + + ReturnVehicleProvider() + end, function (data, menu) + menu.close() + end) + end) + +end + function OpenShopMenu () IsInShopMenu = true @@ -218,7 +250,10 @@ function OpenShopMenu () TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + local newPlate = GeneratePlate() local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) + vehicleProps.plate = newPlate + SetVehicleNumberPlateText(vehicle, newPlate) if Config.EnableOwnedVehicles then TriggerServerEvent('esx_vehicleshop:setVehicleOwned', vehicleProps) @@ -251,7 +286,10 @@ function OpenShopMenu () TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + local newPlate = GeneratePlate() local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) + vehicleProps.plate = newPlate + SetVehicleNumberPlateText(vehicle, newPlate) TriggerServerEvent('esx_vehicleshop:setVehicleOwnedSociety', playerData.job.name, vehicleProps) @@ -286,7 +324,10 @@ function OpenShopMenu () TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + local newPlate = GeneratePlate() local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) + vehicleProps.plate = newPlate + SetVehicleNumberPlateText(vehicle, newPlate) if Config.EnableOwnedVehicles then TriggerServerEvent('esx_vehicleshop:setVehicleOwned', vehicleProps) @@ -372,6 +413,7 @@ function OpenResellerMenu () {label = _U('buy_vehicle'), value = 'buy_vehicle'}, {label = _U('pop_vehicle'), value = 'pop_vehicle'}, {label = _U('depop_vehicle'), value = 'depop_vehicle'}, + {label = _U('return_provider'), value = 'return_provider'}, {label = _U('create_bill'), value = 'create_bill'}, {label = _U('get_rented_vehicles'), value = 'get_rented_vehicles'}, {label = _U('set_vehicle_owner_sell'), value = 'set_vehicle_owner_sell'}, @@ -382,26 +424,21 @@ function OpenResellerMenu () } }, function (data, menu) - if data.current.value == 'buy_vehicle' then + local action = data.current.value + + if action == 'buy_vehicle' then OpenShopMenu() - end - if data.current.value == 'put_stock' then + elseif action == 'put_stock' then OpenPutStocksMenu() - end - - if data.current.value == 'get_stock' then + elseif action == 'get_stock' then OpenGetStocksMenu() - end - - if data.current.value == 'pop_vehicle' then + elseif action == 'pop_vehicle' then OpenPopVehicleMenu() - end - - if data.current.value == 'depop_vehicle' then + elseif action == 'depop_vehicle' then DeleteShopInsideVehicles() - end - - if data.current.value == 'create_bill' then + elseif action == 'return_provider' then + ReturnVehicleProvider() + elseif action == 'create_bill' then local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() if closestPlayer == -1 or closestDistance > 3.0 then ESX.ShowNotification(_U('no_players')) @@ -434,13 +471,9 @@ function OpenResellerMenu () menu.close() end ) - end - - if data.current.value == 'get_rented_vehicles' then + elseif action == 'get_rented_vehicles' then OpenRentedVehiclesMenu() - end - - if data.current.value == 'set_vehicle_owner_sell' then + elseif action == 'set_vehicle_owner_sell' then local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() if closestPlayer == -1 or closestDistance > 3.0 then @@ -463,9 +496,7 @@ function OpenResellerMenu () ESX.ShowNotification(_U('vehicle_sold_to', vehicleProps.plate, GetPlayerName(closestPlayer))) end end - end - - if data.current.value == 'set_vehicle_owner_sell_society' then + elseif action == 'set_vehicle_owner_sell_society' then local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() if closestPlayer == -1 or closestDistance > 3.0 then @@ -488,9 +519,7 @@ function OpenResellerMenu () end end, GetPlayerServerId(closestPlayer)) end - end - - if data.current.value == 'set_vehicle_owner_rent' then + elseif action == 'set_vehicle_owner_rent' then ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'set_vehicle_owner_rent_amount', { @@ -596,41 +625,40 @@ function OpenPersonnalVehicleMenu () end function OpenPopVehicleMenu () - ESX.TriggerServerCallback('esx_vehicleshop:getCommercialVehicles', function (vehicles) - local elements = {} + ESX.TriggerServerCallback('esx_vehicleshop:getCommercialVehicles', function (vehicles) + local elements = {} - for i=1, #vehicles, 1 do - table.insert(elements, {label = vehicles[i].name .. ' [MSRP $' .. vehicles[i].price .. ']', value = vehicles[i].name}) - end + for i=1, #vehicles, 1 do + table.insert(elements, { + label = vehicles[i].name .. ' [MSRP $' .. vehicles[i].price .. ']', + value = vehicles[i].name + }) + end - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'commercial_vehicles', - { - title = _U('vehicle_dealer'), - align = 'top-left', - elements = elements - }, - function (data, menu) - local model = data.current.value + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'commercial_vehicles', + { + title = _U('vehicle_dealer'), + align = 'top-left', + elements = elements + }, function (data, menu) + local model = data.current.value - DeleteShopInsideVehicles() + DeleteShopInsideVehicles() - ESX.Game.SpawnVehicle(model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function (vehicle) + ESX.Game.SpawnVehicle(model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function (vehicle) + table.insert(LastVehicles, vehicle) - table.insert(LastVehicles, vehicle) + for i=1, #Vehicles, 1 do + if model == Vehicles[i].model then + CurrentVehicleData = Vehicles[i] + end + end + end) - for i=1, #Vehicles, 1 do - if model == Vehicles[i].model then - CurrentVehicleData = Vehicles[i] - end - end - end) - end, - function (data, menu) - menu.close() - end - ) - end) + end, function (data, menu) + menu.close() + end) + end) end function OpenRentedVehiclesMenu () @@ -965,7 +993,9 @@ Citizen.CreateThread(function () ESX.ShowHelpNotification(CurrentActionMsg) if IsControlJustReleased(0, Keys['E']) then - if CurrentAction == 'reseller_menu' then + if CurrentAction == 'shop_menu' then + OpenShopMenu() + elseif CurrentAction == 'reseller_menu' then OpenResellerMenu() elseif CurrentAction == 'give_back_vehicle' then ESX.TriggerServerCallback('esx_vehicleshop:giveBackVehicle', function (isRentedVehicle) diff --git a/config.lua b/config.lua index 8458c0f3..6d0f81a5 100644 --- a/config.lua +++ b/config.lua @@ -1,10 +1,10 @@ Config = {} Config.DrawDistance = 100.0 Config.MarkerColor = { r = 120, g = 120, b = 240 } -Config.EnablePlayerManagement = false -- If set to true, you need esx_addonaccount, esx_billing and esx_society +Config.EnablePlayerManagement = false -- enables the actual car dealer job. You'll need esx_addonaccount, esx_billing and esx_society Config.EnablePvCommand = true Config.EnableOwnedVehicles = true -Config.EnableSocietyOwnedVehicles = false +Config.EnableSocietyOwnedVehicles = false -- use with EnablePlayerManagement disabled, or else it wont have any effects Config.ResellPercentage = 50 Config.Locale = 'fr' @@ -32,7 +32,7 @@ Config.Zones = { ShopOutside = { Pos = { x = -28.637, y = -1085.691, z = 25.565 }, Size = { x = 1.5, y = 1.5, z = 1.0 }, - Heading = 90.0, + Heading = 330.0, Type = -1, }, diff --git a/locales/br.lua b/locales/br.lua index 072268bd..7b8be885 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -10,6 +10,7 @@ Locales['br'] = { ['dealer_boss'] = 'Concessionária de carros - Chefe', ['delivered'] = 'veículo ~g~entregue~s~ para o revendedor', ['depop_vehicle'] = 'volte ao veiculo', + ['return_provider'] = 'return vehicle to provider', ['deposit_amount'] = 'valor do depósito', ['deposit_money'] = 'depositar dinheiro', ['experianced'] = 'com experiência', @@ -27,12 +28,12 @@ Locales['br'] = { ['pop_vehicle'] = 'sai do veiculo', ['recruit'] = 'Recrutar', ['rent_vehicle'] = 'Concessionária - Veículos para alugar', + ['return_provider_menu'] = 'car Dealer - Return vehicle to provider', ['rental_amount'] = 'montante do aluguel', ['sell_menu'] = 'Pressione ~INPUT_CONTEXT~ para vender ', ['set_vehicle_owner_rent'] = 'Atribuir veículo [Alugar]', ['set_vehicle_owner_sell'] = 'Veículos para [Venda]', ['shop_menu'] = 'pressione ~INPUT_CONTEXT~ para acessar o menu ~y~%s~s~ pela quantidade de ~g~$%s~s~', - ['the_boss'] = 'Chefe', ['vehicle'] = 'veículo ', ['vehicle_dealer'] = 'Veículo - Concessionária', ['vehicle_menu'] = 'Pressione ~INPUT_CONTEXT~ para fazer o seu veículo', @@ -40,6 +41,7 @@ Locales['br'] = { ['vehicle_set_owned'] = 'Veículo ~y~%s~s~ foi atribuído a ~b~%s~s~', ['vehicle_set_rented'] = 'Veículo ~y~%s~s~ foi alugado para ~b~%s~s~', ['vehicle_sold'] = 'Veículo ~g~vendido~s~', + ['vehicle_sold_for'] = 'the ~b~%s~s~ has been ~y~sold~s~ for ~g~$%s~s~', ['vehicle_sold_to'] = 'Veículo ~y~%s~s~ vendido to ~b~%s~s~', ['wash_money'] = 'lavagem de dinheiro', ['withdraw_amount'] = 'quantidade de retirada', diff --git a/locales/de.lua b/locales/de.lua index ca5369dd..9a460209 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -10,6 +10,7 @@ Locales['de'] = { ['dealer_boss'] = 'Autohändler - Boss', ['delivered'] = 'Fahrzeug zum Händler ~g~gebracht~s~', ['depop_vehicle'] = 'Fahrzeug zurückholen', + ['return_provider'] = 'return vehicle to provider', ['deposit_amount'] = 'Einzahlbetrag', ['deposit_money'] = 'Geld einzahlen', ['experianced'] = 'erfahren', @@ -27,13 +28,13 @@ Locales['de'] = { ['pop_vehicle'] = 'Fahrzeug holen', ['recruit'] = 'Neuling', ['rent_vehicle'] = 'Autohändler - Fahrzeuge zum vermieten', + ['return_provider_menu'] = 'car Dealer - Return vehicle to provider', ['rental_amount'] = 'Mietbetrag', ['sell_menu'] = 'drücke ~INPUT_CONTEXT~ zum verkaufen ~y~%s~s~ für den Betrag ~g~$%s~s~', ['set_vehicle_owner_rent'] = 'Fahrzeug zuweisen [Mieten]', ['set_vehicle_owner_sell'] = 'Fahrzeuge [Verkauf]', ['set_vehicle_owner_sell_society'] = 'Fahrzeuge [Verkauf] [Society]', ['shop_menu'] = 'Drücke ~INPUT_CONTEXT~ um das Menü zu öffnen', - ['the_boss'] = 'boss', ['vehicle'] = 'Fahrzeug ', ['vehicle_dealer'] = 'Autohändler', ['vehicle_menu'] = 'Drücke ~INPUT_CONTEXT~ um ein Fahrzeug zu übergeben', @@ -41,6 +42,7 @@ Locales['de'] = { ['vehicle_set_owned'] = 'Vehicle ~y~%s~s~ has been assigned to ~b~%s~s~', ['vehicle_set_rented'] = 'Vehicle ~y~%s~s~ has been rented to ~b~%s~s~', ['vehicle_sold'] = 'Fahrzeug ~g~verkauft~s~', + ['vehicle_sold_for'] = 'the ~b~%s~s~ has been ~y~sold~s~ for ~g~$%s~s~', ['vehicle_sold_to'] = 'Vehicle ~y~%s~s~ sold to ~b~%s~s~', ['wash_money'] = 'Geld waschen', ['withdraw_amount'] = 'Abhebebetrag', diff --git a/locales/en.lua b/locales/en.lua index be12da60..d7ea8eca 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -7,7 +7,7 @@ Locales['en'] = { ['broke_company'] = 'you do not have enough money in the company account', ['purchase_type'] = 'type of purchase', ['society_type'] = 'society', - ['staff_type'] = 'staff', + ['staff_type'] = 'personal usage', ['buy_vehicle_shop'] = 'do you want to purchase %s for $%s?', ['buy_vehicle'] = 'buy vehicle', ['car_dealer'] = 'car Dealership', @@ -15,6 +15,7 @@ Locales['en'] = { ['dealer_boss'] = 'car Dealer - Boss', ['delivered'] = 'the vehicle has been ~g~delivered~s~ to the dealer', ['depop_vehicle'] = 'return vehicle', + ['return_provider'] = 'return vehicle to provider', ['deposit_amount'] = 'deposit amount', ['deposit_money'] = 'deposit money', ['experianced'] = 'experianced', @@ -32,19 +33,20 @@ Locales['en'] = { ['pop_vehicle'] = 'put out vehicle for sale', ['recruit'] = 'recruit', ['rent_vehicle'] = 'car Dealer - Vehicles for rent', + ['return_provider_menu'] = 'car Dealer - Return vehicle to provider', ['rental_amount'] = 'rental amount', ['sell_menu'] = 'press ~INPUT_CONTEXT~ to sell your ~y~%s~s~ for ~g~$%s~s~', ['set_vehicle_owner_rent'] = 'assign vehicle [Location]', - ['set_vehicle_owner_sell'] = 'Sell vehicle', - ['set_vehicle_owner_sell_society'] = 'Assign Vehicle [Sale] [Society]', + ['set_vehicle_owner_sell'] = 'sell vehicle', + ['set_vehicle_owner_sell_society'] = 'assign Vehicle [Sale] [Society]', ['shop_menu'] = 'press ~INPUT_CONTEXT~ to access the menu', - ['the_boss'] = 'boss', ['vehicle_dealer'] = 'vehicle - Car Dealer', ['vehicle_menu'] = 'press ~INPUT_CONTEXT~ to give back the rented vehicle', ['vehicle_purchased'] = 'you bought a vehicle', ['vehicle_set_owned'] = 'vehicle ~y~%s~s~ has been assigned to ~b~%s~s~', ['vehicle_set_rented'] = 'vehicle ~y~%s~s~ has been rented to ~b~%s~s~', ['vehicle_sold'] = 'the vehicle has been ~g~sold~s~', + ['vehicle_sold_for'] = 'the ~b~%s~s~ has been ~y~sold~s~ for ~g~$%s~s~', ['vehicle_sold_to'] = 'the vehicle with plate ~y~%s~s~ has been sold to ~b~%s~s~', ['wash_money'] = 'money laundering', ['withdraw_amount'] = 'amount of withdrawal', diff --git a/locales/fi.lua b/locales/fi.lua index 88e4e658..2e4a2aaf 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -15,6 +15,7 @@ Locales['fi'] = { ['dealer_boss'] = 'autokauppa - Pomo', ['delivered'] = 'ajoneuvo on ~g~kuljetettu~s~ myyjälle', ['depop_vehicle'] = 'palauta ajoneuvo', + ['return_provider'] = 'return vehicle to provider', ['deposit_amount'] = 'talletus summa', ['deposit_money'] = 'talleta rahaa', ['experianced'] = 'kokenut', @@ -32,19 +33,20 @@ Locales['fi'] = { ['pop_vehicle'] = 'ota ajoneuvo ulos näkyville myyntiä varten', ['recruit'] = 'tulokas', ['rent_vehicle'] = 'autokauppa - Vuokrattavat ajokit', + ['return_provider_menu'] = 'car Dealer - Return vehicle to provider', ['rental_amount'] = 'vuokran summa', ['sell_menu'] = 'paina ~INPUT_CONTEXT~ myydäksesi ~y~%s~s~ hintaan: ~g~$%s~s~', ['set_vehicle_owner_rent'] = 'määritä ajoneuvon [Vuokra]', ['set_vehicle_owner_sell'] = 'myy ajoneuvo', ['set_vehicle_owner_sell_society'] = 'määritä ajoneuvon [Hinta] [Firma]', ['shop_menu'] = 'paina ~INPUT_CONTEXT~ avataksesi menu', - ['the_boss'] = 'pomo', ['vehicle_dealer'] = 'ajonevuo - Autokauppa', ['vehicle_menu'] = 'paina ~INPUT_CONTEXT~ tehdäksesi tästä sinun ajoneuvo', ['vehicle_purchased'] = 'sinä ostit ajoneuvon', ['vehicle_set_owned'] = 'ajoneuvo ~y~%s~s~ on nyt määritetty henkilölle ~b~%s~s~', ['vehicle_set_rented'] = 'ajoneuvo ~y~%s~s~ on nyt vuokrattu henkilölle ~b~%s~s~', ['vehicle_sold'] = 'ajoneuvo ~g~myyty~s~', + ['vehicle_sold_for'] = 'the ~b~%s~s~ has been ~y~sold~s~ for ~g~$%s~s~', ['vehicle_sold_to'] = 'ajoneuvo ~y~%s~s~ myyty henkilölle ~b~%s~s~', ['wash_money'] = 'rahanpesu', ['withdraw_amount'] = 'nostettava määrä', diff --git a/locales/fr.lua b/locales/fr.lua index 80ab37f3..3042bc63 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -13,6 +13,7 @@ Locales['fr'] = { ['dealer_boss'] = 'Concessionnaire - Patron', ['delivered'] = 'Véhicule ~g~rendu~s~ au concessionnaire', ['depop_vehicle'] = 'Rentrer véhicule', + ['return_provider'] = 'return vehicle to provider', ['deposit_amount'] = 'Montant du dépôt', ['deposit_money'] = 'Déposer argent', ['experianced'] = 'Experimente', @@ -30,13 +31,13 @@ Locales['fr'] = { ['pop_vehicle'] = 'Sortir véhicule', ['recruit'] = 'Recrue', ['rent_vehicle'] = 'Concessionnaire - Véhicules en location', + ['return_provider_menu'] = 'car Dealer - Return vehicle to provider', ['rental_amount'] = 'Montant de la location', ['sell_menu'] = 'Appuez sur ~INPUT_CONTEXT~ pour vendre ~y~%s~s~ au prix de ~g~$%s~s~', ['set_vehicle_owner_rent'] = 'Attribuer véhicule [Location]', ['set_vehicle_owner_sell'] = 'Attribuer véhicule [Vente]', ['set_vehicle_owner_sell_society'] = 'Attribuer véhicule [Vente] [Société]', ['shop_menu'] = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu', - ['the_boss'] = 'Patron', ['vehicle'] = 'Le véhicule', ['vehicle_dealer'] = 'Concessionnaire - Véhicules', ['vehicle_menu'] = 'Appuez sur ~INPUT_CONTEXT~ pour rendre votre véhicule', @@ -44,6 +45,7 @@ Locales['fr'] = { ['vehicle_set_owned'] = 'Le véhicule ~y~%s~s~ a été attribué à ~b~%s~s~', ['vehicle_set_rented'] = 'Le véhicule ~y~%s~s~ a été loué à ~b~%s~s~', ['vehicle_sold'] = 'Véhicule ~g~vendu~s~', + ['vehicle_sold_for'] = 'the ~b~%s~s~ has been ~y~sold~s~ for ~g~$%s~s~', ['vehicle_sold_to'] = 'Véhicule ~y~%s~s~ vendu à ~b~%s~s~', ['wash_money'] = 'Blanchir argent', ['withdraw_amount'] = 'Montant du retrait', diff --git a/locales/sv.lua b/locales/sv.lua index 21f1d590..0ad82da5 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -5,9 +5,9 @@ Locales['sv'] = { ['vehicle_belongs'] = 'Fordonet med reg numret ~y~%s~s~ tillhör nu ~b~dig~s~', ['bleach amount'] = 'Belopp att tvätta', ['broke_company'] = 'Det finns inte tillräckligt mycket pengar i företagskontot', - ['purchase_type'] = 'type of purchase', - ['society_type'] = 'society', - ['staff_type'] = 'staff', + ['purchase_type'] = 'till vem är fordonet?', + ['society_type'] = 'företag', + ['staff_type'] = 'personlig användning', ['buy_vehicle_shop'] = 'Vill du köpa in %s för $%s?', ['buy_vehicle'] = 'Köp in fordon', ['car_dealer'] = 'Bilhandlaren', @@ -15,6 +15,7 @@ Locales['sv'] = { ['dealer_boss'] = 'Chefmeny', ['delivered'] = 'Fordonet har ~g~levererats~s~ till firman', ['depop_vehicle'] = 'Ställ tillbaka fordonet', + ['return_provider'] = 'sälj tillbaka fordon till leverantör', ['deposit_amount'] = 'Belopp att lägga in', ['deposit_money'] = 'Belopp att lägga in', ['experianced'] = 'Erfaren', @@ -31,20 +32,21 @@ Locales['sv'] = { ['personal_vehicle'] = 'Privat fordon', ['pop_vehicle'] = 'Ställ ut fordon till salu', ['recruit'] = 'Anställ', - ['rent_vehicle'] = 'Bilhandlaren - Fordon för uthyrning', + ['rent_vehicle'] = 'bilförsäljare - Fordon för uthyrning', + ['return_provider_menu'] = 'bilförsäljare - sälj tillbaka fordon till leverantör', ['rental_amount'] = 'Uthyrningsbelopp', ['sell_menu'] = 'Tryck ~INPUT_CONTEXT~ för att sälja ~y~%s~s~ för ~g~$%s~s~', ['set_vehicle_owner_rent'] = 'Anse ägare av uthyrt fordon', ['set_vehicle_owner_sell'] = 'Sälj fordon', ['set_vehicle_owner_sell_society'] = 'Assign Vehicle [Sale] [Society]', ['shop_menu'] = 'Tryck ~INPUT_CONTEXT~ för att få fram menyn', - ['the_boss'] = 'Chef', ['vehicle_dealer'] = 'vehicle - Car Dealer', ['vehicle_menu'] = 'Tryck på~INPUT_CONTEXT~ för att göra dig till ägare av fordonet', ['vehicle_purchased'] = 'Du köpte fordonet', ['vehicle_set_owned'] = 'Fordonet ~y~%s~s~ har tilldelats till ~b~%s~s~', ['vehicle_set_rented'] = 'Fordonet ~y~%s~s~ har hyrts ut till ~b~%s~s~', ['vehicle_sold'] = 'Fordonet har ~g~sålts~s~', + ['vehicle_sold_for'] = '~b~%s~s~ har ~y~sålts~s~ för ~g~$%s~s~', ['vehicle_sold_to'] = '~y~%s~s~ har sålts till ~b~%s~s~', ['wash_money'] = 'Tvätta pengar', ['withdraw_amount'] = 'Belopp att ta ut', diff --git a/server/main.lua b/server/main.lua index d623d457..f0e25384 100644 --- a/server/main.lua +++ b/server/main.lua @@ -275,6 +275,35 @@ ESX.RegisterServerCallback('esx_vehicleshop:getCommercialVehicles', function (so end) end) + +RegisterServerEvent('esx_vehicleshop:returnProvider') +AddEventHandler('esx_vehicleshop:returnProvider', function(vehicleModel) + local _source = source + + MySQL.Async.fetchAll('SELECT * FROM cardealer_vehicles WHERE vehicle = @vehicle LIMIT 1', { + ['@vehicle'] = vehicleModel + }, function (result) + + if result[1] then + local id = result[1].id + local price = ESX.Round(result[1].price * 0.75) + + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_cardealer', function(account) + account.addMoney(price) + end) + + MySQL.Async.execute('DELETE FROM cardealer_vehicles WHERE id = @id', { + ['@id'] = id + }) + + TriggerClientEvent('esx:showNotification', _source, _U('vehicle_sold_for', vehicleModel, price)) + else + print('esx_vehicleshop: ' .. GetPlayerIdentifiers(_source)[1] .. ' attempted selling an invalid vehicle!') + end + + end) +end) + ESX.RegisterServerCallback('esx_vehicleshop:getRentedVehicles', function (source, cb) MySQL.Async.fetchAll('SELECT * FROM rented_vehicles ORDER BY player_name ASC', {}, function (result) local vehicles = {} From 67363add438e2e51d059f6418aae56ed6140eadd Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 25 Jul 2018 22:38:47 +0200 Subject: [PATCH 1635/3224] Fixed incomplete readme, closes #17 --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 14ad8d08..5a7cf9a3 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,15 @@ ## Requirements -* Auto mode +* Auto mode (everyone can buy vehicles from the dealer) * No need to download another resource -* Player management (billing and boss actions) +* Player management (the car dealer job): billing, boss actions and more! * [esx_society](https://github.com/ESX-Org/esx_society) * [esx_billing](https://github.com/ESX-Org/esx_billing) + * [esx_addonaccount](https://github.com/ESX-Org/esx_addonaccount) + * [esx_addoninventory](https://github.com/ESX-Org/esx_addoninventory) + * [cron](https://github.com/ESX-Org/cron) ## Download & Installation From f619a9ff53f0a40a2d704ed77597bc088f7fc922 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 25 Jul 2018 22:55:02 +0200 Subject: [PATCH 1636/3224] Minor changes, readme improvements --- README.md | 60 ++++++++++++++++++++++++++++++++++--------------- __resource.lua | 2 ++ server/main.lua | 44 ++++++++++++++---------------------- 3 files changed, 61 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index caae750b..79b83fa8 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,61 @@ -# fxserver-esx_addonaccount -ESX AddonAccount +# esx_addonaccount -[INSTALLATION] +## Download & Installation -1) CD in your resources/[esx] folder -2) Clone the repository +### Using [fvm](https://github.com/qlaffont/fvm-installer) ``` -git clone https://github.com/FXServer-ESX/fxserver-esx_addonaccount esx_addonaccount +fvm install --save --folder=esx esx-org/esx_addonaccount ``` -3) Import esx_addonaccount.sql in your database -4) Add this in your server.cfg : + +### Using Git +``` +cd resources +git clone https://github.com/ESX-Org/esx_addonaccount [esx]/esx_addonaccount +``` + +### Manually +- Download https://github.com/ESX-Org/esx_addonaccount/archive/master.zip +- Put it in the `[esx]` directory + +## Installation +- Import `esx_addonaccount.sql` in your database +- Add this in your `server.cfg`: ``` start esx_addonaccount ``` -[USAGE] +## Usage +There is two types of accounts: shared and not shared. -There is two types of accounts : shared and not shared. +- Shared accounts doesn't belong to a specific user. Example: society accounts. +- None-shared accounts are created for every user in the server. They are created in db when player is loaded, Example: property black money -- Shared accounts dont belong to a specific user. Example : society account. -- Not shared accounts are created for every user in the server. They are created in db when player is loaded, Example : property black money +### `addon_account` database information +You must create an account in the database -You must create the account in the database (addon_account) before using it : +| `name` | `label` | `shared` | +| -------- | ------- | -------- | +| name of the account | label of the account (not used) | is the account shared with others? (boolean either `0` or `1`) | -name = name of the account, label = label of the account, shared (0 or 1) = Is account shared - -``` +```lua TriggerEvent('esx_addonaccount:getSharedAccount', 'society_realestateagent', function(account) - account.addMoney(500) + account.addMoney(500) end) TriggerEvent('esx_addonaccount:getAccount', 'property_black_money', 'steam:0123456789', function(account) - account.removeMoney(500) + account.removeMoney(500) end) ``` + +# Legal +### License +esx_addonaccount - addon account for ESX + +Copyright (C) 2015-2018 Jérémie N'gadi + +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 http://www.gnu.org/licenses/. \ No newline at end of file diff --git a/__resource.lua b/__resource.lua index e740147b..4b545468 100644 --- a/__resource.lua +++ b/__resource.lua @@ -9,3 +9,5 @@ server_scripts { 'server/classes/addonaccount.lua', 'server/main.lua' } + +dependency 'es_extended' \ No newline at end of file diff --git a/server/main.lua b/server/main.lua index d8633de7..37614381 100644 --- a/server/main.lua +++ b/server/main.lua @@ -15,25 +15,19 @@ AddEventHandler('onMySQLReady', function () 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 - } - ) + 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 @@ -42,13 +36,11 @@ AddEventHandler('onMySQLReady', function () 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 - } - ) + MySQL.Sync.execute('INSERT INTO addon_account_data (account_name, money, owner) VALUES (@account_name, @money, NULL)', + { + ['@account_name'] = name, + ['@money'] = 0 + }) money = 0 @@ -87,7 +79,7 @@ end) AddEventHandler('esx:playerLoaded', function(source) local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) + local xPlayer = ESX.GetPlayerFromId(_source) local addonAccounts = {} for i=1, #AccountsIndex, 1 do @@ -97,14 +89,12 @@ AddEventHandler('esx:playerLoaded', function(source) 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.Async.execute('INSERT INTO addon_account_data (account_name, money, owner) VALUES (@account_name, @money, @owner)', + { + ['@account_name'] = name, + ['@money'] = 0, + ['@owner'] = xPlayer.identifier + }) account = CreateAddonAccount(name, xPlayer.identifier, 0) table.insert(Accounts[name], account) From 1b513debf50b629bfd10dbbb119a1b455e4b57a5 Mon Sep 17 00:00:00 2001 From: Marcin Date: Fri, 27 Jul 2018 05:29:32 +0200 Subject: [PATCH 1637/3224] add pl (#6) * add pl * pl fix --- html/js/app_pl.js | 175 ++++++++++++++++++++++++++++++++++++++++++++++ html/ui_pl.html | 12 ++++ 2 files changed, 187 insertions(+) create mode 100644 html/js/app_pl.js create mode 100644 html/ui_pl.html diff --git a/html/js/app_pl.js b/html/js/app_pl.js new file mode 100644 index 00000000..cbbcef9f --- /dev/null +++ b/html/js/app_pl.js @@ -0,0 +1,175 @@ +(function(){ + + let MenuTpl = + ' - - - -
    -
    Ajouter un contact
    -
    -
    - - - - -
    -
    -
    +
    +
    + + unknown
    -
    - - - - - - + + +
    + +
    Répertoire
    +
    +
    +
    +

    Aucun contact

    +
    +
    +
    +
    + +
    +
    Messages + +
    +
    +
    +
    +

    Aucun message

    +
    +
    +
    +
    + +
    +
    +
    +
    + + + + + +
    +
    +
    + +
    +
    Ajouter un contact
    +
    +
    + + + + +
    +
    +
    + + + + + + + + + + \ No newline at end of file diff --git a/html/ui_br.html b/html/ui_br.html index 9a28cd97..af05a98d 100644 --- a/html/ui_br.html +++ b/html/ui_br.html @@ -1,82 +1,87 @@ - - - - - - -
    - -
    - -
    - - #123456 -
    - - + + + + + -
    - -
    Agenda
    -
    -
    -
    -

    Nenhum contato

    -
    -
    -
    -
    + -
    -
    Mensagens
    -
    -
    -
    -

    Nenhuma mensagem

    -
    -
    -
    -
    +
    -
    -
    -
    -
    - - - - - -
    -
    -
    - -
    -
    Adicionar contato
    -
    -
    - - - - -
    -
    -
    +
    +
    + + unknown
    -
    - - - - - - + + +
    + +
    Agenda
    +
    +
    +
    +

    Nenhum contato

    +
    +
    +
    +
    + +
    +
    Mensagens + +
    +
    +
    +
    +

    Nenhuma mensagem

    +
    +
    +
    +
    + +
    +
    +
    +
    + + + + + +
    +
    +
    + +
    +
    Adicionar contato
    +
    +
    + + + + +
    +
    +
    + +
    +
    + + + + + + + \ No newline at end of file diff --git a/html/ui_de.html b/html/ui_de.html index 55d92593..87faddcd 100644 --- a/html/ui_de.html +++ b/html/ui_de.html @@ -1,82 +1,87 @@ - - - - - - -
    + + + + + -
    + -
    - - #123456 -
    +
    - - -
    - -
    Kontakte
    -
    -
    -
    -

    Keine Kontakte

    -
    -
    -
    -
    - -
    -
    Nachrichten
    -
    -
    -
    -

    Keine Nachrichten

    -
    -
    -
    -
    - -
    -
    -
    -
    - - - - - -
    -
    -
    - -
    -
    Kontakt hinzufügen
    -
    -
    - - - - -
    -
    -
    +
    +
    + + unknown
    + + + +
    + +
    Kontakte
    +
    +
    +
    +

    Keine Kontakte

    +
    +
    +
    +
    + +
    +
    Nachrichten + +
    +
    +
    +
    +

    Keine Nachrichten

    +
    +
    +
    +
    + +
    +
    +
    +
    + + + + + +
    +
    +
    + +
    +
    Kontakt hinzufügen
    +
    +
    + + + + +
    +
    +
    +
    +
    - - - - + + + - - + + + \ No newline at end of file diff --git a/html/ui_en.html b/html/ui_en.html index 9aaacf2b..469fb76a 100644 --- a/html/ui_en.html +++ b/html/ui_en.html @@ -1,82 +1,87 @@ - - - - - - -
    + + + + + -
    + -
    - - #123456 -
    +
    - - -
    - -
    Contacts
    -
    -
    -
    -

    No contacts

    -
    -
    -
    -
    - -
    -
    Messages
    -
    -
    -
    -

    No messages

    -
    -
    -
    -
    - -
    -
    -
    -
    - - - - - -
    -
    -
    - -
    -
    Add a contact
    -
    -
    - - - - -
    -
    -
    +
    +
    + + unknown
    + + + +
    + +
    Contacts
    +
    +
    +
    +

    No contacts

    +
    +
    +
    +
    + +
    +
    Messages + +
    +
    +
    +
    +

    No messages

    +
    +
    +
    +
    + +
    +
    +
    +
    + + + + + +
    +
    +
    + +
    +
    Add a contact
    +
    +
    + + + + +
    +
    +
    +
    +
    - - - - + + + - - + + + \ No newline at end of file From bc233a144168a43695c856b533a2d779ba6b8e97 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 30 Oct 2018 15:25:53 +0100 Subject: [PATCH 1851/3224] See description, resolves #38, resolves #36 - Fixed console error when adding invalid number (use _source) - Fix contacts not refreshing when added (fixed broken code) - Play sound when message recieved - Close phone if open when script is stopping - Get back contacts, etc when restarted mid-game --- client/main.lua | 20 ++++++-- server/main.lua | 122 +++++++++++++++++++++++++++--------------------- 2 files changed, 83 insertions(+), 59 deletions(-) diff --git a/client/main.lua b/client/main.lua index 646d52d0..ba62b52d 100644 --- a/client/main.lua +++ b/client/main.lua @@ -82,13 +82,13 @@ AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) end) RegisterNetEvent('esx_phone:addContact') -AddEventHandler('esx_phone:addContact', function(name, phoneNumber) +AddEventHandler('esx_phone:addContact', function(name, phoneNumber, playerOnline) table.insert(PhoneData.contacts, { name = name, number = phoneNumber, - online = (PhoneNumberSources[contacts[i].number] == nil and false or NetworkIsPlayerActive(GetPlayerFromServerId(PhoneNumberSources[contacts[i].number]))), + online = playerOnline }) - -- CALL HERE RELOADCONTACT + SendNUIMessage({ contactAdded = true, phoneData = PhoneData @@ -103,7 +103,7 @@ AddEventHandler('esx_phone:removeContact', function(name, phoneNumber) break end end - -- CALL HERE RELOADCONTACT + SendNUIMessage({ contactRemoved = true, phoneData = PhoneData @@ -131,7 +131,7 @@ end) RegisterNUICallback('add_contact', function(data, cb) local phoneNumber = tonumber(data.phoneNumber) local contactName = tostring(data.contactName) - + if phoneNumber then TriggerServerEvent('esx_phone:addPlayerContact', phoneNumber, contactName) else @@ -164,6 +164,8 @@ AddEventHandler('esx_phone:onMessage', function(phoneNumber, message, position, ESX.ShowNotification('~b~' .. job .. ': ~s~' .. message) end + PlaySound(-1, "Menu_Accept", "Phone_SoundSet_Default", 0, 0, 1) + SendNUIMessage({ newMessage = true, phoneNumber = phoneNumber, @@ -277,6 +279,14 @@ Citizen.CreateThread(function() end end) +AddEventHandler('onResourceStop', function(resource) + if resource == GetCurrentResourceName() then + if GUI.PhoneIsShowed then + ESX.UI.Menu.CloseAll() + end + end +end) + -- Key controls Citizen.CreateThread(function() while true do diff --git a/server/main.lua b/server/main.lua index 4ae0286e..13bcde33 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,49 +1,8 @@ -ESX = nil -local DisptachRequestId = 0 -local PhoneNumbers = {} +ESX = nil +local DisptachRequestId = 0 +local PhoneNumbers = {} -TriggerEvent('esx:getSharedObject', function(obj) - ESX = obj -end) - -function GenerateUniquePhoneNumber() - local foundNumber, phoneNumber = false, nil - - while not foundNumber do - Citizen.Wait(100) - - math.randomseed(GetGameTimer()) - phoneNumber = math.random(10000, 99999) - - local result = MySQL.Sync.fetchAll('SELECT COUNT(*) as count FROM users WHERE phone_number = @phoneNumber', { - ['@phoneNumber'] = phoneNumber - }) - - if tonumber(result[1].count) == 0 then - foundNumber = true - end - end - - return phoneNumber -end - -function GetDistpatchRequestId() - local requestId = DisptachRequestId - - if DisptachRequestId < 65535 then - DisptachRequestId = DisptachRequestId + 1 - else - DisptachRequestId = 0 - end - - return requestId -end - -AddEventHandler('esx_phone:getDistpatchRequestId', function(cb) - cb(GetDistpatchRequestId()) -end) - -AddEventHandler('esx:playerLoaded', function(source) +function LoadPlayer(source) local xPlayer = ESX.GetPlayerFromId(source) for num,v in pairs(PhoneNumbers) do @@ -101,7 +60,57 @@ AddEventHandler('esx:playerLoaded', function(source) TriggerClientEvent('esx_phone:loaded', source, phoneNumber, contacts) end) end) +end +TriggerEvent('esx:getSharedObject', function(obj) + ESX = obj + + local xPlayers = ESX.GetPlayers() + + for i=1, #xPlayers, 1 do + LoadPlayer(xPlayers[i]) + end +end) + +function GenerateUniquePhoneNumber() + local foundNumber, phoneNumber = false, nil + + while not foundNumber do + Citizen.Wait(100) + + math.randomseed(GetGameTimer()) + phoneNumber = math.random(10000, 99999) + + local result = MySQL.Sync.fetchAll('SELECT COUNT(*) as count FROM users WHERE phone_number = @phoneNumber', { + ['@phoneNumber'] = phoneNumber + }) + + if tonumber(result[1].count) == 0 then + foundNumber = true + end + end + + return phoneNumber +end + +function GetDistpatchRequestId() + local requestId = DisptachRequestId + + if DisptachRequestId < 65535 then + DisptachRequestId = DisptachRequestId + 1 + else + DisptachRequestId = 0 + end + + return requestId +end + +AddEventHandler('esx_phone:getDistpatchRequestId', function(cb) + cb(GetDistpatchRequestId()) +end) + +AddEventHandler('esx:playerLoaded', function(source) + LoadPlayer(source) end) AddEventHandler('esx:playerDropped', function(source) @@ -140,7 +149,7 @@ AddEventHandler('esx_phone:send', function(phoneNumber, message, anon, position) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) - print('MESSAGE => ' .. xPlayer.name .. '@' .. phoneNumber .. ' : ' .. message) + print(('esx_phone: MESSAGE => %s@%s: %s'):format(xPlayer.name, phoneNumber, message)) if PhoneNumbers[phoneNumber] ~= nil then @@ -196,15 +205,15 @@ RegisterServerEvent('esx_phone:addPlayerContact') AddEventHandler('esx_phone:addPlayerContact', function(phoneNumber, contactName) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) - phoneNumber = tonumber(phoneNumber) - - -- is the player trying to enter something else into the database? + phoneNumber = tonumber(phoneNumber) + local playerOnline = false + if phoneNumber == nil then - print('esx_phone: ' .. xPlayer.identifier .. ' attempted to crash the database!') + print(('esx_phone: %s attempted SQL injecting!'):format(xPlayer.identifier)) return end - MySQL.Async.fetchAll('SELECT phone_number FROM users WHERE phone_number = @number', { + MySQL.Async.fetchAll('SELECT phone_number, identifier FROM users WHERE phone_number = @number', { ['@number'] = phoneNumber }, function(result) if result[1] ~= nil then @@ -213,6 +222,7 @@ AddEventHandler('esx_phone:addPlayerContact', function(phoneNumber, contactName) else local contacts = xPlayer.get('contacts') + -- already added player? for i=1, #contacts, 1 do if contacts[i].number == phoneNumber then TriggerClientEvent('esx:showNotification', _source, _U('number_in_contacts')) @@ -222,11 +232,15 @@ AddEventHandler('esx_phone:addPlayerContact', function(phoneNumber, contactName) table.insert(contacts, { name = contactName, - number = phoneNumber, + number = phoneNumber }) xPlayer.set('contacts', contacts) + -- is the player currently online? + local xTarget = ESX.GetPlayerFromIdentifier(result[1].identifier) + playerOnline = (xTarget ~= nil) + MySQL.Async.execute('INSERT INTO user_contacts (identifier, name, number) VALUES (@identifier, @name, @number)', { ['@identifier'] = xPlayer.identifier, @@ -234,7 +248,7 @@ AddEventHandler('esx_phone:addPlayerContact', function(phoneNumber, contactName) ['@number'] = phoneNumber }, function(rowsChanged) TriggerClientEvent('esx:showNotification', _source, _U('contact_added')) - TriggerClientEvent('esx_phone:addContact', _source, contactName, phoneNumber) + TriggerClientEvent('esx_phone:addContact', _source, contactName, phoneNumber, playerOnline) end) end else @@ -277,7 +291,7 @@ AddEventHandler('esx_phone:removePlayerContact', function(phoneNumber, contactNa TriggerClientEvent('esx_phone:removeContact', _source, contactName, phoneNumber) end) else - TriggerClientEvent('esx:showNotification', source, _U('number_not_assigned')) + TriggerClientEvent('esx:showNotification', _source, _U('number_not_assigned')) end end) end) From 9189039cbcbe08b8465705e1c26278f681704888 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 30 Oct 2018 23:14:41 +0100 Subject: [PATCH 1852/3224] Removed incomplete translation --- __resource.lua | 2 -- locales/de.lua | 47 ----------------------------------------------- 2 files changed, 49 deletions(-) delete mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index 2e95ff1e..d44b69fd 100644 --- a/__resource.lua +++ b/__resource.lua @@ -7,7 +7,6 @@ version '1.0.7' server_scripts { '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', - 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fi.lua', @@ -21,7 +20,6 @@ server_scripts { client_scripts { '@es_extended/locale.lua', - 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fi.lua', diff --git a/locales/de.lua b/locales/de.lua deleted file mode 100644 index b1671811..00000000 --- a/locales/de.lua +++ /dev/null @@ -1,47 +0,0 @@ -Locales['de'] = { - -- Cloakroom - ['cloakroom'] = 'Umkleide', - ['ems_clothes_civil'] = 'Zivilkleidung', - ['ems_clothes_ems'] = 'Arbeitskleidung', - -- Vehicles - ['veh_menu'] = 'Fahrzeuge', - ['veh_spawn'] = 'Drücke ~INPUT_CONTEXT~ um ein Fahrzeug zu bekommen', - ['store_veh'] = 'Drücke ~INPUT_CONTEXT~ um das Fahrzeug zu parken', - ['ambulance'] = 'Krankenwagen', - ['helicopter'] = 'Helicopter', - -- Action Menu - ['hospital'] = 'Krankenhaus', - ['revive_inprogress'] = 'wiederbeleben im Gange', - ['revive_complete'] = 'du wurdest wiederbelebt ~y~%s~s~', - ['revive_complete_award'] = 'du wurdest wiederbelebt ~y~%s~s~, ~g~$%s~s~', - ['heal_inprogress'] = 'you are healing!', - ['heal_complete'] = 'you have healed ~y~%s~s~', - ['no_players'] = 'keine Spieler in der Nähe', - ['no_vehicles'] = 'keine Fahrzeuge in der Nähe', - ['player_not_unconscious'] = 'ist nicht im Koma', - ['player_not_conscious'] = 'that player is not conscious!', - -- Boss Menu - ['boss_actions'] = 'boss actions', - -- Misc - ['invalid_amount'] = '~r~ungültiger Betrag', - ['open_menu'] = 'Drücke ~INPUT_CONTEXT~ um das Menü zu öffnen', - ['deposit_amount'] = 'Betrag zum einzahlen', - ['money_withdraw'] = 'Betrag zum abheben', - -- F6 Menu - ['ems_menu'] = 'Notdienst - Menü', - ['ems_menu_title'] = 'Notdienst - Menü', - ['ems_menu_revive'] = 'Spieler wiederbeleben', - ['ems_menu_putincar'] = 'in Fahrzeug setzen', - -- Phone - ['alert_ambulance'] = 'Notdienst anrufen', - -- Death - ['please_wait'] = 'you will bleed out in ~b~%s minutes %s seconds~s~\n', - ['press_respawn'] = 'press [~b~E~w~] to respawn.', - ['respawn_now_fine'] = 'respawn now for ~g~$%s ~w~[Press ~b~E~w~]', - ['respawn_fine'] = 'you paid ~r~$%s~s~ to respawn.', - ['distress_send'] = 'press [~b~G~s~] to send distress signal', - ['distress_sent'] = 'distress signal has been sent to available units!', - ['distress_message'] = 'medical attention required: unconscious citizen!', - -- Revive - ['revive_help'] = 'Spieler wiederbeleben', -} From 8f18c991b8f5714d9849018295506e11348373f8 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 30 Oct 2018 23:22:58 +0100 Subject: [PATCH 1853/3224] Death screen update, see description The system has been changed, so that you will first enter a 'respawn available in x' timer, then after that a bleedout timer will appear. --- client/main.lua | 167 +++++++++++++++++++++++++++--------------------- config.lua | 29 ++++----- locales/br.lua | 9 +-- locales/en.lua | 17 ++--- locales/es.lua | 24 +++++-- locales/fi.lua | 10 +-- locales/fr.lua | 10 +-- locales/pl.lua | 10 +-- locales/sv.lua | 10 +-- server/main.lua | 11 ++-- 10 files changed, 166 insertions(+), 131 deletions(-) diff --git a/client/main.lua b/client/main.lua index 169d5697..ef30436a 100644 --- a/client/main.lua +++ b/client/main.lua @@ -52,11 +52,7 @@ function OnPlayerDeath() IsDead = true TriggerServerEvent('esx_ambulancejob:setDeathStatus', 1) - if Config.ShowDeathTimer == true then - ShowDeathTimer() - end - - StartRespawnTimer() + StartDeathTimer() StartDistressSignal() ClearPedTasksImmediately(PlayerPedId()) @@ -65,7 +61,7 @@ end function StartDistressSignal() Citizen.CreateThread(function() - local timer = Config.RespawnDelayAfterRPDeath + local timer = Config.BleedoutTimer while timer > 0 and IsDead do Citizen.Wait(2) @@ -103,74 +99,113 @@ function SendDistressSignal() }) end -function ShowDeathTimer() - local respawnTimer = Config.RespawnDelayAfterRPDeath - local allowRespawn = Config.RespawnDelayAfterRPDeath/2 - local fineAmount = Config.EarlyRespawnFineAmount - local payFine = false +function DrawGenericTextThisFrame() + SetTextFont(4) + SetTextProportional(0) + SetTextScale(0.0, 0.5) + SetTextColour(255, 255, 255, 255) + SetTextDropshadow(0, 0, 0, 0, 255) + SetTextEdge(1, 0, 0, 0, 255) + SetTextDropShadow() + SetTextOutline() + SetTextCentre(true) +end - if Config.EarlyRespawn and Config.EarlyRespawnFine then - ESX.TriggerServerCallback('esx_ambulancejob:checkBalance', function(finePayable) - if finePayable then - payFine = true - else - payFine = false - end +function secondsToClock(seconds) + local seconds, hours, mins, secs = tonumber(seconds), 0, 0, 0 + + if seconds <= 0 then + return 0, 0 + else + local hours = string.format("%02.f", math.floor(seconds / 3600)) + local mins = string.format("%02.f", math.floor(seconds / 60 - (hours * 60))) + local secs = string.format("%02.f", math.floor(seconds - hours * 3600 - mins * 60)) + + return mins, secs + end +end + +function StartDeathTimer() + local canPayFine = false + + if Config.EarlyRespawnFine then + ESX.TriggerServerCallback('esx_ambulancejob:checkBalance', function(canPay) + canPayFine = canPay end) end + local earlySpawnTimer = ESX.Round(Config.EarlyRespawnTimer / 1000) + local bleedoutTimer = ESX.Round(Config.BleedoutTimer / 1000) + Citizen.CreateThread(function() - while respawnTimer > 0 and IsDead do - Citizen.Wait(0) + -- early respawn timer + while earlySpawnTimer > 0 and IsDead do + Citizen.Wait(1000) - raw_seconds = respawnTimer/1000 - raw_minutes = raw_seconds/60 - minutes = stringsplit(raw_minutes, ".")[1] - seconds = stringsplit(raw_seconds-(minutes*60), ".")[1] - - SetTextFont(4) - SetTextProportional(0) - SetTextScale(0.0, 0.5) - SetTextColour(255, 255, 255, 255) - SetTextDropshadow(0, 0, 0, 0, 255) - SetTextEdge(1, 0, 0, 0, 255) - SetTextDropShadow() - SetTextOutline() - - local text = _U('please_wait', minutes, seconds) - - if Config.EarlyRespawn then - if not Config.EarlyRespawnFine and respawnTimer <= allowRespawn then - text = text .. _U('press_respawn') - elseif Config.EarlyRespawnFine and respawnTimer <= allowRespawn and payFine then - text = text .. _U('respawn_now_fine', fineAmount) - else - text = text - end + if earlySpawnTimer > 0 then + earlySpawnTimer = earlySpawnTimer - 1 end + end + + -- bleedout timer + while bleedoutTimer > 0 and IsDead do + Citizen.Wait(1000) + + if bleedoutTimer > 0 then + bleedoutTimer = bleedoutTimer - 1 + end + end + end) + + Citizen.CreateThread(function() + local text, timeHeld + + -- early respawn timer + while earlySpawnTimer > 0 and IsDead do + Citizen.Wait(0) + text = _U('respawn_available_in', secondsToClock(earlySpawnTimer)) + + DrawGenericTextThisFrame() - SetTextCentre(true) SetTextEntry("STRING") AddTextComponentString(text) DrawText(0.5, 0.8) + end - if Config.EarlyRespawn then - if not Config.EarlyRespawnFine then - if IsControlPressed(0, Keys['E']) then - RemoveItemsAfterRPDeath() - break - end - elseif Config.EarlyRespawnFine then - if respawnTimer <= allowRespawn and payFine then - if IsControlPressed(0, Keys['E']) then - PayFine() - break - end - end + -- bleedout timer + while bleedoutTimer > 0 and IsDead do + Citizen.Wait(0) + text = _U('respawn_bleedout_in', secondsToClock(bleedoutTimer)) + + if not Config.EarlyRespawnFine then + text = text .. _U('respawn_bleedout_prompt') + + if IsControlPressed(0, Keys['E']) and timeHeld > 60 then + break + end + elseif Config.EarlyRespawnFine and canPayFine then + text = text .. _U('respawn_bleedout_fine', ESX.Math.GroupDigits(Config.EarlyRespawnFineAmount)) + + if IsControlPressed(0, Keys['E']) and timeHeld > 60 then + TriggerServerEvent('esx_ambulancejob:payFine') + break end end - respawnTimer = respawnTimer - 15 + + if IsControlPressed(0, Keys['E']) then + timeHeld = timeHeld + 1 + else + timeHeld = 0 + end + + DrawGenericTextThisFrame() + + SetTextEntry("STRING") + AddTextComponentString(text) + DrawText(0.5, 0.8) end + + RemoveItemsAfterRPDeath() end) end @@ -196,12 +231,6 @@ function RemoveItemsAfterRPDeath() end) end -function PayFine() - ESX.TriggerServerCallback('esx_ambulancejob:payFine', function() - RemoveItemsAfterRPDeath() - end) -end - function RespawnPed(ped, coords) SetEntityCoordsNoOffset(ped, coords.x, coords.y, coords.z, false, false, false, true) NetworkResurrectLocalPlayer(coords.x, coords.y, coords.z, coords.heading, true, false) @@ -212,14 +241,6 @@ function RespawnPed(ped, coords) ESX.UI.Menu.CloseAll() end -function StartRespawnTimer() - Citizen.SetTimeout(Config.RespawnDelayAfterRPDeath, function() - if IsDead then - RemoveItemsAfterRPDeath() - end - end) -end - function TeleportFadeEffect(entity, coords) Citizen.CreateThread(function() DoScreenFadeOut(800) diff --git a/config.lua b/config.lua index 313ac88a..9b71a678 100644 --- a/config.lua +++ b/config.lua @@ -11,31 +11,26 @@ Config.Locale = 'fr' local second = 1000 local minute = 60 * second --- How much time before auto respawn at hospital -Config.RespawnDelayAfterRPDeath = 10 * minute +Config.EarlyRespawnTimer = 2 * minute -- Time til respawn is available +Config.BleedoutTimer = 10 * minute -- Time til the player bleeds out -Config.EnablePlayerManagement = false -Config.EnableSocietyOwnedVehicles = false +Config.EnablePlayerManagement = false +Config.EnableSocietyOwnedVehicles = false -Config.RemoveWeaponsAfterRPDeath = true -Config.RemoveCashAfterRPDeath = true -Config.RemoveItemsAfterRPDeath = true +Config.RemoveWeaponsAfterRPDeath = true +Config.RemoveCashAfterRPDeath = true +Config.RemoveItemsAfterRPDeath = true --- Will display a timer that shows RespawnDelayAfterRPDeath as a countdown -Config.ShowDeathTimer = true - --- Will allow respawn after half of RespawnDelayAfterRPDeath has elapsed. -Config.EarlyRespawn = false --- The player will be fined for respawning early (on bank account) -Config.EarlyRespawnFine = false -Config.EarlyRespawnFineAmount = 500 +-- Let the player pay for respawning early, if he can afford it. +Config.EarlyRespawnFine = false +Config.EarlyRespawnFineAmount = 5000 Config.Blip = { Pos = { x = 307.76, y = -1433.47, z = 28.97 }, Sprite = 61, Display = 4, Scale = 1.2, - Colour = 2, + Colour = 2 } Config.HelicopterSpawner = { @@ -43,7 +38,7 @@ Config.HelicopterSpawner = { Heading = 0.0 } --- https://wiki.fivem.net/wiki/Vehicles +-- https://wiki.rage.mp/index.php?title=Vehicles Config.AuthorizedVehicles = { { diff --git a/locales/br.lua b/locales/br.lua index 9f7e1114..aada55b4 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -44,10 +44,11 @@ Locales['br'] = { -- Phone ['alert_ambulance'] = 'Alerta Socorro', -- Death - ['please_wait'] = 'you will bleed out in ~b~%s minutes %s seconds~s~\n', - ['press_respawn'] = 'press [~b~E~w~] to respawn.', - ['respawn_now_fine'] = 'respawn now for ~g~$%s ~w~[Press ~b~E~w~]', - ['respawn_fine'] = 'you paid ~r~$%s~s~ to respawn.', + ['respawn_available_in'] = 'respawn available in ~b~%s minutes %s seconds~s~', + ['respawn_bleedout_in'] = 'you will bleed out in ~b~%s minutes %s seconds~s~\n', + ['respawn_bleedout_prompt'] = 'hold [~b~E~s~] to respawn', + ['respawn_bleedout_fine'] = 'hold [~b~E~s~] to respawn for ~g~$%s~s~', + ['respawn_bleedout_fine_msg'] = 'you paid ~r~$%s~s~ to respawn.', ['distress_send'] = 'press [~b~G~s~] to send distress signal', ['distress_sent'] = 'distress signal has been sent to available units!', ['distress_message'] = 'medical attention required: unconscious citizen!', diff --git a/locales/en.lua b/locales/en.lua index 9b7a1f92..8bef3b95 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -2,7 +2,7 @@ Locales['en'] = { -- Cloakroom ['cloakroom'] = 'locker Room', ['ems_clothes_civil'] = 'civilian Clothes', - ['ems_clothes_ems'] = 'eMS Clothes', + ['ems_clothes_ems'] = 'EMS Clothes', -- Vehicles ['veh_menu'] = 'vehicle', ['veh_spawn'] = 'press ~INPUT_CONTEXT~ to get a Vehicle or Helicopter', @@ -35,7 +35,7 @@ Locales['en'] = { ['bandage'] = 'bandage', ['max_item'] = 'You are already carrying enough on yourself.', -- F6 Menu - ['ems_menu'] = 'eMS Menu', + ['ems_menu'] = 'EMS Menu', ['ems_menu_title'] = 'ambulance - EMS Menu', ['ems_menu_revive'] = 'revive Player', ['ems_menu_putincar'] = 'put in Vehicle', @@ -44,10 +44,11 @@ Locales['en'] = { -- Phone ['alert_ambulance'] = 'alert Ambulance', -- Death - ['please_wait'] = 'you will bleed out in ~b~%s minutes %s seconds~s~\n', - ['press_respawn'] = 'press [~b~E~w~] to respawn.', - ['respawn_now_fine'] = 'respawn now for ~g~$%s ~w~[Press ~b~E~w~]', - ['respawn_fine'] = 'you paid ~r~$%s~s~ to respawn.', + ['respawn_available_in'] = 'respawn available in ~b~%s minutes %s seconds~s~', + ['respawn_bleedout_in'] = 'you will bleed out in ~b~%s minutes %s seconds~s~\n', + ['respawn_bleedout_prompt'] = 'hold [~b~E~s~] to respawn', + ['respawn_bleedout_fine'] = 'hold [~b~E~s~] to respawn for ~g~$%s~s~', + ['respawn_bleedout_fine_msg'] = 'you paid ~r~$%s~s~ to respawn.', ['distress_send'] = 'press [~b~G~s~] to send distress signal', ['distress_sent'] = 'distress signal has been sent to available units!', ['distress_message'] = 'medical attention required: unconscious citizen!', @@ -56,7 +57,7 @@ Locales['en'] = { -- Item ['used_medikit'] = 'You have used ~y~1x~s~ medikit', ['used_bandage'] = 'You have used ~y~1x~s~ bandage', - ['not_enough_medikit'] = 'You do not have ~b~medikit~w~.', - ['not_enough_bandage'] = 'You do not have ~b~bandage~w~.', + ['not_enough_medikit'] = 'You do not have ~b~medikit~s~.', + ['not_enough_bandage'] = 'You do not have ~b~bandage~s~.', ['healed'] = 'you have been treated.', } diff --git a/locales/es.lua b/locales/es.lua index 47f009c9..00f3a7ef 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -27,21 +27,37 @@ Locales['es'] = { ['open_menu'] = 'Presione ~INPUT_CONTEXT~ para abrir el menú', ['deposit_amount'] = 'cantidad de fianza depositada', ['money_withdraw'] = 'cantidad de fianza retirada', + ['fast_travel'] = 'Press on ~INPUT_CONTEXT~ to fast travel.', + ['open_pharmacy'] = 'Press on ~INPUT_CONTEXT~ to open the pharmacy.', + ['pharmacy_menu_title'] = 'Pharmacy', + ['pharmacy_take'] = 'Take', + ['medikit'] = 'medikit', + ['bandage'] = 'bandage', + ['max_item'] = 'You are already carrying enough on yourself.', -- F6 Menu ['ems_menu'] = 'ayuda ciudadana', ['ems_menu_title'] = 'ambulancia - Ayuda Ciudadana', ['ems_menu_revive'] = 'reanimar', ['ems_menu_putincar'] = 'meter en el vehículo', + ['ems_menu_small'] = 'heal small wounds', + ['ems_menu_big'] = 'treat serious injuries', -- Phone ['alert_ambulance'] = 'Alerta de ambulancia', -- Death - ['please_wait'] = 'you will bleed out in ~b~%s minutes %s seconds~s~\n', - ['press_respawn'] = 'press [~b~E~w~] to respawn.', - ['respawn_now_fine'] = 'respawn now for ~g~$%s ~w~[Press ~b~E~w~]', - ['respawn_fine'] = 'you paid ~r~$%s~s~ to respawn.', + ['respawn_available_in'] = 'respawn available in ~b~%s minutes %s seconds~s~', + ['respawn_bleedout_in'] = 'you will bleed out in ~b~%s minutes %s seconds~s~\n', + ['respawn_bleedout_prompt'] = 'hold [~b~E~s~] to respawn', + ['respawn_bleedout_fine'] = 'hold [~b~E~s~] to respawn for ~g~$%s~s~', + ['respawn_bleedout_fine_msg'] = 'you paid ~r~$%s~s~ to respawn.', ['distress_send'] = 'press [~b~G~s~] to send distress signal', ['distress_sent'] = 'distress signal has been sent to available units!', ['distress_message'] = 'medical attention required: unconscious citizen!', -- Revive ['revive_help'] = 'reviver un jugador', + -- Item + ['used_medikit'] = 'You have used ~y~1x~s~ medikit', + ['used_bandage'] = 'You have used ~y~1x~s~ bandage', + ['not_enough_medikit'] = 'You do not have ~b~medikit~s~.', + ['not_enough_bandage'] = 'You do not have ~b~bandage~s~.', + ['healed'] = 'you have been treated.', } diff --git a/locales/fi.lua b/locales/fi.lua index 4c34e898..d51ba970 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -44,10 +44,11 @@ Locales['fi'] = { -- Phone ['alert_ambulance'] = 'hälyytys Ensihoidolle', -- Death - ['please_wait'] = 'you will bleed out in ~b~%s minutes %s seconds~s~\n', - ['press_respawn'] = 'press [~b~E~w~] to respawn.', - ['respawn_now_fine'] = 'respawn now for ~g~$%s ~w~[Press ~b~E~w~]', - ['respawn_fine'] = 'you paid ~r~$%s~s~ to respawn.', + ['respawn_available_in'] = 'respawn available in ~b~%s minutes %s seconds~s~', + ['respawn_bleedout_in'] = 'you will bleed out in ~b~%s minutes %s seconds~s~\n', + ['respawn_bleedout_prompt'] = 'hold [~b~E~s~] to respawn', + ['respawn_bleedout_fine'] = 'hold [~b~E~s~] to respawn for ~g~$%s~s~', + ['respawn_bleedout_fine_msg'] = 'you paid ~r~$%s~s~ to respawn.', ['distress_send'] = 'press [~b~G~s~] to send distress signal', ['distress_sent'] = 'distress signal has been sent to available units!', ['distress_message'] = 'medical attention required: unconscious citizen!', @@ -59,5 +60,4 @@ Locales['fi'] = { ['not_enough_medikit'] = 'ei tarpeeksi ~b~ensiapupakkauksia~w~.', ['not_enough_bandage'] = 'ei tarpeeksi ~b~sideharsoja~w~.', ['healed'] = 'sinua parannettiin', - -- Misc } diff --git a/locales/fr.lua b/locales/fr.lua index 2e94632c..3664d892 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -44,10 +44,11 @@ Locales['fr'] = { -- Phone ['alert_ambulance'] = 'alerte Ambulance', -- Death - ['please_wait'] = 'you will bleed out in ~b~%s minutes %s seconds~s~\n', - ['press_respawn'] = 'press [~b~E~w~] to respawn.', - ['respawn_now_fine'] = 'respawn now for ~g~$%s ~w~[Press ~b~E~w~]', - ['respawn_fine'] = 'you paid ~r~$%s~s~ to respawn.', + ['respawn_available_in'] = 'respawn available in ~b~%s minutes %s seconds~s~', + ['respawn_bleedout_in'] = 'you will bleed out in ~b~%s minutes %s seconds~s~\n', + ['respawn_bleedout_prompt'] = 'hold [~b~E~s~] to respawn', + ['respawn_bleedout_fine'] = 'hold [~b~E~s~] to respawn for ~g~$%s~s~', + ['respawn_bleedout_fine_msg'] = 'you paid ~r~$%s~s~ to respawn.', ['distress_send'] = 'press [~b~G~s~] to send distress signal', ['distress_sent'] = 'distress signal has been sent to available units!', ['distress_message'] = 'medical attention required: unconscious citizen!', @@ -59,5 +60,4 @@ Locales['fr'] = { ['not_enough_medikit'] = 'vous n\'avez pas de ~b~kit de soin~w~.', ['not_enough_bandage'] = 'vous n\'avez pas de ~b~bandage~w~.', ['healed'] = 'vous avez été soigné.', - -- Misc } diff --git a/locales/pl.lua b/locales/pl.lua index c6e299b7..1d2a0931 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -44,10 +44,11 @@ Locales['pl'] = { -- Phone ['alert_ambulance'] = 'wezwij ambulans', -- Death - ['please_wait'] = 'you will bleed out in ~b~%s minutes %s seconds~s~\n', - ['press_respawn'] = 'press [~b~E~w~] to respawn.', - ['respawn_now_fine'] = 'respawn now for ~g~$%s ~w~[Press ~b~E~w~]', - ['respawn_fine'] = 'you paid ~r~$%s~s~ to respawn.', + ['respawn_available_in'] = 'respawn available in ~b~%s minutes %s seconds~s~', + ['respawn_bleedout_in'] = 'you will bleed out in ~b~%s minutes %s seconds~s~\n', + ['respawn_bleedout_prompt'] = 'hold [~b~E~s~] to respawn', + ['respawn_bleedout_fine'] = 'hold [~b~E~s~] to respawn for ~g~$%s~s~', + ['respawn_bleedout_fine_msg'] = 'you paid ~r~$%s~s~ to respawn.', ['distress_send'] = 'press [~b~G~s~] to send distress signal', ['distress_sent'] = 'distress signal has been sent to available units!', ['distress_message'] = 'medical attention required: unconscious citizen!', @@ -59,5 +60,4 @@ Locales['pl'] = { ['not_enough_medikit'] = 'nie posiadasz ~b~apteczki~w~.', ['not_enough_bandage'] = 'nie posiadasz ~b~bandaża~w~.', ['healed'] = 'zostałeś potraktowany', - -- Misc } diff --git a/locales/sv.lua b/locales/sv.lua index 18770e4b..72fb6b05 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -44,10 +44,11 @@ Locales['sv'] = { -- Phone ['alert_ambulance'] = 'ambulanssamtal', -- Death - ['please_wait'] = 'du är medvetslös och kommer att dö om ~b~%s minuter och %s sekunder~s~\n', - ['press_respawn'] = 'tryck [~b~E~s~] för att respawna.', - ['respawn_now_fine'] = 'respawna nu för ~g~%s SEK~s~ [Tryck ~b~E~s~]', - ['respawn_fine'] = 'du betalade ~r~%s SEK~s~ för att respawna.', + ['respawn_available_in'] = 'respawn tillgänglig om ~b~%s:%s~s~', + ['respawn_bleedout_in'] = 'du kommer att blöda ut om ~b~%s:%s~s~\n', + ['respawn_bleedout_prompt'] = 'håll [~b~E~s~] för att respawna', + ['respawn_bleedout_fine'] = 'håll [~b~E~s~] för att respawna, kostar ~g~$%s~s~', + ['respawn_bleedout_fine_msg'] = 'du betalade ~r~%s SEK~s~ för att respawna.', ['distress_send'] = 'tryck ~b~[G]~s~ för att skicka nödsignal', ['distress_sent'] = 'nödsignal har skickats till samtliga enheter!', ['distress_message'] = 'läkarvård krävs: medvetslös medborgare!', @@ -59,5 +60,4 @@ Locales['sv'] = { ['not_enough_medikit'] = 'du har inget ~b~Medecinkit~s~.', ['not_enough_bandage'] = 'du har inget ~b~Bandage~s~.', ['healed'] = 'dina skador har blivit behandlade.', - -- Misc } diff --git a/server/main.lua b/server/main.lua index 2146680c..76604682 100644 --- a/server/main.lua +++ b/server/main.lua @@ -71,7 +71,7 @@ ESX.RegisterServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function( cb() end) -if Config.EarlyRespawn and Config.EarlyRespawnFine then +if Config.EarlyRespawnFine then ESX.RegisterServerCallback('esx_ambulancejob:checkBalance', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) local bankBalance = xPlayer.getAccount('bank').money @@ -79,12 +79,13 @@ if Config.EarlyRespawn and Config.EarlyRespawnFine then cb(bankBalance >= Config.EarlyRespawnFineAmount) end) - ESX.RegisterServerCallback('esx_ambulancejob:payFine', function(source, cb) + RegisterServerEvent('esx_ambulancejob:payFine') + AddEventHandler('esx_ambulancejob:payFine', function() local xPlayer = ESX.GetPlayerFromId(source) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('respawn_fine', Config.EarlyRespawnFineAmount)) - xPlayer.removeAccountMoney('bank', Config.EarlyRespawnFineAmount) + local fineAmount = Config.EarlyRespawnFineAmount - cb() + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('respawn_bleedout_fine_msg', ESX.Math.GroupDigits(fineAmount))) + xPlayer.removeAccountMoney('bank', fineAmount) end) end From c2b1c1de8ba9e816682990cfa912d120ace0343a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 30 Oct 2018 23:33:32 +0100 Subject: [PATCH 1854/3224] Enforce 4 tab indent, final commit v1.1.0 --- __resource.lua | 2 +- esx_ambulancejob.sql | 22 +++++++++++----------- localization/de_esx_ambulancejob.sql | 22 +++++++++++----------- localization/en_esx_ambulancejob.sql | 23 +++++++++++------------ localization/fi_esx_ambulancejob.sql | 15 +++++++-------- localization/pl_esx_ambulancejob.sql | 23 +++++++++++------------ 6 files changed, 52 insertions(+), 55 deletions(-) diff --git a/__resource.lua b/__resource.lua index d44b69fd..fc60045b 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,7 +2,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ESX Ambulance Job' -version '1.0.7' +version '1.1.0' server_scripts { '@mysql-async/lib/MySQL.lua', diff --git a/esx_ambulancejob.sql b/esx_ambulancejob.sql index a2aa8fa9..ddb05e02 100644 --- a/esx_ambulancejob.sql +++ b/esx_ambulancejob.sql @@ -1,31 +1,31 @@ USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES - ('society_ambulance', 'Ambulance', 1) + ('society_ambulance', 'Ambulance', 1) ; INSERT INTO `addon_inventory` (name, label, shared) VALUES - ('society_ambulance', 'Ambulance', 1) + ('society_ambulance', 'Ambulance', 1) ; INSERT INTO `datastore` (name, label, shared) VALUES - ('society_ambulance', 'Ambulance', 1) + ('society_ambulance', 'Ambulance', 1) ; INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES - ('ambulance',0,'ambulance','Ambulancier',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}'), - ('ambulance',1,'doctor','Medecin',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}'), - ('ambulance',2,'chief_doctor','Medecin-chef',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}'), - ('ambulance',3,'boss','Chirurgien',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}') + ('ambulance',0,'ambulance','Ambulancier',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}'), + ('ambulance',1,'doctor','Medecin',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}'), + ('ambulance',2,'chief_doctor','Medecin-chef',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}'), + ('ambulance',3,'boss','Chirurgien',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}') ; INSERT INTO `jobs` (name, label) VALUES - ('ambulance','Ambulance') + ('ambulance','Ambulance') ; INSERT INTO `items` (name, label, `limit`) VALUES - ('bandage','Bandage', 20), - ('medikit','Medikit', 5) + ('bandage','Bandage', 20), + ('medikit','Medikit', 5) ; -ALTER TABLE `users` ADD `isDead` BIT(1) DEFAULT b'0' \ No newline at end of file +ALTER TABLE `users` ADD `isDead` BIT(1) DEFAULT b'0' diff --git a/localization/de_esx_ambulancejob.sql b/localization/de_esx_ambulancejob.sql index fc1a52af..d11f2575 100644 --- a/localization/de_esx_ambulancejob.sql +++ b/localization/de_esx_ambulancejob.sql @@ -1,31 +1,31 @@ USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES - ('society_ambulance', 'Notdienst', 1) + ('society_ambulance', 'Notdienst', 1) ; INSERT INTO `addon_inventory` (name, label, shared) VALUES - ('society_ambulance', 'Ambulance', 1) + ('society_ambulance', 'Ambulance', 1) ; INSERT INTO `datastore` (name, label, shared) VALUES - ('society_ambulance', 'Ambulance', 1) + ('society_ambulance', 'Ambulance', 1) ; INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES - ('ambulance',0,'ambulance','Sanitäter',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}'), - ('ambulance',1,'doctor','Arzt',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}'), - ('ambulance',2,'chief_doctor','Chefarzt',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}'), - ('ambulance',3,'boss','Chirurg',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}') + ('ambulance',0,'ambulance','Sanitäter',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}'), + ('ambulance',1,'doctor','Arzt',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}'), + ('ambulance',2,'chief_doctor','Chefarzt',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}'), + ('ambulance',3,'boss','Chirurg',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}') ; INSERT INTO `jobs` (name, label) VALUES - ('ambulance','Notdienst') + ('ambulance','Notdienst') ; INSERT INTO `items` (name, label, `limit`) VALUES - ('bandage','Bandage', 20), - ('medikit','Medikit', 5) + ('bandage','Bandage', 20), + ('medikit','Medikit', 5) ; -ALTER TABLE `users` ADD `isDead` BIT(1) DEFAULT b'0' \ No newline at end of file +ALTER TABLE `users` ADD `isDead` BIT(1) DEFAULT b'0' diff --git a/localization/en_esx_ambulancejob.sql b/localization/en_esx_ambulancejob.sql index 8ba7a87a..cbe37090 100644 --- a/localization/en_esx_ambulancejob.sql +++ b/localization/en_esx_ambulancejob.sql @@ -1,32 +1,31 @@ USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES - ('society_ambulance', 'EMS', 1) + ('society_ambulance', 'EMS', 1) ; INSERT INTO `addon_inventory` (name, label, shared) VALUES - ('society_ambulance', 'EMS', 1) + ('society_ambulance', 'EMS', 1) ; INSERT INTO `datastore` (name, label, shared) VALUES - ('society_ambulance', 'EMS', 1) + ('society_ambulance', 'EMS', 1) ; - INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES - ('ambulance',0,'ambulance','Jr. EMT',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}'), - ('ambulance',1,'doctor','EMT',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}'), - ('ambulance',2,'chief_doctor','Sr. EMT',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}'), - ('ambulance',3,'boss','EMT Supervisor',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}') + ('ambulance',0,'ambulance','Jr. EMT',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}'), + ('ambulance',1,'doctor','EMT',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}'), + ('ambulance',2,'chief_doctor','Sr. EMT',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}'), + ('ambulance',3,'boss','EMT Supervisor',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}') ; INSERT INTO `jobs` (name, label) VALUES - ('ambulance','EMS') + ('ambulance','EMS') ; INSERT INTO `items` (name, label, `limit`) VALUES - ('bandage','Bandage', 20), - ('medikit','Medikit', 5) + ('bandage','Bandage', 20), + ('medikit','Medikit', 5) ; -ALTER TABLE `users` ADD `isDead` BIT(1) DEFAULT b'0' \ No newline at end of file +ALTER TABLE `users` ADD `isDead` BIT(1) DEFAULT b'0' diff --git a/localization/fi_esx_ambulancejob.sql b/localization/fi_esx_ambulancejob.sql index 4e6be961..3ea64c07 100644 --- a/localization/fi_esx_ambulancejob.sql +++ b/localization/fi_esx_ambulancejob.sql @@ -1,18 +1,17 @@ USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES - ('society_ambulance', 'Ensihoito', 1) + ('society_ambulance', 'Ensihoito', 1) ; INSERT INTO `addon_inventory` (name, label, shared) VALUES - ('society_ambulance', 'Ensihoito', 1) + ('society_ambulance', 'Ensihoito', 1) ; INSERT INTO `datastore` (name, label, shared) VALUES - ('society_ambulance', 'Ensihoito', 1) + ('society_ambulance', 'Ensihoito', 1) ; - INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES ('ambulance',0,'ambulance','Ensihoitaja',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}'), ('ambulance',1,'doctor','Lääkäri',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}'), @@ -21,12 +20,12 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ; INSERT INTO `jobs` (name, label) VALUES - ('ambulance','Ensihoito') + ('ambulance','Ensihoito') ; INSERT INTO `items` (name, label, `limit`) VALUES - ('bandage','Sideharso', 20), - ('medikit','Ensiapupakkaus', 5) + ('bandage','Sideharso', 20), + ('medikit','Ensiapupakkaus', 5) ; -ALTER TABLE `users` ADD `isDead` BIT(1) DEFAULT b'0' \ No newline at end of file +ALTER TABLE `users` ADD `isDead` BIT(1) DEFAULT b'0' diff --git a/localization/pl_esx_ambulancejob.sql b/localization/pl_esx_ambulancejob.sql index abbad63c..a9035d79 100644 --- a/localization/pl_esx_ambulancejob.sql +++ b/localization/pl_esx_ambulancejob.sql @@ -1,32 +1,31 @@ USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES - ('society_ambulance', 'Ambulance', 1) + ('society_ambulance', 'Ambulance', 1) ; INSERT INTO `addon_inventory` (name, label, shared) VALUES - ('society_ambulance', 'Ambulance', 1) + ('society_ambulance', 'Ambulance', 1) ; INSERT INTO `datastore` (name, label, shared) VALUES - ('society_ambulance', 'Pogotowie ratunkowe', 1) + ('society_ambulance', 'Pogotowie ratunkowe', 1) ; - INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES - ('ambulance',0,'ambulance','Ratownik',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}'), - ('ambulance',1,'doctor','Lekarz',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}'), - ('ambulance',2,'chief_doctor','Chirurg',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}'), - ('ambulance',3,'boss','Ordynator',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}') + ('ambulance',0,'ambulance','Ratownik',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}'), + ('ambulance',1,'doctor','Lekarz',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}'), + ('ambulance',2,'chief_doctor','Chirurg',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}'), + ('ambulance',3,'boss','Ordynator',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}') ; INSERT INTO `jobs` (name, label) VALUES - ('ambulance','Pogotowie ratunkowe') + ('ambulance','Pogotowie ratunkowe') ; INSERT INTO `items` (name, label, `limit`) VALUES - ('bandage','Bandaż', 20), - ('medikit','Defibrylator', 5) + ('bandage','Bandaż', 20), + ('medikit','Defibrylator', 5) ; -ALTER TABLE `users` ADD `isDead` BIT(1) DEFAULT b'0' \ No newline at end of file +ALTER TABLE `users` ADD `isDead` BIT(1) DEFAULT b'0' From fab5f4d167c1354ae4ea3e14cb0c563ddf24e413 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 30 Oct 2018 23:58:00 +0100 Subject: [PATCH 1855/3224] Disable most inputs when dead (unconscious can't speak, right?) --- client/main.lua | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/client/main.lua b/client/main.lua index ef30436a..b3fe27ee 100644 --- a/client/main.lua +++ b/client/main.lua @@ -48,6 +48,22 @@ AddEventHandler('playerSpawned', function() end end) +-- Disable most inputs when dead +Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + + if IsDead then + DisableAllControlActions(0) + EnableControlAction(0, Keys['G'], true) + EnableControlAction(0, Keys['T'], true) + EnableControlAction(0, Keys['E'], true) + else + Citizen.Wait(500) + end + end +end) + function OnPlayerDeath() IsDead = true TriggerServerEvent('esx_ambulancejob:setDeathStatus', 1) @@ -323,16 +339,3 @@ if Config.LoadIpl then RequestIpl('Coroner_Int_on') -- Morgue end) end - --- String string -function stringsplit(inputstr, sep) - if sep == nil then - sep = "%s" - end - local t={} ; i=1 - for str in string.gmatch(inputstr, "([^"..sep.."]+)") do - t[i] = str - i = i + 1 - end - return t -end From 5410bf75e89e69087421b1c279ffbf80e2f3b04e Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 31 Oct 2018 14:33:05 +0100 Subject: [PATCH 1856/3224] Secutity improvements, lua executor safe --- client/job.lua | 14 ++++++---- locales/br.lua | 2 +- locales/en.lua | 10 ++++---- locales/es.lua | 6 ++--- locales/fi.lua | 2 +- locales/fr.lua | 2 +- locales/pl.lua | 2 +- locales/sv.lua | 4 +-- server/main.lua | 68 ++++++++++++++++++++++++++++++++----------------- 9 files changed, 68 insertions(+), 42 deletions(-) diff --git a/client/job.lua b/client/job.lua index 80943ecc..529ec5fb 100644 --- a/client/job.lua +++ b/client/job.lua @@ -420,7 +420,10 @@ function OpenVehicleSpawnerMenu() ESX.TriggerServerCallback('esx_society:getVehiclesInGarage', function(vehicles) for i=1, #vehicles, 1 do - table.insert(elements, {label = GetDisplayNameFromVehicleModel(vehicles[i].model) .. ' [' .. vehicles[i].plate .. ']', value = vehicles[i]}) + table.insert(elements, { + label = GetDisplayNameFromVehicleModel(vehicles[i].model) .. ' [' .. vehicles[i].plate .. ']', + value = vehicles[i] + }) end ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_spawner', @@ -432,7 +435,7 @@ function OpenVehicleSpawnerMenu() menu.close() local vehicleProps = data.current.value - ESX.Game.SpawnVehicle(vehicleProps.model, Config.Zones.VehicleSpawnPoint.Pos, 270.0, function(vehicle) + ESX.Game.SpawnVehicle(vehicleProps.model, Config.Zones.VehicleSpawnPoint.Pos, 230.0, function(vehicle) ESX.Game.SetVehicleProperties(vehicle, vehicleProps) local playerPed = PlayerPedId() TaskWarpPedIntoVehicle(playerPed, vehicle, -1) @@ -478,13 +481,14 @@ function OpenPharmacyMenu() title = _U('pharmacy_menu_title'), align = 'top-left', elements = { - {label = _U('pharmacy_take') .. ' ' .. _('medikit'), value = 'medikit'}, - {label = _U('pharmacy_take') .. ' ' .. _('bandage'), value = 'bandage'} + {label = _U('pharmacy_take', _U('medikit')), value = 'medikit'}, + {label = _U('pharmacy_take', _U('bandage')), value = 'bandage'} } }, function(data, menu) TriggerServerEvent('esx_ambulancejob:giveItem', data.current.value) end, function(data, menu) menu.close() + CurrentAction = 'pharmacy' CurrentActionMsg = _U('open_pharmacy') CurrentActionData = {} @@ -526,7 +530,7 @@ AddEventHandler('esx_ambulancejob:heal', function(healType) if healType == 'small' then local health = GetEntityHealth(playerPed) - local newHealth = math.min(maxHealth , math.floor(health + maxHealth/8)) + local newHealth = math.min(maxHealth, math.floor(health + maxHealth / 8)) SetEntityHealth(playerPed, newHealth) elseif healType == 'big' then SetEntityHealth(playerPed, maxHealth) diff --git a/locales/br.lua b/locales/br.lua index aada55b4..1e934fcb 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -30,7 +30,7 @@ Locales['br'] = { ['fast_travel'] = 'Aperte ~INPUT_CONTEXT~ para mover-se rapidamente.', ['open_pharmacy'] = 'Aperte ~INPUT_CONTEXT~ para abrir a farmácia.', ['pharmacy_menu_title'] = 'Farmácia', - ['pharmacy_take'] = 'Tomar', + ['pharmacy_take'] = 'tomar ~y~%s~s~', ['medikit'] = 'Seringa', ['bandage'] = 'Vendagem', ['max_item'] = 'você já carrega o suficiente sobre você.', diff --git a/locales/en.lua b/locales/en.lua index 8bef3b95..17c85a22 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -27,13 +27,13 @@ Locales['en'] = { ['open_menu'] = 'press ~INPUT_CONTEXT~ to open the menu', ['deposit_amount'] = 'deposit Amount', ['money_withdraw'] = 'amount withdrawn', - ['fast_travel'] = 'Press on ~INPUT_CONTEXT~ to fast travel.', - ['open_pharmacy'] = 'Press on ~INPUT_CONTEXT~ to open the pharmacy.', - ['pharmacy_menu_title'] = 'Pharmacy', - ['pharmacy_take'] = 'Take', + ['fast_travel'] = 'press ~INPUT_CONTEXT~ to fast travel.', + ['open_pharmacy'] = 'press ~INPUT_CONTEXT~ to open the pharmacy.', + ['pharmacy_menu_title'] = 'pharmacy', + ['pharmacy_take'] = 'take ~y~%s~s~', ['medikit'] = 'medikit', ['bandage'] = 'bandage', - ['max_item'] = 'You are already carrying enough on yourself.', + ['max_item'] = 'You are already carrying enough.', -- F6 Menu ['ems_menu'] = 'EMS Menu', ['ems_menu_title'] = 'ambulance - EMS Menu', diff --git a/locales/es.lua b/locales/es.lua index 00f3a7ef..2445a06e 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -27,10 +27,10 @@ Locales['es'] = { ['open_menu'] = 'Presione ~INPUT_CONTEXT~ para abrir el menú', ['deposit_amount'] = 'cantidad de fianza depositada', ['money_withdraw'] = 'cantidad de fianza retirada', - ['fast_travel'] = 'Press on ~INPUT_CONTEXT~ to fast travel.', - ['open_pharmacy'] = 'Press on ~INPUT_CONTEXT~ to open the pharmacy.', + ['fast_travel'] = 'Press ~INPUT_CONTEXT~ to fast travel.', + ['open_pharmacy'] = 'Press ~INPUT_CONTEXT~ to open the pharmacy.', ['pharmacy_menu_title'] = 'Pharmacy', - ['pharmacy_take'] = 'Take', + ['pharmacy_take'] = 'take ~y~%s~s~', ['medikit'] = 'medikit', ['bandage'] = 'bandage', ['max_item'] = 'You are already carrying enough on yourself.', diff --git a/locales/fi.lua b/locales/fi.lua index d51ba970..59574c21 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -30,7 +30,7 @@ Locales['fi'] = { ['fast_travel'] = 'paina ~INPUT_CONTEXT~ liikkuaksesi nopeasti kerrosten välillä', ['open_pharmacy'] = 'paina ~INPUT_CONTEXT~ avataksesi lääkekaappi', ['pharmacy_menu_title'] = 'lääkekaappi', - ['pharmacy_take'] = 'ota', + ['pharmacy_take'] = 'ota ~y~%s~s~', ['medikit'] = 'ensiapupakkauksia', ['bandage'] = 'sideharsoja', ['max_item'] = 'sinulla on jo tarpeeksi mukana', diff --git a/locales/fr.lua b/locales/fr.lua index 3664d892..1fa2cca3 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -30,7 +30,7 @@ Locales['fr'] = { ['fast_travel'] = 'appuyez sur ~INPUT_CONTEXT~ pour vous déplacer rapidement.', ['open_pharmacy'] = 'appuyez sur ~INPUT_CONTEXT~ pour ouvrir la pharmacie.', ['pharmacy_menu_title'] = 'Pharmacie', - ['pharmacy_take'] = 'Prendre', + ['pharmacy_take'] = 'prendre ~y~%s~s~', ['medikit'] = 'kit de soin', ['bandage'] = 'bandage', ['max_item'] = 'vous en portez déjà assez sur vous.', diff --git a/locales/pl.lua b/locales/pl.lua index 1d2a0931..31b5486a 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -30,7 +30,7 @@ Locales['pl'] = { ['fast_travel'] = 'naciśnij na ~INPUT_CONTEXT~ do szybkiej podróży.', ['open_pharmacy'] = 'naciśnij na ~INPUT_CONTEXT~ aby otworzyć aptekę', ['pharmacy_menu_title'] = 'apteka', - ['pharmacy_take'] = 'weź', + ['pharmacy_take'] = 'weź ~y~%s~s~', ['medikit'] = 'apteczka', ['bandage'] = 'bandaż', ['max_item'] = 'już masz na sobie dość.', diff --git a/locales/sv.lua b/locales/sv.lua index 72fb6b05..ae3f4a04 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -30,7 +30,7 @@ Locales['sv'] = { ['fast_travel'] = 'tryck på ~INPUT_CONTEXT~ för att snabbresa.', ['open_pharmacy'] = 'tryck på ~INPUT_CONTEXT~ för att öppna apoteket.', ['pharmacy_menu_title'] = 'apotek', - ['pharmacy_take'] = 'ta', + ['pharmacy_take'] = 'ta ~y~%s~s~', ['medikit'] = 'medicinkit', ['bandage'] = 'bandage', ['max_item'] = 'du har redan tillräckligt mycket på dig.', @@ -47,7 +47,7 @@ Locales['sv'] = { ['respawn_available_in'] = 'respawn tillgänglig om ~b~%s:%s~s~', ['respawn_bleedout_in'] = 'du kommer att blöda ut om ~b~%s:%s~s~\n', ['respawn_bleedout_prompt'] = 'håll [~b~E~s~] för att respawna', - ['respawn_bleedout_fine'] = 'håll [~b~E~s~] för att respawna, kostar ~g~$%s~s~', + ['respawn_bleedout_fine'] = 'håll [~b~E~s~] för att respawna, kostar ~g~%s SEK~s~', ['respawn_bleedout_fine_msg'] = 'du betalade ~r~%s SEK~s~ för att respawna.', ['distress_send'] = 'tryck ~b~[G]~s~ för att skicka nödsignal', ['distress_sent'] = 'nödsignal har skickats till samtliga enheter!', diff --git a/server/main.lua b/server/main.lua index 76604682..4eb51635 100644 --- a/server/main.lua +++ b/server/main.lua @@ -4,22 +4,36 @@ TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) RegisterServerEvent('esx_ambulancejob:revive') AddEventHandler('esx_ambulancejob:revive', function(target) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) + local xPlayer = ESX.GetPlayerFromId(source) - xPlayer.addMoney(Config.ReviveReward) - TriggerClientEvent('esx_ambulancejob:revive', target) + if xPlayer.job.name == 'ambulance' then + xPlayer.addMoney(Config.ReviveReward) + TriggerClientEvent('esx_ambulancejob:revive', target) + else + print(('esx_ambulancejob: %s attempted to revive!'):format(xPlayer.identifier)) + end end) RegisterServerEvent('esx_ambulancejob:heal') AddEventHandler('esx_ambulancejob:heal', function(target, type) - TriggerClientEvent('esx_ambulancejob:heal', target, type) + local xPlayer = ESX.GetPlayerFromId(source) + + if xPlayer.job.name == 'ambulance' then + TriggerClientEvent('esx_ambulancejob:heal', target, type) + else + print(('esx_ambulancejob: %s attempted to heal!'):format(xPlayer.identifier)) + end end) RegisterServerEvent('esx_ambulancejob:putInVehicle') AddEventHandler('esx_ambulancejob:putInVehicle', function(target) + local xPlayer = ESX.GetPlayerFromId(source) - TriggerClientEvent('esx_ambulancejob:putInVehicle', target) + if xPlayer.job.name == 'ambulance' then + TriggerClientEvent('esx_ambulancejob:putInVehicle', target) + else + print(('esx_ambulancejob: %s attempted to put in vehicle!'):format(xPlayer.identifier)) + end end) TriggerEvent('esx_phone:registerNumber', 'ambulance', _U('alert_ambulance'), true, true) @@ -112,26 +126,34 @@ end) RegisterServerEvent('esx_ambulancejob:giveItem') AddEventHandler('esx_ambulancejob:giveItem', function(itemName) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) - local item = xPlayer.getInventoryItem(itemName) - local count = 1 + local xPlayer = ESX.GetPlayerFromId(source) - if item.limit ~= -1 then - count = item.limit - item.count + if xPlayer.job.name ~= 'ambulance' then + print(('esx_ambulancejob: %s attempted to spawn in an item!'):format(xPlayer.identifier)) + return + elseif itemName ~= 'medikit' or itemName ~= 'bandage' then + print(('esx_ambulancejob: %s attempted to spawn in an item!'):format(xPlayer.identifier)) + return end - if item.count < item.limit then + local xItem = xPlayer.getInventoryItem(itemName) + + local count = 1 + if xItem.limit ~= -1 then + count = xItem.limit - xItem.count + end + + if xItem.count < xItem.limit then xPlayer.addInventoryItem(itemName, count) else - TriggerClientEvent('esx:showNotification', _source, _U('max_item')) + TriggerClientEvent('esx:showNotification', source, _U('max_item')) end end) TriggerEvent('es:addGroupCommand', 'revive', 'admin', function(source, args, user) if args[1] ~= nil then if GetPlayerName(tonumber(args[1])) ~= nil then - print('esx_ambulancejob: ' .. GetPlayerName(source) .. ' is reviving a player!') + print(('esx_ambulancejob: %s used admin revive'):format(GetPlayerIdentifiers(source)[1])) TriggerClientEvent('esx_ambulancejob:revive', tonumber(args[1])) end else @@ -139,7 +161,7 @@ TriggerEvent('es:addGroupCommand', 'revive', 'admin', function(source, args, use end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, { help = _U('revive_help'), params = { { name = 'id' } } }) +end, { help = _U('revive_help'), params = {{ name = 'id' }} }) ESX.RegisterUsableItem('medikit', function(source) local _source = source @@ -161,12 +183,11 @@ RegisterServerEvent('esx_ambulancejob:firstSpawn') AddEventHandler('esx_ambulancejob:firstSpawn', function() local _source = source local identifier = GetPlayerIdentifiers(_source)[1] - MySQL.Async.fetchScalar('SELECT isDead FROM users WHERE identifier=@identifier', - { + MySQL.Async.fetchScalar('SELECT isDead FROM users WHERE identifier = @identifier', { ['@identifier'] = identifier }, function(isDead) if isDead == 1 then - print('esx_ambulancejob: ' .. GetPlayerName(_source) .. ' (' .. identifier .. ') attempted combat logging!') + print(('esx_ambulancejob: %s attempted combat logging!'):format(identifier)) TriggerClientEvent('esx_ambulancejob:requestDeath', _source) end end) @@ -174,10 +195,11 @@ end) RegisterServerEvent('esx_ambulancejob:setDeathStatus') AddEventHandler('esx_ambulancejob:setDeathStatus', function(isDead) - local _source = source - MySQL.Sync.execute("UPDATE users SET isDead=@isDead WHERE identifier=@identifier", + local identifier = GetPlayerIdentifiers(source)[1] + + MySQL.Sync.execute("UPDATE users SET isDead=@isDead WHERE identifier = @identifier", { - ['@identifier'] = GetPlayerIdentifiers(_source)[1], - ['@isDead'] = isDead + ['@identifier'] = identifier, + ['@isDead'] = isDead }) end) From a38b560a1644426ea17134debee517c7ca8a43e3 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 31 Oct 2018 15:20:47 +0100 Subject: [PATCH 1857/3224] Enforced 4 tab indent --- __resource.lua | 2 +- client/main.lua | 553 +++++++++++++++++++++--------------------------- config.lua | 50 ++--- server/main.lua | 68 +++--- 4 files changed, 294 insertions(+), 379 deletions(-) diff --git a/__resource.lua b/__resource.lua index 32238286..89940347 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,6 +1,6 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' -description 'ESX Real estate job' +description 'ESX Real Estate Job' version '1.0.0' diff --git a/client/main.lua b/client/main.lua index 36195152..4c33738d 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,17 +1,16 @@ local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, + ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, + ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, + ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, + ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 } -local GUI = {} -local PlayerData = {} +local PlayeerData = {} local HasAlreadyEnteredMarker = false local LastZone = nil local CurrentAction = nil @@ -19,405 +18,329 @@ local CurrentActionMsg = '' local CurrentActionData = {} ESX = nil -GUI.Time = 0 Citizen.CreateThread(function() - while ESX == nil do - TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) - Citizen.Wait(0) - end + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end end) function OpenRealestateAgentMenu() + local elements = { + {label = _U('properties'), value = 'properties'}, + {label = _U('clients'), value = 'customers'}, + } - local elements = { - {label = _U('properties'), value = 'properties'}, - {label = _U('clients'), value = 'customers'}, - } + if PlayerData.job ~= nil and PlayerData.job.name == 'realestateagent' and PlayerData.job.grade_name == 'boss' then + table.insert(elements, { + label = _U('boss_action'), + value = 'boss_actions' + }) + end - if PlayerData.job ~= nil and PlayerData.job.name == 'realestateagent' and PlayerData.job.grade_name == 'boss' then - table.insert(elements, {label = _U('boss_action'), value = 'boss_actions'}) - end + ESX.UI.Menu.CloseAll() - ESX.UI.Menu.CloseAll() + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'realestateagent', { + title = _U('realtor'), + elements = elements + }, function(data, menu) - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'realestateagent', - { - title = _U('realtor'), - elements = elements - }, - function(data, menu) + if data.current.value == 'properties' then + OpenPropertyMenu() + elseif data.current.value == 'customers' then + OpenCustomersMenu() + elseif data.current.value == 'boss_actions' then + TriggerEvent('esx_society:openBossMenu', 'realestateagent', function(data, menu) + menu.close() + end) + end - if data.current.value == 'properties' then - OpenPropertyMenu() - end + end, function(data, menu) + menu.close() - if data.current.value == 'customers' then - OpenCustomersMenu() - end - - if data.current.value == 'boss_actions' then - TriggerEvent('esx_society:openBossMenu', 'realestateagent', function(data, menu) - menu.close() - end) - end - - end, - function(data, menu) - - menu.close() - - CurrentAction = 'realestateagent_menu' - CurrentActionMsg = _U('press_to_access') - CurrentActionData = {} - - end - ) + CurrentAction = 'realestateagent_menu' + CurrentActionMsg = _U('press_to_access') + CurrentActionData = {} + end) end function OpenPropertyMenu() + TriggerEvent('esx_property:getProperties', function(properties) - TriggerEvent('esx_property:getProperties', function(properties) + local elements = { + head = {_U('property'), 'Actions'}, + rows = {} + } - local elements = { - head = {_U('property'), 'Actions'}, - rows = {} - } + for i=1, #properties, 1 do + table.insert(elements.rows, { + data = properties[i], + cols = { + properties[i].label, + _U('property_actions') + } + }) + end - for i=1, #properties, 1 do - table.insert(elements.rows, { - data = properties[i], - cols = { - properties[i].label, - _U('property_actions') - } - }) - end + ESX.UI.Menu.Open('list', GetCurrentResourceName(), 'properties', elements, function(data, menu) - ESX.UI.Menu.Open( - 'list', GetCurrentResourceName(), 'properties', - elements, - function(data, menu) + if data.value == 'sell' then - if data.value == 'sell' then + menu.close() - menu.close() + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'sell_property_amount', { + title = _U('amount') + }, function(data2, menu2) + local amount = tonumber(data2.value) - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'sell_property_amount', - { - title = _U('amount') - }, - function(data2, menu2) + if amount == nil then + ESX.ShowNotification(_U('invalid_amount')) + else + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(_U('no_play_near')) + else + TriggerServerEvent('esx_realestateagentjob:sell', GetPlayerServerId(closestPlayer), data.data.name, amount) + menu2.close() + end - local amount = tonumber(data2.value) + OpenPropertyMenu() + end + end, function(data2, menu2) + menu2.close() + end) - if amount == nil then - ESX.ShowNotification(_U('invalid_amount')) - else - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + elseif data.value == 'rent' then - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(_U('no_play_near')) - else - TriggerServerEvent('esx_realestateagentjob:sell', GetPlayerServerId(closestPlayer), data.data.name, amount) - menu2.close() - end + menu.close() - OpenPropertyMenu() + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'rent_property_amount', { + title = _U('amount') + }, function(data2, menu2) + local amount = tonumber(data2.value) - end + if amount == nil then + ESX.ShowNotification(_U('invalid_amount')) + else + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(_U('no_play_near')) + else + TriggerServerEvent('esx_realestateagentjob:rent', GetPlayerServerId(closestPlayer), data.data.name, amount) + menu2.close() + end - end, - function(data2, menu2) - menu2.close() - end - ) + OpenPropertyMenu() + end + end, function(data2, menu2) + menu2.close() + end) - end + elseif data.value == 'gps' then - if data.value == 'rent' then + TriggerEvent('esx_property:getProperty', data.data.name, function(property) + if property.isSingle then + SetNewWaypoint(property.entering.x, property.entering.y) + else + TriggerEvent('esx_property:getGateway', property, function(gateway) + SetNewWaypoint(gateway.entering.x, gateway.entering.y) + end) + end + end) - menu.close() + end - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'rent_property_amount', - { - title = _U('amount') - }, - function(data2, menu2) + end, function(data, menu) + menu.close() + end) - local amount = tonumber(data2.value) - - if amount == nil then - ESX.ShowNotification(_U('invalid_amount')) - else - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(_U('no_play_near')) - else - TriggerServerEvent('esx_realestateagentjob:rent', GetPlayerServerId(closestPlayer), data.data.name, amount) - menu2.close() - end - - OpenPropertyMenu() - - end - - end, - function(data2, menu2) - menu2.close() - end - ) - - end - - if data.value == 'gps' then - - TriggerEvent('esx_property:getProperty', data.data.name, function(property) - - if property.isSingle then - SetNewWaypoint(property.entering.x, property.entering.y) - else - TriggerEvent('esx_property:getGateway', property, function(gateway) - SetNewWaypoint(gateway.entering.x, gateway.entering.y) - end) - end - - end) - - end - - end, - function(data, menu) - menu.close() - end - ) - - end) + end) end function OpenCustomersMenu() + ESX.TriggerServerCallback('esx_realestateagentjob:getCustomers', function(customers) + local elements = { + head = {'Client', _U('property'), 'Type', 'Actions'}, + rows = {} + } - ESX.TriggerServerCallback('esx_realestateagentjob:getCustomers', function(customers) + for i=1, #customers, 1 do + table.insert(elements.rows, { + data = customers[i], + cols = { + customers[i].name, + customers[i].propertyName, + (customers[i].propertyRented and _U('rent') or _U('sell')), + _U('contract') + } + }) + end - local elements = { - head = {'Client', _U('property'), 'Type', 'Actions'}, - rows = {} - } + ESX.UI.Menu.Open('list', GetCurrentResourceName(), 'customers', elements, function(data, menu) - for i=1, #customers, 1 do - table.insert(elements.rows, { - data = customers[i], - cols = { - customers[i].name, - customers[i].propertyName, - (customers[i].propertyRented and _U('rent') or _U('sell')), - _U('contract') - } - }) - end - - ESX.UI.Menu.Open( - 'list', GetCurrentResourceName(), 'customers', - elements, - function(data, menu) - - if data.value == 'revoke' then - TriggerServerEvent('esx_realestateagentjob:revoke', data.data.propertyName, data.data.propertyOwner) - OpenCustomersMenu() - end - - if data.value == 'gps' then - - TriggerEvent('esx_property:getProperty', data.data.propertyName, function(property) - - if property.isSingle then - SetNewWaypoint(property.entering.x, property.entering.y) - else - TriggerEvent('esx_property:getGateway', property, function(gateway) - SetNewWaypoint(gateway.entering.x, gateway.entering.y) - end) - end - - end) - - end - - end, - function(data, menu) - menu.close() - end - ) - - end) + if data.value == 'revoke' then + TriggerServerEvent('esx_realestateagentjob:revoke', data.data.propertyName, data.data.propertyOwner) + OpenCustomersMenu() + elseif data.value == 'gps' then + TriggerEvent('esx_property:getProperty', data.data.propertyName, function(property) + if property.isSingle then + SetNewWaypoint(property.entering.x, property.entering.y) + else + TriggerEvent('esx_property:getGateway', property, function(gateway) + SetNewWaypoint(gateway.entering.x, gateway.entering.y) + end) + end + end) + end + end, function(data, menu) + menu.close() + end) + end) end RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) + PlayerData = xPlayer - PlayerData = xPlayer - - if PlayerData.job.name == 'realestateagent' then - Config.Zones.OfficeActions.Type = 1 - else - Config.Zones.OfficeActions.Type = -1 - end - + if PlayerData.job.name == 'realestateagent' then + Config.Zones.OfficeActions.Type = 1 + else + Config.Zones.OfficeActions.Type = -1 + end end) RegisterNetEvent('esx:setJob') AddEventHandler('esx:setJob', function(job) + PlayerData.job = job - PlayerData.job = job - - if PlayerData.job.name == 'realestateagent' then - Config.Zones.OfficeActions.Type = 1 - else - Config.Zones.OfficeActions.Type = -1 - end - + if PlayerData.job.name == 'realestateagent' then + Config.Zones.OfficeActions.Type = 1 + else + Config.Zones.OfficeActions.Type = -1 + end end) AddEventHandler('esx_realestateagentjob:hasEnteredMarker', function(zone) - - if zone == 'OfficeEnter' then - local playerPed = GetPlayerPed(-1) - SetEntityCoords(playerPed, Config.Zones.OfficeInside.Pos.x, Config.Zones.OfficeInside.Pos.y, Config.Zones.OfficeInside.Pos.z) - end - - if zone == 'OfficeExit' then - local playerPed = GetPlayerPed(-1) - SetEntityCoords(playerPed, Config.Zones.OfficeOutside.Pos.x, Config.Zones.OfficeOutside.Pos.y, Config.Zones.OfficeOutside.Pos.z) - end - - if zone == 'OfficeActions' and PlayerData.job ~= nil and PlayerData.job.name == 'realestateagent' then - CurrentAction = 'realestateagent_menu' - CurrentActionMsg = _U('press_to_access') - CurrentActionData = {} - end - + if zone == 'OfficeEnter' then + local playerPed = PlayerPedId() + SetEntityCoords(playerPed, Config.Zones.OfficeInside.Pos.x, Config.Zones.OfficeInside.Pos.y, Config.Zones.OfficeInside.Pos.z) + elseif zone == 'OfficeExit' then + local playerPed = PlayerPedId() + SetEntityCoords(playerPed, Config.Zones.OfficeOutside.Pos.x, Config.Zones.OfficeOutside.Pos.y, Config.Zones.OfficeOutside.Pos.z) + elseif zone == 'OfficeActions' and PlayerData.job ~= nil and PlayerData.job.name == 'realestateagent' then + CurrentAction = 'realestateagent_menu' + CurrentActionMsg = _U('press_to_access') + CurrentActionData = {} + end end) AddEventHandler('esx_realestateagentjob:hasExitedMarker', function(zone) - ESX.UI.Menu.CloseAll() - CurrentAction = nil + ESX.UI.Menu.CloseAll() + CurrentAction = nil end) RegisterNetEvent('esx_phone:loaded') AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) + local specialContact = { + name = _U('realtor'), + number = 'realestateagent', + base64Icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAlgAAAJYCAYAAAC+ZpjcAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAOuZJREFUeNrs3V+MXHed4O0zVqQgC9O+sgWR7L5J7Lmwu1dxxE3sNDNo590hIXlnJV4JgtIsr1iimVeYi0SWgDedAUsWuRijYRTP7M7QUQjSIL07DoHZ3RG8ace52FGC6LYvxjY3dkshsq/cBFnkKnu+VefYlXZ1dVX3OVXnz/NIpUoIAudUddWnf+f35w8++OCDBACA4uxwCQAABBYAgMACABBYAAAILAAAgQUAILAAABBYAAACCwBAYAEAILAAAAQWAIDAAgBos3tcAqAMO2dPzfX87e70Mbvuv9LvPyvacvq4Oeg/u7V8YsmrBRTtDz744ANXARg1mqazR5jrCaaZmv8rrvTEVx5eV7OHGAMEFrCtgJpLPjzC9Iir8yHnsud8NGxJgAECC9odUdNJd/SpN6LiMeXqFGItC6/e+LqaxtdVlwYEFlD/kMrjaS65c0vPSNRkxcjX1ewR4bWchtdNlwUEFlDNmJpO7oxEzSVGpOokH/Fayp6XjXaBwALGH1O714XUnJhqZHQt9YaXkS4QWECxQTW9LqZmXJVWWumNLqNcILCArQVV/tjvqtDHtSy4lgQXCCxAUCG4QGABpUTVEz1B5ZYfZVjpia2zLgcILGhiUE2nT3lUPe6KMAGvZsF11ugWCCyoc1TFpPT5xCgV1ZOPbi2msbXscoDAgqpHVYxS5SNV5lJRB/ncrbNuJYLAgipGVTzsR0Wdxf5bZ8UWCCwQVSC2QGBBjaMqn1M1L6poYWwtJuZsgcCCgqJquieqzKmC7pytPLauuhwgsGDYqIqz/p7IouoRVwQ2dC6LrbPOSgSBBRuFVdwCPJ6YVwWjyudrnXYLEQQW9I5WRVjZqwq2L/bYOp0Y1UJgCSxaGVZGq6BcRrUQWNCisJpPzK2CcevM1UpDa9GlQGBBc6IqbgMezx5Gq2ByYlQrbh+edvsQgQX1Dav8NuBTrgZUzkuJ24cILKhVWM2lTwuJ24BQB3H7cCENrSWXAoEF1Qyr+SysbAgK9XMtC61FlwKBBcIKEFogsGhMVJm4Ds1mQjwCC4QVILRAYCGsAKEFAgthJawAoYXAgu3HVUTVgrACNgitmAx/2qVAYMFwYTWfWBUIDMeqQwQWbBJWc+nTorACthha8zYsRWDBh8NqIbHzOrB9doZHYNH6sJrOwspZgUDRXspC66pLgcCiLWFlZSAwDlYcIrBoTVzNJyawA+NlIjwCi8aG1Wz2m6R5VsCkxPys42loLbsUCCzqHlZxO3AhfXzN1QAq4ntJd0TLbUMEFrWMq/mkO2plnhVQNTE/67jbhggs6hRWbgcCdeG2IQKLyodVvjrwOVcDqJnnE6sNEVhUMK7mEruwA/VmN3gEFpUJqxi1ituBNgsFmiI2KT1uNAuBxaTi6omkO2plEjvQNDEJPkazzroUCCzGFVa7s7B63NUAGu7VLLSMZjGSHS4BI8ZVjFpdFVdAS8Rn3dXssw+GZgSLYcPKqBXQdkazGJoRLIaJK6NWAEazGIERLAaFlWNuAPpz3A4Ciy3FVezGHqtn7GsF0F/sm/WEXeDpxy1C+sXVQvr0K3EFMFB8Rv4q+8yEDzGCRW9YxS3BGLVyhiDAaOJMwyfcMiRnBIs8rvKJ7OIKYHTx2WkCPAKLD8VVHHXzT4kd2QG2Iz5D/yn7TKXl3CJsd1hNJ91bgjOuBkChVpLuLcOrLkU7GcFqb1zFMPayuAIoRXy2LrtlKLBoV1wtJG4JApQtv2W44FK0j1uE7QorqwQBJsMqw5YxgtWeuIqNQ5fFFcBExGfvcvZZjMCiIXE1n9g4FGDS8o1J512K5nOLsPlxtZg+PeVKAFTKS7eWTwgtgUUNw8p8K4BqMy+rwdwibGZcmW8FUH3mZQksahRXsefKUmK+FUAdxGf1kv2yBBbVjqvjif2tAOom3y/ruEvRHOZgNSeuFhOT2QHqzuR3gUVFwspkdoBmMfldYFGBuFpKnCcI0DRxWPScyKovc7DqG1ex6uSquAJopPhsv2qFocBi/HG1lJjMDtBk8Rm/JLIEFuOJq/mke+yNuAJoR2Q5XkdgMYa4+oErAdA6PxBZAoty4mpBXAG0PrIWXIZ6sIqwHnG1mNjjCoAue2XVgBEscQVAvTyVfTcgsBBXAIis9nCLsJphZQNRAIZhQ9KKMoIlrgCor/iuWMq+OxBYiCsARJbAQlwBILIYkjlY4gpa49iRfcnR9NHr/Nuryc333k8uXL7uAtEE5mQJLMQVjMc3vvpw8v88+VDysY/eO/C/99vfvZ+spKG1lgbXyqXryepv1pJrPQ8QWQgscQWt98XPHkq+8fTDyb6PF3N058UrN5Kb7/0+eeOt1U6ExaiX0S9EFgJLXEErxK3Av/v2ZwoLq2Gsvtsd5bpwqRthbj0isgSWqyCuoDFhFSNWRx/cV6k/l/hCZAksxhNYy+IKirP/E1PJC89+Onl07v7a/dnz+Oo83kkj7PKNZC1uQ6YRBkVFVhpYsy6DwGp6XC0mjr+BwsIqRqyefOxQI//98kn34osCOCBaYIkrYLCpXR9J/uILR4ZaGdhU4guRJbAQV1CYYbdcaLON4msle0ZkuQwCqylxdTp9+porAVtX9JYLbXb+l6t37fUlvlrl+TSyFlwGgVX3uIrfFH7gSsDWxMrAmMB+6IE9LsaE4stGq430pTSyFl0GgSWuoIVhVcUtF9qs30ar4ktkIbDGHVexJPZXrgSMpukrA9sQX8FeX7Xx79LIWnYZBFad4mopfZgsAkOKlYHf/OrDyZ9/4YiL0TA2Wq20GH6cE1kCqw5xFbu0XxVXMHxYtX3LhTaz3URlImvabu8Cq+pxtZTYpR2GYmUg4qsyHKlTsHtcgkKdFVewucc+9UDywrN/LKwYKEY0Y5HD0QeHjy/bTWzZTPYdNudSFMMIVkFsJAqbszKQcbHX15bZiFRgVSqujqdPf+VKQH91PowZ8dVCX08j67TLILAmHVdPpE//5ErA3WICe9wKtOUCdY6vlu719X+mkXXWO0JgTSqubMcAG4SVlYE0Tcs2WrV9g8CaWFzFisF44+13NeCOWBkYtwOFFW3S0L2+rqWPWSsLt8Yqwq07K67gDisDabN438ej3wKO3hWPEWARXTXZamJ/YmXhlhnB2gIrBuEOKwNheBFbz3z358nLP7lYpz+2lYUCayxxFW8yBzjTelYGwmhh9dc/fCv5/itv13W1ooOhBVapceUAZ1rPykAYzQ9fu5icfPHNJkyGdzC0wColrkxqp/VhZWUgDC+2fPjKt37WpFWGJr2PwCT34ZnUTmv9xRceSr759MPCCoYMqxixauCZiSa9j8AI1hB2zp5aSJ+ecyVoG4cxw/Biq4YIq5pNYN+K528tn1jwigus7caVndppHSsDYXgxgf07aVh9/5W3Sv3/idv0FZogb6d3gbWtuJpOuvOu/PpOK8TKwL/79meEFQwZVuNYGRg/l/ELTzz/yZd/VJV//ZhYFvOxrnon9GcO1mBnxRVtCav4ALcyEIYzjpWB638uY25XhUxl35Gz3g0CayQ7Z0/FSeIzrgRNZmUgjGYcKwPj5/KbX304+fP0Z7PiZuK78tbyiePeGQJr2LiKeVdfcyVoMisDYbSwKntlYE1/4fla+p25ZD6WwBomrmK/q0VXgqayMhCGFysDn/nuL5LXXr/i53JjizFn2f5YAmsz5l3RSFYGwvDGdWZg/FzGwpKa/8KTz8ea884RWH1l+1094krQJFYGwmhhNY6VgQ38heeR+A61P9Ydtmm4E1fOGaRRnBkIo4mVgXE7cBxbLmzl5zLmgVVom4aNOK8wYwQruT3vygQ9mveF8erF5No7a8nMwb2dD/ZDD+xxUWCdny79unM70MrAQpyNAQvzsQRWbiFxziANE7+Fx4qn9aueIrTyx770EfE1tetetxBpHSsDS7E/+05t/dYNrb9F6Cgc+PCXwcyBPZ3nw+nz/vu6ITZzYK/tHGiMWBkYe1mVfRhz0SsDa3KLMNf6o3RaHVjZrcGriVWDMJSYmBuOps+7I8IO7umOhNnygZqE1TgOY37sUw905j8W/XNRs8CK+62t3rqh7bcIF8UVDC//jb/fb/75bcfDB7q3HI891I0w876YNCsDJ2Iq+459oq0XoLUjWG4Nwhg/abNbj+Z9MW5/k0bVd868WfrKwBee/XTy6Nz9pf671GwEK9faW4WtDCy3Bpv35R2/OcacoV4XLt+4PdGb6seXeV8UaRyHMY97K5SaBlZrbxW29RbhorhqxhfzKKtz4sNp7b33k5VL15PV9EP3Ws+DCX769kRwv+NIIp7FF6NEiJWB1fqoTlp6q7B1I1huDTZD0atzLl65kdyML/q3uhF24fJ18VUD4oven+HYy2ocKwPjduAk3mM1HcHKte5WYasCy63B+itrdY74El/UU91XBrYosFp3q7BttwhPi6v6fllOanVOvgqu3//3uOIrQqHMSbpN5LZjs1kZWDtT2XfwfFv+hVszgrVz9tRc+vS693i91Pmg4n7xtdXbF+lvfR/637xwKXs2kb+UL1TxVW1NWhk4ipqPYOU+lX6eLQms5sRV3BqMwycdh1OjsNrqgahV9+wLv0h/635rS4E1zAfw+on8K1mEIb7qbhwrA6v82dOQwLqWPlpxVmFbbhEeF1f1kK/O+cZXH27wv2N5X8b5SF+/37rNJds+tx0nFxZWBjbn9+fsO3lBYNVcnOqdPj3nPV2PsPLhVp4qzCUTX+JrFOM6M/AvvvBQ8s2nH/Z6jM9z6Xfz2VvLJ5YFVr2d9l6utqK3XKD8+LqZPSO+yhAT2GPLhbJXBvrsmfh385zAqqm0kOfTp0e8j6upCsue2V58xQhDjHLlk+7PpyEhvoqNr861b8nh2lYGtsoj8R19a/nEosCqX1ztToxeVZIPt+aIL/p4iK9y46vfLbI4VHt3nOfYkPiKCezPfPcXpYZVXLP4pc5nT2Wczm4VNnLCe5NHsBYSe15VShWXPSO+6iq/VpvFV+eXmoe6EZaPRlZJTGCPeVZtXRnYclPZd/XxJv7LNXKbhmxi+6+8d6sTVj7c7jh55s3OYxTDbtPQBOKr/J/HeESExYrWScXXOI62adqq5IZs09DPv2vihPemjmC5NViFX02sDGQLhhn56jzeWbPR6hbk1y+/ZifPbBxfMwe7z0XeUhvX0TYRVT57avWdPSewKs7E9mqw7Jly4+vufxYTpFfy7SXEVyHxtf4XppkD2TyvWOk4YnyNawK7lYG11MgJ740KrGxi+4L36uT4cGNSIubjy36U+LLL/fAGxWoeX/l2E+vFbd6yQzcWz8SxWj57amuhaRPemzaCZcf2CbEykLrGVycAHDFUWHz1227CZw9DaNwO740JrLR8p5OGrkSo9E9EjQ9jhtygI4YivoJd7qv32WPxTOMcT7/LF28tn7gqsKolqtfYsA83KCW+7HJfDXEbMvay8tnTzJc3+y6fF1gVkRbvXPr0lPfmeD7crAyELrvc++yhcE9lo1hLAqsaFrwny2dlIAxv1I1WgxWPPnu4/Z0+J7AmLBu9si1DiawMhPHFl+0mfPbQ2bZhru6jWE0YwVr0XixHrM6Jo22qeLwGNNVWtptoWnxZGUj23T4tsCYk21TUtgwFcyAq1C++Qt23m/DZQ4/9dd98tO4jWAvegwW+m60MhFrbbLuJqsaXlYEM+I4XWOOWlq1NRQv8cGvSgahAfeIrRq3+5e8/bwI7fX/vj+/6W8snanm+cC0Dy5E4xXEgKjAovsre6ytGrnz+MMBCtm1D7Y7QqesIVoxeWVayDVbn1Ess6/daMQmD9vrKJ93HdhMv/+TiyNEV0xLMt2ITU0lNj9DZUbc/cDZ65UicLYrVOf/64/+U/O1fOhS1ThzLQhXlk+7//AtHkv/1j1/qBNOogQVDOJ599wussi90YvRqZDHP4X/+/eeT//FfP2/bBaAUT37WJHVKkY9iCayyGL3awrsyVuc88+nOb5eG4oEyxRwtKEntRrHqNoJl9GpEMYE0hu8ByuacRcocL0hqNsBSm0nuRq+25ivf+lnnEXMd8se+9DFzcG8yteteo1oA1EWMYp2uy4rCOq0iNHq1DdeyvW36/lqw6yPJzIE94guAKqvVisK6BRYlGHSWWR5f8Xw4Iuy+7ijYzIG99q4BYBItILCKkp05aPRqwvH12utX7vrnse2D+Kq32MU7NpH0+rFdsVq5aQdPUzlTdTmjsC4jWAveU9U0bHztjueD2W1I+29V6zVM4+rkmTf7vn7haPrs9WOob75dwpyxNYHA2q5s9MqZgw2Lr/hNd3fM8/LlXfnXr9+IRL5gIl7H+FI99lD3dbTHGjAG++swilWHEawF76XmyZdz9/vy7o2v4Mu7evJFE/nrd/KM+ALG3gYCa6vSQp1LjF61Pr58eYsvgHViFGvu1vKJJYG19UKFLX95B9tN1OP122i7EJPugQGNMCewRpSW6Wz69Ij3D2V+eYuv6hi0XUiISffx+n3j6YfN1QPCI9EKt5ZPLAus0dj3qkeMyvzFk0eSa++sJRcu39j0y4jhv7yNnNRD76T7f/vnp10QIG+FeYE1pOxYnKe8b+6ISd9PPnb3SfW//d37ycrl693RG/FVeHwFe31VS7zXL165Yd4WEJ5Km+F4FY/PqeoIltGrIcWXfNzmOvpgIr5KMupGq7abKN/N9H0M0NMMCwJLYImvlsTXRnt9sX1xPQEE1ggciyO+mmLQXl9sz6RvD66+u5acfPHNzpy9fOTSdhMwMZU8PqeKI1jz3iviC6os3v8v/+Ri33+W3ya2YhXG3g4CayO2Zqh3fIU4OHjtvTTCLl1PVrNtE1ayCIO2xFc8+v6abbsQKEvltmyo2giWuVc1l39RPDp3/13/LFZ+xeTkOFw4IuxCPhK2wZcRNM1Wtgtpcnz52aeEhpgXWOtkWzM84f3RXPn8lH5fGDGnJT5sL1zqRtj59EvoZhZhIL6aGV8Ci4I9ES1RlS0bqjSCFXFlcntLxbYG8RgUX+Z9URUxClvl+Iq/NuGeFprKWmJRYH2Y24NsEl93/zOT7mm7Qe/33vM5Y5uQfpsVQ8McF1g9ssntM94XjMqKR9jY+vM5z7+1mrzw7KedQkCTzVRlsntVRrCMXjHW+Op82VjxSMvE1hJPPn7IqkWarhKT3SceWCa3MymDVjyKL5oq5o8JLBquEpPdqzCCZXI74guAolRisnsVAmvee4EmxVc+SpDv9WW7CYCJtEV7A2vn7KnpxM7tNDC++t2CiY1Wn/nuz02yByhf7Ow+fWv5xNVJ/QF2VKAwoRViX6L/8V8/n3zxs5bKAzS9MQQWjFms4gJAYJUi2/tqv9cfACjB/qw12hVYidErqIQvPn6os9M3QANNrDUEFrRcHEP0L3//+eSxTz3gYgACqyATWUW4c/aUva+gQmLX+3/8qz/r/HV+uPaFSzeSm+/9Pjn/9urtI1cAamYqmuPW8omzrQisxM7tUFl3Dtfuv9VERFfvPl82WQUqLppDYAHVFVtNhH7xZYd7oMKBNXZjDyy3B6GZHC8EVNREbhNOYgTL6BWIr4HxZc4XUEJ7CCxAfIV8wn3n8c7a7QADqHp7jDWw3B4ERnFnwr1rAWzL2G8TjnsfLKNXAMAkjLVBxh1Yc15fAGACxtogYwssZw8CTbH/PjMdoI4/uuM8m3Ccc7DmvbZAEzz52KFk7bfvJ6+9fsWKR6iXaJHjTQusOa8r0BR//oUjnUeu3xFDN7Pd7oHKGFuLjCWwds6emk6fZryu9fCHf/pisv8TU8nhA3uTqV33Jsce2pfs3vWR27t4A3cbdMSQ+ILKmIkmubV84mojAiuxerBW8lseb6RfAuHkmTv/bCoNrZkDezoBti99zBzsRli/LxVAfEEFRZOcbkpgzXk96yEO8x0kjjbJw2s98QXlxVfnOY0uc76gkCZpTGA97vWsh5vbOBtuUHyFY0f2dSLscETYfVOdEJs5sDf52EfvdeFhxPiKX4bi5/WNt7pHDUV8GfmC6jRJ6YGV7d4Ot+MrVl4NE1+dkbCPWw4P/eRzIgeNfK0/YsjIF9xpk7J3dR/HCNacl5LtxFdMtt8dtxqPdCfbHz64R3zBAI4YgqHaRGDRbvktj363H3vjK1jxCEAV2qTUwLI9Q/3EnKg6x1fvisf8NqPtJgBY/3VX9nYNZY9gzXkN66VJE84HbTexPr6seARonWiURYEFJcZXL9tNAAgsgQUFG2avL9tNADQisEpTWmBl86/2e/1oanwNu92E+AKopP1lzsMqcwRrzmtH2wyz3UREFwCVEK2yKLCgxuywDdCewNohsACAFgdWKUoJLPOvAIAa2J81Sz0CKzF6BQDUQynNUlZgzXq9AIAaKKVZjGABAG1WSrMUHlg7Z0/tTpw/CADUw0zWLtUOrMTtQaiV1XfXkvO/XE1++7v3XQygrQpvlzL2wZrzOtVb7Ea+0VExNM/Lr15MTp558/bf5xuiHj3SPXvx2EP70r//SHLogT0uFtBU0S5LVQ8sI1g198Kzn06+8+KbnciKo2Fol3xD1DyyT5658882OgjbcUBAzRnBonwxUvGPf/Vnt/8+bh+tvfd+snLperL6m7XkWvpYuXxDfLXQoIOwg7MYgZoqvF0KDaxssy4HrTXM0Qe7t4oenbv/rn/WG1/xHKMf17IIo30chA3U1FTRBz8XPYLl9qD4uu3ilRvJzRjxeGtVfCG+gKqLhhFYVF8+KTqPsM3i62b2jPjaKL5isv1jf3R/su/jBsqBUgLrbFUDa87rw3bjK7YNiFGuC5e6EXY+/fIVX+Irj6/vnHkzeff8cRcGKFqhDWMEi8qJ0Yl4iC/6sbgCKMl0JQMr2wXVuD2Viq9gTy8AhrA/WubW8omblQqsxOgVFY6v2KV8JZ9k/04aYdk2E+ILgHUts1S1wJrzulBVsRotwuvog4n4Yttie5IYKT18cI9d7qFZ5qoYWNNeF5oeXzZaJcTq197jhUJsLZE/7HIPtVVYywgs2GJ8hRjJyL9wbTfRbpvt8WavLxBYW/WI14W2yed7DTvp3shXe9loFWqhsJYpJLCyI3KAHv0m3ccGq//+yz8SWYgvqKiijswpagRLYMEQYjL0f/n2Z5LPHf//XAwKja98zle/0VRg5KapTGDNeT1gOPElCGXGV0TXTIx4ZRPujz20r/vXjhiCYZtmqSqBtdvrAVAN67cZOXmm+/x33/5M8uRjh1wgGEPT7CjoD2OTUYCK+8q3fnZ75StQbtMILIAWiS1FgPoElhv7AEATFNI02w6snbOn5rwWAEBTFNE2O1xGAIBiFRFYcy4jAJQrttpgbLbdNkUEli0aAKBk9jEbq223TRGBZQUhANAk224bc7Cg5WKX79j5G4DiFBFYj7iMUF9xdt2//P3nRRZAgW1zj2sIxCHUl//708nK5evJhUs3kpvv/T45//Zqcu03a50HAGMMLHtgQXN87KP3dkaz4rHexSvd6IpdwFez6Fq5fKNz5h1AE0Xj3Fo+sTSRwALaIUa4Qr/4irPt1t57P1m5dF181cCqEUkYi+0G1rRLCO2WR9ejc/cPjK94vnD5utuOE+baw3gaR2DxIb/93fudeTgzB/Z2bhlBWfHVe9uxE2Nvr6Z/340wgLYHFg0TcfUnX/7R7b8/dqS7hP/wgT3J/vumOjsJiy+KMOi2Yx766289Gv0C6mK7gTXnEjbbG293Rxdee/3KXf9MfFGWfMJ96Df6BTAG22ocI1iUEl+H09DavSv9kkwjbHdE2ME9nQBz1AMAbbDdwHIOIX3l82jyCNssvuI5v2UEABWwrcbZbmDNuP4UGV8xyhWPiLCpNMLiGBfxBcAEbKtx3CKkUvJJzHl8nTwjvqieLz5+KPnhTy6acA8ILJodXzHZfuZANs8rJtsf7EZYvxVqkxYr46i3mEv4b//8dOev8+0mHDGUdH7hAbYZWI7JaaYqBslw0fL7vrccqxhfse0AzTFou4mIr87O9i3Z5T7mU0KTbOe4HCNYNN6g+Aq2m6DM+IrHZrvcO2IImkdg0Xqj7vVluwmKMOwu9/kRQ3a5h/YEli0aaHV82euLsgy67bj6bne0K5/zdSEb9Ro0SguMv3W2E1izrjttNupeX+KLIsR7KB7DHDHUb/RrykR0GLV1zo47sIAtxBeUZbMjhiLAbprjBWMhsABaFGAWb8B47HAJAACqE1gmuQMATbbl1tlOYJnkDgA02ZZbxy1CAICCCSwAAIEFACCwqBkbEQKAwKJgn/3U/S4CAGyDjUa5y9/+5WeSow/tS669s5acf3vVIbMVEIf+9jsaBQCBRY08+dihu/4zh8wCgMCiYMMcMhsBFiNf4gsAgQXblB8ye/TBZNP4Wv1NdyRsJYswABBYUGB8hfO/XE1DK42wS9fFFwCtDyxH5VCI/Jbjo3P3iy8AWh9Yy+njEZcQ8VVv//n//Vny8k8uJvs/MdV5HD6wN5nadW9y7KF9H3oNABhPYIH4aoC4NvlzPPKFCSfP3PnvxOazMwf2dAJsX/qYOdiNsJk0xuIWMAACC/Elvka02YrQY0f2dSLscETYfVO3R8Ni1SmAwALx1XmOjT3Xsg1W85EdNpbH12uvX7nrn8Utx9277k2OphG2OyLs4B7xBQgsaGN89Zt3dPFKd4PViK9OjNnlfij59ek3Aia+AIEFLXfogT0bxle+y/36jVbdeiwmvvLbjibcAwILWuTOLvf9/3nvrcfvv/J2paIr5k7VJb5irtePT/9HE+uBytvhEkD5uhut7ku+8dWH00D4s0r92WJiel1EbH3yc//gDQUILODu2GLrLDgABBYAgMACYDOxqCGfVwfQj0nuACN6+dWLyckzb3b+ev0u9/mKR7vcg8DaKmcRAq23lV3uxRfUxvIkAuum6w4w2KBd7iO+go1WobK23DpuEQJMOL6G3eU+nvMNb4FqE1gAFTRol/v8MO2IsKk0wo49tE98gcACYDvyY5ny+Dp5ZuP4mjnYfbb/GtQnsJZdPoBqx1evmGz/wrN/nDz52CEXCkpune3sg2WSO0CNxIrHOIwcKL91bDQKAFAwgQUAUJXAurV8YsnlAwCaajutYwQLAKBgAgsAoGKBteISAgANtK3G2W5g2aoBAGiibTWOW4QAAAXbbmAtuYRQb3GOHQDFNo6zCKHl4oy6f/3xf0reeGs1ufne75Pzb8fz+7cPGwZg/IF11SVslotXbiTfefHN5PCBPcn++7qHxs4c2Jt87KP3ujgNduiBPZ3Heqvvds+1u3Dpxu34Cv3OuQNomG01jsDiQ+JL9LXXr3Qe6x07sq9zWGxvfMVj38enXLiGitc2HjHKtd5vf/d+snL5evdw4XfSCLt8o3PWnfhiFBHxPkMQWLRa/sXZL74OH9ib7N51b3I0jbDdEWEH94ivhotRzQivow8m4osti/eIzwmaaFuBFVvI75w95Spye75Ovy/QfvEVz/1uSSG+AKpgu0cCGsFiovGV32aMCJtKIyxWtImv9sZXOP/L1TS40gi7dL3zHO8fk+6BuikisM6lj0dcSraiM4qRPvL4OnlmcHyFfvOBaI789X107v67/lk++gVQsnNVCCwYe3zFZPuZA9k8r1jpeLAbYeKr2fLRL4CqKyKwlhMjWI0Rt+fqYNCcnfXxZbsJALbQNhMPLOcRNkgT5j5tNmG633YT4guAItumiMBaSh/PeS2oi0HbTfTGl+0m2MgXHz+UfP+VtzsxDzTSUhUCC1oRX/b6Ihev+eX//nRnwn3vLvdWOwKFBZa9sGiLYff6CoO2m4iVcNTfne0m7p50nx8xZK8vqKft7oFVSGBl1tKHX+MRX0NsN0Hz3TliKOkb2DZahUpbK+J/pKjAspIQNrB+uwnazS73UHnLRfyPFBVYVwUWwPjiazUL95UswoDmBhYAE4iv0HvEUB5f+QMYSSHbTxUVWEuJrRoAJmaYI4YiwMwDhKGapjKBddXrAVBNjhiC8TfNjiL+R24tnxBYAEDtFdU0Owr8M53zsgAANVZYyxQZWFe9LgBAjRXWMgKLu8SGmAAgsKoRWEtel2b45tMPdw48BoCWKaxlijzsednr0gyxzPvd88eTi1e6h9i+8VZ3f504DsZhtgA0WGEtU1hg3Vo+cXPn7ClnEjZIflDxoMNsL1zqRtj5t1fFFwB1thYtU7nA6ik/R+a0wJ3DbIeLr+A8NQAqrNA7cUUH1pLAYlB8OcwWgIpaqnJgmYfFQKMcZiu+ABijSo9gCSzEFwACq8j/sdhe3kR3xh1f4fwvuysdVy5dT1Z/050DtpJFGABsYq3oY//uKeEPuZQ+HvdaMU75fK/YYkJ8AbCFdilUGYG1LLCoU3yF3r2+rmURBkBrFD7FqawRrOe8VtQpvvqteGzLRqt/88rbyWuvX+ns3n/4wJ5k/31Tyf5PTCUzB/Z2bs0CtMBSHQLLRHcaYdSNVkMdJ93Hnzn/c0dorXfsyL7b8bU7ng/u6QRYbMUB0BDVH8HKdnRfSf9yxutFU42y11fV531t9mcaFF9xMPjuXfcmR9MIE19ATa0UuYN7aYHVU4ICi1babLuJZ7778+Tln1xsxL9rfru038hdhFY8IsKm0gg79lA3wvKRQYCKWCrjf/SeEv+wT3nN4O74euHZTzcmsAbJFwvk8XXyjPgCKqmUqU1lBhawQWS13ajx5bYjUKJSmqWUwMo2HL0Wn5VeN6Co+PriZw91RgBFKlDUR07RG4zmdtStCIH2ilurn/zcP7gQQOVbRWAB9fp10yawgMACABBYhcnuaV7z2kG1xSaiAC1U2vyrcE/Jf/goQ9s1QIXFDu39NhFlY3GG5Z98+Ud2uYd6Wyrzf1xgAYwozqYMg3a5t9cXCKza/uEBJmHl0uYHfg/abiJGvWYOZKNdcbD2wW6E9Tt6CRBYd8n2w3IuIUCPOP9xo4PBxReM5/ekMudflR5YPYUosADEF1TFUtn/B+MKrK95LQHKj6980v3++7pzwGYO7LXzPTQxsG4tnzi7c/aUlxJgTPHVb9J9rHg8mj6+8dWHXSxaL9qk7P+PHWP6d3nVywkwORFfJ8+8mfx06dcuBm03liYZV2AteT0BJm+YFZDQcGNpknEF1lmvJwBQAWNpkrEEVrYUcsVrCgBMUOnbM+TuGeO/1FJiu4bKy48Aid2nd8fy7yP7bh8BYhdqAGpuaVz/R+MMrMXEdg21ceFyd55GvyXhjgABoKYWGxdYt5ZPLO+cPXUtvp+9vvU26AiQfvEVbIT4YXF98ogFYDxfX9EijQuszFLi8OfWxpddqO+I268AjL1BxmbcgXVWYLXXVo4AsQs1AAU2SDMDK9vVfS2+T73ODBtfIXahdgRIOeI2bu9II0ATv2bGsXv7xAKrpyCNYjGSzY4AWR9fnZGwj+v4YcQt2h+f/o/Jy69e7MwLi1u8AA0z9v04BRYfEqNCTYqvfttNiK+7PTp3f+eRW323O5fuwqUbyc33fp+G141NRxmph/NeQwRWMwPLbcJqa9ott0HbTfTGV7DdxB0RoPHotwDht797P1nJRrquvbOWrGYLG1ayCAOomLHfHpxIYPWUpFEsKhVfm203Ib7uRHiE19EH+//z2Kx27b33O2feiS+gAiZyXJ/Agj7s9bV1+XXoveUovgCBNQZuE9LU+Bp2r6+baWSIr43jK55jhPFm9gywRRO5PTixwMosJo7OoWk/yUPu9SUaRouvfN5XHmAAI7TGRAgsqEB8MVg+72ujAAOoWmDtmNT/cXYe0DWvPQBQgrGePViZwJp0WQJsVawoBSpvoo0hsABG9Ngf3d+ZUwcIrEoG1q3lE1fTp3PeA0CdxCas//rjLyXf+OrDnaOajh2xRQdUzLmsMSbmngpchCjMR7wXgLpFVgTWelXf6yv+LNACi5P+A1QhsGJ/itOJPbGABhi02vHile7Zjm+8tXp7r698X7VxsakrLbCWTGhz0UoF1q3lEzd3zp6yszvQePlRS/12/a9CfEFDnI22aH1gZU4LrOp47FMPJK+9fsWFgArHl13uYWBTTFwlAiv2qdg5e2ol/csZ74vJe+HZP05277q3M1fDBzhUO75W3+2Ocl241I2w89lmtja1paVWJrn3VeUCq6c4f+C9MXkxefdv//Izt/8+P6akc7vinfSDPJuw6wMcqvHzGo9+8bX+Z3fVLUea73RV/iBVCiyT3SsqP6bk6IP9/3nVV02Bn13XglaoxOT2ygWWye71NWjVlPgCYEwqMbm9coGVMdldfIkvgA3s/8SU27yDG6IyKhVY2WT32NndxqPiS3wBCKxhnavK5PZKBlZmUWAxbHzZLwiApIJnG1cusNICXdw5e8pkd7YUXzZrBGidtWgHgTWcCKznvGcY1TCbNfbuF2SzRoDaO13FP5TAQnwldzZrtNcXgMBqbGBlWza8lFhRyJjc2azx7n+Wb9Zo0j1A5bxUpa0ZKh9YPUUqsJi4fLPGsNGk+2DeF8BEWqGSKhtYtmygLvL4GvacOCNfAIWo3NYMtQiszEL6eN17iLrqd05c3HI88B9eFFkA22+EytpR5T9cWqZL6dM17yGaJG45zhzY40IAbN21rBEEVlMLFQDQButV/RZhvvFoXMj93k9QnpNn3uw84iiO/LEvnu/r/vXMgb2d0TeACbtWxY1FaxdYPaX6A+8pGMMn1yYrII8dySb1p8+7d30kOXxwTzfGPu7wBWBsTVB5tQgsx+dAdeSbr/bbhDUf+Tp8YG8yteve5NhD3QjLN3kF2Ka1Ooxe1SawMnZ3h4rLR7/y+Dp55s4/m0pDKyb3u/UIbLMFaqFugXU8MYoF9fy1c5Ojh2LUa/eue2+Pfs0c3Nu5HSm+gPxjRGCVIDs+xygWNFR+6HZvhMWo13/59mf67qAPtM7pqh6L08+Oul3crGCBNvy6+t7vk++8+KYLAdRq9Kp2gZWV62nvM2iPfGSrSn742sXOGZT5OZRA6Wo1ehXuqeNFTszFAiYZWK9evGs+We/2FZ2/f2jjMyqBkdRu9KqWgWUuFlBF67ev6LeCMp4Px0pKKyhhFLUbvaplYOUXOzGKBdTl1++eFZSvvX7lrn+er6Ds3bzV/mHQ/fFJajo1qJaBlY1iLaR/+Vfee0Dd9VtBmbN5Ky23UMfRq9oGVhZZp9PIilEsZxQCjTXK5q2xd1hEmHlfNOXtH9/1df3D31Pzi7+QOKMQaKlBm7euj6/P/tEDRr2o43d8be2o8x8+O4/omvcgQP/4evknF5OTZ95MPvm5f+hsLwE1ca0uZw42MrAy896HAJv7yrd+lvx06dcuBL7bBdbm0sJdSp/OeS8CbG7l0nUXgao7l323C6wKWPB+BADf6QKrQFnpvuQ9CQC19lITRq8aE1g9xesgaACop7WkQXekGhNYafFeTRwEDQB1dTr7LhdYVXxxEts2AEDdXEsaNkjSqMDKttNf8D4FyhTH1gCFqu2ROK0IrCyyFhPbNgAliuNogMKcq/umoq0IrMxx71cA8J0tsAqUlvBy+vQ971kAqLTvZd/ZAqtGFhLbNgB8yPkNDoeGCWjUtgytCaxsspxbhQBQTcebNrG9FYGVRdZiYsI7AFRNIye2tyaw8kL2PgYA380Cq0DZ5LnnvZcBoBKeb+rE9lYFVsYO7wAweY3bsb3VgZVNopv3vgaAiZpv8sT21gVWFllL6dNLdf3z33zv/eTilRt+NAGoq5ey7+JWuKdlL25MqnsifUzV7Q9+4fL15JOf+4fOX+//xNTtx770MXNwb+fojqMP7vPjC2Owe9dHXAQYzVrSskVnrQqsGJbcOXtqPv3Lf6rzv8e136x1Hv1MpR/8Mwf2iC8o0RcfP5R8/5W3Nvw5BO7SmluDrQysLLLOppH1avqXjzfyV4T3fp+8scFOzevja/993VGwmQN7k4991OG1MKz4efm3f366c9t+5fL15No7a50d0gf98gPbtfru2oaf7xX3anz3tu31uqel79P59HE1qeGtwrLiKxw7sq8TYYcjwsQXbOrQA3s6j16//d37nei6cOlGJ7bi9v7K5Rudnz/Yqnhffe74f6vlV0/S0kVmrQysptwqLFoeX6+9fmVgfMX8k8MHs5Gwj0+5cNAjfiGJW/Lrb8vn4fXGW6vJajbS9YZzARnCD1+7mDzz3V/UNdJbd2uw1YGVRVajbxWOM74OH9ibRlf6pZJGmPiC0cIrbvtcuHwjWbl0vfOcj3rBT5d+nYbVz+t827mVtwZbH1h5WSctvFVYtPzLoN9v4/3iK57X31aBQWL0p6m3quMXkXg8Onf/h/7zmN8VX6x5eMXPmfld7XD+l6vJyRffrPsIZ2tvDQqsxK3CScdXvtVERFisdDz20D7xRV9xa61tK2Hz+V3rwyu+fDuT6bc4sd5tyeqK0cy4FdjvTkEdBzDaemtQYN2JrLhV+L30L7/mx3u8rq2bh3LyzOD4CraboO26txnv/s8jvIaZWB8/U1QvrGLE6uWfXGzKv9L32nxrUGB92ELS3YB0v0tR/fiy1xdsFF79J9b3hteUTVIrI16fv/7hW8n3X3m7SatMr2Xfqa0nsJLbtwojsH7lalTfKHt95fFluwnaaKOJ9UzeyTNvNi2sck+0/dagwLo7spbTyHo+/cvnXI1mxlew1xcwSbHlQtwObOiChefju9SrLLD6RdZCGllz6V8+4mo007B7fYkvoEgxRy4msDd4C45z8R3qlRZYg8StwquJrRvEVw97fQFbEdttxF5WDV+9uZZ9dyKwNmbrBvoZda8v8QXt1sCVgYPMm3clsIaNLFs3UGh8rd9uIpbQA80TKwO/82JMYH+rLf/KtmQQWCNH1vFsPtaMq0FR8dW73QTQrLBq4JYLm1mJ70qvvsDairinHCsi3OsBoK+GrwzciHlXm9jhEmwsLfOrScvPUgKgv1gZ+Id/+mLylW/9rI3nRM5n35EIrC1HVtxbft6VACAPq//j//5R8idf/lFbD+B+3rwrgVVUZC2kT+dcCYD2ipWB/9fX/1snrFp8aLb9roZkDtbw8vlYzisEaJGYwB57WbVky4VBriXmXQ3NCNaQsj0+vLGYiAu2dYCJhFWcGXjgP7worrJJ7fa7ElhlRVaMYH3JlWDcYnf5WKkEjEf8vEVYRWC1aNuFQY47Z3A0bhGOHlmL2f5YT7kajFOsVIpHiHMTg93joVg/Xfp153ZgSyevb+Sl+O5zGQTWOCJrPo2s6cSh0ExIPsG230Tb3kOrZw52d5A/+uA+Fw0GiJWBsZdViyevbyQmtc+7DAJrnEx6p9Lx1e/Q6t746vx9dnSPAKOtYmVgjAwLq75MahdY45cdCh1vvKXETu/UNL4c3UObw6pFhzFvhUnt22SS+/YiK0aw5l0JgHrIVwZ+8nM/EFeDzZvULrAmHVmxm+3XXQmAavubV962MnA4X7dTu8CqSmSdTp9eciUAqie2XIgzA5954efCanMvZd9pCKzKRNZ84jgdKMXae++7CIwsPzOwpYcxb4UVgwUyyb1Y+aT3GZcCivPa/3+ls93EzIG9ycc+eq8LwkBWBm7JSmLFoMCqqmxl4Vz6l1cTKwuhMDEZuXdCcu92E/vvm+pssiq+sDJwy2J4b86KQYFVl8haEllQjs32+gp2uW+PWBn41z98qzN5HXElsJodWctZZP3K1YDJxFe/20OHD+xNo+te8dUgEVXff+Vtk9e3bs52DAKrjpEVB0P/wNWAarhw+fqm8RXPMd8rdrmPCDv0wB4XroJiZWDcDjR5fVu+JK4EVl0jKw6GTkQW1C++ene5j1GueIivyYuVgc989xe3Xy+2FVeLLoPAqntkTad/+ZyrAfUUoyTxGBRfnVuNMdneAduluHjlRhpWP7cysBjPiyuB1ZTIWsgi6ylXA5oZX/3ESseZA3vE1zZYGVi42Eh0wWUQWE2KrPnsdqHIgpaIidcbjbjk8WW7if6sDCwtruZdBoElsoBWxNdG2020Mb7ysLIyUFwJLLYSWbOJ3d6BAYaNr7pvNxG3V48+2P1rKwNLsyKuBFZbzCWO1AFKiK9J7vUV/38jB9Y7a8Kq5LjKvnMYsz/44IMPXIUJ2Dl7arfIAsapN75CGdtNZNMgqFBc2aVdYIksgAkpaq8vgSWuEFgiC2AL8TVouwmBJa4QWCILYJvW7/VlWwVxhcASWQCIK0qxwyWohuwHYi77AQEAcSWwEFkAiCsElsgCQFxREnOwKmzn7KnFxLE6APTn+JsKM4JVYdkPzkuuBADiSmAhsgAQVwKLWkTW864EQOs9L67qwRysGtk5eyp+qH7gSgC00pfSuFp0GerBCFaNZD9YX3IlAMQV1WYEq4Z2zp6aTbq7vk+5GgCNtpZ0t2FYdinqxQhWDWU/aHPZDx4A4gqBRYGRNZ3YkBSgieKzfVpcCSwmE1n5ru/nXA2Axng1sTt77ZmD1RB2fQdoBHtcNYQRrIbIfiC/7koA1NaXxFVzGMFqmJ2zp55InxYTKwwB6iIms8+ncXXWpRBYVDuyYhuH+EHd72oAVNq19PGEyezN4xZhA2U/qBFZJr8DVFd8Rs+Kq2YygtVwJr8DVJLJ7A1nBKvhsh9gx+sAVIfJ7C1gBKslzMsCmDjzrVrECFZLmJcFMFHmW7WMEawW2jl7aiF9es6VABiL59OwWnAZBBbtiCz7ZQGUy/5WAouWRtZ00p2XNeNqABQqDmuO+VZXXQqBRXtD63T69DVXAqAQ30vD6rjLILBcBdwyBNg+twQRWPSNrN1J95bhI64GwEhilWDcErzpUiCw2Ci0FhKrDAGGZZUgAouhI8vGpACD2TiUDdlolL56Nib9nqsBcJf4bLRxKBsygsWmTIAHuM1EdoZiBItNZR8k0+njVVcDaLH4DJwWVwzDCBYjMZoFtJBRK0ZmBIuRGM0CWsaoFVtiBIstM5oFNJhRK7bFCBZb1jOa9ZKrATRIfKYZtWJbjGBRiJ2zp+aS7miWfbOAuop9rWLUasmlYLuMYFGI7AMp9s163tUAaig+u2bFFUUxgkXhsl3gTyfONASqL84QPG7DUAQWdQqt+Sy0TIIHqmYtC6tFl4IyuEVIabIPrunEcTtAtcRn0rS4okxGsBgLtw2BCnA7EIFFY0NrPn1aSKw2BMYnVgcuGLFCYNH0yNodv0VmD/OzgLLEPKsYOT+dxtVNlwOBRVtCazrpjmY95WoABYvNQmPU6qpLgcCiraE1l4WW+VnAdp3LwmrJpUBgQWI3eGBb7MKOwIJNQms+MREeGD6sTGBHYMEIoXU8Cy0T4YH11rKwOu1SILBg9Miy4hBYH1ZWBiKwQGgBwgqBBUILEFYgsBBarggIKxBYUGxszSdWHUJTWBWIwAKhBQgrEFi0I7TmEjvDQ13YeR2BBTULrdmkO0fLWYdQPXFWYMyvWnYpEFhQz9AyIR6qwcR1BBY0NLbm06d4uH0I4xO3ARfNr0JgQfNDK799+ERiVAvKEKNVZxO3ARFY0MrQ2p1FVsTWjCsC27aSdG8DnnUbEIEFGNWCrTNaBQILNg2tfFRrPjFXCwbpzK1KjFaBwIIRY2s6C6142MAUuhuCRlTFpPWrLgcILNhubM32xJZbiLTJWk9UuQUIAgtKi624hZg/xBZNjaqYVxW3/866HCCwQGyBqAKBBQ2MrbnEnC3qIeZULYkqEFhQl9jK52xFbNljiypZyaLKnCoQWFDr2JpO7oxsPe6KMAGvJndGqq66HCCwoInBlcdWPIxuUYZ8lGrJrT8QWNDG2Jruia14mLvFVuRzqfKouuqSgMACBBeCCgQWMPbgmk3cUmyz/JbfsqACgQUUH1y7e2Irf7b/VrOs9cZUPDvrDwQWMP7oms5iqze8RFc9xK2+qz1BtWx0CgQWUN3o6h3pms4ej7gyE3Uui6nbQWVkCgQW0IzwymMrwiuPMCNexYnbe8vZ42YWUleNSoHAAtobX3PZX/bGVzDy9WHnsufeiErSiFpyaQCBBWw1wKazRx5jSRZkdV/huJIFU5JHU3Lnlp6AAgQWUJkYy+Nrdt1/pd9/VrTlnmDq+5+JJkBgAQDUwA6XAABAYAEACCwAAIEFAIDAAgAQWAAAAgsAAIEFACCwAAAEFgAAAgsAQGABAAgsAIA2+98CDAD+qU4UvSgs4wAAAABJRU5ErkJggg==' + } - local specialContact = { - name = _U('realtor'), - number = 'realestateagent', - base64Icon = 'data:image/png;base64,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' - } - - TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) - + TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) end) -- Create Blips Citizen.CreateThread(function() + local blip = AddBlipForCoord(Config.Zones.OfficeEnter.Pos.x, Config.Zones.OfficeEnter.Pos.y, Config.Zones.OfficeEnter.Pos.z) - local blip = AddBlipForCoord(Config.Zones.OfficeEnter.Pos.x, Config.Zones.OfficeEnter.Pos.y, Config.Zones.OfficeEnter.Pos.z) - - SetBlipSprite (blip, 357) - SetBlipDisplay(blip, 4) - SetBlipScale (blip, 1.0) - SetBlipColour (blip, 59) - SetBlipAsShortRange(blip, true) - - BeginTextCommandSetBlipName("STRING") - AddTextComponentString(_U('realtors')) - EndTextCommandSetBlipName(blip) + SetBlipSprite (blip, 357) + SetBlipDisplay(blip, 4) + SetBlipScale (blip, 1.0) + SetBlipColour (blip, 59) + SetBlipAsShortRange(blip, true) + BeginTextCommandSetBlipName("STRING") + AddTextComponentString(_U('realtors')) + EndTextCommandSetBlipName(blip) end) -- Display markers Citizen.CreateThread(function() - while true do + while true do - Wait(0) + Citizen.Wait(0) - local coords = GetEntityCoords(GetPlayerPed(-1)) + local coords = GetEntityCoords(PlayerPedId()) - for k,v in pairs(Config.Zones) do - if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then - DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) - end - end + for k,v in pairs(Config.Zones) do + if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) + end + end - end + end end) -- Enter / Exit marker events Citizen.CreateThread(function() - while true do + while true do - Wait(0) + Citizen.Wait(0) - local coords = GetEntityCoords(GetPlayerPed(-1)) - local isInMarker = false - local currentZone = nil + local coords = GetEntityCoords(PlayerPedId()) + local isInMarker = false + local currentZone = nil - for k,v in pairs(Config.Zones) do - if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then - isInMarker = true - currentZone = k - end - end + for k,v in pairs(Config.Zones) do + if GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x then + isInMarker = true + currentZone = k + end + end - if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then - HasAlreadyEnteredMarker = true - LastZone = currentZone - TriggerEvent('esx_realestateagentjob:hasEnteredMarker', currentZone) - end + if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then + HasAlreadyEnteredMarker = true + LastZone = currentZone + TriggerEvent('esx_realestateagentjob:hasEnteredMarker', currentZone) + end - if not isInMarker and HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = false - TriggerEvent('esx_realestateagentjob:hasExitedMarker', LastZone) - end + if not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent('esx_realestateagentjob:hasExitedMarker', LastZone) + end - end + end end) -- Key controls Citizen.CreateThread(function() - while true do + while true do + Citizen.Wait(0) - Citizen.Wait(0) + if CurrentAction ~= nil then + ESX.ShowHelpNotification(CurrentActionMsg) - if CurrentAction ~= nil then + if IsControlJustReleased(0, Keys['E']) then + if CurrentAction == 'realestateagent_menu' then + OpenRealestateAgentMenu() + end - SetTextComponentFormat('STRING') - AddTextComponentString(CurrentActionMsg) - DisplayHelpTextFromStringLabel(0, 0, 1, -1) - - if IsControlPressed(0, Keys['E']) and (GetGameTimer() - GUI.Time) > 300 then - - if CurrentAction == 'realestateagent_menu' then - OpenRealestateAgentMenu() - end - - CurrentAction = nil - GUI.Time = GetGameTimer() - - end - - end - - end + CurrentAction = nil + end + else + Citizen.Wait(500) + end + end end) -- Load IPLS Citizen.CreateThread(function() - LoadMpDlcMaps() - EnableMpDlcMaps(true) - RequestIpl('ex_dt1_02_office_02c') + LoadMpDlcMaps() + EnableMpDlcMaps(true) + RequestIpl('ex_dt1_02_office_02c') end) diff --git a/config.lua b/config.lua index 9700d9b4..1d41cda0 100644 --- a/config.lua +++ b/config.lua @@ -4,33 +4,33 @@ Config.MarkerColor = { r = 120, g = 120, b = 240 } Config.Locale = 'fr' Config.Zones = { - OfficeEnter = { - Pos = { x = -199.151, y = -575.000, z = 39.489 }, - Size = { x = 1.5, y = 1.5, z = 1.0 }, - Type = 1, - }, + OfficeEnter = { + Pos = { x = -199.151, y = -575.000, z = 39.489 }, + Size = { x = 1.5, y = 1.5, z = 1.0 }, + Type = 1 + }, - OfficeExit = { - Pos = { x = -141.226, y = -614.166, z = 167.820 }, - Size = { x = 1.5, y = 1.5, z = 1.0 }, - Type = 1, - }, + OfficeExit = { + Pos = { x = -141.226, y = -614.166, z = 167.820 }, + Size = { x = 1.5, y = 1.5, z = 1.0 }, + Type = 1 + }, - OfficeInside = { - Pos = { x = -140.969, y = -616.785, z = 167.820 }, - Size = { x = 1.5, y = 1.5, z = 1.0 }, - Type = -1, - }, + OfficeInside = { + Pos = { x = -140.969, y = -616.785, z = 167.820 }, + Size = { x = 1.5, y = 1.5, z = 1.0 }, + Type = -1 + }, - OfficeOutside = { - Pos = { x = -202.238, y = -578.193, z = 39.500 }, - Size = { x = 1.5, y = 1.5, z = 1.0 }, - Type = -1, - }, + OfficeOutside = { + Pos = { x = -202.238, y = -578.193, z = 39.500 }, + Size = { x = 1.5, y = 1.5, z = 1.0 }, + Type = -1 + }, - OfficeActions = { - Pos = { x = -124.786, y = -641.486, z = 167.820 }, - Size = { x = 1.5, y = 1.5, z = 1.0 }, - Type = -1, - }, + OfficeActions = { + Pos = { x = -124.786, y = -641.486, z = 167.820 }, + Size = { x = 1.5, y = 1.5, z = 1.0 }, + Type = -1 + } } diff --git a/server/main.lua b/server/main.lua index 66603c1b..754de01c 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,66 +1,58 @@ ESX = nil -TriggerEvent('esx:getSharedObject', function(obj) - ESX = obj -end) +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) TriggerEvent('esx_phone:registerNumber', 'realestateagent', _U('client'), false, false) TriggerEvent('esx_society:registerSociety', 'realestateagent', 'Agent immobilier', 'society_realestateagent', 'society_realestateagent', 'society_realestateagent', {type = 'private'}) RegisterServerEvent('esx_realestateagentjob:revoke') AddEventHandler('esx_realestateagentjob:revoke', function(property, owner) - TriggerEvent('esx_property:removeOwnedPropertyIdentifier', property, owner) + TriggerEvent('esx_property:removeOwnedPropertyIdentifier', property, owner) end) RegisterServerEvent('esx_realestateagentjob:sell') AddEventHandler('esx_realestateagentjob:sell', function(target, property, price) + local xPlayer = ESX.GetPlayerFromId(target) + xPlayer.removeMoney(price) - local xPlayer = ESX.GetPlayerFromId(target) + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_realestateagent', function(account) + account.addMoney(price) + end) - xPlayer.removeMoney(price) - - TriggerEvent('esx_addonaccount:getSharedAccount', 'society_realestateagent', function(account) - account.addMoney(price) - end) - - TriggerEvent('esx_property:setPropertyOwned', property, price, false, xPlayer.identifier) + TriggerEvent('esx_property:setPropertyOwned', property, price, false, xPlayer.identifier) end) RegisterServerEvent('esx_realestateagentjob:rent') AddEventHandler('esx_realestateagentjob:rent', function(target, property, price) + local xPlayer = ESX.GetPlayerFromId(target) - local xPlayer = ESX.GetPlayerFromId(target) - - TriggerEvent('esx_property:setPropertyOwned', property, price, true, xPlayer.identifier) + TriggerEvent('esx_property:setPropertyOwned', property, price, true, xPlayer.identifier) end) ESX.RegisterServerCallback('esx_realestateagentjob:getCustomers', function(source, cb) + TriggerEvent('esx_ownedproperty:getOwnedProperties', function(properties) - TriggerEvent('esx_ownedproperty:getOwnedProperties', function(properties) + local xPlayers = ESX.GetPlayers() + local customers = {} - local xPlayers = ESX.GetPlayers() - local customers = {} + for i=1, #properties, 1 do + for j=1, #xPlayers, 1 do + local xPlayer = ESX.GetPlayerFromId(xPlayers[j]) - for i=1, #properties, 1 do - for j=1, #xPlayers, 1 do + if xPlayer.identifier == properties[i].owner then + table.insert(customers, { + name = xPlayer.name, + propertyOwner = properties[i].owner, + propertyRented = properties[i].rented, + propertyId = properties[i].id, + propertyPrice = properties[i].price, + propertyName = properties[i].name + }) + end + end + end - local xPlayer = ESX.GetPlayerFromId(xPlayers[j]) - - if xPlayer.identifier == properties[i].owner then - table.insert(customers, { - name = xPlayer.name, - propertyOwner = properties[i].owner, - propertyRented = properties[i].rented, - propertyId = properties[i].id, - propertyPrice = properties[i].price, - propertyName = properties[i].name - }) - end - end - end - - cb(customers) - - end) + cb(customers) + end) end) From d65947e61b650c0d17c5b50d3cf013840aff01e8 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 31 Oct 2018 15:25:08 +0100 Subject: [PATCH 1858/3224] Locale cleanup --- esx_realestateagentjob.sql | 12 ++++++------ locales/br.lua | 6 +----- locales/de.lua | 8 ++------ locales/en.lua | 6 ------ locales/fi.lua | 6 ------ locales/fr.lua | 6 ------ locales/sv.lua | 8 +------- localization/de_esx_realestateagentjob.sql | 12 ++++++------ localization/en_esx_realestateagentjob.sql | 12 ++++++------ localization/fi_esx_realestateagentjob.sql | 12 ++++++------ 10 files changed, 28 insertions(+), 60 deletions(-) diff --git a/esx_realestateagentjob.sql b/esx_realestateagentjob.sql index f7fc3ffb..867643ab 100644 --- a/esx_realestateagentjob.sql +++ b/esx_realestateagentjob.sql @@ -1,16 +1,16 @@ USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES - ('society_realestateagent','Agent immobilier',1) + ('society_realestateagent','Agent immobilier',1) ; INSERT INTO `jobs` (name, label) VALUES - ('realestateagent','Agent immobilier') + ('realestateagent','Agent immobilier') ; INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES - ('realestateagent',0,'location','Location',10,'{}','{}'), - ('realestateagent',1,'vendeur','Vendeur',25,'{}','{}'), - ('realestateagent',2,'gestion','Gestion',40,'{}','{}'), - ('realestateagent',3,'boss','Patron',0,'{}','{}') + ('realestateagent',0,'location','Location',10,'{}','{}'), + ('realestateagent',1,'vendeur','Vendeur',25,'{}','{}'), + ('realestateagent',2,'gestion','Gestion',40,'{}','{}'), + ('realestateagent',3,'boss','Patron',0,'{}','{}') ; diff --git a/locales/br.lua b/locales/br.lua index a91df3bf..46e8d94c 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -2,14 +2,9 @@ Locales['br'] = { ['properties'] = 'Propriedades', ['property'] = 'Propriedade', ['clients'] = 'Clientes', - ['remove_comp_money'] = 'Remover dinheiro da empresa', - ['dep_money'] = 'Depositar dinheiro', - ['wash_money'] = 'Lavagem de dinheiro', ['realtor'] = 'Corretor de imóveis', ['amount_withdraw'] = 'Quantidade de retirada', ['invalid_amount'] = 'Quantidade inválida', - ['amount_deposit'] = 'Valor do depósito', - ['amount_wash'] = 'Quantidade para lavagem', ['press_to_access'] = 'Pressione ~INPUT_CONTEXT~ para abrir o menu', ['property_actions'] = '{{Assign [Sell]|sell}} {{Assign [Rent]|rent}} {{GPS|gps}}', ['amount'] = 'Quantidade', @@ -18,4 +13,5 @@ Locales['br'] = { ['rent'] = 'Alugar', ['sell'] = 'Vender', ['realtors'] = 'Agente Imobiliário', + ['boss_action'] = 'boss Actions', } diff --git a/locales/de.lua b/locales/de.lua index 3c3b669e..50be0920 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -1,15 +1,10 @@ -Locales['en'] = { +Locales['de'] = { ['properties'] = 'Immobilien', ['property'] = 'Immobilie', ['clients'] = 'Kunden', - ['remove_comp_money'] = 'Firmengeld abheben', - ['dep_money'] = 'Geld einzahlen', - ['wash_money'] = 'Geld waschen', ['realtor'] = 'Makler', ['amount_withdraw'] = 'Betrag zun abheben', ['invalid_amount'] = 'ungültiger Betrag', - ['amount_deposit'] = 'Betrag zum einzahlen', - ['amount_launder'] = 'Betrag zum waschen', ['press_to_access'] = 'Drücke ~INPUT_CONTEXT~ um das Menü zu öffnen', ['property_actions'] = '{{Zuweisen [Verkaufen]|sell}} {{Zuweisen [Vermieten]|rent}} {{GPS|gps}}', ['amount'] = 'Betrag', @@ -18,4 +13,5 @@ Locales['en'] = { ['rent'] = 'Mieten', ['sell'] = 'Verkaufen', ['realtors'] = 'Makler', + ['boss_action'] = 'boss Actions', } diff --git a/locales/en.lua b/locales/en.lua index 68d42bc8..54e5f377 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -2,14 +2,9 @@ Locales['en'] = { ['properties'] = 'properties', ['property'] = 'property', ['clients'] = 'clients', - ['remove_comp_money'] = 'remove company money', - ['dep_money'] = 'deposit money', - ['wash_money'] = 'wash money', ['realtor'] = 'real Estate Agent', ['amount_withdraw'] = 'amount of withdrawal', ['invalid_amount'] = 'invalid amount', - ['amount_deposit'] = 'deposit amount', - ['amount_launder'] = 'amount to launder', ['press_to_access'] = 'press ~INPUT_CONTEXT~ to access the menu', ['property_actions'] = '{{Assign [Sell]|sell}} {{Assign [Rent]|rent}} {{GPS|gps}}', ['amount'] = 'amount', @@ -18,6 +13,5 @@ Locales['en'] = { ['rent'] = 'rent', ['sell'] = 'sell', ['realtors'] = 'real Estate Agents', - ['client'] = 'real Estate Client', ['boss_action'] = 'boss Actions', } diff --git a/locales/fi.lua b/locales/fi.lua index 4e78da1f..1d293904 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -2,14 +2,9 @@ Locales['fi'] = { ['properties'] = 'kiinteistöt', ['property'] = 'kiinteistö', ['clients'] = 'asiakkaat', - ['remove_comp_money'] = 'nosta yrityksen varoja', - ['dep_money'] = 'talleta rahaa', - ['wash_money'] = 'pese rahaa', ['realtor'] = 'kiinteistövälittäjä', ['amount_withdraw'] = 'nostettava määrä', ['invalid_amount'] = 'virheellinen summa', - ['amount_deposit'] = 'talletettava summa', - ['amount_launder'] = 'pestävä summa', ['press_to_access'] = 'paina ~INPUT_CONTEXT~ avataksesi menu', ['property_actions'] = '{{Aseta [Myy]|sell}} {{Aseta [Vuokraa]|rent}} {{GPS|gps}}', ['amount'] = 'määrä', @@ -18,6 +13,5 @@ Locales['fi'] = { ['rent'] = 'vuokraa', ['sell'] = 'myy', ['realtors'] = 'Kiinteistövälitys', - ['client'] = 'Kiinteistövälityksen asiakas', ['boss_action'] = 'pomo Toiminnot', } diff --git a/locales/fr.lua b/locales/fr.lua index 108a74d4..6e66c57d 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -2,14 +2,9 @@ Locales['fr'] = { ['properties'] = 'propriétés', ['property'] = 'propriété', ['clients'] = 'clients', - ['remove_comp_money'] = 'retirer argent société', - ['dep_money'] = 'déposer argent', - ['wash_money'] = 'blanchir argent', ['realtor'] = 'agent Immobilier', ['amount_withdraw'] = 'montant du retrait', ['invalid_amount'] = 'montant invalide', - ['amount_deposit'] = 'montant du dépôt', - ['amount_launder'] = 'montant à blanchir', ['press_to_access'] = 'appuez sur ~INPUT_CONTEXT~ pour accéder au menu', ['property_actions'] = '{{Assigner [Vente]|sell}} {{Assigner [Location]|rent}} {{GPS|gps}}', ['amount'] = 'montant', @@ -18,6 +13,5 @@ Locales['fr'] = { ['rent'] = 'location', ['sell'] = 'vente', ['realtors'] = 'agents Immobilier', - ['client'] = 'Client immo', ['boss_action'] = 'action Patron', } diff --git a/locales/sv.lua b/locales/sv.lua index 3e802985..fb4e0f79 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -2,15 +2,10 @@ Locales['sv'] = { ['properties'] = 'fastigheter', ['property'] = 'fastighet', ['clients'] = 'klienter', - ['remove_comp_money'] = 'ta företagspengar', - ['dep_money'] = 'sätt in', - ['wash_money'] = 'tvätta kläder', ['realtor'] = 'mäklare', ['amount_withdraw'] = 'summa', ['invalid_amount'] = 'ogiltigt belopp', - ['amount_deposit'] = 'sätt in summa', - ['amount_launder'] = 'summa att tvätta', - ['press_to_access'] = 'trycka ~INPUT_CONTEXT~ för att öppna menyn.', + ['press_to_access'] = 'tryck ~INPUT_CONTEXT~ för att öppna menyn.', ['property_actions'] = '{{Assign [Köp]|Köp}} {{Assign [Hyra]|Hyra}} {{GPS|gps}}', ['amount'] = 'summa', ['no_play_near'] = 'det finns inga spelare i närheten!', @@ -18,6 +13,5 @@ Locales['sv'] = { ['rent'] = 'hyra', ['sell'] = 'sälj', ['realtors'] = 'mäklare', - ['client'] = 'klienter', ['boss_action'] = 'chefmeny', } \ No newline at end of file diff --git a/localization/de_esx_realestateagentjob.sql b/localization/de_esx_realestateagentjob.sql index 0b6de025..9c787e8f 100644 --- a/localization/de_esx_realestateagentjob.sql +++ b/localization/de_esx_realestateagentjob.sql @@ -1,16 +1,16 @@ USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES - ('society_realestateagent','Immobilienverkauf',1) + ('society_realestateagent','Immobilienverkauf',1) ; INSERT INTO `jobs` (name, label) VALUES - ('realestateagent','Immobilienverkauf') + ('realestateagent','Immobilienverkauf') ; INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES - ('realestateagent',0,'location','Vermieter',10,'{}','{}'), - ('realestateagent',1,'vendeur','Verkäufer',25,'{}','{}'), - ('realestateagent',2,'gestion','Manager',40,'{}','{}'), - ('realestateagent',3,'boss','Boss',0,'{}','{}') + ('realestateagent',0,'location','Vermieter',10,'{}','{}'), + ('realestateagent',1,'vendeur','Verkäufer',25,'{}','{}'), + ('realestateagent',2,'gestion','Manager',40,'{}','{}'), + ('realestateagent',3,'boss','Boss',0,'{}','{}') ; diff --git a/localization/en_esx_realestateagentjob.sql b/localization/en_esx_realestateagentjob.sql index 28b2659a..4e7e96e9 100644 --- a/localization/en_esx_realestateagentjob.sql +++ b/localization/en_esx_realestateagentjob.sql @@ -1,16 +1,16 @@ USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES - ('society_realestateagent','Real Estate Company',1) + ('society_realestateagent','Real Estate Company',1) ; INSERT INTO `jobs` (name, label) VALUES - ('realestateagent','Realtor') + ('realestateagent','Realtor') ; INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES - ('realestateagent',0,'location','Renting Agent',10,'{}','{}'), - ('realestateagent',1,'vendeur','Agent',25,'{}','{}'), - ('realestateagent',2,'gestion','Management',40,'{}','{}'), - ('realestateagent',3,'boss','Broker',0,'{}','{}') + ('realestateagent',0,'location','Renting Agent',10,'{}','{}'), + ('realestateagent',1,'vendeur','Agent',25,'{}','{}'), + ('realestateagent',2,'gestion','Management',40,'{}','{}'), + ('realestateagent',3,'boss','Broker',0,'{}','{}') ; diff --git a/localization/fi_esx_realestateagentjob.sql b/localization/fi_esx_realestateagentjob.sql index 45bb8f66..7c505468 100644 --- a/localization/fi_esx_realestateagentjob.sql +++ b/localization/fi_esx_realestateagentjob.sql @@ -1,16 +1,16 @@ USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES - ('society_realestateagent','Kiinteistvälittäjä',1) + ('society_realestateagent','Kiinteistvälittäjä',1) ; INSERT INTO `jobs` (name, label) VALUES - ('realestateagent','Kiinteistövälittäjä') + ('realestateagent','Kiinteistövälittäjä') ; INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES - ('realestateagent',0,'location','Vuokraisäntä',10,'{}','{}'), - ('realestateagent',1,'vendeur','Myyjä',25,'{}','{}'), - ('realestateagent',2,'gestion','Johtaja',40,'{}','{}'), - ('realestateagent',3,'boss','Pomo',0,'{}','{}') + ('realestateagent',0,'location','Vuokraisäntä',10,'{}','{}'), + ('realestateagent',1,'vendeur','Myyjä',25,'{}','{}'), + ('realestateagent',2,'gestion','Johtaja',40,'{}','{}'), + ('realestateagent',3,'boss','Pomo',0,'{}','{}') ; From 922f0c17a7109430321ee512c341ca5442107233 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 31 Oct 2018 15:58:36 +0100 Subject: [PATCH 1859/3224] JS cleanup, performance improvements --- client/main.lua | 13 +++--- html/css/app.css | 58 ++++++++++++------------- html/js/app.js | 109 ++++++++++++++++++++++------------------------- html/ui.html | 23 +++++----- 4 files changed, 101 insertions(+), 102 deletions(-) diff --git a/client/main.lua b/client/main.lua index 71ea3380..9a62f450 100644 --- a/client/main.lua +++ b/client/main.lua @@ -30,7 +30,7 @@ Citizen.CreateThread(function() local closeMenu = function(namespace, name) OpenedMenus[namespace .. '_' .. name] = nil - local OpenedMenuCount = 0 + local OpenedMenuCount = 0 SendNUIMessage({ action = 'closeMenu', @@ -53,23 +53,24 @@ Citizen.CreateThread(function() ESX.UI.Menu.RegisterType(MenuType, openMenu, closeMenu) - AddEventHandler('esx_menu_list:message:menu_submit', function(data) + 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) - AddEventHandler('esx_menu_list:message:menu_cancel', function(data) - + 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) end) \ No newline at end of file diff --git a/html/css/app.css b/html/css/app.css index e850e5c0..75ce8066 100644 --- a/html/css/app.css +++ b/html/css/app.css @@ -1,52 +1,52 @@ @font-face { - font-family: bankgothic; - src: url('../fonts/bankgothic.ttf'); + font-family: bankgothic; + src: url('../fonts/bankgothic.ttf'); } @font-face { - font-family: pcdown; - src: url('../fonts/pdown.ttf'); + font-family: pcdown; + src: url('../fonts/pdown.ttf'); } .menu { - font-family: bankgothic; - position : absolute; - left : 50%; - top : 50%; - transform : translate(-50%, -50%); - box-shadow : 0px 0px 50px 0px #000; - overflow-y : auto; - max-height : 90%; + font-family: bankgothic; + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + box-shadow: 0px 0px 50px 0px #000; + overflow-y: auto; + max-height: 90%; } .menu button { - font-family: bankgothic; + font-family: bankgothic; } -.menu > table { - border : 1px transparent; - border-spacing : 0; - min-width : 400px; - background-color: #FFF; +.menu>table { + border: 1px transparent; + border-spacing: 0; + min-width: 400px; + background-color: #FFF; } -.menu > table > thead { - background-color: #506be6; - text-align : center; - height : 40px; - line-height : 40px; - color : #fff; +.menu>table>thead { + background-color: #506be6; + text-align: center; + height: 40px; + line-height: 40px; + color: #fff; } .menu td { - text-align: center; - padding : 8px; + text-align: center; + padding: 8px; } .menu tbody tr:nth-child(even) { - background: #CCC + background: #CCC } .menu tbody tr:nth-child(odd) { - background: #FFF -} + background: #FFF +} \ No newline at end of file diff --git a/html/js/app.js b/html/js/app.js index fb391537..943e2db8 100644 --- a/html/js/app.js +++ b/html/js/app.js @@ -23,15 +23,17 @@ ESX_MENU.ResourceName = 'esx_menu_list'; ESX_MENU.opened = {}; ESX_MENU.focus = []; - ESX_MENU.data = {} + ESX_MENU.data = {}; - ESX_MENU.open = function(namespace, name, data){ + ESX_MENU.open = function(namespace, name, data) { - if(typeof ESX_MENU.opened[namespace] == 'undefined') + if (typeof ESX_MENU.opened[namespace] == 'undefined') { ESX_MENU.opened[namespace] = {}; + } - if(typeof ESX_MENU.opened[namespace][name] != 'undefined') + if (typeof ESX_MENU.opened[namespace][name] != 'undefined') { ESX_MENU.close(namespace, name); + } data._namespace = namespace; data._name = name; @@ -44,24 +46,22 @@ }); ESX_MENU.render(); - } + }; - ESX_MENU.close = function(namespace, name){ - + ESX_MENU.close = function(namespace, name) { delete ESX_MENU.opened[namespace][name]; - for(let i=0; i' + matches[k][1] + ''); + } - view.rows[i].cols.push({data: data, content: col}) - + view.rows[i].cols.push({data: data, content: col}); } - } - let menu = $(Mustache.render(MenuTpl, view)) + let menu = $(Mustache.render(MenuTpl, view)); - menu.find('button[data-namespace][data-name]').click(function(){ + menu.find('button[data-namespace][data-name]').click(function() { ESX_MENU.submit($(this).data('namespace'), $(this).data('name'), { data : ESX_MENU.data[$(this).data('namespace')][$(this).data('name')][parseInt($(this).data('id'))], value: $(this).data('value') - }) - }) + }); + }); menu.hide(); @@ -134,37 +134,35 @@ } } - if(typeof focused != 'undefined') + if (typeof focused != 'undefined') { $('#menu_' + focused.namespace + '_' + focused.name).show(); + } $(menuContainer).show(); - - } + }; ESX_MENU.submit = function(namespace, name, data){ - SendMessage(ESX_MENU.ResourceName, 'menu_submit', { + $.post('http://' + ESX_MENU.ResourceName + '/menu_submit', JSON.stringify({ _namespace: namespace, _name : name, data : data.data, value : data.value - }); - } + })); + }; ESX_MENU.cancel = function(namespace, name){ - SendMessage(ESX_MENU.ResourceName, 'menu_cancel', { + $.post('http://' + ESX_MENU.ResourceName + '/menu_cancel', JSON.stringify({ _namespace: namespace, _name : name - }); - } + })); + }; ESX_MENU.getFocused = function(){ return ESX_MENU.focus[ESX_MENU.focus.length - 1]; - } + }; window.onData = (data) => { - switch(data.action){ - case 'openMenu' : { ESX_MENU.open(data.namespace, data.name, data.data); break; @@ -174,23 +172,20 @@ ESX_MENU.close(data.namespace, data.name); break; } - } - - } + }; window.onload = function(e){ window.addEventListener('message', (event) => { - onData(event.data) + onData(event.data); }); - } + }; - document.onkeyup = function(data) { - - if(data.which == 27) { - let focused = ESX_MENU.getFocused(); - ESX_MENU.cancel(focused.namespace, focused.name); - } - }; + document.onkeyup = function(data) { + if(data.which == 27) { + let focused = ESX_MENU.getFocused(); + ESX_MENU.cancel(focused.namespace, focused.name); + } + }; -})() \ No newline at end of file +})(); \ No newline at end of file diff --git a/html/ui.html b/html/ui.html index 09b1fbc5..af5fd03b 100644 --- a/html/ui.html +++ b/html/ui.html @@ -1,13 +1,16 @@ - - - - - - - - - - + + + + + + + + + + + + + \ No newline at end of file From f3ddbf05b4fa3009657b97b1dbef5a4f689b581d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 31 Oct 2018 15:59:59 +0100 Subject: [PATCH 1860/3224] Security improvements --- server/main.lua | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/server/main.lua b/server/main.lua index 754de01c..6d805555 100644 --- a/server/main.lua +++ b/server/main.lua @@ -7,19 +7,30 @@ TriggerEvent('esx_society:registerSociety', 'realestateagent', 'Agent immobilier RegisterServerEvent('esx_realestateagentjob:revoke') AddEventHandler('esx_realestateagentjob:revoke', function(property, owner) - TriggerEvent('esx_property:removeOwnedPropertyIdentifier', property, owner) + local xPlayer = ESX.GetPlayerFromId(source) + + if xPlayer.job.name == 'realestateagent' then + TriggerEvent('esx_property:removeOwnedPropertyIdentifier', property, owner) + else + print(('esx_realestateagentjob: %s attempted to revoke a property!'):format(xPlayer.identifier)) + end end) RegisterServerEvent('esx_realestateagentjob:sell') AddEventHandler('esx_realestateagentjob:sell', function(target, property, price) - local xPlayer = ESX.GetPlayerFromId(target) - xPlayer.removeMoney(price) + local xPlayer, xTarget = ESX.GetPlayerFromId(source), ESX.GetPlayerFromId(target) - TriggerEvent('esx_addonaccount:getSharedAccount', 'society_realestateagent', function(account) - account.addMoney(price) - end) + if xPlayer.job.name == 'realestateagent' then + xTarget.removeMoney(price) - TriggerEvent('esx_property:setPropertyOwned', property, price, false, xPlayer.identifier) + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_realestateagent', function(account) + account.addMoney(price) + end) + + TriggerEvent('esx_property:setPropertyOwned', property, price, false, xTarget.identifier) + else + print(('esx_realestateagentjob: %s attempted to sell a property!'):format(xPlayer.identifier)) + end end) RegisterServerEvent('esx_realestateagentjob:rent') @@ -31,7 +42,6 @@ end) ESX.RegisterServerCallback('esx_realestateagentjob:getCustomers', function(source, cb) TriggerEvent('esx_ownedproperty:getOwnedProperties', function(properties) - local xPlayers = ESX.GetPlayers() local customers = {} @@ -53,6 +63,5 @@ ESX.RegisterServerCallback('esx_realestateagentjob:getCustomers', function(sourc end cb(customers) - end) end) From 53e0ac9a20360e31e6cb04eba5ed361bf3edcd3a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 31 Oct 2018 16:03:54 +0100 Subject: [PATCH 1861/3224] Fix for job when script restarts --- client/main.lua | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/client/main.lua b/client/main.lua index 4c33738d..7b835239 100644 --- a/client/main.lua +++ b/client/main.lua @@ -10,7 +10,6 @@ local Keys = { ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 } -local PlayeerData = {} local HasAlreadyEnteredMarker = false local LastZone = nil local CurrentAction = nil @@ -24,6 +23,18 @@ Citizen.CreateThread(function() TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) Citizen.Wait(0) end + + while ESX.GetPlayerData().job == nil do + Citizen.Wait(100) + end + + ESX.PlayerData = ESX.GetPlayerData() + + if ESX.PlayerData.job.name == 'realestateagent' then + Config.Zones.OfficeActions.Type = 1 + else + Config.Zones.OfficeActions.Type = -1 + end end) function OpenRealestateAgentMenu() @@ -32,7 +43,7 @@ function OpenRealestateAgentMenu() {label = _U('clients'), value = 'customers'}, } - if PlayerData.job ~= nil and PlayerData.job.name == 'realestateagent' and PlayerData.job.grade_name == 'boss' then + if ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'realestateagent' and ESX.PlayerData.job.grade_name == 'boss' then table.insert(elements, { label = _U('boss_action'), value = 'boss_actions' @@ -202,22 +213,11 @@ function OpenCustomersMenu() end) end -RegisterNetEvent('esx:playerLoaded') -AddEventHandler('esx:playerLoaded', function(xPlayer) - PlayerData = xPlayer - - if PlayerData.job.name == 'realestateagent' then - Config.Zones.OfficeActions.Type = 1 - else - Config.Zones.OfficeActions.Type = -1 - end -end) - RegisterNetEvent('esx:setJob') AddEventHandler('esx:setJob', function(job) - PlayerData.job = job + ESX.PlayerData.job = job - if PlayerData.job.name == 'realestateagent' then + if ESX.PlayerData.job.name == 'realestateagent' then Config.Zones.OfficeActions.Type = 1 else Config.Zones.OfficeActions.Type = -1 @@ -231,7 +231,7 @@ AddEventHandler('esx_realestateagentjob:hasEnteredMarker', function(zone) elseif zone == 'OfficeExit' then local playerPed = PlayerPedId() SetEntityCoords(playerPed, Config.Zones.OfficeOutside.Pos.x, Config.Zones.OfficeOutside.Pos.y, Config.Zones.OfficeOutside.Pos.z) - elseif zone == 'OfficeActions' and PlayerData.job ~= nil and PlayerData.job.name == 'realestateagent' then + elseif zone == 'OfficeActions' and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'realestateagent' then CurrentAction = 'realestateagent_menu' CurrentActionMsg = _U('press_to_access') CurrentActionData = {} From 74653246b0d2fc7731699fa4546a0a4635b6d05e Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 3 Nov 2018 21:53:44 +0100 Subject: [PATCH 1862/3224] Performance, respect EnableHud from ESX --- client/main.lua | 73 +++++++++++++++------------------------ html/scripts/app.js | 54 +++++++++++++++-------------- html/ui.html | 24 +++++++------ server/classes/status.lua | 2 +- server/main.lua | 60 +++++++++++--------------------- 5 files changed, 89 insertions(+), 124 deletions(-) diff --git a/client/main.lua b/client/main.lua index 17a7aac7..4a4dbb1c 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,46 +1,38 @@ local Status = {} +local isPaused = false function GetStatusData(minimal) - local status = {} for i=1, #Status, 1 do - if minimal then - table.insert(status, { name = Status[i].name, val = Status[i].val, - percent = (Status[i].val / Config.StatusMax) * 100, + percent = (Status[i].val / Config.StatusMax) * 100 }) - else - table.insert(status, { name = Status[i].name, val = Status[i].val, color = Status[i].color, visible = Status[i].visible(Status[i]), max = Status[i].max, - percent = (Status[i].val / Config.StatusMax) * 100, + percent = (Status[i].val / Config.StatusMax) * 100 }) - end - end return status - end AddEventHandler('esx_status:registerStatus', function(name, default, color, visible, tickCallback) - local s = CreateStatus(name, default, color, visible, tickCallback) - table.insert(Status, s) + local status = CreateStatus(name, default, color, visible, tickCallback) + table.insert(Status, status) end) RegisterNetEvent('esx_status:load') AddEventHandler('esx_status:load', function(status) - for i=1, #Status, 1 do for j=1, #status, 1 do if Status[i].name == status[j].name then @@ -50,27 +42,23 @@ AddEventHandler('esx_status:load', function(status) end Citizen.CreateThread(function() - while true do - - for i=1, #Status, 1 do - Status[i].onTick() - end + while true do + for i=1, #Status, 1 do + Status[i].onTick() + end SendNUIMessage({ update = true, status = GetStatusData() }) - Citizen.Wait(Config.TickTime) - - end + Citizen.Wait(Config.TickTime) + end end) - end) RegisterNetEvent('esx_status:set') AddEventHandler('esx_status:set', function(name, val) - for i=1, #Status, 1 do if Status[i].name == name then Status[i].set(val) @@ -84,12 +72,10 @@ AddEventHandler('esx_status:set', function(name, val) }) TriggerServerEvent('esx_status:update', GetStatusData(true)) - end) RegisterNetEvent('esx_status:add') AddEventHandler('esx_status:add', function(name, val) - for i=1, #Status, 1 do if Status[i].name == name then Status[i].add(val) @@ -103,12 +89,10 @@ AddEventHandler('esx_status:add', function(name, val) }) TriggerServerEvent('esx_status:update', GetStatusData(true)) - end) RegisterNetEvent('esx_status:remove') AddEventHandler('esx_status:remove', function(name, val) - for i=1, #Status, 1 do if Status[i].name == name then Status[i].remove(val) @@ -122,44 +106,40 @@ AddEventHandler('esx_status:remove', function(name, val) }) TriggerServerEvent('esx_status:update', GetStatusData(true)) - end) AddEventHandler('esx_status:getStatus', function(name, cb) - for i=1, #Status, 1 do if Status[i].name == name then cb(Status[i]) return end end - end) AddEventHandler('esx_status:setDisplay', function(val) - SendNUIMessage({ setDisplay = true, display = val }) - end) -- Pause menu disable hud display -local isPaused = false +if ESX.GetConfig().EnableHud then + Citizen.CreateThread(function() + while true do + Citizen.Wait(300) -Citizen.CreateThread(function() - while true do - Citizen.Wait(10) - if IsPauseMenuActive() and not isPaused then - isPaused = true - TriggerEvent('esx_status:setDisplay', 0.0) - elseif not IsPauseMenuActive() and isPaused then - isPaused = false - TriggerEvent('esx_status:setDisplay', 0.5) - end - end -end) + if IsPauseMenuActive() and not isPaused then + isPaused = true + TriggerEvent('esx_status:setDisplay', 0.0) + elseif not IsPauseMenuActive() and isPaused then + isPaused = false + TriggerEvent('esx_status:setDisplay', 0.5) + end + end + end) +end -- Loaded event Citizen.CreateThread(function() @@ -170,6 +150,7 @@ end) Citizen.CreateThread(function() while true do Citizen.Wait(Config.UpdateInterval) + TriggerServerEvent('esx_status:update', GetStatusData(true)) end -end) \ No newline at end of file +end) diff --git a/html/scripts/app.js b/html/scripts/app.js index e009ce7e..8e01f20c 100644 --- a/html/scripts/app.js +++ b/html/scripts/app.js @@ -1,15 +1,15 @@ -(function(){ +(function () { + let status = []; - let status = [] - - let renderStatus = function(){ + let renderStatus = function () { $('#status_list').html(''); - for(let i=0; i' + @@ -17,41 +17,43 @@ '
    ' + '
    ' + '
    '); - + statusDiv.find('.status_inner') - .css({'border' : '1px solid ' + status[i].color}) - ; + .css({ 'border': '1px solid ' + status[i].color }) + ; statusDiv.find('.status_val') .css({ - 'background-color' : status[i].color, - 'width' : (status[i].val / 10000) + '%' + 'background-color': status[i].color, + 'width': (status[i].val / 10000) + '%' }) - ; + ; - $('#status_list').append(statusDiv) + $('#status_list').append(statusDiv); } - } + }; - window.onData = function(data){ - - if(data.update){ - + window.onData = function (data) { + if (data.update) { status.length = 0; - for(let i=0; i - - - - - - -
    - - - - + + + + + + + +
    + + + + + \ No newline at end of file diff --git a/server/classes/status.lua b/server/classes/status.lua index 7cf02782..226daa60 100644 --- a/server/classes/status.lua +++ b/server/classes/status.lua @@ -1,5 +1,5 @@ function CreateStatus(xPlayer, name, default, color, visible, tickCallback, clientAction) - + local self = {} self.val = default diff --git a/server/main.lua b/server/main.lua index b0f8c46a..eed4d956 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,5 +1,4 @@ -ESX = nil -local RegisteredStatus = {} +ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) @@ -7,43 +6,30 @@ AddEventHandler('esx:playerLoaded', function(source) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) - MySQL.Async.fetchAll( - 'SELECT * FROM users WHERE identifier = @identifier', - { + MySQL.Async.fetchAll('SELECT status FROM users WHERE identifier = @identifier', { ['@identifier'] = xPlayer.identifier - }, - function(result) - - local data = {} - - if result[1].status ~= nil then - data = json.decode(result[1].status) - end - - xPlayer.set('status', data) - - TriggerClientEvent('esx_status:load', _source, data) + }, function(result) + local data = {} + if result[1].status ~= nil then + data = json.decode(result[1].status) end - ) + xPlayer.set('status', data) + TriggerClientEvent('esx_status:load', _source, data) + end) end) AddEventHandler('esx:playerDropped', function(source) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) - local data = {} local status = xPlayer.get('status') - MySQL.Async.execute( - 'UPDATE users SET status = @status WHERE identifier = @identifier', - { - ['@status'] = json.encode(status), - ['@identifier'] = xPlayer.identifier - } - ) - + MySQL.Async.execute('UPDATE users SET status = @status WHERE identifier = @identifier', { + ['@status'] = json.encode(status), + ['@identifier'] = xPlayer.identifier + }) end) AddEventHandler('esx_status:getStatus', function(playerId, statusName, cb) @@ -56,14 +42,13 @@ AddEventHandler('esx_status:getStatus', function(playerId, statusName, cb) break end end - end) RegisterServerEvent('esx_status:update') AddEventHandler('esx_status:update', function(status) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) - + if xPlayer ~= nil then xPlayer.set('status', status) end @@ -71,24 +56,19 @@ end) function SaveData() local xPlayers = ESX.GetPlayers() - - for i=1, #xPlayers, 1 do + for i=1, #xPlayers, 1 do local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) local data = {} local status = xPlayer.get('status') - MySQL.Async.execute( - 'UPDATE users SET status = @status WHERE identifier = @identifier', - { - ['@status'] = json.encode(status), - ['@identifier'] = xPlayer.identifier - } - ) - + MySQL.Async.execute('UPDATE users SET status = @status WHERE identifier = @identifier', { + ['@status'] = json.encode(status), + ['@identifier'] = xPlayer.identifier + }) end SetTimeout(10 * 60 * 1000, SaveData) end -SaveData() \ No newline at end of file +SaveData() From ae1a7c8ca057195099463eccd96de6752d00ecfe Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 3 Nov 2018 23:08:23 +0100 Subject: [PATCH 1863/3224] Added index to datastore Co-Authored-By: GHMatti --- esx_datastore.sql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/esx_datastore.sql b/esx_datastore.sql index c8d8debf..345f76d9 100644 --- a/esx_datastore.sql +++ b/esx_datastore.sql @@ -15,5 +15,8 @@ CREATE TABLE `datastore_data` ( `owner` varchar(255), `data` longtext, + INDEX index_datastore_name (`name`), + CONSTRAINT unique_datastore_owner_name UNIQUE (`owner`, `name`), + PRIMARY KEY (`id`) ); From 5df65428717e379950eb2360443ec12d5cdf7b4f Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 3 Nov 2018 23:10:19 +0100 Subject: [PATCH 1864/3224] Renamed column isDead to is_dead --- client/main.lua | 2 +- esx_ambulancejob.sql | 4 +++- localization/de_esx_ambulancejob.sql | 4 +++- localization/en_esx_ambulancejob.sql | 4 +++- localization/fi_esx_ambulancejob.sql | 4 +++- localization/pl_esx_ambulancejob.sql | 4 +++- server/main.lua | 7 +++---- 7 files changed, 19 insertions(+), 10 deletions(-) diff --git a/client/main.lua b/client/main.lua index b3fe27ee..0e739c98 100644 --- a/client/main.lua +++ b/client/main.lua @@ -296,7 +296,7 @@ AddEventHandler('esx_ambulancejob:revive', function() DoScreenFadeOut(800) while not IsScreenFadedOut() do - Citizen.Wait(0) + Citizen.Wait(50) end ESX.SetPlayerData('lastPosition', { diff --git a/esx_ambulancejob.sql b/esx_ambulancejob.sql index ddb05e02..d88d5676 100644 --- a/esx_ambulancejob.sql +++ b/esx_ambulancejob.sql @@ -28,4 +28,6 @@ INSERT INTO `items` (name, label, `limit`) VALUES ('medikit','Medikit', 5) ; -ALTER TABLE `users` ADD `isDead` BIT(1) DEFAULT b'0' +ALTER TABLE `users` + ADD `is_dead` TINYINT(1) NULL DEFAULT '0' +; diff --git a/localization/de_esx_ambulancejob.sql b/localization/de_esx_ambulancejob.sql index d11f2575..0ebf079d 100644 --- a/localization/de_esx_ambulancejob.sql +++ b/localization/de_esx_ambulancejob.sql @@ -28,4 +28,6 @@ INSERT INTO `items` (name, label, `limit`) VALUES ('medikit','Medikit', 5) ; -ALTER TABLE `users` ADD `isDead` BIT(1) DEFAULT b'0' +ALTER TABLE `users` + ADD `is_dead` TINYINT(1) NULL DEFAULT '0' +; diff --git a/localization/en_esx_ambulancejob.sql b/localization/en_esx_ambulancejob.sql index cbe37090..6bb4ecf1 100644 --- a/localization/en_esx_ambulancejob.sql +++ b/localization/en_esx_ambulancejob.sql @@ -28,4 +28,6 @@ INSERT INTO `items` (name, label, `limit`) VALUES ('medikit','Medikit', 5) ; -ALTER TABLE `users` ADD `isDead` BIT(1) DEFAULT b'0' +ALTER TABLE `users` + ADD `is_dead` TINYINT(1) NULL DEFAULT '0' +; diff --git a/localization/fi_esx_ambulancejob.sql b/localization/fi_esx_ambulancejob.sql index 3ea64c07..7c001e0d 100644 --- a/localization/fi_esx_ambulancejob.sql +++ b/localization/fi_esx_ambulancejob.sql @@ -28,4 +28,6 @@ INSERT INTO `items` (name, label, `limit`) VALUES ('medikit','Ensiapupakkaus', 5) ; -ALTER TABLE `users` ADD `isDead` BIT(1) DEFAULT b'0' +ALTER TABLE `users` + ADD `is_dead` TINYINT(1) NULL DEFAULT '0' +; diff --git a/localization/pl_esx_ambulancejob.sql b/localization/pl_esx_ambulancejob.sql index a9035d79..c3715181 100644 --- a/localization/pl_esx_ambulancejob.sql +++ b/localization/pl_esx_ambulancejob.sql @@ -28,4 +28,6 @@ INSERT INTO `items` (name, label, `limit`) VALUES ('medikit','Defibrylator', 5) ; -ALTER TABLE `users` ADD `isDead` BIT(1) DEFAULT b'0' +ALTER TABLE `users` + ADD `is_dead` TINYINT(1) NULL DEFAULT '0' +; diff --git a/server/main.lua b/server/main.lua index 4eb51635..b233f93d 100644 --- a/server/main.lua +++ b/server/main.lua @@ -183,10 +183,10 @@ RegisterServerEvent('esx_ambulancejob:firstSpawn') AddEventHandler('esx_ambulancejob:firstSpawn', function() local _source = source local identifier = GetPlayerIdentifiers(_source)[1] - MySQL.Async.fetchScalar('SELECT isDead FROM users WHERE identifier = @identifier', { + MySQL.Async.fetchScalar('SELECT is_dead FROM users WHERE identifier = @identifier', { ['@identifier'] = identifier }, function(isDead) - if isDead == 1 then + if isDead then print(('esx_ambulancejob: %s attempted combat logging!'):format(identifier)) TriggerClientEvent('esx_ambulancejob:requestDeath', _source) end @@ -197,8 +197,7 @@ RegisterServerEvent('esx_ambulancejob:setDeathStatus') AddEventHandler('esx_ambulancejob:setDeathStatus', function(isDead) local identifier = GetPlayerIdentifiers(source)[1] - MySQL.Sync.execute("UPDATE users SET isDead=@isDead WHERE identifier = @identifier", - { + MySQL.Sync.execute('UPDATE users SET is_dead = @isDead WHERE identifier = @identifier', { ['@identifier'] = identifier, ['@isDead'] = isDead }) From db29c87ae4bbd23b61ec32f05b86ceade9f1867a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 3 Nov 2018 23:10:52 +0100 Subject: [PATCH 1865/3224] Final commit v1.1.1 --- __resource.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__resource.lua b/__resource.lua index fc60045b..957f6528 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,7 +2,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ESX Ambulance Job' -version '1.1.0' +version '1.1.1' server_scripts { '@mysql-async/lib/MySQL.lua', From 2bad03e88a02cf7ae693103b99bddcd77d6a7f6f Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 4 Nov 2018 12:32:28 +0100 Subject: [PATCH 1866/3224] Removed confirm escape --- client/main.lua | 27 +++++++-------------------- locales/br.lua | 3 --- locales/de.lua | 3 --- locales/en.lua | 3 --- locales/fi.lua | 3 --- locales/fr.lua | 3 --- locales/pl.lua | 3 --- locales/sv.lua | 3 --- 8 files changed, 7 insertions(+), 41 deletions(-) diff --git a/client/main.lua b/client/main.lua index de8bee5b..eb5fa08c 100644 --- a/client/main.lua +++ b/client/main.lua @@ -65,7 +65,7 @@ function OpenMenu(submitCb, cancelCb, restrict) local componentId = _components[i].componentId if componentId == 0 then - value = GetPedPropIndex(playerPed, _components[i].componentId) + value = GetPedPropIndex(playerPed, _components[i].componentId) end local data = { @@ -94,11 +94,10 @@ function OpenMenu(submitCb, cancelCb, restrict) camOffset = _components[1].camOffset ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'skin', { - title = _U('skin_menu'), - align = 'top-left', + title = _U('skin_menu'), + align = 'top-left', elements = elements }, function(data, menu) - TriggerEvent('skinchanger:getSkin', function(skin) LastSkin = skin end) @@ -106,22 +105,9 @@ function OpenMenu(submitCb, cancelCb, restrict) submitCb(data, menu) DeleteSkinCam() end, function(data, menu) - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'confirm_escape', { - title = _U('confirm_escape'), - align = 'top-left', - elements = { - {label = _U('no'), value = 'no'}, - {label = _U('yes'), value = 'yes'} - } - }, function(data2, menu2) - if data2.current.value == 'yes' then - menu.close() - DeleteSkinCam() - TriggerEvent('skinchanger:loadSkin', LastSkin) - end - - menu2.close() - end) + menu.close() + DeleteSkinCam() + TriggerEvent('skinchanger:loadSkin', LastSkin) if cancelCb ~= nil then cancelCb(data, menu) @@ -272,6 +258,7 @@ function OpenSaveableMenu(submitCb, cancelCb, restrict) TriggerEvent('skinchanger:getSkin', function(skin) TriggerServerEvent('esx_skin:save', skin) + if submitCb ~= nil then submitCb(data, menu) end diff --git a/locales/br.lua b/locales/br.lua index 52eb7d1c..2a9d09d4 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -3,7 +3,4 @@ Locales['br'] = { ['use_rotate_view'] = 'Use ~INPUT_VEH_FLY_ROLL_LEFT_ONLY~ e ~INPUT_VEH_FLY_ROLL_RIGHT_ONLY~ para girar a visão.', ['skin'] = 'Trocar', ['saveskin'] = 'Salvar', - ['confirm_escape'] = 'do you want to cancel the skin changer? All changes go unsaved.', - ['no'] = 'no', - ['yes'] = 'yes', } diff --git a/locales/de.lua b/locales/de.lua index 25bc1c4f..f1439358 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -3,7 +3,4 @@ Locales['de'] = { ['use_rotate_view'] = 'benutze ~INPUT_VEH_FLY_ROLL_LEFT_ONLY~ und ~INPUT_VEH_FLY_ROLL_RIGHT_ONLY~ um die Sicht zu drehen.', ['skin'] = 'Skin ändern', ['saveskin'] = 'Skin speichern', - ['confirm_escape'] = 'do you want to cancel the skin changer? All changes go unsaved.', - ['no'] = 'no', - ['yes'] = 'yes', } diff --git a/locales/en.lua b/locales/en.lua index 1fb10930..f1ee073e 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -3,7 +3,4 @@ Locales['en'] = { ['use_rotate_view'] = 'use ~INPUT_VEH_FLY_ROLL_LEFT_ONLY~ and ~INPUT_VEH_FLY_ROLL_RIGHT_ONLY~ to rotate the view.', ['skin'] = 'change skin', ['saveskin'] = 'save skin to a file', - ['confirm_escape'] = 'do you want to cancel the skin changer? All changes go unsaved.', - ['no'] = 'no', - ['yes'] = 'yes', } diff --git a/locales/fi.lua b/locales/fi.lua index 1ea163a5..39e6d75f 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -3,7 +3,4 @@ Locales['fi'] = { ['use_rotate_view'] = 'paina ~INPUT_VEH_FLY_ROLL_LEFT_ONLY~ tai ~INPUT_VEH_FLY_ROLL_RIGHT_ONLY~ liikutaaksesi kameraa.', ['skin'] = 'vaihda ulkonäköä', ['saveskin'] = 'talleta ulkonäkö tiedostoon', - ['confirm_escape'] = 'do you want to cancel the skin changer? All changes go unsaved.', - ['no'] = 'no', - ['yes'] = 'yes', } diff --git a/locales/fr.lua b/locales/fr.lua index c71b7723..22cfc7bc 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -3,7 +3,4 @@ Locales['fr'] = { ['use_rotate_view'] = 'utilisez ~INPUT_VEH_FLY_ROLL_LEFT_ONLY~ et ~INPUT_VEH_FLY_ROLL_RIGHT_ONLY~ pour tourner la vue.', ['skin'] = 'changer de skin', ['saveskin'] = 'sauvegarder skin dans un fichier', - ['confirm_escape'] = 'do you want to cancel the skin changer? All changes go unsaved.', - ['no'] = 'no', - ['yes'] = 'yes', } diff --git a/locales/pl.lua b/locales/pl.lua index 173fad3e..3961df62 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -3,7 +3,4 @@ Locales['pl'] = { ['use_rotate_view'] = 'użyj ~INPUT_VEH_FLY_ROLL_LEFT_ONLY~ i ~INPUT_VEH_FLY_ROLL_RIGHT_ONLY~ aby obrócić ekran.', ['skin'] = 'zmien wygląd', ['saveskin'] = 'zapisz wygląd do pliku', - ['confirm_escape'] = 'czy chcesz anulować zmianę wyglądu? Wszystkie zmiany zostaną utracone.', - ['no'] = 'nie', - ['yes'] = 'tak', } diff --git a/locales/sv.lua b/locales/sv.lua index 8f3dfcf8..02ddd5f0 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -3,7 +3,4 @@ Locales['sv'] = { ['use_rotate_view'] = 'använd ~INPUT_VEH_FLY_ROLL_LEFT_ONLY~ och ~INPUT_VEH_FLY_ROLL_RIGHT_ONLY~ för att rotera.', ['skin'] = 'ändra skin', ['saveskin'] = 'spara skin till fil', - ['confirm_escape'] = 'vill du avbryta menyn? Alla ändringar går osparade.', - ['no'] = 'nej', - ['yes'] = 'ja', } From ee768270dd11a8046913769124fcceda1023b7f9 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 4 Nov 2018 12:33:22 +0100 Subject: [PATCH 1867/3224] Make sure only admin can write to disk #13 --- server/main.lua | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/server/main.lua b/server/main.lua index 5a9ff59c..7141a161 100644 --- a/server/main.lua +++ b/server/main.lua @@ -15,17 +15,27 @@ end) RegisterServerEvent('esx_skin:responseSaveSkin') AddEventHandler('esx_skin:responseSaveSkin', function(skin) - local file = io.open('resources/[esx]/esx_skin/skins.txt', "a") - file:write(json.encode(skin) .. "\n\n") - file:flush() - file:close() + TriggerEvent('es:getPlayerFromId', source, function(user) + TriggerEvent('es:canGroupTarget', user.getGroup(), "admin", function(available) + if available then + local file = io.open('resources/[esx]/esx_skin/skins.txt', "a") + + file:write(json.encode(skin) .. "\n\n") + file:flush() + file:close() + else + print(('esx_skin: %s attempted saving skin to file'):format(user.getIdentifier())) + end + end) + end) + end) ESX.RegisterServerCallback('esx_skin:getPlayerSkin', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.fetchAll('SELECT * FROM users WHERE identifier = @identifier', { + MySQL.Async.fetchAll('SELECT skin FROM users WHERE identifier = @identifier', { ['@identifier'] = xPlayer.identifier }, function(users) local user = users[1] From ce687ff579343b3dbf3ce51b8ce9c721fe9545d4 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 4 Nov 2018 12:35:11 +0100 Subject: [PATCH 1868/3224] Manal pr closes #12 --- locales/pl.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/pl.lua b/locales/pl.lua index 3961df62..9458a7a4 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -1,6 +1,6 @@ Locales['pl'] = { ['skin_menu'] = 'menu wyglądu', ['use_rotate_view'] = 'użyj ~INPUT_VEH_FLY_ROLL_LEFT_ONLY~ i ~INPUT_VEH_FLY_ROLL_RIGHT_ONLY~ aby obrócić ekran.', - ['skin'] = 'zmien wygląd', + ['skin'] = 'zmień wygląd', ['saveskin'] = 'zapisz wygląd do pliku', } From db3e45ce32d15531f241ce5a9e3aae13f37064c7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 4 Nov 2018 21:20:54 +0100 Subject: [PATCH 1869/3224] Fixed bugs with setting death status, combat loggers now force-respawn --- client/job.lua | 1 + client/main.lua | 31 +++++++++++++++++-------------- locales/br.lua | 1 + locales/en.lua | 1 + locales/es.lua | 1 + locales/fi.lua | 1 + locales/fr.lua | 1 + locales/pl.lua | 1 + locales/sv.lua | 1 + server/main.lua | 10 +++++----- 10 files changed, 30 insertions(+), 19 deletions(-) diff --git a/client/job.lua b/client/job.lua index 529ec5fb..48da14d5 100644 --- a/client/job.lua +++ b/client/job.lua @@ -1,4 +1,5 @@ local HasAlreadyEnteredMarker, LastZone, CurrentAction, CurrentActionMsg, CurrentActionData = nil, nil, nil, '', {} +local IsBusy = false function OpenAmbulanceActionsMenu() local elements = { diff --git a/client/main.lua b/client/main.lua index 0e739c98..0141e83b 100644 --- a/client/main.lua +++ b/client/main.lua @@ -10,7 +10,7 @@ Keys = { ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 } -local FirstSpawn, IsBusy = true, false +local FirstSpawn, PlayerLoaded = true, false IsDead = false ESX = nil @@ -25,12 +25,14 @@ Citizen.CreateThread(function() Citizen.Wait(100) end + PlayerLoaded = true ESX.PlayerData = ESX.GetPlayerData() end) RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) ESX.PlayerData = xPlayer + PlayerLoaded = true end) RegisterNetEvent('esx:setJob') @@ -42,9 +44,19 @@ AddEventHandler('playerSpawned', function() IsDead = false if FirstSpawn then - TriggerServerEvent('esx_ambulancejob:firstSpawn') exports.spawnmanager:setAutoSpawn(false) -- disable respawn FirstSpawn = false + + ESX.TriggerServerCallback('esx_ambulancejob:getDeathStatus', function(isDead) + if isDead and Config.AntiCombatLog then + while not PlayerLoaded do + Citizen.Wait(1000) + end + + ESX.ShowNotification(_U('combatlog_message')) + RemoveItemsAfterRPDeath() + end + end) end end) @@ -66,7 +78,7 @@ end) function OnPlayerDeath() IsDead = true - TriggerServerEvent('esx_ambulancejob:setDeathStatus', 1) + TriggerServerEvent('esx_ambulancejob:setDeathStatus', true) StartDeathTimer() StartDistressSignal() @@ -226,7 +238,7 @@ function StartDeathTimer() end function RemoveItemsAfterRPDeath() - TriggerServerEvent('esx_ambulancejob:setDeathStatus', 0) + TriggerServerEvent('esx_ambulancejob:setDeathStatus', false) Citizen.CreateThread(function() DoScreenFadeOut(800) @@ -290,7 +302,7 @@ RegisterNetEvent('esx_ambulancejob:revive') AddEventHandler('esx_ambulancejob:revive', function() local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) - TriggerServerEvent('esx_ambulancejob:setDeathStatus', 0) + TriggerServerEvent('esx_ambulancejob:setDeathStatus', true) Citizen.CreateThread(function() DoScreenFadeOut(800) @@ -322,15 +334,6 @@ AddEventHandler('esx_ambulancejob:revive', function() end) end) - -RegisterNetEvent('esx_ambulancejob:requestDeath') -AddEventHandler('esx_ambulancejob:requestDeath', function() - if Config.AntiCombatLog then - Citizen.Wait(5000) - SetEntityHealth(PlayerPedId(), 0) - end -end) - -- Load unloaded IPLs if Config.LoadIpl then Citizen.CreateThread(function() diff --git a/locales/br.lua b/locales/br.lua index 1e934fcb..2d7db462 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -52,6 +52,7 @@ Locales['br'] = { ['distress_send'] = 'press [~b~G~s~] to send distress signal', ['distress_sent'] = 'distress signal has been sent to available units!', ['distress_message'] = 'medical attention required: unconscious citizen!', + ['combatlog_message'] = 'you have been force-respawned because you\'ve previously left the server when dead.', -- Revive ['revive_help'] = 'reviver um jogador', -- Item diff --git a/locales/en.lua b/locales/en.lua index 17c85a22..053012f2 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -52,6 +52,7 @@ Locales['en'] = { ['distress_send'] = 'press [~b~G~s~] to send distress signal', ['distress_sent'] = 'distress signal has been sent to available units!', ['distress_message'] = 'medical attention required: unconscious citizen!', + ['combatlog_message'] = 'you have been force-respawned because you\'ve previously left the server when dead.', -- Revive ['revive_help'] = 'revive a player', -- Item diff --git a/locales/es.lua b/locales/es.lua index 2445a06e..df241022 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -52,6 +52,7 @@ Locales['es'] = { ['distress_send'] = 'press [~b~G~s~] to send distress signal', ['distress_sent'] = 'distress signal has been sent to available units!', ['distress_message'] = 'medical attention required: unconscious citizen!', + ['combatlog_message'] = 'you have been force-respawned because you\'ve previously left the server when dead.', -- Revive ['revive_help'] = 'reviver un jugador', -- Item diff --git a/locales/fi.lua b/locales/fi.lua index 59574c21..d474c1f5 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -52,6 +52,7 @@ Locales['fi'] = { ['distress_send'] = 'press [~b~G~s~] to send distress signal', ['distress_sent'] = 'distress signal has been sent to available units!', ['distress_message'] = 'medical attention required: unconscious citizen!', + ['combatlog_message'] = 'you have been force-respawned because you\'ve previously left the server when dead.', -- Revive ['revive_help'] = 'elvytä pelaaja', -- Item diff --git a/locales/fr.lua b/locales/fr.lua index 1fa2cca3..3dc156b1 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -52,6 +52,7 @@ Locales['fr'] = { ['distress_send'] = 'press [~b~G~s~] to send distress signal', ['distress_sent'] = 'distress signal has been sent to available units!', ['distress_message'] = 'medical attention required: unconscious citizen!', + ['combatlog_message'] = 'you have been force-respawned because you\'ve previously left the server when dead.', -- Revive ['revive_help'] = 'relancer un joueur', -- Item diff --git a/locales/pl.lua b/locales/pl.lua index 31b5486a..e301f8b4 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -52,6 +52,7 @@ Locales['pl'] = { ['distress_send'] = 'press [~b~G~s~] to send distress signal', ['distress_sent'] = 'distress signal has been sent to available units!', ['distress_message'] = 'medical attention required: unconscious citizen!', + ['combatlog_message'] = 'you have been force-respawned because you\'ve previously left the server when dead.', -- Revive ['revive_help'] = 'ożyw gracza', -- Item diff --git a/locales/sv.lua b/locales/sv.lua index ae3f4a04..7097678f 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -52,6 +52,7 @@ Locales['sv'] = { ['distress_send'] = 'tryck ~b~[G]~s~ för att skicka nödsignal', ['distress_sent'] = 'nödsignal har skickats till samtliga enheter!', ['distress_message'] = 'läkarvård krävs: medvetslös medborgare!', + ['combatlog_message'] = 'du har force-respawnats på grund av att du lämnat servern medans du var död', -- Revive ['revive_help'] = 'återuppliva en spelare', -- Item diff --git a/server/main.lua b/server/main.lua index b233f93d..2a66b62c 100644 --- a/server/main.lua +++ b/server/main.lua @@ -179,17 +179,17 @@ ESX.RegisterUsableItem('bandage', function(source) TriggerClientEvent('esx:showNotification', _source, _U('used_bandage')) end) -RegisterServerEvent('esx_ambulancejob:firstSpawn') -AddEventHandler('esx_ambulancejob:firstSpawn', function() - local _source = source - local identifier = GetPlayerIdentifiers(_source)[1] +ESX.RegisterServerCallback('esx_ambulancejob:getDeathStatus', function(source, cb) + local identifier = GetPlayerIdentifiers(source)[1] + MySQL.Async.fetchScalar('SELECT is_dead FROM users WHERE identifier = @identifier', { ['@identifier'] = identifier }, function(isDead) if isDead then print(('esx_ambulancejob: %s attempted combat logging!'):format(identifier)) - TriggerClientEvent('esx_ambulancejob:requestDeath', _source) end + + cb(isDead) end) end) From 485dc685f2f10d3b48084a84a9cba00fd804df14 Mon Sep 17 00:00:00 2001 From: Jeffrey-Lang <34451211+Jeffrey-Lang@users.noreply.github.com> Date: Sun, 4 Nov 2018 21:27:34 +0100 Subject: [PATCH 1870/3224] Fixed respawning with /revive (#87) - Fix spawning at hostiptal with /revive command or revive by ems menu - Now correctly repawning to hospital after bleedoutTimer runs out --- client/main.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index 0141e83b..5b834543 100644 --- a/client/main.lua +++ b/client/main.lua @@ -209,6 +209,7 @@ function StartDeathTimer() text = text .. _U('respawn_bleedout_prompt') if IsControlPressed(0, Keys['E']) and timeHeld > 60 then + RemoveItemsAfterRPDeath() break end elseif Config.EarlyRespawnFine and canPayFine then @@ -216,6 +217,7 @@ function StartDeathTimer() if IsControlPressed(0, Keys['E']) and timeHeld > 60 then TriggerServerEvent('esx_ambulancejob:payFine') + RemoveItemsAfterRPDeath() break end end @@ -232,8 +234,10 @@ function StartDeathTimer() AddTextComponentString(text) DrawText(0.5, 0.8) end - - RemoveItemsAfterRPDeath() + + if bleedoutTimer < 1 and IsDead then + RemoveItemsAfterRPDeath() + end end) end From c9187dd6df65181f13f48570651673308fc3ec42 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 4 Nov 2018 21:28:54 +0100 Subject: [PATCH 1871/3224] Corrected is_dead --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 5b834543..fb932b83 100644 --- a/client/main.lua +++ b/client/main.lua @@ -306,7 +306,7 @@ RegisterNetEvent('esx_ambulancejob:revive') AddEventHandler('esx_ambulancejob:revive', function() local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) - TriggerServerEvent('esx_ambulancejob:setDeathStatus', true) + TriggerServerEvent('esx_ambulancejob:setDeathStatus', false) Citizen.CreateThread(function() DoScreenFadeOut(800) From a5bebc8bec2fedb1d82c8c8f3b42b85e9292d497 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 4 Nov 2018 22:21:19 +0100 Subject: [PATCH 1872/3224] Fixed max key length error --- esx_datastore.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esx_datastore.sql b/esx_datastore.sql index 345f76d9..5b31b018 100644 --- a/esx_datastore.sql +++ b/esx_datastore.sql @@ -11,8 +11,8 @@ CREATE TABLE `datastore` ( CREATE TABLE `datastore_data` ( `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL, - `owner` varchar(255), + `name` varchar(60) NOT NULL, + `owner` varchar(60), `data` longtext, INDEX index_datastore_name (`name`), From e06aa05b0e3619b50db2b6ce8fbafb337f8dd468 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 4 Nov 2018 22:31:56 +0100 Subject: [PATCH 1873/3224] name as primary key --- esx_datastore.sql | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/esx_datastore.sql b/esx_datastore.sql index 5b31b018..5b694f8a 100644 --- a/esx_datastore.sql +++ b/esx_datastore.sql @@ -1,12 +1,11 @@ USE `essentialmode`; CREATE TABLE `datastore` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL, + `name` varchar(60) NOT NULL, `label` varchar(255) NOT NULL, `shared` int(11) NOT NULL, - PRIMARY KEY (`id`) + PRIMARY KEY (`name`) ); CREATE TABLE `datastore_data` ( From c5aa786087e2d4ac53a36df966cf4343df5e81a9 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 4 Nov 2018 22:32:37 +0100 Subject: [PATCH 1874/3224] name as primary key --- README.md | 11 +++++++---- esx_addoninventory.sql | 5 ++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 113f008d..a3863058 100644 --- a/README.md +++ b/README.md @@ -26,14 +26,17 @@ start esx_addoninventory ``` ## Usage -There is two types of inventories : shared and not shared. +There are two types of inventories: shared and not shared. - Shared inventories dont belong to a specific user. Example: foodstore items. -- Not shared inventories are created for every user in the server. They are created in db when player is loaded, Example: property items +- None-shared inventories are created for every user in the server. They are created in db when player is loaded, Example: property items -You must create the inventory in the database (addon_inventory) before using it : +### `addon_inventory` database information +An addon inventory must be configured in the database before using it. Don't forget to run a server restart afterwards (you can alternative restart the script and relog all clients) -name = name of the inventory, label = label of the inventory, shared (0 or 1) = Is inventory shared +| `name` | `label` | `shared` | +| -------- | ------- | -------- | +| name of the inventory | label of the inventory (not used) | is the inventory shared with others? (boolean either `0` or `1`) | ```lua TriggerEvent('esx_addoninventory:getSharedInventory', 'society_police', function(inventory) diff --git a/esx_addoninventory.sql b/esx_addoninventory.sql index 424ba207..7a664629 100644 --- a/esx_addoninventory.sql +++ b/esx_addoninventory.sql @@ -1,12 +1,11 @@ USE `essentialmode`; CREATE TABLE `addon_inventory` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL, + `name` varchar(60) NOT NULL, `label` varchar(255) NOT NULL, `shared` int(11) NOT NULL, - PRIMARY KEY (`id`) + PRIMARY KEY (`name`) ); CREATE TABLE `addon_inventory_items` ( From 750c125db754394c433e989b38d536ddaec10b37 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 4 Nov 2018 22:32:56 +0100 Subject: [PATCH 1875/3224] name as primary key --- README.md | 2 +- esx_addonaccount.sql | 21 +++++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 79b83fa8..8826cb16 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ There is two types of accounts: shared and not shared. - None-shared accounts are created for every user in the server. They are created in db when player is loaded, Example: property black money ### `addon_account` database information -You must create an account in the database +An addon account must be configured in the database before using it. Don't forget to run a server restart afterwards (you can alternative restart the script and relog all clients) | `name` | `label` | `shared` | | -------- | ------- | -------- | diff --git a/esx_addonaccount.sql b/esx_addonaccount.sql index 95e9e703..5b42b181 100644 --- a/esx_addonaccount.sql +++ b/esx_addonaccount.sql @@ -1,17 +1,18 @@ USE `essentialmode`; CREATE TABLE `addon_account` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL, - `label` varchar(255) NOT NULL, - `shared` int(11) NOT NULL, - PRIMARY KEY (`id`) + `name` varchar(60) NOT NULL, + `label` varchar(255) NOT NULL, + `shared` int(11) NOT NULL, + + PRIMARY KEY (`name`) ); CREATE TABLE `addon_account_data` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `account_name` varchar(255) DEFAULT NULL, - `money` double NOT NULL, - `owner` varchar(255) DEFAULT NULL, - PRIMARY KEY (`id`) + `id` int(11) NOT NULL AUTO_INCREMENT, + `account_name` varchar(255) DEFAULT NULL, + `money` double NOT NULL, + `owner` varchar(255) DEFAULT NULL, + + PRIMARY KEY (`id`) ); From d70d4af99606219e83d5d7356ddf030dd3389df4 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 4 Nov 2018 22:50:01 +0100 Subject: [PATCH 1876/3224] Minor changes --- client/main.lua | 3 +++ server/main.lua | 20 +++++--------------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/client/main.lua b/client/main.lua index 03901014..2d9b5f9f 100644 --- a/client/main.lua +++ b/client/main.lua @@ -53,13 +53,16 @@ function SetUnsetAccessory(accessory) TriggerEvent('skinchanger:getSkin', function(skin) local mAccessory = -1 local mColor = 0 + if _accessory == "mask" then mAccessory = 0 end + if skin[_accessory .. '_1'] == mAccessory then mAccessory = accessorySkin[_accessory .. '_1'] mColor = accessorySkin[_accessory .. '_2'] end + local accessorySkin = {} accessorySkin[_accessory .. '_1'] = mAccessory accessorySkin[_accessory .. '_2'] = mColor diff --git a/server/main.lua b/server/main.lua index 1b614f92..6c674ae2 100644 --- a/server/main.lua +++ b/server/main.lua @@ -4,11 +4,10 @@ TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) RegisterServerEvent('esx_accessories:pay') AddEventHandler('esx_accessories:pay', function() - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) - xPlayer.removeMoney(Config.Price) - TriggerClientEvent('esx:showNotification', _source, _U('you_paid', Config.Price)) + local xPlayer = ESX.GetPlayerFromId(source) + xPlayer.removeMoney(Config.Price) + TriggerClientEvent('esx:showNotification', source, _U('you_paid', Config.Price)) end) RegisterServerEvent('esx_accessories:save') @@ -17,7 +16,6 @@ AddEventHandler('esx_accessories:save', function(skin, accessory) local xPlayer = ESX.GetPlayerFromId(_source) TriggerEvent('esx_datastore:getDataStore', 'user_' .. string.lower(accessory), xPlayer.identifier, function(store) - store.set('has' .. accessory, true) local itemSkin = {} @@ -25,22 +23,19 @@ AddEventHandler('esx_accessories:save', function(skin, accessory) local item2 = string.lower(accessory) .. '_2' itemSkin[item1] = skin[item1] itemSkin[item2] = skin[item2] + store.set('skin', itemSkin) - end) - end) ESX.RegisterServerCallback('esx_accessories:get', function(source, cb, accessory) local xPlayer = ESX.GetPlayerFromId(source) TriggerEvent('esx_datastore:getDataStore', 'user_' .. string.lower(accessory), xPlayer.identifier, function(store) - local hasAccessory = (store.get('has' .. accessory) and store.get('has' .. accessory) or false) local skin = (store.get('skin') and store.get('skin') or {}) cb(hasAccessory, skin) - end) end) @@ -48,10 +43,5 @@ end) ESX.RegisterServerCallback('esx_accessories:checkMoney', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) - if xPlayer.get('money') >= Config.Price then - cb(true) - else - cb(false) - end - + cb(xPlayer.get('money') >= Config.Price) end) From 2028350a9593c7b7acea1ace34653d6301691b25 Mon Sep 17 00:00:00 2001 From: April <39036878+aprilkae@users.noreply.github.com> Date: Sun, 4 Nov 2018 16:52:17 -0500 Subject: [PATCH 1877/3224] fix for removing glasses (#11) * fixed issue where you couldn't remove glasses (or incorrect glasses were put on) --- client/main.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/main.lua b/client/main.lua index 2d9b5f9f..8530f9ea 100644 --- a/client/main.lua +++ b/client/main.lua @@ -56,6 +56,8 @@ function SetUnsetAccessory(accessory) if _accessory == "mask" then mAccessory = 0 + elseif _accessory == "glasses" then + mAccessory = 5 end if skin[_accessory .. '_1'] == mAccessory then From bef16c09b680937712e414040c68dc92b349fd59 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 4 Nov 2018 22:56:19 +0100 Subject: [PATCH 1878/3224] Enforce 2 space indent on locale files --- client/main.lua | 16 +++++++--------- locales/en.lua | 34 +++++++++++++++++----------------- locales/fi.lua | 34 +++++++++++++++++----------------- locales/fr.lua | 34 +++++++++++++++++----------------- locales/sv.lua | 34 +++++++++++++++++----------------- server/main.lua | 2 +- 6 files changed, 76 insertions(+), 78 deletions(-) diff --git a/client/main.lua b/client/main.lua index 2d9b5f9f..aa0ff237 100644 --- a/client/main.lua +++ b/client/main.lua @@ -34,7 +34,7 @@ function OpenAccessoryMenu() {label = _U('helmet'), value = 'Helmet'}, {label = _U('ears'), value = 'Ears'}, {label = _U('mask'), value = 'Mask'}, - {label = _U('glasses'), value = 'Glasses'}, + {label = _U('glasses'), value = 'Glasses'} } }, function(data, menu) menu.close() @@ -91,7 +91,7 @@ function OpenShopMenu(accessory) align = 'top-left', elements = { {label = _U('no'), value = 'no'}, - {label = _U('yes', Config.Price), value = 'yes'} + {label = _U('yes', ESX.Math.GroupDigits(Config.Price)), value = 'yes'} } }, function(data, menu) menu.close() @@ -112,14 +112,14 @@ function OpenShopMenu(accessory) end if data.current.value == 'no' then - local player = GetPlayerPed(-1) + local player = PlayerPedId() TriggerEvent('esx_skin:getLastSkin', function(skin) TriggerEvent('skinchanger:loadSkin', skin) end) if accessory == "Ears" then ClearPedProp(player, 2) elseif accessory == "Mask" then - SetPedComponentVariation(player, 1, 0 ,0 ,2) + SetPedComponentVariation(player, 1, 0 ,0, 2) elseif accessory == "Helmet" then ClearPedProp(player, 0) elseif accessory == "Glasses" then @@ -188,7 +188,7 @@ end) Citizen.CreateThread(function() while true do Citizen.Wait(0) - local coords = GetEntityCoords(GetPlayerPed(-1)) + local coords = GetEntityCoords(PlayerPedId()) for k,v in pairs(Config.Zones) do for i = 1, #v.Pos, 1 do if(Config.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos[i].x, v.Pos[i].y, v.Pos[i].z, true) < Config.DrawDistance) then @@ -203,12 +203,12 @@ end) Citizen.CreateThread(function() while true do Citizen.Wait(10) - local coords = GetEntityCoords(GetPlayerPed(-1)) + local coords = GetEntityCoords(PlayerPedId()) local isInMarker = false local currentZone = nil for k,v in pairs(Config.Zones) do for i = 1, #v.Pos, 1 do - if(GetDistanceBetweenCoords(coords, v.Pos[i].x, v.Pos[i].y, v.Pos[i].z, true) < Config.Size.x) then + if GetDistanceBetweenCoords(coords, v.Pos[i].x, v.Pos[i].y, v.Pos[i].z, true) < Config.Size.x then isInMarker = true currentZone = k end @@ -235,14 +235,12 @@ Citizen.CreateThread(function() Citizen.Wait(10) if CurrentAction ~= nil then - ESX.ShowHelpNotification(CurrentActionMsg) if IsControlJustReleased(0, Keys['E']) and CurrentActionData.accessory then OpenShopMenu(CurrentActionData.accessory) CurrentAction = nil end - elseif CurrentAction == nil and not Config.EnableControls then Citizen.Wait(500) end diff --git a/locales/en.lua b/locales/en.lua index 2cb77f7d..0ea2f75f 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,19 +1,19 @@ Locales ['en'] = { - ['valid_purchase'] = 'validate this purchase?', - ['yes'] = 'yes ($%s)', - ['no'] = 'no', - ['helmet'] = 'helmet / Hat', - ['glasses'] = 'glasses', - ['mask'] = 'mask', - ['ears'] = 'ears accessories', - ['shop'] = '%s shop', - ['set_unset'] = 'put on / Take off', - ['not_enough_money'] = 'you do not have enough money', - ['press_access'] = 'press ~INPUT_CONTEXT~ to access the menu', - ['accessories_blip'] = 'accessories', - ['no_ears'] = 'you do not have ears accessories', - ['no_glasses'] = 'you do not have glasses', - ['no_helmet'] = 'you do not have a helmet', - ['no_mask'] = 'you do not have a mask', - ['you_paid'] = 'you paid ~g~$%s~s~', + ['valid_purchase'] = 'validate this purchase?', + ['yes'] = 'yes ($%s)', + ['no'] = 'no', + ['helmet'] = 'helmet / Hat', + ['glasses'] = 'glasses', + ['mask'] = 'mask', + ['ears'] = 'ears accessories', + ['shop'] = '%s shop', + ['set_unset'] = 'put on / Take off', + ['not_enough_money'] = 'you do not have enough money', + ['press_access'] = 'press ~INPUT_CONTEXT~ to access the menu', + ['accessories_blip'] = 'accessories', + ['no_ears'] = 'you do not have ears accessories', + ['no_glasses'] = 'you do not have glasses', + ['no_helmet'] = 'you do not have a helmet', + ['no_mask'] = 'you do not have a mask', + ['you_paid'] = 'you paid ~g~$%s~s~', } diff --git a/locales/fi.lua b/locales/fi.lua index 4b8748bc..d5c5cfe9 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -1,19 +1,19 @@ Locales ['fi'] = { - ['valid_purchase'] = 'varmista ostos?', - ['yes'] = 'kyllä ($%s)', - ['no'] = 'ei', - ['helmet'] = 'kypärä / Hattu', - ['glasses'] = 'lasit', - ['mask'] = 'maskit', - ['ears'] = 'korva asusteet', - ['shop'] = '%s asustekauppa', - ['set_unset'] = 'laita päälle / Ota pois', - ['not_enough_money'] = 'sinulla ei ole tarpeeksi rahaa', - ['press_access'] = 'paina ~INPUT_CONTEXT~ avataksesi menu', - ['accessories_blip'] = 'asusteet', - ['no_ears'] = 'sinulla ei ole korva asusteita', - ['no_glasses'] = 'sinulla ei ole laseja', - ['no_helmet'] = 'sinulla ei ole kypäriä', - ['no_mask'] = 'sinulla ei ole maskeja', - ['you_paid'] = 'sinä maksoit ~g~$%s~s~', + ['valid_purchase'] = 'varmista ostos?', + ['yes'] = 'kyllä ($%s)', + ['no'] = 'ei', + ['helmet'] = 'kypärä / Hattu', + ['glasses'] = 'lasit', + ['mask'] = 'maskit', + ['ears'] = 'korva asusteet', + ['shop'] = '%s asustekauppa', + ['set_unset'] = 'laita päälle / Ota pois', + ['not_enough_money'] = 'sinulla ei ole tarpeeksi rahaa', + ['press_access'] = 'paina ~INPUT_CONTEXT~ avataksesi menu', + ['accessories_blip'] = 'asusteet', + ['no_ears'] = 'sinulla ei ole korva asusteita', + ['no_glasses'] = 'sinulla ei ole laseja', + ['no_helmet'] = 'sinulla ei ole kypäriä', + ['no_mask'] = 'sinulla ei ole maskeja', + ['you_paid'] = 'sinä maksoit ~g~$%s~s~', } diff --git a/locales/fr.lua b/locales/fr.lua index c6a02037..4e324f2c 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,19 +1,19 @@ Locales ['fr'] = { - ['valid_purchase'] = 'valider cet achat?', - ['yes'] = 'oui ($%s)', - ['no'] = 'non', - ['helmet'] = 'casque / Chapeau', - ['glasses'] = 'lunettes', - ['mask'] = 'masque', - ['ears'] = 'accessoires d\'oreilles', - ['shop'] = '%s magasin de', - ['set_unset'] = 'mettre / Enlever', - ['not_enough_money'] = 'vous n\'avez pas assez d\'argent', - ['press_access'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder au menu', - ['accessories_blip'] = 'accessoires', - ['no_ears'] = 'vous n\'avez pas d\'accessoires d\'oreilles', - ['no_glasses'] = 'vous n\'avez pas de lunettes', - ['no_helmet'] = 'vous n\'avez pas de casque / chapeau', - ['no_mask'] = 'vous n\'avez pas de masque', - ['you_paid'] = 'vous avez payé ~g~$%s~s~', + ['valid_purchase'] = 'valider cet achat?', + ['yes'] = 'oui ($%s)', + ['no'] = 'non', + ['helmet'] = 'casque / Chapeau', + ['glasses'] = 'lunettes', + ['mask'] = 'masque', + ['ears'] = 'accessoires d\'oreilles', + ['shop'] = '%s magasin de', + ['set_unset'] = 'mettre / Enlever', + ['not_enough_money'] = 'vous n\'avez pas assez d\'argent', + ['press_access'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder au menu', + ['accessories_blip'] = 'accessoires', + ['no_ears'] = 'vous n\'avez pas d\'accessoires d\'oreilles', + ['no_glasses'] = 'vous n\'avez pas de lunettes', + ['no_helmet'] = 'vous n\'avez pas de casque / chapeau', + ['no_mask'] = 'vous n\'avez pas de masque', + ['you_paid'] = 'vous avez payé ~g~$%s~s~', } diff --git a/locales/sv.lua b/locales/sv.lua index 54f99179..7d033564 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -1,19 +1,19 @@ Locales ['sv'] = { - ['valid_purchase'] = 'bekräfta köp?', - ['yes'] = 'ja (%s SEK)', - ['no'] = 'nej', - ['helmet'] = 'hjälm / hat', - ['glasses'] = 'glasögon', - ['mask'] = 'ansiktsmask', - ['ears'] = 'örontillbehör', - ['shop'] = '%s affär', - ['set_unset'] = 'ta på / av', - ['not_enough_money'] = 'du har inte råd!', - ['press_access'] = 'tryck ~INPUT_CONTEXT~ för att öppna menyn.', - ['accessories_blip'] = 'extrautröstning', - ['no_ears'] = 'du har inga öron tillbehör', - ['no_glasses'] = 'du har inga glasögon', - ['no_helmet'] = 'du har ingen hjälm', - ['no_mask'] = 'du har inte någon mask', - ['you_paid'] = 'du har betalat ~g~%s SEK~s~', + ['valid_purchase'] = 'bekräfta köp?', + ['yes'] = 'ja (%s SEK)', + ['no'] = 'nej', + ['helmet'] = 'hjälm / hat', + ['glasses'] = 'glasögon', + ['mask'] = 'ansiktsmask', + ['ears'] = 'örontillbehör', + ['shop'] = '%s affär', + ['set_unset'] = 'ta på / av', + ['not_enough_money'] = 'du har inte råd!', + ['press_access'] = 'tryck ~INPUT_CONTEXT~ för att öppna menyn.', + ['accessories_blip'] = 'extrautröstning', + ['no_ears'] = 'du har inga öron tillbehör', + ['no_glasses'] = 'du har inga glasögon', + ['no_helmet'] = 'du har ingen hjälm', + ['no_mask'] = 'du har inte någon mask', + ['you_paid'] = 'du har betalat ~g~%s SEK~s~', } diff --git a/server/main.lua b/server/main.lua index 6c674ae2..83d1d255 100644 --- a/server/main.lua +++ b/server/main.lua @@ -7,7 +7,7 @@ AddEventHandler('esx_accessories:pay', function() local xPlayer = ESX.GetPlayerFromId(source) xPlayer.removeMoney(Config.Price) - TriggerClientEvent('esx:showNotification', source, _U('you_paid', Config.Price)) + TriggerClientEvent('esx:showNotification', source, _U('you_paid', ESX.Math.GroupDigits(Config.Price))) end) RegisterServerEvent('esx_accessories:save') From c54723289adc5b9aecc240992da4fef6ecd5a692 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 5 Nov 2018 13:57:04 +0100 Subject: [PATCH 1879/3224] Revert "fix for removing glasses (#11)" This reverts commit 2028350a9593c7b7acea1ace34653d6301691b25. --- client/main.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index a2cd0716..aa0ff237 100644 --- a/client/main.lua +++ b/client/main.lua @@ -56,8 +56,6 @@ function SetUnsetAccessory(accessory) if _accessory == "mask" then mAccessory = 0 - elseif _accessory == "glasses" then - mAccessory = 5 end if skin[_accessory .. '_1'] == mAccessory then From ed591192e7e0aa564a99561e1609e9a70a8ec1aa Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 5 Nov 2018 20:17:02 +0100 Subject: [PATCH 1880/3224] Enforced 4 tab indent on sql files --- esx_jobs.sql | 68 ++++++++++++++++++------------------ localization/br_esx_jobs.sql | 68 ++++++++++++++++++------------------ localization/de_esx_jobs.sql | 68 ++++++++++++++++++------------------ localization/en_esx_jobs.sql | 68 ++++++++++++++++++------------------ localization/fi_esx_jobs.sql | 68 ++++++++++++++++++------------------ localization/sv_esx_jobs.sql | 68 ++++++++++++++++++------------------ 6 files changed, 204 insertions(+), 204 deletions(-) diff --git a/esx_jobs.sql b/esx_jobs.sql index 79234905..ed88e1aa 100644 --- a/esx_jobs.sql +++ b/esx_jobs.sql @@ -1,47 +1,47 @@ USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES - ('caution', 'Caution', 0) + ('caution', 'Caution', 0) ; INSERT INTO `jobs` (name, label) VALUES - ('slaughterer', 'Abatteur'), - ('fisherman', 'Pêcheur'), - ('miner', 'Mineur'), - ('lumberjack', 'Bûcheron'), - ('fueler', 'Raffineur'), - ('reporter', 'Journaliste'), - ('tailor', 'Couturier') + ('slaughterer', 'Abatteur'), + ('fisherman', 'Pêcheur'), + ('miner', 'Mineur'), + ('lumberjack', 'Bûcheron'), + ('fueler', 'Raffineur'), + ('reporter', 'Journaliste'), + ('tailor', 'Couturier') ; INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES - ('lumberjack', 0, 'employee', 'Intérimaire', 0, '{}', '{}'), - ('fisherman', 0, 'employee', 'Intérimaire', 0, '{}', '{}'), - ('fueler', 0, 'employee', 'Intérimaire', 0, '{}', '{}'), - ('reporter', 0, 'employee', 'Intérimaire', 0, '{}', '{}'), - ('tailor',0,'employee','Intérimaire',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}'), - ('miner', 0, 'employee', 'Intérimaire', 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}', '{}'), - ('slaughterer',0,'employee','Intérimaire',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}') + ('lumberjack', 0, 'employee', 'Intérimaire', 0, '{}', '{}'), + ('fisherman', 0, 'employee', 'Intérimaire', 0, '{}', '{}'), + ('fueler', 0, 'employee', 'Intérimaire', 0, '{}', '{}'), + ('reporter', 0, 'employee', 'Intérimaire', 0, '{}', '{}'), + ('tailor',0,'employee','Intérimaire',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}'), + ('miner', 0, 'employee', 'Intérimaire', 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}', '{}'), + ('slaughterer',0,'employee','Intérimaire',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}') ; INSERT INTO `items` (`name`, `label`, `limit`) VALUES - ('alive_chicken', 'Poulet vivant', 20), - ('slaughtered_chicken', 'Poulet abattu', 20), - ('packaged_chicken', 'Poulet en barquette', 100), - ('fish', 'Poisson', 100), - ('stone', 'Pierre', 7), - ('washed_stone', 'Pierre Lavée', 7), - ('copper', 'Cuivre', 56), - ('iron', 'Fer', 42), - ('gold', 'Or', 21), - ('diamond', 'Diamant', 50), - ('wood', 'Bois', 20), - ('cutted_wood', 'Bois coupé', 20), - ('packaged_plank', 'Paquet de planches', 100), - ('petrol', 'Pétrole', 24), - ('petrol_raffin', 'Pétrole Raffiné', 24), - ('essence', 'Essence', 24), - ('wool', 'Laine', 40), - ('fabric', 'Tissu', 80), - ('clothe', 'Vêtement', 40) + ('alive_chicken', 'Poulet vivant', 20), + ('slaughtered_chicken', 'Poulet abattu', 20), + ('packaged_chicken', 'Poulet en barquette', 100), + ('fish', 'Poisson', 100), + ('stone', 'Pierre', 7), + ('washed_stone', 'Pierre Lavée', 7), + ('copper', 'Cuivre', 56), + ('iron', 'Fer', 42), + ('gold', 'Or', 21), + ('diamond', 'Diamant', 50), + ('wood', 'Bois', 20), + ('cutted_wood', 'Bois coupé', 20), + ('packaged_plank', 'Paquet de planches', 100), + ('petrol', 'Pétrole', 24), + ('petrol_raffin', 'Pétrole Raffiné', 24), + ('essence', 'Essence', 24), + ('wool', 'Laine', 40), + ('fabric', 'Tissu', 80), + ('clothe', 'Vêtement', 40) ; diff --git a/localization/br_esx_jobs.sql b/localization/br_esx_jobs.sql index 33c65b47..7892cbc6 100644 --- a/localization/br_esx_jobs.sql +++ b/localization/br_esx_jobs.sql @@ -1,47 +1,47 @@ USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES - ('caution', 'Deposito', 0) + ('caution', 'Deposito', 0) ; INSERT INTO `jobs` (name, label) VALUES - ('slaughterer', 'Abatedor'), - ('fisherman', 'Pescador'), - ('miner', 'Minerador'), - ('lumberjack', 'Lenhador'), - ('fueler', 'Refinador'), - ('reporter', 'Jornalista'), - ('tailor', 'Costureiro') + ('slaughterer', 'Abatedor'), + ('fisherman', 'Pescador'), + ('miner', 'Minerador'), + ('lumberjack', 'Lenhador'), + ('fueler', 'Refinador'), + ('reporter', 'Jornalista'), + ('tailor', 'Costureiro') ; INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES - ('lumberjack', 0, 'employee', 'Temporario', 0, '{}', '{}'), - ('fisherman', 0, 'employee', 'Temporario', 0, '{}', '{}'), - ('fueler', 0, 'employee', 'Temporario', 0, '{}', '{}'), - ('reporter', 0, 'employee', 'Temporario', 0, '{}', '{}'), - ('tailor',0, 'employee','Temporario',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}'), - ('miner', 0, 'employee', 'Temporario', 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}', '{}'), - ('slaughterer',0,'employee','Temporario',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}') + ('lumberjack', 0, 'employee', 'Temporario', 0, '{}', '{}'), + ('fisherman', 0, 'employee', 'Temporario', 0, '{}', '{}'), + ('fueler', 0, 'employee', 'Temporario', 0, '{}', '{}'), + ('reporter', 0, 'employee', 'Temporario', 0, '{}', '{}'), + ('tailor',0, 'employee','Temporario',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}'), + ('miner', 0, 'employee', 'Temporario', 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}', '{}'), + ('slaughterer',0,'employee','Temporario',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}') ; INSERT INTO `items` (`name`, `label`) VALUES - ('alive_chicken', 'Frango Vivo', 20), - ('slaughtered_chicken', 'Frango Abatido', 20), - ('packaged_chicken', 'Frango na Bandeja', 100), - ('fish', 'Peixe', 100), - ('stone', 'Pedra', 7), - ('washed_stone', 'Pedra Limpa', 7), - ('copper', 'Cobre', 56), - ('iron', 'Ferro', 42), - ('gold', 'Ouro', 21), - ('diamond', 'Diamante', 50), - ('wood', 'Madeira', 20), - ('cutted_wood', 'Madeira Cortada', 20), - ('packaged_plank', 'Tábua Embalada', 100), - ('petrol', 'Petroleo', 24), - ('petrol_raffin', 'Petroleo Refinado', 24), - ('essence', 'Gasolina', 24), - ('wool', 'Lã', 40), - ('fabric', 'Tecido', 80), - ('clothe', 'Roupa', 40) + ('alive_chicken', 'Frango Vivo', 20), + ('slaughtered_chicken', 'Frango Abatido', 20), + ('packaged_chicken', 'Frango na Bandeja', 100), + ('fish', 'Peixe', 100), + ('stone', 'Pedra', 7), + ('washed_stone', 'Pedra Limpa', 7), + ('copper', 'Cobre', 56), + ('iron', 'Ferro', 42), + ('gold', 'Ouro', 21), + ('diamond', 'Diamante', 50), + ('wood', 'Madeira', 20), + ('cutted_wood', 'Madeira Cortada', 20), + ('packaged_plank', 'Tábua Embalada', 100), + ('petrol', 'Petroleo', 24), + ('petrol_raffin', 'Petroleo Refinado', 24), + ('essence', 'Gasolina', 24), + ('wool', 'Lã', 40), + ('fabric', 'Tecido', 80), + ('clothe', 'Roupa', 40) ; diff --git a/localization/de_esx_jobs.sql b/localization/de_esx_jobs.sql index ee32b926..2e68f197 100644 --- a/localization/de_esx_jobs.sql +++ b/localization/de_esx_jobs.sql @@ -1,47 +1,47 @@ USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES - ('caution', 'Caution', 0) + ('caution', 'Caution', 0) ; INSERT INTO `jobs` (name, label) VALUES - ('slaughterer', 'Schlachterei'), - ('fisherman', 'Fischerei'), - ('miner', 'Bergbau'), - ('lumberjack', 'Holzbetrieb'), - ('fueler', 'Raffinerie'), - ('reporter', 'Kanal 7'), - ('tailor', 'Schneiderei') + ('slaughterer', 'Schlachterei'), + ('fisherman', 'Fischerei'), + ('miner', 'Bergbau'), + ('lumberjack', 'Holzbetrieb'), + ('fueler', 'Raffinerie'), + ('reporter', 'Kanal 7'), + ('tailor', 'Schneiderei') ; INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES - ('lumberjack', 0, 'employee', 'Mitarbeiter', 0, '{}', '{}'), - ('fisherman', 0, 'employee', 'Mitarbeiter', 0, '{}', '{}'), - ('fueler', 0, 'employee', 'Mitarbeiter', 0, '{}', '{}'), - ('reporter', 0, 'employee', 'Mitarbeiter', 0, '{}', '{}'), - ('tailor', 0, 'employee', 'Mitarbeiter', 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}'), - ('miner', 0, 'employee', 'Mitarbeiter', 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}', '{}'), - ('slaughterer',0,'employee','Mitarbeiter', 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}') + ('lumberjack', 0, 'employee', 'Mitarbeiter', 0, '{}', '{}'), + ('fisherman', 0, 'employee', 'Mitarbeiter', 0, '{}', '{}'), + ('fueler', 0, 'employee', 'Mitarbeiter', 0, '{}', '{}'), + ('reporter', 0, 'employee', 'Mitarbeiter', 0, '{}', '{}'), + ('tailor', 0, 'employee', 'Mitarbeiter', 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}'), + ('miner', 0, 'employee', 'Mitarbeiter', 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}', '{}'), + ('slaughterer',0,'employee','Mitarbeiter', 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}') ; INSERT INTO `items` (`name`, `label`, `limit`) VALUES - ('alive_chicken', 'lebendes Huhn', 20), - ('slaughtered_chicken', 'geschlachtetes Huhn', 20), - ('packaged_chicken', 'Hähnchenfilet', 100), - ('fish', 'Fisch', 100), - ('stone', 'Felsbrocken', 7), - ('washed_stone', 'gewaschener Felsbrocken', 7), - ('copper', 'Kupfer', 56), - ('iron', 'Eisen', 42), - ('gold', 'Gold', 21), - ('diamond', 'Diamant', 50), - ('wood', 'Holz', 20), - ('cutted_wood', 'Holzstämme', 20), - ('packaged_plank', 'Bretterpaket', 100), - ('petrol', 'Öl', 24), - ('petrol_raffin', 'bearbeitetes Öl', 24), - ('essence', 'Benzin', 24), - ('whool', 'Wolle', 40), - ('fabric', 'Tuch', 80), - ('clothe', 'Kleidung', 40) + ('alive_chicken', 'lebendes Huhn', 20), + ('slaughtered_chicken', 'geschlachtetes Huhn', 20), + ('packaged_chicken', 'Hähnchenfilet', 100), + ('fish', 'Fisch', 100), + ('stone', 'Felsbrocken', 7), + ('washed_stone', 'gewaschener Felsbrocken', 7), + ('copper', 'Kupfer', 56), + ('iron', 'Eisen', 42), + ('gold', 'Gold', 21), + ('diamond', 'Diamant', 50), + ('wood', 'Holz', 20), + ('cutted_wood', 'Holzstämme', 20), + ('packaged_plank', 'Bretterpaket', 100), + ('petrol', 'Öl', 24), + ('petrol_raffin', 'bearbeitetes Öl', 24), + ('essence', 'Benzin', 24), + ('whool', 'Wolle', 40), + ('fabric', 'Tuch', 80), + ('clothe', 'Kleidung', 40) ; diff --git a/localization/en_esx_jobs.sql b/localization/en_esx_jobs.sql index c9aad07e..89cd925f 100644 --- a/localization/en_esx_jobs.sql +++ b/localization/en_esx_jobs.sql @@ -1,47 +1,47 @@ USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES - ('caution', 'caution', 0) + ('caution', 'caution', 0) ; INSERT INTO `jobs` (name, label) VALUES - ('slaughterer', 'Butcher'), - ('fisherman', 'Fisherman'), - ('miner', 'Miner'), - ('lumberjack', 'Lumberjack'), - ('fueler', 'Fueler'), - ('reporter', 'Reporter'), - ('tailor', 'Tailor') + ('slaughterer', 'Butcher'), + ('fisherman', 'Fisherman'), + ('miner', 'Miner'), + ('lumberjack', 'Lumberjack'), + ('fueler', 'Fueler'), + ('reporter', 'Reporter'), + ('tailor', 'Tailor') ; INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES - ('lumberjack', 0, 'employee', 'Employee', 0, '{}', '{}'), - ('fisherman', 0, 'employee', 'Employee', 0, '{}', '{}'), - ('fueler', 0, 'employee', 'Employee', 0, '{}', '{}'), - ('reporter', 0, 'employee', 'Employee', 0, '{}', '{}'), - ('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}'), - ('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}', '{}'), - ('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}') + ('lumberjack', 0, 'employee', 'Employee', 0, '{}', '{}'), + ('fisherman', 0, 'employee', 'Employee', 0, '{}', '{}'), + ('fueler', 0, 'employee', 'Employee', 0, '{}', '{}'), + ('reporter', 0, 'employee', 'Employee', 0, '{}', '{}'), + ('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}'), + ('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}', '{}'), + ('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}') ; INSERT INTO `items` (`name`, `label`, `limit`) VALUES - ('alive_chicken', 'living chicken', 20), - ('slaughtered_chicken', 'slaughtered chicken', 20), - ('packaged_chicken', 'chicken fillet', 100), - ('fish', 'fish', 100), - ('stone', 'stone', 7), - ('washed_stone', 'washed stone', 7), - ('copper', 'copper', 56), - ('iron', 'iron', 42), - ('gold', 'gold', 21), - ('diamond', 'diamond', 50), - ('wood', 'wood', 20), - ('cutted_wood', 'cut wood', 20), - ('packaged_plank', 'packaged wood', 100), - ('petrol', 'oil', 24), - ('petrol_raffin', 'processed oil', 24), - ('essence', 'gas', 24), - ('wool', 'wool', 40), - ('fabric', 'fabric', 80), - ('clothe', 'cloth', 40) + ('alive_chicken', 'living chicken', 20), + ('slaughtered_chicken', 'slaughtered chicken', 20), + ('packaged_chicken', 'chicken fillet', 100), + ('fish', 'fish', 100), + ('stone', 'stone', 7), + ('washed_stone', 'washed stone', 7), + ('copper', 'copper', 56), + ('iron', 'iron', 42), + ('gold', 'gold', 21), + ('diamond', 'diamond', 50), + ('wood', 'wood', 20), + ('cutted_wood', 'cut wood', 20), + ('packaged_plank', 'packaged wood', 100), + ('petrol', 'oil', 24), + ('petrol_raffin', 'processed oil', 24), + ('essence', 'gas', 24), + ('wool', 'wool', 40), + ('fabric', 'fabric', 80), + ('clothe', 'cloth', 40) ; diff --git a/localization/fi_esx_jobs.sql b/localization/fi_esx_jobs.sql index 5859b3cd..8a751f3c 100644 --- a/localization/fi_esx_jobs.sql +++ b/localization/fi_esx_jobs.sql @@ -1,47 +1,47 @@ USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES - ('caution', 'caution', 0) + ('caution', 'caution', 0) ; INSERT INTO `jobs` (name, label) VALUES - ('slaughterer', 'Teurastaja'), - ('fisherman', 'Kalastaja'), - ('miner', 'Kaivostyöläinen'), - ('lumberjack', 'Metsuri'), - ('fueler', 'Öljynjalostaja'), - ('reporter', 'Journalisti'), - ('tailor', 'Räätäli') + ('slaughterer', 'Teurastaja'), + ('fisherman', 'Kalastaja'), + ('miner', 'Kaivostyöläinen'), + ('lumberjack', 'Metsuri'), + ('fueler', 'Öljynjalostaja'), + ('reporter', 'Journalisti'), + ('tailor', 'Räätäli') ; INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES - ('lumberjack', 0, 'interim', 'Työläinen', 0, '{}', '{}'), - ('fisherman', 0, 'interim', 'Työläinen', 0, '{}', '{}'), - ('fueler', 0, 'interim', 'Työläinen', 0, '{}', '{}'), - ('reporter', 0, 'employee', 'Työläinen', 0, '{}', '{}'), - ('tailor', 0, 'interim', 'Työläinen', 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}'), - ('miner', 0, 'interim', 'Työläinen', 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}', '{}'), - ('slaughterer', 0, 'interim', 'Työläinen', 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}') + ('lumberjack', 0, 'interim', 'Työläinen', 0, '{}', '{}'), + ('fisherman', 0, 'interim', 'Työläinen', 0, '{}', '{}'), + ('fueler', 0, 'interim', 'Työläinen', 0, '{}', '{}'), + ('reporter', 0, 'employee', 'Työläinen', 0, '{}', '{}'), + ('tailor', 0, 'interim', 'Työläinen', 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}'), + ('miner', 0, 'interim', 'Työläinen', 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}', '{}'), + ('slaughterer', 0, 'interim', 'Työläinen', 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}') ; INSERT INTO `items` (`name`, `label`, `limit`) VALUES - ('alive_chicken', 'Elävä kana', 20), - ('slaughtered_chicken', 'Teurastettu kana', 20), - ('packaged_chicken', 'Kananfilee', 100), - ('fish', 'Kala', 100), - ('stone', 'Kivi', 7), - ('washed_stone', 'Puhdistettu Kivi', 7), - ('copper', 'Kupari', 56), - ('iron', 'Rauta', 42), - ('gold', 'Kulta', 21), - ('diamond', 'Timantti', 50), - ('wood', 'Puu', 20), - ('cutted_wood', 'Pilkottu Puu', 20), - ('packaged_plank', 'Paketoitu Lankku', 100), - ('petrol', 'Öljy', 24), - ('petrol_raffin', 'Prosessoitu Öljy', 24), - ('essence', 'Polttoöljy', 24), - ('wool', 'Villa', 40), - ('fabric', 'Kangas', 80), - ('clothe', 'Vaate', 40) + ('alive_chicken', 'Elävä kana', 20), + ('slaughtered_chicken', 'Teurastettu kana', 20), + ('packaged_chicken', 'Kananfilee', 100), + ('fish', 'Kala', 100), + ('stone', 'Kivi', 7), + ('washed_stone', 'Puhdistettu Kivi', 7), + ('copper', 'Kupari', 56), + ('iron', 'Rauta', 42), + ('gold', 'Kulta', 21), + ('diamond', 'Timantti', 50), + ('wood', 'Puu', 20), + ('cutted_wood', 'Pilkottu Puu', 20), + ('packaged_plank', 'Paketoitu Lankku', 100), + ('petrol', 'Öljy', 24), + ('petrol_raffin', 'Prosessoitu Öljy', 24), + ('essence', 'Polttoöljy', 24), + ('wool', 'Villa', 40), + ('fabric', 'Kangas', 80), + ('clothe', 'Vaate', 40) ; diff --git a/localization/sv_esx_jobs.sql b/localization/sv_esx_jobs.sql index c9a5a71a..7116073a 100644 --- a/localization/sv_esx_jobs.sql +++ b/localization/sv_esx_jobs.sql @@ -1,47 +1,47 @@ USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES - ('caution', 'caution', 0) + ('caution', 'caution', 0) ; INSERT INTO `jobs` (name, label) VALUES - ('slaughterer', 'Slaktare'), - ('fisherman', 'Fiskare'), - ('miner', 'Gruvarbetare'), - ('lumberjack', 'Skogshuggare'), - ('fueler', 'Bensintankare'), - ('reporter', 'Reporter'), - ('tailor', 'Skräddare') + ('slaughterer', 'Slaktare'), + ('fisherman', 'Fiskare'), + ('miner', 'Gruvarbetare'), + ('lumberjack', 'Skogshuggare'), + ('fueler', 'Bensintankare'), + ('reporter', 'Reporter'), + ('tailor', 'Skräddare') ; INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES - ('lumberjack', 0, 'employee', 'Anställd', 0, '{}', '{}'), - ('fisherman', 0, 'employee', 'Anställd', 0, '{}', '{}'), - ('fueler', 0, 'employee', 'Anställd', 0, '{}', '{}'), - ('reporter', 0, 'employee', 'Anställd', 0, '{}', '{}'), - ('tailor', 0, 'employee', 'Anställd', 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}'), - ('miner', 0, 'employee', 'Anställd', 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}', '{}'), - ('slaughterer', 0, 'employee', 'Anställd', 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}') + ('lumberjack', 0, 'employee', 'Anställd', 0, '{}', '{}'), + ('fisherman', 0, 'employee', 'Anställd', 0, '{}', '{}'), + ('fueler', 0, 'employee', 'Anställd', 0, '{}', '{}'), + ('reporter', 0, 'employee', 'Anställd', 0, '{}', '{}'), + ('tailor', 0, 'employee', 'Anställd', 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}'), + ('miner', 0, 'employee', 'Anställd', 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}', '{}'), + ('slaughterer', 0, 'employee', 'Anställd', 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}') ; INSERT INTO `items` (`name`, `label`, `limit`) VALUES - ('alive_chicken', 'levande kyckling', 20), - ('slaughtered_chicken', 'slaktad kyckling', 20), - ('packaged_chicken', 'paketerad kyckling', 100), - ('fish', 'fisk', 100), - ('stone', 'sten', 7), - ('washed_stone', 'tvättad sten', 7), - ('copper', 'coppar', 56), - ('iron', 'järn', 42), - ('gold', 'guld', 21), - ('diamond', 'diamant', 50), - ('wood', 'trä', 20), - ('cutted_wood', 'sågat trä', 20), - ('packaged_plank', 'paketerad trä', 100), - ('petrol', 'olja', 24), - ('petrol_raffin', 'bearbetad olja', 24), - ('essence', 'gas', 24), - ('wool', 'ull', 40), - ('fabric', 'tyg', 80), - ('clothe', 'kläde', 40) + ('alive_chicken', 'levande kyckling', 20), + ('slaughtered_chicken', 'slaktad kyckling', 20), + ('packaged_chicken', 'paketerad kyckling', 100), + ('fish', 'fisk', 100), + ('stone', 'sten', 7), + ('washed_stone', 'tvättad sten', 7), + ('copper', 'coppar', 56), + ('iron', 'järn', 42), + ('gold', 'guld', 21), + ('diamond', 'diamant', 50), + ('wood', 'trä', 20), + ('cutted_wood', 'sågat trä', 20), + ('packaged_plank', 'paketerad trä', 100), + ('petrol', 'olja', 24), + ('petrol_raffin', 'bearbetad olja', 24), + ('essence', 'gas', 24), + ('wool', 'ull', 40), + ('fabric', 'tyg', 80), + ('clothe', 'kläde', 40) ; From b50650db542c7feb991aa2a48f3c71919ea32145 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 5 Nov 2018 20:31:57 +0100 Subject: [PATCH 1881/3224] Corrected number grouping --- client/main.lua | 4 ++-- server/main.lua | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/main.lua b/client/main.lua index aac235c5..b9ceb88c 100644 --- a/client/main.lua +++ b/client/main.lua @@ -44,7 +44,7 @@ function OpenBuyLicenseMenu(zone) ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'shop_license', { title = _U('buy_license'), elements = { - { label = _U('yes', ('%s'):format(ESX.Math.GroupDigits(_U('shop_menu_item', Config.LicensePrice)))), value = 'yes' }, + { label = _U('yes', ('%s'):format((_U('shop_menu_item', ESX.Math.GroupDigits(Config.LicensePrice)))), value = 'yes' }, { label = _U('no'), value = 'no' } } }, function(data, menu) @@ -64,7 +64,7 @@ function OpenShopMenu(zone) local item = Config.Zones[zone].Items[i] table.insert(elements, { - label = ('%s - %s'):format(item.label, ESX.Math.GroupDigits(_U('shop_menu_item', item.price))), + label = ('%s - %s'):format(item.label, _U('shop_menu_item', ESX.Math.GroupDigits(item.price))), weaponName = item.item }) end diff --git a/server/main.lua b/server/main.lua index ba6e5ba8..aa2978e1 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,4 +1,4 @@ -ESX = nil +ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) From 04e35bb78c0b79db193c560f4186e72ba818d921 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 5 Nov 2018 22:44:25 +0100 Subject: [PATCH 1882/3224] Resolved #33 --- client/main.lua | 172 ++++++++++++++++++------------------------------ locales/br.lua | 1 - locales/en.lua | 1 - locales/fi.lua | 1 - locales/fr.lua | 1 - locales/sv.lua | 1 - server/main.lua | 66 ++++++------------- 7 files changed, 86 insertions(+), 157 deletions(-) diff --git a/client/main.lua b/client/main.lua index f27eff4a..ad994a26 100644 --- a/client/main.lua +++ b/client/main.lua @@ -10,31 +10,24 @@ local Keys = { ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 } -local PlayerData = {} -local menuIsShowed = false -local hintIsShowed = false +local PlayerData = {} +local menuIsShowed = false +local hintIsShowed = false local hasAlreadyEnteredMarker = false -local Blips = {} -local JobBlips = {} +local Blips = {} +local JobBlips = {} +local isInMarker = false +local isInPublicMarker = false -local collectedItem = nil -local collectedQtty = 0 -local isInMarker = false -local isInPublicMarker = false +local hintToDisplay = "no hint to display" +local onDuty = false +local spawner = 0 +local myPlate = {} -local hintToDisplay = "no hint to display" -local onDuty = false -local spawner = 0 -local myPlate = {} -local isJobVehicleDestroyed = false +local vehicleObjInCaseofDrop = nil +local vehicleInCaseofDrop = nil -local cautionVehicleInCaseofDrop = 0 -local maxCautionVehicleInCaseofDrop = 0 -local vehicleObjInCaseofDrop = nil -local vehicleInCaseofDrop = nil -local vehicleHashInCaseofDrop = nil -local vehicleMaxHealthInCaseofDrop = nil -local vehicleOldHealthInCaseofDrop = nil +local vehicleMaxHealth = nil ESX = nil @@ -55,7 +48,6 @@ end) RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) PlayerData = xPlayer - TriggerServerEvent('esx_jobs:giveBackCautionInCaseOfDrop') refreshBlips() end) @@ -75,7 +67,6 @@ function OpenMenu() ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin) TriggerEvent('skinchanger:loadSkin', skin) end) - elseif data.current.value == 'job_wear' then onDuty = true ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) @@ -129,11 +120,7 @@ AddEventHandler('esx_jobs:action', function(job, zone) end if ESX.Game.IsSpawnPointClear(spawnPoint.Pos, 5.0) then - TriggerServerEvent('esx_jobs:setCautionInCaseOfDrop', zone.Caution) - cautionVehicleInCaseofDrop = zone.Caution - maxCautionVehicleInCaseofDrop = cautionVehicleInCaseofDrop - - spawnVehicle(spawnPoint, vehicle) + spawnVehicle(spawnPoint, vehicle, zone.Caution) else ESX.ShowNotification(_U('spawn_blocked')) end @@ -146,37 +133,45 @@ AddEventHandler('esx_jobs:action', function(job, zone) for l,w in pairs(v.Zones) do if w.Type == "vehdelete" and w.Spawner == zone.Spawner then local playerPed = PlayerPedId() + if IsPedInAnyVehicle(playerPed, false) then - local vehicle = GetVehiclePedIsIn(playerPed, 0) + + local vehicle = GetVehiclePedIsIn(playerPed, false) local plate = GetVehicleNumberPlateText(vehicle) plate = string.gsub(plate, " ", "") local driverPed = GetPedInVehicleSeat(vehicle, -1) - for i=1, #myPlate, 1 do - if myPlate[i] == plate and playerPed == driverPed then - TriggerServerEvent('esx_jobs:caution', "give_back", cautionVehicleInCaseofDrop, 0, 0) - DeleteVehicle(GetVehiclePedIsIn(playerPed, 0)) + if playerPed == driverPed then - if w.Teleport ~= 0 then - SetEntityCoords(PlayerPedId(), w.Teleport.x, w.Teleport.y, w.Teleport.z) + for i=1, #myPlate, 1 do + if myPlate[i] == plate then + + local vehicleHealth = GetVehicleEngineHealth(vehicleInCaseofDrop) + local giveBack = ESX.Math.Round(vehicleHealth / vehicleMaxHealth, 2) + + TriggerServerEvent('esx_jobs:caution', "give_back", giveBack, 0, 0) + DeleteVehicle(GetVehiclePedIsIn(playerPed, false)) + + if w.Teleport ~= 0 then + ESX.Game.Teleport(playerPed, w.Teleport) + end + + table.remove(myPlate, i) + + if vehicleObjInCaseofDrop.HasCaution then + vehicleInCaseofDrop = nil + vehicleObjInCaseofDrop = nil + vehicleMaxHealth = nil + end + + break end - - table.remove(myPlate, i) - - if vehicleObjInCaseofDrop.HasCaution then - cautionVehicleInCaseofDrop = 0 - maxCautionVehicleInCaseofDrop = 0 - vehicleInCaseofDrop = nil - vehicleHashInCaseofDrop = nil - vehicleMaxHealthInCaseofDrop = nil - vehicleOldHealthInCaseofDrop = nil - vehicleObjInCaseofDrop = nil - TriggerServerEvent('esx_jobs:setCautionInCaseOfDrop', 0) - end - - break end + + else + ESX.ShowNotification(_U('not_your_vehicle')) end + end looping = false @@ -231,7 +226,6 @@ AddEventHandler('esx:setJob', function(job) PlayerData.job = job onDuty = false myPlate = {} -- loosing vehicle caution in case player changes job. - isJobVehicleDestroyed = false spawner = 0 deleteBlips() refreshBlips() @@ -276,10 +270,10 @@ function refreshBlips() end end -function spawnVehicle(spawnPoint, vehicle) - hintToDisplay = "no hint to display" +function spawnVehicle(spawnPoint, vehicle, vehicleCaution) + hintToDisplay = 'no hint to display' hintIsShowed = false - TriggerServerEvent('esx_jobs:caution', "take", cautionVehicleInCaseofDrop, spawnPoint, vehicle) + TriggerServerEvent('esx_jobs:caution', 'take', vehicleCaution, spawnPoint, vehicle) end RegisterNetEvent('esx_jobs:spawnJobVehicle') @@ -301,14 +295,11 @@ AddEventHandler('esx_jobs:spawnJobVehicle', function(spawnPoint, vehicle) plate = string.gsub(plate, " ", "") TaskWarpPedIntoVehicle(playerPed, spawnedVehicle, -1) - isJobVehicleDestroyed = false if vehicle.HasCaution then vehicleInCaseofDrop = spawnedVehicle - vehicleHashInCaseofDrop = vehicle.Hash vehicleObjInCaseofDrop = vehicle - vehicleMaxHealthInCaseofDrop = GetEntityMaxHealth(spawnedVehicle) - vehicleOldHealthInCaseofDrop = vehicleMaxHealthInCaseofDrop + vehicleMaxHealth = GetVehicleEngineHealth(spawnedVehicle) end end) end) @@ -317,6 +308,7 @@ end) Citizen.CreateThread(function() while true do Citizen.Wait(10) + if hintIsShowed then ESX.ShowHelpNotification(hintToDisplay) else @@ -367,18 +359,18 @@ end) Citizen.CreateThread(function() while true do Citizen.Wait(10) - local coords = GetEntityCoords(PlayerPedId()) - local position = nil - local zone = nil + local coords = GetEntityCoords(PlayerPedId()) + local position = nil + local zone = nil for k,v in pairs(Config.PublicZones) do - if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then + if GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x then isInPublicMarker = true position = v.Teleport zone = v break else - isInPublicMarker = false + isInPublicMarker = false end end @@ -450,21 +442,21 @@ Citizen.CreateThread(function() local playerPed = PlayerPedId() if IsPedInAnyVehicle(playerPed, false) then - local vehicle = GetVehiclePedIsIn(playerPed) + local vehicle = GetVehiclePedIsIn(playerPed, false) local driverPed = GetPedInVehicleSeat(vehicle, -1) - local isVehicleOwner = false local plate = GetVehicleNumberPlateText(vehicle) plate = string.gsub(plate, " ", "") - for i=1, #myPlate, 1 do - if myPlate[i] == plate and playerPed == driverPed then - hintToDisplay = _U('security_deposit', zone.Hint, cautionVehicleInCaseofDrop) - isVehicleOwner = true - break - end - end + if playerPed == driverPed then - if not isVehicleOwner then + for i=1, #myPlate, 1 do + if myPlate[i] == plate then + hintToDisplay = zone.Hint + break + end + end + + else hintToDisplay = _U('not_your_vehicle') end else @@ -495,40 +487,6 @@ Citizen.CreateThread(function() end end) --- Vehicle caution -Citizen.CreateThread(function() - while true do - Citizen.Wait(0) - if vehicleInCaseofDrop ~= nil then - if onDuty and IsVehicleModel(vehicleInCaseofDrop, vehicleHashInCaseofDrop) then - local vehicleHealth = GetEntityHealth(vehicleInCaseofDrop) - - if vehicleOldHealthInCaseofDrop ~= vehicleHealth then - local cautionValue = 0 - vehicleOldHealthInCaseofDrop = vehicleHealth - if vehicleHealth == vehicleMaxHealthInCaseofDrop then - cautionValue = maxCautionVehicleInCaseofDrop - cautionVehicleInCaseofDrop = cautionValue - else - local healthPct = (vehicleHealth * 100) / vehicleMaxHealthInCaseofDrop - local damagePct = 100 - healthPct - cautionValue = math.ceil(cautionVehicleInCaseofDrop - cautionVehicleInCaseofDrop * damagePct * 2.5 / 100) - if cautionValue < 0 then - cautionValue = 0 - elseif cautionValue >= cautionVehicleInCaseofDrop then - cautionValue = cautionVehicleInCaseofDrop - end - cautionVehicleInCaseofDrop = cautionValue - end - TriggerServerEvent('esx_jobs:setCautionInCaseOfDrop', cautionValue) - end - end - else - Citizen.Wait(1000) - end - end -end) - Citizen.CreateThread(function() -- Slaughterer RemoveIpl("CS1_02_cf_offmission") diff --git a/locales/br.lua b/locales/br.lua index 7cc81de9..feff893a 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -8,7 +8,6 @@ Locales['br'] = { ['bank_deposit_taken'] = 'um depósito de segurança de ~g~$%s~s~ foi tirado de você.', ['foot_work'] = 'você deve estar a pé para poder trabalhar.', ['next_point'] = 'vá para o próximo passo depois de completar este.', - ['security_deposit'] = '%s \nA segurança dada será ~g~$%s~s~', ['not_your_vehicle'] = 'este não é o seu veículo ou você deve ser um motorista.', ['in_vehicle'] = 'você deve estar em um veículo.', ['wrong_point'] = 'você não está no ponto certo de entrega.', diff --git a/locales/en.lua b/locales/en.lua index f3e6ba99..2e1c948d 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -8,7 +8,6 @@ Locales['en'] = { ['bank_deposit_taken'] = 'a security deposit of ~r~$%s~s~ was taken from you.', ['foot_work'] = 'you have to be on foot to be able to work.', ['next_point'] = 'go to the next step after completing this one.', - ['security_deposit'] = '%s \nYou will be given ~g~$%s~s~', ['not_your_vehicle'] = 'this is not your vehicle or you must be a driver.', ['in_vehicle'] = 'you must sit in a vehicle.', ['wrong_point'] = 'you are not at the right point of delivery.', diff --git a/locales/fi.lua b/locales/fi.lua index 9c125b14..2d84df38 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -8,7 +8,6 @@ Locales['fi'] = { ['bank_deposit_taken'] = 'vakuuden summa ~r~€%s~s~ otettiin sinulta.', ['foot_work'] = 'sinun täytyy olla jalan, jotta voit työskennellä', ['next_point'] = 'mene seuraavaan pisteeseen kun olet valmis täällä', - ['security_deposit'] = '%s \nVakuus joka annetaan on ~g~€%s~s~', ['not_your_vehicle'] = 'tämä ei ole sinun ajoneuvo tai et ole sen kuski', ['in_vehicle'] = 'sinun täytyy olla ajoneuvossa', ['wrong_point'] = 'et ole oikeassa paikassa', diff --git a/locales/fr.lua b/locales/fr.lua index ea600acb..d7a9d443 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -8,7 +8,6 @@ Locales['fr'] = { ['bank_deposit_taken'] = 'une caution de ~g~$%s~s~ vous a été prélevée.', ['foot_work'] = 'vous devez être à pied pour pouvoir travailler.', ['next_point'] = 'rendez-vous à la prochaine étape après avoir complété celle-ci.', - ['security_deposit'] = '%s \nLa caution rendue sera de ~g~$%s~s~', ['not_your_vehicle'] = 'ce n\'est pas votre véhicule ou vous devez être conducteur.', ['in_vehicle'] = 'vous devez être dans un véhicule.', ['wrong_point'] = 'vous n\'êtes pas au bon point de livraison.', diff --git a/locales/sv.lua b/locales/sv.lua index feb98659..2d0c451f 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -8,7 +8,6 @@ Locales['sv'] = { ['bank_deposit_taken'] = 'en deposition på ~r~%s SEK~s~ togs från dig.', ['foot_work'] = 'du måste vara till fots för att kunna arbeta.', ['next_point'] = 'gå till nästa steg efter att du har avslutat här.', - ['security_deposit'] = '%s \nDu kommer få tillbaka ~g~%s SEK~s~', ['not_your_vehicle'] = 'det här är inte ditt fordon eller så måste du vara föraren.', ['in_vehicle'] = 'du måste sitta i ett fordon!', ['wrong_point'] = 'du är inte på rätt leveranspunkt!', diff --git a/server/main.lua b/server/main.lua index 880d3a03..cded8b57 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,46 +1,8 @@ local PlayersWorking = {} -local Players = {} - ESX = nil + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) -AddEventHandler('esx:playerLoaded', function(source) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) - xPlayer.set('caution', 0) -end) - -AddEventHandler('esx:playerDropped', function(source) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) - local caution = xPlayer.get('caution') - TriggerEvent('esx_addonaccount:getAccount', 'caution', xPlayer.identifier, function(account) - account.addMoney(caution) - end) -end) - -RegisterServerEvent('esx_jobs:setCautionInCaseOfDrop') -AddEventHandler('esx_jobs:setCautionInCaseOfDrop', function(caution) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) - xPlayer.set('caution', caution) -end) - -RegisterServerEvent('esx_jobs:giveBackCautionInCaseOfDrop') -AddEventHandler('esx_jobs:giveBackCautionInCaseOfDrop', function() - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) - - TriggerEvent('esx_addonaccount:getAccount', 'caution', xPlayer.identifier, function(account) - local caution = account.money - account.removeMoney(caution) - if caution > 0 then - xPlayer.addAccountMoney('bank', caution) - TriggerClientEvent('esx:showNotification', _source, _U('bank_deposit_returned', caution)) - end - end) -end) - local function Work(source, item) SetTimeout(item[1].time, function() @@ -117,13 +79,27 @@ AddEventHandler('esx_jobs:caution', function(cautionType, cautionAmount, spawnPo local xPlayer = ESX.GetPlayerFromId(source) if cautionType == "take" then - xPlayer.removeAccountMoney('bank', cautionAmount) - xPlayer.set('caution', cautionAmount) - TriggerClientEvent('esx:showNotification', source, _U('bank_deposit_taken', cautionAmount)) + TriggerEvent('esx_addonaccount:getAccount', 'caution', xPlayer.identifier, function(account) + xPlayer.removeAccountMoney('bank', cautionAmount) + account.addMoney(cautionAmount) + end) + + TriggerClientEvent('esx:showNotification', source, _U('bank_deposit_taken', ESX.Math.GroupDigits(cautionAmount))) TriggerClientEvent('esx_jobs:spawnJobVehicle', source, spawnPoint, vehicle) elseif cautionType == "give_back" then - xPlayer.addAccountMoney('bank', cautionAmount) - xPlayer.set('caution', 0) - TriggerClientEvent('esx:showNotification', source, _U('bank_deposit_returned', cautionAmount)) + + if cautionAmount > 1 then + print(('esx_jobs: %s is using cheat engine!'):format(xPlayer.identifier)) + return + end + + TriggerEvent('esx_addonaccount:getAccount', 'caution', xPlayer.identifier, function(account) + local caution = account.money + local toGive = ESX.Math.Round(caution * cautionAmount) + + xPlayer.addAccountMoney('bank', toGive) + account.removeMoney(toGive) + TriggerClientEvent('esx:showNotification', source, _U('bank_deposit_returned', ESX.Math.GroupDigits(toGive))) + end) end end) From b0364a35f287354dd95dc9e110cf79a0402185fd Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 5 Nov 2018 22:55:33 +0100 Subject: [PATCH 1883/3224] Proper js formatting --- html/js/app.js | 165 ++++++++++++++++++++++--------------------------- 1 file changed, 75 insertions(+), 90 deletions(-) diff --git a/html/js/app.js b/html/js/app.js index 5a8f882a..c3c5f52d 100644 --- a/html/js/app.js +++ b/html/js/app.js @@ -20,26 +20,31 @@ ESX_MENU.focus = []; ESX_MENU.pos = {}; - ESX_MENU.open = function(namespace, name, data){ + ESX_MENU.open = function(namespace, name, data) { - if(typeof ESX_MENU.opened[namespace] == 'undefined') + if (typeof ESX_MENU.opened[namespace] == 'undefined') { ESX_MENU.opened[namespace] = {}; + } - if(typeof ESX_MENU.opened[namespace][name] != 'undefined') + if (typeof ESX_MENU.opened[namespace][name] != 'undefined') { ESX_MENU.close(namespace, name); + } - if(typeof ESX_MENU.pos[namespace] == 'undefined') + if (typeof ESX_MENU.pos[namespace] == 'undefined') { ESX_MENU.pos[namespace] = {}; + } - for(let i=0; i { - switch(data.action){ + switch (data.action) { - case 'openMenu' : { + case 'openMenu': { ESX_MENU.open(data.namespace, data.name, data.data); break; } - case 'closeMenu' : { + case 'closeMenu': { ESX_MENU.close(data.namespace, data.name); break; } - case 'controlPressed' : { + case 'controlPressed': { - switch(data.control){ - - case 'ENTER' : { + switch (data.control) { + case 'ENTER': { let focused = ESX_MENU.getFocused(); - if(typeof focused != 'undefined') { - + if (typeof focused != 'undefined') { let menu = ESX_MENU.opened[focused.namespace][focused.name]; let pos = ESX_MENU.pos[focused.namespace][focused.name]; let elem = menu.elements[pos]; - if(menu.elements.length > 0) + if (menu.elements.length > 0) { ESX_MENU.submit(focused.namespace, focused.name, elem); - + } } break; } - case 'BACKSPACE' : { - + case 'BACKSPACE': { let focused = ESX_MENU.getFocused(); - if(typeof focused != 'undefined') { - + if (typeof focused != 'undefined') { ESX_MENU.cancel(focused.namespace, focused.name); - } break; } - case 'TOP' : { + case 'TOP': { let focused = ESX_MENU.getFocused(); - if(typeof focused != 'undefined') { + if (typeof focused != 'undefined') { - let menu = ESX_MENU.opened[focused.namespace][focused.name]; - let pos = ESX_MENU.pos[focused.namespace][focused.name]; + let menu = ESX_MENU.opened[focused.namespace][focused.name]; + let pos = ESX_MENU.pos[focused.namespace][focused.name]; - if(pos > 0) + if (pos > 0) { ESX_MENU.pos[focused.namespace][focused.name]--; - else + } else { ESX_MENU.pos[focused.namespace][focused.name] = menu.elements.length - 1; + } let elem = menu.elements[ESX_MENU.pos[focused.namespace][focused.name]]; - for(let i=0; i min){ + if (elem.value > min) { elem.value--; ESX_MENU.change(focused.namespace, focused.name, elem); } ESX_MENU.render(); - break; } default: break; - } $('#menu_' + focused.namespace + '_' + focused.name).find('.menu-item.selected')[0].scrollIntoView(); - } break; @@ -321,39 +312,33 @@ let focused = ESX_MENU.getFocused(); - if(typeof focused != 'undefined') { - - let menu = ESX_MENU.opened[focused.namespace][focused.name]; - let pos = ESX_MENU.pos[focused.namespace][focused.name]; - let elem = menu.elements[pos]; - - switch(elem.type){ + if (typeof focused != 'undefined') { + let menu = ESX_MENU.opened[focused.namespace][focused.name]; + let pos = ESX_MENU.pos[focused.namespace][focused.name]; + let elem = menu.elements[pos]; + switch(elem.type) { case 'default': break; - case 'slider' : { - - if(typeof elem.options != 'undefined' && elem.value < elem.options.length - 1){ + case 'slider': { + if (typeof elem.options != 'undefined' && elem.value < elem.options.length - 1) { elem.value++; ESX_MENU.change(focused.namespace, focused.name, elem); } - if(typeof elem.max != 'undefined' && elem.value < elem.max){ + if (typeof elem.max != 'undefined' && elem.value < elem.max) { elem.value++; ESX_MENU.change(focused.namespace, focused.name, elem); } ESX_MENU.render(); - break; } default: break; - } $('#menu_' + focused.namespace + '_' + focused.name).find('.menu-item.selected')[0].scrollIntoView(); - } break; From 23ef814d82730a599124e5f9e3db7ca6605c4ecb Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 6 Nov 2018 20:10:55 +0100 Subject: [PATCH 1884/3224] Push forgotten resource metadata, closes #156 --- __resource.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/__resource.lua b/__resource.lua index 7e2f587c..3826fd4d 100644 --- a/__resource.lua +++ b/__resource.lua @@ -55,6 +55,7 @@ client_scripts { 'client/modules/scaleform.lua', 'client/modules/streaming.lua', + 'shared/modules/math.lua', 'shared/functions.lua' } From 6633258f77e1f7d0c5e54a5da1f30865bf4bff95 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 7 Nov 2018 21:30:30 +0100 Subject: [PATCH 1885/3224] Fixed #11, update esx_property too! --- client/main.lua | 4 ++-- server/main.lua | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/client/main.lua b/client/main.lua index 7b835239..70195f0c 100644 --- a/client/main.lua +++ b/client/main.lua @@ -63,7 +63,7 @@ function OpenRealestateAgentMenu() OpenCustomersMenu() elseif data.current.value == 'boss_actions' then TriggerEvent('esx_society:openBossMenu', 'realestateagent', function(data, menu) - menu.close() + menu.close() end) end @@ -183,7 +183,7 @@ function OpenCustomersMenu() data = customers[i], cols = { customers[i].name, - customers[i].propertyName, + customers[i].propertyLabel, (customers[i].propertyRented and _U('rent') or _U('sell')), _U('contract') } diff --git a/server/main.lua b/server/main.lua index 6d805555..2cc6eed5 100644 --- a/server/main.lua +++ b/server/main.lua @@ -56,7 +56,8 @@ ESX.RegisterServerCallback('esx_realestateagentjob:getCustomers', function(sourc propertyRented = properties[i].rented, propertyId = properties[i].id, propertyPrice = properties[i].price, - propertyName = properties[i].name + propertyName = properties[i].name, + propertyLabel = properties[i].label }) end end From cd5f72e28d8833240241321fe82e5d3c590e5780 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 7 Nov 2018 21:30:56 +0100 Subject: [PATCH 1886/3224] Get property label too --- server/main.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/server/main.lua b/server/main.lua index 27f53b8b..f5acb377 100644 --- a/server/main.lua +++ b/server/main.lua @@ -132,6 +132,7 @@ AddEventHandler('esx_ownedproperty:getOwnedProperties', function(cb) table.insert(properties, { id = result[i].id, name = result[i].name, + label = GetProperty(result[i].name).label, price = result[i].price, rented = (result[i].rented == 1 and true or false), owner = result[i].owner From edf40ed57d567e85f72cd836dbeb63a7392ad7ec Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 7 Nov 2018 21:35:23 +0100 Subject: [PATCH 1887/3224] Fixed #13 --- locales/sv.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/sv.lua b/locales/sv.lua index fb4e0f79..6ced172c 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -6,10 +6,10 @@ Locales['sv'] = { ['amount_withdraw'] = 'summa', ['invalid_amount'] = 'ogiltigt belopp', ['press_to_access'] = 'tryck ~INPUT_CONTEXT~ för att öppna menyn.', - ['property_actions'] = '{{Assign [Köp]|Köp}} {{Assign [Hyra]|Hyra}} {{GPS|gps}}', + ['property_actions'] = '{{Sälj fastighet|sell}} {Hyr ut fastighet|rent}} {{GPS|gps}}', ['amount'] = 'summa', ['no_play_near'] = 'det finns inga spelare i närheten!', - ['contract'] = '{{Ta bort kontrakt|Ta bort}} {{GPS|gps}}', + ['contract'] = '{{Återkalla kontrakt|revoke}} {{GPS|gps}}', ['rent'] = 'hyra', ['sell'] = 'sälj', ['realtors'] = 'mäklare', From 4a90d6fac93f707cc745e60619fcce6cd910e7f7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 7 Nov 2018 21:58:24 +0100 Subject: [PATCH 1888/3224] Added missing translatable strings --- client/main.lua | 11 ++++++----- locales/br.lua | 37 +++++++++++++++++++++++-------------- locales/de.lua | 33 +++++++++++++++++++++------------ locales/en.lua | 19 ++++++++++++++----- locales/fi.lua | 19 ++++++++++++++----- locales/fr.lua | 19 ++++++++++++++----- locales/sv.lua | 21 +++++++++++++++------ 7 files changed, 107 insertions(+), 52 deletions(-) diff --git a/client/main.lua b/client/main.lua index 70195f0c..e48a38f8 100644 --- a/client/main.lua +++ b/client/main.lua @@ -54,6 +54,7 @@ function OpenRealestateAgentMenu() ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'realestateagent', { title = _U('realtor'), + align = 'top-left', elements = elements }, function(data, menu) @@ -81,7 +82,7 @@ function OpenPropertyMenu() TriggerEvent('esx_property:getProperties', function(properties) local elements = { - head = {_U('property'), 'Actions'}, + head = {_U('property_name'), _U('property_actions')}, rows = {} } @@ -90,7 +91,7 @@ function OpenPropertyMenu() data = properties[i], cols = { properties[i].label, - _U('property_actions') + _U('property_actionbuttons') } }) end @@ -174,7 +175,7 @@ end function OpenCustomersMenu() ESX.TriggerServerCallback('esx_realestateagentjob:getCustomers', function(customers) local elements = { - head = {'Client', _U('property'), 'Type', 'Actions'}, + head = {_U('customer_client'), _U('customer_property'), _U('customer_agreement'), _U('customer_actions')}, rows = {} } @@ -184,8 +185,8 @@ function OpenCustomersMenu() cols = { customers[i].name, customers[i].propertyLabel, - (customers[i].propertyRented and _U('rent') or _U('sell')), - _U('contract') + (customers[i].propertyRented and _U('customer_rent') or _U('customer_sell')), + _U('customer_contractbuttons') } }) end diff --git a/locales/br.lua b/locales/br.lua index 46e8d94c..0f4fd156 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,17 +1,26 @@ Locales['br'] = { - ['properties'] = 'Propriedades', - ['property'] = 'Propriedade', - ['clients'] = 'Clientes', - ['realtor'] = 'Corretor de imóveis', - ['amount_withdraw'] = 'Quantidade de retirada', - ['invalid_amount'] = 'Quantidade inválida', - ['press_to_access'] = 'Pressione ~INPUT_CONTEXT~ para abrir o menu', - ['property_actions'] = '{{Assign [Sell]|sell}} {{Assign [Rent]|rent}} {{GPS|gps}}', - ['amount'] = 'Quantidade', - ['no_play_near'] = 'Nenhum jogador nas proximidades', - ['contract'] = '{{Revoke contract|revoke}} {{GPS|gps}}', - ['rent'] = 'Alugar', - ['sell'] = 'Vender', - ['realtors'] = 'Agente Imobiliário', + ['properties'] = 'propriedades', + ['clients'] = 'clientes', + ['realtor'] = 'corretor de imóveis', + ['amount_withdraw'] = 'quantidade de retirada', + ['invalid_amount'] = 'quantidade inválida', + ['press_to_access'] = 'pressione ~INPUT_CONTEXT~ para abrir o menu', + ['amount'] = 'quantidade', + ['no_play_near'] = 'nenhum jogador nas proximidades', + ['realtors'] = 'agente Imobiliário', ['boss_action'] = 'boss Actions', + + -- Property menu + ['property_name'] = 'propriedade', + ['property_actions'] = 'actions', + ['property_actionbuttons'] = '{{Assign [Sell]|sell}} {{Assign [Rent]|rent}} {{GPS|gps}}', + + -- Customer menu + ['customer_client'] = 'clientes', + ['customer_property'] = 'propriedade', + ['customer_agreement'] = 'agreement', + ['customer_actions'] = 'actions', + ['customer_contractbuttons'] = '{{Revoke contract|revoke}} {{GPS|gps}}', + ['customer_rent'] = 'alugar', + ['customer_sell'] = 'vender', } diff --git a/locales/de.lua b/locales/de.lua index 50be0920..e66d0f0c 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -1,17 +1,26 @@ Locales['de'] = { ['properties'] = 'Immobilien', - ['property'] = 'Immobilie', - ['clients'] = 'Kunden', - ['realtor'] = 'Makler', - ['amount_withdraw'] = 'Betrag zun abheben', + ['clients'] = 'kunden', + ['realtor'] = 'makler', + ['amount_withdraw'] = 'betrag zun abheben', ['invalid_amount'] = 'ungültiger Betrag', - ['press_to_access'] = 'Drücke ~INPUT_CONTEXT~ um das Menü zu öffnen', - ['property_actions'] = '{{Zuweisen [Verkaufen]|sell}} {{Zuweisen [Vermieten]|rent}} {{GPS|gps}}', - ['amount'] = 'Betrag', - ['no_play_near'] = 'Kein Spieler in der Nähe', - ['contract'] = '{{Revoke contract|revoke}} {{GPS|gps}}', - ['rent'] = 'Mieten', - ['sell'] = 'Verkaufen', - ['realtors'] = 'Makler', + ['press_to_access'] = 'drücke ~INPUT_CONTEXT~ um das Menü zu öffnen', + ['amount'] = 'betrag', + ['no_play_near'] = 'kein Spieler in der Nähe', + ['realtors'] = 'makler', ['boss_action'] = 'boss Actions', + + -- Property menu + ['property_name'] = 'immobilie', + ['property_actions'] = 'actions', + ['property_actionbuttons'] = '{{Zuweisen [Verkaufen]|sell}} {{Zuweisen [Vermieten]|rent}} {{GPS|gps}}', + + -- Customer menu + ['customer_client'] = 'kunden', + ['customer_property'] = 'immobilie', + ['customer_agreement'] = 'agreement', + ['customer_actions'] = 'actions', + ['customer_contractbuttons'] = '{{Revoke contract|revoke}} {{GPS|gps}}', + ['customer_rent'] = 'mieten', + ['customer_sell'] = 'verkaufen', } diff --git a/locales/en.lua b/locales/en.lua index 54e5f377..42e5b608 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,17 +1,26 @@ Locales['en'] = { ['properties'] = 'properties', - ['property'] = 'property', ['clients'] = 'clients', ['realtor'] = 'real Estate Agent', ['amount_withdraw'] = 'amount of withdrawal', ['invalid_amount'] = 'invalid amount', ['press_to_access'] = 'press ~INPUT_CONTEXT~ to access the menu', - ['property_actions'] = '{{Assign [Sell]|sell}} {{Assign [Rent]|rent}} {{GPS|gps}}', ['amount'] = 'amount', ['no_play_near'] = 'no players nearby', - ['contract'] = '{{Revoke contract|revoke}} {{GPS|gps}}', - ['rent'] = 'rent', - ['sell'] = 'sell', ['realtors'] = 'real Estate Agents', ['boss_action'] = 'boss Actions', + + -- Property menu + ['property_name'] = 'property', + ['property_actions'] = 'actions', + ['property_actionbuttons'] = '{{Assign [Sell]|sell}} {{Assign [Rent]|rent}} {{GPS|gps}}', + + -- Customer menu + ['customer_client'] = 'client', + ['customer_property'] = 'property', + ['customer_agreement'] = 'agreement', + ['customer_actions'] = 'actions', + ['customer_contractbuttons'] = '{{Revoke contract|revoke}} {{GPS|gps}}', + ['customer_rent'] = 'rented', + ['customer_sell'] = 'sold', } diff --git a/locales/fi.lua b/locales/fi.lua index 1d293904..eeaa552c 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -1,17 +1,26 @@ Locales['fi'] = { ['properties'] = 'kiinteistöt', - ['property'] = 'kiinteistö', ['clients'] = 'asiakkaat', ['realtor'] = 'kiinteistövälittäjä', ['amount_withdraw'] = 'nostettava määrä', ['invalid_amount'] = 'virheellinen summa', ['press_to_access'] = 'paina ~INPUT_CONTEXT~ avataksesi menu', - ['property_actions'] = '{{Aseta [Myy]|sell}} {{Aseta [Vuokraa]|rent}} {{GPS|gps}}', ['amount'] = 'määrä', ['no_play_near'] = 'ei pelaajia lähettyvillä', - ['contract'] = '{{Pura sopimus|revoke}} {{GPS|gps}}', - ['rent'] = 'vuokraa', - ['sell'] = 'myy', ['realtors'] = 'Kiinteistövälitys', ['boss_action'] = 'pomo Toiminnot', + + -- Property menu + ['property_name'] = 'kiinteistö', + ['property_actions'] = 'actions', + ['property_actionbuttons'] = '{{Aseta [Myy]|sell}} {{Aseta [Vuokraa]|rent}} {{GPS|gps}}', + + -- Customer menu + ['customer_client'] = 'client', + ['customer_property'] = 'kiinteistö', + ['customer_agreement'] = 'agreement', + ['customer_actions'] = 'actions', + ['customer_contractbuttons'] = '{{Pura sopimus|revoke}} {{GPS|gps}}', + ['customer_rent'] = 'vuokraa', + ['customer_sell'] = 'myy', } diff --git a/locales/fr.lua b/locales/fr.lua index 6e66c57d..006d97a9 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,17 +1,26 @@ Locales['fr'] = { ['properties'] = 'propriétés', - ['property'] = 'propriété', ['clients'] = 'clients', ['realtor'] = 'agent Immobilier', ['amount_withdraw'] = 'montant du retrait', ['invalid_amount'] = 'montant invalide', ['press_to_access'] = 'appuez sur ~INPUT_CONTEXT~ pour accéder au menu', - ['property_actions'] = '{{Assigner [Vente]|sell}} {{Assigner [Location]|rent}} {{GPS|gps}}', ['amount'] = 'montant', ['no_play_near'] = 'aucun joueur à proximité', - ['contract'] = '{{Révoquer contrat|revoke}} {{GPS|gps}}', - ['rent'] = 'location', - ['sell'] = 'vente', ['realtors'] = 'agents Immobilier', ['boss_action'] = 'action Patron', + + -- Property menu + ['property_name'] = 'propriété', + ['property_actions'] = 'actions', + ['property_actionbuttons'] = '{{Assigner [Vente]|sell}} {{Assigner [Location]|rent}} {{GPS|gps}}', + + -- Customer menu + ['customer_client'] = 'client', + ['customer_property'] = 'propriété', + ['customer_agreement'] = 'agreement', + ['customer_actions'] = 'actions', + ['customer_contractbuttons'] = '{{Révoquer contrat|revoke}} {{GPS|gps}}', + ['customer_rent'] = 'location', + ['customer_sell'] = 'vente', } diff --git a/locales/sv.lua b/locales/sv.lua index 6ced172c..2cf3d418 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -1,17 +1,26 @@ Locales['sv'] = { ['properties'] = 'fastigheter', - ['property'] = 'fastighet', ['clients'] = 'klienter', ['realtor'] = 'mäklare', ['amount_withdraw'] = 'summa', ['invalid_amount'] = 'ogiltigt belopp', ['press_to_access'] = 'tryck ~INPUT_CONTEXT~ för att öppna menyn.', - ['property_actions'] = '{{Sälj fastighet|sell}} {Hyr ut fastighet|rent}} {{GPS|gps}}', ['amount'] = 'summa', ['no_play_near'] = 'det finns inga spelare i närheten!', - ['contract'] = '{{Återkalla kontrakt|revoke}} {{GPS|gps}}', - ['rent'] = 'hyra', - ['sell'] = 'sälj', ['realtors'] = 'mäklare', ['boss_action'] = 'chefmeny', -} \ No newline at end of file + + -- Property menu + ['property_name'] = 'fastighet', + ['property_actions'] = 'åtgärder', + ['property_actionbuttons'] = '{{Sälj fastighet|sell}} {{Hyr ut fastighet|rent}} {{GPS|gps}}', + + -- Customer menu + ['customer_client'] = 'client', + ['customer_property'] = 'fastighet', + ['customer_agreement'] = 'överenskommelse', + ['customer_actions'] = 'åtgärder', + ['customer_contractbuttons'] = '{{Återkalla kontrakt|revoke}} {{GPS|gps}}', + ['customer_rent'] = 'hyrd', + ['customer_sell'] = 'såld', +} From 092adc0578805671477aed71ba7f8ea0789f8e6f Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 8 Nov 2018 21:33:39 +0100 Subject: [PATCH 1889/3224] Removed un-needed assets, closes #14 --- client/main.lua | 23 ++++++++++------------- stream/v_15_shrm_glass1.ydr | Bin 878 -> 0 bytes stream/v_carshowroom.ybn | Bin 35063 -> 0 bytes stream/v_int_15.ytyp | Bin 11886 -> 0 bytes 4 files changed, 10 insertions(+), 13 deletions(-) delete mode 100644 stream/v_15_shrm_glass1.ydr delete mode 100644 stream/v_carshowroom.ybn delete mode 100644 stream/v_int_15.ytyp diff --git a/client/main.lua b/client/main.lua index bc5d6b2a..4f2a81f9 100644 --- a/client/main.lua +++ b/client/main.lua @@ -982,7 +982,7 @@ Citizen.CreateThread(function () end) -- Key controls -Citizen.CreateThread(function () +Citizen.CreateThread(function() while true do Citizen.Wait(10) @@ -998,7 +998,7 @@ Citizen.CreateThread(function () elseif CurrentAction == 'reseller_menu' then OpenResellerMenu() elseif CurrentAction == 'give_back_vehicle' then - ESX.TriggerServerCallback('esx_vehicleshop:giveBackVehicle', function (isRentedVehicle) + ESX.TriggerServerCallback('esx_vehicleshop:giveBackVehicle', function(isRentedVehicle) if isRentedVehicle then ESX.Game.DeleteVehicle(CurrentActionData.vehicle) ESX.ShowNotification(_U('delivered')) @@ -1007,7 +1007,7 @@ Citizen.CreateThread(function () end end, GetVehicleNumberPlateText(CurrentActionData.vehicle)) elseif CurrentAction == 'resell_vehicle' then - ESX.TriggerServerCallback('esx_vehicleshop:resellVehicle', function (isOwnedVehicle) + ESX.TriggerServerCallback('esx_vehicleshop:resellVehicle', function(isOwnedVehicle) if isOwnedVehicle then ESX.Game.DeleteVehicle(CurrentActionData.vehicle) ESX.ShowNotification(_U('vehicle_sold')) @@ -1025,14 +1025,11 @@ Citizen.CreateThread(function () end end) --- Load IPLS -Citizen.CreateThread(function () - RemoveIpl('v_carshowroom') - RemoveIpl('shutter_open') - RemoveIpl('shutter_closed') - RemoveIpl('shr_int') - RemoveIpl('csr_inMission') - RequestIpl('v_carshowroom') - RequestIpl('shr_int') - RequestIpl('shutter_closed') +Citizen.CreateThread(function() + RequestIpl('shr_int') -- Load walls and floor + + local interiorID = 7170 + LoadInterior(interiorID) + EnableInteriorProp(interiorID, 'csr_beforeMission') -- Load large window + RefreshInterior(interiorID) end) diff --git a/stream/v_15_shrm_glass1.ydr b/stream/v_15_shrm_glass1.ydr deleted file mode 100644 index 506aeed9e4904dc54441a5227d6e8d0aa5bc9dfd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 878 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%0A$<{Y6Ed^Kjs2^yn4*|7OiK#dZr`Ve+m!2s5E$F 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 I4#*V#158wB$N&HU diff --git a/stream/v_int_15.ytyp b/stream/v_int_15.ytyp deleted file mode 100644 index a78a172b6b1a1974725f9d3101abd0f86b762096..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11886 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%0A_3vgv zh_|nuBcM;_PCjCj%Q9X8ye)5%CV$Pa7m`%gPP%0`cqbZQr-}u30)?7NhHG(BQ&)=_ zHCumbu_!pBT9A?L#M<{ba0p8?ss$qy{L2e}qx+XsoL0j(y!H1piGzU2LGNMY;4#>S zw*{t_s33(Q9m-*}cKZT>@lLms-KLK`rgV9;LGu}(HcJqD@J>I(enA}ft=Bc2Ckaed zA-_o;Hk06B_Lbo{!t2 zW@bKmLg9tjO5*of?%AG(GZXD9N?i#L%y072Y)lZ}Uw1tmG{KwP=Z$x8{g*ODmsMSD*tePnKR7b{1PUciQ<#f zw|@h9O9!i5DUU*tA_IA9E}ch^esF@Y`@Wl`{J>1OS683%rzLkY_=#8_w~LjRc#p5( zf1vAEb~96V$T_V@R(YGDEoI=4#dp3r^Z9gS z#EVsNz-rz_q2~tn5G$;euDw_Ery8eV70PszqeQ=b|I^in=Tm2(CRH*BRgL+yPwXWW z?pP1L_-YP!YmkF(c2}N>>8jA*j>TiJ8(qc2ej1c}wB7;r^k$pF`5;X7=iCr;g*a68 z2|ZtHWA@2_R}FrQKa`ypae-C{?FXv4Jz;S49Fu93w{TCQojem^}A zB6(6EL)_9{v&eDe^zD^-!vTpTY5143J?AY(6fXW+VYFR@f~woA-~-GlH1pU|+H^Wf zDbWqV1Vv4A&-MNBEPha9mr~(=lK3v7@TzOh1&CUFzs}OkY?J_O^%Q3S`}f!-G~x@J z_0z#mxh}aj<=;3AxVoPfv}4%9eY$i?a|GyrUH^)aSy>i+EYjel|4r6*ATh*`=@Nr^Vc?NjRb3!*3bD xnZ4Act##5uSx^$40zYX`a7=Y!)f!|mt%1X8`MzzejJH^M$N%jIKrR5({|nrXd~E;# From fc1920a474d94613adc7f994f3ab2df87ac18a2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rychl=C3=BD?= Date: Fri, 9 Nov 2018 16:57:11 +0100 Subject: [PATCH 1890/3224] Czech diacritic temp remove Solves https://github.com/rp-esx-fivem/esx_joblisting/issues/2 --- locales/cs.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/locales/cs.lua b/locales/cs.lua index aaa5aef3..d089e3fb 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -1,7 +1,7 @@ Locales['cs'] = { - ['new_job'] = 'máte novou práci!', - ['access_job_center'] = 'zmáčkněte ~INPUT_PICKUP~ pro přístup na ~b~Úřad práce~s~.', - ['job_center'] = 'úřad práce', + ['new_job'] = 'mate novou praci!', + ['access_job_center'] = 'stiskni ~INPUT_PICKUP~ pro pristup na ~b~Urad prace~s~.', + ['job_center'] = 'Urad prace', } From a93361737ddea828959f802ca318903e8a2cb532 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 9 Nov 2018 22:18:39 +0100 Subject: [PATCH 1891/3224] Fixed #92 --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 2a66b62c..649f4ae3 100644 --- a/server/main.lua +++ b/server/main.lua @@ -131,7 +131,7 @@ AddEventHandler('esx_ambulancejob:giveItem', function(itemName) if xPlayer.job.name ~= 'ambulance' then print(('esx_ambulancejob: %s attempted to spawn in an item!'):format(xPlayer.identifier)) return - elseif itemName ~= 'medikit' or itemName ~= 'bandage' then + elseif (itemName ~= 'medikit' and itemName ~= 'bandage') then print(('esx_ambulancejob: %s attempted to spawn in an item!'):format(xPlayer.identifier)) return end From 22b77b8d927f9818c03f8b29f148f8653dd5fc1d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 9 Nov 2018 22:32:09 +0100 Subject: [PATCH 1892/3224] Fixed pharmacy color --- locales/br.lua | 2 +- locales/en.lua | 2 +- locales/es.lua | 2 +- locales/fi.lua | 2 +- locales/fr.lua | 2 +- locales/pl.lua | 2 +- locales/sv.lua | 4 ++-- server/main.lua | 4 +++- 8 files changed, 11 insertions(+), 9 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index 2d7db462..cc22645d 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -30,7 +30,7 @@ Locales['br'] = { ['fast_travel'] = 'Aperte ~INPUT_CONTEXT~ para mover-se rapidamente.', ['open_pharmacy'] = 'Aperte ~INPUT_CONTEXT~ para abrir a farmácia.', ['pharmacy_menu_title'] = 'Farmácia', - ['pharmacy_take'] = 'tomar ~y~%s~s~', + ['pharmacy_take'] = 'tomar %s', ['medikit'] = 'Seringa', ['bandage'] = 'Vendagem', ['max_item'] = 'você já carrega o suficiente sobre você.', diff --git a/locales/en.lua b/locales/en.lua index 053012f2..ca1b0d39 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -30,7 +30,7 @@ Locales['en'] = { ['fast_travel'] = 'press ~INPUT_CONTEXT~ to fast travel.', ['open_pharmacy'] = 'press ~INPUT_CONTEXT~ to open the pharmacy.', ['pharmacy_menu_title'] = 'pharmacy', - ['pharmacy_take'] = 'take ~y~%s~s~', + ['pharmacy_take'] = 'take %s', ['medikit'] = 'medikit', ['bandage'] = 'bandage', ['max_item'] = 'You are already carrying enough.', diff --git a/locales/es.lua b/locales/es.lua index df241022..aea37cb3 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -30,7 +30,7 @@ Locales['es'] = { ['fast_travel'] = 'Press ~INPUT_CONTEXT~ to fast travel.', ['open_pharmacy'] = 'Press ~INPUT_CONTEXT~ to open the pharmacy.', ['pharmacy_menu_title'] = 'Pharmacy', - ['pharmacy_take'] = 'take ~y~%s~s~', + ['pharmacy_take'] = 'take %s', ['medikit'] = 'medikit', ['bandage'] = 'bandage', ['max_item'] = 'You are already carrying enough on yourself.', diff --git a/locales/fi.lua b/locales/fi.lua index d474c1f5..841e6a89 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -30,7 +30,7 @@ Locales['fi'] = { ['fast_travel'] = 'paina ~INPUT_CONTEXT~ liikkuaksesi nopeasti kerrosten välillä', ['open_pharmacy'] = 'paina ~INPUT_CONTEXT~ avataksesi lääkekaappi', ['pharmacy_menu_title'] = 'lääkekaappi', - ['pharmacy_take'] = 'ota ~y~%s~s~', + ['pharmacy_take'] = 'ota %s', ['medikit'] = 'ensiapupakkauksia', ['bandage'] = 'sideharsoja', ['max_item'] = 'sinulla on jo tarpeeksi mukana', diff --git a/locales/fr.lua b/locales/fr.lua index 3dc156b1..cfc249db 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -30,7 +30,7 @@ Locales['fr'] = { ['fast_travel'] = 'appuyez sur ~INPUT_CONTEXT~ pour vous déplacer rapidement.', ['open_pharmacy'] = 'appuyez sur ~INPUT_CONTEXT~ pour ouvrir la pharmacie.', ['pharmacy_menu_title'] = 'Pharmacie', - ['pharmacy_take'] = 'prendre ~y~%s~s~', + ['pharmacy_take'] = 'prendre %s', ['medikit'] = 'kit de soin', ['bandage'] = 'bandage', ['max_item'] = 'vous en portez déjà assez sur vous.', diff --git a/locales/pl.lua b/locales/pl.lua index e301f8b4..6d523288 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -30,7 +30,7 @@ Locales['pl'] = { ['fast_travel'] = 'naciśnij na ~INPUT_CONTEXT~ do szybkiej podróży.', ['open_pharmacy'] = 'naciśnij na ~INPUT_CONTEXT~ aby otworzyć aptekę', ['pharmacy_menu_title'] = 'apteka', - ['pharmacy_take'] = 'weź ~y~%s~s~', + ['pharmacy_take'] = 'weź %s', ['medikit'] = 'apteczka', ['bandage'] = 'bandaż', ['max_item'] = 'już masz na sobie dość.', diff --git a/locales/sv.lua b/locales/sv.lua index 7097678f..ea7abf73 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -23,14 +23,14 @@ Locales['sv'] = { -- Boss Menu ['boss_actions'] = 'chef meny', -- Misc - ['invalid_amount'] = '~r~ogiltig mängd', + ['invalid_amount'] = '~r~Ogiltig mängd', ['open_menu'] = 'tryck ~INPUT_CONTEXT~ för att öppna menyn.', ['deposit_amount'] = 'mängd att sätta in', ['money_withdraw'] = 'mängd att ta ut', ['fast_travel'] = 'tryck på ~INPUT_CONTEXT~ för att snabbresa.', ['open_pharmacy'] = 'tryck på ~INPUT_CONTEXT~ för att öppna apoteket.', ['pharmacy_menu_title'] = 'apotek', - ['pharmacy_take'] = 'ta ~y~%s~s~', + ['pharmacy_take'] = 'ta %s', ['medikit'] = 'medicinkit', ['bandage'] = 'bandage', ['max_item'] = 'du har redan tillräckligt mycket på dig.', diff --git a/server/main.lua b/server/main.lua index 649f4ae3..e2f86711 100644 --- a/server/main.lua +++ b/server/main.lua @@ -137,8 +137,8 @@ AddEventHandler('esx_ambulancejob:giveItem', function(itemName) end local xItem = xPlayer.getInventoryItem(itemName) - local count = 1 + if xItem.limit ~= -1 then count = xItem.limit - xItem.count end @@ -167,6 +167,7 @@ ESX.RegisterUsableItem('medikit', function(source) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) xPlayer.removeInventoryItem('medikit', 1) + TriggerClientEvent('esx_ambulancejob:heal', _source, 'big') TriggerClientEvent('esx:showNotification', _source, _U('used_medikit')) end) @@ -175,6 +176,7 @@ ESX.RegisterUsableItem('bandage', function(source) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) xPlayer.removeInventoryItem('bandage', 1) + TriggerClientEvent('esx_ambulancejob:heal', _source, 'small') TriggerClientEvent('esx:showNotification', _source, _U('used_bandage')) end) From aedd4132cdd83794f2842fd88ecdb5d340b07229 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 9 Nov 2018 23:38:00 +0100 Subject: [PATCH 1893/3224] Only select what we need --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index a3ab6237..9bcf75f9 100644 --- a/server/main.lua +++ b/server/main.lua @@ -129,7 +129,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) -- Get job name, grade and last position table.insert(tasks2, function(cb2) - MySQL.Async.fetchAll('SELECT * FROM `users` WHERE `identifier` = @identifier', { + MySQL.Async.fetchAll('SELECT loadout, position FROM `users` WHERE `identifier` = @identifier', { ['@identifier'] = player.getIdentifier() }, function(result) userData.job['name'] = result[1].job From 6a4918b58fec83ee106f963221a6db0b2b7bb26b Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 9 Nov 2018 23:59:38 +0100 Subject: [PATCH 1894/3224] Initial cleanup --- __resource.lua | 36 ++--- client/main.lua | 398 +++++++++++++++++++++------------------------- esx_bankerjob.sql | 2 +- server/main.lua | 163 +++++++++---------- 4 files changed, 276 insertions(+), 323 deletions(-) diff --git a/__resource.lua b/__resource.lua index 3dd04a4f..93ed9324 100644 --- a/__resource.lua +++ b/__resource.lua @@ -5,27 +5,27 @@ description 'ESX Banker job' version '1.0.1' server_scripts { - '@async/async.lua', - '@mysql-async/lib/MySQL.lua', - '@es_extended/locale.lua', - 'config.lua', - 'locales/de.lua', - 'locales/br.lua', - 'locales/en.lua', - 'locales/fi.lua', - 'locales/fr.lua', - 'server/main.lua' + '@async/async.lua', + '@mysql-async/lib/MySQL.lua', + '@es_extended/locale.lua', + 'config.lua', + 'locales/de.lua', + 'locales/br.lua', + 'locales/en.lua', + 'locales/fi.lua', + 'locales/fr.lua', + 'server/main.lua' } client_scripts { - '@es_extended/locale.lua', - 'config.lua', - 'locales/de.lua', - 'locales/br.lua', - 'locales/en.lua', - 'locales/fi.lua', - 'locales/fr.lua', - 'client/main.lua' + '@es_extended/locale.lua', + 'config.lua', + 'locales/de.lua', + 'locales/br.lua', + 'locales/en.lua', + 'locales/fi.lua', + 'locales/fr.lua', + 'client/main.lua' } dependency 'es_extended' \ No newline at end of file diff --git a/client/main.lua b/client/main.lua index 460d99a8..8dba3eb3 100644 --- a/client/main.lua +++ b/client/main.lua @@ -11,7 +11,6 @@ local Keys = { } local PlayerData = {} -local GUI = {} local hasAlreadyEnteredMarker = false local lastZone = nil local CurrentAction = nil @@ -19,295 +18,258 @@ local CurrentActionMsg = '' local CurrentActionData = {} ESX = nil -GUI.Time = 0 Citizen.CreateThread(function () - while ESX == nil do - TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) - Citizen.Wait(0) - end + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end + + end) RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function (xPlayer) - PlayerData = xPlayer + PlayerData = xPlayer end) RegisterNetEvent('esx:setJob') AddEventHandler('esx:setJob', function (job) - PlayerData.job = job + PlayerData.job = job end) -function OpenBankActionsMenu () - local elements = { - { label = _U('customers'), value = 'customers' }, - { label = _U('billing'), value = 'billing' }, - } +function OpenBankActionsMenu() + local elements = { + { label = _U('customers'), value = 'customers' }, + { label = _U('billing'), value = 'billing' }, + } - if PlayerData.job.grade_name == 'boss' then - table.insert(elements, { label = _U('boss_actions'), value = 'boss_actions' }) - end + if PlayerData.job.grade_name == 'boss' then + table.insert(elements, { label = _U('boss_actions'), value = 'boss_actions' }) + end - ESX.UI.Menu.CloseAll() + ESX.UI.Menu.CloseAll() - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'bank_actions', - { - title = _U('bank'), - align = 'top-left', - elements = elements, - }, - function (data, menu) - if data.current.value == 'customers' then - OpenCustomersMenu() - end + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'bank_actions', { + title = _U('bank'), + align = 'top-left', + elements = elements + }, function(data, menu) + if data.current.value == 'customers' then + OpenCustomersMenu() + elseif data.current.value == 'billing' then + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'billing', { + title = _U('bill_amount') + }, function(data, menu) + local amount = tonumber(data.value) - if data.current.value == 'billing' then - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'billing', - { - title = _U('bill_amount'), - }, - function (data, menu) - local amount = tonumber(data.value) + if amount == nil then + ESX.ShowNotification(_U('invalid_amount')) + else + menu.close() - if amount == nil then - ESX.ShowNotification(_U('invalid_amount')) - else - menu.close() + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer == -1 or closestDistance > 5.0 then + ESX.ShowNotification(_U('no_player_nearby')) + else + TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_banker', 'Banque', amount) + end + end + end, function(data, menu) + menu.close() + end) - if closestPlayer == -1 or closestDistance > 5.0 then - ESX.ShowNotification(_U('no_player_nearby')) - else - TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_banker', 'Banque', amount) - end - end - end, - function (data, menu) - menu.close() - end - ) + elseif data.current.value == 'boss_actions' then + TriggerEvent('esx_society:openBossMenu', 'banker', function (data, menu) + menu.close() + end, {wash = false}) + end - end - - if data.current.value == 'boss_actions' then - TriggerEvent('esx_society:openBossMenu', 'banker', function (data, menu) - menu.close() - end, {wash = false}) - end - - end, - function (data, menu) - menu.close() - - CurrentAction = 'bank_actions_menu' - CurrentActionMsg = _U('press_input_context_to_open_menu') - CurrentActionData = {} - end - ) + end, function(data, menu) + menu.close() + CurrentAction = 'bank_actions_menu' + CurrentActionMsg = _U('press_input_context_to_open_menu') + CurrentActionData = {} + end) end -function OpenCustomersMenu () - ESX.TriggerServerCallback('esx_bankerjob:getCustomers', function (customers) - local elements = { - head = { _U('customer'), _U('balance'), _U('actions') }, - rows = {} - } +function OpenCustomersMenu() + ESX.TriggerServerCallback('esx_bankerjob:getCustomers', function(customers) + local elements = { + head = { _U('customer'), _U('balance'), _U('actions') }, + rows = {} + } - for i=1, #customers, 1 do - table.insert(elements.rows, { - data = customers[i], - cols = { - customers[i].name, - customers[i].bankSavings, - '{{' .. _U('deposit') .. '|deposit}} {{' .. _U('withdraw') .. '|withdraw}}', - } - }) - end + for i=1, #customers, 1 do + table.insert(elements.rows, { + data = customers[i], + cols = { + customers[i].name, + customers[i].bankSavings, + '{{' .. _U('deposit') .. '|deposit}} {{' .. _U('withdraw') .. '|withdraw}}' + } + }) + end - ESX.UI.Menu.Open( - 'list', GetCurrentResourceName(), 'customers', - elements, - function (data, menu) - local customer = data.data + ESX.UI.Menu.Open('list', GetCurrentResourceName(), 'customers', elements, function(data, menu) - if data.value == 'deposit' then - menu.close() + local customer = data.data - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'customer_deposit_amount', - { - title = _U('amount'), - }, - function (data2, menu) - local amount = tonumber(data2.value) + if data.value == 'deposit' then + menu.close() - if amount == nil then - ESX.ShowNotification(_U('invalid_amount')) - else - menu.close() + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'customer_deposit_amount', { + title = _U('amount') + }, function(data2, menu2) + local amount = tonumber(data2.value) - TriggerServerEvent('esx_bankerjob:customerDeposit', customer.source, amount) + if amount == nil then + ESX.ShowNotification(_U('invalid_amount')) + else + menu2.close() - OpenCustomersMenu() - end - end, - function (data2, menu) - menu.close() - OpenCustomersMenu() - end - ) - end + TriggerServerEvent('esx_bankerjob:customerDeposit', customer.source, amount) - if data.value == 'withdraw' then - menu.close() + OpenCustomersMenu() + end + end, function(data2, menu2) + menu2.close() + OpenCustomersMenu() + end) + elseif data.value == 'withdraw' then + menu.close() - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'customer_withdraw_amount', - { - title = _U('amount'), - }, - function (data2, menu) - local amount = tonumber(data2.value) + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'customer_withdraw_amount', { + title = _U('amount') + }, function(data2, menu2) + local amount = tonumber(data2.value) - if amount == nil then - ESX.ShowNotification(_U('invalid_amount')) - else - menu.close() + if amount == nil then + ESX.ShowNotification(_U('invalid_amount')) + else + menu2.close() - TriggerServerEvent('esx_bankerjob:customerWithdraw', customer.source, amount) + TriggerServerEvent('esx_bankerjob:customerWithdraw', customer.source, amount) + OpenCustomersMenu() + end + end, function(data2, menu2) + menu2.close() + OpenCustomersMenu() + end) + end - OpenCustomersMenu() + end, function(data, menu) + menu.close() + end) - end - end, - function (data2, menu) - menu.close() - OpenCustomersMenu() - end - ) - - end - - end, - function (data, menu) - menu.close() - end - ) - - end) + end) end AddEventHandler('esx_bankerjob:hasEnteredMarker', function (zone) - if zone == 'BankActions' and PlayerData.job ~= nil and PlayerData.job.name == 'banker' then - CurrentAction = 'bank_actions_menu' - CurrentActionMsg = _U('press_input_context_to_open_menu') - CurrentActionData = {} - end + if zone == 'BankActions' and PlayerData.job ~= nil and PlayerData.job.name == 'banker' then + CurrentAction = 'bank_actions_menu' + CurrentActionMsg = _U('press_input_context_to_open_menu') + CurrentActionData = {} + end end) AddEventHandler('esx_bankerjob:hasExitedMarker', function (zone) - CurrentAction = nil - ESX.UI.Menu.CloseAll() + CurrentAction = nil + ESX.UI.Menu.CloseAll() end) RegisterNetEvent('esx_phone:loaded') AddEventHandler('esx_phone:loaded', function (phoneNumber, contacts) - local specialContact = { - name = 'Banque', - number = 'banker', - base64Icon = 'data:image/x-icon;base64,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RCU6uEMlDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4w41Qub+NULqfjVC7b41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/4FMt/8RIJ/+2QyX/tkMl/7ZDJf+2QyX/tkMl4LhEJay2QyVyuEQlNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyXfuUQlZLhEJQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4841Quz+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/gUy3/xkko/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/t0Ml07dDJUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4U41Quo+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/j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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC5341Qu++NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/2lAs/7tFJv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX8uEQlfQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4M41Qup+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/9FNKv+4QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4o41Qu5+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/cUSz/vUUm/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl6rZDJSsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuGONULt/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/1E4r/7hDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl4rdDJRsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgzjVC7L41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/4lMt/8pKKf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/t0MlzrdDJQ4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Qup+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/95SLf/BRyf/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/uEQlrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULnfjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/ZUCv/ukQm/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/uEQlfQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC5E41Qu++NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/0E0q/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX8uUQlSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuFONULuPjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/4FMt/8ZJKP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyXmt0MlFgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC6v41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/91RLP++Rib/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+4RCWzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuYONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/WTyv/uEQl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+5RCVlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhTjVC7v41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/zEsp/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJfG3QyUWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Quo+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/lZEH/9se6//78/P///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////vz7/+jEu/++Vz3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7lEJagAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULjzjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5WE+//rk3v////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////fq5/+8VDn/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7dDJUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4E41Quz+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/0v7H//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+S4rf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/t0Ml07hEJQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULmDjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//75+P///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Pn4/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/uUQlZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4I41Qu3+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyXfuEMlCQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULm/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/++fj///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////z5+P+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+5RCV0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4E41Qu3+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+6Xf//+/Pz////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+/Pv/0499/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJeO4RCUEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULlzjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+ZmRf/umYP/8amW//vn4v//////////////////////////////////////////////////////+vPx/9uklf/aoZL/2qGS/9qhkv/aoZL/2qGS/9qhkv/aoZL/2qGS/9qhkv/aoZL/8NnS///////////////////////////////////////////////////////8+fj/3qmc/9qhkv/aoZL/2qGS/9qhkv/aoZL/2qGS/9qhkv/aoZL/2qGS/9qhkv/rzcX///////////////////////////////////////////////////////78+//hsqb/1pWE/79aQP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Quz+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/riW//////////////////////////////////////////////////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTv/////////////////////////////////////////////////////////////////jua3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/u1E2//78+////////////////////////////////////////////////////////////+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/t0Ml0wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULjjjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+uJb//////////////////////////////////////////////////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/w2ZO/////////////////////////////////////////////////////////////////+O5rf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+7UTb//vz7////////////////////////////////////////////////////////////7NDI/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/uEQlPQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Qun+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+2Ref/xqZb/8amW//jUyv//////////////////////2qGS/9qhkv/aoZL/1pWE/7dGKP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/y3tl/9qhkv/aoZL/2qGS///////////////////////aoZL/2qGS/9qhkv/Ym4v/uUsv/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/Hb1j/2qGS/9qhkv/aoZL//////////////////////+zQyP/aoZL/2qGS/9mejv+8VDn/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+5RCWjAAAAAAAAAAAAAAAAAAAAAAAAAAAA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VC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7hEJawAAAAAAAAAAAAAAAAAAAAA41Qu7+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl8QAAAAAAAAAAAAAAAONULjDjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/uEQlNQAAAAAAAAAA41Qub+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyVyAAAAAAAAAADjVC6n41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7hEJawAAAAAAAAAAONULtvjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl4AAAAADjVC4M41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/vUUmDuNULjTjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/79GJv/QTCo141QuXONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/FSCf/4VMt/9ZPK1zjVC6D41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/zEsp/+NULv/jVC7/3lItg+NULp/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9JOKv/jVC7/41Qu/+NULv/jVC6f41Quv+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7pEJf/YUCv/41Qu/+NULv/jVC7/41Qu/+NULr/jVC7X41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+9RSb/3FEs/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu1+NULuPjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/wUcn/+BTLf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7j41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8hJKP/iUy3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/OTCr/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+4QyX/1U8r/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/ukQm/9pQLP/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/75GJv/eUi3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/DSCf/4FMt/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/y0op/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9FNKv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULuPjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7hEJf/XTyv/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7j41Qu1+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+9RSb/3FEs/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULtfjVC6/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/wEcn/99SLf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Quv+NULp/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8ZJKP/iUy3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC6f41Qug+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+h3WP/87+v//////////////////////////////////////////////////////+3QyP+4SSv/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/uk4y//Hc1v//////////////////////////////////////////////////////8t/Z/7tRNv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+3Rij/7M3F///////////////////////////////////////////////////////68/H/yHJb/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/NSyn/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULoPjVC5c41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/9Lyt/////////////////////////////////////////////////////////////////86BbP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/UkoH/////////////////////////////////////////////////////////////////15iI/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8t7Zv/////////////////////////////////////////////////////////////////juK3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+4QyX/004q/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuXONULjTjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5mZE/+ZpSP/voY3/////////////////////////////////////////////////////////////////y3tm/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9KMev/////////////////////////////////////////////////////////////////WlYT/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/yXVf////////////////////////////////////////////////////////////+/b1/9GJdv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/ukQl/9lQLP/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC4041QuDONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+qBZf////////////////////////////////////////////////////////////////////////////v29f/aoZL/2qGS/9qhkv/aoZL/2qGS/9qhkv/aoZL/2qGS/9qhkv/aoZL/3KeY//35+P///////////////////////////////////////////////////////vz7/9ynmP/aoZL/2qGS/9qhkv/aoZL/2qGS/9qhkv/Ym4v/0Yp3/9GKd//Rinf/+O3r///////////////////////////////////////////////////////////////////////58O7/vFQ5/7ZDJf+2QyX/tkMl/71GJv/eUi3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULgwAAAAA41Qu2+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/+NfO///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Ym4v/tkMl/7ZDJf/DSCf/4FMt/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7bAAAAAAAAAADjVC6n41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/76uX//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+O4rf+2QyX/yUop/+JTLf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULqcAAAAAAAAAAONULm/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//nc1P//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////2ZuL/9BNKv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QubwAAAAAAAAAA41QuMONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/7I92//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////nt6v/cYD//41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC4wAAAAAAAAAAAAAAAA41Qu7+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/6Xxf//rf2P/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////1xrr/5WlI/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu7wAAAAAAAAAAAAAAAAAAAADjVC6n41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Yx/+6Zg//88e7////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////64dv/6oFl/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC6nAAAAAAAAAAAAAAAAAAAAAONULlzjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+ReO//zt6f//vz8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////99PL/75yG/+NWMf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULlwAAAAAAAAAAAAAAAAAAAAA41QuFONULvvjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/ocVL/99HH///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+/Pz/87mq/+VhPv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7741QuFAAAAAAAAAAAAAAAAAAAAAAAAAAA41Quu+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/7Ixz//vp5f//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+NfO/+h0Vf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULrsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC5k41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5Fk0//Cnk//++fj/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////++nl/+yPdv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgzjVC7341Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+ZmRf/1xLf//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////vn4//Gplv/kWTT/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvfjVC4MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULp/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/pfF//+t/Y//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////XEt//maUj/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QunwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuOONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVjH/7peA//zx7v////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////rh2//qf2L/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC44AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Quz+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5F47//K0o//+/Pz///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////308v/umYP/41Yx/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuzwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC5c41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+dvTv/30cf///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////78/P/zt6f/5F47/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC5cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgTjVC7j41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/siW//++fi///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30cf/6HFS/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu3+NULgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULm/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/kWTT/8KeT//339f/////////////////////////////////////////////////////////////////////////////////////////////////76eX/7Ixz/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC5vAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuCONULt/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5mZF//XCtP/////////////////////////////////////////////////////////////////////////////////++fj/8KeT/+RZNP/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu3+NULggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuYONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+l8X//53NX/////////////////////////////////////////////////////////////////9cS3/+ZmRf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC5gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4E41Quz+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NWMf/ul4D//PHu////////////////////////////////////////////+dzV/+l8X//jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Quz+NULgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4841Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/kXjv/8rGg//78/P///////////////////////PHu/+6XgP/jVjH/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC48AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC6j41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/6HdY//fPxP/++fj//PLv//S8rf/mZkX/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuowAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhTjVC7v41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULu/jVC4UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULmDjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULq/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULq8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuFONULuPjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7j41QuFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuRONULvvjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu++NULkQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Qud+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC53AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Qup+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QupwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4M41Quy+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULsvjVC4MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4Y41Qu3+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7f41QuGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4o41Qu5+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu5+NULigAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4o41Qu8+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvPjVC4oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4841Qu8+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7z41QuPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4o41Qu5+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu5+NULigAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4o41Qu3+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULt/jVC4oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4Y41Quy+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7L41QuGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4M41Quq+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qup+NULgwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Qud+NULvvjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu++NULncAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuRONULuPjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULuPjVC5EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuFONULq/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC6v41QuFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULmDjVC7v41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7v41QuYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhTjVC6j41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Quo+NULhQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4841Quz+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Quz+NULjwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4E41QuYONULt/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu3+NULmDjVC4EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuCONULm/jVC7f41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu3+NULm/jVC4IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgTjVC5c41Quz+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Quz+NULlzjVC4EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuOONULp/jVC7341Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7341Qun+NULjgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgzjVC5k41Quu+NULvvjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvvjVC6741QuZONULgwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuFONULlzjVC6n41Qu7+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu7+NULqfjVC5c41QuFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuMONULm/jVC6n41Qu2+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULtvjVC6n41Qub+NULjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuDONULjTjVC5c41Qug+NULp/jVC6/41Qu1+NULuPjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULuPjVC7X41Quv+NULp/jVC6D41QuXONULjTjVC4MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////AAAA////////////////8AAAAA///////////////wAAAAAA//////////////gAAAAAAB/////////////gAAAAAAAH////////////AAAAAAAAAP///////////AAAAAAAAAA///////////AAAAAAAAAAD//////////gAAAAAAAAAAf/////////gAAAAAAAAAAB/////////wAAAAAAAAAAAP////////wAAAAAAAAAAAA////////4AAAAAAAAAAAAH///////8AAAAAAAAAAAAA///////8AAAAAAAAAAAAAD//////+AAAAAAAAAAAAAAf//////AAAAAAAAAAAAAAD//////gAAAAAAAAAAAAAAf/////wAAAAAAAAAAAAAAD/////4AAAAAAAAAAAAAAAf////8AAAAAAAAAAAAAAAD////+AAAAAAAAAAAAAAAAf////AAAAAAAAAAAAAAAAD////wAAAAAAAAAAAAAAAA////4AAAAAAAAAAAAAAAAH///8AAAAAAAAAAAAAAAAA///+AAAAAAAAAAAAAAAAAH///gAAAAAAAAAAAAAAAAB///wAAAAAAAAAAAAAAAAAP//4AAAAAAAAAAAAAAAAAB//+AAAAAAAAAAAAAAAAAAf//AAAAAAAAAAAAAAAAAAD//gAAAAAAAAAAAAAAAAAAf/4AAAAAAAAAAAAAAAAAAH/8AAAAAAAAAAAAAAAAAAA//AAAAAAAAAAAAAAAAAAAP/gAAAAAAAAAAAAAAAAAAB/4AAAAAAAAAAAAAAAAAAAf+AAAAAAAAAAAAAAAAAAAH/AAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAP4AAAAAAAAAAAAAAAAAAAB+AAAAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAAAAAAHwAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAAAABwAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAA+AAAAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAAAAAAH4AAAAAAAAAAAAAAAAAAAB/AAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAP+AAAAAAAAAAAAAAAAAAAH/gAAAAAAAAAAAAAAAAAAB/4AAAAAAAAAAAAAAAAAAAf/AAAAAAAAAAAAAAAAAAAP/wAAAAAAAAAAAAAAAAAAD/+AAAAAAAAAAAAAAAAAAB//gAAAAAAAAAAAAAAAAAAf/8AAAAAAAAAAAAAAAAAAP//gAAAAAAAAAAAAAAAAAH//4AAAAAAAAAAAAAAAAAB///AAAAAAAAAAAAAAAAAA///4AAAAAAAAAAAAAAAAAf//+AAAAAAAAAAAAAAAAAH///wAAAAAAAAAAAAAAAAD///+AAAAAAAAAAAAAAAAB////wAAAAAAAAAAAAAAAA////8AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAAH////8AAAAAAAAAAAAAAAD/////gAAAAAAAAAAAAAAB/////8AAAAAAAAAAAAAAA//////gAAAAAAAAAAAAAAf/////8AAAAAAAAAAAAAAP//////gAAAAAAAAAAAAAH//////8AAAAAAAAAAAAAD///////wAAAAAAAAAAAAD///////+AAAAAAAAAAAAB////////wAAAAAAAAAAAA/////////AAAAAAAAAAAA/////////4AAAAAAAAAAAf/////////gAAAAAAAAAAf/////////8AAAAAAAAAAP//////////wAAAAAAAAAP///////////AAAAAAAAAP///////////+AAAAAAAAf////////////4AAAAAAAf/////////////wAAAAAA///////////////wAAAAD////////////////wAAAP////////KAAAAGAAAADAAAAAAQAgAAAAAACAlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4I41QuKeJTLU7jVC5341Qum+JTLb3j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QiT+tUIk/rVCJP62QyX7tkMlXQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMtDuNULuTjVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/8a6c/v///////////v7+/v///////////v7+/v////////////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/tymmP+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tkMl5rdDJQ8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMteONULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/99PJ/v///////////v7+/v///////////v7+/v////////////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/uzOx/+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rhEJXsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy0Y4lMt6OJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+99HH/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/uvMxP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rZDJei3QyUaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC584lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/6Xlb/vrh2v/+/Pv//v7+/v///////////v7+/v////////////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v/////+/f3/8+Db/sZuVv+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+4RCV/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhDjVC7f4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uRbNv/nbk3/+NjP/v///////////v7+/v////////////////7+/v7+/Pz/2qCR/79aQP6/WkD/v1pA/79aQP6/WkD/v1pA/79aQP7bpJb//vz8//7+/v7///////////7+/v7///////////7+/v7t0sv/wV9F/79aQP6/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QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyVrAAAAAAAAAADiUy2s4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7maUj+/v7+/v7+/v7+/v7+yHFb/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7aoZL+/v7+/v7+/v7aoJH+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/shyW/7+/v7+/v7+/v7+/v6/WkD+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP63QyWwAAAAAONULgjjVC7g4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyXhtkMlCeNULinjVC7z4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX1uUQlLOJTLU7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7maUj+/v7+/v7+/v7+/v7+yHFb/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7aoZL+/v7+/v7+/v7aoJH+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/shyW/7+/v7+/v7+/v7+/v6/WkD+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+vkYmT+NULnfjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf/FSSf/1U4rd+NULpvjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/stLKf/hUy3/3lIsm+JTLb3iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7maUj+/v7+/v7+/v7+/v7+yHFb/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7aoZL+/v7+/v7+/v7aoJH+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/shyW/7+/v7+/v7+/v7+/v6/WkD+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP64QyX+0U0q/uJTLf7iUy3+4lMtveNULtbjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rpEJf/WTyv/4lMt/uNULv/jVC7/4lMt1uNULunjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/vEUm/ttRLP/jVC7/4lMt/uNULv/jVC7/4lMt6eJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7maUj+/v7+/v7+/v7+/v7+yHFb/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7aoZL+/v7+/v7+/v7aoJH+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/shyW/7+/v7+/v7+/v7+/v6/WkD+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7CRyf+31It/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tkMl/shJKP/gUy3/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/zUsp/uJTLf/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7maUj+/v7+/v7+/v7+/v7+yHFb/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7aoZL+/v7+/v7+/v7aoJH+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/shyW/7+/v7+/v7+/v7+/v6/WkD+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rhEJf7UTiv+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/u0Um/tlQK//iUy3/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+/Rib/3FEs/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uJTLeniUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7maUj+/v7+/v7+/v7+/v7+yHFb/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7aoZL+/v7+/v7+/v7aoJH+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/shyW/7+/v7+/v7+/v7+/v6/WkD+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/sRIJ/7gUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt6eNULtbjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/ykop/uFTLf/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt1uNULr3jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lQu/uNULv/maUj//v7+/v//////////yHJb/7ZDJf62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7ZDJf7aoZL///////7+/v7aoZL/tkMl/7ZDJf62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tkMl/shyW////////v7+/v////+/WkD/tkMl/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rdDJf/PTCn/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMtveJTLZviUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7lYkD++uLc/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v769PL+x29Y/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7aoZL+/v39/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v79/f7cppj+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/sZsVP768vD+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/vXm4v69Vjv+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+uUQl/tZPK/7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMtm+NULnfjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNYM//odFX//vz7/v///////////v7+/v////////////////7+/v7/////26KT/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7z4Nv///////7+/v7///////////7+/v7///////////7+/v7049//tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/tmfkP///////v7+/v///////////v7+/v///////////v7+/v35+P/DZEz/tUIk/rZDJf+2QyX/tUIk/rZDJf+9RSb/2lAs/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMtd+JTLU7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+521N/vnd1v764dr+/vr6/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/f3+3que/tGJdv7RiXb+0Yl2/tGJdv7RiXb+0Yl2/tGJdv7sz8f+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7u08z+0Yl2/tGJdv7RiXb+0Yl2/tGJdv7MfWj+ynhi/teaif79+/v+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/vr08v7t0sv+6ce+/rlMMP61QiT+tUIk/sBHJ/7eUiz+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMtTeNULinjVC7z4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/87mq/v///////////v7+/v///////////v7+/v////////////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/tGKeP+2QyX/xkko/uFTLf/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7z4lMtKeNULgjjVC7g4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/9MG0/v///////////v7+/v///////////v7+/v////////////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/taSgf/MSyn/4VMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7g4lMtBwAAAADiUy2s4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+7Ixy/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7++/Xz/ttmRv7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy2sAAAAAAAAAADjVC5p4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uqAZP/52tL//v7+/v///////////v7+/v////////////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v79/P/2zMD/53BR/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC5pAAAAAAAAAADjVC4o4lMt+ONULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/kXDj/7pmD/vzv6////v7//v7+/v////////////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v/////+/v7/+uTe/uuJb//jWDP/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULvjjVC4oAAAAAAAAAADiUy0I4lMtzeJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uVmRP7zuKj+/vr6/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v318/7wppL+5F06/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLc3iUy0IAAAAAAAAAAAAAAAA4lMtf+NULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/6HNU/vfRx//+/f3///////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v/////++vn/9cG0/uZmRP/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULn8AAAAAAAAAAAAAAAAAAAAA4lMtKONULv3jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNYM//sj3b/+uTf//7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v39/vjXzv/pfWH/41Uw/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/eNULigAAAAAAAAAAAAAAAAAAAAAAAAAAOJTLcbiUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+5F87/vGrmP799/X+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v787er+7piC/uNYMv7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMtxgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULl3jVC7+4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7makn/9cG0//77+/7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////fb1/vKwn//lYDz/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7+4lMtXQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhDjVC7f4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Yw/+qCZv752tL//v39//7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v77+v/2y8D/6HRV/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7f4lMtDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy1+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7kWzb+7pqD/vzx7v7+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VC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+NULv7nb1D/76CL/+6Zgv7mZkT/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC644lMtBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy0u4lMt8OJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLfDiUy0uAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMtauNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULmoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMtA+NULrHjVC7+41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7+4lMtsONULgMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOJTLRriUy3a4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3a4lMtGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4041Qu7OJTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULuzjVC40AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuU+JTLfnjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt+eNULlMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOJTLXHiUy364lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy364lMtcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC534lMt/ONULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULvzjVC53AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4E4lMtd+NULvrjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt+uNULnfjVC4EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOJTLXHiUy354lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy354lMtcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC5T4lMt7eNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULuzjVC5TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMtNeNULtrjVC7+4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7+4lMt2uNULjQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOJTLRriUy2x4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy2w4lMtGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4D4lMtauNULvDjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt8ONULmrjVC4DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULi7jVC644lMt++NULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULvvjVC644lMtLgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy0G4lMtWuJTLeTiUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt5OJTLVriUy0FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULg7jVC544lMt6ONULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULujjVC544lMtDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMtGONULnzjVC7f4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv7jVC7f4lMte+NULhgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy0P4lMtXeJTLcbiUy394lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy394lMtxuJTLV3iUy0PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4o41QugOJTLc3jVC7441Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC744lMtzeNULn/jVC4oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOJTLQjjVC4o41QuaeJTLazjVC7g41Qu8+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULvPjVC7g4lMtrONULmnjVC4o4lMtCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy0H4lMtKeJTLU3iUy134lMtm+JTLb3iUy3W4lMt6eJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLeniUy3W4lMtveJTLZviUy134lMtTeJTLSniUy0HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////4AAAf//////////+AAAAB//////////4AAAAAf/////////AAAAAAD////////8AAAAAAA////////wAAAAAAAP///////AAAAAAAAD//////+AAAAAAAAB//////4AAAAAAAAAf/////wAAAAAAAAAP/////gAAAAAAAAAH/////AAAAAAAAAAD////+AAAAAAAAAAB////4AAAAAAAAAAAf///4AAAAAAAAAAAf///wAAAAAAAAAAAP///gAAAAAAAAAAAH///AAAAAAAAAAAAD//+AAAAAAAAAAAAB//8AAAAAAAAAAAAA//8AAAAAAAAAAAAA//4AAAAAAAAAAAAAf/wAAAAAAAAAAAAAP/wAAAAAAAAAAAAAP/gAAAAAAAAAAAAAH/gAAAAAAAAAAAAAH/AAAAAAAAAAAAAAD/AAAAAAAAAAAAAAD+AAAAAAAAAAAAAAB+AAAAAAAAAAAAAAB+AAAAAAAAAAAAAAB8AAAAAAAAAAAAAAA8AAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAA+AAAAAAAAAAAAAAB+AAAAAAAAAAAAAAB+AAAAAAAAAAAAAAB/AAAAAAAAAAAAAAD/AAAAAAAAAAAAAAD/gAAAAAAAAAAAAAH/gAAAAAAAAAAAAAH/wAAAAAAAAAAAAAP/wAAAAAAAAAAAAAP/4AAAAAAAAAAAAAf/8AAAAAAAAAAAAA//8AAAAAAAAAAAAA//+AAAAAAAAAAAAB///AAAAAAAAAAAAD///gAAAAAAAAAAAH///wAAAAAAAAAAAP///4AAAAAAAAAAAf///4AAAAAAAAAAAf///+AAAAAAAAAAB/////AAAAAAAAAAD/////gAAAAAAAAAH/////wAAAAAAAAAP/////4AAAAAAAAAf/////+AAAAAAAAB///////AAAAAAAAD///////wAAAAAAAP///////8AAAAAAA/////////AA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QiT+tkMl/7ZDJf+1QiT+tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7ZDJf+1QiT+tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7dDJaa2QyUCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULlXjVC7941Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVjH/42dF/8heQv+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/vlk+/7dGKP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf23QyVXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuDuNULt/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NYM//2yLz//v39/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////v38/+nHv/+4SCv/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyXgtkMlDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMthuNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/++eiP/+/v7+//////7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+//////7+/v7///////////7+/v7//////v7+/v/////+/v7+//////7+/v7VlIP/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/t0MliQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4d41Qu8ONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//K0o//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////frJ//tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl8LdDJR4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC6N4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+p/Y//77On+/v7+//7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+//////7+/v7///////////7+/v7//////v7+/v/////+/v7+//////fs6f7JdF3/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rdDJZAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhXjVC7s41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/kWzf/76CL//7+/v///////////////////////////+W+s/+8VDn/vFQ5/7xUOf+8VDn/vFQ5/9aWhf/+/f3////////////////////////////mv7X/vFQ5/7xUOf+8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QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl8rZDJRjjVC5D41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/sjnX////////////DZk3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/v1pA////////////v1pA/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTf///////////8+Db/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7hDJUXjVC5041Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7sjnX//v7+/v/////DZk3+tkMl/7ZDJf+1QiT+tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+v1pA///////+/v7+v1pA/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/8NmTf7//////v7+/s+Db/+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7tFJXXjVC6d41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/sjnX////////////DZk3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/v1pA////////////v1pA/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTf///////////8+Db/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/wEYm/9ZPK53jVC7B41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7sjnX//v7+/v/////DZk3+tkMl/7ZDJf+1QiT+tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+v1pA///////+/v7+v1pA/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/8NmTf7//////v7+/s+Db/+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf/FSCf+4FMt/+FTLcHjVC7e41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/sjnX////////////DZk3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/v1pA////////////v1pA/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTf///////////8+Db/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8tLKf/iUy3/41Qu/+NULt7jVC7y41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7sjnX//v7+/v/////DZk3+tkMl/7ZDJf+1QiT+tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+v1pA///////+/v7+v1pA/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/8NmTf7//////v7+/s+Db/+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP63QyX/0U0q/uJTLf/iUy3+41Qu/+JTLfLjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/sjnX////////////DZk3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/v1pA////////////v1pA/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTf///////////8+Db/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7pEJf/XTyv/4lMt/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/sjnX////////////DZk3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/v1pA////////////v1pA/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTf///////////8+Db/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/vUUm/9tRLP/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7sjnX//v7+/v/////DZk3+tkMl/7ZDJf+1QiT+tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+v1pA///////+/v7+v1pA/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/8NmTf7//////v7+/s+Db/+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP7CRyf/31It/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/sjnX////////////DZk3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/v1pA////////////v1pA/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTf///////////8+Db/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8dJKP/hUy3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7y41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7sjnX//v7+/v/////DZk3+tkMl/7ZDJf+1QiT+tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+v1pA///////+/v7+v1pA/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/8NmTf7//////v7+/s+Db/+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX+zkwp/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLfLjVC7e41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/sjnX////////////DZk3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/v1pA////////////v1pA/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTf///////////8+Db/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7hEJf/UTir/4lMt/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULt7jVC7B41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+6HJT//Cplv71xrr//v7+/v/////hsqb+2qCR/8FfRv+1QiT+tkMl/7VCJP62QyX/tUIk/sBeRf/aoJH+36yf///////+/v7+36yf/9qgkf7BYEb/tUIk/rZDJf+1QiT+tkMl/7VCJP7AXkX/2p+Q/+Gypv7//////v7+/ufBt//aoJH+xGhQ/7VCJP62QyX/tkMl/7VCJP62QyX/u0Qm/tlQK//iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLcHjVC6d41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVzL/9L2v/////////////////////////////////+K2qv+2QyX/tkMl/7ZDJf+2QyX/tkMl/+K0qP/////////////////////////////////juKz/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/hs6f/////////////////////////////////47es/7ZDJf+2QyX/tkMl/7ZDJf+/Rib/3VEs/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULp3jVC5041Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+hyU//65uD+/PHu//7+/v7//////v7+/v/////+/v7+/////+zPx//cppj+3KaY/9ymmP7cppj/3KaY/uzOxv/+/v7+///////////+/v7+//////7+/v7s0Mj/3KaY/tymmP/cppj+26OU/9eZif7oxLr///////7+/v7//////v7+/v/////+/v7+9ujl/+/X0P68Uzj/tkMl/8NIJ/7gUi3/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLXTjVC5D41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Cnk//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////OgGz/ykop/+JTLf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULkLjVC4X41Qu8eJTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+uHbP/+/v7+//////7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+//////7+/v7///////////7+/v7//////v7+/v/////+/v7+//////35+P7aZ0n/4lMt/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu8eJTLRcAAAAA41QuxeNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/qgWb/+d7W///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+/v7/99PJ/+h1Vv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuxQAAAAAAAAAA41QufeNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5Fk1/++diP/88e7//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////v7+//vq5f/skHf/41Yx/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QufQAAAAAAAAAA41QuK+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7lY0D/87mq/v76+f/+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+//////7+/v7///////////7+/v799vT/8auZ/uRcOP/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41QuKwAAAAAAAAAA41QuAuNULs7jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+h3Wf/41Mr//v79/////////////////////////////////////////////////////////////////////////////////////////////////////////////vz8//XGuv/nbEz/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7O41QuAgAAAAAAAAAAAAAAAOJTLWzjVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/jVTD+7ZB4//vo4//+/v7+//////7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+//////7+/v753tf/6oNn/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy1sAAAAAAAAAAAAAAAAAAAAAONULhTjVC7s41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+RcOP/xq5n//fXz/////////////////////////////////////////////////////////////////////////////O/s/++dh//jWDP/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULuzjVC4UAAAAAAAAAAAAAAAAAAAAAAAAAADjVC6P4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+5mxL//XGuv7+/f3//v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v77+v/zuKj+5WNA/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULo0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4d41Qu8ONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NUL//qgWX/+d3W///+/v/////////////////////////////////+/f3/99LI/+h0Vv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu8ONULh0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMthuNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/41k1/u+ch//88u/+///////////+/v7+//////vo4/7sjnX/41Yx/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMthgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuDuNULt/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/lYT7/87us//349v/99PH/8aya/+RaNv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7f41QuDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULlXjVC7941Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+VjQf/lYT3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv3jVC5VAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgLiUy2k41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLaTjVC4CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4T41Qu3ONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu3ONULhMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuN+NULvHiUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7x41QuNwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULljjVC7741Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvvjVC5YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy1z41Qu/OJTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/OJTLXMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Quf+NULvzjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7841QufwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOJTLXPjVC774lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULvviUy1zAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC5Y41Qu8uNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu8eNULlgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuN+NULtzjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7c41QuNwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhPiUy2k41Qu/eNULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/eJTLaTjVC4TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4C41QuVeNULt/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7f41QuVeNULgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULg7iUy2G41Qu8OJTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu8OJTLYbjVC4OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuHeNULo3jVC7s41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULuzjVC6N41QuHQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4U4lMtbONULs7iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7O4lMtbONULhQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgLjVC4r41QufeNULsXjVC7x41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvHjVC7F41QufeNULivjVC4CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy0X41QuQuJTLXTjVC6d4lMtweNULt7iUy3y41Qu/+NULv/iUy3+41Qu/+JTLfLjVC7e4lMtweNULp3iUy1041QuQuJTLRcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD////gAAf///8AAAD///4AAAB///8AAAD///gAAAAf//8AAAD//+AAAAAH//8AAAD//4AAAAAB//8AAAD//gAAAAAAf/8AAAD//AAAAAAAP/8AAAD/+AAAAAAAH/8AAAD/8AAAAAAAD/8AAAD/4AAAAAAAB/8AAAD/wAAAAAAAA/8AAAD/gAAAAAAAAf8AAAD/AAAAAAAAAP8AAAD+AAAAAAAAAH8AAAD8AAAAAAAAAD8AAAD4AAAAAAAAAB8AAAD4AAAAAAAAAB8AAADwAAAAAAAAAA8AAADwAAAAAAAAAA8AAADgAAAAAAAAAAcAAADgAAAAAAAAAAcAAADAAAAAAAAAAAMAAADAAAAAAAAAAAMAAACAAAAAAAAAAAEAAACAAAAAAAAAAAEAAACAAAAAAAAAAAEAAACAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAEAAACAAAAAAAAAAAEAAACAAAAAAAAAAAEAAACAAAAAAAAAAAEAAADAAAAAAAAAAAMAAADAAAAAAAAAAAMAAADgAAAAAAAAAAcAAADgAAAAAAAAAAcAAADwAAAAAAAAAA8AAADwAAAAAAAAAA8AAAD4AAAAAAAAAB8AAAD4AAAAAAAAAB8AAAD8AAAAAAAAAD8AAAD+AAAAAAAAAH8AAAD/AAAAAAAAAP8AAAD/gAAAAAAAAf8AAAD/wAAAAAAAA/8AAAD/4AAAAAAAB/8AAAD/8AAAAAAAD/8AAAD/+AAAAAAAH/8AAAD/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QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJfi3QyUyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuBeNULtPjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/91RLP++Rib/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/t0Ml1bZDJQUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULnfjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41cy//XDtv/+/v7///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////7+/v/nwbf/t0cq/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+3QyV5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhnjVC7z41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+6Ygf///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9OOe/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl9LdDJRoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC6V41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/wqJT////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Zn5D/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+3QyWWAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4Y41Qu9+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5WRC//S/sP/6493////////////////////////////15eH/7NDI/+zQyP/s0Mj/7NDI/+zQyP/79fP///////////////////////79/f/t0sv/7NDI/+zQyP/s0Mj/7NDI//Hb1f////////////////////////////fr6P/kuq//vVY7/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl+LZDJRkAAAAAAAAAAAAAAAAAAAAA41QugeNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/9cS3////////////////////////////7NDI/7ZDJf+2QyX/tkMl/7ZDJf+8VDn/////////////////////////////////zH5p/7ZDJf+2QyX/tkMl/7ZDJf/cp5n////////////////////////////15+P/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyWEAAAAAAAAAAAAAAAA41QuA+NULuXjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+VjQP/qfmL/+d7X///////juK3/yHJb/75YPf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8RoUP/Iclv////////////Iclv/x3BZ/7ZFJ/+2QyX/tkMl/7ZDJf+2QyX/uk4x/8hyW//juK3///////Hb1v/Iclv/wF5E/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl5rZDJQMAAAAAAAAAAONULkfjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//jUyv//////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/2qGS///////s0Mj/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyVKAAAAAAAAAADjVC6a41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/41Mr//////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf///////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9qhkv//////7NDI/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMlnAAAAAAAAAAA41Qu5eNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/+NTK///////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX///////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/aoZL//////+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJecAAAAA41QuJ+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//jUyv//////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/2qGS///////s0Mj/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMlKeNULmDjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/41Mr//////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf///////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9qhkv//////7NDI/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7hDJWPjVC6P41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/+NTK///////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX///////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/aoZL//////+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/ARyeQ41Qut+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//jUyv//////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/2qGS///////s0Mj/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/KSin/3lItt+NULtfjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/41Mr//////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf///////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9qhkv//////7NDI/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7dDJf/RTSr/41Qu/+NULtfjVC7u41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/+NTK///////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX///////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/aoZL//////+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7hEJf/XTyv/41Qu/+NULv/jVC7u41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//jUyv//////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/2qGS///////s0Mj/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7xFJv/cUSz/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/41Mr//////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf///////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9qhkv//////7NDI/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8BHJ//fUi3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/+NTK///////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX///////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/aoZL//////+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8ZJKP/hUy3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//jUyv//////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/2qGS///////s0Mj/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/81LKf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULu7jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/41Mr//////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf///////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9qhkv//////7NDI/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/t0Ml/9NOKv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULu7jVC7X41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/+NTK///////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX///////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/aoZL//////+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/ukQl/9lQLP/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7X41Qut+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/2yLz////////////////////////////cppj/tkMl/7ZDJf+2QyX/tkMl/75ZP//79vT///////////////////////v39f+/XEL/tkMl/7ZDJf+2QyX/tkMl/9ujlP///////////////////////////+nHvv+2QyX/tkMl/7ZDJf+2QyX/vUYm/91RLP/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qut+NULo/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+RfO//ys6L/++fi////////////////////////////6MS7/8hyW//Iclv/yHJb/8hyW//QhXL//v39///////////////////////+/v7/0Ih1/8hyW//Iclv/x3BZ/8NmTv/kurD////////////////////////////y39r/2Z2N/7dHKv+2QyX/wkcn/+BTLf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULo/jVC5g41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/umoP////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////KdmD/yUoo/+JTLf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC5g41QuJ+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/64Rp///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9+vn/2mdI/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuJwAAAADjVC7l41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/qgWX/+uLb///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////42M//6HVX/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu5QAAAAAAAAAA41QumuNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NWMf/vnoj//fPx//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////zt6f/tkXn/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULpoAAAAAAAAAAONULkfjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+ViP//zuqr//v39/////////////////////////////////////////////////////////////////////////////////////////////////////////////vn4//GunP/kXDf/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC5HAAAAAAAAAADjVC4D41Qu5eNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+h0Vv/41s3/////////////////////////////////////////////////////////////////////////////////////////////////9sm9/+ZqSf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7l41QuAwAAAAAAAAAAAAAAAONULoHjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+yOdf/76+f////////////////////////////////////////////////////////////////////////////649z/6oJn/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QugQAAAAAAAAAAAAAAAAAAAADjVC4Y41Qu+ONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5Fo2//Grmf/++ff///////////////////////////////////////////////////////3z8f/vnoj/41Yx/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu9+NULhgAAAAAAAAAAAAAAAAAAAAAAAAAAONULpXjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5mpI//XHu////////////////////////////////////////v39//O6qv/lYj//41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULpUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4Z41Qu8+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/6oBk//rh2///////////////////////+NXM/+h0Vv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvPjVC4ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULnfjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVjH/756I//zx7v/76+b/7JB4/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC53AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4F41Qu0+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7T41QuBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULjDjVC7441Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7441QuMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QubeNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QubQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC6f41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QunwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuBuNULrvjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Quu+NULgYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4K41QuyONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuyONULgoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgrjVC6741Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Quu+NULgoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuBuNULqDjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qun+NULgYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QubeNULvjjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7441QubQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4w41Qu0+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7T41QuMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgXjVC5341Qu8+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvPjVC5341QuBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhnjVC6V41Qu9+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu9+NULpXjVC4ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhjjVC6B41Qu5eNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7l41QugeNULhgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgPjVC5H41QumuNULuXjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu5eNULprjVC5H41QuAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuJ+NULmDjVC6P41Qut+NULtfjVC7u41Qu/+NULv/jVC7/41Qu/+NULu7jVC7X41Qut+NULo/jVC5g41QuJwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAA///////wAAAP/////8AAAAP/////AAAAAP////wAAAAAP///+AAAAAAf///wAAAAAA///8AAAAAAA///gAAAAAAB//8AAAAAAAD//gAAAAAAAH/+AAAAAAAAf/wAAAAAAAA/+AAAAAAAAB/wAAAAAAAAD/AAAAAAAAAP4AAAAAAAAAfgAAAAAAAAB8AAAAAAAAADwAAAAAAAAAOAAAAAAAAAAYAAAAAAAAABgAAAAAAAAAGAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAGAAAAAAAAAAYAAAAAAAAABgAAAAAAAAAHAAAAAAAAAA8AAAAAAAAAD4AAAAAAAAAfgAAAAAAAAB/AAAAAAAAAP8AAAAAAAAA/4AAAAAAAAH/wAAAAAAAA//gAAAAAAAH/+AAAAAAAAf/8AAAAAAAD//4AAAAAAAf//wAAAAAAD///wAAAAAA////gAAAAAH////AAAAAA/////AAAAAP/////AAAAD//////AAAA///////wAA////KAAAADAAAABgAAAAAQAgAAAAAACAJQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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QyX/tkMlZuNULpriUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+8rSj/v////+/WkD+tUIk/rZDJf+1QiT+tUIk/rZDJf+1QiT+7M/I/uzPyP+1QiT+tUIk/rZDJf+1QiT+tUIk/rZDJf+/WkD+/////9+sn/61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+uEQlm+NULsTiUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+8rSj/v////+/WkD+tUIk/rZDJf+1QiT+tUIk/rZDJf+1QiT+7M/I/uzPyP+1QiT+tUIk/rZDJf+1QiT+tUIk/rZDJf+/WkD+/////9+sn/61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP67RSb+1k8rxONULuTjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8rSj//////+/WkD/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/7NDI/+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+/WkD//////9+sn/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/79GJv/eUi3/41Qu5ONULvniUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+8rSj/v////+/WkD+tUIk/rZDJf+1QiT+tUIk/rZDJf+1QiT+7M/I/uzPyP+1QiT+tUIk/rZDJf+1QiT+tUIk/rZDJf+/WkD+/////9+sn/61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+xUgn/+FTLf7iUy3+4lMt+eNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+8rSj/v////+/WkD+tUIk/rZDJf+1QiT+tUIk/rZDJf+1QiT+7M/I/uzPyP+1QiT+tUIk/rZDJf+1QiT+tUIk/rZDJf+/WkD+/////9+sn/61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+tkMl/7ZDJf7LSyn+4lMt/+JTLf7iUy3+4lMt/uNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8rSj//////+/WkD/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/7NDI/+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+/WkD//////9+sn/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/t0Ml/9JNKv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvniUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+8rSj/v////+/WkD+tUIk/rZDJf+1QiT+tUIk/rZDJf+1QiT+7M/I/uzPyP+1QiT+tUIk/rZDJf+1QiT+tUIk/rZDJf+/WkD+/////9+sn/61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP65RCX+108r/+JTLf7iUy3+41Qu/+JTLf7iUy3+4lMt+eNULuTiUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+8rSj/v////+/WkD+tUIk/rZDJf+1QiT+tUIk/rZDJf+1QiT+7M/I/uzPyP+1QiT+tUIk/rZDJf+1QiT+tUIk/rZDJf+/WkD+/////9+sn/61QiT+tkMl/7VCJP61QiT+tkMl/71FJv7cUSz+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+4lMt5ONULsTjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+VhPf/99/X/////////////////58G3/7ZDJf+2QyX/tkMl/86Bbf/+/v7////////////+/v7/z4Rw/7ZDJf+2QyX/tkMl/+a/tf/////////////////89/b/u1A0/7ZDJf+2QyX/wUcn/99SLf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuxONULpriUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+6HNU//zv6/7+/f3+/v7+/v/////+/v7+9unm/ujEuv/oxLr+6MS6/u/Vz//+/v7+/v7+/v/////+/v7+79bQ/ujEuv/oxLr+5byy/vTk4P/+/v7+//////7+/v79/Pv+9ebi/75XPP7HSSj+4VMt/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+4lMtmuNULmXiUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+6X1g//7+/v7+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+//////7+/v7+/v7+/vz8/9hmR/7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+4lMtZeNULiTjVC7941Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+qCZ//64dv///7+//////////////////////////////////////////////////////////////////////////////////////////////////7+/v/52tL/6Xpc/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7941QuJONULgLiUy3S4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7jWDP+756J/v3z8P/+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/O7q/+2Vff7jVjH+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3S4lMtAgAAAADjVC5741Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+VjQf/zu6z//v38//////////////////////////////////////////////////////////////////76+f/ysaD/5F47/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC57AAAAAAAAAADiUy0b4lMt9uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+4lMt/uNULv/iUy3+6HVW/vjWzP/+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v3+9s3C/uduTv/iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLfbiUy0bAAAAAAAAAAAAAAAA4lMtn+NULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+4lMt/uNULv/iUy3+4lMt/uNVMP/skHf+++rm/v/////+/v7+/v7+/v/////+/v7+/v7+/vrk3v/rhmz+41Qu/uNULv/iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLZ4AAAAAAAAAAAAAAAAAAAAA41QuIeNULvjjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5Fw4//Gtm//++fj////////////99fL/76OO/+NZNP/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu+ONULiEAAAAAAAAAAAAAAAAAAAAAAAAAAONULoXiUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/makn+9MGz/vO7q//lZEL+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41QuhQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgviUy3W4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3W41QuCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4z41Qu9eNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvXjVC4zAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMtXeNULv3iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/eJTLV0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULnjiUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41QueAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgHjVC5441Qu/eNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv3jVC5441QuAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMtXeNULvXiUy3+41Qu/+JTLf7iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/i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iXb/0Yl2/+jGvf///////////+3TzP/RiXb/0Yl2//Lg2////////////+G0qP+3Ryr/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyWlAAAAAONULhLjVC7441Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41cy/++hjP/v1c//vFQ4/7ZDJf+2QyX/uUwv/9+sn//frJ//uk4y/7ZDJf+2QyX/u1E1/+/Vz//XmIf/uEks/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJfi2QyUT41QuX+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/7ZR8/+zQyP+2QyX/tkMl/7ZDJf+2QyX/2qGS/9qhkv+2QyX/tkMl/7ZDJf+2QyX/7NDI/9GJdv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJWDjVC6h41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/tlHz/7NDI/7ZDJf+2QyX/tkMl/7ZDJf/aoZL/2qGS/7ZDJf+2QyX/tkMl/7ZDJf/s0Mj/0Yl2/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMlouNULtHjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+2UfP/s0Mj/tkMl/7ZDJf+2QyX/tkMl/9qhkv/aoZL/tkMl/7ZDJf+2QyX/tkMl/+zQyP/RiXb/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/HSSjR41Qu8ONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/7ZR8/+zQyP+2QyX/tkMl/7ZDJf+2QyX/2qGS/9qhkv+2QyX/tkMl/7ZDJf+2QyX/7NDI/9GJdv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/0E0q/+NULvDjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/tlHz/7NDI/7ZDJf+2QyX/tkMl/7ZDJf/aoZL/2qGS/7ZDJf+2QyX/tkMl/7ZDJf/s0Mj/0Yl2/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/uEQl/9ZPK//jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+2UfP/s0Mj/tkMl/7ZDJf+2QyX/tkMl/9qhkv/aoZL/tkMl/7ZDJf+2QyX/tkMl/+zQyP/RiXb/tkMl/7ZDJf+2QyX/tkMl/7tFJv/bUSz/41Qu/+NULv/jVC7/41Qu8ONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/7ZR8/+zQyP+2QyX/tkMl/7ZDJf+2QyX/2qGS/9qhkv+2QyX/tkMl/7ZDJf+2QyX/7NDI/9GJdv+2QyX/tkMl/7ZDJf/ARif/31It/+NULv/jVC7/41Qu/+NULvDjVC7R41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Yx//Gtm/////////////Da1P+/WkD/v1pA/+K0qf///////////+K2qv+/WkD/vVc8/+/X0P///////////9qhkv+2RCb/xUko/+FTLf/jVC7/41Qu/+NULv/jVC7/41Qu0eNULqHjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/ncVL//////////////////////////////////////////////////////////////////////////////////v39/9RfQP/iUy3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC6h41QuX+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/qg2j/+uPd//////////////////////////////////////////////////////////////////nf2P/pfWH/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULl/jVC4S41Qu+ONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVzL/76CL//308v////////////////////////////////////////////zx7v/umYP/41Yw/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7441QuEgAAAADjVC6k41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5WJA//S8rf/+/f3///////////////////////78+//ztaX/5F88/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULqMAAAAAAAAAAONULivjVC7841Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+h2WP/4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iXb+0Yl2/tGJdv7NgGz+tkMl/rVCJP61QiT+tkMl9bdDJSQAAAAAAAAAAONULq7iUy3+41Qu/+NULv/ma0v+/vz8///////+/v7+/////////////////v7+/v/////+/v7+///////////+/Pz+wF1D/7ZDJf+1QiT+tkMl/7ZDJa4AAAAA4FMtJeNULvziUy3+41Qu/+NULv/iUy3+6oRp//zv7P/dqZv+uEgr/71WO//sz8f/7M/H/sBeRP+4SCv+2qCR//ju6//OgW3+tkMl/7ZDJf+1QiT+tkMl/7ZDJf22QyUm4lMtfeJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/vjZ0f66TjL+tUIk/rVCJP7RiXb+0Yl2/rVCJP61QiT+uk4y/u/Vz/61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP62QyV+41Quv+NULv/iUy3+41Qu/+NULv/iUy3+41Qu//jZ0f+6TjL+tkMl/7ZDJf/RiXb/0Yl2/rZDJf+1QiT+uk4y/+/Vz/+1QiT+tkMl/7ZDJf+1QiT+tkMl/7ZDJf+2QyXA41Qu6eNULv/iUy3+41Qu/+NULv/iUy3+41Qu//jZ0f+6TjL+tkMl/7ZDJf/RiXb/0Yl2/rZDJf+1QiT+uk4y/+/Vz/+1QiT+tkMl/7ZDJf+1QiT+tkMl/7hDJf/UTivp41Qu/eNULv/iUy3+41Qu/+NULv/iUy3+41Qu//jZ0f+6TjL+tkMl/7ZDJf/RiXb/0Yl2/rZDJf+1QiT+uk4y/+/Vz/+1QiT+tkMl/7ZDJf+1QiT+u0Um/9pQLP/iUy394lMt/eJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/vjZ0f66TjL+tUIk/rVCJP7RiXb+0Yl2/rVCJP61QiT+uk4y/u/Vz/61QiT+tUIk/rVCJP6/Rib+3lIt/uJTLf7iUy3941Qu6eNULv/iUy3+41Qu/+NULv/iUy3+6oBj//vs6P/Wl4b+tkMl/7xSN//oxLr/6MS6/rxTN/+1QiT+1paG//fq5//Ic13+tkMl/8VIKP/hUy3+41Qu/+NULv/iUy3p4lMtv+JTLf7iUy3+4lMt/uJTLf7lZkT+/vr5/v7+/v78+fj+8+Hc/vXm4v7+/v7+/v7+/vXm4v7y39r+/Pj3/v7+/v789/b+0FY2/uJTLf7iUy3+4lMt/uJTLf7i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', - } + local specialContact = { + name = 'Banque', + number = 'banker', + base64Icon = 'data:image/x-icon;base64,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RCU6uEMlDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4w41Qub+NULqfjVC7b41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/4FMt/8RIJ/+2QyX/tkMl/7ZDJf+2QyX/tkMl4LhEJay2QyVyuEQlNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyXfuUQlZLhEJQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4841Quz+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/gUy3/xkko/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/t0Ml07dDJUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4U41Quo+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/j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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC5341Qu++NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/2lAs/7tFJv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX8uEQlfQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4M41Qup+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/9FNKv+4QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4o41Qu5+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/cUSz/vUUm/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl6rZDJSsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuGONULt/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/1E4r/7hDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl4rdDJRsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgzjVC7L41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/4lMt/8pKKf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/t0MlzrdDJQ4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Qup+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/95SLf/BRyf/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/uEQlrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULnfjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/ZUCv/ukQm/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/uEQlfQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC5E41Qu++NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/0E0q/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX8uUQlSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuFONULuPjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/4FMt/8ZJKP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyXmt0MlFgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC6v41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/91RLP++Rib/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+4RCWzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuYONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/WTyv/uEQl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+5RCVlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhTjVC7v41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/zEsp/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJfG3QyUWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Quo+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/lZEH/9se6//78/P///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////vz7/+jEu/++Vz3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7lEJagAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULjzjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5WE+//rk3v////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////fq5/+8VDn/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7dDJUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4E41Quz+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/0v7H//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+S4rf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/t0Ml07hEJQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULmDjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//75+P///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Pn4/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/uUQlZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4I41Qu3+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyXfuEMlCQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULm/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/++fj///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////z5+P+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+5RCV0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4E41Qu3+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+6Xf//+/Pz////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+/Pv/0499/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJeO4RCUEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULlzjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+ZmRf/umYP/8amW//vn4v//////////////////////////////////////////////////////+vPx/9uklf/aoZL/2qGS/9qhkv/aoZL/2qGS/9qhkv/aoZL/2qGS/9qhkv/aoZL/8NnS///////////////////////////////////////////////////////8+fj/3qmc/9qhkv/aoZL/2qGS/9qhkv/aoZL/2qGS/9qhkv/aoZL/2qGS/9qhkv/rzcX///////////////////////////////////////////////////////78+//hsqb/1pWE/79aQP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Quz+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/riW//////////////////////////////////////////////////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTv/////////////////////////////////////////////////////////////////jua3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/u1E2//78+////////////////////////////////////////////////////////////+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/t0Ml0wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULjjjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+uJb//////////////////////////////////////////////////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/w2ZO/////////////////////////////////////////////////////////////////+O5rf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+7UTb//vz7////////////////////////////////////////////////////////////7NDI/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/uEQlPQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Qun+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+2Ref/xqZb/8amW//jUyv//////////////////////2qGS/9qhkv/aoZL/1pWE/7dGKP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/y3tl/9qhkv/aoZL/2qGS///////////////////////aoZL/2qGS/9qhkv/Ym4v/uUsv/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/Hb1j/2qGS/9qhkv/aoZL//////////////////////+zQyP/aoZL/2qGS/9mejv+8VDn/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+5RCWjAAAAAAAAAAAAAAAAAAAAAAAAAAAA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VC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7hEJawAAAAAAAAAAAAAAAAAAAAA41Qu7+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl8QAAAAAAAAAAAAAAAONULjDjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/uEQlNQAAAAAAAAAA41Qub+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyVyAAAAAAAAAADjVC6n41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7hEJawAAAAAAAAAAONULtvjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl4AAAAADjVC4M41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/vUUmDuNULjTjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/79GJv/QTCo141QuXONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/FSCf/4VMt/9ZPK1zjVC6D41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/zEsp/+NULv/jVC7/3lItg+NULp/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9JOKv/jVC7/41Qu/+NULv/jVC6f41Quv+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7pEJf/YUCv/41Qu/+NULv/jVC7/41Qu/+NULr/jVC7X41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+9RSb/3FEs/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu1+NULuPjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/wUcn/+BTLf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7j41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8hJKP/iUy3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/OTCr/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+4QyX/1U8r/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/ukQm/9pQLP/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/75GJv/eUi3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/DSCf/4FMt/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/y0op/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9FNKv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULuPjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7hEJf/XTyv/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7j41Qu1+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+9RSb/3FEs/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULtfjVC6/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/wEcn/99SLf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Quv+NULp/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8ZJKP/iUy3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC6f41Qug+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+h3WP/87+v//////////////////////////////////////////////////////+3QyP+4SSv/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/uk4y//Hc1v//////////////////////////////////////////////////////8t/Z/7tRNv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+3Rij/7M3F///////////////////////////////////////////////////////68/H/yHJb/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/NSyn/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULoPjVC5c41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/9Lyt/////////////////////////////////////////////////////////////////86BbP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/UkoH/////////////////////////////////////////////////////////////////15iI/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8t7Zv/////////////////////////////////////////////////////////////////juK3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+4QyX/004q/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuXONULjTjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5mZE/+ZpSP/voY3/////////////////////////////////////////////////////////////////y3tm/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9KMev/////////////////////////////////////////////////////////////////WlYT/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/yXVf////////////////////////////////////////////////////////////+/b1/9GJdv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/ukQl/9lQLP/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC4041QuDONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+qBZf////////////////////////////////////////////////////////////////////////////v29f/aoZL/2qGS/9qhkv/aoZL/2qGS/9qhkv/aoZL/2qGS/9qhkv/aoZL/3KeY//35+P///////////////////////////////////////////////////////vz7/9ynmP/aoZL/2qGS/9qhkv/aoZL/2qGS/9qhkv/Ym4v/0Yp3/9GKd//Rinf/+O3r///////////////////////////////////////////////////////////////////////58O7/vFQ5/7ZDJf+2QyX/tkMl/71GJv/eUi3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULgwAAAAA41Qu2+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/+NfO///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Ym4v/tkMl/7ZDJf/DSCf/4FMt/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7bAAAAAAAAAADjVC6n41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/76uX//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+O4rf+2QyX/yUop/+JTLf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULqcAAAAAAAAAAONULm/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//nc1P//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////2ZuL/9BNKv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QubwAAAAAAAAAA41QuMONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/7I92//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////nt6v/cYD//41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC4wAAAAAAAAAAAAAAAA41Qu7+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/6Xxf//rf2P/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////1xrr/5WlI/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu7wAAAAAAAAAAAAAAAAAAAADjVC6n41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Yx/+6Zg//88e7////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////64dv/6oFl/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC6nAAAAAAAAAAAAAAAAAAAAAONULlzjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+ReO//zt6f//vz8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////99PL/75yG/+NWMf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULlwAAAAAAAAAAAAAAAAAAAAA41QuFONULvvjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/ocVL/99HH///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+/Pz/87mq/+VhPv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7741QuFAAAAAAAAAAAAAAAAAAAAAAAAAAA41Quu+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/7Ixz//vp5f//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+NfO/+h0Vf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULrsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC5k41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5Fk0//Cnk//++fj/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////++nl/+yPdv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgzjVC7341Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+ZmRf/1xLf//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////vn4//Gplv/kWTT/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvfjVC4MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULp/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/pfF//+t/Y//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////XEt//maUj/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QunwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuOONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVjH/7peA//zx7v////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////rh2//qf2L/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC44AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Quz+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5F47//K0o//+/Pz///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////308v/umYP/41Yx/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuzwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC5c41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+dvTv/30cf///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////78/P/zt6f/5F47/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC5cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgTjVC7j41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/siW//++fi///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30cf/6HFS/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu3+NULgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULm/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/kWTT/8KeT//339f/////////////////////////////////////////////////////////////////////////////////////////////////76eX/7Ixz/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC5vAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuCONULt/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5mZF//XCtP/////////////////////////////////////////////////////////////////////////////////++fj/8KeT/+RZNP/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu3+NULggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuYONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+l8X//53NX/////////////////////////////////////////////////////////////////9cS3/+ZmRf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC5gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4E41Quz+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NWMf/ul4D//PHu////////////////////////////////////////////+dzV/+l8X//jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Quz+NULgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4841Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/kXjv/8rGg//78/P///////////////////////PHu/+6XgP/jVjH/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC48AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC6j41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/6HdY//fPxP/++fj//PLv//S8rf/mZkX/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuowAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhTjVC7v41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULu/jVC4UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULmDjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULq/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULq8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuFONULuPjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7j41QuFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuRONULvvjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu++NULkQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Qud+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC53AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Qup+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QupwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4M41Quy+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULsvjVC4MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4Y41Qu3+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7f41QuGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4o41Qu5+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu5+NULigAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4o41Qu8+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvPjVC4oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4841Qu8+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7z41QuPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4o41Qu5+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu5+NULigAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4o41Qu3+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULt/jVC4oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4Y41Quy+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7L41QuGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4M41Quq+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qup+NULgwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Qud+NULvvjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu++NULncAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuRONULuPjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULuPjVC5EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuFONULq/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC6v41QuFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULmDjVC7v41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7v41QuYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhTjVC6j41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Quo+NULhQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4841Quz+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Quz+NULjwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4E41QuYONULt/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu3+NULmDjVC4EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuCONULm/jVC7f41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu3+NULm/jVC4IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgTjVC5c41Quz+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Quz+NULlzjVC4EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuOONULp/jVC7341Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7341Qun+NULjgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgzjVC5k41Quu+NULvvjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvvjVC6741QuZONULgwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuFONULlzjVC6n41Qu7+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu7+NULqfjVC5c41QuFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuMONULm/jVC6n41Qu2+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULtvjVC6n41Qub+NULjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuDONULjTjVC5c41Qug+NULp/jVC6/41Qu1+NULuPjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULuPjVC7X41Quv+NULp/jVC6D41QuXONULjTjVC4MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////AAAA////////////////8AAAAA///////////////wAAAAAA//////////////gAAAAAAB/////////////gAAAAAAAH////////////AAAAAAAAAP///////////AAAAAAAAAA///////////AAAAAAAAAAD//////////gAAAAAAAAAAf/////////gAAAAAAAAAAB/////////wAAAAAAAAAAAP////////wAAAAAAAAAAAA////////4AAAAAAAAAAAAH///////8AAAAAAAAAAAAA///////8AAAAAAAAAAAAAD//////+AAAAAAAAAAAAAAf//////AAAAAAAAAAAAAAD//////gAAAAAAAAAAAAAAf/////wAAAAAAAAAAAAAAD/////4AAAAAAAAAAAAAAAf////8AAAAAAAAAAAAAAAD////+AAAAAAAAAAAAAAAAf////AAAAAAAAAAAAAAAAD////wAAAAAAAAAAAAAAAA////4AAAAAAAAAAAAAAAAH///8AAAAAAAAAAAAAAAAA///+AAAAAAAAAAAAAAAAAH///gAAAAAAAAAAAAAAAAB///wAAAAAAAAAAAAAAAAAP//4AAAAAAAAAAAAAAAAAB//+AAAAAAAAAAAAAAAAAAf//AAAAAAAAAAAAAAAAAAD//gAAAAAAAAAAAAAAAAAAf/4AAAAAAAAAAAAAAAAAAH/8AAAAAAAAAAAAAAAAAAA//AAAAAAAAAAAAAAAAAAAP/gAAAAAAAAAAAAAAAAAAB/4AAAAAAAAAAAAAAAAAAAf+AAAAAAAAAAAAAAAAAAAH/AAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAP4AAAAAAAAAAAAAAAAAAAB+AAAAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAAAAAAHwAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAAAABwAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAA+AAAAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAAAAAAH4AAAAAAAAAAAAAAAAAAAB/AAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAP+AAAAAAAAAAAAAAAAAAAH/gAAAAAAAAAAAAAAAAAAB/4AAAAAAAAAAAAAAAAAAAf/AAAAAAAAAAAAAAAAAAAP/wAAAAAAAAAAAAAAAAAAD/+AAAAAAAAAAAAAAAAAAB//gAAAAAAAAAAAAAAAAAAf/8AAAAAAAAAAAAAAAAAAP//gAAAAAAAAAAAAAAAAAH//4AAAAAAAAAAAAAAAAAB///AAAAAAAAAAAAAAAAAA///4AAAAAAAAAAAAAAAAAf//+AAAAAAAAAAAAAAAAAH///wAAAAAAAAAAAAAAAAD///+AAAAAAAAAAAAAAAAB////wAAAAAAAAAAAAAAAA////8AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAAH////8AAAAAAAAAAAAAAAD/////gAAAAAAAAAAAAAAB/////8AAAAAAAAAAAAAAA//////gAAAAAAAAAAAAAAf/////8AAAAAAAAAAAAAAP//////gAAAAAAAAAAAAAH//////8AAAAAAAAAAAAAD///////wAAAAAAAAAAAAD///////+AAAAAAAAAAAAB////////wAAAAAAAAAAAA/////////AAAAAAAAAAAA/////////4AAAAAAAAAAAf/////////gAAAAAAAAAAf/////////8AAAAAAAAAAP//////////wAAAAAAAAAP///////////AAAAAAAAAP///////////+AAAAAAAAf////////////4AAAAAAAf/////////////wAAAAAA///////////////wAAAAD////////////////wAAAP////////KAAAAGAAAADAAAAAAQAgAAAAAACAlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4I41QuKeJTLU7jVC5341Qum+JTLb3j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QiT+tUIk/rVCJP62QyX7tkMlXQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMtDuNULuTjVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/8a6c/v///////////v7+/v///////////v7+/v////////////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/tymmP+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tkMl5rdDJQ8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMteONULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/99PJ/v///////////v7+/v///////////v7+/v////////////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/uzOx/+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rhEJXsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy0Y4lMt6OJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+99HH/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/uvMxP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rZDJei3QyUaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC584lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/6Xlb/vrh2v/+/Pv//v7+/v///////////v7+/v////////////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v/////+/f3/8+Db/sZuVv+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+4RCV/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhDjVC7f4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uRbNv/nbk3/+NjP/v///////////v7+/v////////////////7+/v7+/Pz/2qCR/79aQP6/WkD/v1pA/79aQP6/WkD/v1pA/79aQP7bpJb//vz8//7+/v7///////////7+/v7///////////7+/v7t0sv/wV9F/79aQP6/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QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyVrAAAAAAAAAADiUy2s4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7maUj+/v7+/v7+/v7+/v7+yHFb/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7aoZL+/v7+/v7+/v7aoJH+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/shyW/7+/v7+/v7+/v7+/v6/WkD+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP63QyWwAAAAAONULgjjVC7g4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyXhtkMlCeNULinjVC7z4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX1uUQlLOJTLU7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7maUj+/v7+/v7+/v7+/v7+yHFb/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7aoZL+/v7+/v7+/v7aoJH+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/shyW/7+/v7+/v7+/v7+/v6/WkD+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+vkYmT+NULnfjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf/FSSf/1U4rd+NULpvjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/stLKf/hUy3/3lIsm+JTLb3iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7maUj+/v7+/v7+/v7+/v7+yHFb/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7aoZL+/v7+/v7+/v7aoJH+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/shyW/7+/v7+/v7+/v7+/v6/WkD+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP64QyX+0U0q/uJTLf7iUy3+4lMtveNULtbjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rpEJf/WTyv/4lMt/uNULv/jVC7/4lMt1uNULunjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/vEUm/ttRLP/jVC7/4lMt/uNULv/jVC7/4lMt6eJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7maUj+/v7+/v7+/v7+/v7+yHFb/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7aoZL+/v7+/v7+/v7aoJH+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/shyW/7+/v7+/v7+/v7+/v6/WkD+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7CRyf+31It/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tkMl/shJKP/gUy3/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/zUsp/uJTLf/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7maUj+/v7+/v7+/v7+/v7+yHFb/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7aoZL+/v7+/v7+/v7aoJH+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/shyW/7+/v7+/v7+/v7+/v6/WkD+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rhEJf7UTiv+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/u0Um/tlQK//iUy3/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+/Rib/3FEs/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uJTLeniUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7maUj+/v7+/v7+/v7+/v7+yHFb/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7aoZL+/v7+/v7+/v7aoJH+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/shyW/7+/v7+/v7+/v7+/v6/WkD+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/sRIJ/7gUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt6eNULtbjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/ykop/uFTLf/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt1uNULr3jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lQu/uNULv/maUj//v7+/v//////////yHJb/7ZDJf62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7ZDJf7aoZL///////7+/v7aoZL/tkMl/7ZDJf62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tkMl/shyW////////v7+/v////+/WkD/tkMl/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rdDJf/PTCn/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMtveJTLZviUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7lYkD++uLc/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v769PL+x29Y/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7aoZL+/v39/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v79/f7cppj+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/sZsVP768vD+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/vXm4v69Vjv+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+uUQl/tZPK/7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMtm+NULnfjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNYM//odFX//vz7/v///////////v7+/v////////////////7+/v7/////26KT/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7z4Nv///////7+/v7///////////7+/v7///////////7+/v7049//tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/tmfkP///////v7+/v///////////v7+/v///////////v7+/v35+P/DZEz/tUIk/rZDJf+2QyX/tUIk/rZDJf+9RSb/2lAs/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMtd+JTLU7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+521N/vnd1v764dr+/vr6/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/f3+3que/tGJdv7RiXb+0Yl2/tGJdv7RiXb+0Yl2/tGJdv7sz8f+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7u08z+0Yl2/tGJdv7RiXb+0Yl2/tGJdv7MfWj+ynhi/teaif79+/v+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/vr08v7t0sv+6ce+/rlMMP61QiT+tUIk/sBHJ/7eUiz+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMtTeNULinjVC7z4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/87mq/v///////////v7+/v///////////v7+/v////////////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/tGKeP+2QyX/xkko/uFTLf/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7z4lMtKeNULgjjVC7g4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/9MG0/v///////////v7+/v///////////v7+/v////////////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/taSgf/MSyn/4VMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7g4lMtBwAAAADiUy2s4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+7Ixy/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7++/Xz/ttmRv7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy2sAAAAAAAAAADjVC5p4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uqAZP/52tL//v7+/v///////////v7+/v////////////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v79/P/2zMD/53BR/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC5pAAAAAAAAAADjVC4o4lMt+ONULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/kXDj/7pmD/vzv6////v7//v7+/v////////////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v/////+/v7/+uTe/uuJb//jWDP/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULvjjVC4oAAAAAAAAAADiUy0I4lMtzeJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uVmRP7zuKj+/vr6/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v318/7wppL+5F06/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLc3iUy0IAAAAAAAAAAAAAAAA4lMtf+NULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/6HNU/vfRx//+/f3///////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v/////++vn/9cG0/uZmRP/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULn8AAAAAAAAAAAAAAAAAAAAA4lMtKONULv3jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNYM//sj3b/+uTf//7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v39/vjXzv/pfWH/41Uw/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/eNULigAAAAAAAAAAAAAAAAAAAAAAAAAAOJTLcbiUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+5F87/vGrmP799/X+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v787er+7piC/uNYMv7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMtxgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULl3jVC7+4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7makn/9cG0//77+/7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////fb1/vKwn//lYDz/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7+4lMtXQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhDjVC7f4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Yw/+qCZv752tL//v39//7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v77+v/2y8D/6HRV/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7f4lMtDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy1+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7kWzb+7pqD/vzx7v7+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VC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+NULv7nb1D/76CL/+6Zgv7mZkT/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC644lMtBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy0u4lMt8OJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLfDiUy0uAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMtauNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULmoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMtA+NULrHjVC7+41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7+4lMtsONULgMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOJTLRriUy3a4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3a4lMtGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4041Qu7OJTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULuzjVC40AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuU+JTLfnjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt+eNULlMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOJTLXHiUy364lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy364lMtcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC534lMt/ONULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULvzjVC53AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4E4lMtd+NULvrjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt+uNULnfjVC4EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOJTLXHiUy354lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy354lMtcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC5T4lMt7eNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULuzjVC5TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMtNeNULtrjVC7+4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7+4lMt2uNULjQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOJTLRriUy2x4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy2w4lMtGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4D4lMtauNULvDjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt8ONULmrjVC4DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULi7jVC644lMt++NULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULvvjVC644lMtLgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy0G4lMtWuJTLeTiUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt5OJTLVriUy0FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULg7jVC544lMt6ONULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULujjVC544lMtDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMtGONULnzjVC7f4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv7jVC7f4lMte+NULhgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy0P4lMtXeJTLcbiUy394lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy394lMtxuJTLV3iUy0PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4o41QugOJTLc3jVC7441Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC744lMtzeNULn/jVC4oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOJTLQjjVC4o41QuaeJTLazjVC7g41Qu8+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULvPjVC7g4lMtrONULmnjVC4o4lMtCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy0H4lMtKeJTLU3iUy134lMtm+JTLb3iUy3W4lMt6eJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLeniUy3W4lMtveJTLZviUy134lMtTeJTLSniUy0HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////4AAAf//////////+AAAAB//////////4AAAAAf/////////AAAAAAD////////8AAAAAAA////////wAAAAAAAP///////AAAAAAAAD//////+AAAAAAAAB//////4AAAAAAAAAf/////wAAAAAAAAAP/////gAAAAAAAAAH/////AAAAAAAAAAD////+AAAAAAAAAAB////4AAAAAAAAAAAf///4AAAAAAAAAAAf///wAAAAAAAAAAAP///gAAAAAAAAAAAH///AAAAAAAAAAAAD//+AAAAAAAAAAAAB//8AAAAAAAAAAAAA//8AAAAAAAAAAAAA//4AAAAAAAAAAAAAf/wAAAAAAAAAAAAAP/wAAAAAAAAAAAAAP/gAAAAAAAAAAAAAH/gAAAAAAAAAAAAAH/AAAAAAAAAAAAAAD/AAAAAAAAAAAAAAD+AAAAAAAAAAAAAAB+AAAAAAAAAAAAAAB+AAAAAAAAAAAAAAB8AAAAAAAAAAAAAAA8AAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAA+AAAAAAAAAAAAAAB+AAAAAAAAAAAAAAB+AAAAAAAAAAAAAAB/AAAAAAAAAAAAAAD/AAAAAAAAAAAAAAD/gAAAAAAAAAAAAAH/gAAAAAAAAAAAAAH/wAAAAAAAAAAAAAP/wAAAAAAAAAAAAAP/4AAAAAAAAAAAAAf/8AAAAAAAAAAAAA//8AAAAAAAAAAAAA//+AAAAAAAAAAAAB///AAAAAAAAAAAAD///gAAAAAAAAAAAH///wAAAAAAAAAAAP///4AAAAAAAAAAAf///4AAAAAAAAAAAf///+AAAAAAAAAAB/////AAAAAAAAAAD/////gAAAAAAAAAH/////wAAAAAAAAAP/////4AAAAAAAAAf/////+AAAAAAAAB///////AAAAAAAAD///////wAAAAAAAP///////8AAAAAAA/////////AA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QiT+tkMl/7ZDJf+1QiT+tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7ZDJf+1QiT+tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7dDJaa2QyUCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULlXjVC7941Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVjH/42dF/8heQv+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/vlk+/7dGKP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf23QyVXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuDuNULt/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NYM//2yLz//v39/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////v38/+nHv/+4SCv/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyXgtkMlDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMthuNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/++eiP/+/v7+//////7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+//////7+/v7///////////7+/v7//////v7+/v/////+/v7+//////7+/v7VlIP/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/t0MliQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4d41Qu8ONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//K0o//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////frJ//tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl8LdDJR4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC6N4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+p/Y//77On+/v7+//7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+//////7+/v7///////////7+/v7//////v7+/v/////+/v7+//////fs6f7JdF3/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rdDJZAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhXjVC7s41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/kWzf/76CL//7+/v///////////////////////////+W+s/+8VDn/vFQ5/7xUOf+8VDn/vFQ5/9aWhf/+/f3////////////////////////////mv7X/vFQ5/7xUOf+8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QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl8rZDJRjjVC5D41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/sjnX////////////DZk3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/v1pA////////////v1pA/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTf///////////8+Db/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7hDJUXjVC5041Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7sjnX//v7+/v/////DZk3+tkMl/7ZDJf+1QiT+tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+v1pA///////+/v7+v1pA/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/8NmTf7//////v7+/s+Db/+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7tFJXXjVC6d41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/sjnX////////////DZk3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/v1pA////////////v1pA/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTf///////////8+Db/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/wEYm/9ZPK53jVC7B41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7sjnX//v7+/v/////DZk3+tkMl/7ZDJf+1QiT+tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+v1pA///////+/v7+v1pA/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/8NmTf7//////v7+/s+Db/+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf/FSCf+4FMt/+FTLcHjVC7e41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/sjnX////////////DZk3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/v1pA////////////v1pA/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTf///////////8+Db/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8tLKf/iUy3/41Qu/+NULt7jVC7y41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7sjnX//v7+/v/////DZk3+tkMl/7ZDJf+1QiT+tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+v1pA///////+/v7+v1pA/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/8NmTf7//////v7+/s+Db/+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP63QyX/0U0q/uJTLf/iUy3+41Qu/+JTLfLjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/sjnX////////////DZk3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/v1pA////////////v1pA/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTf///////////8+Db/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7pEJf/XTyv/4lMt/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/sjnX////////////DZk3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/v1pA////////////v1pA/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTf///////////8+Db/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/vUUm/9tRLP/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7sjnX//v7+/v/////DZk3+tkMl/7ZDJf+1QiT+tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+v1pA///////+/v7+v1pA/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/8NmTf7//////v7+/s+Db/+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP7CRyf/31It/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/sjnX////////////DZk3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/v1pA////////////v1pA/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTf///////////8+Db/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8dJKP/hUy3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7y41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7sjnX//v7+/v/////DZk3+tkMl/7ZDJf+1QiT+tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+v1pA///////+/v7+v1pA/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/8NmTf7//////v7+/s+Db/+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX+zkwp/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLfLjVC7e41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/sjnX////////////DZk3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/v1pA////////////v1pA/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTf///////////8+Db/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7hEJf/UTir/4lMt/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULt7jVC7B41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+6HJT//Cplv71xrr//v7+/v/////hsqb+2qCR/8FfRv+1QiT+tkMl/7VCJP62QyX/tUIk/sBeRf/aoJH+36yf///////+/v7+36yf/9qgkf7BYEb/tUIk/rZDJf+1QiT+tkMl/7VCJP7AXkX/2p+Q/+Gypv7//////v7+/ufBt//aoJH+xGhQ/7VCJP62QyX/tkMl/7VCJP62QyX/u0Qm/tlQK//iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLcHjVC6d41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVzL/9L2v/////////////////////////////////+K2qv+2QyX/tkMl/7ZDJf+2QyX/tkMl/+K0qP/////////////////////////////////juKz/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/hs6f/////////////////////////////////47es/7ZDJf+2QyX/tkMl/7ZDJf+/Rib/3VEs/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULp3jVC5041Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+hyU//65uD+/PHu//7+/v7//////v7+/v/////+/v7+/////+zPx//cppj+3KaY/9ymmP7cppj/3KaY/uzOxv/+/v7+///////////+/v7+//////7+/v7s0Mj/3KaY/tymmP/cppj+26OU/9eZif7oxLr///////7+/v7//////v7+/v/////+/v7+9ujl/+/X0P68Uzj/tkMl/8NIJ/7gUi3/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLXTjVC5D41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Cnk//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////OgGz/ykop/+JTLf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULkLjVC4X41Qu8eJTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+uHbP/+/v7+//////7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+//////7+/v7///////////7+/v7//////v7+/v/////+/v7+//////35+P7aZ0n/4lMt/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu8eJTLRcAAAAA41QuxeNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/qgWb/+d7W///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+/v7/99PJ/+h1Vv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuxQAAAAAAAAAA41QufeNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5Fk1/++diP/88e7//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////v7+//vq5f/skHf/41Yx/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QufQAAAAAAAAAA41QuK+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7lY0D/87mq/v76+f/+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+//////7+/v7///////////7+/v799vT/8auZ/uRcOP/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41QuKwAAAAAAAAAA41QuAuNULs7jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+h3Wf/41Mr//v79/////////////////////////////////////////////////////////////////////////////////////////////////////////////vz8//XGuv/nbEz/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7O41QuAgAAAAAAAAAAAAAAAOJTLWzjVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/jVTD+7ZB4//vo4//+/v7+//////7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+//////7+/v753tf/6oNn/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy1sAAAAAAAAAAAAAAAAAAAAAONULhTjVC7s41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+RcOP/xq5n//fXz/////////////////////////////////////////////////////////////////////////////O/s/++dh//jWDP/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULuzjVC4UAAAAAAAAAAAAAAAAAAAAAAAAAADjVC6P4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+5mxL//XGuv7+/f3//v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v77+v/zuKj+5WNA/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULo0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4d41Qu8ONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NUL//qgWX/+d3W///+/v/////////////////////////////////+/f3/99LI/+h0Vv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu8ONULh0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMthuNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/41k1/u+ch//88u/+///////////+/v7+//////vo4/7sjnX/41Yx/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMthgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuDuNULt/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/lYT7/87us//349v/99PH/8aya/+RaNv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7f41QuDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULlXjVC7941Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+VjQf/lYT3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv3jVC5VAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgLiUy2k41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLaTjVC4CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4T41Qu3ONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu3ONULhMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuN+NULvHiUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7x41QuNwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULljjVC7741Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvvjVC5YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy1z41Qu/OJTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/OJTLXMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Quf+NULvzjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7841QufwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOJTLXPjVC774lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULvviUy1zAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC5Y41Qu8uNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu8eNULlgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuN+NULtzjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7c41QuNwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhPiUy2k41Qu/eNULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/eJTLaTjVC4TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4C41QuVeNULt/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7f41QuVeNULgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULg7iUy2G41Qu8OJTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu8OJTLYbjVC4OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuHeNULo3jVC7s41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULuzjVC6N41QuHQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4U4lMtbONULs7iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7O4lMtbONULhQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgLjVC4r41QufeNULsXjVC7x41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvHjVC7F41QufeNULivjVC4CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy0X41QuQuJTLXTjVC6d4lMtweNULt7iUy3y41Qu/+NULv/iUy3+41Qu/+JTLfLjVC7e4lMtweNULp3iUy1041QuQuJTLRcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD////gAAf///8AAAD///4AAAB///8AAAD///gAAAAf//8AAAD//+AAAAAH//8AAAD//4AAAAAB//8AAAD//gAAAAAAf/8AAAD//AAAAAAAP/8AAAD/+AAAAAAAH/8AAAD/8AAAAAAAD/8AAAD/4AAAAAAAB/8AAAD/wAAAAAAAA/8AAAD/gAAAAAAAAf8AAAD/AAAAAAAAAP8AAAD+AAAAAAAAAH8AAAD8AAAAAAAAAD8AAAD4AAAAAAAAAB8AAAD4AAAAAAAAAB8AAADwAAAAAAAAAA8AAADwAAAAAAAAAA8AAADgAAAAAAAAAAcAAADgAAAAAAAAAAcAAADAAAAAAAAAAAMAAADAAAAAAAAAAAMAAACAAAAAAAAAAAEAAACAAAAAAAAAAAEAAACAAAAAAAAAAAEAAACAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAEAAACAAAAAAAAAAAEAAACAAAAAAAAAAAEAAACAAAAAAAAAAAEAAADAAAAAAAAAAAMAAADAAAAAAAAAAAMAAADgAAAAAAAAAAcAAADgAAAAAAAAAAcAAADwAAAAAAAAAA8AAADwAAAAAAAAAA8AAAD4AAAAAAAAAB8AAAD4AAAAAAAAAB8AAAD8AAAAAAAAAD8AAAD+AAAAAAAAAH8AAAD/AAAAAAAAAP8AAAD/gAAAAAAAAf8AAAD/wAAAAAAAA/8AAAD/4AAAAAAAB/8AAAD/8AAAAAAAD/8AAAD/+AAAAAAAH/8AAAD/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QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJfi3QyUyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuBeNULtPjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/91RLP++Rib/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/t0Ml1bZDJQUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULnfjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41cy//XDtv/+/v7///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////7+/v/nwbf/t0cq/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+3QyV5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhnjVC7z41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+6Ygf///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9OOe/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl9LdDJRoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC6V41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/wqJT////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Zn5D/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+3QyWWAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4Y41Qu9+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5WRC//S/sP/6493////////////////////////////15eH/7NDI/+zQyP/s0Mj/7NDI/+zQyP/79fP///////////////////////79/f/t0sv/7NDI/+zQyP/s0Mj/7NDI//Hb1f////////////////////////////fr6P/kuq//vVY7/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl+LZDJRkAAAAAAAAAAAAAAAAAAAAA41QugeNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/9cS3////////////////////////////7NDI/7ZDJf+2QyX/tkMl/7ZDJf+8VDn/////////////////////////////////zH5p/7ZDJf+2QyX/tkMl/7ZDJf/cp5n////////////////////////////15+P/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyWEAAAAAAAAAAAAAAAA41QuA+NULuXjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+VjQP/qfmL/+d7X///////juK3/yHJb/75YPf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8RoUP/Iclv////////////Iclv/x3BZ/7ZFJ/+2QyX/tkMl/7ZDJf+2QyX/uk4x/8hyW//juK3///////Hb1v/Iclv/wF5E/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl5rZDJQMAAAAAAAAAAONULkfjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//jUyv//////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/2qGS///////s0Mj/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyVKAAAAAAAAAADjVC6a41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/41Mr//////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf///////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9qhkv//////7NDI/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMlnAAAAAAAAAAA41Qu5eNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/+NTK///////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX///////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/aoZL//////+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJecAAAAA41QuJ+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//jUyv//////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/2qGS///////s0Mj/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMlKeNULmDjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/41Mr//////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf///////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9qhkv//////7NDI/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7hDJWPjVC6P41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/+NTK///////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX///////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/aoZL//////+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/ARyeQ41Qut+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//jUyv//////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/2qGS///////s0Mj/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/KSin/3lItt+NULtfjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/41Mr//////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf///////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9qhkv//////7NDI/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7dDJf/RTSr/41Qu/+NULtfjVC7u41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/+NTK///////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX///////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/aoZL//////+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7hEJf/XTyv/41Qu/+NULv/jVC7u41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//jUyv//////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/2qGS///////s0Mj/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7xFJv/cUSz/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/41Mr//////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf///////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9qhkv//////7NDI/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8BHJ//fUi3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/+NTK///////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX///////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/aoZL//////+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8ZJKP/hUy3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//jUyv//////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/2qGS///////s0Mj/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/81LKf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULu7jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/41Mr//////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf///////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9qhkv//////7NDI/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/t0Ml/9NOKv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULu7jVC7X41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/+NTK///////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX///////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/aoZL//////+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/ukQl/9lQLP/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7X41Qut+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/2yLz////////////////////////////cppj/tkMl/7ZDJf+2QyX/tkMl/75ZP//79vT///////////////////////v39f+/XEL/tkMl/7ZDJf+2QyX/tkMl/9ujlP///////////////////////////+nHvv+2QyX/tkMl/7ZDJf+2QyX/vUYm/91RLP/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qut+NULo/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+RfO//ys6L/++fi////////////////////////////6MS7/8hyW//Iclv/yHJb/8hyW//QhXL//v39///////////////////////+/v7/0Ih1/8hyW//Iclv/x3BZ/8NmTv/kurD////////////////////////////y39r/2Z2N/7dHKv+2QyX/wkcn/+BTLf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULo/jVC5g41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/umoP////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////KdmD/yUoo/+JTLf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC5g41QuJ+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/64Rp///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9+vn/2mdI/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuJwAAAADjVC7l41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/qgWX/+uLb///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////42M//6HVX/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu5QAAAAAAAAAA41QumuNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NWMf/vnoj//fPx//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////zt6f/tkXn/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULpoAAAAAAAAAAONULkfjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+ViP//zuqr//v39/////////////////////////////////////////////////////////////////////////////////////////////////////////////vn4//GunP/kXDf/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC5HAAAAAAAAAADjVC4D41Qu5eNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+h0Vv/41s3/////////////////////////////////////////////////////////////////////////////////////////////////9sm9/+ZqSf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7l41QuAwAAAAAAAAAAAAAAAONULoHjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+yOdf/76+f////////////////////////////////////////////////////////////////////////////649z/6oJn/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QugQAAAAAAAAAAAAAAAAAAAADjVC4Y41Qu+ONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5Fo2//Grmf/++ff///////////////////////////////////////////////////////3z8f/vnoj/41Yx/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu9+NULhgAAAAAAAAAAAAAAAAAAAAAAAAAAONULpXjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5mpI//XHu////////////////////////////////////////v39//O6qv/lYj//41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULpUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4Z41Qu8+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/6oBk//rh2///////////////////////+NXM/+h0Vv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvPjVC4ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULnfjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVjH/756I//zx7v/76+b/7JB4/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC53AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4F41Qu0+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7T41QuBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULjDjVC7441Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7441QuMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QubeNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QubQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC6f41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QunwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuBuNULrvjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Quu+NULgYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4K41QuyONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuyONULgoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgrjVC6741Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Quu+NULgoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuBuNULqDjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qun+NULgYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QubeNULvjjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7441QubQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4w41Qu0+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7T41QuMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgXjVC5341Qu8+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvPjVC5341QuBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhnjVC6V41Qu9+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu9+NULpXjVC4ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhjjVC6B41Qu5eNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7l41QugeNULhgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgPjVC5H41QumuNULuXjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu5eNULprjVC5H41QuAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuJ+NULmDjVC6P41Qut+NULtfjVC7u41Qu/+NULv/jVC7/41Qu/+NULu7jVC7X41Qut+NULo/jVC5g41QuJwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAA///////wAAAP/////8AAAAP/////AAAAAP////wAAAAAP///+AAAAAAf///wAAAAAA///8AAAAAAA///gAAAAAAB//8AAAAAAAD//gAAAAAAAH/+AAAAAAAAf/wAAAAAAAA/+AAAAAAAAB/wAAAAAAAAD/AAAAAAAAAP4AAAAAAAAAfgAAAAAAAAB8AAAAAAAAADwAAAAAAAAAOAAAAAAAAAAYAAAAAAAAABgAAAAAAAAAGAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAGAAAAAAAAAAYAAAAAAAAABgAAAAAAAAAHAAAAAAAAAA8AAAAAAAAAD4AAAAAAAAAfgAAAAAAAAB/AAAAAAAAAP8AAAAAAAAA/4AAAAAAAAH/wAAAAAAAA//gAAAAAAAH/+AAAAAAAAf/8AAAAAAAD//4AAAAAAAf//wAAAAAAD///wAAAAAA////gAAAAAH////AAAAAA/////AAAAAP/////AAAAD//////AAAA///////wAA////KAAAADAAAABgAAAAAQAgAAAAAACAJQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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QyX/tkMlZuNULpriUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+8rSj/v////+/WkD+tUIk/rZDJf+1QiT+tUIk/rZDJf+1QiT+7M/I/uzPyP+1QiT+tUIk/rZDJf+1QiT+tUIk/rZDJf+/WkD+/////9+sn/61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+uEQlm+NULsTiUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+8rSj/v////+/WkD+tUIk/rZDJf+1QiT+tUIk/rZDJf+1QiT+7M/I/uzPyP+1QiT+tUIk/rZDJf+1QiT+tUIk/rZDJf+/WkD+/////9+sn/61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP67RSb+1k8rxONULuTjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8rSj//////+/WkD/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/7NDI/+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+/WkD//////9+sn/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/79GJv/eUi3/41Qu5ONULvniUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+8rSj/v////+/WkD+tUIk/rZDJf+1QiT+tUIk/rZDJf+1QiT+7M/I/uzPyP+1QiT+tUIk/rZDJf+1QiT+tUIk/rZDJf+/WkD+/////9+sn/61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+xUgn/+FTLf7iUy3+4lMt+eNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+8rSj/v////+/WkD+tUIk/rZDJf+1QiT+tUIk/rZDJf+1QiT+7M/I/uzPyP+1QiT+tUIk/rZDJf+1QiT+tUIk/rZDJf+/WkD+/////9+sn/61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+tkMl/7ZDJf7LSyn+4lMt/+JTLf7iUy3+4lMt/uNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8rSj//////+/WkD/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/7NDI/+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+/WkD//////9+sn/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/t0Ml/9JNKv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvniUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+8rSj/v////+/WkD+tUIk/rZDJf+1QiT+tUIk/rZDJf+1QiT+7M/I/uzPyP+1QiT+tUIk/rZDJf+1QiT+tUIk/rZDJf+/WkD+/////9+sn/61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP65RCX+108r/+JTLf7iUy3+41Qu/+JTLf7iUy3+4lMt+eNULuTiUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+8rSj/v////+/WkD+tUIk/rZDJf+1QiT+tUIk/rZDJf+1QiT+7M/I/uzPyP+1QiT+tUIk/rZDJf+1QiT+tUIk/rZDJf+/WkD+/////9+sn/61QiT+tkMl/7VCJP61QiT+tkMl/71FJv7cUSz+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+4lMt5ONULsTjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+VhPf/99/X/////////////////58G3/7ZDJf+2QyX/tkMl/86Bbf/+/v7////////////+/v7/z4Rw/7ZDJf+2QyX/tkMl/+a/tf/////////////////89/b/u1A0/7ZDJf+2QyX/wUcn/99SLf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuxONULpriUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+6HNU//zv6/7+/f3+/v7+/v/////+/v7+9unm/ujEuv/oxLr+6MS6/u/Vz//+/v7+/v7+/v/////+/v7+79bQ/ujEuv/oxLr+5byy/vTk4P/+/v7+//////7+/v79/Pv+9ebi/75XPP7HSSj+4VMt/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+4lMtmuNULmXiUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+6X1g//7+/v7+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+//////7+/v7+/v7+/vz8/9hmR/7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+4lMtZeNULiTjVC7941Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+qCZ//64dv///7+//////////////////////////////////////////////////////////////////////////////////////////////////7+/v/52tL/6Xpc/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7941QuJONULgLiUy3S4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7jWDP+756J/v3z8P/+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/O7q/+2Vff7jVjH+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3S4lMtAgAAAADjVC5741Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+VjQf/zu6z//v38//////////////////////////////////////////////////////////////////76+f/ysaD/5F47/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC57AAAAAAAAAADiUy0b4lMt9uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+4lMt/uNULv/iUy3+6HVW/vjWzP/+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v3+9s3C/uduTv/iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLfbiUy0bAAAAAAAAAAAAAAAA4lMtn+NULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+4lMt/uNULv/iUy3+4lMt/uNVMP/skHf+++rm/v/////+/v7+/v7+/v/////+/v7+/v7+/vrk3v/rhmz+41Qu/uNULv/iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLZ4AAAAAAAAAAAAAAAAAAAAA41QuIeNULvjjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5Fw4//Gtm//++fj////////////99fL/76OO/+NZNP/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu+ONULiEAAAAAAAAAAAAAAAAAAAAAAAAAAONULoXiUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/makn+9MGz/vO7q//lZEL+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41QuhQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgviUy3W4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3W41QuCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4z41Qu9eNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvXjVC4zAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMtXeNULv3iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/eJTLV0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULnjiUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41QueAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgHjVC5441Qu/eNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv3jVC5441QuAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMtXeNULvXiUy3+41Qu/+JTLf7iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/i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iXb/0Yl2/+jGvf///////////+3TzP/RiXb/0Yl2//Lg2////////////+G0qP+3Ryr/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyWlAAAAAONULhLjVC7441Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41cy/++hjP/v1c//vFQ4/7ZDJf+2QyX/uUwv/9+sn//frJ//uk4y/7ZDJf+2QyX/u1E1/+/Vz//XmIf/uEks/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJfi2QyUT41QuX+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/7ZR8/+zQyP+2QyX/tkMl/7ZDJf+2QyX/2qGS/9qhkv+2QyX/tkMl/7ZDJf+2QyX/7NDI/9GJdv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJWDjVC6h41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/tlHz/7NDI/7ZDJf+2QyX/tkMl/7ZDJf/aoZL/2qGS/7ZDJf+2QyX/tkMl/7ZDJf/s0Mj/0Yl2/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMlouNULtHjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+2UfP/s0Mj/tkMl/7ZDJf+2QyX/tkMl/9qhkv/aoZL/tkMl/7ZDJf+2QyX/tkMl/+zQyP/RiXb/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/HSSjR41Qu8ONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/7ZR8/+zQyP+2QyX/tkMl/7ZDJf+2QyX/2qGS/9qhkv+2QyX/tkMl/7ZDJf+2QyX/7NDI/9GJdv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/0E0q/+NULvDjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/tlHz/7NDI/7ZDJf+2QyX/tkMl/7ZDJf/aoZL/2qGS/7ZDJf+2QyX/tkMl/7ZDJf/s0Mj/0Yl2/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/uEQl/9ZPK//jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+2UfP/s0Mj/tkMl/7ZDJf+2QyX/tkMl/9qhkv/aoZL/tkMl/7ZDJf+2QyX/tkMl/+zQyP/RiXb/tkMl/7ZDJf+2QyX/tkMl/7tFJv/bUSz/41Qu/+NULv/jVC7/41Qu8ONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/7ZR8/+zQyP+2QyX/tkMl/7ZDJf+2QyX/2qGS/9qhkv+2QyX/tkMl/7ZDJf+2QyX/7NDI/9GJdv+2QyX/tkMl/7ZDJf/ARif/31It/+NULv/jVC7/41Qu/+NULvDjVC7R41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Yx//Gtm/////////////Da1P+/WkD/v1pA/+K0qf///////////+K2qv+/WkD/vVc8/+/X0P///////////9qhkv+2RCb/xUko/+FTLf/jVC7/41Qu/+NULv/jVC7/41Qu0eNULqHjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/ncVL//////////////////////////////////////////////////////////////////////////////////v39/9RfQP/iUy3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC6h41QuX+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/qg2j/+uPd//////////////////////////////////////////////////////////////////nf2P/pfWH/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULl/jVC4S41Qu+ONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVzL/76CL//308v////////////////////////////////////////////zx7v/umYP/41Yw/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7441QuEgAAAADjVC6k41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5WJA//S8rf/+/f3///////////////////////78+//ztaX/5F88/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULqMAAAAAAAAAAONULivjVC7841Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+h2WP/4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iXb+0Yl2/tGJdv7NgGz+tkMl/rVCJP61QiT+tkMl9bdDJSQAAAAAAAAAAONULq7iUy3+41Qu/+NULv/ma0v+/vz8///////+/v7+/////////////////v7+/v/////+/v7+///////////+/Pz+wF1D/7ZDJf+1QiT+tkMl/7ZDJa4AAAAA4FMtJeNULvziUy3+41Qu/+NULv/iUy3+6oRp//zv7P/dqZv+uEgr/71WO//sz8f/7M/H/sBeRP+4SCv+2qCR//ju6//OgW3+tkMl/7ZDJf+1QiT+tkMl/7ZDJf22QyUm4lMtfeJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/vjZ0f66TjL+tUIk/rVCJP7RiXb+0Yl2/rVCJP61QiT+uk4y/u/Vz/61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP62QyV+41Quv+NULv/iUy3+41Qu/+NULv/iUy3+41Qu//jZ0f+6TjL+tkMl/7ZDJf/RiXb/0Yl2/rZDJf+1QiT+uk4y/+/Vz/+1QiT+tkMl/7ZDJf+1QiT+tkMl/7ZDJf+2QyXA41Qu6eNULv/iUy3+41Qu/+NULv/iUy3+41Qu//jZ0f+6TjL+tkMl/7ZDJf/RiXb/0Yl2/rZDJf+1QiT+uk4y/+/Vz/+1QiT+tkMl/7ZDJf+1QiT+tkMl/7hDJf/UTivp41Qu/eNULv/iUy3+41Qu/+NULv/iUy3+41Qu//jZ0f+6TjL+tkMl/7ZDJf/RiXb/0Yl2/rZDJf+1QiT+uk4y/+/Vz/+1QiT+tkMl/7ZDJf+1QiT+u0Um/9pQLP/iUy394lMt/eJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/vjZ0f66TjL+tUIk/rVCJP7RiXb+0Yl2/rVCJP61QiT+uk4y/u/Vz/61QiT+tUIk/rVCJP6/Rib+3lIt/uJTLf7iUy3941Qu6eNULv/iUy3+41Qu/+NULv/iUy3+6oBj//vs6P/Wl4b+tkMl/7xSN//oxLr/6MS6/rxTN/+1QiT+1paG//fq5//Ic13+tkMl/8VIKP/hUy3+41Qu/+NULv/iUy3p4lMtv+JTLf7iUy3+4lMt/uJTLf7lZkT+/vr5/v7+/v78+fj+8+Hc/vXm4v7+/v7+/v7+/vXm4v7y39r+/Pj3/v7+/v789/b+0FY2/uJTLf7iUy3+4lMt/uJTLf7iUy2/41QufeNULv/iUy3+41Qu/+NULv/iUy3+6oRp//rk3v/+/v7+/////////////////v7+/v/////+/v7+//////rg2f/qf2P+41Qu/+NULv/iUy3+41Qu/+NULv/iUy194lMtJeNULvziUy3+41Qu/+NULv/iUy3+41Qu/+NXMv/voIv+/fTy/////////////v7+/v/////88u/+7puF/+NWMf/iUy3+41Qu/+NULv/iUy3+41Qu/+NULvziUy0lAAAAAOJTLa7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+5WNB/vS8rv7+/f3+/vz7/vO3qP7lYD3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLa4AAAAAAAAAAOJTLSTiUy3041Qu/+NULv/iUy3+41Qu/+NULv/iUy3+41Qu/+NULv/odVb/53FS/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+NULv/iUy3+41Qu9ONULiQAAAAAAAAAAAAAAADiUy1h41Qu/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+NULv/jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+NULv/iUy3+41QuYQAAAAAAAAAAAAAAAAAAAAAAAAAA4lMtfOJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy18AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULmHiUy3041Qu/+NULv/iUy3+41Qu/+NULv/jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu9ONULmEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy0k41QuruNULvziUy3+41Qu/+NULv/jVC7/4lMt/uNULv/iUy3+41Qu/+NULvziUy2u41QuJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOJTLSXiUy194lMtv+JTLeniUy394lMt/eJTLeniUy2/4lMtfeJTLSUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/gB/APgAHwDwAA8A4AAHAMAAAwCAAAEAgAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAEAgAABAMAAAwDgAAcA8AAPAPgAHwD+AH8AKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADDSCcz41QumuNULtziUy37zEsp+7ZDJdy2QyWboTsgNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJg4HgrjVC6d41Qu/uNULv/gUi3/w0gn/7ZDJf+2QyX/tkMl/7ZDJf62QyWegzAaCgAAAAAAAAAAAAAAAJg4HgrjVC7E41Qu/+NULv/aUCz/vEUm/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJcWFMRoKAAAAAAAAAADjVC6d41Qu/+NULv/ieFz/yXJb/8hyW//Iclv/yHJb/8hyW//Iclv/xm5W/7ZDJf+2QyX/tkMlngAAAADDSCcz41Qu/uNULv/kXjr/++rm//36+f/oxLr/+fDu//r08v/oxLr/+/f2//fs6f+6TjL/tkMl/7ZDJf6mPSE041QumuNULv/jVC7/41Qu/+h4Wv/Tj33/tkMl/8p3Yf/Kd2L/tkMl/9OOfP/Fa1T/tkMl/7ZDJf+2QyX/tkMlm+NULtzjVC7/41Qu/+NULv/odFX/0Yl2/7ZDJf/Iclv/yHJb/7ZDJf/RiXb/w2ZN/7ZDJf+2QyX/tkMl/7pEJdzjVC7741Qu/+NULv/jVC7/6HRV/9GJdv+2QyX/yHJb/8hyW/+2QyX/0Yl2/8NmTf+2QyX/tkMl/79GJv/eUi3741Qu++NULv/jVC7/41Qu/+h0Vf/RiXb/tkMl/8hyW//Iclv/tkMl/9GJdv/DZk3/tkMl/8RIJ//hUy3/41Qu++NULtzjVC7/41Qu/+RcN//76ub/+/X0/9+sn//37On/9+zp/96rnv/79fP/9efj/8xQL//iUy3/41Qu/+NULtzjVC6a41Qu/+NULv/jVC7/6oRp//rk3v//////////////////////+uLb/+qBZf/jVC7/41Qu/+NULv/jVC6ayEooM+NULv7jVC7/41Qu/+NULv/jVzL/76GM//318//98/H/752I/+NWMf/jVC7/41Qu/+NULv/jVC7+0k0qMwAAAADjVC6d41Qu/+NULv/jVC7/41Qu/+NULv/lYj//5WE+/+NULv/jVC7/41Qu/+NULv/jVC7/41QunQAAAAAAAAAAozwhCuNULsTjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuxK5AIwoAAAAAAAAAAAAAAACkPSEK41QuneNULv7jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7+41Quna5AIwoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADOTCkz41QumuNULtzjVC7741Qu++NULtzjVC6a0k0qMwAAAAAAAAAAAAAAAAAAAADwDwAAwAMAAIABAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAAgAEAAMADAADwDwAA' + } - TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) + TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) end) -- Create Blips -Citizen.CreateThread(function () - local blip = AddBlipForCoord(Config.Zones.BankActions.Pos.x, Config.Zones.BankActions.Pos.y, Config.Zones.BankActions.Pos.z) +Citizen.CreateThread(function() + local blip = AddBlipForCoord(Config.Zones.BankActions.Pos.x, Config.Zones.BankActions.Pos.y, Config.Zones.BankActions.Pos.z) - SetBlipSprite (blip, 108) - SetBlipDisplay(blip, 4) - SetBlipScale (blip, 1.0) - SetBlipColour (blip, 30) - SetBlipAsShortRange(blip, true) + SetBlipSprite (blip, 108) + SetBlipDisplay(blip, 4) + SetBlipScale (blip, 1.0) + SetBlipColour (blip, 30) + SetBlipAsShortRange(blip, true) - BeginTextCommandSetBlipName('STRING') - AddTextComponentString(_U('bank')) - EndTextCommandSetBlipName(blip) + BeginTextCommandSetBlipName('STRING') + AddTextComponentString(_U('bank')) + EndTextCommandSetBlipName(blip) end) -- Display markers -Citizen.CreateThread(function () - while true do - Wait(0) +Citizen.CreateThread(function() + while true do + Citizen.Wait(0) - local coords = GetEntityCoords(GetPlayerPed(-1)) + local coords = GetEntityCoords(PlayerPedId()) - for k,v in pairs(Config.Zones) do - if(PlayerData.job ~= nil and PlayerData.job.name == 'banker' and v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then - DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) - end - end - - end + for k,v in pairs(Config.Zones) do + if(PlayerData.job ~= nil and PlayerData.job.name == 'banker' and v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) + end + end + end end) -- Activate menu when player is inside marker -Citizen.CreateThread(function () - while true do - Wait(0) +Citizen.CreateThread(function() + while true do + Citizen.Wait(10) - if(PlayerData.job ~= nil and PlayerData.job.name == 'banker') then - local coords = GetEntityCoords(GetPlayerPed(-1)) - local isInMarker = false - local currentZone = nil + if(PlayerData.job ~= nil and PlayerData.job.name == 'banker') then + local coords = GetEntityCoords(PlayerPedId()) + local isInMarker = false + local currentZone = nil - for k,v in pairs(Config.Zones) do - if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then - isInMarker = true - currentZone = k - end - end + for k,v in pairs(Config.Zones) do + if GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x then + isInMarker = true + currentZone = k + end + end - if isInMarker and not hasAlreadyEnteredMarker then - hasAlreadyEnteredMarker = true - lastZone = currentZone - TriggerEvent('esx_bankerjob:hasEnteredMarker', currentZone) - end + if isInMarker and not hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = true + lastZone = currentZone + TriggerEvent('esx_bankerjob:hasEnteredMarker', currentZone) + end - if not isInMarker and hasAlreadyEnteredMarker then - hasAlreadyEnteredMarker = false - TriggerEvent('esx_bankerjob:hasExitedMarker', lastZone) - end - end + if not isInMarker and hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = false + TriggerEvent('esx_bankerjob:hasExitedMarker', lastZone) + end + end - end + end end) -- Key Controls Citizen.CreateThread(function () - while true do - Citizen.Wait(10) + while true do + Citizen.Wait(10) - if CurrentAction ~= nil then - SetTextComponentFormat('STRING') - AddTextComponentString(CurrentActionMsg) - DisplayHelpTextFromStringLabel(0, 0, 1, -1) + if CurrentAction ~= nil then + ESX.ShowHelpNotification(CurrentActionMsg) - if IsControlPressed(0, Keys['E']) and PlayerData.job ~= nil and PlayerData.job.name == 'banker' and (GetGameTimer() - GUI.Time) > 150 then - if CurrentAction == 'bank_actions_menu' then - OpenBankActionsMenu() - end + if IsControlJustReleased(0, Keys['E']) and PlayerData.job ~= nil and PlayerData.job.name == 'banker' then + if CurrentAction == 'bank_actions_menu' then + OpenBankActionsMenu() + end - CurrentAction = nil - GUI.Time = GetGameTimer() - end - end + CurrentAction = nil + end + end - end + end end) diff --git a/esx_bankerjob.sql b/esx_bankerjob.sql index 335a91c6..6294b3ff 100644 --- a/esx_bankerjob.sql +++ b/esx_bankerjob.sql @@ -12,7 +12,7 @@ INSERT INTO `jobs` (name, label) VALUES INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES ('banker',0,'advisor','Conseiller',10,'{}','{}'), ('banker',1,'banker','Banquier',20,'{}','{}'), - ('banker',2,'business_banker','Banquier d\'affaire',30,'{}','{}'), + ('banker',2,'business_banker',"Banquier d\'affaire",30,'{}','{}'), ('banker',3,'trader','Trader',40,'{}','{}'), ('banker',4,'boss','Patron',0,'{}','{}') ; diff --git a/server/main.lua b/server/main.lua index 78fc6386..faeff15c 100644 --- a/server/main.lua +++ b/server/main.lua @@ -7,117 +7,108 @@ TriggerEvent('esx_society:registerSociety', 'banker', 'Banquier', 'society_banke RegisterServerEvent('esx_bankerjob:customerDeposit') AddEventHandler('esx_bankerjob:customerDeposit', function (target, amount) - local xPlayer = ESX.GetPlayerFromId(target) + local xPlayer = ESX.GetPlayerFromId(target) - TriggerEvent('esx_addonaccount:getSharedAccount', 'society_banker', function (account) - if amount > 0 and account.money >= amount then - account.removeMoney(amount) + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_banker', function (account) + if amount > 0 and account.money >= amount then + account.removeMoney(amount) - TriggerEvent('esx_addonaccount:getAccount', 'bank_savings', xPlayer.identifier, function (account) - account.addMoney(amount) - end) - else - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('invalid_amount')) - end - end) + TriggerEvent('esx_addonaccount:getAccount', 'bank_savings', xPlayer.identifier, function (account) + account.addMoney(amount) + end) + else + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('invalid_amount')) + end + end) end) RegisterServerEvent('esx_bankerjob:customerWithdraw') AddEventHandler('esx_bankerjob:customerWithdraw', function (target, amount) - local xPlayer = ESX.GetPlayerFromId(target) + local xPlayer = ESX.GetPlayerFromId(target) - TriggerEvent('esx_addonaccount:getAccount', 'bank_savings', xPlayer.identifier, function (account) - if amount > 0 and account.money >= amount then - account.removeMoney(amount) + TriggerEvent('esx_addonaccount:getAccount', 'bank_savings', xPlayer.identifier, function (account) + if amount > 0 and account.money >= amount then + account.removeMoney(amount) - TriggerEvent('esx_addonaccount:getSharedAccount', 'society_banker', function (account) - account.addMoney(amount) - end) - else - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('invalid_amount')) - end - end) + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_banker', function (account) + account.addMoney(amount) + end) + else + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('invalid_amount')) + end + end) end) ESX.RegisterServerCallback('esx_bankerjob:getCustomers', function (source, cb) - local xPlayers = ESX.GetPlayers() - local customers = {} + local xPlayers = ESX.GetPlayers() + local customers = {} - for i=1, #xPlayers, 1 do + for i=1, #xPlayers, 1 do + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) - local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + TriggerEvent('esx_addonaccount:getAccount', 'bank_savings', xPlayer.identifier, function(account) + table.insert(customers, { + source = xPlayer.source, + name = xPlayer.name, + bankSavings = account.money + }) + end) + end - TriggerEvent('esx_addonaccount:getAccount', 'bank_savings', xPlayer.identifier, function (account) - table.insert(customers, { - source = xPlayer.source, - name = GetPlayerName(xPlayer.source), - bankSavings = account.money - }) - end) - - end - - cb(customers) + cb(customers) end) -function CalculateBankSavings (d, h, m) - local asyncTasks = {} +function CalculateBankSavings(d, h, m) + local asyncTasks = {} - MySQL.Async.fetchAll( - 'SELECT * FROM addon_account_data WHERE account_name = @account_name', - { ['@account_name'] = 'bank_savings' }, - function (result) - local bankInterests = 0 + MySQL.Async.fetchAll('SELECT * FROM addon_account_data WHERE account_name = @account_name', { + ['@account_name'] = 'bank_savings' + }, function(result) + local bankInterests = 0 - for i=1, #result, 1 do - local foundPlayer = false - local xPlayer = ESX.GetPlayerFromIdentifier(result[i].owner) + for i=1, #result, 1 do + local xPlayer = ESX.GetPlayerFromIdentifier(result[i].owner) - if xPlayer ~= nil then - TriggerEvent('esx_addonaccount:getAccount', 'bank_savings', xPlayer.identifier, function (account) - local interests = math.floor(account.money / 100 * Config.BankSavingPercentage) - bankInterests = bankInterests + interests + if xPlayer then + TriggerEvent('esx_addonaccount:getAccount', 'bank_savings', xPlayer.identifier, function(account) + local interests = math.floor(account.money / 100 * Config.BankSavingPercentage) + bankInterests = bankInterests + interests - table.insert(asyncTasks, function(cb) - account.addMoney(interests) - end) - end) - else - local interests = math.floor(result[i].money / 100 * Config.BankSavingPercentage) - local newMoney = result[i].money + interests; - bankInterests = bankInterests + interests + table.insert(asyncTasks, function(cb) + account.addMoney(interests) + end) + end) + else + local interests = math.floor(result[i].money / 100 * Config.BankSavingPercentage) + local newMoney = result[i].money + interests + bankInterests = bankInterests + interests - local scope = function (newMoney, owner) - table.insert(asyncTasks, function (cb) + 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', + { + ['@money'] = newMoney, + ['@owner'] = owner, + ['@account_name'] = 'bank_savings', + }, function(rowsChanged) + cb() + end) + end) + end - MySQL.Async.execute( - 'UPDATE addon_account_data SET money = @money WHERE owner = @owner AND account_name = @account_name', - { - ['@money'] = newMoney, - ['@owner'] = owner, - ['@account_name'] = 'bank_savings', - }, - function (rowsChanged) - cb() - end - ) - end) - end + scope(newMoney, result[i].owner) + end + end - scope(newMoney, result[i].owner) - end - end + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_banker', function(account) + account.addMoney(bankInterests) + end) - TriggerEvent('esx_addonaccount:getSharedAccount', 'society_banker', function (account) - account.addMoney(bankInterests) - end) + Async.parallelLimit(asyncTasks, 5, function(results) + print('[BANK] Calculated interests') + end) - Async.parallelLimit(asyncTasks, 5, function (results) - print('[BANK] Calculated interests') - end) - - end - ) + end) end TriggerEvent('cron:runAt', 22, 0, CalculateBankSavings) From 0249c123696cbc3163ea17b8308823e52ccdded4 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 10 Nov 2018 00:04:02 +0100 Subject: [PATCH 1895/3224] SQL tab indent, proper job usage --- client/main.lua | 26 +++++++++++++++----------- config.lua | 12 ++++++------ esx_bankerjob.sql | 16 ++++++++-------- localization/de_esx_bankerjob.sql | 16 ++++++++-------- localization/en_esx_bankerjob.sql | 16 ++++++++-------- localization/fi_esx_bankerjob.sql | 16 ++++++++-------- 6 files changed, 53 insertions(+), 49 deletions(-) diff --git a/client/main.lua b/client/main.lua index 8dba3eb3..855c84ae 100644 --- a/client/main.lua +++ b/client/main.lua @@ -10,7 +10,6 @@ local Keys = { ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 } -local PlayerData = {} local hasAlreadyEnteredMarker = false local lastZone = nil local CurrentAction = nil @@ -25,26 +24,30 @@ Citizen.CreateThread(function () Citizen.Wait(0) end - + while ESX.GetPlayerData().job == nil do + Citizen.Wait(100) + end + + ESX.PlayerData = ESX.GetPlayerData() end) RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function (xPlayer) - PlayerData = xPlayer + ESX.PlayerData = xPlayer end) RegisterNetEvent('esx:setJob') AddEventHandler('esx:setJob', function (job) - PlayerData.job = job + ESX.PlayerData.job = job end) function OpenBankActionsMenu() local elements = { { label = _U('customers'), value = 'customers' }, - { label = _U('billing'), value = 'billing' }, + { label = _U('billing'), value = 'billing' } } - if PlayerData.job.grade_name == 'boss' then + if ESX.PlayerData.job.grade_name == 'boss' then table.insert(elements, { label = _U('boss_actions'), value = 'boss_actions' }) end @@ -169,7 +172,7 @@ function OpenCustomersMenu() end AddEventHandler('esx_bankerjob:hasEnteredMarker', function (zone) - if zone == 'BankActions' and PlayerData.job ~= nil and PlayerData.job.name == 'banker' then + if zone == 'BankActions' and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'banker' then CurrentAction = 'bank_actions_menu' CurrentActionMsg = _U('press_input_context_to_open_menu') CurrentActionData = {} @@ -215,7 +218,7 @@ Citizen.CreateThread(function() local coords = GetEntityCoords(PlayerPedId()) for k,v in pairs(Config.Zones) do - if(PlayerData.job ~= nil and PlayerData.job.name == 'banker' and v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then + if(ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'banker' and v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) end end @@ -227,7 +230,7 @@ Citizen.CreateThread(function() while true do Citizen.Wait(10) - if(PlayerData.job ~= nil and PlayerData.job.name == 'banker') then + if(ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'banker') then local coords = GetEntityCoords(PlayerPedId()) local isInMarker = false local currentZone = nil @@ -262,14 +265,15 @@ Citizen.CreateThread(function () if CurrentAction ~= nil then ESX.ShowHelpNotification(CurrentActionMsg) - if IsControlJustReleased(0, Keys['E']) and PlayerData.job ~= nil and PlayerData.job.name == 'banker' then + if IsControlJustReleased(0, Keys['E']) and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'banker' then if CurrentAction == 'bank_actions_menu' then OpenBankActionsMenu() end CurrentAction = nil end + else + Citizen.Wait(500) end - end end) diff --git a/config.lua b/config.lua index c2336801..391f8ce5 100644 --- a/config.lua +++ b/config.lua @@ -5,11 +5,11 @@ Config.Locale = 'fr' Config.Zones = { - BankActions = { - Pos = { x = 260.130, y = 204.308, z = 109.287 }, - Size = { x = 1.5, y = 1.5, z = 1.0 }, - Color = { r = 102, g = 102, b = 204 }, - Type = 1 - } + BankActions = { + Pos = { x = 260.130, y = 204.308, z = 109.287 }, + Size = { x = 1.5, y = 1.5, z = 1.0 }, + Color = { r = 102, g = 102, b = 204 }, + Type = 1 + } } diff --git a/esx_bankerjob.sql b/esx_bankerjob.sql index 6294b3ff..90b8b128 100644 --- a/esx_bankerjob.sql +++ b/esx_bankerjob.sql @@ -1,18 +1,18 @@ USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES - ('society_banker','Banque',1), - ('bank_savings','Livret Bleu',0) + ('society_banker','Banque',1), + ('bank_savings','Livret Bleu',0) ; INSERT INTO `jobs` (name, label) VALUES - ('banker','Banquier') + ('banker','Banquier') ; INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES - ('banker',0,'advisor','Conseiller',10,'{}','{}'), - ('banker',1,'banker','Banquier',20,'{}','{}'), - ('banker',2,'business_banker',"Banquier d\'affaire",30,'{}','{}'), - ('banker',3,'trader','Trader',40,'{}','{}'), - ('banker',4,'boss','Patron',0,'{}','{}') + ('banker',0,'advisor','Conseiller',10,'{}','{}'), + ('banker',1,'banker','Banquier',20,'{}','{}'), + ('banker',2,'business_banker',"Banquier d\'affaire",30,'{}','{}'), + ('banker',3,'trader','Trader',40,'{}','{}'), + ('banker',4,'boss','Patron',0,'{}','{}') ; diff --git a/localization/de_esx_bankerjob.sql b/localization/de_esx_bankerjob.sql index af0919b5..a1da4469 100644 --- a/localization/de_esx_bankerjob.sql +++ b/localization/de_esx_bankerjob.sql @@ -1,18 +1,18 @@ USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES - ('society_banker','Bank',1), - ('bank_savings','Bank',0) + ('society_banker','Bank',1), + ('bank_savings','Bank',0) ; INSERT INTO `jobs` (name, label) VALUES - ('banker','Banker') + ('banker','Banker') ; INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES - ('banker',0,'advisor','Berater',10,'{}','{}'), - ('banker',1,'banker','Banker',20,'{}','{}'), - ('banker',2,'business_banker','Business Banker',30,'{}','{}'), - ('banker',3,'trader','Trader',40,'{}','{}'), - ('banker',4,'boss','Boss',0,'{}','{}') + ('banker',0,'advisor','Berater',10,'{}','{}'), + ('banker',1,'banker','Banker',20,'{}','{}'), + ('banker',2,'business_banker','Business Banker',30,'{}','{}'), + ('banker',3,'trader','Trader',40,'{}','{}'), + ('banker',4,'boss','Boss',0,'{}','{}') ; diff --git a/localization/en_esx_bankerjob.sql b/localization/en_esx_bankerjob.sql index 798d271e..d70d5647 100644 --- a/localization/en_esx_bankerjob.sql +++ b/localization/en_esx_bankerjob.sql @@ -1,18 +1,18 @@ USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES - ('society_banker','Bank',1), - ('bank_savings','Bank Savings',0) + ('society_banker','Bank',1), + ('bank_savings','Bank Savings',0) ; INSERT INTO `jobs` (name, label) VALUES - ('banker','Banker') + ('banker','Banker') ; INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES - ('banker',0,'advisor','Advisor',10,'{}','{}'), - ('banker',1,'banker','Banker',20,'{}','{}'), - ('banker',2,'business_banker','Business Banker',30,'{}','{}'), - ('banker',3,'trader','Trader',40,'{}','{}'), - ('banker',4,'boss','Lead Banker',0,'{}','{}') + ('banker',0,'advisor','Advisor',10,'{}','{}'), + ('banker',1,'banker','Banker',20,'{}','{}'), + ('banker',2,'business_banker','Business Banker',30,'{}','{}'), + ('banker',3,'trader','Trader',40,'{}','{}'), + ('banker',4,'boss','Lead Banker',0,'{}','{}') ; diff --git a/localization/fi_esx_bankerjob.sql b/localization/fi_esx_bankerjob.sql index b5755b39..36332571 100644 --- a/localization/fi_esx_bankerjob.sql +++ b/localization/fi_esx_bankerjob.sql @@ -1,18 +1,18 @@ USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES - ('society_banker','Pankki',1), - ('bank_savings','Pankki',0) + ('society_banker','Pankki',1), + ('bank_savings','Pankki',0) ; INSERT INTO `jobs` (name, label) VALUES - ('banker','Pankkiiri') + ('banker','Pankkiiri') ; INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES - ('banker',0,'advisor','Konsultti',10,'{}','{}'), - ('banker',1,'banker','Pankkiiri',20,'{}','{}'), - ('banker',2,'business_banker','Yritys Pankkiiri',30,'{}','{}'), - ('banker',3,'trader','Välittäjä',40,'{}','{}'), - ('banker',4,'boss','Pomo',0,'{}','{}') + ('banker',0,'advisor','Konsultti',10,'{}','{}'), + ('banker',1,'banker','Pankkiiri',20,'{}','{}'), + ('banker',2,'business_banker','Yritys Pankkiiri',30,'{}','{}'), + ('banker',3,'trader','Välittäjä',40,'{}','{}'), + ('banker',4,'boss','Pomo',0,'{}','{}') ; From db50388543b51dfd7dc166196fec8fad5b09ef5c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 10 Nov 2018 10:37:27 +0100 Subject: [PATCH 1896/3224] Minor changes, missing semicolons in JS --- __resource.lua | 3 -- client/functions.lua | 2 +- client/main.lua | 8 ++-- config.lua | 4 +- es_extended.sql | 2 - html/css/app.css | 4 +- html/img/keys/enter.png | Bin 941 -> 0 bytes html/img/keys/return.png | Bin 376 -> 0 bytes html/js/app.js | 99 +++++++++++++++++++-------------------- 9 files changed, 57 insertions(+), 65 deletions(-) delete mode 100644 html/img/keys/enter.png delete mode 100644 html/img/keys/return.png diff --git a/__resource.lua b/__resource.lua index 3826fd4d..c947865a 100644 --- a/__resource.lua +++ b/__resource.lua @@ -76,9 +76,6 @@ files { 'html/fonts/pdown.ttf', 'html/fonts/bankgothic.ttf', - 'html/img/keys/enter.png', - 'html/img/keys/return.png', - 'html/img/accounts/bank.png', 'html/img/accounts/black_money.png' } diff --git a/client/functions.lua b/client/functions.lua index c453a2c2..5131653e 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -261,7 +261,7 @@ ESX.GetWeaponLabel = function(name) for i=1, #weapons, 1 do if weapons[i].name == name then - return weapons[i].label + return weapons[i].label end end end diff --git a/client/main.lua b/client/main.lua index 6e155de1..6bd986b0 100644 --- a/client/main.lua +++ b/client/main.lua @@ -160,6 +160,7 @@ AddEventHandler('esx:setAccountMoney', function(account) for i=1, #ESX.PlayerData.accounts, 1 do if ESX.PlayerData.accounts[i].name == account.name then ESX.PlayerData.accounts[i] = account + break end end @@ -179,7 +180,7 @@ RegisterNetEvent('esx:addInventoryItem') AddEventHandler('esx:addInventoryItem', function(item, count) for i=1, #ESX.PlayerData.inventory, 1 do if ESX.PlayerData.inventory[i].name == item.name then - ESX.PlayerData.inventory[i] = item + ESX.PlayerData.inventory[i] = item end end @@ -194,7 +195,7 @@ RegisterNetEvent('esx:removeInventoryItem') AddEventHandler('esx:removeInventoryItem', function(item, count) for i=1, #ESX.PlayerData.inventory, 1 do if ESX.PlayerData.inventory[i].name == item.name then - ESX.PlayerData.inventory[i] = item + ESX.PlayerData.inventory[i] = item end end @@ -407,7 +408,6 @@ AddEventHandler('esx:deleteVehicle', function() end end) - -- Pause menu disable HUD display if Config.EnableHud then Citizen.CreateThread(function() @@ -544,7 +544,7 @@ Citizen.CreateThread(function() for k,v in pairs(Pickups) do - local distance = GetDistanceBetweenCoords(coords.x, coords.y, coords.z, v.coords.x, v.coords.y, v.coords.z, true) + local distance = GetDistanceBetweenCoords(coords.x, coords.y, coords.z, v.coords.x, v.coords.y, v.coords.z, true) local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() if distance <= 5.0 then diff --git a/config.lua b/config.lua index 56f912a6..c7a6590b 100644 --- a/config.lua +++ b/config.lua @@ -1,5 +1,5 @@ Config = {} -Config.Locale = 'fr' +Config.Locale = 'sv' Config.Accounts = { 'bank', 'black_money' } Config.AccountLabels = { bank = _U('bank'), black_money = _U('black_money') } @@ -9,7 +9,9 @@ Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true Config.EnableWeaponPickup = true Config.EnableHud = true -- enable the default hud? Display current job and accounts (black, bank & cash) + Config.RemoveInventoryItemDelay = 5 * 60000 Config.PaycheckInterval = 7 * 60000 Config.MaxPlayers = 32 + Config.EnableDebug = false diff --git a/es_extended.sql b/es_extended.sql index badf8f87..31fa0467 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -44,7 +44,6 @@ CREATE TABLE `jobs` ( INSERT INTO `jobs` VALUES ('unemployed','Unemployed'); CREATE TABLE `user_accounts` ( - `id` int(11) NOT NULL AUTO_INCREMENT, `identifier` varchar(255) NOT NULL, `name` varchar(255) NOT NULL, @@ -54,7 +53,6 @@ CREATE TABLE `user_accounts` ( ); CREATE TABLE `user_inventory` ( - `id` int(11) NOT NULL AUTO_INCREMENT, `identifier` varchar(255) NOT NULL, `item` varchar(255) NOT NULL, diff --git a/html/css/app.css b/html/css/app.css index e4327c9c..bac47fad 100644 --- a/html/css/app.css +++ b/html/css/app.css @@ -1,11 +1,11 @@ @font-face { font-family: 'Pricedown'; - src: url('../fonts/pdown.ttf')/* TTF file for CSS3 browsers */ + src: url('../fonts/pdown.ttf') } @font-face { font-family: 'bankgothic'; - src: url('../fonts/bankgothic.ttf')/* TTF file for CSS3 browsers */ + src: url('../fonts/bankgothic.ttf') } html { diff --git a/html/img/keys/enter.png b/html/img/keys/enter.png deleted file mode 100644 index 3eb9a1f69f58c651517329c92d28cdb1c605f165..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 941 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h5*QjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ISV`@iy0XB4ude`@%$Aj3=GUpo-U3d6>)E`8wN=`3bZEbov^iFaeu%P z(=cbwj44wlOz4rm5xb{;*Ri~}uR6cp(A&Mg;nJ7c^H#o^DiE{vT2%I1{SRyZiuLSP z%I`LO*R@CY*bePa+aw;ZJ8?S+Bq+DcEWq?az(jNYVCfZ787ofAZePh8!fO)pBkQX z_v_cMN3~tQ9xnRXb?ICkwaPbd-|8+sfB5~ocaKb5*$ZEQP2MMD?ps&IpveBkTdrZ6 zxw-l0$rY8AfmJN&5XWi1Tr~N;qpPCYQm=EdrvtPXJvz5h@~FDPw92D`R+fPvAFW@~ zU8c75`%1Gbh1a`Q>?qE0`*<(h^|W${-y)Ec<2}XS`n>x2)3WZB?5;)4TWYMP-*<76OIq zPp@4X%Z+C%*K#BUX=ORzsAov;Kl`m>i&y`Jz)nzj*Qmyplm-1%6v*YUbiCHwmEO<$ zF|Z@`-}HhOKR<9>X}?rT5Bm9ye^tw4euv}#-v4JmQzRDkY{|X*_d_{Xwfto_xNQ|y z-^Qlff58%JWZtYCU#*y5vIf?_WBTiPU(9hK5Tmx!-~Iodkpb3zr{Lwk`bljQz#(xy zvE05v9vtTHlU}QP{nuV*08Uf+$??{$l9IqgWxio$Zh{XeF$LeaxXn-#^iFnsKzTLkWYeXNfKEXTvUB0pJdzPZ}OMgdS+TyQ( lJso37+@RE7f9~qla<)GklNn{1`ISV`@iy0XBj({-ZRBb+Kpaxz~7srr_xVN`&cQqS`I9#;&|Ns0smZ-L@ zqu)%cbtmkrE=&Hfsn_t^{^k|)kLw3AbqG7mVR+;>`#|k>^_ZL6&QAQlndu0pf*(U6 zREkAFy}^PJuTYF$!{g|Ur7IbD{_6-gJlsE>3DGO)9eE;D=anIC*ESQi{xCV$~42}L!4TJCrkQD1~tJw zr&teYqgpL=o@s|#!;B|~71m*K { - ESX = {}; + ESX = {}; ESX.HUDElements = []; - ESX.setHUDDisplay = function(opacity){ + ESX.setHUDDisplay = function (opacity) { $('#hud').css('opacity', opacity); - } - - ESX.insertHUDElement = function(name, index, priority, html, data){ + }; + ESX.insertHUDElement = function (name, index, priority, html, data) { ESX.HUDElements.push({ - name : name, - index : index, - priority : priority, - html : html, - data : data - }) + name: name, + index: index, + priority: priority, + html: html, + data: data + }); - ESX.HUDElements.sort((a,b) => { + ESX.HUDElements.sort((a, b) => { return a.index - b.index || b.priority - a.priority; - }) + }); + }; - } + ESX.updateHUDElement = function (name, data) { - ESX.updateHUDElement = function(name, data){ - - for(let i=0; i { - - switch(data.action){ - - case 'setHUDDisplay' : { + switch (data.action) { + case 'setHUDDisplay': { ESX.setHUDDisplay(data.opacity); break; } - case 'insertHUDElement' : { + case 'insertHUDElement': { ESX.insertHUDElement(data.name, data.index, data.priority, data.html, data.data); break; } - case 'updateHUDElement' : { + case 'updateHUDElement': { ESX.updateHUDElement(data.name, data.data); break; } - case 'deleteHUDElement' : { + case 'deleteHUDElement': { ESX.deleteHUDElement(data.name); break; } - case 'inventoryNotification' : { - ESX.inventoryNotification(data.add, data.item, data.count) + case 'inventoryNotification': { + ESX.inventoryNotification(data.add, data.item, data.count); } - } + }; - } - - window.onload = function(e){ + window.onload = function (e) { window.addEventListener('message', (event) => { - onData(event.data) + onData(event.data); }); - } + }; -})() \ No newline at end of file +})(); \ No newline at end of file From bac7be4f6b04ee61627bec09a619e15c3db38dea Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 10 Nov 2018 10:38:00 +0100 Subject: [PATCH 1897/3224] Added setName() to xPlayer class --- server/classes/player.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server/classes/player.lua b/server/classes/player.lua index 3bd4ef3c..03f29901 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -194,6 +194,10 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l return self.name end + self.setName = function(newName) + self.name = newName + end + self.getLastPosition = function() return self.lastPosition end From 9093c9912b4ffce4a46d7e2ae9523fbd05d2dbf0 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 10 Nov 2018 11:11:07 +0100 Subject: [PATCH 1898/3224] Fixed #157 --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 9bcf75f9..d3717a86 100644 --- a/server/main.lua +++ b/server/main.lua @@ -129,7 +129,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) -- Get job name, grade and last position table.insert(tasks2, function(cb2) - MySQL.Async.fetchAll('SELECT loadout, position FROM `users` WHERE `identifier` = @identifier', { + MySQL.Async.fetchAll('SELECT job, job_grade, loadout, position FROM `users` WHERE `identifier` = @identifier', { ['@identifier'] = player.getIdentifier() }, function(result) userData.job['name'] = result[1].job From 9363881047c40b9f0c2bd46e940a3c2a75064474 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 10 Nov 2018 11:39:21 +0100 Subject: [PATCH 1899/3224] Group digits --- client/main.lua | 4 ++-- server/main.lua | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/client/main.lua b/client/main.lua index de8bcb65..7d9f3c9e 100644 --- a/client/main.lua +++ b/client/main.lua @@ -275,7 +275,7 @@ function OpenPropertyMenu(property) { title = property.label, align = 'top-left', - elements = elements, + elements = elements }, function(data, menu) menu.close() @@ -387,7 +387,7 @@ function OpenGatewayAvailablePropertiesMenu(property) for i=1, #gatewayProperties, 1 do if not PropertyIsOwned(gatewayProperties[i]) then table.insert(elements, { - label = gatewayProperties[i].label .. ' $' .. gatewayProperties[i].price, + label = gatewayProperties[i].label .. ' $' .. ESX.Math.GroupDigits(gatewayProperties[i].price), value = gatewayProperties[i].name, price = gatewayProperties[i].price }) diff --git a/server/main.lua b/server/main.lua index f5acb377..8cb3fa8e 100644 --- a/server/main.lua +++ b/server/main.lua @@ -24,9 +24,9 @@ function SetPropertyOwned(name, price, rented, owner) TriggerClientEvent('esx_property:setPropertyOwned', xPlayer.source, name, true) if rented then - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('rented_for', price)) + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('rented_for', ESX.Math.GroupDigits(price))) else - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('purchased_for', price)) + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('purchased_for', ESX.Math.GroupDigits(price))) end end end) @@ -155,8 +155,9 @@ RegisterServerEvent('esx_property:rentProperty') AddEventHandler('esx_property:rentProperty', function(propertyName) local xPlayer = ESX.GetPlayerFromId(source) local property = GetProperty(propertyName) + local rent = ESX.Math.Round(property.price / 200) - SetPropertyOwned(propertyName, property.price / 200, true, xPlayer.identifier) + SetPropertyOwned(propertyName, rent, true, xPlayer.identifier) end) RegisterServerEvent('esx_property:buyProperty') @@ -428,7 +429,7 @@ function PayRent(d, h, m) -- message player if connected if xPlayer ~= nil then xPlayer.removeAccountMoney('bank', result[i].price) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('paid_rent', result[i].price)) + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('paid_rent', ESX.Math.GroupDigits(result[i].price))) else -- pay rent either way MySQL.Sync.execute('UPDATE users SET bank = bank - @bank WHERE identifier = @identifier', { From 1c6f57e22b5fb5cf35b57e0e591c3fef49434d8a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 10 Nov 2018 11:59:35 +0100 Subject: [PATCH 1900/3224] Fixed #46, proper digit grouping --- client/main.lua | 48 +++++++++++++++++++++++++++++++++++++++--------- server/main.lua | 4 ++-- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/client/main.lua b/client/main.lua index 7d9f3c9e..4f975a71 100644 --- a/client/main.lua +++ b/client/main.lua @@ -368,6 +368,7 @@ function OpenGatewayOwnedPropertiesMenu(property) if data2.current.value == 'enter' then TriggerEvent('instance:create', 'property', {property = data.current.value, owner = ESX.GetPlayerData().identifier}) + menu2.close() elseif data2.current.value == 'leave' then TriggerServerEvent('esx_property:removeOwnedProperty', data.current.value) end @@ -396,7 +397,7 @@ function OpenGatewayAvailablePropertiesMenu(property) ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'gateway_available_properties', { - title = property.name.. ' - ' .. _U('available_properties'), + title = property.name .. ' - ' .. _U('available_properties'), align = 'top-left', elements = elements }, function(data, menu) @@ -405,7 +406,7 @@ function OpenGatewayAvailablePropertiesMenu(property) ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'gateway_available_properties_actions', { - title = property.name, + title = property.label .. ' - ' .. _U('available_properties'), align = 'top-left', elements = { {label = _U('buy'), value = 'buy'}, @@ -561,20 +562,34 @@ function OpenRoomInventoryMenu(property, owner) local elements = {} if inventory.blackMoney > 0 then - table.insert(elements, {label = _U('dirty_money', inventory.blackMoney), type = 'item_account', value = 'black_money'}) + table.insert(elements, { + label = _U('dirty_money', ESX.Math.GroupDigits(inventory.blackMoney)), + type = 'item_account', + value = 'black_money' + }) end for i=1, #inventory.items, 1 do local item = inventory.items[i] if item.count > 0 then - table.insert(elements, {label = item.label .. ' x' .. item.count, type = 'item_standard', value = item.name}) + table.insert(elements, { + label = item.label .. ' x' .. item.count, + type = 'item_standard', + value = item.name + }) end end for i=1, #inventory.weapons, 1 do local weapon = inventory.weapons[i] - table.insert(elements, {label = ESX.GetWeaponLabel(weapon.name) .. ' [' .. weapon.ammo .. ']', type = 'item_weapon', value = weapon.name, ammo = weapon.ammo}) + + table.insert(elements, { + label = ESX.GetWeaponLabel(weapon.name) .. ' [' .. weapon.ammo .. ']', + type = 'item_weapon', + value = weapon.name, + ammo = weapon.ammo + }) end ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'room_inventory', @@ -596,7 +611,7 @@ function OpenRoomInventoryMenu(property, owner) else ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'get_item_count', { - title = _U('amount'), + title = _U('amount') }, function(data2, menu) local quantity = tonumber(data2.value) @@ -632,13 +647,22 @@ function OpenPlayerInventoryMenu(property, owner) local elements = {} if inventory.blackMoney > 0 then - table.insert(elements, {label = _U('dirty_money', inventory.blackMoney), type = 'item_account', value = 'black_money'}) + table.insert(elements, { + label = _U('dirty_money', ESX.Math.GroupDigits(inventory.blackMoney)), + type = 'item_account', + value = 'black_money' + }) end for i=1, #inventory.items, 1 do local item = inventory.items[i] + if item.count > 0 then - table.insert(elements, {label = item.label .. ' x' .. item.count, type = 'item_standard', value = item.name}) + table.insert(elements, { + label = item.label .. ' x' .. item.count, + type = 'item_standard', + value = item.name + }) end end @@ -649,7 +673,13 @@ function OpenPlayerInventoryMenu(property, owner) local weaponHash = GetHashKey(weaponList[i].name) if HasPedGotWeapon(playerPed, weaponHash, false) and weaponList[i].name ~= 'WEAPON_UNARMED' then local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) - table.insert(elements, {label = weaponList[i].label .. ' [' .. ammo .. ']', type = 'item_weapon', value = weaponList[i].name, ammo = ammo}) + + table.insert(elements, { + label = weaponList[i].label .. ' [' .. ammo .. ']', + type = 'item_weapon', + value = weaponList[i].name, + ammo = ammo + }) end end diff --git a/server/main.lua b/server/main.lua index 8cb3fa8e..c578dfb1 100644 --- a/server/main.lua +++ b/server/main.lua @@ -363,7 +363,7 @@ ESX.RegisterServerCallback('esx_property:getPropertyInventory', function(source, end) TriggerEvent('esx_datastore:getDataStore', 'property', xPlayer.identifier, function(store) - local storeWeapons = store.get('weapons') or {} + weapons = store.get('weapons') or {} end) cb({ @@ -427,7 +427,7 @@ function PayRent(d, h, m) local xPlayer = ESX.GetPlayerFromIdentifier(result[i].owner) -- message player if connected - if xPlayer ~= nil then + if xPlayer then xPlayer.removeAccountMoney('bank', result[i].price) TriggerClientEvent('esx:showNotification', xPlayer.source, _U('paid_rent', ESX.Math.GroupDigits(result[i].price))) else -- pay rent either way From b5d389a82e7546835a0c156e9ac9283882fce8ba Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 10 Nov 2018 13:20:11 +0100 Subject: [PATCH 1901/3224] 4 tab indent, cleanup --- README.md | 1 - client/main.lua | 1495 ++++++++++++++++++++++------------------------- config.lua | 180 +++--- server/main.lua | 335 +++++------ 4 files changed, 933 insertions(+), 1078 deletions(-) diff --git a/README.md b/README.md index 6f27877a..ca7a1d38 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,6 @@ git clone https://github.com/ESX-Org/esx_mecanojob [esx]/esx_mecanojob - Download https://github.com/ESX-Org/esx_mecanojob/archive/master.zip - Put it in the `[esx]` directory - ## Installation - Import `esx_mecanojob.sql` in your database - If you want player management you have to set `Config.EnablePlayerManagement` to `true` in `config.lua` diff --git a/client/main.lua b/client/main.lua index df823fc7..b3e58a14 100644 --- a/client/main.lua +++ b/client/main.lua @@ -16,7 +16,6 @@ local LastZone = nil local CurrentAction = nil local CurrentActionMsg = '' local CurrentActionData = {} -local OnJob = false local CurrentlyTowedVehicle = nil local Blips = {} local NPCOnJob = false @@ -36,375 +35,320 @@ Citizen.CreateThread(function() TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) Citizen.Wait(0) end - + Citizen.Wait(5000) PlayerData = ESX.GetPlayerData() end) function SelectRandomTowable() + local index = GetRandomIntInRange(1, #Config.Towables) - local index = GetRandomIntInRange(1, #Config.Towables) - - for k,v in pairs(Config.Zones) do - if v.Pos.x == Config.Towables[index].x and v.Pos.y == Config.Towables[index].y and v.Pos.z == Config.Towables[index].z then - return k - end - end - + for k,v in pairs(Config.Zones) do + if v.Pos.x == Config.Towables[index].x and v.Pos.y == Config.Towables[index].y and v.Pos.z == Config.Towables[index].z then + return k + end + end end function StartNPCJob() + NPCOnJob = true - NPCOnJob = true + NPCTargetTowableZone = SelectRandomTowable() + local zone = Config.Zones[NPCTargetTowableZone] - NPCTargetTowableZone = SelectRandomTowable() - local zone = Config.Zones[NPCTargetTowableZone] + Blips['NPCTargetTowableZone'] = AddBlipForCoord(zone.Pos.x, zone.Pos.y, zone.Pos.z) + SetBlipRoute(Blips['NPCTargetTowableZone'], true) - Blips['NPCTargetTowableZone'] = AddBlipForCoord(zone.Pos.x, zone.Pos.y, zone.Pos.z) - SetBlipRoute(Blips['NPCTargetTowableZone'], true) - - ESX.ShowNotification(_U('drive_to_indicated')) + ESX.ShowNotification(_U('drive_to_indicated')) end function StopNPCJob(cancel) + if Blips['NPCTargetTowableZone'] ~= nil then + RemoveBlip(Blips['NPCTargetTowableZone']) + Blips['NPCTargetTowableZone'] = nil + end - if Blips['NPCTargetTowableZone'] ~= nil then - RemoveBlip(Blips['NPCTargetTowableZone']) - Blips['NPCTargetTowableZone'] = nil - end + if Blips['NPCDelivery'] ~= nil then + RemoveBlip(Blips['NPCDelivery']) + Blips['NPCDelivery'] = nil + end - if Blips['NPCDelivery'] ~= nil then - RemoveBlip(Blips['NPCDelivery']) - Blips['NPCDelivery'] = nil - end + Config.Zones.VehicleDelivery.Type = -1 + NPCOnJob = false + NPCTargetTowable = nil + NPCTargetTowableZone = nil + NPCHasSpawnedTowable = false + NPCHasBeenNextToTowable = false - Config.Zones.VehicleDelivery.Type = -1 - - NPCOnJob = false - NPCTargetTowable = nil - NPCTargetTowableZone = nil - NPCHasSpawnedTowable = false - NPCHasBeenNextToTowable = false - - if cancel then - ESX.ShowNotification(_U('mission_canceled')) - else - TriggerServerEvent('esx_mecanojob:onNPCJobCompleted') - end - + if cancel then + ESX.ShowNotification(_U('mission_canceled')) + else + --TriggerServerEvent('esx_mecanojob:onNPCJobCompleted') + end end function OpenMecanoActionsMenu() - local elements = { - {label = _U('vehicle_list'), value = 'vehicle_list'}, - {label = _U('work_wear'), value = 'cloakroom'}, - {label = _U('civ_wear'), value = 'cloakroom2'}, - {label = _U('deposit_stock'), value = 'put_stock'}, - {label = _U('withdraw_stock'), value = 'get_stock'} - } - if Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.grade_name == 'boss' then - table.insert(elements, {label = _U('boss_actions'), value = 'boss_actions'}) - end + local elements = { + {label = _U('vehicle_list'), value = 'vehicle_list'}, + {label = _U('work_wear'), value = 'cloakroom'}, + {label = _U('civ_wear'), value = 'cloakroom2'}, + {label = _U('deposit_stock'), value = 'put_stock'}, + {label = _U('withdraw_stock'), value = 'get_stock'} + } - ESX.UI.Menu.CloseAll() + if Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.grade_name == 'boss' then + table.insert(elements, {label = _U('boss_actions'), value = 'boss_actions'}) + end - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'mecano_actions', - { - title = _U('mechanic'), - align = 'top-left', - elements = elements - }, - function(data, menu) - if data.current.value == 'vehicle_list' then + ESX.UI.Menu.CloseAll() - if Config.EnableSocietyOwnedVehicles then + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'mecano_actions', { + title = _U('mechanic'), + align = 'top-left', + elements = elements + }, function(data, menu) + if data.current.value == 'vehicle_list' then - local elements = {} + if Config.EnableSocietyOwnedVehicles then - ESX.TriggerServerCallback('esx_society:getVehiclesInGarage', function(vehicles) + local elements = {} - for i=1, #vehicles, 1 do - table.insert(elements, {label = GetDisplayNameFromVehicleModel(vehicles[i].model) .. ' [' .. vehicles[i].plate .. ']', value = vehicles[i]}) - end + ESX.TriggerServerCallback('esx_society:getVehiclesInGarage', function(vehicles) + for i=1, #vehicles, 1 do + table.insert(elements, { + label = GetDisplayNameFromVehicleModel(vehicles[i].model) .. ' [' .. vehicles[i].plate .. ']', + value = vehicles[i] + }) + end - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'vehicle_spawner', - { - title = _U('service_vehicle'), - align = 'top-left', - elements = elements, - }, - function(data, menu) + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_spawner', { + title = _U('service_vehicle'), + align = 'top-left', + elements = elements + }, function(data, menu) + menu.close() + local vehicleProps = data.current.value - menu.close() + ESX.Game.SpawnVehicle(vehicleProps.model, Config.Zones.VehicleSpawnPoint.Pos, 270.0, function(vehicle) + ESX.Game.SetVehicleProperties(vehicle, vehicleProps) + local playerPed = PlayerPedId() + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + end) - local vehicleProps = data.current.value + TriggerServerEvent('esx_society:removeVehicleFromGarage', 'mecano', vehicleProps) + end, function(data, menu) + menu.close() + end) + end, 'mecano') - ESX.Game.SpawnVehicle(vehicleProps.model, Config.Zones.VehicleSpawnPoint.Pos, 270.0, function(vehicle) - ESX.Game.SetVehicleProperties(vehicle, vehicleProps) - local playerPed = GetPlayerPed(-1) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - end) + else - TriggerServerEvent('esx_society:removeVehicleFromGarage', 'mecano', vehicleProps) + local elements = { + {label = _U('flat_bed'), value = 'flatbed'}, + {label = _U('tow_truck'), value = 'towtruck2'} + } - end, - function(data, menu) - menu.close() - end - ) + if Config.EnablePlayerManagement and PlayerData.job ~= nil and (PlayerData.job.grade_name == 'boss' or PlayerData.job.grade_name == 'chef' or PlayerData.job.grade_name == 'experimente') then + table.insert(elements, {label = 'SlamVan', value = 'slamvan3'}) + end - end, 'mecano') + ESX.UI.Menu.CloseAll() - else + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'spawn_vehicle', { + title = _U('service_vehicle'), + align = 'top-left', + elements = elements + }, function(data, menu) + if Config.MaxInService == -1 then + ESX.Game.SpawnVehicle(data.current.value, Config.Zones.VehicleSpawnPoint.Pos, 90.0, function(vehicle) + local playerPed = PlayerPedId() + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + end) + else + ESX.TriggerServerCallback('esx_service:enableService', function(canTakeService, maxInService, inServiceCount) + if canTakeService then + ESX.Game.SpawnVehicle(data.current.value, Config.Zones.VehicleSpawnPoint.Pos, 90.0, function(vehicle) + local playerPed = PlayerPedId() + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + end) + else + ESX.ShowNotification(_U('service_full') .. inServiceCount .. '/' .. maxInService) + end + end, 'mecano') + end - local elements = { - {label = _U('flat_bed'), value = 'flatbed'}, - {label = _U('tow_truck'), value = 'towtruck2'} - } + menu.close() + end, function(data, menu) + menu.close() + OpenMecanoActionsMenu() + end) - if Config.EnablePlayerManagement and PlayerData.job ~= nil and - (PlayerData.job.grade_name == 'boss' or PlayerData.job.grade_name == 'chef' or PlayerData.job.grade_name == 'experimente') then - table.insert(elements, {label = 'SlamVan', value = 'slamvan3'}) - end + end - ESX.UI.Menu.CloseAll() + elseif data.current.value == 'cloakroom' then - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'spawn_vehicle', - { - title = _U('service_vehicle'), - align = 'top-left', - elements = elements - }, - function(data, menu) - for i=1, #elements, 1 do - if Config.MaxInService == -1 then - ESX.Game.SpawnVehicle(data.current.value, Config.Zones.VehicleSpawnPoint.Pos, 90.0, function(vehicle) - local playerPed = GetPlayerPed(-1) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - end) - break - else - ESX.TriggerServerCallback('esx_service:enableService', function(canTakeService, maxInService, inServiceCount) - if canTakeService then - ESX.Game.SpawnVehicle(data.current.value, Config.Zones.VehicleSpawnPoint.Pos, 90.0, function(vehicle) - local playerPed = GetPlayerPed(-1) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - end) - else - ESX.ShowNotification(_U('service_full') .. inServiceCount .. '/' .. maxInService) - end - end, 'mecano') - break - end - end - menu.close() - end, - function(data, menu) - menu.close() - OpenMecanoActionsMenu() - end - ) + menu.close() + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) + if skin.sex == 0 then + TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_male) + else + TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_female) + end + end) - end - end + elseif data.current.value == 'cloakroom2' then - if data.current.value == 'cloakroom' then - menu.close() - ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) + menu.close() + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) + TriggerEvent('skinchanger:loadSkin', skin) + end) - if skin.sex == 0 then - TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_male) - else - TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_female) - end + elseif data.current.value == 'put_stock' then + OpenPutStocksMenu() + elseif data.current.value == 'get_stock' then + OpenGetStocksMenu() + elseif data.current.value == 'boss_actions' then + TriggerEvent('esx_society:openBossMenu', 'mecano', function(data, menu) + menu.close() + end) + end - end) - end + end, function(data, menu) + menu.close() - if data.current.value == 'cloakroom2' then - menu.close() - ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) - - TriggerEvent('skinchanger:loadSkin', skin) - - end) - end - - if data.current.value == 'put_stock' then - OpenPutStocksMenu() - end - - if data.current.value == 'get_stock' then - OpenGetStocksMenu() - end - - if data.current.value == 'boss_actions' then - TriggerEvent('esx_society:openBossMenu', 'mecano', function(data, menu) - menu.close() - end) - end - - end, - function(data, menu) - menu.close() - CurrentAction = 'mecano_actions_menu' - CurrentActionMsg = _U('open_actions') - CurrentActionData = {} - end - ) + CurrentAction = 'mecano_actions_menu' + CurrentActionMsg = _U('open_actions') + CurrentActionData = {} + end) end function OpenMecanoHarvestMenu() - if Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.grade_name ~= 'recrue' then - local elements = { - {label = _U('gas_can'), value = 'gaz_bottle'}, - {label = _U('repair_tools'), value = 'fix_tool'}, - {label = _U('body_work_tools'), value = 'caro_tool'} - } + if Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.grade_name ~= 'recrue' then - ESX.UI.Menu.CloseAll() + local elements = { + {label = _U('gas_can'), value = 'gaz_bottle'}, + {label = _U('repair_tools'), value = 'fix_tool'}, + {label = _U('body_work_tools'), value = 'caro_tool'} + } - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'mecano_harvest', - { - title = _U('harvest'), - align = 'top-left', - elements = elements - }, - function(data, menu) - if data.current.value == 'gaz_bottle' then - menu.close() - TriggerServerEvent('esx_mecanojob:startHarvest') - end + ESX.UI.Menu.CloseAll() - if data.current.value == 'fix_tool' then - menu.close() - TriggerServerEvent('esx_mecanojob:startHarvest2') - end + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'mecano_harvest', { + title = _U('harvest'), + align = 'top-left', + elements = elements + }, function(data, menu) - if data.current.value == 'caro_tool' then - menu.close() - TriggerServerEvent('esx_mecanojob:startHarvest3') - end + if data.current.value == 'gaz_bottle' then + menu.close() + TriggerServerEvent('esx_mecanojob:startHarvest') + elseif data.current.value == 'fix_tool' then + menu.close() + TriggerServerEvent('esx_mecanojob:startHarvest2') + elseif data.current.value == 'caro_tool' then + menu.close() + TriggerServerEvent('esx_mecanojob:startHarvest3') + end - end, - function(data, menu) - menu.close() - CurrentAction = 'mecano_harvest_menu' - CurrentActionMsg = _U('harvest_menu') - CurrentActionData = {} - end - ) - else - ESX.ShowNotification(_U('not_experienced_enough')) - end + end, function(data, menu) + menu.close() + CurrentAction = 'mecano_harvest_menu' + CurrentActionMsg = _U('harvest_menu') + CurrentActionData = {} + end) + + else + ESX.ShowNotification(_U('not_experienced_enough')) + end end function OpenMecanoCraftMenu() - if Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.grade_name ~= 'recrue' then + if Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.grade_name ~= 'recrue' then - local elements = { - {label = _U('blowtorch'), value = 'blow_pipe'}, - {label = _U('repair_kit'), value = 'fix_kit'}, - {label = _U('body_kit'), value = 'caro_kit'} - } + local elements = { + {label = _U('blowtorch'), value = 'blow_pipe'}, + {label = _U('repair_kit'), value = 'fix_kit'}, + {label = _U('body_kit'), value = 'caro_kit'} + } - ESX.UI.Menu.CloseAll() + ESX.UI.Menu.CloseAll() - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'mecano_craft', - { - title = _U('craft'), - align = 'top-left', - elements = elements - }, - function(data, menu) - if data.current.value == 'blow_pipe' then - menu.close() - TriggerServerEvent('esx_mecanojob:startCraft') - end + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'mecano_craft', { + title = _U('craft'), + align = 'top-left', + elements = elements + }, function(data, menu) + if data.current.value == 'blow_pipe' then + menu.close() + TriggerServerEvent('esx_mecanojob:startCraft') + elseif data.current.value == 'fix_kit' then + menu.close() + TriggerServerEvent('esx_mecanojob:startCraft2') + elseif data.current.value == 'caro_kit' then + menu.close() + TriggerServerEvent('esx_mecanojob:startCraft3') + end - if data.current.value == 'fix_kit' then - menu.close() - TriggerServerEvent('esx_mecanojob:startCraft2') - end + end, function(data, menu) + menu.close() - if data.current.value == 'caro_kit' then - menu.close() - TriggerServerEvent('esx_mecanojob:startCraft3') - end + CurrentAction = 'mecano_craft_menu' + CurrentActionMsg = _U('craft_menu') + CurrentActionData = {} + end) - end, - function(data, menu) - menu.close() - CurrentAction = 'mecano_craft_menu' - CurrentActionMsg = _U('craft_menu') - CurrentActionData = {} - end - ) - else - ESX.ShowNotification(_U('not_experienced_enough')) - end + else + ESX.ShowNotification(_U('not_experienced_enough')) + end end function OpenMobileMecanoActionsMenu() - ESX.UI.Menu.CloseAll() + ESX.UI.Menu.CloseAll() - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'mobile_mecano_actions', - { - title = _U('mechanic'), - align = 'top-left', - elements = { - {label = _U('billing'), value = 'billing'}, - {label = _U('hijack'), value = 'hijack_vehicle'}, - {label = _U('repair'), value = 'fix_vehicle'}, - {label = _U('clean'), value = 'clean_vehicle'}, - {label = _U('imp_veh'), value = 'del_vehicle'}, - {label = _U('flat_bed'), value = 'dep_vehicle'}, - {label = _U('place_objects'), value = 'object_spawner'} - } - }, - function(data, menu) - if IsBusy then return end + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'mobile_mecano_actions', { + title = _U('mechanic'), + align = 'top-left', + elements = { + {label = _U('billing'), value = 'billing'}, + {label = _U('hijack'), value = 'hijack_vehicle'}, + {label = _U('repair'), value = 'fix_vehicle'}, + {label = _U('clean'), value = 'clean_vehicle'}, + {label = _U('imp_veh'), value = 'del_vehicle'}, + {label = _U('flat_bed'), value = 'dep_vehicle'}, + {label = _U('place_objects'), value = 'object_spawner'} + } + }, function(data, menu) + if IsBusy then return end - if data.current.value == 'billing' then - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'billing', - { - title = _U('invoice_amount') - }, - function(data, menu) - local amount = tonumber(data.value) - if amount == nil or amount < 0 then - ESX.ShowNotification(_U('amount_invalid')) - else - - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(_U('no_players_nearby')) - else + if data.current.value == 'billing' then + + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'billing', { + title = _U('invoice_amount') + }, function(data, menu) + local amount = tonumber(data.value) + + if amount == nil or amount < 0 then + ESX.ShowNotification(_U('amount_invalid')) + else + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(_U('no_players_nearby')) + else + menu.close() + TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_mecano', _U('mechanic'), amount) + end + end + end, function(data, menu) menu.close() - TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_mecano', _U('mechanic'), amount) - end - end - end, - function(data, menu) - menu.close() - end - ) - end + end) - if data.current.value == 'hijack_vehicle' then + elseif data.current.value == 'hijack_vehicle' then - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() local vehicle = ESX.Game.GetVehicleInDirection() local coords = GetEntityCoords(playerPed) @@ -432,7 +376,7 @@ function OpenMobileMecanoActionsMenu() elseif data.current.value == 'fix_vehicle' then - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() local vehicle = ESX.Game.GetVehicleInDirection() local coords = GetEntityCoords(playerPed) @@ -462,7 +406,7 @@ function OpenMobileMecanoActionsMenu() elseif data.current.value == 'clean_vehicle' then - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() local vehicle = ESX.Game.GetVehicleInDirection() local coords = GetEntityCoords(playerPed) @@ -487,588 +431,529 @@ function OpenMobileMecanoActionsMenu() ESX.ShowNotification(_U('no_vehicle_nearby')) end - elseif data.current.value == 'del_vehicle' then + elseif data.current.value == 'del_vehicle' then - local ped = GetPlayerPed(-1) + local ped = PlayerPedId() - if DoesEntityExist(ped) and not IsEntityDead(ped) then - local pos = GetEntityCoords( ped ) + if DoesEntityExist(ped) and not IsEntityDead(ped) then + local pos = GetEntityCoords( ped ) - if IsPedSittingInAnyVehicle(ped) then - local vehicle = GetVehiclePedIsIn( ped, false ) + if IsPedSittingInAnyVehicle(ped) then + local vehicle = GetVehiclePedIsIn( ped, false ) - if GetPedInVehicleSeat(vehicle, -1) == ped then - ESX.ShowNotification(_U('vehicle_impounded')) - ESX.Game.DeleteVehicle(vehicle) - else - ESX.ShowNotification(_U('must_seat_driver')) - end - else - local vehicle = ESX.Game.GetVehicleInDirection() + if GetPedInVehicleSeat(vehicle, -1) == ped then + ESX.ShowNotification(_U('vehicle_impounded')) + ESX.Game.DeleteVehicle(vehicle) + else + ESX.ShowNotification(_U('must_seat_driver')) + end + else + local vehicle = ESX.Game.GetVehicleInDirection() - if DoesEntityExist(vehicle) then - ESX.ShowNotification(_U('vehicle_impounded')) - ESX.Game.DeleteVehicle(vehicle) - else - ESX.ShowNotification(_U('must_near')) - end - end - end - end + if DoesEntityExist(vehicle) then + ESX.ShowNotification(_U('vehicle_impounded')) + ESX.Game.DeleteVehicle(vehicle) + else + ESX.ShowNotification(_U('must_near')) + end + end + end - if data.current.value == 'dep_vehicle' then + elseif data.current.value == 'dep_vehicle' then - local playerped = GetPlayerPed(-1) - local vehicle = GetVehiclePedIsIn(playerped, true) + local playerPed = PlayerPedId() + local vehicle = GetVehiclePedIsIn(playerPed, true) - local towmodel = GetHashKey('flatbed') - local isVehicleTow = IsVehicleModel(vehicle, towmodel) + local towmodel = GetHashKey('flatbed') + local isVehicleTow = IsVehicleModel(vehicle, towmodel) - if isVehicleTow then - local targetVehicle = ESX.Game.GetVehicleInDirection() + if isVehicleTow then + local targetVehicle = ESX.Game.GetVehicleInDirection() - if CurrentlyTowedVehicle == nil then - if targetVehicle ~= 0 then - if not IsPedInAnyVehicle(playerped, true) then - if vehicle ~= targetVehicle then - AttachEntityToEntity(targetVehicle, vehicle, 20, -0.5, -5.0, 1.0, 0.0, 0.0, 0.0, false, false, false, false, 20, true) - CurrentlyTowedVehicle = targetVehicle - ESX.ShowNotification(_U('vehicle_success_attached')) + if CurrentlyTowedVehicle == nil then + if targetVehicle ~= 0 then + if not IsPedInAnyVehicle(playerPed, true) then + if vehicle ~= targetVehicle then + AttachEntityToEntity(targetVehicle, vehicle, 20, -0.5, -5.0, 1.0, 0.0, 0.0, 0.0, false, false, false, false, 20, true) + CurrentlyTowedVehicle = targetVehicle + ESX.ShowNotification(_U('vehicle_success_attached')) - if NPCOnJob then + if NPCOnJob then + if NPCTargetTowable == targetVehicle then + ESX.ShowNotification(_U('please_drop_off')) + Config.Zones.VehicleDelivery.Type = 1 - if NPCTargetTowable == targetVehicle then - ESX.ShowNotification(_U('please_drop_off')) + if Blips['NPCTargetTowableZone'] ~= nil then + RemoveBlip(Blips['NPCTargetTowableZone']) + Blips['NPCTargetTowableZone'] = nil + end - Config.Zones.VehicleDelivery.Type = 1 + Blips['NPCDelivery'] = AddBlipForCoord(Config.Zones.VehicleDelivery.Pos.x, Config.Zones.VehicleDelivery.Pos.y, Config.Zones.VehicleDelivery.Pos.z) + SetBlipRoute(Blips['NPCDelivery'], true) + end + end + else + ESX.ShowNotification(_U('cant_attach_own_tt')) + end + end + else + ESX.ShowNotification(_U('no_veh_att')) + end + else - if Blips['NPCTargetTowableZone'] ~= nil then - RemoveBlip(Blips['NPCTargetTowableZone']) - Blips['NPCTargetTowableZone'] = nil - end + AttachEntityToEntity(CurrentlyTowedVehicle, vehicle, 20, -0.5, -12.0, 1.0, 0.0, 0.0, 0.0, false, false, false, false, 20, true) + DetachEntity(CurrentlyTowedVehicle, true, true) - Blips['NPCDelivery'] = AddBlipForCoord(Config.Zones.VehicleDelivery.Pos.x, Config.Zones.VehicleDelivery.Pos.y, Config.Zones.VehicleDelivery.Pos.z) + if NPCOnJob then + if NPCTargetDeleterZone then - SetBlipRoute(Blips['NPCDelivery'], true) + if CurrentlyTowedVehicle == NPCTargetTowable then + ESX.Game.DeleteVehicle(NPCTargetTowable) + TriggerServerEvent('esx_mecanojob:onNPCJobMissionCompleted') + StopNPCJob() + NPCTargetDeleterZone = false + else + ESX.ShowNotification(_U('not_right_veh')) + end - end + else + ESX.ShowNotification(_U('not_right_place')) + end + end - end + CurrentlyTowedVehicle = nil + ESX.ShowNotification(_U('veh_det_succ')) - else - ESX.ShowNotification(_U('cant_attach_own_tt')) - end - end - else - ESX.ShowNotification(_U('no_veh_att')) - end - else + end + else + ESX.ShowNotification(_U('imp_flatbed')) + end - AttachEntityToEntity(CurrentlyTowedVehicle, vehicle, 20, -0.5, -12.0, 1.0, 0.0, 0.0, 0.0, false, false, false, false, 20, true) - DetachEntity(CurrentlyTowedVehicle, true, true) + elseif data.current.value == 'object_spawner' then - if NPCOnJob then - - if NPCTargetDeleterZone then - - if CurrentlyTowedVehicle == NPCTargetTowable then - ESX.Game.DeleteVehicle(NPCTargetTowable) - TriggerServerEvent('esx_mecanojob:onNPCJobMissionCompleted') - StopNPCJob() - NPCTargetDeleterZone = false - - else - ESX.ShowNotification(_U('not_right_veh')) - end - - else - ESX.ShowNotification(_U('not_right_place')) - end - - end - - CurrentlyTowedVehicle = nil - - ESX.ShowNotification(_U('veh_det_succ')) - end - else - ESX.ShowNotification(_U('imp_flatbed')) - end - end - - if data.current.value == 'object_spawner' then - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() if IsPedSittingInAnyVehicle(playerPed) then ESX.ShowNotification(_U('inside_vehicle')) return end - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'mobile_mecano_actions_spawn', - { - title = _U('objects'), - align = 'top-left', - elements = { - {label = _U('roadcone'), value = 'prop_roadcone02a'}, - {label = _U('toolbox'), value = 'prop_toolchest_01'}, - }, - }, - function(data2, menu2) + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'mobile_mecano_actions_spawn', { + title = _U('objects'), + align = 'top-left', + elements = { + {label = _U('roadcone'), value = 'prop_roadcone02a'}, + {label = _U('toolbox'), value = 'prop_toolchest_01'} + } + }, function(data2, menu2) + local model = data2.current.value + local coords = GetEntityCoords(playerPed) + local forward = GetEntityForwardVector(playerPed) + local x, y, z = table.unpack(coords + forward * 1.0) - local model = data2.current.value - local coords = GetEntityCoords(playerPed) - local forward = GetEntityForwardVector(playerPed) - local x, y, z = table.unpack(coords + forward * 1.0) + if model == 'prop_roadcone02a' then + z = z - 2.0 + elseif model == 'prop_toolchest_01' then + z = z - 2.0 + end - if model == 'prop_roadcone02a' then - z = z - 2.0 - elseif model == 'prop_toolchest_01' then - z = z - 2.0 - end + ESX.Game.SpawnObject(model, { + x = x, + y = y, + z = z + }, function(obj) + SetEntityHeading(obj, GetEntityHeading(playerPed)) + PlaceObjectOnGroundProperly(obj) + end) - ESX.Game.SpawnObject(model, { - x = x, - y = y, - z = z - }, function(obj) - SetEntityHeading(obj, GetEntityHeading(playerPed)) - PlaceObjectOnGroundProperly(obj) - end) + end, function(data2, menu2) + menu2.close() + end) - end, - function(data2, menu2) - menu2.close() - end - ) + end - end - - end, - function(data, menu) - menu.close() - end - ) + end, function(data, menu) + menu.close() + end) end function OpenGetStocksMenu() - ESX.TriggerServerCallback('esx_mecanojob:getStockItems', function(items) - local elements = {} + ESX.TriggerServerCallback('esx_mecanojob:getStockItems', function(items) - for i=1, #items, 1 do - table.insert(elements, {label = 'x' .. items[i].count .. ' ' .. items[i].label, value = items[i].name}) - end + local elements = {} - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'stocks_menu', - { - title = _U('mechanic_stock'), - align = 'top-left', - elements = elements - }, - function(data, menu) + for i=1, #items, 1 do + table.insert(elements, { + label = 'x' .. items[i].count .. ' ' .. items[i].label, + value = items[i].name + }) + end - local itemName = data.current.value + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', + { + title = _U('mechanic_stock'), + align = 'top-left', + elements = elements + }, function(data, menu) - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'stocks_menu_get_item_count', - { - title = _U('quantity') - }, - function(data2, menu2) + local itemName = data.current.value - local count = tonumber(data2.value) + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'stocks_menu_get_item_count', { + title = _U('quantity') + }, function(data2, menu2) + local count = tonumber(data2.value) - if count == nil then - ESX.ShowNotification(_U('invalid_quantity')) - else - menu2.close() - menu.close() - TriggerServerEvent('esx_mecanojob:getStockItem', itemName, count) + if count == nil then + ESX.ShowNotification(_U('invalid_quantity')) + else + menu2.close() + menu.close() + TriggerServerEvent('esx_mecanojob:getStockItem', itemName, count) - Citizen.Wait(1000) - OpenGetStocksMenu() - end + Citizen.Wait(1000) + OpenGetStocksMenu() + end + end, function(data2, menu2) + menu2.close() + end) - end, - function(data2, menu2) - menu2.close() - end - ) + end, function(data, menu) + menu.close() + end) - end, - function(data, menu) - menu.close() - end - ) - - end) + end) end function OpenPutStocksMenu() -ESX.TriggerServerCallback('esx_mecanojob:getPlayerInventory', function(inventory) + ESX.TriggerServerCallback('esx_mecanojob:getPlayerInventory', function(inventory) + local elements = {} - local elements = {} + for i=1, #inventory.items, 1 do + local item = inventory.items[i] - for i=1, #inventory.items, 1 do + if item.count > 0 then + table.insert(elements, { + label = item.label .. ' x' .. item.count, + type = 'item_standard', + value = item.name + }) + end + end - local item = inventory.items[i] + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', { + title = _U('inventory'), + align = 'top-left', + elements = elements + }, function(data, menu) - if item.count > 0 then - table.insert(elements, {label = item.label .. ' x' .. item.count, type = 'item_standard', value = item.name}) - end + local itemName = data.current.value - end + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'stocks_menu_put_item_count', { + title = _U('quantity') + }, function(data2, menu2) + local count = tonumber(data2.value) - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'stocks_menu', - { - title = _U('inventory'), - align = 'top-left', - elements = elements - }, - function(data, menu) + if count == nil then + ESX.ShowNotification(_U('invalid_quantity')) + else + menu2.close() + menu.close() + TriggerServerEvent('esx_mecanojob:putStockItems', itemName, count) - local itemName = data.current.value + Citizen.Wait(1000) + OpenPutStocksMenu() + end + end, function(data2, menu2) + menu2.close() + end) + end, function(data, menu) + menu.close() + end) - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'stocks_menu_put_item_count', - { - title = _U('quantity') - }, - function(data2, menu2) - - local count = tonumber(data2.value) - - if count == nil then - ESX.ShowNotification(_U('invalid_quantity')) - else - menu2.close() - menu.close() - TriggerServerEvent('esx_mecanojob:putStockItems', itemName, count) - - Citizen.Wait(1000) - OpenPutStocksMenu() - end - - end, - function(data2, menu2) - menu2.close() - end - ) - - end, - function(data, menu) - menu.close() - end - ) - - end) + end) end RegisterNetEvent('esx_mecanojob:onHijack') AddEventHandler('esx_mecanojob:onHijack', function() - local playerPed = GetPlayerPed(-1) - local coords = GetEntityCoords(playerPed) + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) - if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + local vehicle = nil - local vehicle = nil + if IsPedInAnyVehicle(playerPed, false) then + vehicle = GetVehiclePedIsIn(playerPed, false) + else + vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) + end - if IsPedInAnyVehicle(playerPed, false) then - vehicle = GetVehiclePedIsIn(playerPed, false) - else - vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) - end + local chance = math.random(100) + local alarm = math.random(100) - local crochete = math.random(100) - local alarm = math.random(100) + if DoesEntityExist(vehicle) then + if alarm <= 33 then + SetVehicleAlarm(vehicle, true) + StartVehicleAlarm(vehicle) + end - if DoesEntityExist(vehicle) then - if alarm <= 33 then - SetVehicleAlarm(vehicle, true) - StartVehicleAlarm(vehicle) - end - TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_WELDING", 0, true) - Citizen.CreateThread(function() - Citizen.Wait(10000) - if crochete <= 66 then - SetVehicleDoorsLocked(vehicle, 1) - SetVehicleDoorsLockedForAllPlayers(vehicle, false) - ClearPedTasksImmediately(playerPed) - ESX.ShowNotification(_U('veh_unlocked')) - else - ESX.ShowNotification(_U('hijack_failed')) - ClearPedTasksImmediately(playerPed) - end - end) - end + TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_WELDING", 0, true) - end + Citizen.CreateThread(function() + Citizen.Wait(10000) + if chance <= 66 then + SetVehicleDoorsLocked(vehicle, 1) + SetVehicleDoorsLockedForAllPlayers(vehicle, false) + ClearPedTasksImmediately(playerPed) + ESX.ShowNotification(_U('veh_unlocked')) + else + ESX.ShowNotification(_U('hijack_failed')) + ClearPedTasksImmediately(playerPed) + end + end) + + end + end end) RegisterNetEvent('esx_mecanojob:onCarokit') AddEventHandler('esx_mecanojob:onCarokit', function() - local playerPed = GetPlayerPed(-1) - local coords = GetEntityCoords(playerPed) + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) - if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + local vehicle = nil - local vehicle = nil + if IsPedInAnyVehicle(playerPed, false) then + vehicle = GetVehiclePedIsIn(playerPed, false) + else + vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) + end - if IsPedInAnyVehicle(playerPed, false) then - vehicle = GetVehiclePedIsIn(playerPed, false) - else - vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) - end - - if DoesEntityExist(vehicle) then - TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_HAMMERING", 0, true) - Citizen.CreateThread(function() - Citizen.Wait(10000) - SetVehicleFixed(vehicle) - SetVehicleDeformationFixed(vehicle) - ClearPedTasksImmediately(playerPed) - ESX.ShowNotification(_U('body_repaired')) - end) - end - end + if DoesEntityExist(vehicle) then + TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_HAMMERING", 0, true) + Citizen.CreateThread(function() + Citizen.Wait(10000) + SetVehicleFixed(vehicle) + SetVehicleDeformationFixed(vehicle) + ClearPedTasksImmediately(playerPed) + ESX.ShowNotification(_U('body_repaired')) + end) + end + end end) RegisterNetEvent('esx_mecanojob:onFixkit') AddEventHandler('esx_mecanojob:onFixkit', function() - local playerPed = GetPlayerPed(-1) - local coords = GetEntityCoords(playerPed) + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) - if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + local vehicle = nil - local vehicle = nil + if IsPedInAnyVehicle(playerPed, false) then + vehicle = GetVehiclePedIsIn(playerPed, false) + else + vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) + end - if IsPedInAnyVehicle(playerPed, false) then - vehicle = GetVehiclePedIsIn(playerPed, false) - else - vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) - end - - if DoesEntityExist(vehicle) then - TaskStartScenarioInPlace(playerPed, "PROP_HUMAN_BUM_BIN", 0, true) - Citizen.CreateThread(function() - Citizen.Wait(20000) - SetVehicleFixed(vehicle) - SetVehicleDeformationFixed(vehicle) - SetVehicleUndriveable(vehicle, false) - ClearPedTasksImmediately(playerPed) - ESX.ShowNotification(_U('veh_repaired')) - end) - end - end + if DoesEntityExist(vehicle) then + TaskStartScenarioInPlace(playerPed, "PROP_HUMAN_BUM_BIN", 0, true) + Citizen.CreateThread(function() + Citizen.Wait(20000) + SetVehicleFixed(vehicle) + SetVehicleDeformationFixed(vehicle) + SetVehicleUndriveable(vehicle, false) + ClearPedTasksImmediately(playerPed) + ESX.ShowNotification(_U('veh_repaired')) + end) + end + end end) RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) - PlayerData = xPlayer + PlayerData = xPlayer end) RegisterNetEvent('esx:setJob') AddEventHandler('esx:setJob', function(job) - PlayerData.job = job + PlayerData.job = job end) AddEventHandler('esx_mecanojob:hasEnteredMarker', function(zone) + if zone == NPCJobTargetTowable then - if zone == NPCJobTargetTowable then + elseif zone =='VehicleDelivery' then + NPCTargetDeleterZone = true + elseif zone == 'MecanoActions' then + CurrentAction = 'mecano_actions_menu' + CurrentActionMsg = _U('open_actions') + CurrentActionData = {} + elseif zone == 'Garage' then + CurrentAction = 'mecano_harvest_menu' + CurrentActionMsg = _U('harvest_menu') + CurrentActionData = {} + elseif zone == 'Craft' then + CurrentAction = 'mecano_craft_menu' + CurrentActionMsg = _U('craft_menu') + CurrentActionData = {} + elseif zone == 'VehicleDeleter' then + local playerPed = PlayerPedId() - end - - if zone =='VehicleDelivery' then - NPCTargetDeleterZone = true - end - - if zone == 'MecanoActions' then - CurrentAction = 'mecano_actions_menu' - CurrentActionMsg = _U('open_actions') - CurrentActionData = {} - end - - if zone == 'Garage' then - CurrentAction = 'mecano_harvest_menu' - CurrentActionMsg = _U('harvest_menu') - CurrentActionData = {} - end - - if zone == 'Craft' then - CurrentAction = 'mecano_craft_menu' - CurrentActionMsg = _U('craft_menu') - CurrentActionData = {} - end - - if zone == 'VehicleDeleter' then - - local playerPed = GetPlayerPed(-1) - - if IsPedInAnyVehicle(playerPed, false) then - - local vehicle = GetVehiclePedIsIn(playerPed, false) - - CurrentAction = 'delete_vehicle' - CurrentActionMsg = _U('veh_stored') - CurrentActionData = {vehicle = vehicle} - end - end + if IsPedInAnyVehicle(playerPed, false) then + local vehicle = GetVehiclePedIsIn(playerPed, false) + CurrentAction = 'delete_vehicle' + CurrentActionMsg = _U('veh_stored') + CurrentActionData = {vehicle = vehicle} + end + end end) AddEventHandler('esx_mecanojob:hasExitedMarker', function(zone) + if zone =='VehicleDelivery' then + NPCTargetDeleterZone = false + elseif zone == 'Craft' then + TriggerServerEvent('esx_mecanojob:stopCraft') + TriggerServerEvent('esx_mecanojob:stopCraft2') + TriggerServerEvent('esx_mecanojob:stopCraft3') + elseif zone == 'Garage' then + TriggerServerEvent('esx_mecanojob:stopHarvest') + TriggerServerEvent('esx_mecanojob:stopHarvest2') + TriggerServerEvent('esx_mecanojob:stopHarvest3') + end - if zone =='VehicleDelivery' then - NPCTargetDeleterZone = false - end - - if zone == 'Craft' then - TriggerServerEvent('esx_mecanojob:stopCraft') - TriggerServerEvent('esx_mecanojob:stopCraft2') - TriggerServerEvent('esx_mecanojob:stopCraft3') - end - - if zone == 'Garage' then - TriggerServerEvent('esx_mecanojob:stopHarvest') - TriggerServerEvent('esx_mecanojob:stopHarvest2') - TriggerServerEvent('esx_mecanojob:stopHarvest3') - end - - CurrentAction = nil - ESX.UI.Menu.CloseAll() + CurrentAction = nil + ESX.UI.Menu.CloseAll() end) AddEventHandler('esx_mecanojob:hasEnteredEntityZone', function(entity) + local playerPed = PlayerPedId() - local playerPed = GetPlayerPed(-1) - - if PlayerData.job ~= nil and PlayerData.job.name == 'mecano' and not IsPedInAnyVehicle(playerPed, false) then - CurrentAction = 'remove_entity' - CurrentActionMsg = _U('press_remove_obj') - CurrentActionData = {entity = entity} - end - + if PlayerData.job ~= nil and PlayerData.job.name == 'mecano' and not IsPedInAnyVehicle(playerPed, false) then + CurrentAction = 'remove_entity' + CurrentActionMsg = _U('press_remove_obj') + CurrentActionData = {entity = entity} + end end) AddEventHandler('esx_mecanojob:hasExitedEntityZone', function(entity) - - if CurrentAction == 'remove_entity' then - CurrentAction = nil - end - + if CurrentAction == 'remove_entity' then + CurrentAction = nil + end end) RegisterNetEvent('esx_phone:loaded') AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) - local specialContact = { - name = _U('mechanic'), - number = 'mecano', - base64Icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAAA4BJREFUWIXtll9oU3cUx7/nJA02aSSlFouWMnXVB0ejU3wcRteHjv1puoc9rA978cUi2IqgRYWIZkMwrahUGfgkFMEZUdg6C+u21z1o3fbgqigVi7NzUtNcmsac40Npltz7S3rvUHzxQODec87vfD+/e0/O/QFv7Q0beV3QeXqmgV74/7H7fZJvuLwv8q/Xeux1gUrNBpN/nmtavdaqDqBK8VT2RDyV2VHmF1lvLERSBtCVynzYmcp+A9WqT9kcVKX4gHUehF0CEVY+1jYTTIwvt7YSIQnCTvsSUYz6gX5uDt7MP7KOKuQAgxmqQ+neUA+I1B1AiXi5X6ZAvKrabirmVYFwAMRT2RMg7F9SyKspvk73hfrtbkMPyIhA5FVqi0iBiEZMMQdAui/8E4GPv0oAJkpc6Q3+6goAAGpWBxNQmTLFmgL3jSJNgQdGv4pMts2EKm7ICJB/aG0xNdz74VEk13UYCx1/twPR8JjDT8wttyLZtkoAxSb8ZDCz0gdfKxWkFURf2v9qTYH7SK7rQIDn0P3nA0ehixvfwZwE0X9vBE/mW8piohhl1WH18UQBhYnre8N/L8b8xQvlx4ACbB4NnzaeRYDnKm0EALCMLXy84hwuTCXL/ExoB1E7qcK/8NCLIq5HcTT0i6u8TYbXUM1cAyyveVq8Xls7XhYrvY/4n3gC8C+dsmAzL1YUiyfWxvHzsy/w/dNd+KjhW2yvv/RfXr7x9QDcmo1he2RBiCCI1Q8jVj9szPNixVfgz+UiIGyDSrcoRu2J16d3I6e1VYvNSQjXpnucAcEPUOkGYZs/l4uUhowt/3kqu1UIv9n90fAY9jT3YBlbRvFTD4fw++wHjhiTRL/bG75t0jI2ITcHb5om4Xgmhv57xpGOg3d/NIqryOR7z+r+MC6qBJB/ZB2t9Om1D5lFm843G/3E3HI7Yh1xDRAfzLQr5EClBf/HBHK462TG2J0OABXeyWDPZ8VqxmBWYscpyghwtTd4EKpDTjCZdCNmzFM9k+4LHXIFACJN94Z6FiFEpKDQw9HndWsEuhnADVMhAUaYJBp9XrcGQKJ4qFE9k+6r2+MG3k5N8VQ22TVglbX2ZwOzX2VvNKr91zmY6S7N6zqZicVT2WNLyVSehESaBhxnOALfMeYX+K/S2yv7wmMAlvwyuR7FxQUyf0fgc/jztfkJr7XeGgC8BJJgWNV8ImT+AAAAAElFTkSuQmCC' - } - TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) + local specialContact = { + name = _U('mechanic'), + number = 'mecano', + base64Icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAAA4BJREFUWIXtll9oU3cUx7/nJA02aSSlFouWMnXVB0ejU3wcRteHjv1puoc9rA978cUi2IqgRYWIZkMwrahUGfgkFMEZUdg6C+u21z1o3fbgqigVi7NzUtNcmsac40Npltz7S3rvUHzxQODec87vfD+/e0/O/QFv7Q0beV3QeXqmgV74/7H7fZJvuLwv8q/Xeux1gUrNBpN/nmtavdaqDqBK8VT2RDyV2VHmF1lvLERSBtCVynzYmcp+A9WqT9kcVKX4gHUehF0CEVY+1jYTTIwvt7YSIQnCTvsSUYz6gX5uDt7MP7KOKuQAgxmqQ+neUA+I1B1AiXi5X6ZAvKrabirmVYFwAMRT2RMg7F9SyKspvk73hfrtbkMPyIhA5FVqi0iBiEZMMQdAui/8E4GPv0oAJkpc6Q3+6goAAGpWBxNQmTLFmgL3jSJNgQdGv4pMts2EKm7ICJB/aG0xNdz74VEk13UYCx1/twPR8JjDT8wttyLZtkoAxSb8ZDCz0gdfKxWkFURf2v9qTYH7SK7rQIDn0P3nA0ehixvfwZwE0X9vBE/mW8piohhl1WH18UQBhYnre8N/L8b8xQvlx4ACbB4NnzaeRYDnKm0EALCMLXy84hwuTCXL/ExoB1E7qcK/8NCLIq5HcTT0i6u8TYbXUM1cAyyveVq8Xls7XhYrvY/4n3gC8C+dsmAzL1YUiyfWxvHzsy/w/dNd+KjhW2yvv/RfXr7x9QDcmo1he2RBiCCI1Q8jVj9szPNixVfgz+UiIGyDSrcoRu2J16d3I6e1VYvNSQjXpnucAcEPUOkGYZs/l4uUhowt/3kqu1UIv9n90fAY9jT3YBlbRvFTD4fw++wHjhiTRL/bG75t0jI2ITcHb5om4Xgmhv57xpGOg3d/NIqryOR7z+r+MC6qBJB/ZB2t9Om1D5lFm843G/3E3HI7Yh1xDRAfzLQr5EClBf/HBHK462TG2J0OABXeyWDPZ8VqxmBWYscpyghwtTd4EKpDTjCZdCNmzFM9k+4LHXIFACJN94Z6FiFEpKDQw9HndWsEuhnADVMhAUaYJBp9XrcGQKJ4qFE9k+6r2+MG3k5N8VQ22TVglbX2ZwOzX2VvNKr91zmY6S7N6zqZicVT2WNLyVSehESaBhxnOALfMeYX+K/S2yv7wmMAlvwyuR7FxQUyf0fgc/jztfkJr7XeGgC8BJJgWNV8ImT+AAAAAElFTkSuQmCC' + } + + TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) end) -- Pop NPC mission vehicle when inside area Citizen.CreateThread(function() - while true do + while true do - Wait(0) + Citizen.Wait(10) - if NPCTargetTowableZone ~= nil and not NPCHasSpawnedTowable then + if NPCTargetTowableZone ~= nil and not NPCHasSpawnedTowable then + local coords = GetEntityCoords(PlayerPedId()) + local zone = Config.Zones[NPCTargetTowableZone] - local coords = GetEntityCoords(GetPlayerPed(-1)) - local zone = Config.Zones[NPCTargetTowableZone] + if GetDistanceBetweenCoords(coords, zone.Pos.x, zone.Pos.y, zone.Pos.z, true) < Config.NPCSpawnDistance then + local model = Config.Vehicles[GetRandomIntInRange(1, #Config.Vehicles)] - if GetDistanceBetweenCoords(coords, zone.Pos.x, zone.Pos.y, zone.Pos.z, true) < Config.NPCSpawnDistance then + ESX.Game.SpawnVehicle(model, zone.Pos, 0, function(vehicle) + NPCTargetTowable = vehicle + end) - local model = Config.Vehicles[GetRandomIntInRange(1, #Config.Vehicles)] + NPCHasSpawnedTowable = true + end + end - ESX.Game.SpawnVehicle(model, zone.Pos, 0, function(vehicle) - NPCTargetTowable = vehicle - end) + if NPCTargetTowableZone ~= nil and NPCHasSpawnedTowable and not NPCHasBeenNextToTowable then + local coords = GetEntityCoords(PlayerPedId()) + local zone = Config.Zones[NPCTargetTowableZone] - NPCHasSpawnedTowable = true + if GetDistanceBetweenCoords(coords, zone.Pos.x, zone.Pos.y, zone.Pos.z, true) < Config.NPCNextToDistance then + ESX.ShowNotification(_U('please_tow')) + NPCHasBeenNextToTowable = true + end + end - end - - end - - if NPCTargetTowableZone ~= nil and NPCHasSpawnedTowable and not NPCHasBeenNextToTowable then - - local coords = GetEntityCoords(GetPlayerPed(-1)) - local zone = Config.Zones[NPCTargetTowableZone] - - if(GetDistanceBetweenCoords(coords, zone.Pos.x, zone.Pos.y, zone.Pos.z, true) < Config.NPCNextToDistance) then - ESX.ShowNotification(_U('please_tow')) - NPCHasBeenNextToTowable = true - end - - end - - end + end end) -- Create Blips Citizen.CreateThread(function() - local blip = AddBlipForCoord(Config.Zones.MecanoActions.Pos.x, Config.Zones.MecanoActions.Pos.y, Config.Zones.MecanoActions.Pos.z) - SetBlipSprite (blip, 446) - SetBlipDisplay(blip, 4) - SetBlipScale (blip, 1.8) - SetBlipColour (blip, 5) - SetBlipAsShortRange(blip, true) - BeginTextCommandSetBlipName("STRING") - AddTextComponentString(_U('mechanic')) - EndTextCommandSetBlipName(blip) + local blip = AddBlipForCoord(Config.Zones.MecanoActions.Pos.x, Config.Zones.MecanoActions.Pos.y, Config.Zones.MecanoActions.Pos.z) + + SetBlipSprite (blip, 446) + SetBlipDisplay(blip, 4) + SetBlipScale (blip, 1.8) + SetBlipColour (blip, 5) + SetBlipAsShortRange(blip, true) + + BeginTextCommandSetBlipName("STRING") + AddTextComponentString(_U('mechanic')) + EndTextCommandSetBlipName(blip) end) -- Display markers Citizen.CreateThread(function() - while true do - Wait(0) - if PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then + while true do + Citizen.Wait(0) + if PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then + local coords = GetEntityCoords(PlayerPedId()) - local coords = GetEntityCoords(GetPlayerPed(-1)) - - for k,v in pairs(Config.Zones) do - if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then - DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) - end - end - end - end + for k,v in pairs(Config.Zones) do + if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) + end + end + end + end end) -- Enter / Exit marker events Citizen.CreateThread(function() - while true do - Wait(0) - if PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then - local coords = GetEntityCoords(GetPlayerPed(-1)) - local isInMarker = false - local currentZone = nil - for k,v in pairs(Config.Zones) do - if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then - isInMarker = true - currentZone = k - end - end - if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then - HasAlreadyEnteredMarker = true - LastZone = currentZone - TriggerEvent('esx_mecanojob:hasEnteredMarker', currentZone) - end - if not isInMarker and HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = false - TriggerEvent('esx_mecanojob:hasExitedMarker', LastZone) - end - end - end + while true do + Citizen.Wait(10) + + if PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then + + local coords = GetEntityCoords(PlayerPedId()) + local isInMarker = false + local currentZone = nil + + for k,v in pairs(Config.Zones) do + if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then + isInMarker = true + currentZone = k + end + end + + if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then + HasAlreadyEnteredMarker = true + LastZone = currentZone + TriggerEvent('esx_mecanojob:hasEnteredMarker', currentZone) + end + + if not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent('esx_mecanojob:hasExitedMarker', LastZone) + end + + end + end end) Citizen.CreateThread(function() @@ -1080,18 +965,18 @@ Citizen.CreateThread(function() while true do Citizen.Wait(500) - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) local closestDistance = -1 local closestEntity = nil for i=1, #trackedEntities, 1 do - local object = GetClosestObjectOfType(coords.x, coords.y, coords.z, 3.0, GetHashKey(trackedEntities[i]), false, false, false) + local object = GetClosestObjectOfType(coords.x, coords.y, coords.z, 3.0, GetHashKey(trackedEntities[i]), false, false, false) if DoesEntityExist(object) then local objCoords = GetEntityCoords(object) - local distance = GetDistanceBetweenCoords(coords.x, coords.y, coords.z, objCoords.x, objCoords.y, objCoords.z, true) + local distance = GetDistanceBetweenCoords(coords.x, coords.y, coords.z, objCoords.x, objCoords.y, objCoords.z, true) if closestDistance == -1 or closestDistance > distance then closestDistance = distance @@ -1116,89 +1001,79 @@ end) -- Key Controls Citizen.CreateThread(function() - while true do - Citizen.Wait(0) + while true do + Citizen.Wait(10) - if CurrentAction ~= nil then + if CurrentAction ~= nil then + ESX.ShowHelpNotification(CurrentActionMsg) - SetTextComponentFormat('STRING') - AddTextComponentString(CurrentActionMsg) - DisplayHelpTextFromStringLabel(0, 0, 1, -1) + if IsControlJustReleased(0, Keys['E']) and PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then - if IsControlJustReleased(0, Keys['E']) and PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then + if CurrentAction == 'mecano_actions_menu' then + OpenMecanoActionsMenu() + elseif CurrentAction == 'mecano_harvest_menu' then + OpenMecanoHarvestMenu() + elseif CurrentAction == 'mecano_craft_menu' then + OpenMecanoCraftMenu() + elseif CurrentAction == 'delete_vehicle' then - if CurrentAction == 'mecano_actions_menu' then - OpenMecanoActionsMenu() - end + if Config.EnableSocietyOwnedVehicles then - if CurrentAction == 'mecano_harvest_menu' then - OpenMecanoHarvestMenu() - end + local vehicleProps = ESX.Game.GetVehicleProperties(CurrentActionData.vehicle) + TriggerServerEvent('esx_society:putVehicleInGarage', 'mecano', vehicleProps) - if CurrentAction == 'mecano_craft_menu' then - OpenMecanoCraftMenu() - end + else - if CurrentAction == 'delete_vehicle' then + if + GetEntityModel(vehicle) == GetHashKey('flatbed') or + GetEntityModel(vehicle) == GetHashKey('towtruck2') or + GetEntityModel(vehicle) == GetHashKey('slamvan3') + then + TriggerServerEvent('esx_service:disableService', 'mecano') + end - if Config.EnableSocietyOwnedVehicles then + end - local vehicleProps = ESX.Game.GetVehicleProperties(CurrentActionData.vehicle) - TriggerServerEvent('esx_society:putVehicleInGarage', 'mecano', vehicleProps) + ESX.Game.DeleteVehicle(CurrentActionData.vehicle) + end - else + elseif CurrentAction == 'remove_entity' then + DeleteEntity(CurrentActionData.entity) + end - if - GetEntityModel(vehicle) == GetHashKey('flatbed') or - GetEntityModel(vehicle) == GetHashKey('towtruck2') or - GetEntityModel(vehicle) == GetHashKey('slamvan3') - then - TriggerServerEvent('esx_service:disableService', 'mecano') - end + CurrentAction = nil + end - end + if IsControlJustReleased(0, Keys['F6']) and not IsDead and PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then + OpenMobileMecanoActionsMenu() + end - ESX.Game.DeleteVehicle(CurrentActionData.vehicle) - end + if IsControlJustReleased(0, Keys['DELETE']) and not IsDead and PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then - if CurrentAction == 'remove_entity' then - DeleteEntity(CurrentActionData.entity) - end + if NPCOnJob then - CurrentAction = nil - end - end + if GetGameTimer() - NPCLastCancel > 5 * 60000 then + StopNPCJob(true) + NPCLastCancel = GetGameTimer() + else + ESX.ShowNotification(_U('wait_five')) + end - if IsControlJustReleased(0, Keys['F6']) and not IsDead and PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then - OpenMobileMecanoActionsMenu() - end + else - if IsControlJustReleased(0, Keys['DELETE']) and not IsDead and PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then + local playerPed = PlayerPedId() - if NPCOnJob then + if IsPedInAnyVehicle(playerPed, false) and IsVehicleModel(GetVehiclePedIsIn(playerPed, false), GetHashKey("flatbed")) then + StartNPCJob() + else + ESX.ShowNotification(_U('must_in_flatbed')) + end - if GetGameTimer() - NPCLastCancel > 5 * 60000 then - StopNPCJob(true) - NPCLastCancel = GetGameTimer() - else - ESX.ShowNotification(_U('wait_five')) - end + end - else + end - local playerPed = GetPlayerPed(-1) - - if IsPedInAnyVehicle(playerPed, false) and IsVehicleModel(GetVehiclePedIsIn(playerPed, false), GetHashKey("flatbed")) then - StartNPCJob() - else - ESX.ShowNotification(_U('must_in_flatbed')) - end - - end - - end - - end + end end) AddEventHandler('esx:onPlayerDeath', function() @@ -1207,4 +1082,4 @@ end) AddEventHandler('playerSpawned', function(spawn) IsDead = false -end) \ No newline at end of file +end) diff --git a/config.lua b/config.lua index f9932363..1a580b14 100644 --- a/config.lua +++ b/config.lua @@ -8,105 +8,107 @@ Config.NPCNextToDistance = 25.0 Config.NPCJobEarnings = { min = 15, max = 40 } Config.Locale = 'fr' +Config.Vehicles = { + 'adder', + 'asea', + 'asterope', + 'banshee', + 'buffalo' +} + Config.Zones = { - MecanoActions = { - Pos = { x = -342.291, y = -133.370, z = 38.009 }, - Size = { x = 1.5, y = 1.5, z = 1.0 }, - Color = { r = 204, g = 204, b = 0 }, - Type = 1, - }, - Garage = { - Pos = { x = -97.5797576904297, y = 6496.11376953125, z = 30.4909038543701 }, - Size = { x = 1.5, y = 1.5, z = 1.0 }, - Color = { r = 204, g = 204, b = 0 }, - Type = 1, - }, + MecanoActions = { + Pos = { x = -342.291, y = -133.370, z = 38.009 }, + Size = { x = 1.5, y = 1.5, z = 1.0 }, + Color = { r = 204, g = 204, b = 0 }, + Type = 1, + }, - Craft = { - Pos = { x = -323.140, y = -129.882, z = 37.999 }, - Size = { x = 1.5, y = 1.5, z = 1.0 }, - Color = { r = 204, g = 204, b = 0 }, - Type = 1, - }, + Garage = { + Pos = { x = -97.5797576904297, y = 6496.11376953125, z = 30.4909038543701 }, + Size = { x = 1.5, y = 1.5, z = 1.0 }, + Color = { r = 204, g = 204, b = 0 }, + Type = 1, + }, - VehicleSpawnPoint = { - Pos = { x = -366.354, y = -110.766, z = 37.696 }, - Size = { x = 1.5, y = 1.5, z = 1.0 }, - Type = -1, - }, + Craft = { + Pos = { x = -323.140, y = -129.882, z = 37.999 }, + Size = { x = 1.5, y = 1.5, z = 1.0 }, + Color = { r = 204, g = 204, b = 0 }, + Type = 1, + }, - VehicleDeleter = { - Pos = { x = -386.899, y = -105.675, z = 37.683 }, - Size = { x = 3.0, y = 3.0, z = 1.0 }, - Color = { r = 204, g = 204, b = 0 }, - Type = 1, - }, + VehicleSpawnPoint = { + Pos = { x = -366.354, y = -110.766, z = 37.696 }, + Size = { x = 1.5, y = 1.5, z = 1.0 }, + Type = -1, + }, + + VehicleDeleter = { + Pos = { x = -386.899, y = -105.675, z = 37.683 }, + Size = { x = 3.0, y = 3.0, z = 1.0 }, + Color = { r = 204, g = 204, b = 0 }, + Type = 1, + }, + + VehicleDelivery = { + Pos = { x = -382.925, y = -133.748, z = 37.685 }, + Size = { x = 20.0, y = 20.0, z = 3.0 }, + Color = { r = 204, g = 204, b = 0 }, + Type = -1, + } - VehicleDelivery = { - Pos = { x = -382.925, y = -133.748, z = 37.685 }, - Size = { x = 20.0, y = 20.0, z = 3.0 }, - Color = { r = 204, g = 204, b = 0 }, - Type = -1, - }, } Config.Towables = { - { ['x'] = -2480.8720703125, ['y'] = -211.96409606934, ['z'] = 17.397672653198 }, - { ['x'] = -2723.392578125, ['y'] = 13.207388877869, ['z'] = 15.12806892395 }, - { ['x'] = -3169.6235351563, ['y'] = 976.18127441406, ['z'] = 15.038360595703 }, - { ['x'] = -3139.7568359375, ['y'] = 1078.7182617188, ['z'] = 20.189767837524 }, - { ['x'] = -1656.9357910156, ['y'] = -246.16479492188, ['z'] = 54.510955810547 }, - { ['x'] = -1586.6560058594, ['y'] = -647.56115722656, ['z'] = 29.441320419312 }, - { ['x'] = -1036.1470947266, ['y'] = -491.05856323242, ['z'] = 36.214912414551 }, - { ['x'] = -1029.1884765625, ['y'] = -475.53167724609, ['z'] = 36.416831970215 }, - { ['x'] = 75.212287902832, ['y'] = 164.8522644043, ['z'] = 104.69123077393 }, - { ['x'] = -534.60491943359, ['y'] = -756.71801757813, ['z'] = 31.599143981934 }, - { ['x'] = 487.24212646484, ['y'] = -30.827201843262, ['z'] = 88.856712341309 }, - { ['x'] = -772.20111083984, ['y'] = -1281.8114013672, ['z'] = 4.5642876625061 }, - { ['x'] = -663.84173583984, ['y'] = -1206.9936523438, ['z'] = 10.171216011047 }, - { ['x'] = 719.12451171875, ['y'] = -767.77545166016, ['z'] = 24.892364501953 }, - { ['x'] = -970.95465087891, ['y'] = -2410.4453125, ['z'] = 13.344270706177 }, - { ['x'] = -1067.5234375, ['y'] = -2571.4064941406, ['z'] = 13.211874008179 }, - { ['x'] = -619.23968505859, ['y'] = -2207.2927246094, ['z'] = 5.5659561157227 }, - { ['x'] = 1192.0831298828, ['y'] = -1336.9086914063, ['z'] = 35.106426239014 }, - { ['x'] = -432.81033325195, ['y'] = -2166.0505371094, ['z'] = 9.8885231018066 }, - { ['x'] = -451.82403564453, ['y'] = -2269.34765625, ['z'] = 7.1719741821289 }, - { ['x'] = 939.26702880859, ['y'] = -2197.5390625, ['z'] = 30.546691894531 }, - { ['x'] = -556.11486816406, ['y'] = -1794.7312011719, ['z'] = 22.043060302734 }, - { ['x'] = 591.73504638672, ['y'] = -2628.2197265625, ['z'] = 5.5735430717468 }, - { ['x'] = 1654.515625, ['y'] = -2535.8325195313, ['z'] = 74.491394042969 }, - { ['x'] = 1642.6146240234, ['y'] = -2413.3159179688, ['z'] = 93.139915466309 }, - { ['x'] = 1371.3223876953, ['y'] = -2549.525390625, ['z'] = 47.575256347656 }, - { ['x'] = 383.83779907227, ['y'] = -1652.8695068359, ['z'] = 37.278503417969 }, - { ['x'] = 27.219129562378, ['y'] = -1030.8818359375, ['z'] = 29.414621353149 }, - { ['x'] = 229.26435852051, ['y'] = -365.91101074219, ['z'] = 43.750762939453 }, - { ['x'] = -85.809432983398, ['y'] = -51.665500640869, ['z'] = 61.10591506958 }, - { ['x'] = -4.5967531204224, ['y'] = -670.27124023438, ['z'] = 31.85863494873 }, - { ['x'] = -111.89884185791, ['y'] = 91.96940612793, ['z'] = 71.080169677734 }, - { ['x'] = -314.26129150391, ['y'] = -698.23309326172, ['z'] = 32.545776367188 }, - { ['x'] = -366.90979003906, ['y'] = 115.53963470459, ['z'] = 65.575706481934 }, - { ['x'] = -592.06726074219, ['y'] = 138.20733642578, ['z'] = 60.074813842773 }, - { ['x'] = -1613.8572998047, ['y'] = 18.759860992432, ['z'] = 61.799819946289 }, - { ['x'] = -1709.7995605469, ['y'] = 55.105819702148, ['z'] = 65.706237792969 }, - { ['x'] = -521.88830566406, ['y'] = -266.7805480957, ['z'] = 34.940990447998 }, - { ['x'] = -451.08666992188, ['y'] = -333.52026367188, ['z'] = 34.021533966064 }, - { ['x'] = 322.36480712891, ['y'] = -1900.4990234375, ['z'] = 25.773607254028 }, + { ['x'] = -2480.8720703125, ['y'] = -211.96409606934, ['z'] = 17.397672653198 }, + { ['x'] = -2723.392578125, ['y'] = 13.207388877869, ['z'] = 15.12806892395 }, + { ['x'] = -3169.6235351563, ['y'] = 976.18127441406, ['z'] = 15.038360595703 }, + { ['x'] = -3139.7568359375, ['y'] = 1078.7182617188, ['z'] = 20.189767837524 }, + { ['x'] = -1656.9357910156, ['y'] = -246.16479492188, ['z'] = 54.510955810547 }, + { ['x'] = -1586.6560058594, ['y'] = -647.56115722656, ['z'] = 29.441320419312 }, + { ['x'] = -1036.1470947266, ['y'] = -491.05856323242, ['z'] = 36.214912414551 }, + { ['x'] = -1029.1884765625, ['y'] = -475.53167724609, ['z'] = 36.416831970215 }, + { ['x'] = 75.212287902832, ['y'] = 164.8522644043, ['z'] = 104.69123077393 }, + { ['x'] = -534.60491943359, ['y'] = -756.71801757813, ['z'] = 31.599143981934 }, + { ['x'] = 487.24212646484, ['y'] = -30.827201843262, ['z'] = 88.856712341309 }, + { ['x'] = -772.20111083984, ['y'] = -1281.8114013672, ['z'] = 4.5642876625061 }, + { ['x'] = -663.84173583984, ['y'] = -1206.9936523438, ['z'] = 10.171216011047 }, + { ['x'] = 719.12451171875, ['y'] = -767.77545166016, ['z'] = 24.892364501953 }, + { ['x'] = -970.95465087891, ['y'] = -2410.4453125, ['z'] = 13.344270706177 }, + { ['x'] = -1067.5234375, ['y'] = -2571.4064941406, ['z'] = 13.211874008179 }, + { ['x'] = -619.23968505859, ['y'] = -2207.2927246094, ['z'] = 5.5659561157227 }, + { ['x'] = 1192.0831298828, ['y'] = -1336.9086914063, ['z'] = 35.106426239014 }, + { ['x'] = -432.81033325195, ['y'] = -2166.0505371094, ['z'] = 9.8885231018066 }, + { ['x'] = -451.82403564453, ['y'] = -2269.34765625, ['z'] = 7.1719741821289 }, + { ['x'] = 939.26702880859, ['y'] = -2197.5390625, ['z'] = 30.546691894531 }, + { ['x'] = -556.11486816406, ['y'] = -1794.7312011719, ['z'] = 22.043060302734 }, + { ['x'] = 591.73504638672, ['y'] = -2628.2197265625, ['z'] = 5.5735430717468 }, + { ['x'] = 1654.515625, ['y'] = -2535.8325195313, ['z'] = 74.491394042969 }, + { ['x'] = 1642.6146240234, ['y'] = -2413.3159179688, ['z'] = 93.139915466309 }, + { ['x'] = 1371.3223876953, ['y'] = -2549.525390625, ['z'] = 47.575256347656 }, + { ['x'] = 383.83779907227, ['y'] = -1652.8695068359, ['z'] = 37.278503417969 }, + { ['x'] = 27.219129562378, ['y'] = -1030.8818359375, ['z'] = 29.414621353149 }, + { ['x'] = 229.26435852051, ['y'] = -365.91101074219, ['z'] = 43.750762939453 }, + { ['x'] = -85.809432983398, ['y'] = -51.665500640869, ['z'] = 61.10591506958 }, + { ['x'] = -4.5967531204224, ['y'] = -670.27124023438, ['z'] = 31.85863494873 }, + { ['x'] = -111.89884185791, ['y'] = 91.96940612793, ['z'] = 71.080169677734 }, + { ['x'] = -314.26129150391, ['y'] = -698.23309326172, ['z'] = 32.545776367188 }, + { ['x'] = -366.90979003906, ['y'] = 115.53963470459, ['z'] = 65.575706481934 }, + { ['x'] = -592.06726074219, ['y'] = 138.20733642578, ['z'] = 60.074813842773 }, + { ['x'] = -1613.8572998047, ['y'] = 18.759860992432, ['z'] = 61.799819946289 }, + { ['x'] = -1709.7995605469, ['y'] = 55.105819702148, ['z'] = 65.706237792969 }, + { ['x'] = -521.88830566406, ['y'] = -266.7805480957, ['z'] = 34.940990447998 }, + { ['x'] = -451.08666992188, ['y'] = -333.52026367188, ['z'] = 34.021533966064 }, + { ['x'] = 322.36480712891, ['y'] = -1900.4990234375, ['z'] = 25.773607254028 } } for i=1, #Config.Towables, 1 do - Config.Zones['Towable' .. i] = { - Pos = Config.Towables[i], - Size = { x = 1.5, y = 1.5, z = 1.0 }, - Color = { r = 204, g = 204, b = 0 }, - Type = -1 - } + Config.Zones['Towable' .. i] = { + Pos = Config.Towables[i], + Size = { x = 1.5, y = 1.5, z = 1.0 }, + Color = { r = 204, g = 204, b = 0 }, + Type = -1 + } end - -Config.Vehicles = { - 'adder', - 'asea', - 'asterope', - 'banshee', - 'buffalo' -} diff --git a/server/main.lua b/server/main.lua index 890bdd75..ce4baf68 100644 --- a/server/main.lua +++ b/server/main.lua @@ -9,262 +9,251 @@ PlayersCrafting3 = {} TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) if Config.MaxInService ~= -1 then - TriggerEvent('esx_service:activateService', 'mecano', Config.MaxInService) + TriggerEvent('esx_service:activateService', 'mecano', Config.MaxInService) end TriggerEvent('esx_phone:registerNumber', 'mecano', _U('mechanic_customer'), true, true) TriggerEvent('esx_society:registerSociety', 'mecano', 'Mecano', 'society_mecano', 'society_mecano', 'society_mecano', {type = 'private'}) local function Harvest(source) + SetTimeout(4000, function() - SetTimeout(4000, function() + if PlayersHarvesting[source] == true then + local xPlayer = ESX.GetPlayerFromId(source) + local GazBottleQuantity = xPlayer.getInventoryItem('gazbottle').count - if PlayersHarvesting[source] == true then + if GazBottleQuantity >= 5 then + TriggerClientEvent('esx:showNotification', source, _U('you_do_not_room')) + else + xPlayer.addInventoryItem('gazbottle', 1) + Harvest(source) + end + end - local xPlayer = ESX.GetPlayerFromId(source) - local GazBottleQuantity = xPlayer.getInventoryItem('gazbottle').count - - if GazBottleQuantity >= 5 then - TriggerClientEvent('esx:showNotification', source, _U('you_do_not_room')) - else - xPlayer.addInventoryItem('gazbottle', 1) - Harvest(source) - end - end - end) + end) end RegisterServerEvent('esx_mecanojob:startHarvest') AddEventHandler('esx_mecanojob:startHarvest', function() - local _source = source - PlayersHarvesting[_source] = true - TriggerClientEvent('esx:showNotification', _source, _U('recovery_gas_can')) - Harvest(source) + local _source = source + PlayersHarvesting[_source] = true + TriggerClientEvent('esx:showNotification', _source, _U('recovery_gas_can')) + Harvest(source) end) RegisterServerEvent('esx_mecanojob:stopHarvest') AddEventHandler('esx_mecanojob:stopHarvest', function() - local _source = source - PlayersHarvesting[_source] = false + local _source = source + PlayersHarvesting[_source] = false end) local function Harvest2(source) + SetTimeout(4000, function() - SetTimeout(4000, function() + if PlayersHarvesting2[source] == true then + local xPlayer = ESX.GetPlayerFromId(source) + local FixToolQuantity = xPlayer.getInventoryItem('fixtool').count - if PlayersHarvesting2[source] == true then + if FixToolQuantity >= 5 then + TriggerClientEvent('esx:showNotification', source, _U('you_do_not_room')) + else + xPlayer.addInventoryItem('fixtool', 1) + Harvest2(source) + end + end - local xPlayer = ESX.GetPlayerFromId(source) - local FixToolQuantity = xPlayer.getInventoryItem('fixtool').count - if FixToolQuantity >= 5 then - TriggerClientEvent('esx:showNotification', source, _U('you_do_not_room')) - else - xPlayer.addInventoryItem('fixtool', 1) - Harvest2(source) - end - end - end) + end) end RegisterServerEvent('esx_mecanojob:startHarvest2') AddEventHandler('esx_mecanojob:startHarvest2', function() - local _source = source - PlayersHarvesting2[_source] = true - TriggerClientEvent('esx:showNotification', _source, _U('recovery_repair_tools')) - Harvest2(_source) + local _source = source + PlayersHarvesting2[_source] = true + TriggerClientEvent('esx:showNotification', _source, _U('recovery_repair_tools')) + Harvest2(_source) end) RegisterServerEvent('esx_mecanojob:stopHarvest2') AddEventHandler('esx_mecanojob:stopHarvest2', function() - local _source = source - PlayersHarvesting2[_source] = false + local _source = source + PlayersHarvesting2[_source] = false end) local function Harvest3(source) + SetTimeout(4000, function() - SetTimeout(4000, function() + if PlayersHarvesting3[source] == true then + local xPlayer = ESX.GetPlayerFromId(source) + local CaroToolQuantity = xPlayer.getInventoryItem('carotool').count + if CaroToolQuantity >= 5 then + TriggerClientEvent('esx:showNotification', source, _U('you_do_not_room')) + else + xPlayer.addInventoryItem('carotool', 1) + Harvest3(source) + end + end - if PlayersHarvesting3[source] == true then - - local xPlayer = ESX.GetPlayerFromId(source) - local CaroToolQuantity = xPlayer.getInventoryItem('carotool').count - if CaroToolQuantity >= 5 then - TriggerClientEvent('esx:showNotification', source, _U('you_do_not_room')) - else - xPlayer.addInventoryItem('carotool', 1) - Harvest3(source) - end - end - end) + end) end RegisterServerEvent('esx_mecanojob:startHarvest3') AddEventHandler('esx_mecanojob:startHarvest3', function() - local _source = source - PlayersHarvesting3[_source] = true - TriggerClientEvent('esx:showNotification', _source, _U('recovery_body_tools')) - Harvest3(_source) + local _source = source + PlayersHarvesting3[_source] = true + TriggerClientEvent('esx:showNotification', _source, _U('recovery_body_tools')) + Harvest3(_source) end) RegisterServerEvent('esx_mecanojob:stopHarvest3') AddEventHandler('esx_mecanojob:stopHarvest3', function() - local _source = source - PlayersHarvesting3[_source] = false + local _source = source + PlayersHarvesting3[_source] = false end) local function Craft(source) + SetTimeout(4000, function() - SetTimeout(4000, function() + if PlayersCrafting[source] == true then + local xPlayer = ESX.GetPlayerFromId(source) + local GazBottleQuantity = xPlayer.getInventoryItem('gazbottle').count - if PlayersCrafting[source] == true then + if GazBottleQuantity <= 0 then + TriggerClientEvent('esx:showNotification', source, _U('not_enough_gas_can')) + else + xPlayer.removeInventoryItem('gazbottle', 1) + xPlayer.addInventoryItem('blowpipe', 1) + Craft(source) + end + end - local xPlayer = ESX.GetPlayerFromId(source) - local GazBottleQuantity = xPlayer.getInventoryItem('gazbottle').count - - if GazBottleQuantity <= 0 then - TriggerClientEvent('esx:showNotification', source, _U('not_enough_gas_can')) - else - xPlayer.removeInventoryItem('gazbottle', 1) - xPlayer.addInventoryItem('blowpipe', 1) - Craft(source) - end - end - end) + end) end RegisterServerEvent('esx_mecanojob:startCraft') AddEventHandler('esx_mecanojob:startCraft', function() - local _source = source - PlayersCrafting[_source] = true - TriggerClientEvent('esx:showNotification', _source, _U('assembling_blowtorch')) - Craft(_source) + local _source = source + PlayersCrafting[_source] = true + TriggerClientEvent('esx:showNotification', _source, _U('assembling_blowtorch')) + Craft(_source) end) RegisterServerEvent('esx_mecanojob:stopCraft') AddEventHandler('esx_mecanojob:stopCraft', function() - local _source = source - PlayersCrafting[_source] = false + local _source = source + PlayersCrafting[_source] = false end) local function Craft2(source) + SetTimeout(4000, function() - SetTimeout(4000, function() + if PlayersCrafting2[source] == true then + local xPlayer = ESX.GetPlayerFromId(source) + local FixToolQuantity = xPlayer.getInventoryItem('fixtool').count - if PlayersCrafting2[source] == true then + if FixToolQuantity <= 0 then + TriggerClientEvent('esx:showNotification', source, _U('not_enough_repair_tools')) + else + xPlayer.removeInventoryItem('fixtool', 1) + xPlayer.addInventoryItem('fixkit', 1) + Craft2(source) + end + end - local xPlayer = ESX.GetPlayerFromId(source) - local FixToolQuantity = xPlayer.getInventoryItem('fixtool').count - if FixToolQuantity <= 0 then - TriggerClientEvent('esx:showNotification', source, _U('not_enough_repair_tools')) - else - xPlayer.removeInventoryItem('fixtool', 1) - xPlayer.addInventoryItem('fixkit', 1) - Craft2(source) - end - end - end) + end) end RegisterServerEvent('esx_mecanojob:startCraft2') AddEventHandler('esx_mecanojob:startCraft2', function() - local _source = source - PlayersCrafting2[_source] = true - TriggerClientEvent('esx:showNotification', _source, _U('assembling_repair_kit')) - Craft2(_source) + local _source = source + PlayersCrafting2[_source] = true + TriggerClientEvent('esx:showNotification', _source, _U('assembling_repair_kit')) + Craft2(_source) end) RegisterServerEvent('esx_mecanojob:stopCraft2') AddEventHandler('esx_mecanojob:stopCraft2', function() - local _source = source - PlayersCrafting2[_source] = false + local _source = source + PlayersCrafting2[_source] = false end) local function Craft3(source) + SetTimeout(4000, function() - SetTimeout(4000, function() + if PlayersCrafting3[source] == true then + local xPlayer = ESX.GetPlayerFromId(source) + local CaroToolQuantity = xPlayer.getInventoryItem('carotool').count - if PlayersCrafting3[source] == true then + if CaroToolQuantity <= 0 then + TriggerClientEvent('esx:showNotification', source, _U('not_enough_body_tools')) + else + xPlayer.removeInventoryItem('carotool', 1) + xPlayer.addInventoryItem('carokit', 1) + Craft3(source) + end + end - local xPlayer = ESX.GetPlayerFromId(source) - local CaroToolQuantity = xPlayer.getInventoryItem('carotool').count - if CaroToolQuantity <= 0 then - TriggerClientEvent('esx:showNotification', source, _U('not_enough_body_tools')) - else - xPlayer.removeInventoryItem('carotool', 1) - xPlayer.addInventoryItem('carokit', 1) - Craft3(source) - end - end - end) + end) end RegisterServerEvent('esx_mecanojob:startCraft3') AddEventHandler('esx_mecanojob:startCraft3', function() - local _source = source - PlayersCrafting3[_source] = true - TriggerClientEvent('esx:showNotification', _source, _U('assembling_body_kit')) - Craft3(_source) + local _source = source + PlayersCrafting3[_source] = true + TriggerClientEvent('esx:showNotification', _source, _U('assembling_body_kit')) + Craft3(_source) end) RegisterServerEvent('esx_mecanojob:stopCraft3') AddEventHandler('esx_mecanojob:stopCraft3', function() - local _source = source - PlayersCrafting3[_source] = false + local _source = source + PlayersCrafting3[_source] = false end) RegisterServerEvent('esx_mecanojob:onNPCJobMissionCompleted') AddEventHandler('esx_mecanojob:onNPCJobMissionCompleted', function() + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) + local total = math.random(Config.NPCJobEarnings.min, Config.NPCJobEarnings.max); - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) - local total = math.random(Config.NPCJobEarnings.min, Config.NPCJobEarnings.max); + if xPlayer.job.grade >= 3 then + total = total * 2 + end - if xPlayer.job.grade >= 3 then - total = total * 2 - end - - TriggerEvent('esx_addonaccount:getSharedAccount', 'society_mecano', function(account) - account.addMoney(total) - end) - - TriggerClientEvent("esx:showNotification", _source, _U('your_comp_earned').. total) + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_mecano', function(account) + account.addMoney(total) + end) + TriggerClientEvent("esx:showNotification", _source, _U('your_comp_earned').. total) end) ESX.RegisterUsableItem('blowpipe', function(source) + local _source = source + local xPlayer = ESX.GetPlayerFromId(source) - local _source = source - local xPlayer = ESX.GetPlayerFromId(source) - - xPlayer.removeInventoryItem('blowpipe', 1) - - TriggerClientEvent('esx_mecanojob:onHijack', _source) - TriggerClientEvent('esx:showNotification', _source, _U('you_used_blowtorch')) + xPlayer.removeInventoryItem('blowpipe', 1) + TriggerClientEvent('esx_mecanojob:onHijack', _source) + TriggerClientEvent('esx:showNotification', _source, _U('you_used_blowtorch')) end) ESX.RegisterUsableItem('fixkit', function(source) + local _source = source + local xPlayer = ESX.GetPlayerFromId(source) - local _source = source - local xPlayer = ESX.GetPlayerFromId(source) - - xPlayer.removeInventoryItem('fixkit', 1) - - TriggerClientEvent('esx_mecanojob:onFixkit', _source) - TriggerClientEvent('esx:showNotification', _source, _U('you_used_repair_kit')) + xPlayer.removeInventoryItem('fixkit', 1) + TriggerClientEvent('esx_mecanojob:onFixkit', _source) + TriggerClientEvent('esx:showNotification', _source, _U('you_used_repair_kit')) end) ESX.RegisterUsableItem('carokit', function(source) + local _source = source + local xPlayer = ESX.GetPlayerFromId(source) - local _source = source - local xPlayer = ESX.GetPlayerFromId(source) - - xPlayer.removeInventoryItem('carokit', 1) - - TriggerClientEvent('esx_mecanojob:onCarokit', _source) - TriggerClientEvent('esx:showNotification', _source, _U('you_used_body_kit')) + xPlayer.removeInventoryItem('carokit', 1) + TriggerClientEvent('esx_mecanojob:onCarokit', _source) + TriggerClientEvent('esx:showNotification', _source, _U('you_used_body_kit')) end) RegisterServerEvent('esx_mecanojob:getStockItem') @@ -274,10 +263,10 @@ AddEventHandler('esx_mecanojob:getStockItem', function(itemName, count) TriggerEvent('esx_addoninventory:getSharedInventory', 'society_mecano', function(inventory) local item = inventory.getItem(itemName) local sourceItem = xPlayer.getInventoryItem(itemName) - + -- is there enough in the society? if count > 0 and item.count >= count then - + -- can the player carry the said amount of x item? if sourceItem.limit ~= -1 and (sourceItem.count + count) > sourceItem.limit then TriggerClientEvent('esx:showNotification', xPlayer.source, _U('player_cannot_hold')) @@ -293,43 +282,33 @@ AddEventHandler('esx_mecanojob:getStockItem', function(itemName, count) end) ESX.RegisterServerCallback('esx_mecanojob:getStockItems', function(source, cb) - - TriggerEvent('esx_addoninventory:getSharedInventory', 'society_mecano', function(inventory) - cb(inventory.items) - end) - + TriggerEvent('esx_addoninventory:getSharedInventory', 'society_mecano', function(inventory) + cb(inventory.items) + end) end) RegisterServerEvent('esx_mecanojob:putStockItems') AddEventHandler('esx_mecanojob:putStockItems', function(itemName, count) + local xPlayer = ESX.GetPlayerFromId(source) - local xPlayer = ESX.GetPlayerFromId(source) + TriggerEvent('esx_addoninventory:getSharedInventory', 'society_mecano', function(inventory) + local item = inventory.getItem(itemName) + local playerItemCount = xPlayer.getInventoryItem(itemName).count - TriggerEvent('esx_addoninventory:getSharedInventory', 'society_mecano', function(inventory) - - local item = inventory.getItem(itemName) - local playerItemCount = xPlayer.getInventoryItem(itemName).count - - if item.count >= 0 and count <= playerItemCount then - xPlayer.removeInventoryItem(itemName, count) - inventory.addItem(itemName, count) - else - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('invalid_quantity')) - end - - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('have_deposited', count, item.label)) - - end) + if item.count >= 0 and count <= playerItemCount then + xPlayer.removeInventoryItem(itemName, count) + inventory.addItem(itemName, count) + else + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('invalid_quantity')) + end + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('have_deposited', count, item.label)) + end) end) ESX.RegisterServerCallback('esx_mecanojob:getPlayerInventory', function(source, cb) + local xPlayer = ESX.GetPlayerFromId(source) + local items = xPlayer.inventory - local xPlayer = ESX.GetPlayerFromId(source) - local items = xPlayer.inventory - - cb({ - items = items - }) - + cb({items = items}) end) From 7b8329878f028f3f6fcb2f64fd15f648c7983014 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 10 Nov 2018 19:37:13 +0100 Subject: [PATCH 1902/3224] Fixed removing dressing label, close menu on enter and proper loadout fetch --- client/main.lua | 46 ++++++++++++++++++++++------------------------ server/main.lua | 11 ++++++----- 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/client/main.lua b/client/main.lua index 4f975a71..0adecf7e 100644 --- a/client/main.lua +++ b/client/main.lua @@ -368,7 +368,7 @@ function OpenGatewayOwnedPropertiesMenu(property) if data2.current.value == 'enter' then TriggerEvent('instance:create', 'property', {property = data.current.value, owner = ESX.GetPlayerData().identifier}) - menu2.close() + ESX.UI.Menu.CloseAll() elseif data2.current.value == 'leave' then TriggerServerEvent('esx_property:removeOwnedProperty', data.current.value) end @@ -490,7 +490,10 @@ function OpenRoomMenu(property, owner) local elements = {} for i=1, #dressing, 1 do - table.insert(elements, {label = dressing[i], value = i}) + table.insert(elements, { + label = dressing[i], + value = i + }) end ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'player_dressing', @@ -520,13 +523,15 @@ function OpenRoomMenu(property, owner) ESX.TriggerServerCallback('esx_property:getPlayerDressing', function(dressing) local elements = {} - + for i=1, #dressing, 1 do - table.insert(elements, {label = dressing[i].label, value = i}) + table.insert(elements, { + label = dressing[i], + value = i + }) end - - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'remove_cloth', - { + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'remove_cloth', { title = property.label .. ' - ' .. _U('remove_cloth'), align = 'top-left', elements = elements @@ -534,8 +539,7 @@ function OpenRoomMenu(property, owner) menu2.close() TriggerServerEvent('esx_property:removeOutfit', data2.current.value) ESX.ShowNotification(_U('removed_cloth')) - end, - function(data2, menu2) + end, function(data2, menu2) menu2.close() end) end) @@ -656,7 +660,7 @@ function OpenPlayerInventoryMenu(property, owner) for i=1, #inventory.items, 1 do local item = inventory.items[i] - + if item.count > 0 then table.insert(elements, { label = item.label .. ' x' .. item.count, @@ -666,21 +670,15 @@ function OpenPlayerInventoryMenu(property, owner) end end - local playerPed = PlayerPedId() - local weaponList = ESX.GetWeaponList() + for i=1, #inventory.weapons, 1 do + local weapon = inventory.weapons[i] - for i=1, #weaponList, 1 do - local weaponHash = GetHashKey(weaponList[i].name) - if HasPedGotWeapon(playerPed, weaponHash, false) and weaponList[i].name ~= 'WEAPON_UNARMED' then - local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) - - table.insert(elements, { - label = weaponList[i].label .. ' [' .. ammo .. ']', - type = 'item_weapon', - value = weaponList[i].name, - ammo = ammo - }) - end + table.insert(elements, { + label = weapon.label .. ' [' .. weapon.ammo .. ']', + type = 'item_weapon', + value = weapon.name, + ammo = weapon.ammo + }) end ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'player_inventory', diff --git a/server/main.lua b/server/main.lua index c578dfb1..2b8ad71f 100644 --- a/server/main.lua +++ b/server/main.lua @@ -212,10 +212,10 @@ AddEventHandler('esx_property:getItem', function(owner, type, item, count) if type == 'item_standard' then local sourceItem = xPlayer.getInventoryItem(item) - + TriggerEvent('esx_addoninventory:getInventory', 'property', xPlayerOwner.identifier, function(inventory) local inventoryItem = inventory.getItem(item) - + -- is there enough in the property? if count > 0 and inventoryItem.count >= count then @@ -380,7 +380,8 @@ ESX.RegisterServerCallback('esx_property:getPlayerInventory', function(source, c cb({ blackMoney = blackMoney, - items = items + items = items, + weapons = xPlayer.getLoadout() }) end) @@ -388,8 +389,8 @@ ESX.RegisterServerCallback('esx_property:getPlayerDressing', function(source, cb local xPlayer = ESX.GetPlayerFromId(source) TriggerEvent('esx_datastore:getDataStore', 'property', xPlayer.identifier, function(store) - local count = store.count('dressing') - local labels = {} + local count = store.count('dressing') + local labels = {} for i=1, count, 1 do local entry = store.get('dressing', i) From 08df1362491a808b113b9d89d66c727007821e33 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 10 Nov 2018 21:44:23 +0100 Subject: [PATCH 1903/3224] Default language to France --- config.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.lua b/config.lua index c7a6590b..a42083d6 100644 --- a/config.lua +++ b/config.lua @@ -1,5 +1,5 @@ Config = {} -Config.Locale = 'sv' +Config.Locale = 'fr' Config.Accounts = { 'bank', 'black_money' } Config.AccountLabels = { bank = _U('bank'), black_money = _U('black_money') } From a567e94f50bc7452944d9ad53e81d57d9dc9f7cd Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 10 Nov 2018 23:30:14 +0100 Subject: [PATCH 1904/3224] Don't select everything, async usage --- server/main.lua | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/server/main.lua b/server/main.lua index d1dc69eb..3e46bf71 100644 --- a/server/main.lua +++ b/server/main.lua @@ -69,19 +69,21 @@ RegisterCommand('news', function(source, args, rawCommand) end, false) function GetCharacterName(source) - -- fetch identity in sync - local result = MySQL.Sync.fetchAll('SELECT * FROM users WHERE identifier = @identifier', - { - ['@identifier'] = GetPlayerIdentifiers(source)[1] - }) - if result[1] ~= nil and result[1].firstname ~= nil and result[1].lastname ~= nil then - if Config.OnlyFirstname then - return result[1].firstname + MySQL.Async.fetchAll('SELECT firstname, lastname FROM users WHERE identifier = @identifier', { + ['@identifier'] = GetPlayerIdentifiers(source)[1] + }, function(result) + if result[1] ~= nil and result[1].firstname ~= nil and result[1].lastname ~= nil then + + if Config.OnlyFirstname then + return result[1].firstname + else + return result[1].firstname .. ' ' .. result[1].lastname + end + else - return result[1].firstname .. ' ' .. result[1].lastname + return GetPlayerName(source) end - else - return GetPlayerName(source) - end + end) + end From 5c49d02433330a26fc80bb7d5c4f029af754b252 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 10 Nov 2018 23:47:14 +0100 Subject: [PATCH 1905/3224] Cleanup, fixed #6 --- __resource.lua | 42 ++++++++++++------------ client/main.lua | 85 +++++++++++++++---------------------------------- config.lua | 27 ++++++++-------- locales/br.lua | 17 +++++----- locales/de.lua | 15 ++++----- locales/en.lua | 17 +++++----- locales/es.lua | 15 ++++----- locales/fi.lua | 17 +++++----- locales/fr.lua | 17 +++++----- server/main.lua | 18 +++-------- 10 files changed, 111 insertions(+), 159 deletions(-) diff --git a/__resource.lua b/__resource.lua index f6487c62..a31bfb4d 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,30 +1,32 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' -description 'ESX BarberShop' +description 'ESX Barber Shop' version '1.0.1' server_scripts { - '@mysql-async/lib/MySQL.lua', - '@es_extended/locale.lua', - 'locales/br.lua', - 'locales/de.lua', - 'locales/en.lua', - 'locales/fi.lua', - 'locales/fr.lua', - 'locales/es.lua', - 'config.lua', - 'server/main.lua' + '@mysql-async/lib/MySQL.lua', + '@es_extended/locale.lua', + 'locales/br.lua', + 'locales/de.lua', + 'locales/en.lua', + 'locales/fi.lua', + 'locales/fr.lua', + 'locales/es.lua', + 'config.lua', + 'server/main.lua' } client_scripts { - '@es_extended/locale.lua', - 'locales/br.lua', - 'locales/de.lua', - 'locales/en.lua', - 'locales/fi.lua', - 'locales/fr.lua', - 'locales/es.lua', - 'config.lua', - 'client/main.lua' + '@es_extended/locale.lua', + 'locales/br.lua', + 'locales/de.lua', + 'locales/en.lua', + 'locales/fi.lua', + 'locales/fr.lua', + 'locales/es.lua', + 'config.lua', + 'client/main.lua' } + +dependency 'es_extended' \ No newline at end of file diff --git a/client/main.lua b/client/main.lua index 188840d1..ccc1c905 100644 --- a/client/main.lua +++ b/client/main.lua @@ -18,20 +18,18 @@ local LastZone = nil local CurrentAction = nil local CurrentActionMsg = '' local CurrentActionData = {} -local HasPayed = false +local HasPaid = false Citizen.CreateThread(function() - while ESX == nil do TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) Citizen.Wait(0) end - end) function OpenShopMenu() - HasPayed = false + HasPaid = false TriggerEvent('esx_skin:openRestrictedMenu', function(data, menu) @@ -43,45 +41,37 @@ function OpenShopMenu() title = _U('valid_purchase'), align = 'top-left', elements = { - {label = _U('yes'), value = 'yes'}, - {label = _U('no'), value = 'no'}, + {label = _U('no'), value = 'no'}, + {label = _U('yes'), value = 'yes'} } }, function(data, menu) - menu.close() if data.current.value == 'yes' then ESX.TriggerServerCallback('esx_barbershop:checkMoney', function(hasEnoughMoney) - if hasEnoughMoney then - TriggerEvent('skinchanger:getSkin', function(skin) TriggerServerEvent('esx_skin:save', skin) end) TriggerServerEvent('esx_barbershop:pay') - HasPayed = true + HasPaid = true else - - TriggerEvent('esx_skin:getLastSkin', function(skin) - TriggerEvent('skinchanger:loadSkin', skin) + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin) + TriggerEvent('skinchanger:loadSkin', skin) end) ESX.ShowNotification(_U('not_enough_money')) - end - end) - end + elseif data.current.value == 'no' then - if data.current.value == 'no' then - - TriggerEvent('esx_skin:getLastSkin', function(skin) - TriggerEvent('skinchanger:loadSkin', skin) + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin) + TriggerEvent('skinchanger:loadSkin', skin) end) end @@ -89,27 +79,20 @@ function OpenShopMenu() CurrentAction = 'shop_menu' CurrentActionMsg = _U('press_access') CurrentActionData = {} - - end, - function(data, menu) - + end, function(data, menu) menu.close() CurrentAction = 'shop_menu' CurrentActionMsg = _U('press_access') CurrentActionData = {} - - end - ) + end) end, function(data, menu) - menu.close() CurrentAction = 'shop_menu' CurrentActionMsg = _U('press_access') CurrentActionData = {} - end, { 'beard_1', 'beard_2', @@ -144,25 +127,20 @@ AddEventHandler('esx_barbershop:hasEnteredMarker', function(zone) end) AddEventHandler('esx_barbershop:hasExitedMarker', function(zone) - ESX.UI.Menu.CloseAll() CurrentAction = nil - if not HasPayed then - + if not HasPaid then TriggerEvent('esx_skin:getLastSkin', function(skin) TriggerEvent('skinchanger:loadSkin', skin) end) - end - end) -- Create Blips Citizen.CreateThread(function() - for i=1, #Config.Shops, 1 do - + local blip = AddBlipForCoord(Config.Shops[i].x, Config.Shops[i].y, Config.Shops[i].z) SetBlipSprite (blip, 71) @@ -174,39 +152,36 @@ Citizen.CreateThread(function() BeginTextCommandSetBlipName("STRING") AddTextComponentString(_U('barber_blip')) EndTextCommandSetBlipName(blip) - end + end end) -- Display markers Citizen.CreateThread(function() while true do - - Wait(0) - - local coords = GetEntityCoords(GetPlayerPed(-1)) - + Citizen.Wait(0) + + local coords = GetEntityCoords(PlayerPedId()) + for k,v in pairs(Config.Zones) do if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) end end - end end) -- Enter / Exit marker events Citizen.CreateThread(function() while true do + Citizen.Wait(0) - Wait(0) - - local coords = GetEntityCoords(GetPlayerPed(-1)) + local coords = GetEntityCoords(PlayerPedId()) local isInMarker = false local currentZone = nil for k,v in pairs(Config.Zones) do - if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then + if GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x then isInMarker = true currentZone = k end @@ -222,34 +197,26 @@ Citizen.CreateThread(function() HasAlreadyEnteredMarker = false TriggerEvent('esx_barbershop:hasExitedMarker', LastZone) end - end end) -- Key controls Citizen.CreateThread(function() while true do - Citizen.Wait(0) if CurrentAction ~= nil then + ESX.ShowHelpNotification(CurrentActionMsg) - SetTextComponentFormat('STRING') - AddTextComponentString(CurrentActionMsg) - DisplayHelpTextFromStringLabel(0, 0, 1, -1) - - if IsControlPressed(0, Keys['E']) and (GetGameTimer() - GUI.Time) > 300 then - + if IsControlJustReleased(0, Keys['E']) then if CurrentAction == 'shop_menu' then OpenShopMenu() end CurrentAction = nil - GUI.Time = GetGameTimer() - end - + else + Citizen.Wait(500) end - end end) \ No newline at end of file diff --git a/config.lua b/config.lua index e9f30d60..4ec366dc 100644 --- a/config.lua +++ b/config.lua @@ -6,27 +6,26 @@ Config.DrawDistance = 100.0 Config.MarkerSize = {x = 1.5, y = 1.5, z = 1.0} Config.MarkerColor = {r = 102, g = 102, b = 204} Config.MarkerType = 1 + Config.Locale = 'fr' Config.Zones = {} Config.Shops = { - {x = -814.308, y = -183.823, z = 36.568}, - {x = 136.826, y = -1708.373, z = 28.291}, - {x = -1282.604, y = -1116.757, z = 5.990}, - {x = 1931.513, y = 3729.671, z = 31.844}, - {x = 1212.840, y = -472.921, z = 65.208}, - {x = -32.885, y = -152.319, z = 56.076}, - {x = -278.077, y = 6228.463, z = 30.695}, + {x = -814.308, y = -183.823, z = 36.568}, + {x = 136.826, y = -1708.373, z = 28.291}, + {x = -1282.604, y = -1116.757, z = 5.990}, + {x = 1931.513, y = 3729.671, z = 31.844}, + {x = 1212.840, y = -472.921, z = 65.208}, + {x = -32.885, y = -152.319, z = 56.076}, + {x = -278.077, y = 6228.463, z = 30.695} } for i=1, #Config.Shops, 1 do - Config.Zones['Shop_' .. i] = { - Pos = Config.Shops[i], - Size = Config.MarkerSize, - Color = Config.MarkerColor, - Type = Config.MarkerType - } - + Pos = Config.Shops[i], + Size = Config.MarkerSize, + Color = Config.MarkerColor, + Type = Config.MarkerType + } end diff --git a/locales/br.lua b/locales/br.lua index 0cc4e13a..06aca5b7 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,10 +1,9 @@ Locales['br'] = { - - ['valid_purchase'] = 'validar esta compra?', - ['yes'] = 'sim', - ['no'] = 'não', - ['not_enough_money'] = 'você não tem dinheiro suficiente', - ['press_access'] = 'pressione ~INPUT_CONTEXT~ para acessar o menu', - ['barber_blip'] = 'Barbearia', - ['you_paid'] = 'você pagou ', -} \ No newline at end of file + ['valid_purchase'] = 'validar esta compra?', + ['yes'] = 'sim', + ['no'] = 'não', + ['not_enough_money'] = 'você não tem dinheiro suficiente', + ['press_access'] = 'pressione ~INPUT_CONTEXT~ para acessar o menu', + ['barber_blip'] = 'Barbearia', + ['you_paid'] = 'você pagou $%s', +} diff --git a/locales/de.lua b/locales/de.lua index e5c26ff2..6053408c 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -1,10 +1,9 @@ Locales['de'] = { - - ['valid_purchase'] = 'Einkauf bestätigen?', - ['yes'] = 'ja', - ['no'] = 'nein', - ['not_enough_money'] = 'du hast nicht genug Geld', - ['press_access'] = 'Drücke ~INPUT_CONTEXT~ um das Menü zu öffnen', - ['barber_blip'] = 'Friseur', - ['you_paid'] = 'du bezahlst ', + ['valid_purchase'] = 'Einkauf bestätigen?', + ['yes'] = 'ja', + ['no'] = 'nein', + ['not_enough_money'] = 'du hast nicht genug Geld', + ['press_access'] = 'Drücke ~INPUT_CONTEXT~ um das Menü zu öffnen', + ['barber_blip'] = 'Friseur', + ['you_paid'] = 'du bezahlst $%s', } \ No newline at end of file diff --git a/locales/en.lua b/locales/en.lua index 6534c364..0dc26ab0 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,10 +1,9 @@ Locales['en'] = { - - ['valid_purchase'] = 'validate this purchase?', - ['yes'] = 'yes', - ['no'] = 'no', - ['not_enough_money'] = 'you do not have enough money', - ['press_access'] = 'press ~INPUT_CONTEXT~ to access the menu', - ['barber_blip'] = 'barber shop', - ['you_paid'] = 'you paid ', -} \ No newline at end of file + ['valid_purchase'] = 'validate this purchase?', + ['yes'] = 'yes', + ['no'] = 'no', + ['not_enough_money'] = 'you do not have enough money', + ['press_access'] = 'press ~INPUT_CONTEXT~ to access the menu', + ['barber_blip'] = 'barber shop', + ['you_paid'] = 'you paid $%s', +} diff --git a/locales/es.lua b/locales/es.lua index 0abd39b3..befb6ef9 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -1,10 +1,9 @@ Locales['es'] = { - - ['valid_purchase'] = '¿validar esta compra?', - ['yes'] = 'Si', - ['no'] = 'No', - ['not_enough_money'] = 'No tienes suficente dinero', - ['press_access'] = 'Presiona ~INPUT_CONTEXT~ para acceder al menú', - ['barber_blip'] = 'Barbero', - ['you_paid'] = 'Has pagado ', + ['valid_purchase'] = '¿validar esta compra?', + ['yes'] = 'si', + ['no'] = 'no', + ['not_enough_money'] = 'no tienes suficente dinero', + ['press_access'] = 'presiona ~INPUT_CONTEXT~ para acceder al menú', + ['barber_blip'] = 'barbero', + ['you_paid'] = 'has pagado $%s', } diff --git a/locales/fi.lua b/locales/fi.lua index 953735ee..3486fce0 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -1,10 +1,9 @@ Locales['fi'] = { - - ['valid_purchase'] = 'varmista tämä ostos?', - ['yes'] = 'kyllä', - ['no'] = 'ei', - ['not_enough_money'] = 'sinulla ei ole tarpeeksi rahaa', - ['press_access'] = 'paina ~INPUT_CONTEXT~ avataksesi menu', - ['barber_blip'] = 'Kampaamo', - ['you_paid'] = 'sinä maksoit ', -} \ No newline at end of file + ['valid_purchase'] = 'varmista tämä ostos?', + ['yes'] = 'kyllä', + ['no'] = 'ei', + ['not_enough_money'] = 'sinulla ei ole tarpeeksi rahaa', + ['press_access'] = 'paina ~INPUT_CONTEXT~ avataksesi menu', + ['barber_blip'] = 'Kampaamo', + ['you_paid'] = 'sinä maksoit $%s', +} diff --git a/locales/fr.lua b/locales/fr.lua index ac1683a6..bfe267db 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,10 +1,9 @@ Locales['fr'] = { - - ['valid_purchase'] = 'valider cet achat ?', - ['yes'] = 'oui', - ['no'] = 'non', - ['not_enough_money'] = 'vous n\'avez pas assez d\'argent', - ['press_access'] = 'appuez sur ~INPUT_CONTEXT~ pour accéder au menu', - ['barber_blip'] = 'barbier', - ['you_paid'] = 'vous avez payé ', -} \ No newline at end of file + ['valid_purchase'] = 'valider cet achat ?', + ['yes'] = 'oui', + ['no'] = 'non', + ['not_enough_money'] = 'vous n\'avez pas assez d\'argent', + ['press_access'] = 'appuez sur ~INPUT_CONTEXT~ pour accéder au menu', + ['barber_blip'] = 'barbier', + ['you_paid'] = 'vous avez payé $%s', +} diff --git a/server/main.lua b/server/main.lua index 49d8b2b4..b6fbf525 100644 --- a/server/main.lua +++ b/server/main.lua @@ -4,25 +4,15 @@ TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) RegisterServerEvent('esx_barbershop:pay') AddEventHandler('esx_barbershop:pay', function() - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) + local xPlayer = ESX.GetPlayerFromId(_source) xPlayer.removeMoney(Config.Price) - - TriggerClientEvent('esx:showNotification', source, _U('you_paid') .. '$' .. Config.Price) - + TriggerClientEvent('esx:showNotification', source, _U('you_paid', ESX.Math.GroupDigits(Config.Price))) end) ESX.RegisterServerCallback('esx_barbershop:checkMoney', function(source, cb) + local xPlayer = ESX.GetPlayerFromId(source) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) - - if xPlayer.get('money') >= Config.Price then - cb(true) - else - cb(false) - end - + cb(xPlayer.get('money') >= Config.Price) end) From 1ce1645fc4e1bac05a5a9a8343d696682ef3f1be Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 10 Nov 2018 23:49:14 +0100 Subject: [PATCH 1906/3224] Properly revert skin if player doesn't buy, closes #17 --- client/main.lua | 4 ++-- server/main.lua | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/client/main.lua b/client/main.lua index ed56aa2f..cf17b6e9 100644 --- a/client/main.lua +++ b/client/main.lua @@ -84,7 +84,7 @@ function OpenShopMenu() end) else - TriggerEvent('esx_skin:getLastSkin', function(skin) + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin) TriggerEvent('skinchanger:loadSkin', skin) end) @@ -92,7 +92,7 @@ function OpenShopMenu() end end) elseif data.current.value == 'no' then - TriggerEvent('esx_skin:getLastSkin', function(skin) + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin) TriggerEvent('skinchanger:loadSkin', skin) end) end diff --git a/server/main.lua b/server/main.lua index 7b12bc14..e3e45da9 100644 --- a/server/main.lua +++ b/server/main.lua @@ -8,7 +8,6 @@ AddEventHandler('esx_clotheshop:saveOutfit', function(label, skin) local xPlayer = ESX.GetPlayerFromId(_source) TriggerEvent('esx_datastore:getDataStore', 'property', xPlayer.identifier, function(store) - local dressing = store.get('dressing') if dressing == nil then @@ -21,7 +20,6 @@ AddEventHandler('esx_clotheshop:saveOutfit', function(label, skin) }) store.set('dressing', dressing) - end) end) From 64e665bbae068f2261aa1d9c6bf46f531c50dea9 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 10 Nov 2018 23:52:00 +0100 Subject: [PATCH 1907/3224] Updated readme, final commit v1.1.0 --- README.md | 41 +++++++++++++++++++++++++++++++---------- __resource.lua | 7 +++++-- client/main.lua | 4 ++-- 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 886ee230..ea1dceab 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,40 @@ -# fxserver-esx_barbershop -FXServer ESX Barber Shop +# esx_barbershop -[REQUIREMENTS] +## Requirements +- [esx_skin](https://github.com/ESX-Org/esx_skin) -- esx_skin => https://github.com/FXServer-ESX/fxserver-esx_skin +## Download & Installation -[INSTALLATION] - -1) CD in your resources/[esx] folder -2) Clone the repository +### Using [fvm](https://github.com/qlaffont/fvm-installer) ``` -git clone https://github.com/FXServer-ESX/fxserver-esx_barbershop esx_barbershop +fvm install --save --folder=esx esx-org/esx_barbershop ``` -3) Add this in your server.cfg : + +### Using Git +``` +cd resources +git clone https://github.com/ESX-Org/esx_barbershop [esx]/esx_barbershop +``` + +### Manually +- Download https://github.com/ESX-Org/esx_barbershop/archive/master.zip +- Put it in the `[esx]` directory + +## Installation +- Add this in your `server.cfg`: ``` start esx_barbershop ``` + +# Legal +### License +esx_barbershop - barber shop! + +Copyright (C) 2015-2018 Jérémie N'gadi + +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 http://www.gnu.org/licenses/. \ No newline at end of file diff --git a/__resource.lua b/__resource.lua index a31bfb4d..243ffac2 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,7 +2,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ESX Barber Shop' -version '1.0.1' +version '1.1.0' server_scripts { '@mysql-async/lib/MySQL.lua', @@ -29,4 +29,7 @@ client_scripts { 'client/main.lua' } -dependency 'es_extended' \ No newline at end of file +dependencies { + 'es_extended', + 'esx_skin' +} diff --git a/client/main.lua b/client/main.lua index ccc1c905..39afd32c 100644 --- a/client/main.lua +++ b/client/main.lua @@ -174,8 +174,8 @@ end) -- Enter / Exit marker events Citizen.CreateThread(function() while true do - Citizen.Wait(0) - + Citizen.Wait(200) + local coords = GetEntityCoords(PlayerPedId()) local isInMarker = false local currentZone = nil From 29d13d81c9b972b5daf5b614952b2b6101b87fe0 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 10 Nov 2018 23:52:35 +0100 Subject: [PATCH 1908/3224] Very final commit v1.1.0 --- __resource.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/__resource.lua b/__resource.lua index 243ffac2..3637c8ee 100644 --- a/__resource.lua +++ b/__resource.lua @@ -5,7 +5,6 @@ description 'ESX Barber Shop' version '1.1.0' server_scripts { - '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', 'locales/br.lua', 'locales/de.lua', From 0fff512922693921d6c2d8db5af226123f1f329c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 10 Nov 2018 23:54:42 +0100 Subject: [PATCH 1909/3224] Ok very very final commit --- client/main.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index 39afd32c..7be8e70a 100644 --- a/client/main.lua +++ b/client/main.lua @@ -131,8 +131,8 @@ AddEventHandler('esx_barbershop:hasExitedMarker', function(zone) CurrentAction = nil if not HasPaid then - TriggerEvent('esx_skin:getLastSkin', function(skin) - TriggerEvent('skinchanger:loadSkin', skin) + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin) + TriggerEvent('skinchanger:loadSkin', skin) end) end end) From 093d5535a6708b0b428ac09fa713d18fbf32981d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 11 Nov 2018 11:22:41 +0100 Subject: [PATCH 1910/3224] Check if player already has weapon --- locales/br.lua | 3 ++- locales/de.lua | 3 ++- locales/en.lua | 3 ++- locales/es.lua | 3 ++- locales/fi.lua | 3 ++- locales/fr.lua | 3 ++- locales/pl.lua | 3 ++- locales/sv.lua | 13 +++++++++++++ server/main.lua | 9 +++++++-- 9 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 locales/sv.lua diff --git a/locales/br.lua b/locales/br.lua index d4e9add3..2e80ea9c 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -2,9 +2,10 @@ Locales ['br'] = { ['buy_license'] = 'buy weapon license?', ['yes'] = '%s', ['no'] = 'no', - ['buy'] = 'você comprou %s', + ['buy'] = 'você comprou ~y~%s~s~ for ~r~R$%s~s~', ['not_enough_black'] = 'você não tem dinheiro sujo suficiente', ['not_enough'] = 'você não tem dinheiro suficiente', + ['already_owned'] = 'you already own this weapon!', ['shop'] = 'comprar', ['shop_menu'] = 'pressione ~INPUT_CONTEXT~ para comprar armas.', ['shop_menu_item'] = 'R$%s', diff --git a/locales/de.lua b/locales/de.lua index 070f3a7e..1022cac5 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -2,9 +2,10 @@ Locales ['de'] = { ['buy_license'] = 'buy weapon license?', ['yes'] = '%s', ['no'] = 'no', - ['buy'] = 'du kaufst %s', + ['buy'] = 'du kaufst ~y~%s~s~ for ~r~%s EUR~s~', ['not_enough_black'] = 'du hast nicht genug Schwarzgeld', ['not_enough'] = 'du hast nicht genug Geld', + ['already_owned'] = 'you already own this weapon!', ['shop'] = 'geschäft', ['shop_menu'] = 'drücke ~INPUT_CONTEXT~ um auf das Geschäft zuzugreifen.', ['shop_menu_item'] = '%s EUR', diff --git a/locales/en.lua b/locales/en.lua index cd95640e..06bc7062 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -2,9 +2,10 @@ Locales ['en'] = { ['buy_license'] = 'buy weapon license?', ['yes'] = '%s', ['no'] = 'no', - ['buy'] = 'you bought %s', + ['buy'] = 'you bought ~y~%s~s~ for ~r~$%s~s~', ['not_enough_black'] = 'you do not have enough dirty money', ['not_enough'] = 'you do not have enough money', + ['already_owned'] = 'you already own this weapon!', ['shop'] = 'weapon shop', ['shop_menu'] = 'press ~INPUT_CONTEXT~ to access the ~y~weapon store~s~.', ['shop_menu_item'] = '$%s', diff --git a/locales/es.lua b/locales/es.lua index 47d20ab2..95b5e98b 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -2,9 +2,10 @@ Locales ['es'] = { ['buy_license'] = 'buy weapon license?', ['yes'] = '%s', ['no'] = 'no', - ['buy'] = 'has comprado %s', + ['buy'] = 'has comprado ~y~%s~s~ for ~r~%s EUR~s~', ['not_enough_black'] = 'usted no tiene ~r~suficiente~s~ dinero negro', ['not_enough'] = 'usted no tiene ~r~suficiente~s~ dinero', + ['already_owned'] = 'you already own this weapon!', ['shop'] = 'tienda', ['shop_menu'] = 'presione ~INPUT_CONTEXT~ para acceder a la tienda.', ['shop_menu_item'] = '%s EUR', diff --git a/locales/fi.lua b/locales/fi.lua index fa1a60f2..d549fe68 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -2,9 +2,10 @@ Locales ['fi'] = { ['buy_license'] = 'osta lisenssi?', ['yes'] = '%s', ['no'] = 'ei', - ['buy'] = 'sinä ostit %s', + ['buy'] = 'sinä ostit ~y~%s~s~ for ~r~%s EUR~s~', ['not_enough_black'] = 'ei tarpeeksi likaista rahaa', ['not_enough'] = 'sinulla ei ole tarpeeksi rahaa', + ['already_owned'] = 'you already own this weapon!', ['shop'] = 'kauppa', ['shop_menu'] = 'paina ~INPUT_CONTEXT~ avataksesi kauppa ikkuna.', ['shop_menu_item'] = '%s EUR', diff --git a/locales/fr.lua b/locales/fr.lua index fbdbff49..b674c5f7 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -2,9 +2,10 @@ Locales ['fr'] = { ['buy_license'] = 'acheter une license?', ['yes'] = '%s', ['no'] = 'non', - ['buy'] = 'vous avez acheté %s', + ['buy'] = 'vous avez acheté ~y~%s~s~ for ~r~%s EUR~s~', ['not_enough_black'] = 'Vous n\'avez ~r~pas assez~s~ d\'argent sale', ['not_enough'] = 'vous n\'avez ~r~pas assez~s~ d\'argent', + ['already_owned'] = 'you already own this weapon!', ['shop'] = 'magasin', ['shop_menu'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder au magasin.', ['shop_menu_item'] = '%s EUR', diff --git a/locales/pl.lua b/locales/pl.lua index d52dc9aa..e64bb7fb 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -2,9 +2,10 @@ Locales ['pl'] = { ['buy_license'] = 'czy chcesz kupić licencję?', ['yes'] = '%s', ['no'] = 'nie', - ['buy'] = 'kupiłeś/aś %s', + ['buy'] = 'kupiłeś/aś ~y~%s~s~ for ~r~%s PLN~s~', ['not_enough_black'] = 'nie masz wystarczająco brudnej kasy', ['not_enough'] = 'nie masz wystarczająco pieniędzy', + ['already_owned'] = 'you already own this weapon!', ['shop'] = 'sklep', ['shop_menu'] = 'Wciśnij ~INPUT_CONTEXT~ aby otworzyć sklep.', ['shop_menu_item'] = '%s PLN', diff --git a/locales/sv.lua b/locales/sv.lua new file mode 100644 index 00000000..05a4df01 --- /dev/null +++ b/locales/sv.lua @@ -0,0 +1,13 @@ +Locales ['sv'] = { + ['buy_license'] = 'vill du köpa ett vapenlicens?', + ['yes'] = '%s', + ['no'] = 'nej tack', + ['buy'] = 'du köpte ~y~%s~s~ för ~r~%s SEK~s~', + ['not_enough_black'] = 'du har inte tillräckligt med svarta pengar', + ['not_enough'] = 'du har inte råd för detta', + ['already_owned'] = 'du äger redan detta vapen!', + ['shop'] = 'vapenaffär', + ['shop_menu'] = 'tryck ~INPUT_CONTEXT~ för att komma åt ~y~vapenaffären~s~.', + ['shop_menu_item'] = '%s SEK', + ['map_blip'] = 'vapenaffär', +} diff --git a/server/main.lua b/server/main.lua index aa2978e1..54297cab 100644 --- a/server/main.lua +++ b/server/main.lua @@ -58,12 +58,17 @@ AddEventHandler('esx_weashop:buyItem', function(weaponName, zone) local xPlayer = ESX.GetPlayerFromId(_source) local price = GetPrice(weaponName, zone) + if xPlayer.hasWeapon(weaponName) then + TriggerClientEvent('esx:showNotification', _source, _U('already_owned')) + return + end + if zone == "BlackWeashop" then if xPlayer.getAccount('black_money').money >= price then xPlayer.removeAccountMoney('black_money', price) xPlayer.addWeapon(weaponName, 42) - TriggerClientEvent('esx:showNotification', _source, _U('buy', ESX.GetWeaponLabel(weaponName))) + TriggerClientEvent('esx:showNotification', _source, _U('buy', ESX.GetWeaponLabel(weaponName), price)) else TriggerClientEvent('esx:showNotification', _source, _U('not_enough_black')) end @@ -73,7 +78,7 @@ AddEventHandler('esx_weashop:buyItem', function(weaponName, zone) if xPlayer.getMoney() >= price then xPlayer.removeMoney(price) xPlayer.addWeapon(weaponName, 42) - TriggerClientEvent('esx:showNotification', _source, _U('buy', ESX.GetWeaponLabel(weaponName))) + TriggerClientEvent('esx:showNotification', _source, _U('buy', ESX.GetWeaponLabel(weaponName), price)) else TriggerClientEvent('esx:showNotification', _source, _U('not_enough')) end From ed3c2f54c7adf124c995b7c915fc2c26fc245e98 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 11 Nov 2018 11:24:36 +0100 Subject: [PATCH 1911/3224] Fixed #35 --- client/main.lua | 4 ++-- server/main.lua | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/main.lua b/client/main.lua index b9ceb88c..ee6f3740 100644 --- a/client/main.lua +++ b/client/main.lua @@ -44,8 +44,8 @@ function OpenBuyLicenseMenu(zone) ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'shop_license', { title = _U('buy_license'), elements = { - { label = _U('yes', ('%s'):format((_U('shop_menu_item', ESX.Math.GroupDigits(Config.LicensePrice)))), value = 'yes' }, - { label = _U('no'), value = 'no' } + { label = _U('no'), value = 'no' }, + { label = _U('yes', ('%s'):format((_U('shop_menu_item', ESX.Math.GroupDigits(Config.LicensePrice))))), value = 'yes' }, } }, function(data, menu) if data.current.value == 'yes' then diff --git a/server/main.lua b/server/main.lua index 54297cab..239d48b5 100644 --- a/server/main.lua +++ b/server/main.lua @@ -87,10 +87,10 @@ AddEventHandler('esx_weashop:buyItem', function(weaponName, zone) end) function GetPrice(weaponName, zone) - local result = MySQL.Sync.fetchAll('SELECT 1 FROM weashops WHERE zone = @zone AND item = @item', { + local result = MySQL.Sync.fetchAll('SELECT price FROM weashops WHERE zone = @zone AND item = @item', { ['@zone'] = zone, ['@item'] = weaponName }) - + return result[1].price end From 464d4bde073a3c253310c638351c4d00925e0493 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 11 Nov 2018 11:26:14 +0100 Subject: [PATCH 1912/3224] Updated missing resource manifest --- README.md | 2 +- __resource.lua | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e3b90b2a..65e213d5 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ start esx_weashops # Legal ### License -esx_weashops - Legal and illegal weapon shop +esx_weashops - Legal and illegal weapon shops Copyright (C) 2015-2018 Jérémie N'gadi diff --git a/__resource.lua b/__resource.lua index 1b141e5c..2dd1d1a6 100644 --- a/__resource.lua +++ b/__resource.lua @@ -14,6 +14,7 @@ server_scripts { 'locales/fr.lua', 'locales/es.lua', 'locales/pl.lua', + 'locales/sv.lua', 'config.lua', 'server/main.lua' } @@ -27,6 +28,7 @@ client_scripts { 'locales/fr.lua', 'locales/es.lua', 'locales/pl.lua', + 'locales/sv.lua', 'config.lua', 'client/main.lua' } From 0ca59d676638377d3a57f6f3e09f1dd477694658 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 11 Nov 2018 11:51:32 +0100 Subject: [PATCH 1913/3224] Perfrormance improvements, removed marker code --- client/main.lua | 63 +++++++++---------- config.lua | 148 ++++++++++++++++++++++---------------------- html/css/app.css | 134 +++++++++++++++++++-------------------- html/scripts/app.js | 11 +++- server/main.lua | 13 ++-- 5 files changed, 183 insertions(+), 186 deletions(-) diff --git a/client/main.lua b/client/main.lua index 409bf218..5d519238 100644 --- a/client/main.lua +++ b/client/main.lua @@ -51,8 +51,8 @@ end) Citizen.CreateThread(function() if not Config.EnableBlips then return end - for i=1, #Config.ATMS, 1 do - local blip = AddBlipForCoord(Config.ATMS[i].x, Config.ATMS[i].y, Config.ATMS[i].z - Config.ZDiff) + for i=1, #Config.ATMLocations, 1 do + local blip = AddBlipForCoord(Config.ATMLocations[i].x, Config.ATMLocations[i].y, Config.ATMLocations[i].z - Config.ZDiff) SetBlipSprite (blip, Config.BlipSprite) SetBlipDisplay(blip, 4) SetBlipScale (blip, 0.9) @@ -64,72 +64,69 @@ Citizen.CreateThread(function() end end) --- Render markers -Citizen.CreateThread(function() - while true do - Citizen.Wait(1) - local coords = GetEntityCoords(PlayerPedId()) - for i=1, #Config.ATMS, 1 do - if(GetDistanceBetweenCoords(coords, Config.ATMS[i].x, Config.ATMS[i].y, Config.ATMS[i].z, true) < Config.DrawDistance) then - DrawMarker(Config.MarkerType, Config.ATMS[i].x, Config.ATMS[i].y, Config.ATMS[i].z - Config.ZDiff, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.ZoneSize.x, Config.ZoneSize.y, Config.ZoneSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) - end - end - end -end) - -- Activate menu when player is inside marker Citizen.CreateThread(function() while true do Citizen.Wait(10) local coords = GetEntityCoords(PlayerPedId()) + local canSleep = true isInATMMarker = false - for i=1, #Config.ATMS, 1 do - if(GetDistanceBetweenCoords(coords, Config.ATMS[i].x, Config.ATMS[i].y, Config.ATMS[i].z, true) < Config.ZoneSize.x / 2) then + for k,v in pairs(Config.ATMLocations) do + if(GetDistanceBetweenCoords(coords, v.x, v.y, v.z, true) < Config.ZoneSize.x / 2) then isInATMMarker = true ESX.ShowHelpNotification(_U('press_e_atm')) + canSleep = false end end if isInATMMarker and not hasAlreadyEnteredMarker then hasAlreadyEnteredMarker = true + canSleep = false end if not isInATMMarker and hasAlreadyEnteredMarker then hasAlreadyEnteredMarker = false SetNuiFocus(false) menuIsShowed = false + canSleep = false + SendNUIMessage({ hideAll = true }) end + + if canSleep then + Citizen.Wait(500) + end end end) -- Menu interactions Citizen.CreateThread(function() while true do - Citizen.Wait(1) + Citizen.Wait(10) + if menuIsShowed then DisableControlAction(0, 1, true) -- LookLeftRight DisableControlAction(0, 2, true) -- LookUpDown DisableControlAction(0, 142, true) -- MeleeAttackAlternate DisableControlAction(0, 106, true) -- VehicleMouseControlOverride - else - if IsControlJustReleased(0, Keys['E']) and isInATMMarker and IsPedOnFoot(PlayerPedId()) then - menuIsShowed = true - ESX.TriggerServerCallback('esx:getPlayerData', function(data) - SendNUIMessage({ - showMenu = true, - player = { - money = data.money, - accounts = data.accounts - } - }) - end) - -- Open UI and display Native Cursor - SetNuiFocus(true, true) - end + elseif IsControlJustReleased(0, Keys['E']) and isInATMMarker and IsPedOnFoot(PlayerPedId()) then + menuIsShowed = true + ESX.TriggerServerCallback('esx:getPlayerData', function(data) + SendNUIMessage({ + showMenu = true, + player = { + money = data.money, + accounts = data.accounts + } + }) + end) + + SetNuiFocus(true, true) + elseif (not isInATMMarker and not menuIsShowed) then + Citizen.Wait(500) end end end) diff --git a/config.lua b/config.lua index 17d90e9e..23d784f4 100644 --- a/config.lua +++ b/config.lua @@ -1,83 +1,81 @@ Config = {} -Config.MarkerType = 1 -Config.DrawDistance = 100.0 Config.ZoneSize = {x = 3.0, y = 3.0, z = 0.3} -Config.MarkerColor = {r = 100, g = 100, b = 204} Config.ZDiff = 2.0 Config.BlipSprite = 431 Config.Locale = 'fr' Config.EnableBlips = false -- for some reason ATM blips are extremly buggy and will bug out the map -Config.ATMS = { - { ['x'] = -386.733, ['y'] = 6045.953, ['z'] = 31.501}, - { ['x'] = -110.753, ['y'] = 6467.703, ['z'] = 31.784}, - { ['x'] = 155.4300, ['y'] = 6641.991, ['z'] = 31.784}, - { ['x'] = 174.6720, ['y'] = 6637.218, ['z'] = 31.784}, - { ['x'] = 1703.138, ['y'] = 6426.783, ['z'] = 32.730}, - { ['x'] = 1735.114, ['y'] = 6411.035, ['z'] = 35.164}, - { ['x'] = 1702.842, ['y'] = 4933.593, ['z'] = 42.051}, - { ['x'] = 1967.333, ['y'] = 3744.293, ['z'] = 32.272}, - { ['x'] = 1174.532, ['y'] = 2705.278, ['z'] = 38.027}, - { ['x'] = 2564.399, ['y'] = 2585.100, ['z'] = 38.016}, - { ['x'] = 2558.683, ['y'] = 349.6010, ['z'] = 108.050}, - { ['x'] = 2558.051, ['y'] = 389.4817, ['z'] = 108.660}, - { ['x'] = 1077.692, ['y'] = -775.796, ['z'] = 58.218}, - { ['x'] = 1139.018, ['y'] = -469.886, ['z'] = 66.789}, - { ['x'] = 1168.975, ['y'] = -457.241, ['z'] = 66.641}, - { ['x'] = 1153.884, ['y'] = -326.540, ['z'] = 69.245}, - { ['x'] = 236.4638, ['y'] = 217.4718, ['z'] = 106.840}, - { ['x'] = 265.0043, ['y'] = 212.1717, ['z'] = 106.780}, - { ['x'] = -164.568, ['y'] = 233.5066, ['z'] = 94.919}, - { ['x'] = -1827.04, ['y'] = 785.5159, ['z'] = 138.020}, - { ['x'] = -1409.39, ['y'] = -99.2603, ['z'] = 52.473}, - { ['x'] = -1215.64, ['y'] = -332.231, ['z'] = 37.881}, - { ['x'] = -2072.41, ['y'] = -316.959, ['z'] = 13.345}, - { ['x'] = -2975.72, ['y'] = 379.7737, ['z'] = 14.992}, - { ['x'] = -2962.60, ['y'] = 482.1914, ['z'] = 15.762}, - { ['x'] = -3144.13, ['y'] = 1127.415, ['z'] = 20.868}, - { ['x'] = -1305.40, ['y'] = -706.240, ['z'] = 25.352}, - { ['x'] = -717.614, ['y'] = -915.880, ['z'] = 19.268}, - { ['x'] = -526.566, ['y'] = -1222.90, ['z'] = 18.434}, - { ['x'] = 149.4551, ['y'] = -1038.95, ['z'] = 29.366}, - { ['x'] = -846.304, ['y'] = -340.402, ['z'] = 38.687}, - { ['x'] = -1216.27, ['y'] = -331.461, ['z'] = 37.773}, - { ['x'] = -56.1935, ['y'] = -1752.53, ['z'] = 29.452}, - { ['x'] = -273.001, ['y'] = -2025.60, ['z'] = 30.197}, - { ['x'] = 314.187, ['y'] = -278.621, ['z'] = 54.170}, - { ['x'] = -351.534, ['y'] = -49.529, ['z'] = 49.042}, - { ['x'] = -1570.197, ['y'] = -546.651, ['z'] = 34.955}, - { ['x'] = 33.232, ['y'] = -1347.849, ['z'] = 29.497}, - { ['x'] = 129.216, ['y'] = -1292.347, ['z'] = 29.269}, - { ['x'] = 289.012, ['y'] = -1256.545, ['z'] = 29.440}, - { ['x'] = 1686.753, ['y'] = 4815.809, ['z'] = 42.008}, - { ['x'] = -302.408, ['y'] = -829.945, ['z'] = 32.417}, - { ['x'] = 5.134, ['y'] = -919.949, ['z'] = 29.557}, - { ['x'] = -284.037, ['y'] = 6224.385, ['z'] = 31.187}, - { ['x'] = -135.165, ['y'] = 6365.738, ['z'] = 31.101}, - { ['x'] = -94.9690, ['y'] = 6455.301, ['z'] = 31.784}, - { ['x'] = 1821.917, ['y'] = 3683.483, ['z'] = 34.244}, - { ['x'] = 540.0420, ['y'] = 2671.007, ['z'] = 42.177}, - { ['x'] = 381.2827, ['y'] = 323.2518, ['z'] = 103.270}, - { ['x'] = 285.2029, ['y'] = 143.5690, ['z'] = 104.970}, - { ['x'] = 157.7698, ['y'] = 233.5450, ['z'] = 106.450}, - { ['x'] = -1205.35, ['y'] = -325.579, ['z'] = 37.870}, - { ['x'] = -2955.70, ['y'] = 488.7218, ['z'] = 15.486}, - { ['x'] = -3044.22, ['y'] = 595.2429, ['z'] = 7.595}, - { ['x'] = -3241.10, ['y'] = 996.6881, ['z'] = 12.500}, - { ['x'] = -3241.11, ['y'] = 1009.152, ['z'] = 12.877}, - { ['x'] = -538.225, ['y'] = -854.423, ['z'] = 29.234}, - { ['x'] = -711.156, ['y'] = -818.958, ['z'] = 23.768}, - { ['x'] = -256.831, ['y'] = -719.646, ['z'] = 33.444}, - { ['x'] = -203.548, ['y'] = -861.588, ['z'] = 30.205}, - { ['x'] = 112.4102, ['y'] = -776.162, ['z'] = 31.427}, - { ['x'] = 112.9290, ['y'] = -818.710, ['z'] = 31.386}, - { ['x'] = 119.9000, ['y'] = -883.826, ['z'] = 31.191}, - { ['x'] = -261.692, ['y'] = -2012.64, ['z'] = 30.121}, - { ['x'] = -254.112, ['y'] = -692.483, ['z'] = 33.616}, - { ['x'] = -1415.909, ['y'] = -211.825, ['z'] = 46.500}, - { ['x'] = -1430.122, ['y'] = -211.014, ['z'] = 46.500}, - { ['x'] = 287.645, ['y'] = -1282.646, ['z'] = 29.659}, - { ['x'] = 295.839, ['y'] = -895.640, ['z'] = 29.217}, - { ['x'] = -1315.73, ['y'] = -834.89, ['z'] = 16.96}, - { ['x'] = 89.75, ['y'] = 2.35, ['z'] = 68.31} + +Config.ATMLocations = { + { ['x'] = -386.733, ['y'] = 6045.953, ['z'] = 31.501}, + { ['x'] = -110.753, ['y'] = 6467.703, ['z'] = 31.784}, + { ['x'] = 155.4300, ['y'] = 6641.991, ['z'] = 31.784}, + { ['x'] = 174.6720, ['y'] = 6637.218, ['z'] = 31.784}, + { ['x'] = 1703.138, ['y'] = 6426.783, ['z'] = 32.730}, + { ['x'] = 1735.114, ['y'] = 6411.035, ['z'] = 35.164}, + { ['x'] = 1702.842, ['y'] = 4933.593, ['z'] = 42.051}, + { ['x'] = 1967.333, ['y'] = 3744.293, ['z'] = 32.272}, + { ['x'] = 1174.532, ['y'] = 2705.278, ['z'] = 38.027}, + { ['x'] = 2564.399, ['y'] = 2585.100, ['z'] = 38.016}, + { ['x'] = 2558.683, ['y'] = 349.6010, ['z'] = 108.050}, + { ['x'] = 2558.051, ['y'] = 389.4817, ['z'] = 108.660}, + { ['x'] = 1077.692, ['y'] = -775.796, ['z'] = 58.218}, + { ['x'] = 1139.018, ['y'] = -469.886, ['z'] = 66.789}, + { ['x'] = 1168.975, ['y'] = -457.241, ['z'] = 66.641}, + { ['x'] = 1153.884, ['y'] = -326.540, ['z'] = 69.245}, + { ['x'] = 236.4638, ['y'] = 217.4718, ['z'] = 106.840}, + { ['x'] = 265.0043, ['y'] = 212.1717, ['z'] = 106.780}, + { ['x'] = -164.568, ['y'] = 233.5066, ['z'] = 94.919}, + { ['x'] = -1827.04, ['y'] = 785.5159, ['z'] = 138.020}, + { ['x'] = -1409.39, ['y'] = -99.2603, ['z'] = 52.473}, + { ['x'] = -1215.64, ['y'] = -332.231, ['z'] = 37.881}, + { ['x'] = -2072.41, ['y'] = -316.959, ['z'] = 13.345}, + { ['x'] = -2975.72, ['y'] = 379.7737, ['z'] = 14.992}, + { ['x'] = -2962.60, ['y'] = 482.1914, ['z'] = 15.762}, + { ['x'] = -3144.13, ['y'] = 1127.415, ['z'] = 20.868}, + { ['x'] = -1305.40, ['y'] = -706.240, ['z'] = 25.352}, + { ['x'] = -717.614, ['y'] = -915.880, ['z'] = 19.268}, + { ['x'] = -526.566, ['y'] = -1222.90, ['z'] = 18.434}, + { ['x'] = 149.4551, ['y'] = -1038.95, ['z'] = 29.366}, + { ['x'] = -846.304, ['y'] = -340.402, ['z'] = 38.687}, + { ['x'] = -1216.27, ['y'] = -331.461, ['z'] = 37.773}, + { ['x'] = -56.1935, ['y'] = -1752.53, ['z'] = 29.452}, + { ['x'] = -273.001, ['y'] = -2025.60, ['z'] = 30.197}, + { ['x'] = 314.187, ['y'] = -278.621, ['z'] = 54.170}, + { ['x'] = -351.534, ['y'] = -49.529, ['z'] = 49.042}, + { ['x'] = -1570.197, ['y'] = -546.651, ['z'] = 34.955}, + { ['x'] = 33.232, ['y'] = -1347.849, ['z'] = 29.497}, + { ['x'] = 129.216, ['y'] = -1292.347, ['z'] = 29.269}, + { ['x'] = 289.012, ['y'] = -1256.545, ['z'] = 29.440}, + { ['x'] = 1686.753, ['y'] = 4815.809, ['z'] = 42.008}, + { ['x'] = -302.408, ['y'] = -829.945, ['z'] = 32.417}, + { ['x'] = 5.134, ['y'] = -919.949, ['z'] = 29.557}, + { ['x'] = -284.037, ['y'] = 6224.385, ['z'] = 31.187}, + { ['x'] = -135.165, ['y'] = 6365.738, ['z'] = 31.101}, + { ['x'] = -94.9690, ['y'] = 6455.301, ['z'] = 31.784}, + { ['x'] = 1821.917, ['y'] = 3683.483, ['z'] = 34.244}, + { ['x'] = 540.0420, ['y'] = 2671.007, ['z'] = 42.177}, + { ['x'] = 381.2827, ['y'] = 323.2518, ['z'] = 103.270}, + { ['x'] = 285.2029, ['y'] = 143.5690, ['z'] = 104.970}, + { ['x'] = 157.7698, ['y'] = 233.5450, ['z'] = 106.450}, + { ['x'] = -1205.35, ['y'] = -325.579, ['z'] = 37.870}, + { ['x'] = -2955.70, ['y'] = 488.7218, ['z'] = 15.486}, + { ['x'] = -3044.22, ['y'] = 595.2429, ['z'] = 7.595}, + { ['x'] = -3241.10, ['y'] = 996.6881, ['z'] = 12.500}, + { ['x'] = -3241.11, ['y'] = 1009.152, ['z'] = 12.877}, + { ['x'] = -538.225, ['y'] = -854.423, ['z'] = 29.234}, + { ['x'] = -711.156, ['y'] = -818.958, ['z'] = 23.768}, + { ['x'] = -256.831, ['y'] = -719.646, ['z'] = 33.444}, + { ['x'] = -203.548, ['y'] = -861.588, ['z'] = 30.205}, + { ['x'] = 112.4102, ['y'] = -776.162, ['z'] = 31.427}, + { ['x'] = 112.9290, ['y'] = -818.710, ['z'] = 31.386}, + { ['x'] = 119.9000, ['y'] = -883.826, ['z'] = 31.191}, + { ['x'] = -261.692, ['y'] = -2012.64, ['z'] = 30.121}, + { ['x'] = -254.112, ['y'] = -692.483, ['z'] = 33.616}, + { ['x'] = -1415.909, ['y'] = -211.825, ['z'] = 46.500}, + { ['x'] = -1430.122, ['y'] = -211.014, ['z'] = 46.500}, + { ['x'] = 287.645, ['y'] = -1282.646, ['z'] = 29.659}, + { ['x'] = 295.839, ['y'] = -895.640, ['z'] = 29.217}, + { ['x'] = -1315.73, ['y'] = -834.89, ['z'] = 16.96}, + { ['x'] = 89.75, ['y'] = 2.35, ['z'] = 68.31} } diff --git a/html/css/app.css b/html/css/app.css index f075f982..75a2123f 100644 --- a/html/css/app.css +++ b/html/css/app.css @@ -1,117 +1,117 @@ @font-face { - font-family: roboto; - src: url('../roboto.ttf'); + font-family: roboto; + src: url('../roboto.ttf'); } body { - width: 100%; - height: 100%; - overflow: hidden; - font-family: roboto; + width: 100%; + height: 100%; + overflow: hidden; + font-family: roboto; } #cursor { - position: absolute; - z-index: 999999; - display: none; + position: absolute; + z-index: 999999; + display: none; } -#container{ - position: absolute; - background: linear-gradient(#0c3b97,#3458ae); - height: 500px; - width: 600px; - top: 50%; - left: 50%; - margin: -250px 0 0 -300px; - cursor: default; +#container { + position: absolute; + background: linear-gradient(#0c3b97, #3458ae); + height: 500px; + width: 600px; + top: 50%; + left: 50%; + margin: -250px 0 0 -300px; + cursor: default; } -#header{ - position: absolute; - display: block; - width: 100%; - height: 75px; - background: linear-gradient(#f5f5f5, #adadad); +#header { + position: absolute; + display: block; + width: 100%; + height: 75px; + background: linear-gradient(#f5f5f5, #adadad); } #logo { - height: 55px; - margin: 10px; + height: 55px; + margin: 10px; } #welcome-text { - font-size: 25px; - position: absolute; - top: 100px; - left: 50%; - width: 450px; - margin: 0 0 0 -225px; - color: white; + font-size: 25px; + position: absolute; + top: 100px; + left: 50%; + width: 450px; + margin: 0 0 0 -225px; + color: white; } #menu { - position: relative; - top: 90%; + position: relative; + top: 90%; } #menu { - display: flex; - flex-direction: column; - height: 150px; - margin: -150px auto 0; - width: 500px; + display: flex; + flex-direction: column; + height: 150px; + margin: -150px auto 0; + width: 500px; } #menu div { - display: flex; - flex-direction: row; + display: flex; + flex-direction: row; } input { - margin: 0 20px 0 0; - background: linear-gradient(#00408e, #02306b); - border-radius: 5px; - border: 1px solid #4f89d4; - color: white; + margin: 0 20px 0 0; + background: linear-gradient(#00408e, #02306b); + border-radius: 5px; + border: 1px solid #4f89d4; + color: white; } -input::-webkit-outer-spin-button, -input::-webkit-inner-spin-button { - /* display: none; <- Crashes Chrome on hover */ - -webkit-appearance: none; - margin: 0; /* <-- Apparently some margin are still there even though it's hidden */ +input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { + /* display: none; <- Crashes Chrome on hover */ + -webkit-appearance: none; + margin: 0; + /* <-- Apparently some margin are still there even though it's hidden */ } button { - background: #ffffff; - border-radius: 5px; + background: #ffffff; + border-radius: 5px; } button:hover { - cursor: pointer; + cursor: pointer; } #deposit_btn { - width: 250px; - height: 50px; - font-size: 2em; + width: 250px; + height: 50px; + font-size: 2em; } #deposit_amount { - width: 250px; - height: 50px; - font-size: 2em; + width: 250px; + height: 50px; + font-size: 2em; } #withdraw_btn { - width : 250px; - height: 50px; - font-size: 2em; + width: 250px; + height: 50px; + font-size: 2em; } #withdraw_amount { - width : 250px; - height : 50px; - font-size: 2em; + width: 250px; + height: 50px; + font-size: 2em; } \ No newline at end of file diff --git a/html/scripts/app.js b/html/scripts/app.js index 3a643a28..b36703da 100644 --- a/html/scripts/app.js +++ b/html/scripts/app.js @@ -1,5 +1,4 @@ $(window).ready(function () { - // NUI Callback window.addEventListener('message', function (event) { let data = event.data; @@ -7,12 +6,14 @@ $(window).ready(function () { $('#container').fadeIn(); $('#menu').fadeIn(); $('#deposit_amount').val(data.player.money); + let bankAmount = 0; for (let i = 0; i < data.player.accounts.length; i++) { if (data.player.accounts[i].name == 'bank') { bankAmount = data.player.accounts[i].money; } } + $('#withdraw_amount').val(bankAmount); } else if (data.hideAll) { $('#container').fadeOut(); @@ -31,14 +32,16 @@ $(window).ready(function () { $.post('http://esx_atm/deposit', JSON.stringify({ amount: $('#deposit_amount').val() })); + $('#deposit_amount').val(0); }) - $('#deposit_amount').on("keyup", function(e) { + $('#deposit_amount').on("keyup", function (e) { if (e.keyCode == 13) { $.post('http://esx_atm/deposit', JSON.stringify({ amount: $('#deposit_amount').val() })); + $('#deposit_amount').val(0); } }); @@ -47,14 +50,16 @@ $(window).ready(function () { $.post('http://esx_atm/withdraw', JSON.stringify({ amount: $('#withdraw_amount').val() })); + $('#withdraw_amount').val(0); }); - $('#withdraw_amount').on("keyup", function(e) { + $('#withdraw_amount').on("keyup", function (e) { if (e.keyCode == 13) { $.post('http://esx_atm/withdraw', JSON.stringify({ amount: $('#withdraw_amount').val() })); + $('#withdraw_amount').val(0); } }); diff --git a/server/main.lua b/server/main.lua index 704bb176..1fa90643 100644 --- a/server/main.lua +++ b/server/main.lua @@ -8,7 +8,8 @@ AddEventHandler('esx_atm:deposit', function(amount) amount = tonumber(amount) if not tonumber(amount) then return end - amount = round(amount) + amount = ESX.Math.Round(amount) + if amount == nil or amount <= 0 or amount > xPlayer.getMoney() then TriggerClientEvent('esx:showNotification', _source, _U('invalid_amount')) else @@ -23,11 +24,11 @@ AddEventHandler('esx_atm:withdraw', function(amount) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) amount = tonumber(amount) + local accountMoney = xPlayer.getAccount('bank').money if not tonumber(amount) then return end - amount = round(amount) - local accountMoney = 0 - accountMoney = xPlayer.getAccount('bank').money + amount = ESX.Math.Round(amount) + if amount == nil or amount <= 0 or amount > accountMoney then TriggerClientEvent('esx:showNotification', _source, _U('invalid_amount')) else @@ -36,7 +37,3 @@ AddEventHandler('esx_atm:withdraw', function(amount) TriggerClientEvent('esx:showNotification', _source, _U('withdraw_money', amount)) end end) - -function round(x) - return x>=0 and math.floor(x+0.5) or math.ceil(x-0.5) -end \ No newline at end of file From a4152db8c36588e5f594675f5572310d5aa046fc Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 11 Nov 2018 11:52:16 +0100 Subject: [PATCH 1914/3224] xPlayer.hasWeapon() function --- server/classes/player.lua | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 03f29901..114cc66d 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -384,15 +384,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end end - local foundWeapon = false - - for i=1, #self.loadout, 1 do - if self.loadout[i].name == weaponName then - foundWeapon = true - end - end - - if not foundWeapon then + if not self.hasWeapon(weaponName) then table.insert(self.loadout, { name = weaponName, ammo = ammo, @@ -414,8 +406,6 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end end - local foundWeapon = false - for i=1, #self.loadout, 1 do if self.loadout[i].name == weaponName then table.remove(self.loadout, i) @@ -427,5 +417,15 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l TriggerClientEvent('esx:removeInventoryItem', self.source, {label = weaponLabel}, 1) end + self.hasWeapon = function(weaponName) + for i=1, #self.loadout, 1 do + if self.loadout[i].name == weaponName then + return true + end + end + + return false + end + return self end From af2f506110f722c34895c7f51ef023b24a31ebe9 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 11 Nov 2018 12:06:03 +0100 Subject: [PATCH 1915/3224] Further performance improvements --- client/main.lua | 46 +++++++++++++++++++++++----------------------- config.lua | 3 ++- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/client/main.lua b/client/main.lua index 5d519238..f2ed0d5a 100644 --- a/client/main.lua +++ b/client/main.lua @@ -73,10 +73,9 @@ Citizen.CreateThread(function() isInATMMarker = false for k,v in pairs(Config.ATMLocations) do - if(GetDistanceBetweenCoords(coords, v.x, v.y, v.z, true) < Config.ZoneSize.x / 2) then - isInATMMarker = true - ESX.ShowHelpNotification(_U('press_e_atm')) - canSleep = false + if GetDistanceBetweenCoords(coords, v.x, v.y, v.z, true) < 1.0 then + isInATMMarker, canSleep = true, true + break end end @@ -107,31 +106,32 @@ Citizen.CreateThread(function() while true do Citizen.Wait(10) - if menuIsShowed then - DisableControlAction(0, 1, true) -- LookLeftRight - DisableControlAction(0, 2, true) -- LookUpDown - DisableControlAction(0, 142, true) -- MeleeAttackAlternate - DisableControlAction(0, 106, true) -- VehicleMouseControlOverride - elseif IsControlJustReleased(0, Keys['E']) and isInATMMarker and IsPedOnFoot(PlayerPedId()) then - menuIsShowed = true - ESX.TriggerServerCallback('esx:getPlayerData', function(data) - SendNUIMessage({ - showMenu = true, - player = { - money = data.money, - accounts = data.accounts - } - }) - end) + if isInATMMarker and not menuIsShowed then - SetNuiFocus(true, true) - elseif (not isInATMMarker and not menuIsShowed) then + ESX.ShowHelpNotification(_U('press_e_atm')) + + if IsControlJustReleased(0, Keys['E']) and IsPedOnFoot(PlayerPedId()) then + menuIsShowed = true + ESX.TriggerServerCallback('esx:getPlayerData', function(data) + SendNUIMessage({ + showMenu = true, + player = { + money = data.money, + accounts = data.accounts + } + }) + end) + + SetNuiFocus(true, true) + end + + else Citizen.Wait(500) end end end) --- close the menu when script is restarting to avoid being stuck in NUI focus +-- close the menu when script is stopping to avoid being stuck in NUI focus AddEventHandler('onResourceStop', function(resource) if resource == GetCurrentResourceName() then if menuIsShowed then diff --git a/config.lua b/config.lua index 23d784f4..2dec24e0 100644 --- a/config.lua +++ b/config.lua @@ -1,7 +1,8 @@ Config = {} -Config.ZoneSize = {x = 3.0, y = 3.0, z = 0.3} + Config.ZDiff = 2.0 Config.BlipSprite = 431 + Config.Locale = 'fr' Config.EnableBlips = false -- for some reason ATM blips are extremly buggy and will bug out the map From 42ccf8f287d6828b4d4fb324ad2dd792d0a98a36 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 11 Nov 2018 12:28:17 +0100 Subject: [PATCH 1916/3224] Optimized getting shop items, open menu after license bought --- client/main.lua | 21 +++++++++++++---- config.lua | 2 +- server/main.lua | 62 ++++++++++++++++++++++++++----------------------- 3 files changed, 50 insertions(+), 35 deletions(-) diff --git a/client/main.lua b/client/main.lua index ee6f3740..b46d8ee3 100644 --- a/client/main.lua +++ b/client/main.lua @@ -24,13 +24,20 @@ Citizen.CreateThread(function() Citizen.Wait(0) end - ESX.TriggerServerCallback('esx_weashop:requestDBItems', function(ShopItems) - for k,v in pairs(ShopItems) do + ESX.TriggerServerCallback('esx_weashop:getShop', function(shopItems) + for k,v in pairs(shopItems) do Config.Zones[k].Items = v end end) end) +RegisterNetEvent('esx_weashop:sendShop') +AddEventHandler('esx_weashop:sendShop', function(shopItems) + for k,v in pairs(shopItems) do + Config.Zones[k].Items = v + end +end) + RegisterNetEvent('esx_weashop:loadLicenses') AddEventHandler('esx_weashop:loadLicenses', function(licenses) for i = 1, #licenses, 1 do @@ -49,9 +56,13 @@ function OpenBuyLicenseMenu(zone) } }, function(data, menu) if data.current.value == 'yes' then - TriggerServerEvent('esx_weashop:buyLicense') + ESX.TriggerServerCallback('esx_weashop:buyLicense', function(bought) + if bought then + menu.close() + OpenShopMenu(zone) + end + end) end - menu.close() end, function(data, menu) menu.close() end) @@ -179,7 +190,7 @@ Citizen.CreateThread(function() if Licenses['weapon'] ~= nil or Config.Zones[CurrentActionData.zone].legal == 1 then OpenShopMenu(CurrentActionData.zone) else - OpenBuyLicenseMenu() + OpenBuyLicenseMenu(CurrentActionData.zone) end else OpenShopMenu(CurrentActionData.zone) diff --git a/config.lua b/config.lua index ab01d636..2406ec53 100644 --- a/config.lua +++ b/config.lua @@ -21,7 +21,7 @@ Config.Zones = { { x = 22.09, y = -1107.28, z = 28.80 }, { x = 2567.69, y = 294.38, z = 107.73 }, { x = -1117.58, y = 2698.61, z = 17.55 }, - { x = 842.44, y = -1033.42, z = 27.19 }, + { x = 842.44, y = -1033.42, z = 27.19 } } }, diff --git a/server/main.lua b/server/main.lua index 239d48b5..e6154273 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,7 +1,32 @@ ESX = nil +local shopItems = {} TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) +MySQL.ready(function() + + MySQL.Async.fetchAll('SELECT * FROM weashops', {}, function(result) + for i=1, #result, 1 do + if shopItems[result[i].zone] == nil then + shopItems[result[i].zone] = {} + end + + table.insert(shopItems[result[i].zone], { + item = result[i].item, + price = result[i].price, + label = ESX.GetWeaponLabel(result[i].item) + }) + end + + TriggerClientEvent('esx_weashop:sendShop', -1, shopItems) + end) + +end) + +ESX.RegisterServerCallback('esx_weashop:getShop', function(source, cb) + cb(shopItems) +end) + function LoadLicenses(source) TriggerEvent('esx_license:getLicenses', source, function(licenses) TriggerClientEvent('esx_weashop:loadLicenses', source, licenses) @@ -14,44 +39,23 @@ if Config.LicenseEnable then end) end -RegisterServerEvent('esx_weashop:buyLicense') -AddEventHandler('esx_weashop:buyLicense', function() - local _source = source +ESX.RegisterServerCallback('esx_weashop:buyLicense', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) if xPlayer.getMoney() >= Config.LicensePrice then xPlayer.removeMoney(Config.LicensePrice) - TriggerEvent('esx_license:addLicense', _source, 'weapon', function() - LoadLicenses(_source) + TriggerEvent('esx_license:addLicense', source, 'weapon', function() + LoadLicenses(source) end) + + cb(true) else - TriggerClientEvent('esx:showNotification', _source, _U('not_enough')) + cb(false) + TriggerClientEvent('esx:showNotification', source, _U('not_enough')) end end) -ESX.RegisterServerCallback('esx_weashop:requestDBItems', function(source, cb) - MySQL.Async.fetchAll('SELECT * FROM weashops', {}, function(result) - local shopItems = {} - - for i=1, #result, 1 do - - if shopItems[result[i].zone] == nil then - shopItems[result[i].zone] = {} - end - - table.insert(shopItems[result[i].zone], { - item = result[i].item, - price = result[i].price, - label = ESX.GetWeaponLabel(result[i].item) - }) - - end - - cb(shopItems) - end) -end) - RegisterServerEvent('esx_weashop:buyItem') AddEventHandler('esx_weashop:buyItem', function(weaponName, zone) local _source = source @@ -63,7 +67,7 @@ AddEventHandler('esx_weashop:buyItem', function(weaponName, zone) return end - if zone == "BlackWeashop" then + if zone == 'BlackWeashop' then if xPlayer.getAccount('black_money').money >= price then xPlayer.removeAccountMoney('black_money', price) From d2a369e8256c638b98afcb8d1e7dd4a2e2717c26 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 11 Nov 2018 12:37:14 +0100 Subject: [PATCH 1917/3224] Added menu aligment --- client/main.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index b46d8ee3..878e3427 100644 --- a/client/main.lua +++ b/client/main.lua @@ -50,6 +50,7 @@ function OpenBuyLicenseMenu(zone) ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'shop_license', { title = _U('buy_license'), + align = 'top-left', elements = { { label = _U('no'), value = 'no' }, { label = _U('yes', ('%s'):format((_U('shop_menu_item', ESX.Math.GroupDigits(Config.LicensePrice))))), value = 'yes' }, @@ -83,7 +84,8 @@ function OpenShopMenu(zone) ESX.UI.Menu.CloseAll() ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'shop', { - title = _U('shop'), + title = _U('shop'), + align = 'top-left', elements = elements }, function(data, menu) TriggerServerEvent('esx_weashop:buyItem', data.current.weaponName, zone) From 45e6ce5f7daebbc8d51ca16a6d58ed2a11f8a953 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 11 Nov 2018 12:50:48 +0100 Subject: [PATCH 1918/3224] 4 tab indent update --- client/main.lua | 1245 +++++++++++++++++++++++------------------------ config.lua | 64 +-- server/main.lua | 12 +- 3 files changed, 647 insertions(+), 674 deletions(-) diff --git a/client/main.lua b/client/main.lua index 4f2a81f9..3a37fb7d 100644 --- a/client/main.lua +++ b/client/main.lua @@ -83,20 +83,22 @@ AddEventHandler('esx_vehicleshop:sendVehicles', function (vehicles) Vehicles = vehicles end) -function DeleteShopInsideVehicles () - while #LastVehicles > 0 do - local vehicle = LastVehicles[1] - ESX.Game.DeleteVehicle(vehicle) - table.remove(LastVehicles, 1) - end +function DeleteShopInsideVehicles() + while #LastVehicles > 0 do + local vehicle = LastVehicles[1] + + ESX.Game.DeleteVehicle(vehicle) + table.remove(LastVehicles, 1) + end end function ReturnVehicleProvider() + ESX.TriggerServerCallback('esx_vehicleshop:getCommercialVehicles', function (vehicles) local elements = {} local returnPrice for i=1, #vehicles, 1 do - returnPrice = ESX.Round(vehicles[i].price * 0.75) + returnPrice = ESX.Math.Round(vehicles[i].price * 0.75) table.insert(elements, { label = vehicles[i].name .. ' [$' .. returnPrice .. ']', @@ -123,508 +125,491 @@ function ReturnVehicleProvider() end -function OpenShopMenu () - IsInShopMenu = true - - ESX.UI.Menu.CloseAll() - - local playerPed = PlayerPedId() - - FreezeEntityPosition(playerPed, true) - SetEntityVisible(playerPed, false) - SetEntityCoords(playerPed, Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z) - - local vehiclesByCategory = {} - local elements = {} - local firstVehicleData = nil - - for i=1, #Categories, 1 do - vehiclesByCategory[Categories[i].name] = {} - end - - for i=1, #Vehicles, 1 do - table.insert(vehiclesByCategory[Vehicles[i].category], Vehicles[i]) - end - - for i=1, #Categories, 1 do - local category = Categories[i] - local categoryVehicles = vehiclesByCategory[category.name] - local options = {} - - for j=1, #categoryVehicles, 1 do - local vehicle = categoryVehicles[j] - - if i == 1 and j == 1 then - firstVehicleData = vehicle - end - - table.insert(options, vehicle.name .. ' $' .. vehicle.price .. '') - end - - table.insert(elements, { - name = category.name, - label = category.label, - value = 0, - type = 'slider', - max = #Categories[i], - options = options - }) - end - - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'vehicle_shop', - { - title = _U('car_dealer'), - align = 'top-left', - elements = elements - }, - function (data, menu) - local vehicleData = vehiclesByCategory[data.current.name][data.current.value + 1] - - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'shop_confirm', - { - title = _U('buy_vehicle_shop', vehicleData.name, vehicleData.price), - align = 'top-left', - elements = { - {label = _U('yes'), value = 'yes'}, - {label = _U('no'), value = 'no'}, - }, - }, - function (data2, menu2) - if data2.current.value == 'yes' then - if Config.EnablePlayerManagement then - ESX.TriggerServerCallback('esx_vehicleshop:buyVehicleSociety', function (hasEnoughMoney) - if hasEnoughMoney then - IsInShopMenu = false - - DeleteShopInsideVehicles() - - local playerPed = PlayerPedId() - - CurrentAction = 'shop_menu' - CurrentActionMsg = _U('shop_menu') - CurrentActionData = {} - - FreezeEntityPosition(playerPed, false) - SetEntityVisible(playerPed, true) - SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos.x, Config.Zones.ShopEntering.Pos.y, Config.Zones.ShopEntering.Pos.z) - - menu2.close() - menu.close() - - ESX.ShowNotification(_U('vehicle_purchased')) - else - ESX.ShowNotification(_U('broke_company')) - end - - end, 'cardealer', vehicleData.model) - else - local playerData = ESX.GetPlayerData() - - if Config.EnableSocietyOwnedVehicles and playerData.job.grade_name == 'boss' then - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'shop_confirm_buy_type', - { - title = _U('purchase_type'), - align = 'top-left', - elements = { - {label = _U('staff_type'), value = 'personnal'}, - {label = _U('society_type'), value = 'society'}, - }, - }, - function (data3, menu3) - - if data3.current.value == 'personnal' then - ESX.TriggerServerCallback('esx_vehicleshop:buyVehicle', function (hasEnoughMoney) - if hasEnoughMoney then - IsInShopMenu = false - - menu3.close() - menu2.close() - menu.close() - - DeleteShopInsideVehicles() - - ESX.Game.SpawnVehicle(vehicleData.model, Config.Zones.ShopOutside.Pos, Config.Zones.ShopOutside.Heading, function (vehicle) - - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - - local newPlate = GeneratePlate() - local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) - vehicleProps.plate = newPlate - SetVehicleNumberPlateText(vehicle, newPlate) - - if Config.EnableOwnedVehicles then - TriggerServerEvent('esx_vehicleshop:setVehicleOwned', vehicleProps) - end - - ESX.ShowNotification(_U('vehicle_purchased')) - end) - - FreezeEntityPosition(playerPed, false) - SetEntityVisible(playerPed, true) - else - ESX.ShowNotification(_U('not_enough_money')) - end - end, vehicleData.model) - end - - if data3.current.value == 'society' then - ESX.TriggerServerCallback('esx_vehicleshop:buyVehicleSociety', function (hasEnoughMoney) - if hasEnoughMoney then - - IsInShopMenu = false - - menu3.close() - menu2.close() - menu.close() +function OpenShopMenu() + + IsInShopMenu = true + + ESX.UI.Menu.CloseAll() + + local playerPed = PlayerPedId() + + FreezeEntityPosition(playerPed, true) + SetEntityVisible(playerPed, false) + SetEntityCoords(playerPed, Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z) + + local vehiclesByCategory = {} + local elements = {} + local firstVehicleData = nil + + for i=1, #Categories, 1 do + vehiclesByCategory[Categories[i].name] = {} + end - DeleteShopInsideVehicles() + for i=1, #Vehicles, 1 do + table.insert(vehiclesByCategory[Vehicles[i].category], Vehicles[i]) + end - ESX.Game.SpawnVehicle(vehicleData.model, Config.Zones.ShopOutside.Pos, Config.Zones.ShopOutside.Heading, function (vehicle) + for i=1, #Categories, 1 do + local category = Categories[i] + local categoryVehicles = vehiclesByCategory[category.name] + local options = {} - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + for j=1, #categoryVehicles, 1 do + local vehicle = categoryVehicles[j] - local newPlate = GeneratePlate() - local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) - vehicleProps.plate = newPlate - SetVehicleNumberPlateText(vehicle, newPlate) + if i == 1 and j == 1 then + firstVehicleData = vehicle + end - TriggerServerEvent('esx_vehicleshop:setVehicleOwnedSociety', playerData.job.name, vehicleProps) + table.insert(options, vehicle.name .. ' $' .. vehicle.price .. '') + end - ESX.ShowNotification(_U('vehicle_purchased')) + table.insert(elements, { + name = category.name, + label = category.label, + value = 0, + type = 'slider', + max = #Categories[i], + options = options + }) + end - end) + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop', + { + title = _U('car_dealer'), + align = 'top-left', + elements = elements + }, function (data, menu) + local vehicleData = vehiclesByCategory[data.current.name][data.current.value + 1] - FreezeEntityPosition(playerPed, false) - SetEntityVisible(playerPed, true) - else - ESX.ShowNotification(_U('broke_company')) - end - end, playerData.job.name, vehicleData.model) - end - end, - function (data3, menu3) - menu3.close() - end - ) - else - ESX.TriggerServerCallback('esx_vehicleshop:buyVehicle', function (hasEnoughMoney) - if hasEnoughMoney then + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'shop_confirm', { + title = _U('buy_vehicle_shop', vehicleData.name, vehicleData.price), + align = 'top-left', + elements = { + {label = _U('yes'), value = 'yes'}, + {label = _U('no'), value = 'no'}, + } + }, function (data2, menu2) + if data2.current.value == 'yes' then + if Config.EnablePlayerManagement then + ESX.TriggerServerCallback('esx_vehicleshop:buyVehicleSociety', function(hasEnoughMoney) - IsInShopMenu = false + if hasEnoughMoney then + IsInShopMenu = false - menu2.close() - menu.close() + DeleteShopInsideVehicles() - DeleteShopInsideVehicles() + local playerPed = PlayerPedId() - ESX.Game.SpawnVehicle(vehicleData.model, Config.Zones.ShopOutside.Pos, Config.Zones.ShopOutside.Heading, function (vehicle) + CurrentAction = 'shop_menu' + CurrentActionMsg = _U('shop_menu') + CurrentActionData = {} - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + FreezeEntityPosition(playerPed, false) + SetEntityVisible(playerPed, true) + SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos.x, Config.Zones.ShopEntering.Pos.y, Config.Zones.ShopEntering.Pos.z) - local newPlate = GeneratePlate() - local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) - vehicleProps.plate = newPlate - SetVehicleNumberPlateText(vehicle, newPlate) + menu2.close() + menu.close() - if Config.EnableOwnedVehicles then - TriggerServerEvent('esx_vehicleshop:setVehicleOwned', vehicleProps) - end + ESX.ShowNotification(_U('vehicle_purchased')) + else + ESX.ShowNotification(_U('broke_company')) + end - ESX.ShowNotification(_U('vehicle_purchased')) - end) + end, 'cardealer', vehicleData.model) + else + local playerData = ESX.GetPlayerData() - FreezeEntityPosition(playerPed, false) - SetEntityVisible(playerPed, true) - else - ESX.ShowNotification(_U('not_enough_money')) - end - end, vehicleData.model) - end - end - end + if Config.EnableSocietyOwnedVehicles and playerData.job.grade_name == 'boss' then - if data2.current.value == 'no' then + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'shop_confirm_buy_type', { + title = _U('purchase_type'), + align = 'top-left', + elements = { + {label = _U('staff_type'), value = 'personnal'}, + {label = _U('society_type'), value = 'society'} + } + }, function (data3, menu3) - end + if data3.current.value == 'personnal' then - end, - function (data2, menu2) - menu2.close() - end - ) + ESX.TriggerServerCallback('esx_vehicleshop:buyVehicle', function (hasEnoughMoney) - end, - function (data, menu) + if hasEnoughMoney then + IsInShopMenu = false - menu.close() + menu3.close() + menu2.close() + menu.close() - DeleteShopInsideVehicles() + DeleteShopInsideVehicles() - local playerPed = PlayerPedId() + ESX.Game.SpawnVehicle(vehicleData.model, Config.Zones.ShopOutside.Pos, Config.Zones.ShopOutside.Heading, function (vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - CurrentAction = 'shop_menu' - CurrentActionMsg = _U('shop_menu') - CurrentActionData = {} + local newPlate = GeneratePlate() + local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) + vehicleProps.plate = newPlate + SetVehicleNumberPlateText(vehicle, newPlate) - FreezeEntityPosition(playerPed, false) - SetEntityVisible(playerPed, true) - SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos.x, Config.Zones.ShopEntering.Pos.y, Config.Zones.ShopEntering.Pos.z) + if Config.EnableOwnedVehicles then + TriggerServerEvent('esx_vehicleshop:setVehicleOwned', vehicleProps) + end - IsInShopMenu = false + ESX.ShowNotification(_U('vehicle_purchased')) + end) - end, - function (data, menu) - local vehicleData = vehiclesByCategory[data.current.name][data.current.value + 1] - local playerPed = PlayerPedId() + FreezeEntityPosition(playerPed, false) + SetEntityVisible(playerPed, true) + else + ESX.ShowNotification(_U('not_enough_money')) + end - DeleteShopInsideVehicles() + end, vehicleData.model) - ESX.Game.SpawnLocalVehicle(vehicleData.model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function (vehicle) - table.insert(LastVehicles, vehicle) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - FreezeEntityPosition(vehicle, true) - end) - end - ) + elseif data3.current.value == 'society' then - DeleteShopInsideVehicles() + ESX.TriggerServerCallback('esx_vehicleshop:buyVehicleSociety', function (hasEnoughMoney) - ESX.Game.SpawnLocalVehicle(firstVehicleData.model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function (vehicle) - table.insert(LastVehicles, vehicle) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - FreezeEntityPosition(vehicle, true) - end) + if hasEnoughMoney then + IsInShopMenu = false + + menu3.close() + menu2.close() + menu.close() + + DeleteShopInsideVehicles() + + ESX.Game.SpawnVehicle(vehicleData.model, Config.Zones.ShopOutside.Pos, Config.Zones.ShopOutside.Heading, function (vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + + local newPlate = GeneratePlate() + local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) + vehicleProps.plate = newPlate + SetVehicleNumberPlateText(vehicle, newPlate) + + TriggerServerEvent('esx_vehicleshop:setVehicleOwnedSociety', playerData.job.name, vehicleProps) + + ESX.ShowNotification(_U('vehicle_purchased')) + end) + + FreezeEntityPosition(playerPed, false) + SetEntityVisible(playerPed, true) + else + ESX.ShowNotification(_U('broke_company')) + end + + end, playerData.job.name, vehicleData.model) + + end + end, function (data3, menu3) + menu3.close() + end) + else + ESX.TriggerServerCallback('esx_vehicleshop:buyVehicle', function (hasEnoughMoney) + + if hasEnoughMoney then + IsInShopMenu = false + + menu2.close() + menu.close() + + DeleteShopInsideVehicles() + + ESX.Game.SpawnVehicle(vehicleData.model, Config.Zones.ShopOutside.Pos, Config.Zones.ShopOutside.Heading, function (vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + + local newPlate = GeneratePlate() + local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) + vehicleProps.plate = newPlate + SetVehicleNumberPlateText(vehicle, newPlate) + + if Config.EnableOwnedVehicles then + TriggerServerEvent('esx_vehicleshop:setVehicleOwned', vehicleProps) + end + + ESX.ShowNotification(_U('vehicle_purchased')) + end) + + FreezeEntityPosition(playerPed, false) + SetEntityVisible(playerPed, true) + else + ESX.ShowNotification(_U('not_enough_money')) + end + + end, vehicleData.model) + end + end + elseif data2.current.value == 'no' then + + end + + end, function (data2, menu2) + menu2.close() + end) + + end, function (data, menu) + + menu.close() + + DeleteShopInsideVehicles() + + local playerPed = PlayerPedId() + + CurrentAction = 'shop_menu' + CurrentActionMsg = _U('shop_menu') + CurrentActionData = {} + + FreezeEntityPosition(playerPed, false) + SetEntityVisible(playerPed, true) + SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos.x, Config.Zones.ShopEntering.Pos.y, Config.Zones.ShopEntering.Pos.z) + + IsInShopMenu = false + + end, function (data, menu) + local vehicleData = vehiclesByCategory[data.current.name][data.current.value + 1] + local playerPed = PlayerPedId() + + DeleteShopInsideVehicles() + + ESX.Game.SpawnLocalVehicle(vehicleData.model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function (vehicle) + table.insert(LastVehicles, vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + FreezeEntityPosition(vehicle, true) + end) + end) + + DeleteShopInsideVehicles() + + ESX.Game.SpawnLocalVehicle(firstVehicleData.model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function (vehicle) + table.insert(LastVehicles, vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + FreezeEntityPosition(vehicle, true) + end) end -function OpenResellerMenu () +function OpenResellerMenu() - ESX.UI.Menu.CloseAll() + ESX.UI.Menu.CloseAll() - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'reseller', - { - title = _U('car_dealer'), - align = 'top-left', - elements = { - {label = _U('buy_vehicle'), value = 'buy_vehicle'}, - {label = _U('pop_vehicle'), value = 'pop_vehicle'}, - {label = _U('depop_vehicle'), value = 'depop_vehicle'}, - {label = _U('return_provider'), value = 'return_provider'}, - {label = _U('create_bill'), value = 'create_bill'}, - {label = _U('get_rented_vehicles'), value = 'get_rented_vehicles'}, - {label = _U('set_vehicle_owner_sell'), value = 'set_vehicle_owner_sell'}, - {label = _U('set_vehicle_owner_rent'), value = 'set_vehicle_owner_rent'}, - {label = _U('set_vehicle_owner_sell_society'), value = 'set_vehicle_owner_sell_society'}, - {label = _U('deposit_stock'), value = 'put_stock'}, - {label = _U('take_stock'), value = 'get_stock'}, - } - }, - function (data, menu) - local action = data.current.value + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'reseller', + { + title = _U('car_dealer'), + align = 'top-left', + elements = { + {label = _U('buy_vehicle'), value = 'buy_vehicle'}, + {label = _U('pop_vehicle'), value = 'pop_vehicle'}, + {label = _U('depop_vehicle'), value = 'depop_vehicle'}, + {label = _U('return_provider'), value = 'return_provider'}, + {label = _U('create_bill'), value = 'create_bill'}, + {label = _U('get_rented_vehicles'), value = 'get_rented_vehicles'}, + {label = _U('set_vehicle_owner_sell'), value = 'set_vehicle_owner_sell'}, + {label = _U('set_vehicle_owner_rent'), value = 'set_vehicle_owner_rent'}, + {label = _U('set_vehicle_owner_sell_society'), value = 'set_vehicle_owner_sell_society'}, + {label = _U('deposit_stock'), value = 'put_stock'}, + {label = _U('take_stock'), value = 'get_stock'} + } + }, function (data, menu) + local action = data.current.value - if action == 'buy_vehicle' then - OpenShopMenu() - elseif action == 'put_stock' then - OpenPutStocksMenu() - elseif action == 'get_stock' then - OpenGetStocksMenu() - elseif action == 'pop_vehicle' then - OpenPopVehicleMenu() - elseif action == 'depop_vehicle' then - DeleteShopInsideVehicles() - elseif action == 'return_provider' then - ReturnVehicleProvider() - elseif action == 'create_bill' then - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(_U('no_players')) - return - end - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'set_vehicle_owner_sell_amount', - { - title = _U('invoice_amount'), - }, - function (data2, menu) + if action == 'buy_vehicle' then + OpenShopMenu() + elseif action == 'put_stock' then + OpenPutStocksMenu() + elseif action == 'get_stock' then + OpenGetStocksMenu() + elseif action == 'pop_vehicle' then + OpenPopVehicleMenu() + elseif action == 'depop_vehicle' then + DeleteShopInsideVehicles() + elseif action == 'return_provider' then + ReturnVehicleProvider() + elseif action == 'create_bill' then - local amount = tonumber(data2.value) + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(_U('no_players')) + return + end - if amount == nil then - ESX.ShowNotification(_U('invoice_amount')) - else - menu.close() + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'set_vehicle_owner_sell_amount', { + title = _U('invoice_amount') + }, function (data2, menu2) + local amount = tonumber(data2.value) - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if amount == nil then + ESX.ShowNotification(_U('invoice_amount')) + else + menu2.close() - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(_U('no_players')) - else - TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_cardealer', _U('car_dealer'), tonumber(data2.value)) - end - end - end, - function (data2, menu) - menu.close() - end - ) - elseif action == 'get_rented_vehicles' then - OpenRentedVehiclesMenu() - elseif action == 'set_vehicle_owner_sell' then - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(_U('no_players')) - else - - local newPlate = GeneratePlate() - local vehicleProps = ESX.Game.GetVehicleProperties(LastVehicles[#LastVehicles]) - local model = CurrentVehicleData.model - vehicleProps.plate = newPlate - SetVehicleNumberPlateText(LastVehicles[#LastVehicles], newPlate) + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(_U('no_players')) + else + TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_cardealer', _U('car_dealer'), tonumber(data2.value)) + end + end + end, function (data2, menu2) + menu2.close() + end) + elseif action == 'get_rented_vehicles' then + OpenRentedVehiclesMenu() + elseif action == 'set_vehicle_owner_sell' then - TriggerServerEvent('esx_vehicleshop:sellVehicle', model) + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if Config.EnableOwnedVehicles then - TriggerServerEvent('esx_vehicleshop:setVehicleOwnedPlayerId', GetPlayerServerId(closestPlayer), vehicleProps) - ESX.ShowNotification(_U('vehicle_set_owned', vehicleProps.plate, GetPlayerName(closestPlayer))) - else - ESX.ShowNotification(_U('vehicle_sold_to', vehicleProps.plate, GetPlayerName(closestPlayer))) - end - end - elseif action == 'set_vehicle_owner_sell_society' then - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(_U('no_players')) + else - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(_U('no_players')) - else - ESX.TriggerServerCallback('esx:getOtherPlayerData', function (xPlayer) - local newPlate = GeneratePlate() - local vehicleProps = ESX.Game.GetVehicleProperties(LastVehicles[#LastVehicles]) - local model = CurrentVehicleData.model - vehicleProps.plate = newPlate - SetVehicleNumberPlateText(LastVehicles[#LastVehicles], newPlate) - - TriggerServerEvent('esx_vehicleshop:sellVehicle', model) + local newPlate = GeneratePlate() + local vehicleProps = ESX.Game.GetVehicleProperties(LastVehicles[#LastVehicles]) + local model = CurrentVehicleData.model + vehicleProps.plate = newPlate + SetVehicleNumberPlateText(LastVehicles[#LastVehicles], newPlate) - if Config.EnableSocietyOwnedVehicles then - TriggerServerEvent('esx_vehicleshop:setVehicleOwnedSociety', xPlayer.job.name, vehicleProps) - ESX.ShowNotification(_U('vehicle_set_owned', vehicleProps.plate, GetPlayerName(closestPlayer))) - else - ESX.ShowNotification(_U('vehicle_sold_to', vehicleProps.plate, GetPlayerName(closestPlayer))) - end - end, GetPlayerServerId(closestPlayer)) - end - elseif action == 'set_vehicle_owner_rent' then - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'set_vehicle_owner_rent_amount', - { - title = _U('rental_amount'), - }, - function (data2, menu) - local amount = tonumber(data2.value) + TriggerServerEvent('esx_vehicleshop:sellVehicle', model) - if amount == nil then - ESX.ShowNotification(_U('invalid_amount')) - else - menu.close() + if Config.EnableOwnedVehicles then + TriggerServerEvent('esx_vehicleshop:setVehicleOwnedPlayerId', GetPlayerServerId(closestPlayer), vehicleProps) + ESX.ShowNotification(_U('vehicle_set_owned', vehicleProps.plate, GetPlayerName(closestPlayer))) + else + ESX.ShowNotification(_U('vehicle_sold_to', vehicleProps.plate, GetPlayerName(closestPlayer))) + end - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + end - if closestPlayer == -1 or closestDistance > 5.0 then - ESX.ShowNotification(_U('no_players')) - else - - local newPlate = 'RENT' .. string.upper(ESX.GetRandomString(4)) - local vehicleProps = ESX.Game.GetVehicleProperties(LastVehicles[#LastVehicles]) - local model = CurrentVehicleData.model - vehicleProps.plate = newPlate - SetVehicleNumberPlateText(LastVehicles[#LastVehicles], newPlate) + elseif action == 'set_vehicle_owner_sell_society' then - TriggerServerEvent('esx_vehicleshop:rentVehicle', model, vehicleProps.plate, GetPlayerName(closestPlayer), CurrentVehicleData.price, amount, GetPlayerServerId(closestPlayer)) + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if Config.EnableOwnedVehicles then - TriggerServerEvent('esx_vehicleshop:setVehicleOwnedPlayerId', GetPlayerServerId(closestPlayer), vehicleProps) - end + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(_U('no_players')) + else + ESX.TriggerServerCallback('esx:getOtherPlayerData', function (xPlayer) - ESX.ShowNotification(_U('vehicle_set_rented', vehicleProps.plate, GetPlayerName(closestPlayer))) + local newPlate = GeneratePlate() + local vehicleProps = ESX.Game.GetVehicleProperties(LastVehicles[#LastVehicles]) + local model = CurrentVehicleData.model + vehicleProps.plate = newPlate + SetVehicleNumberPlateText(LastVehicles[#LastVehicles], newPlate) - TriggerServerEvent('esx_vehicleshop:setVehicleForAllPlayers', vehicleProps, Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 5.0) - end - end - end, - function (data2, menu) - menu.close() - end - ) - end - end, - function (data, menu) - menu.close() + TriggerServerEvent('esx_vehicleshop:sellVehicle', model) - CurrentAction = 'reseller_menu' - CurrentActionMsg = _U('shop_menu') - CurrentActionData = {} - end - ) + if Config.EnableSocietyOwnedVehicles then + TriggerServerEvent('esx_vehicleshop:setVehicleOwnedSociety', xPlayer.job.name, vehicleProps) + ESX.ShowNotification(_U('vehicle_set_owned', vehicleProps.plate, GetPlayerName(closestPlayer))) + else + ESX.ShowNotification(_U('vehicle_sold_to', vehicleProps.plate, GetPlayerName(closestPlayer))) + end + + end, GetPlayerServerId(closestPlayer)) + end + + elseif action == 'set_vehicle_owner_rent' then + + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'set_vehicle_owner_rent_amount', { + title = _U('rental_amount') + }, function (data2, menu2) + local amount = tonumber(data2.value) + + if amount == nil then + ESX.ShowNotification(_U('invalid_amount')) + else + menu2.close() + + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + + if closestPlayer == -1 or closestDistance > 5.0 then + ESX.ShowNotification(_U('no_players')) + else + + local newPlate = 'RENT' .. string.upper(ESX.GetRandomString(4)) + local vehicleProps = ESX.Game.GetVehicleProperties(LastVehicles[#LastVehicles]) + local model = CurrentVehicleData.model + vehicleProps.plate = newPlate + SetVehicleNumberPlateText(LastVehicles[#LastVehicles], newPlate) + + TriggerServerEvent('esx_vehicleshop:rentVehicle', model, vehicleProps.plate, GetPlayerName(closestPlayer), CurrentVehicleData.price, amount, GetPlayerServerId(closestPlayer)) + + if Config.EnableOwnedVehicles then + TriggerServerEvent('esx_vehicleshop:setVehicleOwnedPlayerId', GetPlayerServerId(closestPlayer), vehicleProps) + end + + ESX.ShowNotification(_U('vehicle_set_rented', vehicleProps.plate, GetPlayerName(closestPlayer))) + + TriggerServerEvent('esx_vehicleshop:setVehicleForAllPlayers', vehicleProps, Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 5.0) + end + end + end, function (data2, menu2) + menu2.close() + end) + end + + end, function (data, menu) + menu.close() + + CurrentAction = 'reseller_menu' + CurrentActionMsg = _U('shop_menu') + CurrentActionData = {} + end) end -function OpenPersonnalVehicleMenu () +function OpenPersonnalVehicleMenu() + ESX.UI.Menu.CloseAll() - ESX.UI.Menu.CloseAll() + ESX.TriggerServerCallback('esx_vehicleshop:getPersonnalVehicles', function (vehicles) + local elements = {} - ESX.TriggerServerCallback('esx_vehicleshop:getPersonnalVehicles', function (vehicles) - local elements = {} + for i=1, #vehicles, 1 do + for j=1, #Vehicles, 1 do + if vehicles[i].model == GetHashKey(Vehicles[j].model) then + vehicles[i].name = Vehicles[j].name + break + end + end + end - for i=1, #vehicles, 1 do - for j=1, #Vehicles, 1 do - if vehicles[i].model == GetHashKey(Vehicles[j].model) then - vehicles[i].name = Vehicles[j].name - end - end - end + for i=1, #vehicles, 1 do + table.insert(elements, { + label = vehicles[i].name .. ' [' .. vehicles[i].plate .. ']', + value = vehicles[i] + }) + end - for i=1, #vehicles, 1 do - table.insert(elements, {label = vehicles[i].name .. ' [' .. vehicles[i].plate .. ']', value = vehicles[i]}) - end + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'personnal_vehicle', + { + title = _U('personal_vehicle'), + align = 'top-left', + elements = elements, + }, function (data, menu) + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) + local heading = GetEntityHeading(playerPed) + local vehicleData = data.current.value - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'personnal_vehicle', - { - title = _U('personal_vehicle'), - align = 'top-left', - elements = elements, - }, - function (data, menu) - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - local heading = GetEntityHeading(playerPed) - local vehicleData = data.current.value + menu.close() - menu.close() - - ESX.Game.SpawnVehicle(vehicleData.model, { - x = coords.x, - y = coords.y, - z = coords.z - }, heading, function (vehicle) - ESX.Game.SetVehicleProperties(vehicle, vehicleData) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - end) - end, - function (data, menu) - menu.close() - end - ) - end) + ESX.Game.SpawnVehicle(vehicleData.model, { + x = coords.x, + y = coords.y, + z = coords.z + }, heading, function (vehicle) + ESX.Game.SetVehicleProperties(vehicle, vehicleData) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + end) + end, function (data, menu) + menu.close() + end) + end) end -function OpenPopVehicleMenu () +function OpenPopVehicleMenu() ESX.TriggerServerCallback('esx_vehicleshop:getCommercialVehicles', function (vehicles) local elements = {} @@ -654,6 +639,90 @@ function OpenPopVehicleMenu () end end end) + end, function (data, menu) + menu.close() + end) + end) +end + +function OpenRentedVehiclesMenu() + ESX.TriggerServerCallback('esx_vehicleshop:getRentedVehicles', function (vehicles) + local elements = {} + + for i=1, #vehicles, 1 do + table.insert(elements, { + label = vehicles[i].playerName .. ' : ' .. vehicles[i].name .. ' - ' .. vehicles[i].plate, + value = vehicles[i].name + }) + end + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'rented_vehicles', { + title = _U('rent_vehicle'), + align = 'top-left', + elements = elements + }, nil, function (data, menu) + menu.close() + end) + end) +end + +function OpenBossActionsMenu() + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'reseller',{ + title = _U('dealer_boss'), + align = 'top-left', + elements = { + {label = _U('boss_actions'), value = 'boss_actions'} + } + }, function (data, menu) + if data.current.value == 'boss_actions' then + TriggerEvent('esx_society:openBossMenu', 'cardealer', function(data, menu) + menu.close() + end) + end + + end, function (data, menu) + menu.close() + + CurrentAction = 'boss_actions_menu' + CurrentActionMsg = _U('shop_menu') + CurrentActionData = {} + end) +end + + +function OpenGetStocksMenu() + ESX.TriggerServerCallback('esx_vehicleshop:getStockItems', function (items) + local elements = {} + + for i=1, #items, 1 do + table.insert(elements, {label = 'x' .. items[i].count .. ' ' .. items[i].label, value = items[i].name}) + end + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', { + title = _U('dealership_stock'), + align = 'top-left', + elements = elements + }, function (data, menu) + local itemName = data.current.value + + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'stocks_menu_get_item_count', { + title = _U('amount') + }, function (data2, menu2) + local count = tonumber(data2.value) + + if count == nil then + ESX.ShowNotification(_U('quantity_invalid')) + else + TriggerServerEvent('esx_vehicleshop:getStockItem', itemName, count) + menu2.close() + menu.close() + OpenGetStocksMenu() + end + end, function (data2, menu2) + menu2.close() + end) end, function (data, menu) menu.close() @@ -661,158 +730,52 @@ function OpenPopVehicleMenu () end) end -function OpenRentedVehiclesMenu () - ESX.TriggerServerCallback('esx_vehicleshop:getRentedVehicles', function (vehicles) - local elements = {} +function OpenPutStocksMenu() + ESX.TriggerServerCallback('esx_vehicleshop:getPlayerInventory', function (inventory) + local elements = {} - for i=1, #vehicles, 1 do - table.insert(elements, {label = vehicles[i].playerName .. ' : ' .. vehicles[i].name .. ' - ' .. vehicles[i].plate, value = vehicles[i].name}) - end + for i=1, #inventory.items, 1 do + local item = inventory.items[i] - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'rented_vehicles', - { - title = _U('rent_vehicle'), - align = 'top-left', - elements = elements - }, - nil, - function (data, menu) - menu.close() - end - ) - end) -end + if item.count > 0 then + table.insert(elements, { + label = item.label .. ' x' .. item.count, + type = 'item_standard', + value = item.name + }) + end + end -function OpenBossActionsMenu () - ESX.UI.Menu.CloseAll() + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', + { + title = _U('inventory'), + align = 'top-left', + elements = elements + }, function (data, menu) + local itemName = data.current.value - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'reseller', - { - title = _U('dealer_boss'), - align = 'top-left', - elements = { - {label = _U('boss_actions'), value = 'boss_actions'}, - }, - }, - function (data, menu) - if data.current.value == 'boss_actions' then - TriggerEvent('esx_society:openBossMenu', 'cardealer', function(data, menu) - menu.close() - end) - end - end, - function (data, menu) - menu.close() + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'stocks_menu_put_item_count', { + title = _U('amount') + }, function (data2, menu2) + local count = tonumber(data2.value) - CurrentAction = 'boss_actions_menu' - CurrentActionMsg = _U('shop_menu') - CurrentActionData = {} - end - ) -end + if count == nil then + ESX.ShowNotification(_U('quantity_invalid')) + else + TriggerServerEvent('esx_vehicleshop:putStockItems', itemName, count) + menu2.close() + menu.close() + OpenPutStocksMenu() + end + end, function (data2, menu2) + menu2.close() + end) -function OpenGetStocksMenu () - ESX.TriggerServerCallback('esx_vehicleshop:getStockItems', function (items) - local elements = {} - - for i=1, #items, 1 do - table.insert(elements, {label = 'x' .. items[i].count .. ' ' .. items[i].label, value = items[i].name}) - end - - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'stocks_menu', - { - title = _U('dealership_stock'), - align = 'top-left', - elements = elements - }, - function (data, menu) - local itemName = data.current.value - - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'stocks_menu_get_item_count', - { - title = _U('amount'), - }, - function (data2, menu2) - local count = tonumber(data2.value) - - if count == nil then - ESX.ShowNotification(_U('quantity_invalid')) - else - TriggerServerEvent('esx_vehicleshop:getStockItem', itemName, count) - menu2.close() - menu.close() - OpenGetStocksMenu() - - - end - end, - function (data2, menu2) - menu2.close() - end - ) - end, - function (data, menu) - menu.close() - end - ) - end) -end - -function OpenPutStocksMenu () - ESX.TriggerServerCallback('esx_vehicleshop:getPlayerInventory', function (inventory) - local elements = {} - - for i=1, #inventory.items, 1 do - local item = inventory.items[i] - - if item.count > 0 then - table.insert(elements, {label = item.label .. ' x' .. item.count, type = 'item_standard', value = item.name}) - end - end - - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'stocks_menu', - { - title = _U('inventory'), - align = 'top-left', - elements = elements - }, - function (data, menu) - local itemName = data.current.value - - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'stocks_menu_put_item_count', - { - title = _U('amount'), - }, - function (data2, menu2) - local count = tonumber(data2.value) - - if count == nil then - ESX.ShowNotification(_U('quantity_invalid')) - else - TriggerServerEvent('esx_vehicleshop:putStockItems', itemName, count) - menu2.close() - menu.close() - OpenPutStocksMenu() - end - - end, - function (data2, menu2) - menu2.close() - end - ) - end, - function (data, menu) - menu.close() - end - ) - end) + end, function (data, menu) + menu.close() + end) + end) end RegisterNetEvent('esx:setJob') @@ -836,70 +799,72 @@ end) RegisterNetEvent('esx_vehicleshop:openPersonnalVehicleMenu') AddEventHandler('esx_vehicleshop:openPersonnalVehicleMenu', function () - OpenPersonnalVehicleMenu() + OpenPersonnalVehicleMenu() end) AddEventHandler('esx_vehicleshop:hasEnteredMarker', function (zone) - if zone == 'ShopEntering' then - if Config.EnablePlayerManagement then - if ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'cardealer' then - CurrentAction = 'reseller_menu' - CurrentActionMsg = _U('shop_menu') - CurrentActionData = {} - end - else - CurrentAction = 'shop_menu' - CurrentActionMsg = _U('shop_menu') - CurrentActionData = {} - end - end + if zone == 'ShopEntering' then - if zone == 'GiveBackVehicle' and Config.EnablePlayerManagement then - local playerPed = PlayerPedId() + if Config.EnablePlayerManagement then + if ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'cardealer' then + CurrentAction = 'reseller_menu' + CurrentActionMsg = _U('shop_menu') + CurrentActionData = {} + end + else + CurrentAction = 'shop_menu' + CurrentActionMsg = _U('shop_menu') + CurrentActionData = {} + end - if IsPedInAnyVehicle(playerPed, false) then - local vehicle = GetVehiclePedIsIn(playerPed, false) + elseif zone == 'GiveBackVehicle' and Config.EnablePlayerManagement then - CurrentAction = 'give_back_vehicle' - CurrentActionMsg = _U('vehicle_menu') + local playerPed = PlayerPedId() - CurrentActionData = { - vehicle = vehicle - } - end - end + if IsPedInAnyVehicle(playerPed, false) then + local vehicle = GetVehiclePedIsIn(playerPed, false) - if zone == 'ResellVehicle' then - local playerPed = PlayerPedId() + CurrentAction = 'give_back_vehicle' + CurrentActionMsg = _U('vehicle_menu') - if IsPedInAnyVehicle(playerPed, false) then - local vehicle = GetVehiclePedIsIn(playerPed, false) - local vehicleData = nil + CurrentActionData = { + vehicle = vehicle + } + end - for i=1, #Vehicles, 1 do - if GetHashKey(Vehicles[i].model) == GetEntityModel(vehicle) then - vehicleData = Vehicles[i] - break - end - end + elseif zone == 'ResellVehicle' then - local resellPrice = math.floor(vehicleData.price / 100 * Config.ResellPercentage) + local playerPed = PlayerPedId() - CurrentAction = 'resell_vehicle' - CurrentActionMsg = _U('sell_menu', vehicleData.name, resellPrice) + if IsPedInAnyVehicle(playerPed, false) then + local vehicle = GetVehiclePedIsIn(playerPed, false) + local vehicleData = nil - CurrentActionData = { - vehicle = vehicle, - price = resellPrice - } - end - end + for i=1, #Vehicles, 1 do + if GetHashKey(Vehicles[i].model) == GetEntityModel(vehicle) then + vehicleData = Vehicles[i] + break + end + end - if zone == 'BossActions' and Config.EnablePlayerManagement and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'cardealer' and ESX.PlayerData.job.grade_name == 'boss' then - CurrentAction = 'boss_actions_menu' - CurrentActionMsg = _U('shop_menu') - CurrentActionData = {} - end + local resellPrice = math.floor(vehicleData.price / 100 * Config.ResellPercentage) + + CurrentAction = 'resell_vehicle' + CurrentActionMsg = _U('sell_menu', vehicleData.name, resellPrice) + + CurrentActionData = { + vehicle = vehicle, + price = resellPrice + } + end + + elseif zone == 'BossActions' and Config.EnablePlayerManagement and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'cardealer' and ESX.PlayerData.job.grade_name == 'boss' then + + CurrentAction = 'boss_actions_menu' + CurrentActionMsg = _U('shop_menu') + CurrentActionData = {} + + end end) AddEventHandler('esx_vehicleshop:hasExitedMarker', function (zone) @@ -987,7 +952,7 @@ Citizen.CreateThread(function() Citizen.Wait(10) if CurrentAction == nil then - Citizen.Wait(200) + Citizen.Wait(500) else ESX.ShowHelpNotification(CurrentActionMsg) @@ -998,6 +963,7 @@ Citizen.CreateThread(function() elseif CurrentAction == 'reseller_menu' then OpenResellerMenu() elseif CurrentAction == 'give_back_vehicle' then + ESX.TriggerServerCallback('esx_vehicleshop:giveBackVehicle', function(isRentedVehicle) if isRentedVehicle then ESX.Game.DeleteVehicle(CurrentActionData.vehicle) @@ -1006,7 +972,9 @@ Citizen.CreateThread(function() ESX.ShowNotification(_U('not_rental')) end end, GetVehicleNumberPlateText(CurrentActionData.vehicle)) + elseif CurrentAction == 'resell_vehicle' then + ESX.TriggerServerCallback('esx_vehicleshop:resellVehicle', function(isOwnedVehicle) if isOwnedVehicle then ESX.Game.DeleteVehicle(CurrentActionData.vehicle) @@ -1015,6 +983,7 @@ Citizen.CreateThread(function() ESX.ShowNotification(_U('not_yours')) end end, GetVehicleNumberPlateText(CurrentActionData.vehicle), CurrentActionData.price) + elseif CurrentAction == 'boss_actions_menu' then OpenBossActionsMenu() end diff --git a/config.lua b/config.lua index 6d0f81a5..cacff508 100644 --- a/config.lua +++ b/config.lua @@ -16,42 +16,42 @@ Config.PlateUseSpace = true Config.Zones = { - ShopEntering = { - Pos = { x = -33.777, y = -1102.021, z = 25.422 }, - Size = { x = 1.5, y = 1.5, z = 1.0 }, - Type = 1, - }, + ShopEntering = { + Pos = { x = -33.777, y = -1102.021, z = 25.422 }, + Size = { x = 1.5, y = 1.5, z = 1.0 }, + Type = 1, + }, - ShopInside = { - Pos = { x = -47.570, y = -1097.221, z = 25.422 }, - Size = { x = 1.5, y = 1.5, z = 1.0 }, - Heading = -20.0, - Type = -1, - }, + ShopInside = { + Pos = { x = -47.570, y = -1097.221, z = 25.422 }, + Size = { x = 1.5, y = 1.5, z = 1.0 }, + Heading = -20.0, + Type = -1, + }, - ShopOutside = { - Pos = { x = -28.637, y = -1085.691, z = 25.565 }, - Size = { x = 1.5, y = 1.5, z = 1.0 }, - Heading = 330.0, - Type = -1, - }, + ShopOutside = { + Pos = { x = -28.637, y = -1085.691, z = 25.565 }, + Size = { x = 1.5, y = 1.5, z = 1.0 }, + Heading = 330.0, + Type = -1, + }, - BossActions = { - Pos = { x = -32.065, y = -1114.277, z = 25.422 }, - Size = { x = 1.5, y = 1.5, z = 1.0 }, - Type = -1, - }, + BossActions = { + Pos = { x = -32.065, y = -1114.277, z = 25.422 }, + Size = { x = 1.5, y = 1.5, z = 1.0 }, + Type = -1, + }, - GiveBackVehicle = { - Pos = { x = -18.227, y = -1078.558, z = 25.675 }, - Size = { x = 3.0, y = 3.0, z = 1.0 }, - Type = (Config.EnablePlayerManagement and 1 or -1), - }, + GiveBackVehicle = { + Pos = { x = -18.227, y = -1078.558, z = 25.675 }, + Size = { x = 3.0, y = 3.0, z = 1.0 }, + Type = (Config.EnablePlayerManagement and 1 or -1), + }, - ResellVehicle = { - Pos = { x = -44.630, y = -1080.738, z = 25.683 }, - Size = { x = 3.0, y = 3.0, z = 1.0 }, - Type = 1, - }, + ResellVehicle = { + Pos = { x = -44.630, y = -1080.738, z = 25.683 }, + Size = { x = 3.0, y = 3.0, z = 1.0 }, + Type = 1, + } } diff --git a/server/main.lua b/server/main.lua index 56160649..758d5798 100644 --- a/server/main.lua +++ b/server/main.lua @@ -211,12 +211,11 @@ ESX.RegisterServerCallback('esx_vehicleshop:buyVehicleSociety', function (source TriggerEvent('esx_addonaccount:getSharedAccount', 'society_' .. society, function (account) if account.money >= vehicleData.price then - account.removeMoney(vehicleData.price) MySQL.Async.execute('INSERT INTO cardealer_vehicles (vehicle, price) VALUES (@vehicle, @price)', { ['@vehicle'] = vehicleData.model, - ['@price'] = vehicleData.price, + ['@price'] = vehicleData.price }) cb(true) @@ -317,7 +316,7 @@ ESX.RegisterServerCallback('esx_vehicleshop:giveBackVehicle', function (source, ['@price'] = basePrice }) - MySQL.Async.execute('DELETE FROM rented_vehicles WHERE plate = @plate',{ + MySQL.Async.execute('DELETE FROM rented_vehicles WHERE plate = @plate', { ['@plate'] = plate }) @@ -329,7 +328,7 @@ ESX.RegisterServerCallback('esx_vehicleshop:giveBackVehicle', function (source, end) end) -ESX.RegisterServerCallback('esx_vehicleshop:resellVehicle', function (source, cb, plate, price) +ESX.RegisterServerCallback('esx_vehicleshop:resellVehicle', function (source, cb, plate, price) -- todo: remove price MySQL.Async.fetchAll('SELECT * FROM rented_vehicles WHERE plate = @plate', { ['@plate'] = plate }, function (result) @@ -346,10 +345,14 @@ ESX.RegisterServerCallback('esx_vehicleshop:resellVehicle', function (source, cb -- does the owner match? if result[1] ~= nil then + + -- todo: does model match? xPlayer.addMoney(price) RemoveOwnedVehicle(plate) cb(true) + else + if xPlayer.job.grade_name == 'boss' then MySQL.Async.fetchAll('SELECT * FROM owned_vehicles WHERE owner = @owner AND @plate = plate', { @@ -368,6 +371,7 @@ ESX.RegisterServerCallback('esx_vehicleshop:resellVehicle', function (source, cb cb(false) end end + end) end end) From e56d700df44517713632e1060e4585963be12d36 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 11 Nov 2018 14:10:57 +0100 Subject: [PATCH 1919/3224] Revert respect ESX config --- client/main.lua | 24 +++++++++++------------- server/main.lua | 5 ++--- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/client/main.lua b/client/main.lua index 4a4dbb1c..ae8e51ad 100644 --- a/client/main.lua +++ b/client/main.lua @@ -125,21 +125,19 @@ AddEventHandler('esx_status:setDisplay', function(val) end) -- Pause menu disable hud display -if ESX.GetConfig().EnableHud then - Citizen.CreateThread(function() - while true do - Citizen.Wait(300) +Citizen.CreateThread(function() + while true do + Citizen.Wait(300) - if IsPauseMenuActive() and not isPaused then - isPaused = true - TriggerEvent('esx_status:setDisplay', 0.0) - elseif not IsPauseMenuActive() and isPaused then - isPaused = false - TriggerEvent('esx_status:setDisplay', 0.5) - end + if IsPauseMenuActive() and not isPaused then + isPaused = true + TriggerEvent('esx_status:setDisplay', 0.0) + elseif not IsPauseMenuActive() and isPaused then + isPaused = false + TriggerEvent('esx_status:setDisplay', 0.5) end - end) -end + end +end) -- Loaded event Citizen.CreateThread(function() diff --git a/server/main.lua b/server/main.lua index eed4d956..ab6b18c5 100644 --- a/server/main.lua +++ b/server/main.lua @@ -46,10 +46,9 @@ end) RegisterServerEvent('esx_status:update') AddEventHandler('esx_status:update', function(status) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) + local xPlayer = ESX.GetPlayerFromId(source) - if xPlayer ~= nil then + if xPlayer then xPlayer.set('status', status) end end) From ade7a3bc167ad4ee6f88f9562d342e2ecbcef0cc Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 11 Nov 2018 14:20:49 +0100 Subject: [PATCH 1920/3224] Minor improvements --- __resource.lua | 4 +- client/main.lua | 12 ++--- html/css/app.css | 85 ++++++++++++++++------------------ html/js/app.js | 114 ++++++++++++++++++++++++---------------------- html/js/app_en.js | 114 ++++++++++++++++++++++++---------------------- html/js/app_pl.js | 114 ++++++++++++++++++++++++---------------------- html/ui_pl.html | 12 ----- 7 files changed, 224 insertions(+), 231 deletions(-) delete mode 100644 html/ui_pl.html diff --git a/__resource.lua b/__resource.lua index 081c5dfc..8d41f890 100644 --- a/__resource.lua +++ b/__resource.lua @@ -18,4 +18,6 @@ files { 'html/fonts/pdown.ttf', 'html/fonts/bankgothic.ttf' -} \ No newline at end of file +} + +dependency 'es_extended' \ No newline at end of file diff --git a/client/main.lua b/client/main.lua index b419cd73..e220444a 100644 --- a/client/main.lua +++ b/client/main.lua @@ -23,7 +23,7 @@ Citizen.CreateThread(function() action = 'openMenu', namespace = namespace, name = name, - data = data, + data = data }) local timeoutId = ESX.SetTimeout(200, function() @@ -41,7 +41,7 @@ Citizen.CreateThread(function() action = 'closeMenu', namespace = namespace, name = name, - data = data, + data = data }) for k,v in pairs(OpenedMenus) do @@ -68,7 +68,7 @@ Citizen.CreateThread(function() if tonumber(data.value) ~= nil then -- Round float values - data.value = round(tonumber(data.value)) + data.value = ESX.Math.Round(tonumber(data.value)) -- Check for negative value if tonumber(data.value) <= 0 then @@ -128,11 +128,9 @@ Citizen.CreateThread(function() DisableControlAction(0, 15, true) -- WeaponWheelPrev DisableControlAction(0, 16, true) -- SelectNextWeapon DisableControlAction(0, 17, true) -- SelectPrevWeapon + else + Citizen.Wait(500) end end end) - - function round(x) - return x>=0 and math.floor(x+0.5) or math.ceil(x-0.5) - end end) \ No newline at end of file diff --git a/html/css/app.css b/html/css/app.css index e50e4d31..459d3c37 100644 --- a/html/css/app.css +++ b/html/css/app.css @@ -1,81 +1,74 @@ @font-face { - font-family: bankgothic; - src: url('../fonts/bankgothic.ttf'); + font-family: bankgothic; + src: url('../fonts/bankgothic.ttf'); } @font-face { - font-family: pcdown; - src: url('../fonts/pdown.ttf'); + font-family: pcdown; + src: url('../fonts/pdown.ttf'); } #controls { - font-family : pcdown; - font-size : 3em; - color : #FFF; - position : absolute; - bottom : 40; - right : 40; - - text-shadow: - -1px -1px 0 #000, - 1px -1px 0 #000, - -1px 1px 0 #000, - 1px 1px 0 #000 - ; + font-family: pcdown; + font-size: 3em; + color: #FFF; + position: absolute; + bottom: 40; + right: 40; + text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000; } .controls { - display: none; + display: none; } .dialog { - - font-family : bankgothic; - background-color: #fff; - color : #fff; - box-shadow : 0px 0px 50px 0px #000; - position : absolute; - overflow : hidden; - top : 50%; - left : 50%; - width : 600px; - height : 104px; - transform : translate(-50%, -50%); + font-family: bankgothic; + background-color: #fff; + color: #fff; + box-shadow: 0px 0px 50px 0px #000; + position: absolute; + overflow: hidden; + top: 50%; + left: 50%; + width: 600px; + height: 104px; + transform: translate(-50%, -50%); } .dialog.big { - height: 200px; + height: 200px; } .dialog .head { - background-color: #506be6; - text-align : center; - height : 40px; + background-color: #506be6; + text-align: center; + height: 40px; } .dialog .head span:before { - content: ""; - display: inline-block; - height: 100%; - vertical-align: middle; + content: ""; + display: inline-block; + height: 100%; + vertical-align: middle; } .dialog input[type="text"] { - width : 100%; - height: 32px; + width: 100%; + height: 32px; } .dialog textarea { - width : 100%; - height: 128px; + width: 100%; + height: 128px; } .dialog button[name="submit"] { - width : 75%; - height: 32px; + width: 75%; + height: 32px; } .dialog button[name="cancel"] { - width : 25%; - height: 32px; + width: 25%; + height: 32px; } \ No newline at end of file diff --git a/html/js/app.js b/html/js/app.js index 8d136b59..4988e11f 100644 --- a/html/js/app.js +++ b/html/js/app.js @@ -1,4 +1,4 @@ -(function(){ +(function () { let MenuTpl = ' +
    +
    + +
    +
    Añadir contacto
    +
    +
    + + + + +
    +
    +
    + +
    + + + + + + + + + From 3e06ce72500dd7cf340972ff75703c5349397c9c Mon Sep 17 00:00:00 2001 From: BackrndSource Date: Wed, 13 Mar 2019 20:25:08 +0000 Subject: [PATCH 2155/3224] Add Spanish Translation --- html/scripts/app_es.js | 512 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 512 insertions(+) create mode 100644 html/scripts/app_es.js diff --git a/html/scripts/app_es.js b/html/scripts/app_es.js new file mode 100644 index 00000000..35738a76 --- /dev/null +++ b/html/scripts/app_es.js @@ -0,0 +1,512 @@ +(function(){ + + let ContactTpl = + '
    ' + + '
    ' + + '
    ' + + '{{sender}}
    #{{phoneNumber}}' + + '
    ' + + '
    ' + + '
    ' + + 'X' + + '' + + '
    ' + + '
    ' + ; + + let MessageTpl = + '
    ' + + '
    ' + + '
    ' + + '{{sender}}
    #{{phoneNumber}}' + + '
    ' + + '
    ' + + '
    {{message}}
    ' + + '
    ' + + '
    ' + ; + + let SpecialContactTpl = '
  • {{name}}
  • '; + + let contacts = []; + let specialContacts = []; + let menu = []; + let currentItem = 0; + let currentVal = null; + let isMessageEditorOpen = false; + let isMessagesOpen = false; + let isPhoneShowed = false; + + let showMain = function() { + $('.screen').removeClass('active'); + $('.screen *').attr('disabled', 'disabled'); + } + + let showRepertoire = function() { + $('#repertoire').addClass('active'); + } + + let hideRepertoire = function() { + $('#repertoire').removeClass('active'); + } + + let showMessages = function(){ + $('#messages').addClass('active'); + isMessagesOpen = true; + } + + let hideMessages = function(){ + $('#messages').removeClass('active'); + isMessagesOpen = false; + } + + let showAddContact = function() { + $('#contact').addClass('active'); + $('.screen *').attr('disabled', 'disabled'); + $('.screen.active *').removeAttr('disabled'); + } + + let hideAddContact = function() { + $('#contact').removeClass('active'); + $('#contact_name').val(''); + $('#contact_number').val(''); + } + + let showNewMessage = function(cnum, cname) { + $('#writer').addClass('active'); + $('#writer_number').val(cnum); + $('#writer .header-title').html(cname); + $('.screen *').attr('disabled', 'disabled'); + $('.screen.active *').removeAttr('disabled'); + } + + let hideNewMessage = function() { + $('#writer').removeClass('active'); + $('#writer_number').val(''); + $('#writer_message').val(''); + $('#writer .header-title').html(''); + } + + let showGPS = function(xPos, yPos) { + $.post('http://esx_phone/setGPS', JSON.stringify({ + x: parseFloat(xPos), + y: parseFloat(yPos) + } + )); + } + + let renderContacts = function(){ + + let contactHTML = ''; + + if(contacts.length > 0) { + + for(let i=0; i 0) { + + for(let i=0; i { + return a.name.localeCompare(b.name); + }); + + renderSpecialContacts(); + + } + + } + + let removeSpecialContact = function(number){ + + for(let i=0; iContactos' + + '
  • Mensajes
  • ' + ); + + for(let i=0; i Date: Fri, 15 Mar 2019 12:30:05 +0100 Subject: [PATCH 2156/3224] Updated native name --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 828521f7..a10c2e4a 100644 --- a/client/main.lua +++ b/client/main.lua @@ -247,7 +247,7 @@ Citizen.CreateThread(function() end if Config.EnableControls then - if IsControlJustReleased(0, Keys['K']) and GetLastInputMethod(2) and not isDead then + if IsControlJustReleased(0, Keys['K']) and IsInputDisabled(0) and not isDead then OpenAccessoryMenu() end end From 077cc4222821c56968eea677bf2504b9cfb3bcbe Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 15 Mar 2019 13:10:16 +0100 Subject: [PATCH 2157/3224] Removed duplicate entry --- locales/fr.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/locales/fr.lua b/locales/fr.lua index 251ebc31..4306447e 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -17,7 +17,6 @@ Locales ['fr'] = { ['dealer_sold'] = 'vous avez vendu ~b~%sx~s~ ~y~%s~s~ pour ~g~$%s~s~', -- license - ['license_title'] = 'you are required to own a processing license to process this product, it can be bought here.', ['license_title'] = 'vous devez posséder une license spécifique vous autorisant à transformer ce produit. Vous pouvez l\'acheter ici.', ['license_no'] = 'non', ['license_bought'] = 'vous avez acheté ~b~%s~s~ pour ~r~$%s~s~', From 2800fa5d8fc2e97d0f931bca643df8feced23da9 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 15 Mar 2019 13:11:02 +0100 Subject: [PATCH 2158/3224] Enforced 2 space indent --- locales/fi.lua | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/locales/fi.lua b/locales/fi.lua index 5bbe8b27..27a967ea 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -1,16 +1,16 @@ Locales['fi'] = { - ['shop_robbery'] = 'kaupan ryöstö', - ['press_to_rob'] = 'paina ~INPUT_CONTEXT~ ~o~ryöstääksesi~s~ kaupan ~b~%s~s~', - ['robbery_timer'] = 'kauppa ryöstö: ~r~%s~s~ sekunttia jäljellä', - ['recently_robbed'] = 'tämä kauppa ryöstettiin vasta. Odota ~y~%s~s~ sekunttia että voit ryöstää.', - ['rob_in_prog'] = '~r~ryöstö menossa kohteessa ~b~%s~s~', - ['started_to_rob'] = 'sinä aloitit ryöstään ~y~%s~s~', - ['alarm_triggered'] = 'hälyytys laukaistu!', - ['robbery_complete'] = '~r~Ryöstö onnistui~s~, sinä ~o~varastit~s~ ~g~$%s~s~', - ['robbery_complete_at'] = '~r~Ryöstö ohitse kohteessa ~y~%s~s~', - ['robbery_cancelled'] = 'ryöstö keskeytyi!', - ['robbery_cancelled_at'] = '~r~Ryöstö kohteessa ~b~%s~s~ keskeytyi!', - ['min_police'] = 'kaupungissa pitää olla vähintää ~b~%s poliisia~s~ paikalla ryöstön aloitukseen.', - ['robbery_already'] = '~r~Ryöstö on jo menossa.', - ['no_threat'] = 'you do not pose a threat to the store keeper', + ['shop_robbery'] = 'kaupan ryöstö', + ['press_to_rob'] = 'paina ~INPUT_CONTEXT~ ~o~ryöstääksesi~s~ kaupan ~b~%s~s~', + ['robbery_timer'] = 'kauppa ryöstö: ~r~%s~s~ sekunttia jäljellä', + ['recently_robbed'] = 'tämä kauppa ryöstettiin vasta. Odota ~y~%s~s~ sekunttia että voit ryöstää.', + ['rob_in_prog'] = '~r~ryöstö menossa kohteessa ~b~%s~s~', + ['started_to_rob'] = 'sinä aloitit ryöstään ~y~%s~s~', + ['alarm_triggered'] = 'hälyytys laukaistu!', + ['robbery_complete'] = '~r~Ryöstö onnistui~s~, sinä ~o~varastit~s~ ~g~$%s~s~', + ['robbery_complete_at'] = '~r~Ryöstö ohitse kohteessa ~y~%s~s~', + ['robbery_cancelled'] = 'ryöstö keskeytyi!', + ['robbery_cancelled_at'] = '~r~Ryöstö kohteessa ~b~%s~s~ keskeytyi!', + ['min_police'] = 'kaupungissa pitää olla vähintää ~b~%s poliisia~s~ paikalla ryöstön aloitukseen.', + ['robbery_already'] = '~r~Ryöstö on jo menossa.', + ['no_threat'] = 'you do not pose a threat to the store keeper', } From a11170f1566a358260ca9079e6a2393c04a8ff89 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 15 Mar 2019 13:12:09 +0100 Subject: [PATCH 2159/3224] 2 space indent --- locales/br.lua | 10 +++++----- locales/de.lua | 10 +++++----- locales/en.lua | 10 +++++----- locales/es.lua | 10 +++++----- locales/fi.lua | 10 +++++----- locales/fr.lua | 10 +++++----- locales/sv.lua | 10 +++++----- 7 files changed, 35 insertions(+), 35 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index 7cb98fad..7b64a402 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,7 +1,7 @@ Locales['br'] = { - ['invalid_amount'] = '~r~Quantidade inválida', - ['deposit_money'] = 'Você depósitou ~g~$%s~s~', - ['withdraw_money'] = 'Você retirou ~g~$%s~s~', - ['press_e_atm'] = 'pressione ~INPUT_PICKUP~ para depósitos ou retiradas do ~g~ATM~s~.', - ['atm_blip'] = 'ATM', + ['invalid_amount'] = '~r~Quantidade inválida', + ['deposit_money'] = 'Você depósitou ~g~$%s~s~', + ['withdraw_money'] = 'Você retirou ~g~$%s~s~', + ['press_e_atm'] = 'pressione ~INPUT_PICKUP~ para depósitos ou retiradas do ~g~ATM~s~.', + ['atm_blip'] = 'ATM', } diff --git a/locales/de.lua b/locales/de.lua index 370df7b8..e78878c7 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -1,7 +1,7 @@ Locales['de'] = { - ['invalid_amount'] = '~r~Ungültiger Betrag', - ['deposit_money'] = 'eingezahlt ~g~$%s~s~', - ['withdraw_money'] = 'abgehoben ~g~$%s~s~', - ['press_e_atm'] = 'Drücke ~INPUT_PICKUP~ um auf den ~g~ATM~s~ zuzugreifen.', - ['atm_blip'] = 'ATM', + ['invalid_amount'] = '~r~Ungültiger Betrag', + ['deposit_money'] = 'eingezahlt ~g~$%s~s~', + ['withdraw_money'] = 'abgehoben ~g~$%s~s~', + ['press_e_atm'] = 'Drücke ~INPUT_PICKUP~ um auf den ~g~ATM~s~ zuzugreifen.', + ['atm_blip'] = 'ATM', } diff --git a/locales/en.lua b/locales/en.lua index bc0bba20..3bfe4a73 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,7 +1,7 @@ Locales['en'] = { - ['invalid_amount'] = '~r~That\'s an invalid amount of money~s~', - ['deposit_money'] = 'you have deposited ~g~$%s~s~', - ['withdraw_money'] = 'you have withdrawn ~g~$%s~s~', - ['press_e_atm'] = 'press ~INPUT_PICKUP~ for deposit or withdrawal from ~g~ATM~s~', - ['atm_blip'] = 'ATM', + ['invalid_amount'] = '~r~That\'s an invalid amount of money~s~', + ['deposit_money'] = 'you have deposited ~g~$%s~s~', + ['withdraw_money'] = 'you have withdrawn ~g~$%s~s~', + ['press_e_atm'] = 'press ~INPUT_PICKUP~ for deposit or withdrawal from ~g~ATM~s~', + ['atm_blip'] = 'ATM', } diff --git a/locales/es.lua b/locales/es.lua index 6448fe18..b9cda8b5 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -1,7 +1,7 @@ Locales['es'] = { - ['invalid_amount'] = '~r~Cantidad no válida', - ['deposit_money'] = 'has depositado ~g~€%s~s~', - ['withdraw_money'] = 'has retirado ~g~€%s~s~', - ['press_e_atm'] = 'presiona ~INPUT_PICKUP~ para depositar o retirar ~g~cash~s~.', - ['atm_blip'] = 'ATM', + ['invalid_amount'] = '~r~Cantidad no válida', + ['deposit_money'] = 'has depositado ~g~€%s~s~', + ['withdraw_money'] = 'has retirado ~g~€%s~s~', + ['press_e_atm'] = 'presiona ~INPUT_PICKUP~ para depositar o retirar ~g~cash~s~.', + ['atm_blip'] = 'ATM', } diff --git a/locales/fi.lua b/locales/fi.lua index 1268dfd2..dfa61c0e 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -1,7 +1,7 @@ Locales['fi'] = { - ['invalid_amount'] = '~r~Tuo oli virheellinen summa!~s~', - ['deposit_money'] = 'sinä talletit ~g~$%s~s~', - ['withdraw_money'] = 'sinä nostit ~g~$%s~s~', - ['press_e_atm'] = 'paina ~INPUT_PICKUP~ talletaaksesi tai nostaaksesi ~g~Automaatilta~s~', - ['atm_blip'] = 'Automaatti', + ['invalid_amount'] = '~r~Tuo oli virheellinen summa!~s~', + ['deposit_money'] = 'sinä talletit ~g~$%s~s~', + ['withdraw_money'] = 'sinä nostit ~g~$%s~s~', + ['press_e_atm'] = 'paina ~INPUT_PICKUP~ talletaaksesi tai nostaaksesi ~g~Automaatilta~s~', + ['atm_blip'] = 'Automaatti', } diff --git a/locales/fr.lua b/locales/fr.lua index a1486017..48f32a92 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,7 +1,7 @@ Locales['fr'] = { - ['invalid_amount'] = '~r~Montant invalide~s~', - ['deposit_money'] = 'vous avez déposé ~g~$%s~s~', - ['withdraw_money'] = 'vous avez retiré ~g~$%s~s~', - ['press_e_atm'] = 'appuyez sur ~INPUT_PICKUP~ pour déposer ou retirer du ~g~cash~s~.', - ['atm_blip'] = 'ATM', + ['invalid_amount'] = '~r~Montant invalide~s~', + ['deposit_money'] = 'vous avez déposé ~g~$%s~s~', + ['withdraw_money'] = 'vous avez retiré ~g~$%s~s~', + ['press_e_atm'] = 'appuyez sur ~INPUT_PICKUP~ pour déposer ou retirer du ~g~cash~s~.', + ['atm_blip'] = 'ATM', } \ No newline at end of file diff --git a/locales/sv.lua b/locales/sv.lua index 67e8cc25..9567b45a 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -1,7 +1,7 @@ Locales['sv'] = { - ['invalid_amount'] = '~r~Det är en ogiltig summa pengar~s~', - ['deposit_money'] = 'du satte in ~g~$%s~s~', - ['withdraw_money'] = 'du har tagit ut ~g~$%s~s~', - ['press_e_atm'] = 'tryck ~INPUT_PICKUP~ för att komma åt denna ~g~ATM~s~', - ['atm_blip'] = 'bankomat', + ['invalid_amount'] = '~r~Det är en ogiltig summa pengar~s~', + ['deposit_money'] = 'du satte in ~g~$%s~s~', + ['withdraw_money'] = 'du har tagit ut ~g~$%s~s~', + ['press_e_atm'] = 'tryck ~INPUT_PICKUP~ för att komma åt denna ~g~ATM~s~', + ['atm_blip'] = 'bankomat', } From 3714e5e268f9d30532a83a4f6b0db1ec380d04ec Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 15 Mar 2019 13:12:37 +0100 Subject: [PATCH 2160/3224] 2 space indent --- locales/br.lua | 4 ++-- locales/de.lua | 4 ++-- locales/en.lua | 4 ++-- locales/fi.lua | 4 ++-- locales/fr.lua | 4 ++-- locales/pl.lua | 4 ++-- locales/sv.lua | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index fbb6a826..5f24ee58 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,4 +1,4 @@ Locales['br'] = { - ['used_bread'] = 'você comeu ~y~1x~s~ ~b~pão~s~', - ['used_water'] = 'você tomou ~y~1x~s~ ~b~água~s~', + ['used_bread'] = 'você comeu ~y~1x~s~ ~b~pão~s~', + ['used_water'] = 'você tomou ~y~1x~s~ ~b~água~s~', } \ No newline at end of file diff --git a/locales/de.lua b/locales/de.lua index 53d6d981..52da2604 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -1,4 +1,4 @@ Locales['de'] = { - ['used_bread'] = 'du hast ~y~1x~s~ ~b~Brot gegessen~s~', - ['used_water'] = 'du hast ~y~1x~s~ ~b~Wasser getrunken~s~', + ['used_bread'] = 'du hast ~y~1x~s~ ~b~Brot gegessen~s~', + ['used_water'] = 'du hast ~y~1x~s~ ~b~Wasser getrunken~s~', } \ No newline at end of file diff --git a/locales/en.lua b/locales/en.lua index 14931fd6..52102ace 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,4 +1,4 @@ Locales['en'] = { - ['used_bread'] = 'you have used ~y~1x~s~ ~b~bread~s~', - ['used_water'] = 'you have used ~y~1x~s~ ~b~water~s~', + ['used_bread'] = 'you have used ~y~1x~s~ ~b~bread~s~', + ['used_water'] = 'you have used ~y~1x~s~ ~b~water~s~', } \ No newline at end of file diff --git a/locales/fi.lua b/locales/fi.lua index ec29041d..aed8ec53 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -1,4 +1,4 @@ Locales['fi'] = { - ['used_bread'] = 'sinä söit ~y~1x~s~ ~b~leipä~s~', - ['used_water'] = 'sinä joit ~y~1x~s~ ~b~vesi~s~', + ['used_bread'] = 'sinä söit ~y~1x~s~ ~b~leipä~s~', + ['used_water'] = 'sinä joit ~y~1x~s~ ~b~vesi~s~', } \ No newline at end of file diff --git a/locales/fr.lua b/locales/fr.lua index c388f04c..5cabcc3f 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,4 +1,4 @@ Locales['fr'] = { - ['used_bread'] = 'vous avez utilisé ~y~1x~s~ ~b~pain~s~', - ['used_water'] = 'vous avez utilisé ~y~1x~s~ ~b~eau~s~', + ['used_bread'] = 'vous avez utilisé ~y~1x~s~ ~b~pain~s~', + ['used_water'] = 'vous avez utilisé ~y~1x~s~ ~b~eau~s~', } \ No newline at end of file diff --git a/locales/pl.lua b/locales/pl.lua index 2ff3fa3d..33f28d83 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -1,4 +1,4 @@ Locales['pl'] = { - ['used_bread'] = 'zjadłeś/aś ~y~1x~s~ ~b~chleb~s~', - ['used_water'] = 'wypiłeś/aś ~y~1x~s~ ~b~woda~s~', + ['used_bread'] = 'zjadłeś/aś ~y~1x~s~ ~b~chleb~s~', + ['used_water'] = 'wypiłeś/aś ~y~1x~s~ ~b~woda~s~', } \ No newline at end of file diff --git a/locales/sv.lua b/locales/sv.lua index b0f9d316..a62e9f6d 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -1,4 +1,4 @@ Locales['sv'] = { - ['used_bread'] = 'du käkade upp en bit ~b~bröd~s~', - ['used_water'] = 'du drack upp en ~b~vattenflaska~s~', + ['used_bread'] = 'du käkade upp en bit ~b~bröd~s~', + ['used_water'] = 'du drack upp en ~b~vattenflaska~s~', } \ No newline at end of file From 5c191995f7ffccab01e0600191661579991f4da9 Mon Sep 17 00:00:00 2001 From: Ffrankys <44752471+Ffrankys@users.noreply.github.com> Date: Fri, 15 Mar 2019 22:39:11 +0100 Subject: [PATCH 2161/3224] Update de_esx_jobs.sql --- localization/de_esx_jobs.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/localization/de_esx_jobs.sql b/localization/de_esx_jobs.sql index 2e68f197..9ea10827 100644 --- a/localization/de_esx_jobs.sql +++ b/localization/de_esx_jobs.sql @@ -41,7 +41,7 @@ INSERT INTO `items` (`name`, `label`, `limit`) VALUES ('petrol', 'Öl', 24), ('petrol_raffin', 'bearbeitetes Öl', 24), ('essence', 'Benzin', 24), - ('whool', 'Wolle', 40), + ('wool', 'Wolle', 40), ('fabric', 'Tuch', 80), ('clothe', 'Kleidung', 40) ; From 9ab635c3004aad95e50510bd92ddc2a45dd0e808 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 17 Mar 2019 00:14:55 +0100 Subject: [PATCH 2162/3224] Removed unused config entry --- config.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/config.lua b/config.lua index 12402226..8a37c47c 100644 --- a/config.lua +++ b/config.lua @@ -17,7 +17,6 @@ Config.EarlyRespawnTimer = 2 * minute -- Time til respawn is available Config.BleedoutTimer = 10 * minute -- Time til the player bleeds out Config.EnablePlayerManagement = false -Config.EnableSocietyOwnedVehicles = false Config.RemoveWeaponsAfterRPDeath = true Config.RemoveCashAfterRPDeath = true From 3f513e2d1bb66aa631393b30c23a4f9811dae999 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 18 Mar 2019 12:04:08 +0100 Subject: [PATCH 2163/3224] Fixed multihospital thread --- client/job.lua | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/client/job.lua b/client/job.lua index 4df79cb0..12b706fc 100644 --- a/client/job.lua +++ b/client/job.lua @@ -14,11 +14,10 @@ function OpenAmbulanceActionsMenu() ESX.UI.Menu.CloseAll() - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'ambulance_actions', - { - title = _U('ambulance'), - align = 'top-left', - elements = elements + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'ambulance_actions', { + title = _U('ambulance'), + align = 'top-left', + elements = elements }, function(data, menu) if data.current.value == 'cloakroom' then OpenCloakroomMenu() @@ -44,11 +43,10 @@ function OpenMobileAmbulanceActionsMenu() } }, function(data, menu) if data.current.value == 'citizen_interaction' then - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'citizen_interaction', - { - title = _U('ems_menu_title'), - align = 'top-left', - elements = { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'citizen_interaction', { + title = _U('ems_menu_title'), + align = 'top-left', + elements = { {label = _U('ems_menu_revive'), value = 'revive'}, {label = _U('ems_menu_small'), value = 'small'}, {label = _U('ems_menu_big'), value = 'big'}, @@ -311,10 +309,10 @@ Citizen.CreateThread(function() TriggerEvent('esx_ambulancejob:hasExitedMarker', LastHospital, LastPart, LastPartNum) end - if letSleep then - Citizen.Wait(500) - end + end + if letSleep then + Citizen.Wait(500) end end end) @@ -417,10 +415,9 @@ AddEventHandler('esx_ambulancejob:putInVehicle', function() end) function OpenCloakroomMenu() - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'cloakroom', - { - title = _U('cloakroom'), - align = 'top-left', + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'cloakroom', { + title = _U('cloakroom'), + align = 'top-left', elements = { {label = _U('ems_clothes_civil'), value = 'citizen_wear'}, {label = _U('ems_clothes_ems'), value = 'ambulance_wear'}, @@ -737,8 +734,7 @@ function OpenShopMenu(elements, restoreCoords, shopCoords) elements = elements }, function(data, menu) - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop_confirm', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop_confirm', { title = _U('vehicleshop_confirm', data.current.name, data.current.price), align = 'top-left', elements = { @@ -867,8 +863,7 @@ end function OpenPharmacyMenu() ESX.UI.Menu.CloseAll() - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'pharmacy', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'pharmacy', { title = _U('pharmacy_menu_title'), align = 'top-left', elements = { From 161ced8393036abb894283bf55378c11fee1bad3 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 18 Mar 2019 13:16:22 +0100 Subject: [PATCH 2164/3224] Fix multiple hospital thread attempt 2 --- client/job.lua | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/client/job.lua b/client/job.lua index 12b706fc..85be6428 100644 --- a/client/job.lua +++ b/client/job.lua @@ -287,28 +287,28 @@ Citizen.CreateThread(function() end end - -- Logic for exiting & entering markers - if isInMarker and not HasAlreadyEnteredMarker or (isInMarker and (LastHospital ~= currentHospital or LastPart ~= currentPart or LastPartNum ~= currentPartNum)) then + end - if - (LastHospital ~= nil and LastPart ~= nil and LastPartNum ~= nil) and - (LastHospital ~= currentHospital or LastPart ~= currentPart or LastPartNum ~= currentPartNum) - then - TriggerEvent('esx_ambulancejob:hasExitedMarker', LastHospital, LastPart, LastPartNum) - hasExited = true - end + -- Logic for exiting & entering markers + if isInMarker and not HasAlreadyEnteredMarker or (isInMarker and (LastHospital ~= currentHospital or LastPart ~= currentPart or LastPartNum ~= currentPartNum)) then - HasAlreadyEnteredMarker, LastHospital, LastPart, LastPartNum = true, currentHospital, currentPart, currentPartNum - - TriggerEvent('esx_ambulancejob:hasEnteredMarker', currentHospital, currentPart, currentPartNum) - - end - - if not hasExited and not isInMarker and HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = false + if + (LastHospital ~= nil and LastPart ~= nil and LastPartNum ~= nil) and + (LastHospital ~= currentHospital or LastPart ~= currentPart or LastPartNum ~= currentPartNum) + then TriggerEvent('esx_ambulancejob:hasExitedMarker', LastHospital, LastPart, LastPartNum) + hasExited = true end + HasAlreadyEnteredMarker, LastHospital, LastPart, LastPartNum = true, currentHospital, currentPart, currentPartNum + + TriggerEvent('esx_ambulancejob:hasEnteredMarker', currentHospital, currentPart, currentPartNum) + + end + + if not hasExited and not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent('esx_ambulancejob:hasExitedMarker', LastHospital, LastPart, LastPartNum) end if letSleep then From 95c662d0eb9cc8f3abb967bc71b98f44785ca7de Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Mon, 18 Mar 2019 22:25:38 -0400 Subject: [PATCH 2165/3224] Fixed #17 --- server/main.lua | 142 ++++++++++++++++++++++++------------------------ 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/server/main.lua b/server/main.lua index 1398997a..7b3ca55c 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,71 +1,71 @@ -AddEventHandler('es:invalidCommandHandler', function(source, command_args, user) - CancelEvent() - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', _U('unknown_command', command_args[1]) } }) -end) - -AddEventHandler('chatMessage', function(source, name, message) - if string.sub(message, 1, string.len('/')) ~= '/' then - CancelEvent() - - if Config.EnableESXIdentity then name = GetCharacterName(source) end - TriggerClientEvent('chat:addMessage', -1, { args = { _U('ooc_prefix', name), message }, color = { 128, 128, 128 } }) - end -end) - -RegisterCommand('twt', function(source, args, rawCommand) - if source == 0 then - print('esx_rpchat: you can\'t use this command from rcon!') - return - end - - args = table.concat(args, ' ') - local name = GetPlayerName(source) - if Config.EnableESXIdentity then name = GetCharacterName(source) end - - TriggerClientEvent('chat:addMessage', -1, { args = { _U('twt_prefix', name), args }, color = { 0, 153, 204 } }) - print(('%s: %s'):format(name, args)) -end, false) - -RegisterCommand('me', function(source, args, rawCommand) - if source == 0 then - print('esx_rpchat: you can\'t use this command from rcon!') - return - end - - args = table.concat(args, ' ') - local name = GetPlayerName(source) - if Config.EnableESXIdentity then name = GetCharacterName(source) end - - TriggerClientEvent('esx_rpchat:sendProximityMessage', -1, source, _U('me_prefix', name), args, { 255, 0, 0 }) - print(('%s: %s'):format(name, args)) -end, false) - -RegisterCommand('do', function(source, args, rawCommand) - if source == 0 then - print('esx_rpchat: you can\'t use this command from rcon!') - return - end - - args = table.concat(args, ' ') - local name = GetPlayerName(source) - if Config.EnableESXIdentity then name = GetCharacterName(source) end - - TriggerClientEvent('esx_rpchat:sendProximityMessage', -1, source, _U('do_prefix', name), args, { 0, 0, 255 }) - print(('%s: %s'):format(name, args)) -end, false) - -function GetCharacterName(source) - local result = MySQL.Sync.fetchAll('SELECT firstname, lastname FROM users WHERE identifier = @identifier', { - ['@identifier'] = GetPlayerIdentifiers(source)[1] - }) - - if result[1] and result[1].firstname and result[1].lastname then - if Config.OnlyFirstname then - return result[1].firstname - else - return ('%s %s'):format(result[1].firstname, result[1].lastname) - end - else - return GetPlayerName(source) - end -end +AddEventHandler('es:invalidCommandHandler', function(source, command_args, user) + CancelEvent() + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', _U('unknown_command', command_args[1]) } }) +end) + +AddEventHandler('chatMessage', function(source, name, message) + if string.sub(message, 1, string.len('/')) ~= '/' then + CancelEvent() + + if Config.EnableESXIdentity then name = GetCharacterName(source) end + TriggerClientEvent('chat:addMessage', -1, { args = { _U('ooc_prefix', name), message }, color = { 128, 128, 128 } }) + end +end) + +RegisterCommand('twt', function(source, args, rawCommand) + if source == 0 then + print('esx_rpchat: you can\'t use this command from rcon!') + return + end + + args = table.concat(args, ' ') + local name = GetPlayerName(source) + if Config.EnableESXIdentity then name = GetCharacterName(source) end + + TriggerClientEvent('chat:addMessage', -1, { args = { _U('twt_prefix', name), args }, color = { 0, 153, 204 } }) + --print(('%s: %s'):format(name, args)) +end, false) + +RegisterCommand('me', function(source, args, rawCommand) + if source == 0 then + print('esx_rpchat: you can\'t use this command from rcon!') + return + end + + args = table.concat(args, ' ') + local name = GetPlayerName(source) + if Config.EnableESXIdentity then name = GetCharacterName(source) end + + TriggerClientEvent('esx_rpchat:sendProximityMessage', -1, source, _U('me_prefix', name), args, { 255, 0, 0 }) + --print(('%s: %s'):format(name, args)) +end, false) + +RegisterCommand('do', function(source, args, rawCommand) + if source == 0 then + print('esx_rpchat: you can\'t use this command from rcon!') + return + end + + args = table.concat(args, ' ') + local name = GetPlayerName(source) + if Config.EnableESXIdentity then name = GetCharacterName(source) end + + TriggerClientEvent('esx_rpchat:sendProximityMessage', -1, source, _U('do_prefix', name), args, { 0, 0, 255 }) + --print(('%s: %s'):format(name, args)) +end, false) + +function GetCharacterName(source) + local result = MySQL.Sync.fetchAll('SELECT firstname, lastname FROM users WHERE identifier = @identifier', { + ['@identifier'] = GetPlayerIdentifiers(source)[1] + }) + + if result[1] and result[1].firstname and result[1].lastname then + if Config.OnlyFirstname then + return result[1].firstname + else + return ('%s %s'):format(result[1].firstname, result[1].lastname) + end + else + return GetPlayerName(source) + end +end From edc8bf4dd9797549cee9d78ed5f45638e6ce5a10 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Mon, 18 Mar 2019 22:27:36 -0400 Subject: [PATCH 2166/3224] Prepare Repo for 1.3.1 Release --- __resource.lua | 60 +++++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/__resource.lua b/__resource.lua index d5cea34f..58c0093b 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,30 +1,30 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' - -description 'ESX RP Chat' - -version '1.3.0' - -server_scripts { - '@mysql-async/lib/MySQL.lua', - '@es_extended/locale.lua', - 'locales/sv.lua', - 'locales/en.lua', - 'locales/fi.lua', - 'locales/fr.lua', - 'locales/cs.lua', - 'config.lua', - 'server/main.lua' -} - -client_scripts { - '@es_extended/locale.lua', - 'locales/sv.lua', - 'locales/en.lua', - 'locales/fi.lua', - 'locales/fr.lua', - 'locales/cs.lua', - 'config.lua', - 'client/main.lua' -} - -dependency 'es_extended' +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + +description 'ESX RP Chat' + +version '1.3.1' + +server_scripts { + '@mysql-async/lib/MySQL.lua', + '@es_extended/locale.lua', + 'locales/sv.lua', + 'locales/en.lua', + 'locales/fi.lua', + 'locales/fr.lua', + 'locales/cs.lua', + 'config.lua', + 'server/main.lua' +} + +client_scripts { + '@es_extended/locale.lua', + 'locales/sv.lua', + 'locales/en.lua', + 'locales/fi.lua', + 'locales/fr.lua', + 'locales/cs.lua', + 'config.lua', + 'client/main.lua' +} + +dependency 'es_extended' From 9b720acb607d616a1e6f890644f65011ae62829e Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 19 Mar 2019 22:22:30 +0100 Subject: [PATCH 2167/3224] Workaround for memory leak #19 --- client/main.lua | 55 ++++++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/client/main.lua b/client/main.lua index eb5fa08c..f89fb1aa 100644 --- a/client/main.lua +++ b/client/main.lua @@ -113,32 +113,39 @@ function OpenMenu(submitCb, cancelCb, restrict) cancelCb(data, menu) end end, function(data, menu) - TriggerEvent('skinchanger:getSkin', function(skin) - zoomOffset = data.current.zoomOffset - camOffset = data.current.camOffset + local skin, components, maxVals - if skin[data.current.name] ~= data.current.value then - -- Change skin element - TriggerEvent('skinchanger:change', data.current.name, data.current.value) - - -- Update max values - TriggerEvent('skinchanger:getData', function(components, maxVals) - for i=1, #elements, 1 do - local newData = {} - - newData.max = maxVals[elements[i].name] - - if elements[i].textureof ~= nil and data.current.name == elements[i].textureof then - newData.value = 0 - end - - menu.update({name = elements[i].name}, newData) - end - - menu.refresh() - end) - end + TriggerEvent('skinchanger:getSkin', function(getSkin) + skin = getSkin end) + + zoomOffset = data.current.zoomOffset + camOffset = data.current.camOffset + + if skin[data.current.name] ~= data.current.value then + -- Change skin element + TriggerEvent('skinchanger:change', data.current.name, data.current.value) + + -- Update max values + TriggerEvent('skinchanger:getData', function(comp, max) + components, maxVals = comp, max + end) + + local newData = {} + + for i=1, #elements, 1 do + newData = {} + newData.max = maxVals[elements[i].name] + + if elements[i].textureof ~= nil and data.current.name == elements[i].textureof then + newData.value = 0 + end + + menu.update({name = elements[i].name}, newData) + end + + menu.refresh() + end end, function(data, menu) DeleteSkinCam() end) From d7ceb92d562819978d4d43c8308316bffb5d182d Mon Sep 17 00:00:00 2001 From: BackrndSource Date: Wed, 27 Mar 2019 12:36:14 +0000 Subject: [PATCH 2168/3224] Update es.lua --- locales/es.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/locales/es.lua b/locales/es.lua index f31e5e9b..c422abc1 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -1,12 +1,12 @@ Locales['es'] = { ['shop'] = 'tienda', ['shops'] = 'tiendas', - ['press_menu'] = 'presiona ~INPUT_CONTEXT~ para acceder a la tienda.', - ['shop_item'] = '$%s', - ['bought'] = 'you just bought ~y~%sx~s~ ~b~%s~s~ for ~r~$%s~s~', + ['press_menu'] = 'pulsa ~INPUT_CONTEXT~ para comprar en la tienda.', + ['shop_item'] = '%s€', + ['bought'] = 'has comprado ~y~%sx~s~ ~b~%s~s~ por ~r~%s€~s~', ['not_enough'] = 'no tienes ~r~suficiente ~s~ dinero: %s', - ['player_cannot_hold'] = 'you do ~r~not~s~ have enough ~y~free space~s~ in your inventory!', - ['shop_confirm'] = 'buy %sx %s for $%s?', + ['player_cannot_hold'] = 'no tienes ~y~espacio libre~s~ en tu inventario...', + ['shop_confirm'] = '¿Comprar %sx %s por $%s?', ['no'] = 'no', - ['yes'] = 'yes', + ['yes'] = 'si', } From 51b2df94aff1ac31e31256d7a2a81a4e75a51cd2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 30 Mar 2019 08:49:03 +0100 Subject: [PATCH 2169/3224] Fixed IsVehicleEmpty() again --- client/functions.lua | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 5ad1d095..57269725 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -410,11 +410,7 @@ ESX.Game.IsVehicleEmpty = function(vehicle) local passengers = GetVehicleNumberOfPassengers(vehicle) local driverSeatFree = IsVehicleSeatFree(vehicle, -1) - if not driverSeatFree then - passengers = passengers + 1 - end - - return passengers == 0 + return passengers == 0 and driverSeatFree end ESX.Game.GetObjects = function() From cddeba024160164d85f0d37cb9c9c247bd4376f1 Mon Sep 17 00:00:00 2001 From: Jafool <5405476+Jafool@users.noreply.github.com> Date: Mon, 1 Apr 2019 15:09:51 +0200 Subject: [PATCH 2170/3224] Fixed faulty job grade name --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index c56fb164..c295072c 100644 --- a/client/main.lua +++ b/client/main.lua @@ -141,7 +141,7 @@ function OpenMechanicActionsMenu() {label = _U('tow_truck'), value = 'towtruck2'} } - if Config.EnablePlayerManagement and ESX.PlayerData.job and (ESX.PlayerData.job.grade_name == 'boss' or ESX.PlayerData.job.grade_name == 'chef' or ESX.PlayerData.job.grade_name == 'experimente') then + if Config.EnablePlayerManagement and ESX.PlayerData.job and (ESX.PlayerData.job.grade_name == 'boss' or ESX.PlayerData.job.grade_name == 'chief' or ESX.PlayerData.job.grade_name == 'experimente') then table.insert(elements, {label = 'SlamVan', value = 'slamvan3'}) end From b3e7209f019e277584d43cfbd1de4a26c7c80dd1 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 2 Apr 2019 22:36:25 +0200 Subject: [PATCH 2171/3224] Fixed society vulnerabilities --- client/main.lua | 46 +++++++------------------ config.lua | 6 ++-- server/main.lua | 92 +++++++++++++++++++++++++++++-------------------- 3 files changed, 71 insertions(+), 73 deletions(-) diff --git a/client/main.lua b/client/main.lua index 503d69a2..27685af5 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,4 +1,4 @@ -ESX = nil +ESX = nil local base64MoneyIcon = 'data:image/png;base64,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/GMzLdsAADhgaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjUtYzAxNCA3OS4xNTE0ODEsIDIwMTMvMDMvMTMtMTI6MDk6MTUgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgICAgICAgICB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8eG1wOkNyZWF0b3JUb29sPkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cyk8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMTUtMTAtMDlUMjA6MTM6MTYrMDI6MDA8L3htcDpDcmVhdGVEYXRlPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxNS0xMC0wOVQyMDoxNDo0NyswMjowMDwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6TWV0YWRhdGFEYXRlPjIwMTUtMTAtMDlUMjA6MTQ6NDcrMDI6MDA8L3htcDpNZXRhZGF0YURhdGU+CiAgICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2UvcG5nPC9kYzpmb3JtYXQ+CiAgICAgICAgIDxwaG90b3Nob3A6Q29sb3JNb2RlPjM8L3Bob3Rvc2hvcDpDb2xvck1vZGU+CiAgICAgICAgIDxwaG90b3Nob3A6SUNDUHJvZmlsZT5zUkdCIElFQzYxOTY2LTIuMTwvcGhvdG9zaG9wOklDQ1Byb2ZpbGU+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6NmZkNGVlNjgtOWU3Mi1jYTQxLTg5NjMtMWRjMmI2M2EzYWExPC94bXBNTTpJbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD54bXAuZGlkOjZmZDRlZTY4LTllNzItY2E0MS04OTYzLTFkYzJiNjNhM2FhMTwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD54bXAuZGlkOjZmZDRlZTY4LTllNzItY2E0MS04OTYzLTFkYzJiNjNhM2FhMTwveG1wTU06T3JpZ2luYWxEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06SGlzdG9yeT4KICAgICAgICAgICAgPHJkZjpTZXE+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmNyZWF0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDo2ZmQ0ZWU2OC05ZTcyLWNhNDEtODk2My0xZGMyYjYzYTNhYTE8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTUtMTAtMDlUMjA6MTM6MTYrMDI6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpTZXE+CiAgICAgICAgIDwveG1wTU06SGlzdG9yeT4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WFJlc29sdXRpb24+OTYwMDAwLzEwMDAwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj45NjAwMDAvMTAwMDA8L3RpZmY6WVJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U+MTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+MTgwPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjE4MDwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAg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' @@ -123,8 +123,7 @@ function OpenBossMenu(society, close, options) table.insert(elements, {label = _U('salary_management'), value = 'manage_grades'}) end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'boss_actions_' .. society, - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'boss_actions_' .. society, { title = _U('boss_menu'), align = 'top-left', elements = elements @@ -151,8 +150,7 @@ function OpenBossMenu(society, close, options) elseif data.current.value == 'deposit_money' then - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'deposit_money_amount_' .. society, - { + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'deposit_money_amount_' .. society, { title = _U('deposit_amount') }, function(data, menu) @@ -171,8 +169,7 @@ function OpenBossMenu(society, close, options) elseif data.current.value == 'wash_money' then - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'wash_money_amount_' .. society, - { + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'wash_money_amount_' .. society, { title = _U('wash_money_amount') }, function(data, menu) @@ -205,8 +202,7 @@ end function OpenManageEmployeesMenu(society) - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'manage_employees_' .. society, - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'manage_employees_' .. society, { title = _U('employee_management'), align = 'top-left', elements = { @@ -238,7 +234,6 @@ function OpenEmployeeList(society) } for i=1, #employees, 1 do - local gradeLabel = (employees[i].job.grade_label == '' and employees[i].job.label or employees[i].job.grade_label) table.insert(elements.rows, { @@ -257,18 +252,13 @@ function OpenEmployeeList(society) if data.value == 'promote' then menu.close() OpenPromoteMenu(society, employee) - end - - if data.value == 'fire' then - - TriggerEvent('esx:showNotification', _U('you_have_fired', employee.name)) + elseif data.value == 'fire' then + ESX.ShowNotification(_U('you_have_fired', employee.name)) ESX.TriggerServerCallback('esx_society:setJob', function() OpenEmployeeList(society) end, employee.identifier, 'unemployed', 0, 'fire') - end - end, function(data, menu) menu.close() OpenManageEmployeesMenu(society) @@ -295,15 +285,13 @@ function OpenRecruitMenu(society) end end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'recruit_' .. society, - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'recruit_' .. society, { title = _U('recruiting'), align = 'top-left', elements = elements }, function(data, menu) - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'recruit_confirm_' .. society, - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'recruit_confirm_' .. society, { title = _U('do_you_want_to_recruit', data.current.name), align = 'top-left', elements = { @@ -311,19 +299,15 @@ function OpenRecruitMenu(society) {label = _U('yes'), value = 'yes'} } }, function(data2, menu2) - menu2.close() if data2.current.value == 'yes' then - - TriggerEvent('esx:showNotification', _U('you_have_hired', data.current.name)) + ESX.ShowNotification(_U('you_have_hired', data.current.name)) ESX.TriggerServerCallback('esx_society:setJob', function() OpenRecruitMenu(society) end, data.current.identifier, society, 0, 'hire') - end - end, function(data2, menu2) menu2.close() end) @@ -352,20 +336,17 @@ function OpenPromoteMenu(society, employee) }) end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'promote_employee_' .. society, - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'promote_employee_' .. society, { title = _U('promote_employee', employee.name), align = 'top-left', elements = elements }, function(data, menu) menu.close() - - TriggerEvent('esx:showNotification', _U('you_have_promoted', employee.name, data.current.label)) + ESX.ShowNotification(_U('you_have_promoted', employee.name, data.current.label)) ESX.TriggerServerCallback('esx_society:setJob', function() OpenEmployeeList(society) end, employee.identifier, society, data.current.value, 'promote') - end, function(data, menu) menu.close() OpenEmployeeList(society) @@ -390,8 +371,7 @@ function OpenManageGradesMenu(society) }) end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'manage_grades_' .. society, - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'manage_grades_' .. society, { title = _U('salary_management'), align = 'top-left', elements = elements diff --git a/config.lua b/config.lua index f2327406..cb4eb304 100644 --- a/config.lua +++ b/config.lua @@ -1,5 +1,5 @@ -Config = {} +Config = {} -Config.Locale = 'fr' +Config.Locale = 'fr' Config.EnableESXIdentity = false -Config.MaxSalary = 3500 +Config.MaxSalary = 3500 diff --git a/server/main.lua b/server/main.lua index 290fe905..ce4bd4d3 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,6 +1,6 @@ -ESX = nil -Jobs = {} -RegisteredSocieties = {} +ESX = nil +local Jobs = {} +local RegisteredSocieties = {} TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) @@ -95,14 +95,12 @@ AddEventHandler('esx_society:depositMoney', function(society, amount) end if amount > 0 and xPlayer.getMoney() >= amount then - TriggerEvent('esx_addonaccount:getSharedAccount', society.account, function(account) xPlayer.removeMoney(amount) account.addMoney(amount) end) TriggerClientEvent('esx:showNotification', xPlayer.source, _U('have_deposited', ESX.Math.GroupDigits(amount))) - else TriggerClientEvent('esx:showNotification', xPlayer.source, _U('invalid_amount')) end @@ -246,50 +244,70 @@ end) ESX.RegisterServerCallback('esx_society:setJob', function(source, cb, identifier, job, grade, type) local xPlayer = ESX.GetPlayerFromId(source) - local xTarget = ESX.GetPlayerFromIdentifier(identifier) + local isBoss = xPlayer.job.grade_name == 'boss' - if xTarget then - xTarget.setJob(job, grade) + if isBoss then + local xTarget = ESX.GetPlayerFromIdentifier(identifier) - if type == 'hire' then - TriggerClientEvent('esx:showNotification', xTarget.source, _U('you_have_been_hired', job)) - elseif type == 'promote' then - TriggerClientEvent('esx:showNotification', xTarget.source, _U('you_have_been_promoted')) - elseif type == 'fire' then - TriggerClientEvent('esx:showNotification', xTarget.source, _U('you_have_been_fired', xTarget.getJob().label)) - end + if xTarget then + xTarget.setJob(job, grade) + + if type == 'hire' then + TriggerClientEvent('esx:showNotification', xTarget.source, _U('you_have_been_hired', job)) + elseif type == 'promote' then + TriggerClientEvent('esx:showNotification', xTarget.source, _U('you_have_been_promoted')) + elseif type == 'fire' then + TriggerClientEvent('esx:showNotification', xTarget.source, _U('you_have_been_fired', xTarget.getJob().label)) + end - 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) cb() - end) + 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) + cb() + end) + end + else + print(('esx_society: %s attempted to setJob'):format(xPlayer.identifier)) + cb() end end) ESX.RegisterServerCallback('esx_society:setJobSalary', function(source, cb, job, grade, salary) - 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) - Jobs[job].grades[tostring(grade)].salary = salary - local xPlayers = ESX.GetPlayers() + local isBoss = isPlayerBoss(source, job) + local identifier = GetPlayerIdentifier(source, 0) - for i=1, #xPlayers, 1 do - local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + if isBoss 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) + Jobs[job].grades[tostring(grade)].salary = salary + local xPlayers = ESX.GetPlayers() - if xPlayer.job.name == job and xPlayer.job.grade == grade then - xPlayer.setJob(job, grade) - end + for i=1, #xPlayers, 1 do + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + + if xPlayer.job.name == job and xPlayer.job.grade == grade then + xPlayer.setJob(job, grade) + end + end + + cb() + end) + else + print(('esx_society: %s attempted to setJobSalary over config limit!'):format(identifier)) + cb() end - + else + print(('esx_society: %s attempted to setJobSalary'):format(identifier)) cb() - end) + end end) ESX.RegisterServerCallback('esx_society:getOnlinePlayers', function(source, cb) From 3de89dca334cc8973c6844998599dd82b443defb Mon Sep 17 00:00:00 2001 From: AnthonyTCS <32744832+AnthonyTCS@users.noreply.github.com> Date: Wed, 3 Apr 2019 22:18:01 +0200 Subject: [PATCH 2172/3224] Fix freeze screen after failing the first test --- html/scripts.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/html/scripts.js b/html/scripts.js index 07f2e817..20ce760f 100644 --- a/html/scripts.js +++ b/html/scripts.js @@ -91,10 +91,18 @@ $(".btnQuestion").click(function () { $(".btnClose").click(function () { $.post('http://esx_dmvschool/close', JSON.stringify({})); + userAnswer = []; + goodAnswer = []; + questionUsed = []; + questionNumber = 1; }); $(".btnKick").click(function () { $.post('http://esx_dmvschool/kick', JSON.stringify({})); + userAnswer = []; + goodAnswer = []; + questionUsed = []; + questionNumber = 1; }); // Handle Form Submits From 6c83e15b4edd93bd57675defdbdb412c30f41da2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 4 Apr 2019 19:15:30 +0200 Subject: [PATCH 2173/3224] Proper arguments, minor changes --- client/main.lua | 7 ++----- config.lua | 12 ++++++------ 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/client/main.lua b/client/main.lua index aba47778..ca12255b 100644 --- a/client/main.lua +++ b/client/main.lua @@ -135,8 +135,7 @@ function OpenDMVSchoolMenu() ESX.UI.Menu.CloseAll() - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'dmvschool_actions', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'dmvschool_actions', { title = _U('driving_school'), elements = elements, align = 'top-left' @@ -209,7 +208,6 @@ end) -- Display markers Citizen.CreateThread(function() while true do - Citizen.Wait(0) local coords = GetEntityCoords(PlayerPedId()) @@ -219,7 +217,6 @@ Citizen.CreateThread(function() DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) end end - end end) @@ -277,7 +274,7 @@ Citizen.CreateThread(function() while true do Citizen.Wait(0) - if CurrentAction ~= nil then + if CurrentAction then ESX.ShowHelpNotification(CurrentActionMsg) diff --git a/config.lua b/config.lua index ffd216a6..d58e6dd8 100644 --- a/config.lua +++ b/config.lua @@ -2,7 +2,7 @@ Config = {} Config.DrawDistance = 100.0 Config.MaxErrors = 5 Config.SpeedMultiplier = 3.6 -Config.Locale = 'sv' +Config.Locale = 'fr' Config.Prices = { dmv = 500, @@ -62,7 +62,7 @@ Config.CheckPoints = { Action = function(playerPed, vehicle, setCurrentZoneType) Citizen.CreateThread(function() DrawMissionText(_U('stop_for_ped'), 5000) - PlaySound(-1, 'RACE_PLACED', 'HUD_AWARDS', 0, 0, 1) + PlaySound(-1, 'RACE_PLACED', 'HUD_AWARDS', false, 0, true) FreezeEntityPosition(vehicle, true) Citizen.Wait(4000) @@ -79,7 +79,7 @@ Config.CheckPoints = { Citizen.CreateThread(function() DrawMissionText(_U('stop_look_left', Config.SpeedLimits['town']), 5000) - PlaySound(-1, 'RACE_PLACED', 'HUD_AWARDS', 0, 0, 1) + PlaySound(-1, 'RACE_PLACED', 'HUD_AWARDS', false, 0, true) FreezeEntityPosition(vehicle, true) Citizen.Wait(6000) @@ -107,7 +107,7 @@ Config.CheckPoints = { Pos = {x = -73.542, y = -1364.335, z = 27.789}, Action = function(playerPed, vehicle, setCurrentZoneType) DrawMissionText(_U('stop_for_passing'), 5000) - PlaySound(-1, 'RACE_PLACED', 'HUD_AWARDS', 0, 0, 1) + PlaySound(-1, 'RACE_PLACED', 'HUD_AWARDS', false, 0, true) FreezeEntityPosition(vehicle, true) Citizen.Wait(6000) FreezeEntityPosition(vehicle, false) @@ -134,7 +134,7 @@ Config.CheckPoints = { setCurrentZoneType('freeway') DrawMissionText(_U('hway_time', Config.SpeedLimits['freeway']), 5000) - PlaySound(-1, 'RACE_PLACED', 'HUD_AWARDS', 0, 0, 1) + PlaySound(-1, 'RACE_PLACED', 'HUD_AWARDS', false, 0, true) end }, @@ -171,7 +171,7 @@ Config.CheckPoints = { Pos = {x = 1163.603, y = -1841.771, z = 35.679}, Action = function(playerPed, vehicle, setCurrentZoneType) DrawMissionText(_U('gratz_stay_alert'), 5000) - PlaySound(-1, 'RACE_PLACED', 'HUD_AWARDS', 0, 0, 1) + PlaySound(-1, 'RACE_PLACED', 'HUD_AWARDS', false, 0, true) end }, From cae59f4f2528ce319c85271dcdd3b355e01373fa Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 4 Apr 2019 19:18:00 +0200 Subject: [PATCH 2174/3224] Proper css indent --- html/styles.css | 260 ++++++++++++++++++++++++------------------------ 1 file changed, 131 insertions(+), 129 deletions(-) diff --git a/html/styles.css b/html/styles.css index 4653f29a..ad39fba4 100644 --- a/html/styles.css +++ b/html/styles.css @@ -1,185 +1,187 @@ html { - overflow: hidden; - font-family: 'Open Sans', sans-serif; + overflow: hidden; + font-family: 'Open Sans', sans-serif; } .full-screen { - width: 100%; - height:100%; - display: flex; - align-items: center; + width: 100%; + height: 100%; + display: flex; + align-items: center; } .question-container { - width: 70%; - height: 700px; - background-color: #fff; - border: 1px solid #222; - border-radius: 1px; - margin-left: auto; - margin-right: auto; - overflow: hidden; - z-index: 9999999; - display: none; + width: 70%; + height: 700px; + background-color: #fff; + border: 1px solid #222; + border-radius: 1px; + margin-left: auto; + margin-right: auto; + overflow: hidden; + z-index: 9999999; + display: none; } .header { - width:100%; - height: 20%; - background-color: #eee; - display: flex; - flex-direction: row; - flex-wrap: wrap; - justify-content: center; + width: 100%; + height: 20%; + background-color: #eee; + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: center; } .header .logo { - width: 80%; - max-height: 50%; - margin: auto; - margin-bottom: 0; + width: 80%; + max-height: 50%; + margin: auto; + margin-bottom: 0; } .header h1 { - font-size: 2em; - text-align: center; - margin:auto; + font-size: 2em; + text-align: center; + margin: auto; } .body { - width: 100%; - height: 80%; - display: flex; - flex-direction: row; - flex-wrap: wrap; - display: none; + width: 100%; + height: 80%; + display: flex; + flex-direction: row; + flex-wrap: wrap; + display: none; } .content { - display: flex; - flex-direction: column; - align-self: center; - width: 90%; - height: 70%; - margin: auto; - border:none; + display: flex; + flex-direction: column; + align-self: center; + width: 90%; + height: 70%; + margin: auto; + border: none; } .content .logo { - width: auto; - max-height: auto; - margin: auto; - margin-bottom: 0; + width: auto; + max-height: auto; + margin: auto; + margin-bottom: 0; } .content h2, p { - margin: 5px; + margin: 5px; } .buttonspot { - display: flex; - flex-direction: column; - align-self: center; - width: auto; - height: 15%; - margin: auto; - border:none; + display: flex; + flex-direction: column; + align-self: center; + width: auto; + height: 15%; + margin: auto; + border: none; } .buttonspot h2, p { - margin: 5px; + margin: 5px; } .button { - width: 30%; - height: 40px; - align-self: center; - text-align: center; - margin-left: 40px; - margin-right: 40px; - background: #6699ff; - background-image: linear-gradient(to bottom, #6699ff, #4d88ff); - border-radius: 4px; - color: #ffffff; - font-size: 1.5em; - text-decoration: none; + width: 30%; + height: 40px; + align-self: center; + text-align: center; + margin-left: 40px; + margin-right: 40px; + background: #6699ff; + background-image: linear-gradient(to bottom, #6699ff, #4d88ff); + border-radius: 4px; + color: #ffffff; + font-size: 1.5em; + text-decoration: none; } - .form { - display: flex; - flex-direction: row; - justify-content: center; - flex-wrap: wrap; - width: 100%; - margin-top:5px; + display: flex; + flex-direction: row; + justify-content: center; + flex-wrap: wrap; + width: 100%; + margin-top: 5px; } .form div { - margin :auto; - margin-top:5px; - margin-bottom: 5px; - width: 100%; + margin: auto; + margin-top: 5px; + margin-bottom: 5px; + width: 100%; } -.submit{ - align-items: center; - height: 30px; - text-align: center; - width: 30%; - background: #017ebc; - background-image: linear-gradient(to bottom, #6699ff, #4d88ff); - border-radius: 4px; - color: #fff; - font-size: 1.2em; - margin-top: 10px; +.submit { + align-items: center; + height: 30px; + text-align: center; + width: 30%; + background: #017ebc; + background-image: linear-gradient(to bottom, #6699ff, #4d88ff); + border-radius: 4px; + color: #fff; + font-size: 1.2em; + margin-top: 10px; } .barre-progression { - width: 50%; - align-self: center; - height: 10%; - margin: auto; - margin-top: 0; - display: flex; - flex-wrap: wrap; - justify-content: center; - padding: 0; + width: 50%; + align-self: center; + height: 10%; + margin: auto; + margin-top: 0; + display: flex; + flex-wrap: wrap; + justify-content: center; + padding: 0; } -.barre-progression h2{ - width: 100%; - height: 60%; - text-align: center; - display: flex; - justify-content: center; - align-items: center; - margin:0; - color: #6699ff; +.barre-progression h2 { + width: 100%; + height: 60%; + text-align: center; + display: flex; + justify-content: center; + align-items: center; + margin: 0; + color: #6699ff; } .progression { - width: 80%; - border: 0 none; - background: #ddd; - border-radius: 14px; - box-shadow: inset 0px 1px 1px rgba(0,0,0,0.5), 0px 1px 0px rgba(255,255,255,0.2); + width: 80%; + border: 0 none; + background: #ddd; + border-radius: 14px; + box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.5), 0px 1px 0px rgba(255, 255, 255, 0.2); } -.progression::-moz-progress-bar { - background: #FFF; - border-radius: 14px; - box-shadow: inset 0 -2px 4px rgba(0,0,0,0.4), 0 2px 5px 0px rgba(0,0,0,0.3); -} -.progression::-webkit-progress-bar { - background: transparent; -} -.progression::-webkit-progress-value { - background-image: linear-gradient(to bottom, #6699ff, #4d88ff); - border-radius: 14px; - box-shadow: inset 0 -2px 4px rgba(0,0,0,0.4), 0 2px 5px 0px rgba(0,0,0,0.3); -} -.bold-text{ - font-weight: bold; - font-size: 1.3em; +.progression::-moz-progress-bar { + background: #FFF; + border-radius: 14px; + box-shadow: inset 0 -2px 4px rgba(0, 0, 0, 0.4), 0 2px 5px 0px rgba(0, 0, 0, 0.3); +} + +.progression::-webkit-progress-bar { + background: transparent; +} + +.progression::-webkit-progress-value { + background-image: linear-gradient(to bottom, #6699ff, #4d88ff); + border-radius: 14px; + box-shadow: inset 0 -2px 4px rgba(0, 0, 0, 0.4), 0 2px 5px 0px rgba(0, 0, 0, 0.3); +} + +.bold-text { + font-weight: bold; + font-size: 1.3em; } \ No newline at end of file From 4baac86207400488770864582043f6e2579224e0 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 4 Apr 2019 19:22:35 +0200 Subject: [PATCH 2175/3224] Minor changes --- README.md | 2 +- html/scripts.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index bd0143b9..2e5fb53e 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ start esx_dmvschool ### License esx_dmvschool - realistic DMV school for ESX -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2019 Jérémie N'gadi 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. diff --git a/html/scripts.js b/html/scripts.js index 20ce760f..56d70097 100644 --- a/html/scripts.js +++ b/html/scripts.js @@ -9,19 +9,19 @@ var nbPossibleQuestions = 10; // number of questions in database questions.js var lastClick = 0; function getRandomQuestion() { - var random = Math.floor(Math.random() * nbPossibleQuestions) + var random = Math.floor(Math.random() * nbPossibleQuestions); while (true) { if (questionUsed.indexOf(random) === -1) { - break + break; } - random = Math.floor(Math.random() * nbPossibleQuestions) + random = Math.floor(Math.random() * nbPossibleQuestions); } - questionUsed.push(random) + questionUsed.push(random); - return random + return random; } // Partial Functions From 207440ae7521cebd1c248b0e3175a065183e835c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 4 Apr 2019 19:32:13 +0200 Subject: [PATCH 2176/3224] Proper group digits and proper formatting --- client/main.lua | 30 ++++++++++++++++++++++-------- locales/br.lua | 1 + locales/en.lua | 1 + locales/fi.lua | 1 + locales/fr.lua | 1 + locales/pl.lua | 1 + locales/sv.lua | 1 + server/main.lua | 2 +- 8 files changed, 29 insertions(+), 9 deletions(-) diff --git a/client/main.lua b/client/main.lua index ca12255b..8f62976b 100644 --- a/client/main.lua +++ b/client/main.lua @@ -116,20 +116,35 @@ function OpenDMVSchoolMenu() local elements = {} if not ownedLicenses['dmv'] then - table.insert(elements, {label = _U('theory_test') .. ' $' .. Config.Prices['dmv'] .. '', value = 'theory_test'}) + table.insert(elements, { + label = (('%s: %s'):format(_U('theory_test'), _U('school_item', ESX.Math.GroupDigits(Config.Prices['dmv'])))), + value = 'theory_test' + }) end if ownedLicenses['dmv'] then if not ownedLicenses['drive'] then - table.insert(elements, {label = _U('road_test_car') .. ' $' .. Config.Prices['drive'] .. '', value = 'drive_test', type = 'drive'}) + table.insert(elements, { + label = (('%s: %s'):format(_U('road_test_car'), _U('school_item', ESX.Math.GroupDigits(Config.Prices['drive'])))), + value = 'drive_test', + type = 'drive' + }) end if not ownedLicenses['drive_bike'] then - table.insert(elements, {label = _U('road_test_bike') .. ' $' .. Config.Prices['drive_bike'] .. '', value = 'drive_test', type = 'drive_bike'}) + table.insert(elements, { + label = (('%s: %s'):format(_U('road_test_bike'), _U('school_item', ESX.Math.GroupDigits(Config.Prices['drive_bike'])))), + value = 'drive_test', + type = 'drive_bike' + }) end if not ownedLicenses['drive_truck'] then - table.insert(elements, {label = _U('road_test_truck') .. ' $' .. Config.Prices['drive_truck'] .. '', value = 'drive_test', type = 'drive_truck'}) + table.insert(elements, { + label = (('%s: %s'):format(_U('drive_truck'), _U('school_item', ESX.Math.GroupDigits(Config.Prices['drive_truck'])))), + value = 'drive_test', + type = 'drive_truck' + }) end end @@ -160,17 +175,17 @@ RegisterNUICallback('question', function(data, cb) openSection = 'question' }) - cb('OK') + cb() end) RegisterNUICallback('close', function(data, cb) StopTheoryTest(true) - cb('OK') + cb() end) RegisterNUICallback('kick', function(data, cb) StopTheoryTest(false) - cb('OK') + cb() end) AddEventHandler('esx_dmvschool:hasEnteredMarker', function(zone) @@ -275,7 +290,6 @@ Citizen.CreateThread(function() Citizen.Wait(0) if CurrentAction then - ESX.ShowHelpNotification(CurrentActionMsg) if IsControlJustReleased(0, Keys['E']) then diff --git a/locales/br.lua b/locales/br.lua index 47f2fff4..3058b104 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -17,6 +17,7 @@ Locales['br'] = { ['road_test_car'] = 'teste de habilidades de condução', ['road_test_bike'] = 'teste de habilidades da motocicleta', ['road_test_truck'] = 'teste de habilidades de caminhão', + ['school_item'] = '$%s', ['driving_school'] = 'escola de condução', ['press_open_menu'] = 'pressione ~INPUT_CONTEXT~ para abrir o menu', ['driving_school_blip'] = 'escola de condução', diff --git a/locales/en.lua b/locales/en.lua index 6df3f17f..55c3c945 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -17,6 +17,7 @@ Locales['en'] = { ['road_test_car'] = 'driving Test', ['road_test_bike'] = 'motorcycle Skills Test', ['road_test_truck'] = 'truck Skills Test', + ['school_item'] = '$%s', ['driving_school'] = 'driving School', ['press_open_menu'] = 'press ~INPUT_CONTEXT~ to open the menu', ['driving_school_blip'] = 'driving School', diff --git a/locales/fi.lua b/locales/fi.lua index ec8cf1ec..88a6cef7 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -17,6 +17,7 @@ Locales['fi'] = { ['road_test_car'] = 'ajokoe', ['road_test_bike'] = 'moottoripyörä ajokoe', ['road_test_truck'] = 'rekka ajokoe', + ['school_item'] = '$%s', ['driving_school'] = 'Autokoulu', ['press_open_menu'] = 'paina ~INPUT_CONTEXT~ hankkiaksesi ajokortin', ['driving_school_blip'] = 'Autokoulu', diff --git a/locales/fr.lua b/locales/fr.lua index 8668d3bb..7608d694 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -17,6 +17,7 @@ Locales['fr'] = { ['road_test_car'] = 'examen de conduite [voiture]', ['road_test_bike'] = 'examen de conduite [moto]', ['road_test_truck'] = 'examen de conduite [camion]', + ['school_item'] = '$%s', ['driving_school'] = 'ecole de conduite', ['press_open_menu'] = 'appuyez sur ~INPUT_CONTEXT~ pour ouvrir le menu', ['driving_school_blip'] = 'auto-école', diff --git a/locales/pl.lua b/locales/pl.lua index 703fe405..97e87a69 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -17,6 +17,7 @@ Locales['pl'] = { ['road_test_car'] = 'egzamin praktyczny kat. B', ['road_test_bike'] = 'egzamin praktyczny kat. A', ['road_test_truck'] = 'egzamin praktyczny kat. C', + ['school_item'] = '$%s', ['driving_school'] = 'szkoła jazdy', ['press_open_menu'] = 'wciśnij ~INPUT_CONTEXT~ by otworzyć menu', ['driving_school_blip'] = 'ośrodek egzaminacyjny', diff --git a/locales/sv.lua b/locales/sv.lua index 9171bafe..ff2b8fe9 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -17,6 +17,7 @@ Locales['sv'] = { ['road_test_car'] = 'B-körkort (personbil)', ['road_test_bike'] = 'A-körkort (motorcykel)', ['road_test_truck'] = 'C-körkort (lastbil)', + ['school_item'] = '%s SEK', ['driving_school'] = 'körskola', ['press_open_menu'] = 'tryck ~INPUT_CONTEXT~ för att öppna menyn', ['driving_school_blip'] = 'körskola', diff --git a/server/main.lua b/server/main.lua index dd364795..6b7133b0 100644 --- a/server/main.lua +++ b/server/main.lua @@ -25,5 +25,5 @@ AddEventHandler('esx_dmvschool:pay', function(price) local xPlayer = ESX.GetPlayerFromId(_source) xPlayer.removeMoney(price) - TriggerClientEvent('esx:showNotification', _source, _U('you_paid', price)) + TriggerClientEvent('esx:showNotification', _source, _U('you_paid', ESX.Math.GroupDigits(price))) end) From a03320bd9c6103c65ba2137f010d8d6c00963760 Mon Sep 17 00:00:00 2001 From: Juju <34923523+ThaJuju@users.noreply.github.com> Date: Wed, 10 Apr 2019 19:48:36 -0400 Subject: [PATCH 2177/3224] Update main.lua need a clientS because in all local file we ave an S at the client end --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index ef41e132..4b6db0d9 100644 --- a/server/main.lua +++ b/server/main.lua @@ -2,7 +2,7 @@ ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) -TriggerEvent('esx_phone:registerNumber', 'realestateagent', _U('client'), false, false) +TriggerEvent('esx_phone:registerNumber', 'realestateagent', _U('clients'), false, false) TriggerEvent('esx_society:registerSociety', 'realestateagent', _U('realtors'), 'society_realestateagent', 'society_realestateagent', 'society_realestateagent', {type = 'private'}) RegisterServerEvent('esx_realestateagentjob:revoke') From 17cbed02633992d08049ab45ff9c1651bed8fb50 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 13 Apr 2019 23:00:26 +0200 Subject: [PATCH 2178/3224] Added table module, thanks to Gizz MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Jérémie N'gadi --- __resource.lua | 2 + common/modules/table.lua | 132 +++++++++++++++++++++++++++++++++++++++ server/main.lua | 5 +- 3 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 common/modules/table.lua diff --git a/__resource.lua b/__resource.lua index cfa44c60..953bf74a 100644 --- a/__resource.lua +++ b/__resource.lua @@ -29,6 +29,7 @@ server_scripts { 'server/commands.lua', 'common/modules/math.lua', + 'common/modules/table.lua', 'common/functions.lua' } @@ -57,6 +58,7 @@ client_scripts { 'client/modules/streaming.lua', 'common/modules/math.lua', + 'common/modules/table.lua', 'common/functions.lua' } diff --git a/common/modules/table.lua b/common/modules/table.lua new file mode 100644 index 00000000..fa65baa4 --- /dev/null +++ b/common/modules/table.lua @@ -0,0 +1,132 @@ +-- nil proof alternative to #table +function ESX.Table.SizeOf(table) + local keys = {} + + for k,v in pairs(table) do + table.insert(keys, tonumber(k)) + end + + table.sort(keys, function(a,b) return a < b end) + + if #keys > 0 then + return keys[#keys] + else + return 0 + end +end + +function ESX.Table.IndexOf(table, value) + for i=1, #table, 1 do + if table[i] == value then + return i + end + end + + return -1 +end + +function ESX.Table.LastIndexOf(table, value) + for i=#table, 1, -1 do + if table[i] == value then + return i + end + end + + return -1 +end + +function ESX.Table.Find(table, cb) + for i=1, #table, 1 do + if cb(table[i]) then + return table[i] + end + end + + return nil +end + +function ESX.Table.FindIndex(table, cb) + for i=1, #table, 1 do + if cb(table[i]) then + return i + end + end + + return -1 +end + +function ESX.Table.Filter(table, cb) + local newTable = {} + + for i=1, #table, 1 do + if cb(table[i]) then + table.insert(newTable, table[i]) + end + end + + return newTable +end + +function ESX.Table.Map(table, cb) + local newTable = {} + + for i=1, #table, 1 do + newTable[i] = cb(table[i], i) + end + + return newTable +end + +function ESX.Table.Reverse(table) + local newTable = {} + + for i=#table, 1, -1 do + table.insert(newTable, table[i]) + end + + return newTable +end + +function ESX.Table.Clone(table) + if type(table) ~= 'table' then return table end + + local meta = getmetatable(table) + local target = {} + + for k,v in pairs(table) do + if type(v) == 'table' then + target[k] = ESX.Table.Clone(v) + else + target[k] = v + end + end + + setmetatable(target, meta) + + return target +end + +function ESX.Table.Concat(table1, table2) + local table3 = ESX.Table.Clone(table1) + + for i=1, #table2, 1 do + table.insert(table3, table2[i]) + end + + return t3 +end + +function ESX.Table.Join(table, sep) + local sep = sep or ',' + local str = '' + + for i=1, #table, 1 do + if i > 1 then + str = str .. sep + end + + str = str .. table[i] + end + + return str +end \ No newline at end of file diff --git a/server/main.lua b/server/main.lua index 4ac0b405..84c3ab20 100644 --- a/server/main.lua +++ b/server/main.lua @@ -17,7 +17,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) table.insert(tasks, function(cb) MySQL.Async.execute('UPDATE `users` SET `name` = @name WHERE `identifier` = @identifier', { ['@identifier'] = player.getIdentifier(), - ['@name'] = userData.playerName + ['@name'] = userData.playerName }, function(rowsChanged) cb() end) @@ -28,7 +28,6 @@ AddEventHandler('es:playerLoaded', function(source, _player) MySQL.Async.fetchAll('SELECT * FROM `user_accounts` WHERE `identifier` = @identifier', { ['@identifier'] = player.getIdentifier() }, function(accounts) - for i=1, #Config.Accounts, 1 do for j=1, #accounts, 1 do if accounts[j].name == Config.Accounts[i] then @@ -38,6 +37,8 @@ AddEventHandler('es:playerLoaded', function(source, _player) label = Config.AccountLabels[accounts[j].name] }) end + + break end end From fb8379899c49adf4715c9f57d7a79420efb5f564 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 13 Apr 2019 23:03:24 +0200 Subject: [PATCH 2179/3224] Missing decleration --- common/modules/table.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/modules/table.lua b/common/modules/table.lua index fa65baa4..62751e56 100644 --- a/common/modules/table.lua +++ b/common/modules/table.lua @@ -1,3 +1,5 @@ +ESX.Table = {} + -- nil proof alternative to #table function ESX.Table.SizeOf(table) local keys = {} From a0cc840ec97aa8b7bac8946c1a3541fb2610a0a0 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 13 Apr 2019 23:15:13 +0200 Subject: [PATCH 2180/3224] Renamed arguments --- common/modules/table.lua | 76 +++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/common/modules/table.lua b/common/modules/table.lua index 62751e56..51126b98 100644 --- a/common/modules/table.lua +++ b/common/modules/table.lua @@ -1,14 +1,16 @@ ESX.Table = {} -- nil proof alternative to #table -function ESX.Table.SizeOf(table) +function ESX.Table.SizeOf(t) local keys = {} - for k,v in pairs(table) do + for k,v in pairs(t) do table.insert(keys, tonumber(k)) end - table.sort(keys, function(a,b) return a < b end) + table.sort(keys, function(a, b) + return a < b + end) if #keys > 0 then return keys[#keys] @@ -17,9 +19,9 @@ function ESX.Table.SizeOf(table) end end -function ESX.Table.IndexOf(table, value) - for i=1, #table, 1 do - if table[i] == value then +function ESX.Table.IndexOf(t, value) + for i=1, #t, 1 do + if t[i] == value then return i end end @@ -27,9 +29,9 @@ function ESX.Table.IndexOf(table, value) return -1 end -function ESX.Table.LastIndexOf(table, value) - for i=#table, 1, -1 do - if table[i] == value then +function ESX.Table.LastIndexOf(t, value) + for i=#t, 1, -1 do + if t[i] == value then return i end end @@ -37,19 +39,19 @@ function ESX.Table.LastIndexOf(table, value) return -1 end -function ESX.Table.Find(table, cb) - for i=1, #table, 1 do - if cb(table[i]) then - return table[i] +function ESX.Table.Find(t, cb) + for i=1, #t, 1 do + if cb(t[i]) then + return t[i] end end return nil end -function ESX.Table.FindIndex(table, cb) - for i=1, #table, 1 do - if cb(table[i]) then +function ESX.Table.FindIndex(t, cb) + for i=1, #t, 1 do + if cb(t[i]) then return i end end @@ -57,45 +59,45 @@ function ESX.Table.FindIndex(table, cb) return -1 end -function ESX.Table.Filter(table, cb) +function ESX.Table.Filter(t, cb) local newTable = {} - for i=1, #table, 1 do - if cb(table[i]) then - table.insert(newTable, table[i]) + for i=1, #t, 1 do + if cb(t[i]) then + table.insert(newTable, t[i]) end end return newTable end -function ESX.Table.Map(table, cb) +function ESX.Table.Map(t, cb) local newTable = {} - for i=1, #table, 1 do - newTable[i] = cb(table[i], i) + for i=1, #t, 1 do + newTable[i] = cb(t[i], i) end return newTable end -function ESX.Table.Reverse(table) +function ESX.Table.Reverse(t) local newTable = {} - for i=#table, 1, -1 do - table.insert(newTable, table[i]) + for i=#t, 1, -1 do + table.insert(newTable, t[i]) end return newTable end -function ESX.Table.Clone(table) - if type(table) ~= 'table' then return table end +function ESX.Table.Clone(t) + if type(t) ~= 'table' then return t end - local meta = getmetatable(table) + local meta = getmetatable(t) local target = {} - for k,v in pairs(table) do + for k,v in pairs(t) do if type(v) == 'table' then target[k] = ESX.Table.Clone(v) else @@ -108,26 +110,26 @@ function ESX.Table.Clone(table) return target end -function ESX.Table.Concat(table1, table2) - local table3 = ESX.Table.Clone(table1) +function ESX.Table.Concat(t1, t2) + local t3 = ESX.Table.Clone(t1) - for i=1, #table2, 1 do - table.insert(table3, table2[i]) + for i=1, #t2, 1 do + table.insert(t3, t2[i]) end return t3 end -function ESX.Table.Join(table, sep) +function ESX.Table.Join(t, sep) local sep = sep or ',' local str = '' - for i=1, #table, 1 do + for i=1, #t, 1 do if i > 1 then str = str .. sep end - str = str .. table[i] + str = str .. t[i] end return str From 16a78f4613f8274f8a69ad925e0e5b116b24be88 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 15 Apr 2019 11:14:37 +0200 Subject: [PATCH 2181/3224] Rewrote .SizeOf() function --- common/modules/table.lua | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/common/modules/table.lua b/common/modules/table.lua index 51126b98..fb862439 100644 --- a/common/modules/table.lua +++ b/common/modules/table.lua @@ -2,21 +2,13 @@ ESX.Table = {} -- nil proof alternative to #table function ESX.Table.SizeOf(t) - local keys = {} + local count = 0 - for k,v in pairs(t) do - table.insert(keys, tonumber(k)) + for _,_ in pairs(t) do + count = count + 1 end - table.sort(keys, function(a, b) - return a < b - end) - - if #keys > 0 then - return keys[#keys] - else - return 0 - end + return count end function ESX.Table.IndexOf(t, value) From 3d27e2b0a67873422d77365089faf53cfa7ea888 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 17 Apr 2019 11:38:12 +0200 Subject: [PATCH 2182/3224] Indent cleanup --- client/functions.lua | 10 +++------- server/functions.lua | 13 ++----------- server/main.lua | 28 ++-------------------------- 3 files changed, 7 insertions(+), 44 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 57269725..ac6a6109 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1138,7 +1138,7 @@ ESX.ShowInventory = function() local players = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) local foundPlayers = false local elements = {} - + for i=1, #players, 1 do if players[i] ~= PlayerId() then foundPlayers = true @@ -1168,7 +1168,7 @@ ESX.ShowInventory = function() for i=1, #players, 1 do if players[i] ~= PlayerId() then - + if players[i] == data2.current.player then foundPlayers = true nearbyPlayer = players[i] @@ -1347,20 +1347,16 @@ end) -- SetTimeout Citizen.CreateThread(function() while true do - Citizen.Wait(0) local currTime = GetGameTimer() for i=1, #ESX.TimeoutCallbacks, 1 do - - if ESX.TimeoutCallbacks[i] ~= nil then + if ESX.TimeoutCallbacks[i] then if currTime >= ESX.TimeoutCallbacks[i].time then ESX.TimeoutCallbacks[i].cb() ESX.TimeoutCallbacks[i] = nil end end - end - end end) diff --git a/server/functions.lua b/server/functions.lua index c61e17b2..621692d8 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -37,14 +37,12 @@ ESX.TriggerServerCallback = function(name, requestId, source, cb, ...) end ESX.SavePlayer = function(xPlayer, cb) - local asyncTasks = {} + local asyncTasks = {} xPlayer.setLastPosition(xPlayer.getCoords()) -- User accounts for i=1, #xPlayer.accounts, 1 do - if ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] ~= xPlayer.accounts[i].money then - table.insert(asyncTasks, function(cb) MySQL.Async.execute('UPDATE user_accounts SET `money` = @money WHERE identifier = @identifier AND name = @name', { ['@money'] = xPlayer.accounts[i].money, @@ -56,16 +54,12 @@ ESX.SavePlayer = function(xPlayer, cb) end) ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] = xPlayer.accounts[i].money - end - end -- Inventory items for i=1, #xPlayer.inventory, 1 do - if ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] ~= xPlayer.inventory[i].count then - table.insert(asyncTasks, function(cb) MySQL.Async.execute('UPDATE user_inventory SET `count` = @count WHERE identifier = @identifier AND item = @item', { ['@count'] = xPlayer.inventory[i].count, @@ -77,9 +71,7 @@ ESX.SavePlayer = function(xPlayer, cb) end) ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] = xPlayer.inventory[i].count - end - end -- Job, loadout and position @@ -96,13 +88,12 @@ ESX.SavePlayer = function(xPlayer, cb) end) Async.parallel(asyncTasks, function(results) - RconPrint('[SAVED] ' .. xPlayer.name .. "\n") + RconPrint('[SAVED] ' .. xPlayer.name .. "^7\n") if cb ~= nil then cb() end end) - end ESX.SavePlayers = function(cb) diff --git a/server/main.lua b/server/main.lua index 84c3ab20..370d135f 100644 --- a/server/main.lua +++ b/server/main.lua @@ -12,7 +12,6 @@ AddEventHandler('es:playerLoaded', function(source, _player) } TriggerEvent('es:getPlayerFromId', _source, function(player) - -- Update user name in DB table.insert(tasks, function(cb) MySQL.Async.execute('UPDATE `users` SET `name` = @name WHERE `identifier` = @identifier', { @@ -78,7 +77,6 @@ AddEventHandler('es:playerLoaded', function(source, _player) end if not found then - table.insert(userData.inventory, { name = k, count = 0, @@ -90,7 +88,6 @@ AddEventHandler('es:playerLoaded', function(source, _player) }) local scope = function(item, identifier) - table.insert(tasks2, function(cb2) MySQL.Async.execute('INSERT INTO user_inventory (identifier, item, count) VALUES (@identifier, @item, @count)', { ['@identifier'] = identifier, @@ -100,11 +97,9 @@ AddEventHandler('es:playerLoaded', function(source, _player) cb2() end) end) - end scope(k, player.getIdentifier()) - end end @@ -204,11 +199,9 @@ AddEventHandler('es:playerLoaded', function(source, _player) -- Run Tasks Async.parallel(tasks, function(results) - local xPlayer = CreateExtendedPlayer(player, userData.accounts, userData.inventory, userData.job, userData.loadout, userData.playerName, userData.lastPosition) xPlayer.getMissingAccounts(function(missingAccounts) - if #missingAccounts > 0 then for i=1, #missingAccounts, 1 do @@ -237,24 +230,21 @@ AddEventHandler('es:playerLoaded', function(source, _player) }) xPlayer.displayMoney(xPlayer.getMoney()) - end) - end) end) - end) AddEventHandler('playerDropped', function(reason) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) - if xPlayer ~= nil then + if xPlayer then TriggerEvent('esx:playerDropped', _source, reason) ESX.SavePlayer(xPlayer, function() - ESX.Players[_source] = nil + ESX.Players[_source] = nil ESX.LastPlayerData[_source] = nil end) end @@ -303,13 +293,11 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo elseif type == 'item_money' then if itemCount > 0 and sourceXPlayer.getMoney() >= itemCount then - sourceXPlayer.removeMoney(itemCount) targetXPlayer.addMoney (itemCount) TriggerClientEvent('esx:showNotification', _source, _U('gave_money', ESX.Math.GroupDigits(itemCount), targetXPlayer.name)) TriggerClientEvent('esx:showNotification', target, _U('received_money', ESX.Math.GroupDigits(itemCount), sourceXPlayer.name)) - else TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) end @@ -317,13 +305,11 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo elseif type == 'item_account' then if itemCount > 0 and sourceXPlayer.getAccount(itemName).money >= itemCount then - sourceXPlayer.removeAccountMoney(itemName, itemCount) targetXPlayer.addAccountMoney (itemName, itemCount) TriggerClientEvent('esx:showNotification', _source, _U('gave_account_money', ESX.Math.GroupDigits(itemCount), Config.AccountLabels[itemName], targetXPlayer.name)) TriggerClientEvent('esx:showNotification', target, _U('received_account_money', ESX.Math.GroupDigits(itemCount), Config.AccountLabels[itemName], sourceXPlayer.name)) - else TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) end @@ -331,7 +317,6 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo elseif type == 'item_weapon' then if not targetXPlayer.hasWeapon(itemName) then - sourceXPlayer.removeWeapon(itemName) targetXPlayer.addWeapon(itemName, itemCount) @@ -344,14 +329,12 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo TriggerClientEvent('esx:showNotification', _source, _U('gave_weapon', weaponLabel, targetXPlayer.name)) TriggerClientEvent('esx:showNotification', target, _U('received_weapon', weaponLabel, sourceXPlayer.name)) end - else TriggerClientEvent('esx:showNotification', _source, _U('gave_weapon_hasalready', targetXPlayer.name, weaponLabel)) TriggerClientEvent('esx:showNotification', _source, _U('received_weapon_hasalready', sourceXPlayer.name, weaponLabel)) end end - end) RegisterServerEvent('esx:removeInventoryItem') @@ -363,7 +346,6 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if itemCount == nil or itemCount < 1 then TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) else - local xPlayer = ESX.GetPlayerFromId(source) local xItem = xPlayer.getInventoryItem(itemName) @@ -376,7 +358,6 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) ESX.CreatePickup('item_standard', itemName, itemCount, pickupLabel, _source) TriggerClientEvent('esx:showNotification', _source, _U('threw_standard', itemCount, xItem.label)) end - end elseif type == 'item_money' then @@ -384,7 +365,6 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if itemCount == nil or itemCount < 1 then TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) else - local xPlayer = ESX.GetPlayerFromId(source) local playerCash = xPlayer.getMoney() @@ -397,7 +377,6 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) ESX.CreatePickup('item_money', 'money', itemCount, pickupLabel, _source) TriggerClientEvent('esx:showNotification', _source, _U('threw_money', ESX.Math.GroupDigits(itemCount))) end - end elseif type == 'item_account' then @@ -405,7 +384,6 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if itemCount == nil or itemCount < 1 then TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) else - local xPlayer = ESX.GetPlayerFromId(source) local account = xPlayer.getAccount(itemName) @@ -418,7 +396,6 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) ESX.CreatePickup('item_account', itemName, itemCount, pickupLabel, _source) TriggerClientEvent('esx:showNotification', _source, _U('threw_account', ESX.Math.GroupDigits(itemCount), string.lower(account.label))) end - end elseif type == 'item_weapon' then @@ -449,7 +426,6 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) end end - end) RegisterServerEvent('esx:useItem') From debaf54c443e2c1d76c24564e4734750609c986d Mon Sep 17 00:00:00 2001 From: KandaSoranyan <32266067+KandaSoranyan@users.noreply.github.com> Date: Sat, 20 Apr 2019 07:45:28 +0200 Subject: [PATCH 2183/3224] translating missing lfr ocale --- locales/fr.lua | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index ed73dc12..f7c1fedd 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -79,8 +79,8 @@ Locales['fr'] = { ['chat_clear'] = 'vider le chat', ['chat_clear_all'] = 'vider le chat pour tous le monde', ['command_clearinventory'] = 'effacer tout les items de l\'inventaire', - ['command_clearloadout'] = 'remove all weapons from loadout', - ['command_playerid_param'] = 'specify playerId or leave blank for yourself', + ['command_clearloadout'] = 'retirer toutes les armes de l\'équipement', + ['command_playerid_param'] = 'spécifiez un playerid ou laissez vide pour vous-même', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', @@ -163,18 +163,18 @@ Locales['fr'] = { ['weapon_flashlight'] = 'lampe torche', ['gadget_nightvision'] = 'vision nocturne', ['gadget_parachute'] = 'parachute', - ['weapon_flare'] = 'Fusée Détresse', + ['weapon_flare'] = 'fusée Détresse', ['weapon_doubleaction'] = 'double-Action Revolver', -- Weapon Components - ['component_clip_default'] = 'default Grip', - ['component_clip_extended'] = 'extended Grip', - ['component_clip_drum'] = 'drum Magazine', - ['component_clip_box'] = 'box Magazine', - ['component_flashlight'] = 'flashlight', - ['component_scope'] = 'scope', - ['component_scope_advanced'] = 'advanced Scope', - ['component_suppressor'] = 'suppressor', - ['component_grip'] = 'grip', - ['component_luxary_finish'] = 'luxary Weapon Finish', + ['component_clip_default'] = 'chargeur par défaut', + ['component_clip_extended'] = 'chargeur grande capacité', + ['component_clip_drum'] = 'chargeur tambour', + ['component_clip_box'] = 'chargeur très grande capacité', + ['component_flashlight'] = 'torche', + ['component_scope'] = 'viseur', + ['component_scope_advanced'] = 'lunette', + ['component_suppressor'] = 'réducteur de son', + ['component_grip'] = 'poignée', + ['component_luxary_finish'] = 'finission de luxe', } From f3046e599a17d10ac483bd5438793fa99afa6b96 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 22 Apr 2019 11:17:51 +0200 Subject: [PATCH 2184/3224] Fixed indent mistake --- __resource.lua | 4 ++-- locales/fr.lua | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/__resource.lua b/__resource.lua index b9e66cda..bd8d6c69 100644 --- a/__resource.lua +++ b/__resource.lua @@ -8,7 +8,7 @@ server_scripts { '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', 'locales/en.lua', - 'locales/fr.lua', + 'locales/fr.lua', 'locales/sv.lua', 'config.lua', 'server/main.lua' @@ -17,7 +17,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', 'locales/en.lua', - 'locales/fr.lua', + 'locales/fr.lua', 'locales/sv.lua', 'config.lua', 'client/main.lua', diff --git a/locales/fr.lua b/locales/fr.lua index 4306447e..8d8a4656 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -17,7 +17,7 @@ Locales ['fr'] = { ['dealer_sold'] = 'vous avez vendu ~b~%sx~s~ ~y~%s~s~ pour ~g~$%s~s~', -- license - ['license_title'] = 'vous devez posséder une license spécifique vous autorisant à transformer ce produit. Vous pouvez l\'acheter ici.', + ['license_title'] = 'vous devez posséder une license spécifique vous autorisant à transformer ce produit. Vous pouvez l\'acheter ici.', ['license_no'] = 'non', ['license_bought'] = 'vous avez acheté ~b~%s~s~ pour ~r~$%s~s~', ['license_bought_fail'] = 'vous ne pouvez pas acheter ~b~%s~s~!', From 166d8c17a6f5cd78f0bf1264c795abd06457274a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 22 Apr 2019 11:36:49 +0200 Subject: [PATCH 2185/3224] Ignore items not registered in "items" table --- server/main.lua | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/server/main.lua b/server/main.lua index 370d135f..3f0a4d73 100644 --- a/server/main.lua +++ b/server/main.lua @@ -51,25 +51,30 @@ AddEventHandler('es:playerLoaded', function(source, _player) MySQL.Async.fetchAll('SELECT * FROM `user_inventory` WHERE `identifier` = @identifier', { ['@identifier'] = player.getIdentifier() }, function(inventory) - local tasks2 = {} - for i=1, #inventory, 1 do - table.insert(userData.inventory, { - name = inventory[i].item, - count = inventory[i].count, - label = ESX.Items[inventory[i].item].label, - limit = ESX.Items[inventory[i].item].limit, - usable = ESX.UsableItemsCallbacks[inventory[i].item] ~= nil, - rare = ESX.Items[inventory[i].item].rare, - canRemove = ESX.Items[inventory[i].item].canRemove - }) + for i=1, #inventory do + local item = ESX.Items[inventory[i].item] + + if item then + table.insert(userData.inventory, { + name = inventory[i].item, + count = inventory[i].count, + label = item.label, + limit = item.limit, + usable = ESX.UsableItemsCallbacks[inventory[i].item] ~= nil, + rare = item.rare, + canRemove = item.canRemove + }) + else + print(('es_extended: invalid item "%s" ignored!'):format(inventory[i].item)) + end end for k,v in pairs(ESX.Items) do local found = false - for j=1, #userData.inventory, 1 do + for j=1, #userData.inventory do if userData.inventory[j].name == k then found = true break From d6323124c233f0cc10cea5396516afb28f15048b Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 22 Apr 2019 11:37:06 +0200 Subject: [PATCH 2186/3224] OneSync note --- config.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.lua b/config.lua index 27e32bb9..95cd34be 100644 --- a/config.lua +++ b/config.lua @@ -10,6 +10,6 @@ Config.DisableWantedLevel = true Config.EnableHud = true -- enable the default hud? Display current job and accounts (black, bank & cash) Config.PaycheckInterval = 7 * 60000 -Config.MaxPlayers = GetConvarInt('sv_maxclients', 32) +Config.MaxPlayers = GetConvarInt('sv_maxclients', 32) -- set this value to 255 if you're running OneSync Config.EnableDebug = false From 1729bc5b48d823741d31fa1eb8f74a716545d9de Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 22 Apr 2019 12:08:10 +0200 Subject: [PATCH 2187/3224] Fixed washing money, closes #77 --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index ce4bd4d3..ad8b4f1a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -112,7 +112,7 @@ AddEventHandler('esx_society:washMoney', function(society, amount) local account = xPlayer.getAccount('black_money') amount = ESX.Math.Round(tonumber(amount)) - if xPlayer.job.name ~= society.name then + if xPlayer.job.name ~= society then print(('esx_society: %s attempted to call washMoney!'):format(xPlayer.identifier)) return end From cde81c4e8e9efc2e0c891e53a1988b80d15df8c8 Mon Sep 17 00:00:00 2001 From: jquiaios Date: Fri, 26 Apr 2019 19:03:01 -0400 Subject: [PATCH 2188/3224] Fix mislocated break in player accounts loop --- server/main.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/main.lua b/server/main.lua index 3f0a4d73..415b703a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -35,9 +35,8 @@ AddEventHandler('es:playerLoaded', function(source, _player) money = accounts[j].money, label = Config.AccountLabels[accounts[j].name] }) + break end - - break end end From b1cdb26a2ab8cd920605474356aceda32ab66108 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rychl=C3=BD?= Date: Sun, 28 Apr 2019 10:44:30 +0200 Subject: [PATCH 2189/3224] Add of Czech translate (#24) * Add of Czech translate Czech translation edit da * Czech diacritic temp remove Solves https://github.com/rp-esx-fivem/esx_atm/issues/1 --- __resource.lua | 2 ++ html/ui_cs.html | 31 +++++++++++++++++++++++++++++++ locales/cs.lua | 7 +++++++ 3 files changed, 40 insertions(+) create mode 100644 html/ui_cs.html create mode 100644 locales/cs.lua diff --git a/__resource.lua b/__resource.lua index 2fb75702..3f6c7f0e 100644 --- a/__resource.lua +++ b/__resource.lua @@ -13,6 +13,7 @@ server_scripts { 'locales/fr.lua', 'locales/es.lua', 'locales/sv.lua', + 'locales/cs.lua', 'config.lua', 'server/main.lua' } @@ -26,6 +27,7 @@ client_scripts { 'locales/fr.lua', 'locales/es.lua', 'locales/sv.lua', + 'locales/cs.lua', 'config.lua', 'client/main.lua' } diff --git a/html/ui_cs.html b/html/ui_cs.html new file mode 100644 index 00000000..a09c670c --- /dev/null +++ b/html/ui_cs.html @@ -0,0 +1,31 @@ + + + + + + +
    + +
    + Dobrý den,
    + Děkujeme Vám za využívání terminálů Fleece Bank +
    + +
    + + + + + \ No newline at end of file diff --git a/locales/cs.lua b/locales/cs.lua new file mode 100644 index 00000000..42ef75fb --- /dev/null +++ b/locales/cs.lua @@ -0,0 +1,7 @@ +Locales['cs'] = { + ['invalid_amount'] = '~r~Zadali jste neplatnou castku~s~', + ['deposit_money'] = 'vlozili jste ~g~$%s~s~', + ['withdraw_money'] = 'vybrali jste ~g~$%s~s~', + ['press_e_atm'] = 'stiskni ~INPUT_PICKUP~ pro pouziti ~g~bankomatu~s~', + ['atm_blip'] = 'bankomat', +} \ No newline at end of file From 47c81f36eb4205339576b48a2ab8def6f28c2522 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 1 May 2019 21:56:49 +0200 Subject: [PATCH 2190/3224] Implemented ESX.Table.Sort() for pairs --- common/modules/table.lua | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/common/modules/table.lua b/common/modules/table.lua index fb862439..ea7dad28 100644 --- a/common/modules/table.lua +++ b/common/modules/table.lua @@ -125,4 +125,35 @@ function ESX.Table.Join(t, sep) end return str +end + +-- Credit: https://stackoverflow.com/a/15706820 +-- Description: sort function for pairs +function ESX.Table.Sort(t, order) + -- collect the keys + local keys = {} + + for k,_ in pairs(t) do + keys[#keys + 1] = k + end + + -- if order function given, sort by it by passing the table and keys a, b, + -- otherwise just sort the keys + if order then + table.sort(keys, function(a,b) + return order(t, a, b) + end) + else + table.sort(keys) + end + + -- return the iterator function + local i = 0 + + return function() + i = i + 1 + if keys[i] then + return keys[i], t[keys[i]] + end + end end \ No newline at end of file From 5469e0b7f487240c4feac52593ca116adce89739 Mon Sep 17 00:00:00 2001 From: Izio Date: Thu, 2 May 2019 01:48:06 +0200 Subject: [PATCH 2191/3224] iZone intergration --- README.md | 18 +++++++++++++ client/jobs/miner.lua | 2 +- client/main.lua | 59 ++++++++++++++++++++++++++++++++++++------- 3 files changed, 69 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 893f0492..196a40da 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,24 @@ git clone https://github.com/ESX-Org/esx_jobs [esx]/esx_jobs start esx_jobs ``` +## iZone integreation (optional) +- You can use iZone with esx_jobs by creating polynomial zones with iZone. When you finish the zone creation, take the zone name and set a Zone field on the job like so: +``` +CloakRoom = { + Zone = "miner_room", -- HERE + Size = {x = 3.0, y = 3.0, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Marker = 1, + Blip = true, + Name = _U("m_miner_locker"), + Type = "cloakroom", + Hint = _U("cloak_change"), + GPS = {x = 884.86, y = -2176.51, z = 29.51} +} +``` +- Note that this is just to have custom zone and avoid using radius. +### [How to install and use iZone](https://github.com/izio38/iZone) + # Legal ### License esx_jobs - jobs diff --git a/client/jobs/miner.lua b/client/jobs/miner.lua index 20e7520e..3aa41a04 100644 --- a/client/jobs/miner.lua +++ b/client/jobs/miner.lua @@ -19,7 +19,7 @@ Config.Jobs.miner = { Zones = { CloakRoom = { - Pos = {x = 892.35, y = -2172.77, z = 31.28}, + Zone = "miner_test", Size = {x = 3.0, y = 3.0, z = 1.0}, Color = {r = 204, g = 204, b = 0}, Marker = 1, diff --git a/client/main.lua b/client/main.lua index fc710ac3..28da5548 100644 --- a/client/main.lua +++ b/client/main.lua @@ -251,7 +251,18 @@ function refreshBlips() for zoneKey,zoneValues in pairs(jobValues.Zones) do if zoneValues.Blip then - local blip = AddBlipForCoord(zoneValues.Pos.x, zoneValues.Pos.y, zoneValues.Pos.z) + local _Pos = {} + if (zoneValues.Zone) then + TriggerEvent("izone:getZoneCenter", zoneValues.Zone, function(_center) + if (_center) then + _Pos = _center + end + end) + else + _Pos = zoneValues.Pos + end + print(_Pos.x) + local blip = AddBlipForCoord(_Pos.x, _Pos.y, _Pos.z) SetBlipSprite (blip, jobValues.BlipInfos.Sprite) SetBlipDisplay (blip, 4) SetBlipScale (blip, 1.2) @@ -333,8 +344,18 @@ Citizen.CreateThread(function() local coords = GetEntityCoords(PlayerPedId()) for k,v in pairs(zones) do if onDuty or v.Type == "cloakroom" or PlayerData.job.name == "reporter" then - if(v.Marker ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then - DrawMarker(v.Marker, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) + if (v.Zone) then + TriggerEvent("izone:getZoneCenter", v.Zone, function(center) + if (not(center == nil)) then + if(v.Marker ~= -1 and GetDistanceBetweenCoords(coords, center.x, center.y, center.z, true) < Config.DrawDistance) then + DrawMarker(v.Marker, center.x, center.y, center.z - 1, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) + end + end + end) + else + if(v.Marker ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then + DrawMarker(v.Marker, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) + end end end end @@ -416,14 +437,34 @@ Citizen.CreateThread(function() local lastZone = nil for k,v in pairs(zones) do - if GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x then - isInMarker = true - currentZone = k - zone = v - break + -- If we defined a zone from iZone + if v.Zone then + TriggerEvent("izone:isPlayerInZone", v.Zone, function(isIn) + if isIn then + isInMarker = true + currentZone = k + zone = v + return + else + isInMarker = false + end + end) + -- Because we were in a routine + if isInMarker then + break + end + -- Else use radius defined from center else - isInMarker = false + if GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x then + isInMarker = true + currentZone = k + zone = v + break + else + isInMarker = false + end end + end if IsControlJustReleased(0, Keys['E']) and not menuIsShowed and isInMarker then From eeaa826c2e8789e88ff18108d1b63ab5e4b77a47 Mon Sep 17 00:00:00 2001 From: Izio Date: Thu, 2 May 2019 01:48:55 +0200 Subject: [PATCH 2192/3224] remove test iZone --- client/jobs/miner.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/jobs/miner.lua b/client/jobs/miner.lua index 3aa41a04..20e7520e 100644 --- a/client/jobs/miner.lua +++ b/client/jobs/miner.lua @@ -19,7 +19,7 @@ Config.Jobs.miner = { Zones = { CloakRoom = { - Zone = "miner_test", + Pos = {x = 892.35, y = -2172.77, z = 31.28}, Size = {x = 3.0, y = 3.0, z = 1.0}, Color = {r = 204, g = 204, b = 0}, Marker = 1, From 28a275a30a2a3d09bda4e64d6a310d9e06e27b27 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 5 May 2019 09:45:43 +0200 Subject: [PATCH 2193/3224] Proper cb usage --- server/main.lua | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/server/main.lua b/server/main.lua index 78f05d7c..24295b96 100644 --- a/server/main.lua +++ b/server/main.lua @@ -24,21 +24,21 @@ ESX.RegisterServerCallback('esx_boat:buyBoat', function(source, cb, vehicleProps if price == 0 then print(('esx_boat: %s attempted to exploit the shop! (invalid vehicle model)'):format(xPlayer.identifier)) cb(false) - end - - if xPlayer.getMoney() >= price then - xPlayer.removeMoney(price) - - MySQL.Async.execute('INSERT INTO owned_vehicles (owner, plate, vehicle, type) VALUES (@owner, @plate, @vehicle, @type)', { - ['@owner'] = xPlayer.identifier, - ['@plate'] = vehicleProps.plate, - ['@vehicle'] = json.encode(vehicleProps), - ['@type'] = 'boat' - }, function(rowsChanged) - cb(true) - end) else - cb(false) + if xPlayer.getMoney() >= price then + xPlayer.removeMoney(price) + + MySQL.Async.execute('INSERT INTO owned_vehicles (owner, plate, vehicle, type) VALUES (@owner, @plate, @vehicle, @type)', { + ['@owner'] = xPlayer.identifier, + ['@plate'] = vehicleProps.plate, + ['@vehicle'] = json.encode(vehicleProps), + ['@type'] = 'boat' + }, function(rowsChanged) + cb(true) + end) + else + cb(false) + end end end) From 8528fd8037b97a7236cfadd5da51ddb5101dfd0c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 5 May 2019 09:48:47 +0200 Subject: [PATCH 2194/3224] Proper cb usage --- client/main.lua | 2 +- server/main.lua | 109 +++++++++++++++++++----------------------------- 2 files changed, 45 insertions(+), 66 deletions(-) diff --git a/client/main.lua b/client/main.lua index 6e8a34e3..ac67c870 100644 --- a/client/main.lua +++ b/client/main.lua @@ -27,7 +27,7 @@ local CurrentTask = {} local playerInService = false local spawnedVehicles, isInShopMenu = {}, false -ESX = nil +ESX = nil Citizen.CreateThread(function() while ESX == nil do diff --git a/server/main.lua b/server/main.lua index 2b23fe41..b4898a9b 100644 --- a/server/main.lua +++ b/server/main.lua @@ -108,7 +108,6 @@ AddEventHandler('esx_policejob:getStockItem', function(itemName, count) local sourceItem = xPlayer.getInventoryItem(itemName) TriggerEvent('esx_addoninventory:getSharedInventory', 'society_police', function(inventory) - local inventoryItem = inventory.getItem(itemName) -- is there enough in the society? @@ -126,7 +125,6 @@ AddEventHandler('esx_policejob:getStockItem', function(itemName, count) TriggerClientEvent('esx:showNotification', _source, _U('quantity_invalid')) end end) - end) RegisterServerEvent('esx_policejob:putStockItems') @@ -135,7 +133,6 @@ AddEventHandler('esx_policejob:putStockItems', function(itemName, count) local sourceItem = xPlayer.getInventoryItem(itemName) TriggerEvent('esx_addoninventory:getSharedInventory', 'society_police', function(inventory) - local inventoryItem = inventory.getItem(itemName) -- does the player have enough of the item? @@ -146,17 +143,12 @@ AddEventHandler('esx_policejob:putStockItems', function(itemName, count) else TriggerClientEvent('esx:showNotification', xPlayer.source, _U('quantity_invalid')) end - end) - end) ESX.RegisterServerCallback('esx_policejob:getOtherPlayerData', function(source, cb, target) - if Config.EnableESXIdentity then - local xPlayer = ESX.GetPlayerFromId(target) - local result = MySQL.Sync.fetchAll('SELECT firstname, lastname, sex, dateofbirth, height FROM users WHERE identifier = @identifier', { ['@identifier'] = xPlayer.identifier }) @@ -194,9 +186,7 @@ ESX.RegisterServerCallback('esx_policejob:getOtherPlayerData', function(source, else cb(data) end - else - local xPlayer = ESX.GetPlayerFromId(target) local data = { @@ -208,7 +198,7 @@ ESX.RegisterServerCallback('esx_policejob:getOtherPlayerData', function(source, } TriggerEvent('esx_status:getStatus', target, 'drunk', function(status) - if status ~= nil then + if status then data.drunk = math.floor(status.percent) end end) @@ -218,9 +208,7 @@ ESX.RegisterServerCallback('esx_policejob:getOtherPlayerData', function(source, end) cb(data) - end - end) ESX.RegisterServerCallback('esx_policejob:getFineList', function(source, cb, category) @@ -242,7 +230,6 @@ ESX.RegisterServerCallback('esx_policejob:getVehicleInfos', function(source, cb, } if result[1] then - MySQL.Async.fetchAll('SELECT name, firstname, lastname FROM users WHERE identifier = @identifier', { ['@identifier'] = result[1].owner }, function(result2) @@ -285,7 +272,6 @@ ESX.RegisterServerCallback('esx_policejob:getVehicleFromPlate', function(source, end) ESX.RegisterServerCallback('esx_policejob:getArmoryWeapons', function(source, cb) - TriggerEvent('esx_datastore:getSharedDataStore', 'society_police', function(store) local weapons = store.get('weapons') @@ -295,11 +281,9 @@ ESX.RegisterServerCallback('esx_policejob:getArmoryWeapons', function(source, cb cb(weapons) end) - end) ESX.RegisterServerCallback('esx_policejob:addArmoryWeapon', function(source, cb, weaponName, removeWeapon) - local xPlayer = ESX.GetPlayerFromId(source) if removeWeapon then @@ -307,7 +291,6 @@ ESX.RegisterServerCallback('esx_policejob:addArmoryWeapon', function(source, cb, end TriggerEvent('esx_datastore:getSharedDataStore', 'society_police', function(store) - local weapons = store.get('weapons') if weapons == nil then @@ -334,13 +317,10 @@ ESX.RegisterServerCallback('esx_policejob:addArmoryWeapon', function(source, cb, store.set('weapons', weapons) cb() end) - end) ESX.RegisterServerCallback('esx_policejob:removeArmoryWeapon', function(source, cb, weaponName) - local xPlayer = ESX.GetPlayerFromId(source) - xPlayer.addWeapon(weaponName, 500) TriggerEvent('esx_datastore:getSharedDataStore', 'society_police', function(store) @@ -371,7 +351,6 @@ ESX.RegisterServerCallback('esx_policejob:removeArmoryWeapon', function(source, store.set('weapons', weapons) cb() end) - end) ESX.RegisterServerCallback('esx_policejob:buyWeapon', function(source, cb, weaponName, type, componentNum) @@ -388,38 +367,38 @@ ESX.RegisterServerCallback('esx_policejob:buyWeapon', function(source, cb, weapo if not selectedWeapon then print(('esx_policejob: %s attempted to buy an invalid weapon.'):format(xPlayer.identifier)) cb(false) - end - - -- Weapon - if type == 1 then - if xPlayer.getMoney() >= selectedWeapon.price then - xPlayer.removeMoney(selectedWeapon.price) - xPlayer.addWeapon(weaponName, 100) - - cb(true) - else - cb(false) - end - - -- Weapon Component - elseif type == 2 then - local price = selectedWeapon.components[componentNum] - local weaponNum, weapon = ESX.GetWeapon(weaponName) - - local component = weapon.components[componentNum] - - if component then - if xPlayer.getMoney() >= price then - xPlayer.removeMoney(price) - xPlayer.addWeaponComponent(weaponName, component.name) + else + -- Weapon + if type == 1 then + if xPlayer.getMoney() >= selectedWeapon.price then + xPlayer.removeMoney(selectedWeapon.price) + xPlayer.addWeapon(weaponName, 100) cb(true) else cb(false) end - else - print(('esx_policejob: %s attempted to buy an invalid weapon component.'):format(xPlayer.identifier)) - cb(false) + + -- Weapon Component + elseif type == 2 then + local price = selectedWeapon.components[componentNum] + local weaponNum, weapon = ESX.GetWeapon(weaponName) + + local component = weapon.components[componentNum] + + if component then + if xPlayer.getMoney() >= price then + xPlayer.removeMoney(price) + xPlayer.addWeaponComponent(weaponName, component.name) + + cb(true) + else + cb(false) + end + else + print(('esx_policejob: %s attempted to buy an invalid weapon component.'):format(xPlayer.identifier)) + cb(false) + end end end end) @@ -433,23 +412,23 @@ ESX.RegisterServerCallback('esx_policejob:buyJobVehicle', function(source, cb, v if price == 0 then print(('esx_policejob: %s attempted to exploit the shop! (invalid vehicle model)'):format(xPlayer.identifier)) cb(false) - end - - 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) - cb(true) - end) else - cb(false) + 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) + cb(true) + end) + else + cb(false) + end end end) From 466ca0a3999fc5807c70b11954169e41db143a1a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 5 May 2019 09:51:18 +0200 Subject: [PATCH 2195/3224] Proper cb usage --- server/main.lua | 127 ++++++++++++++++++++++-------------------------- 1 file changed, 57 insertions(+), 70 deletions(-) diff --git a/server/main.lua b/server/main.lua index 60369e99..2773e180 100644 --- a/server/main.lua +++ b/server/main.lua @@ -71,7 +71,7 @@ AddEventHandler('esx_vehicleshop:setVehicleOwnedPlayerId', function (playerId, v ['@vehicle'] = json.encode(vehicleProps) }, function (rowsChanged) TriggerClientEvent('esx:showNotification', playerId, _U('vehicle_belongs', vehicleProps.plate)) - end) + end) end) RegisterServerEvent('esx_vehicleshop:setVehicleOwnedSociety') @@ -166,7 +166,7 @@ AddEventHandler('esx_vehicleshop:getStockItem', function (itemName, count) -- is there enough in the society? if count > 0 and item.count >= count then - + -- can the player carry the said amount of x item? if sourceItem.limit ~= -1 and (sourceItem.count + count) > sourceItem.limit then TriggerClientEvent('esx:showNotification', _source, _U('player_cannot_hold')) @@ -240,8 +240,7 @@ ESX.RegisterServerCallback('esx_vehicleshop:buyVehicleSociety', function (source if account.money >= vehicleData.price then account.removeMoney(vehicleData.price) - MySQL.Async.execute('INSERT INTO cardealer_vehicles (vehicle, price) VALUES (@vehicle, @price)', - { + MySQL.Async.execute('INSERT INTO cardealer_vehicles (vehicle, price) VALUES (@vehicle, @price)', { ['@vehicle'] = vehicleData.model, ['@price'] = vehicleData.price }, function(rowsChanged) @@ -292,7 +291,7 @@ AddEventHandler('esx_vehicleshop:returnProvider', function(vehicleModel) TriggerClientEvent('esx:showNotification', _source, _U('vehicle_sold_for', vehicleModel, ESX.Math.GroupDigits(price))) else - + print(('esx_vehicleshop: %s attempted selling an invalid vehicle!'):format(GetPlayerIdentifiers(_source)[1])) end @@ -323,8 +322,7 @@ ESX.RegisterServerCallback('esx_vehicleshop:giveBackVehicle', function (source, local vehicle = result[1].vehicle local basePrice = result[1].base_price - MySQL.Async.execute('INSERT INTO cardealer_vehicles (vehicle, price) VALUES (@vehicle, @price)', - { + MySQL.Async.execute('INSERT INTO cardealer_vehicles (vehicle, price) VALUES (@vehicle, @price)', { ['@vehicle'] = vehicle, ['@price'] = basePrice }) @@ -355,80 +353,69 @@ ESX.RegisterServerCallback('esx_vehicleshop:resellVehicle', function (source, cb if resellPrice == 0 then print(('esx_vehicleshop: %s attempted to sell an unknown vehicle!'):format(GetPlayerIdentifiers(source)[1])) cb(false) - end + else + MySQL.Async.fetchAll('SELECT * FROM rented_vehicles WHERE plate = @plate', { + ['@plate'] = plate + }, function (result) + if result[1] then -- is it a rented vehicle? + cb(false) -- it is, don't let the player sell it since he doesn't own it + else + local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.fetchAll('SELECT * FROM rented_vehicles WHERE plate = @plate', { - ['@plate'] = plate - }, function (result) - if result[1] then -- is it a rented vehicle? - cb(false) -- it is, don't let the player sell it since he doesn't own it - else - local xPlayer = ESX.GetPlayerFromId(source) + 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.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) - - if vehicle.model == model then - if vehicle.plate == plate then - xPlayer.addMoney(resellPrice) - RemoveOwnedVehicle(plate) - - cb(true) + if vehicle.model == model then + if vehicle.plate == plate then + xPlayer.addMoney(resellPrice) + RemoveOwnedVehicle(plate) + cb(true) + else + print(('esx_vehicleshop: %s attempted to sell an vehicle with plate mismatch!'):format(xPlayer.identifier)) + cb(false) + end else - print(('esx_vehicleshop: %s attempted to sell an vehicle with plate mismatch!'):format(xPlayer.identifier)) + print(('esx_vehicleshop: %s attempted to sell an vehicle with model mismatch!'):format(xPlayer.identifier)) cb(false) end else - print(('esx_vehicleshop: %s attempted to sell an vehicle with model mismatch!'):format(xPlayer.identifier)) - cb(false) - end + if xPlayer.job.grade_name == 'boss' then + MySQL.Async.fetchAll('SELECT * FROM owned_vehicles WHERE owner = @owner AND @plate = plate', { + ['@owner'] = 'society:' .. xPlayer.job.name, + ['@plate'] = plate + }, function (result) + if result[1] then + local vehicle = json.decode(result[1].vehicle) - else - - if xPlayer.job.grade_name == 'boss' then - MySQL.Async.fetchAll('SELECT * FROM owned_vehicles WHERE owner = @owner AND @plate = plate', { - ['@owner'] = 'society:' .. xPlayer.job.name, - ['@plate'] = plate - }, function (result) - - if result[1] then - - local vehicle = json.decode(result[1].vehicle) - - if vehicle.model == model then - if vehicle.plate == plate then - xPlayer.addMoney(resellPrice) - RemoveOwnedVehicle(plate) - - cb(true) + if vehicle.model == model then + if vehicle.plate == plate then + xPlayer.addMoney(resellPrice) + RemoveOwnedVehicle(plate) + cb(true) + else + print(('esx_vehicleshop: %s attempted to sell an vehicle with plate mismatch!'):format(xPlayer.identifier)) + cb(false) + end else - print(('esx_vehicleshop: %s attempted to sell an vehicle with plate mismatch!'):format(xPlayer.identifier)) + print(('esx_vehicleshop: %s attempted to sell an vehicle with model mismatch!'):format(xPlayer.identifier)) cb(false) end else - print(('esx_vehicleshop: %s attempted to sell an vehicle with model mismatch!'):format(xPlayer.identifier)) cb(false) end - - else - cb(false) - end - - end) - else - cb(false) + end) + else + cb(false) + end end - end - - end) - end - end) + end) + end + end) + end end) @@ -440,13 +427,13 @@ end) ESX.RegisterServerCallback('esx_vehicleshop:getPlayerInventory', function (source, cb) local xPlayer = ESX.GetPlayerFromId(source) - local items = xPlayer.inventory + local items = xPlayer.inventory - cb({ items = items }) + cb({items = items}) end) ESX.RegisterServerCallback('esx_vehicleshop:isPlateTaken', function (source, cb, plate) - MySQL.Async.fetchAll('SELECT * FROM owned_vehicles WHERE plate = @plate', { + MySQL.Async.fetchAll('SELECT 1 FROM owned_vehicles WHERE plate = @plate', { ['@plate'] = plate }, function (result) cb(result[1] ~= nil) From 65b4b0bc588e9bbf8a0395bb98c732b81749fcd5 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 5 May 2019 09:59:36 +0200 Subject: [PATCH 2196/3224] Updated chat events usage --- server/main.lua | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/server/main.lua b/server/main.lua index 4d27c6cd..4d4b4425 100644 --- a/server/main.lua +++ b/server/main.lua @@ -25,27 +25,25 @@ end) TriggerEvent('es:addGroupCommand', 'heal', 'admin', function(source, args, user) -- heal another player - don't heal source if args[1] then - local target = tonumber(args[1]) - + local playerId = tonumber(args[1]) + -- is the argument a number? - if target ~= nil then - + if playerId then -- is the number a valid player? - if GetPlayerName(target) then - print('esx_basicneeds: ' .. GetPlayerName(source) .. ' is healing a player!') - TriggerClientEvent('esx_basicneeds:healPlayer', target) - TriggerClientEvent('chatMessage', target, "HEAL", {223, 66, 244}, "You have been healed!") + if GetPlayerName(playerId) then + print(('esx_basicneeds: %s healed %s'):format(GetPlayerIdentifier(source, 0), GetPlayerIdentifier(playerId, 0))) + TriggerClientEvent('esx_basicneeds:healPlayer', playerId) + TriggerClientEvent('chat:addMessage', source, { args = { '^5HEAL', 'You have been healed.' } }) else - TriggerClientEvent('chatMessage', source, "HEAL", {255, 0, 0}, "Player not found!") + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) end else - TriggerClientEvent('chatMessage', source, "HEAL", {255, 0, 0}, "Incorrect syntax! You must provide a valid player ID") + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid player id.' } }) end else - -- heal source - print('esx_basicneeds: ' .. GetPlayerName(source) .. ' is healing!') + print(('esx_basicneeds: %s healed self'):format(GetPlayerIdentifier(source, 0))) TriggerClientEvent('esx_basicneeds:healPlayer', source) end end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "HEAL", {255, 0, 0}, "Insufficient Permissions.") -end, {help = "Heal a player, or yourself - restores thirst, hunger and health."}) \ No newline at end of file + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) +end, {help = 'Heal a player, or yourself - restores thirst, hunger and health.', params = {{name = 'playerId', help = '(optional) player id'}}}) \ No newline at end of file From 181f060a18dfe24ea2a3ee795422680e3accd3d6 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 5 May 2019 10:01:03 +0200 Subject: [PATCH 2197/3224] Proper cb usage --- server/main.lua | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/server/main.lua b/server/main.lua index 52c8e52a..0f5b78d9 100644 --- a/server/main.lua +++ b/server/main.lua @@ -119,23 +119,23 @@ ESX.RegisterServerCallback('esx_ambulancejob:buyJobVehicle', function(source, cb if price == 0 then print(('esx_ambulancejob: %s attempted to exploit the shop! (invalid vehicle model)'):format(xPlayer.identifier)) cb(false) - end - - 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) - cb(true) - end) else - cb(false) + 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) + cb(true) + end) + else + cb(false) + end end end) From fb9f4263a2d07d07029e18c07ad65a9e392b6438 Mon Sep 17 00:00:00 2001 From: izio38 Date: Sun, 5 May 2019 23:00:08 +0200 Subject: [PATCH 2198/3224] wrong notif target --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 3f0a4d73..b43e66d6 100644 --- a/server/main.lua +++ b/server/main.lua @@ -336,7 +336,7 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo end else TriggerClientEvent('esx:showNotification', _source, _U('gave_weapon_hasalready', targetXPlayer.name, weaponLabel)) - TriggerClientEvent('esx:showNotification', _source, _U('received_weapon_hasalready', sourceXPlayer.name, weaponLabel)) + TriggerClientEvent('esx:showNotification', target, _U('received_weapon_hasalready', sourceXPlayer.name, weaponLabel)) end end From cd0ede58651d137ffefe6ef426329f4d7e409b42 Mon Sep 17 00:00:00 2001 From: SurDaft - Jack Stupple Date: Mon, 6 May 2019 01:08:58 +0100 Subject: [PATCH 2199/3224] fix empty shop bug --- client/main.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/main.lua b/client/main.lua index 5d66a8b6..f4a9ad7e 100644 --- a/client/main.lua +++ b/client/main.lua @@ -27,6 +27,10 @@ Citizen.CreateThread(function() ESX.TriggerServerCallback('esx_shops:requestDBItems', function(ShopItems) for k,v in pairs(ShopItems) do + if (Config.Zones[k] == nil) then + Config.Zones[k] = {} + end + Config.Zones[k].Items = v end end) From d78f21d08344d62df82fe56c6a2d4bf17afcc105 Mon Sep 17 00:00:00 2001 From: SurDaft - Jack Stupple Date: Mon, 6 May 2019 01:37:23 +0100 Subject: [PATCH 2200/3224] Fix markers not showing --- client/main.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index f4a9ad7e..341c446a 100644 --- a/client/main.lua +++ b/client/main.lua @@ -28,7 +28,10 @@ Citizen.CreateThread(function() ESX.TriggerServerCallback('esx_shops:requestDBItems', function(ShopItems) for k,v in pairs(ShopItems) do if (Config.Zones[k] == nil) then - Config.Zones[k] = {} + Config.Zones[k] = { + Items = {}, + Pos = {} + } end Config.Zones[k].Items = v From 83e517330f852a6de10b86964d6a78dc302035b7 Mon Sep 17 00:00:00 2001 From: izio38 Date: Mon, 6 May 2019 14:42:42 +0200 Subject: [PATCH 2201/3224] fix( onesync global voices ) --- client/main.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/client/main.lua b/client/main.lua index e0797571..876e34cf 100644 --- a/client/main.lua +++ b/client/main.lua @@ -38,6 +38,7 @@ AddEventHandler('onClientMapStart', function() end) Citizen.CreateThread(function() + NetworkSetTalkerProximity(voice.default) while true do Citizen.Wait(1) From 36bc96cdfe9e2214706d48d3fe462184169368a7 Mon Sep 17 00:00:00 2001 From: DanishRP Date: Sat, 11 May 2019 01:18:59 +0200 Subject: [PATCH 2202/3224] Changed Variables Changed Variables for self.removeAccountMoney, did not match same scheme as other functions in same function --- server/classes/player.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 256b365c..5642c527 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -289,18 +289,18 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l TriggerClientEvent('esx:setAccountMoney', self.source, account) end - self.removeAccountMoney = function(a, m) - if m < 0 then + self.removeAccountMoney = function(acc, money) + if money < 0 then print(('es_extended: %s attempted exploiting! (reason: player tried removing -1 account balance)'):format(self.identifier)) return end - local account = self.getAccount(a) - local newMoney = account.money - m + local account = self.getAccount(acc) + local newMoney = account.money - ESX.Math.Round(money) account.money = newMoney - if a == 'bank' then + if acc == 'bank' then self.set('bank', newMoney) end From 5d3bfc59a679c9e3e82926add32f08a2c02d87ff Mon Sep 17 00:00:00 2001 From: izio38 Date: Fri, 17 May 2019 19:59:25 +0200 Subject: [PATCH 2203/3224] probably fix global voices --- client/main.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 876e34cf..5a625b62 100644 --- a/client/main.lua +++ b/client/main.lua @@ -37,8 +37,11 @@ AddEventHandler('onClientMapStart', function() end end) +AddEventHandler('playerSpawned', function() + NetworkSetTalkerProximity(voice.default) +end + Citizen.CreateThread(function() - NetworkSetTalkerProximity(voice.default) while true do Citizen.Wait(1) From 16915289922750d02b7c39237a9cc103c2eee378 Mon Sep 17 00:00:00 2001 From: izio38 Date: Sat, 18 May 2019 07:02:13 +0200 Subject: [PATCH 2204/3224] typo --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 5a625b62..c641f803 100644 --- a/client/main.lua +++ b/client/main.lua @@ -39,7 +39,7 @@ end) AddEventHandler('playerSpawned', function() NetworkSetTalkerProximity(voice.default) -end +end) Citizen.CreateThread(function() while true do From 4220c1471a22c0508c2bd32ea391a47b0bcd0765 Mon Sep 17 00:00:00 2001 From: BackrndSource Date: Mon, 20 May 2019 09:19:50 +0200 Subject: [PATCH 2205/3224] Add Spanish Translate (#81) * Create es.lua * Update __resource.lua * Create en_esx_drugs.sql * Create es_esx_drugs.sql --- __resource.lua | 2 ++ locales/es.lua | 30 ++++++++++++++++++++++++++++++ localization/en_esx_drugs.sql | 10 ++++++++++ localization/es_esx_drugs.sql | 10 ++++++++++ 4 files changed, 52 insertions(+) create mode 100644 locales/es.lua create mode 100644 localization/en_esx_drugs.sql create mode 100644 localization/es_esx_drugs.sql diff --git a/__resource.lua b/__resource.lua index bd8d6c69..101f3a7a 100644 --- a/__resource.lua +++ b/__resource.lua @@ -8,6 +8,7 @@ server_scripts { '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', 'locales/en.lua', + 'locales/es.lua', 'locales/fr.lua', 'locales/sv.lua', 'config.lua', @@ -17,6 +18,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', 'locales/en.lua', + 'locales/es.lua', 'locales/fr.lua', 'locales/sv.lua', 'config.lua', diff --git a/locales/es.lua b/locales/es.lua new file mode 100644 index 00000000..a25b83d6 --- /dev/null +++ b/locales/es.lua @@ -0,0 +1,30 @@ +Locales ['es'] = { + -- weed + ['weed_pickupprompt'] = 'pulsa ~INPUT_CONTEXT~ para recolectar ~g~Marijuana húmeda~s~.', + ['weed_inventoryfull'] = 'no puedes llevar más ~g~Marijuana húmeda~s~!', + ['weed_processprompt'] = 'pulsa ~INPUT_CONTEXT~ para ~g~secar la Marijuana~s~.', + ['weed_processingstarted'] = 'secando la ~g~Marijuana húmeda~s~...', + ['weed_processingfull'] = 'no puedes llevar más ~g~Marijuana~s~!', + ['weed_processingenough'] = 'necesitas ~b~3x~s~ ~g~Marijuana húmeda~s~.', + ['weed_processed'] = 'de ~b~3x~s~ ~g~Marijuana húmeda~s~ has obtenido ~b~1x~s~ ~g~Marijuana~s~', + ['weed_processingtoofar'] = 'el secado se ha ~r~cancelado~s~ por que has abandonado el área.', + + -- drug dealer + ['dealer_prompt'] = 'pulsa ~INPUT_CONTEXT~ para hablar con el ~r~Camello~s~.', + ['dealer_title'] = 'camello', + ['dealer_item'] = '$%s', + ['dealer_notenough'] = 'esa mierda no es cantidad suficiente para vender!', + ['dealer_sold'] = 'has vendido ~b~%sx~s~ ~y~%s~s~ por ~g~$%s~s~', + + -- license + ['license_title'] = 'necesitas un permiso para poder tratar con ese producto, puedes comprarlo aquí.', + ['license_no'] = 'no', + ['license_bought'] = 'has comprado ~b~%s~s~ por ~r~$%s~s~', + ['license_bought_fail'] = 'no puedes permitirte ~b~%s~s~!', + ['license_weed'] = 'permiso de cultivo de Marijuana', + + -- blips + ['blip_weedfield'] = 'plantación de Marijuana', + ['blip_weedprocessing'] = 'preparación de Marijuana', + ['blip_drugdealer'] = 'camello' +} diff --git a/localization/en_esx_drugs.sql b/localization/en_esx_drugs.sql new file mode 100644 index 00000000..fe2a3b18 --- /dev/null +++ b/localization/en_esx_drugs.sql @@ -0,0 +1,10 @@ +USE `essentialmode`; + +INSERT INTO `items` (`name`, `label`, `limit`, `rare`, `can_remove`) VALUES + ('cannabis', 'Cannabis', 40, 0, 1), + ('marijuana', 'Marijuana', 14, 0, 1) +; + +INSERT INTO `licenses` (`type`, `label`) VALUES + ('weed_processing', 'Weed Processing License') +; diff --git a/localization/es_esx_drugs.sql b/localization/es_esx_drugs.sql new file mode 100644 index 00000000..496d860a --- /dev/null +++ b/localization/es_esx_drugs.sql @@ -0,0 +1,10 @@ +USE `essentialmode`; + +INSERT INTO `items` (`name`, `label`, `limit`, `rare`, `can_remove`) VALUES + ('cannabis', 'Marijuana húmeda', 40, 0, 1), + ('marijuana', 'Marijuana', 14, 0, 1) +; + +INSERT INTO `licenses` (`type`, `label`) VALUES + ('weed_processing', 'permiso de cultivo de Marijuana') +; From 3705e6b654866c618d16c0d6fb8d8fee42548290 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 20 May 2019 23:02:21 +0200 Subject: [PATCH 2206/3224] Reencode base64 phone logo, minor indent changes --- client/main.lua | 103 +++++++++--------------------------------------- 1 file changed, 19 insertions(+), 84 deletions(-) diff --git a/client/main.lua b/client/main.lua index 6dac949a..aadd5b23 100644 --- a/client/main.lua +++ b/client/main.lua @@ -93,7 +93,6 @@ function DeleteShopInsideVehicles() end function ReturnVehicleProvider() - ESX.TriggerServerCallback('esx_vehicleshop:getCommercialVehicles', function (vehicles) local elements = {} local returnPrice @@ -105,9 +104,8 @@ function ReturnVehicleProvider() value = vehicles[i].name }) end - - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'return_provider_menu', - { + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'return_provider_menu', { title = _U('return_provider_menu'), align = 'top-left', elements = elements @@ -116,30 +114,25 @@ function ReturnVehicleProvider() Citizen.Wait(300) menu.close() - ReturnVehicleProvider() end, function (data, menu) menu.close() end) end) - end function StartShopRestriction() - Citizen.CreateThread(function() while IsInShopMenu do Citizen.Wait(1) - + DisableControlAction(0, 75, true) -- Disable exit vehicle DisableControlAction(27, 75, true) -- Disable exit vehicle end end) - end function OpenShopMenu() - IsInShopMenu = true StartShopRestriction() @@ -192,8 +185,7 @@ function OpenShopMenu() }) end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop', { title = _U('car_dealer'), align = 'top-left', elements = elements @@ -211,7 +203,6 @@ function OpenShopMenu() if data2.current.value == 'yes' then if Config.EnablePlayerManagement then ESX.TriggerServerCallback('esx_vehicleshop:buyVehicleSociety', function(hasEnoughMoney) - if hasEnoughMoney then IsInShopMenu = false @@ -234,33 +225,28 @@ function OpenShopMenu() else ESX.ShowNotification(_U('broke_company')) end - end, 'cardealer', vehicleData.model) else local playerData = ESX.GetPlayerData() if Config.EnableSocietyOwnedVehicles and playerData.job.grade_name == 'boss' then - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'shop_confirm_buy_type', { title = _U('purchase_type'), align = 'top-left', elements = { {label = _U('staff_type'), value = 'personnal'}, {label = _U('society_type'), value = 'society'} - } - }, function (data3, menu3) + }}, function (data3, menu3) if data3.current.value == 'personnal' then ESX.TriggerServerCallback('esx_vehicleshop:buyVehicle', function(hasEnoughMoney) - if hasEnoughMoney then IsInShopMenu = false menu3.close() menu2.close() menu.close() - DeleteShopInsideVehicles() ESX.Game.SpawnVehicle(vehicleData.model, Config.Zones.ShopOutside.Pos, Config.Zones.ShopOutside.Heading, function (vehicle) @@ -283,13 +269,11 @@ function OpenShopMenu() else ESX.ShowNotification(_U('not_enough_money')) end - end, vehicleData.model) elseif data3.current.value == 'society' then ESX.TriggerServerCallback('esx_vehicleshop:buyVehicleSociety', function (hasEnoughMoney) - if hasEnoughMoney then IsInShopMenu = false @@ -306,9 +290,7 @@ function OpenShopMenu() local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) vehicleProps.plate = newPlate SetVehicleNumberPlateText(vehicle, newPlate) - TriggerServerEvent('esx_vehicleshop:setVehicleOwnedSociety', playerData.job.name, vehicleProps) - ESX.ShowNotification(_U('vehicle_purchased')) end) @@ -317,7 +299,6 @@ function OpenShopMenu() else ESX.ShowNotification(_U('broke_company')) end - end, playerData.job.name, vehicleData.model) end @@ -326,13 +307,10 @@ function OpenShopMenu() end) else ESX.TriggerServerCallback('esx_vehicleshop:buyVehicle', function (hasEnoughMoney) - if hasEnoughMoney then IsInShopMenu = false - menu2.close() menu.close() - DeleteShopInsideVehicles() ESX.Game.SpawnVehicle(vehicleData.model, Config.Zones.ShopOutside.Pos, Config.Zones.ShopOutside.Heading, function (vehicle) @@ -355,24 +333,16 @@ function OpenShopMenu() else ESX.ShowNotification(_U('not_enough_money')) end - end, vehicleData.model) end end - elseif data2.current.value == 'no' then - end - end, function (data2, menu2) menu2.close() end) - end, function (data, menu) - menu.close() - DeleteShopInsideVehicles() - local playerPed = PlayerPedId() CurrentAction = 'shop_menu' @@ -384,7 +354,6 @@ function OpenShopMenu() SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos.x, Config.Zones.ShopEntering.Pos.y, Config.Zones.ShopEntering.Pos.z) IsInShopMenu = false - end, function (data, menu) local vehicleData = vehiclesByCategory[data.current.name][data.current.value + 1] local playerPed = PlayerPedId() @@ -432,11 +401,9 @@ function WaitForVehicleToLoad(modelHash) end function OpenResellerMenu() - ESX.UI.Menu.CloseAll() - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'reseller', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'reseller', { title = _U('car_dealer'), align = 'top-left', elements = { @@ -484,7 +451,6 @@ function OpenResellerMenu() ESX.ShowNotification(_U('invalid_amount')) else menu2.close() - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() if closestPlayer == -1 or closestDistance > 3.0 then @@ -506,7 +472,6 @@ function OpenResellerMenu() if closestPlayer == -1 or closestDistance > 3.0 then ESX.ShowNotification(_U('no_players')) else - local newPlate = GeneratePlate() local vehicleProps = ESX.Game.GetVehicleProperties(LastVehicles[#LastVehicles]) local model = CurrentVehicleData.model @@ -522,7 +487,6 @@ function OpenResellerMenu() else ESX.ShowNotification(_U('vehicle_sold_to', vehicleProps.plate, GetPlayerName(closestPlayer))) end - end elseif action == 'set_vehicle_owner_sell_society' then @@ -539,7 +503,6 @@ function OpenResellerMenu() local model = CurrentVehicleData.model vehicleProps.plate = newPlate SetVehicleNumberPlateText(LastVehicles[#LastVehicles], newPlate) - TriggerServerEvent('esx_vehicleshop:sellVehicle', model) TriggerServerEvent('esx_vehicleshop:addToList', GetPlayerServerId(closestPlayer), model, newPlate) @@ -570,21 +533,18 @@ function OpenResellerMenu() if closestPlayer == -1 or closestDistance > 5.0 then ESX.ShowNotification(_U('no_players')) else - local newPlate = 'RENT' .. string.upper(ESX.GetRandomString(4)) local vehicleProps = ESX.Game.GetVehicleProperties(LastVehicles[#LastVehicles]) local model = CurrentVehicleData.model vehicleProps.plate = newPlate SetVehicleNumberPlateText(LastVehicles[#LastVehicles], newPlate) - TriggerServerEvent('esx_vehicleshop:rentVehicle', model, vehicleProps.plate, GetPlayerName(closestPlayer), CurrentVehicleData.price, amount, GetPlayerServerId(closestPlayer)) if Config.EnableOwnedVehicles then - TriggerServerEvent('esx_vehicleshop:setVehicleOwnedPlayerId', GetPlayerServerId(closestPlayer), vehicleProps) + TriggerServerEvent('esx_vehicleshop:setVehicleOwnedPlayerId', GetPlayerServerId(closestPlayer), vehicleProps) end ESX.ShowNotification(_U('vehicle_set_rented', vehicleProps.plate, GetPlayerName(closestPlayer))) - TriggerServerEvent('esx_vehicleshop:setVehicleForAllPlayers', vehicleProps, Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 5.0) end end @@ -592,7 +552,6 @@ function OpenResellerMenu() menu2.close() end) end - end, function (data, menu) menu.close() @@ -600,7 +559,6 @@ function OpenResellerMenu() CurrentActionMsg = _U('shop_menu') CurrentActionData = {} end) - end function OpenPopVehicleMenu() @@ -614,8 +572,7 @@ function OpenPopVehicleMenu() }) end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'commercial_vehicles', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'commercial_vehicles', { title = _U('vehicle_dealer'), align = 'top-left', elements = elements @@ -670,8 +627,7 @@ function OpenBossActionsMenu() elements = { {label = _U('boss_actions'), value = 'boss_actions'}, {label = _U('boss_sold'), value = 'sold_vehicles'} - } - }, function (data, menu) + }}, function (data, menu) if data.current.value == 'boss_actions' then TriggerEvent('esx_society:openBossMenu', 'cardealer', function(data2, menu2) menu2.close() @@ -683,7 +639,7 @@ function OpenBossActionsMenu() head = { _U('customer_client'), _U('customer_model'), _U('customer_plate'), _U('customer_soldby'), _U('customer_date') }, rows = {} } - + for i=1, #customers, 1 do table.insert(elements.rows, { data = customers[i], @@ -714,7 +670,6 @@ function OpenBossActionsMenu() end) end - function OpenGetStocksMenu() ESX.TriggerServerCallback('esx_vehicleshop:getStockItems', function (items) local elements = {} @@ -772,8 +727,7 @@ function OpenPutStocksMenu() end end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', { title = _U('inventory'), align = 'top-left', elements = elements @@ -793,11 +747,9 @@ function OpenPutStocksMenu() menu.close() OpenPutStocksMenu() end - end, function (data2, menu2) menu2.close() end) - end, function (data, menu) menu.close() end) @@ -815,7 +767,6 @@ AddEventHandler('esx:setJob', function (job) if ESX.PlayerData.job.grade_name == 'boss' then Config.Zones.BossActions.Type = 1 end - else Config.Zones.ShopEntering.Type = -1 Config.Zones.BossActions.Type = -1 @@ -847,10 +798,7 @@ AddEventHandler('esx_vehicleshop:hasEnteredMarker', function (zone) CurrentAction = 'give_back_vehicle' CurrentActionMsg = _U('vehicle_menu') - - CurrentActionData = { - vehicle = vehicle - } + CurrentActionData = {vehicle = vehicle} end elseif zone == 'ResellVehicle' then @@ -869,14 +817,14 @@ AddEventHandler('esx_vehicleshop:hasEnteredMarker', function (zone) break end end - + resellPrice = ESX.Math.Round(vehicleData.price / 100 * Config.ResellPercentage) model = GetEntityModel(vehicle) plate = ESX.Math.Trim(GetVehicleNumberPlateText(vehicle)) - + CurrentAction = 'resell_vehicle' CurrentActionMsg = _U('sell_menu', vehicleData.name, ESX.Math.GroupDigits(resellPrice)) - + CurrentActionData = { vehicle = vehicle, label = vehicleData.name, @@ -911,7 +859,6 @@ AddEventHandler('onResourceStop', function(resource) ESX.UI.Menu.CloseAll() DeleteShopInsideVehicles() - local playerPed = PlayerPedId() FreezeEntityPosition(playerPed, false) @@ -927,7 +874,7 @@ if Config.EnablePlayerManagement then local specialContact = { name = _U('dealership'), number = 'cardealer', - base64Icon = 'data:image/x-icon;base64,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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroMD5K6G8+SuinPkro2z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87Rt3/Mzy+/zI7u+AyPLysMju7cjI7vDUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SuhcPkropz5K6O8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTW/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uvEyPLysMju7YDI7uxYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroDD5K6GQ+Sui7Pkro+z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zZBy/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/DI7vMEyO7tnMju7DgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroOD5K6J8+Suj3Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zxI4/80PsP/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r4Mjy9ozI7vD0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugEPkroXD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87Rt3/Mzy+/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u9MyO7tgMju8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugIPkrobz5K6N8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTW/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7vfMjy9dDI7vAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugEPkroYD5K6N8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zZBy/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju73zI8vWQyO7wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroPD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zxI4/80PsT/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u9MyO7tAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroFD5K6KM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R97/Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yPL2oMju7FgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6GA+SujvPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTW/zI7u/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7rxMjy9ZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SuivPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzf8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy9sDI7uxYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhEPkro4z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zxI4/80PsX/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju65jI8vUgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkrodz5K6Ps+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R97/Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/DI7vH0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroDD5K6Kc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTW/zI7u/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI8vawyO7sOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Bg+SujLPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzf8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u84yO7sbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugoPkro3z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zxI4/80PsX/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uuIyO7orAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6Oc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R97/Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uuoyO7orAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Dw+SujzPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTW/zI7u/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uvUzPL8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugoPkro8z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzf8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uvEyO7orAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6Oc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1I5P80PsX/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uuoyO7orAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Bg+SujfPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R9//Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uuIyO7sbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugMPkroyz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTX/zI7vP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u84yO7sOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Kc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI8vawAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+Suh3Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1I5P81P8X/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7vH0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroRD5K6Ps+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R9//Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/DI8vUgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTX/zI7vP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju65jI7uxYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkrorz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy9swAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6GA+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1I5P81P8X/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy9ZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugUPkro7z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R9//Mzy//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7rxMju7FgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6KM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OUTX/zI7vP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yPL2oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+Sug8Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdBzv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7tAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroBD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1J5f81P8X/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u9MyO7wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhgPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R+D/Mz3A/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI8vWQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroCD5K6N8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OkXY/zI7vP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju73zI7vAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhvPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdC0P8yO7r/Mju6/zI7uv8yO7r/Mju6/zI6uP8yOqn/Mjqp/zI6q/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI6qf8yOqn/Mjqp/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy9dAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroBD5K6N8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1J5f81P8b/Mju6/zI7uv8yO7r/Mju6/zI4j/8yNV3/MzM3/zMzM/8zMzP/MzMz/zMzO/8yNWP/Mjmg/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/MjmY/zI1X/8zMzn/MzMz/zMzM/8zMzP/MzM5/zI1X/8yOZj/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7vjMju8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhcPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R+D/Mz3A/zI7uv8yO7r/Mju6/zI6rf8yNVr/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjZr/zI6tf8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjqz/zI1X/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8yNV//Mjqz/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7tgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OkXY/zI7vP8yO7r/Mju6/zI7uv8yOq3/MjRI/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjRS/zI6s/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI6s/8yNEr/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8yNEj/Mjqx/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u9MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+Sug4Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUnn/zdC0P8yO7r/Mju6/zI7uv8yO7r/Mjq4/zI0Tv8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjVn/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/MjVa/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8yNVj/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7vD0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6J8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1J5f81P8b/Mju6/zI7uv8yO7r/Mju6/zI7uv8yN37/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjmY/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI4jf8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8yN4n/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy9owAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugMPkro9z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P87R+D/Mz3A/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zMzQf8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8yNVv/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/MjRO/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zI0Tv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r4Mju7DgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6GQ+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OkXY/zI7vP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yOZ7/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzN/8yOrP/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI6rf8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zI6qf8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7tn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MjVl/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zI3fv8yO7r/IILV/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/H4fW/zI7uv8yNnD/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjZt/zI7uv8oY8n/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8nZcr/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI8vTUAAAAAAAAAAD5K6G8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/xyi6/8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Ho3Z/zI7uv8yOqn/MzM5/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zNEP/Mjq1/zI7uv8XqOP/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Vr+b/Mju6/zI6sf8zMz3/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzPf8yOq//Mju6/x+H1v8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yJ60v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy+cgAAAAAAAAAAPkropz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Kn7q/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Tuen/MEO9/zI7uv8yN4n/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzM5/zI5nv8yO7r/K1TD/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8pXcb/Mju6/zI4lv8zMzX/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzX/MjiU/zI7uv8xP7v/E7fp/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8RwOz/Lkm//zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv81P8epAAAAAAAAAAA+SujbPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P86U+j/EcDt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8hgNT/Mju6/zI7uv8yN4f/MzM3/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzP/8yOJr/Mju6/zI7uv8anN7/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xii4f8yO7r/Mju6/zI4kv8zMzv/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzM5/zI4kv8yO7r/Mju6/yJ60v8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xuY3f8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/N0LP/z1J59sAAAAAPkroDD5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8fnOv/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHA7P8rVsT/Mju6/zI7uv8yOaX/MjVd/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzN/8yNmf/Mjqv/zI7uv8yO7r/JW/O/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yN20P8yO7r/Mju6/zI6qf8yNWX/MzM1/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzM1/zI1Yf8yOqn/Mju6/zI7uv8rVMP/Er7r/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/KV/H/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju8/zpF2P8+Suj/Pkro/zlF2Qw+Sug0Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/y9v6f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xS16P8sUML/Mju6/zI7uv8yO7r/Mjqr/zI3hf8yNnL/MjZl/zI2dP8yOIv/Mjqv/zI7uv8yO7r/Mju6/yhhyP8RwOz/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcDs/ydny/8yO7r/Mju6/zI7uv8yOq//MjiJ/zI2dP8yNmX/MjZ0/zI4if8yOq//Mju6/zI7uv8yO7r/LFDC/xS16P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xar5P8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zM9wf88R+D/Pkro/z5K6P8+Suj/PEfhND5K6Fw+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUzo/xS47P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xO36f8oYcj/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8kdM//EcDs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcDs/yN20P8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/ylcx/8Utej/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/JHTP/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv81P8j/PUnl/z5K6P8+Suj/Pkro/z5K6P88SONcPkrogz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/JI3r/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8ckdr/LFLC/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8pX8f/GKLh/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xik4v8oYcj/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yxQwv8dj9r/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xO56f8wQbz/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/OELR/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1J5oM+SuifPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P81YOn/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Fqvk/x+H1v8jdtD/JW7N/yN40f8ejdn/FLPn/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Us+f/HY/Z/yN40f8lbs3/JHTP/x+H1v8XqOP/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/H4fW/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mjy9/zpG2/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkronz5K6L8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8Yrez/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8sUML/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zQ+w/88SOL/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Sui/Pkro1z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/ymA6v8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Gpze/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv82QMv/PUnm/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Nc+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OVXo/xHA7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8oY8n/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/OUTW/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro4z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Hp7r/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/FbHm/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mzy//ztH3v8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8vcen/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8jeNH/Mju6/zI7uv8yO7r/Mju6/zQ+xf88SOP/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zxN6P8UuOz/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Er7r/zBDvf8yO7r/Mju6/zI7uv83Qc7/PUnn/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/ySP6/8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8ei9j/Mju6/zI7uv8yO7z/OUTY/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/LnPp/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yZpy/8yO7r/Mz3A/ztH4P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P85Vej/Er7s/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/F6jj/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/GKLh/xHC7f8Rwu3/EcLt/xyV3P8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/xat5f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Svuv/L0e+/zU/x/89SeX/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8td+r/EcDt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8ejdn/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8lbs3/EcLt/xHC7f8Rwu3/LkzA/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/G5jd/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcDt/yVuzv84QtH/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P81YOn/Jojq/yKV6/8ilev/IpXr/yKV6/8ilev/IpXr/yKV6/8ilev/HaLr/xHC7f8Rwu3/EcLt/x2P2v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yVuzf8Rwu3/EcLt/xHC7f8uTMD/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8WreX/EcLt/xHC7f8Vr+X/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/HY/a/x2P2v8dj9r/H5Hg/yKV6/8ilev/IpXr/yaK6v81Xeb/OkXa/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8yaOn/EcLt/xHC7f8Rwu3/HY/a/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/JW7N/xHC7f8Rwu3/EcLt/y5MwP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/MEG8/xHC7f8Rwu3/EcLt/yJ60v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zU/x/89SeX/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro4z5K6Nc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zJo6f8Rwu3/EcLt/xHC7f8dj9r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8lbs3/EcLt/xHC7f8Rwu3/LkzA/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8pXcb/EcLt/xHC7f8Rwu3/KV/H/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv83Qs7/PUnn/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujXPkrovz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/M2bp/xHC7f8Rwu3/EcLt/xqa3v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yVuzf8Rwu3/EcLt/xHC7f8uTMD/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yF+0/8Rwu3/EcLt/xK76v8xP7v/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/OUPV/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6L8+SuifPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P84Wej/EcLt/xHC7f8Rwu3/GaDg/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/JW7N/xHC7f8Rwu3/EcLt/y5MwP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Fqvk/xHC7f8Rwu3/HZHa/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju8/zpF2v8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkronz5K6IM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/ztR6P8Rwu3/EcLt/xHC7f8ZoOD/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8lbs3/EcLt/xHC7f8Rwu3/LkzA/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/ydnyv8Rwu3/EcLt/xHC7f8pXMb/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zM8v/87R+D/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuiDPkroXD5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/xO87P8Rwu3/EcLt/xWv5f8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yVuzf8Rwu3/EcLt/xHC7f8uTMD/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8xPbr/Fa/m/xHC7f8Rwu3/F6nj/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv80PsP/PEjj/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Fw+Sug0Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/GK3s/xHC7f8Rwu3/FbHm/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/JW7N/xHC7f8Rwu3/EcLt/y5MwP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/yVtzf8Rwu3/EcLt/xHC7f8ma8z/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/NUDI/z1J5f8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroND5K6Aw+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8fnOv/EcLt/xHC7f8Rwu3/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8lbs3/EcLt/xHC7f8Rwu3/LkzA/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8xPbr/Fa/m/xHC7f8Rwu3/Fa/m/zE9uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zdCz/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SugMAAAAAD5K6Ns+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/yaI6v8Rwu3/EcLt/xHC7f8wQ73/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/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Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/ymA6v8TvOz/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHA7f8fnOv/N1vo/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6M8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroXD5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zlV6P8kjer/FLjs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xmr7P8nhur/OFno/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugEPkro4z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P88Tej/MWzp/yaK6v8cpOv/Fbbs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Svuz/FrPs/xum7P8gmOv/J4bq/y9v6f85Vej/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6N8+SugEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhvPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zhZ6P84Wej/OFno/zhZ6P84Wej/OFno/zhZ6P84Wej/OFno/zhZ6P88Tej/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkrobwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Ag+SujfPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6N8+SugIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6GA+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroBD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6M8+SugEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroPD5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkrooz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6KMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugUPkro7z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujvPkroFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhgPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuivPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuivAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro4z5K6BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6EQ+Suj7Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Ps+SuhEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Hc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkrodwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Kc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6KcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroDD5K6Ms+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujLPkroDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroGD5K6N8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro3z5K6BgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6Oc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Oc+SugoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6PM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujzPkroKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroPD5K6PM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro8z5K6DwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6Oc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Oc+SugoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6N8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujfPkroKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroGD5K6Ms+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkroyz5K6BgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroDD5K6Ks+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Kc+SugMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Hc+Suj7Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Ps+Suh3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6EQ+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujjPkroRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SuivPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkrorz5K6BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhgPkro7z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro7z5K6GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugUPkrooz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6KM+SugUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroPD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6M8+Sug8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroBD5K6GA+SujfPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6N8+SuhgPkroBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Ag+SuhvPkro3z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6N8+SuhvPkroCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugEPkroXD5K6M8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6M8+SuhcPkroBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Dg+SuifPkro9z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro9z5K6J8+Sug4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugMPkroZD5K6Ls+Suj7Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj7Pkrouz5K6GQ+SugMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6BQ+SuhcPkropz5K6O8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6O8+SuinPkroXD5K6BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6DA+SuhvPkropz5K6Ns+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujbPkropz5K6G8+SugwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Aw+Sug0PkroXD5K6IM+SuifPkrovz5K6Nc+SujjPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujjPkro1z5K6L8+SuifPkrogz5K6Fw+Sug0PkroDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD////////wAAAP////////////////AAAAAP//////////////8AAAAAAP/////////////4AAAAAAAf////////////4AAAAAAAB////////////wAAAAAAAAD///////////wAAAAAAAAAP//////////wAAAAAAAAAA//////////4AAAAAAAAAAH/////////4AAAAAAAAAAAf////////8AAAAAAAAAAAD////////8AAAAAAAAAAAAP///////+AAAAAAAAAAAAB////////AAAAAAAAAAAAAP///////AAAAAAAAAAAAAA///////gAAAAAAAAAAAAAH//////wAAAAAAAAAAAAAA//////4AAAAAAAAAAAAAAH/////8AAAAAAAAAAAAAAA/////+AAAAAAAAAAAAAAAH/////AAAAAAAAAAAAAAAA/////gAAAAAAAAAAAAAAAH////wAAAAAAAAAAAAAAAA////8AAAAAAAAAAAAAAAAP///+AAAAAAAAAAAAAAAAB////AAAAAAAAAAAAAAAAAP///gAAAAAAAAAAAAAAAAB///4AAAAAAAAAAAAAAAAAf//8AAAAAAAAAAAAAAAAAD//+AAAAAAAAAAAAAAAAAAf//gAAAAAAAAAAAAAAAAAH//wAAAAAAAAAAAAAAAAAA//4AAAAAAAAAAAAAAAAAAH/+AAAAAAAAAAAAAAAAAAB//AAAAAAAAAAAAAAAAAAAP/wAAAAAAAAAAAAAAAAAAD/4AAAAAAAAAAAAAAAAAAAf+AAAAAAAAAAAAAAAAAAAH/gAAAAAAAAAAAAAAAAAAB/wAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAD+AAAAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAAAAAAH4AAAAAAAAAAAAAAAAAAAB8AAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAPgAAAAAAAAAAAAAAAAAAAH4AAAAAAAAAAAAAAAAAAAB+AAAAAAAAAAAAAAAAAAAAfwAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAD/gAAAAAAAAAAAAAAAAAAB/4AAAAAAAAAAAAAAAAAAAf+AAAAAAAAAAAAAAAAAAAH/wAAAAAAAAAAAAAAAAAAD/8AAAAAAAAAAAAAAAAAAA//gAAAAAAAAAAAAAAAAAAf/4AAAAAAAAAAAAAAAAAAH//AAAAAAAAAAAAAAAAAAD//4AAAAAAAAAAAAAAAAAB//+AAAAAAAAAAAAAAAAAAf//wAAAAAAAAAAAAAAAAAP//+AAAAAAAAAAAAAAAAAH///gAAAAAAAAAAAAAAAAB///8AAAAAAAAAAAAAAAAA////gAAAAAAAAAAAAAAAAf///8AAAAAAAAAAAAAAAAP////AAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAB/////AAAAAAAAAAAAAAAA/////4AAAAAAAAAAAAAAAf/////AAAAAAAAAAAAAAAP/////4AAAAAAAAAAAAAAH//////AAAAAAAAAAAAAAD//////4AAAAAAAAAAAAAB///////AAAAAAAAAAAAAA///////8AAAAAAAAAAAAA////////gAAAAAAAAAAAAf///////8AAAAAAAAAAAAP////////wAAAAAAAAAAAP////////+AAAAAAAAAAAH/////////4AAAAAAAAAAH//////////AAAAAAAAAAD//////////8AAAAAAAAAD///////////wAAAAAAAAD////////////gAAAAAAAH////////////+AAAAAAAH/////////////8AAAAAAP//////////////8AAAAA////////////////8AAAD////////ygAAABgAAAAwAAAAAEAIAAAAAAAgJQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroCD5K6Ck9SedOPkrodz5K6Js9See9Pkro1j5K6Ok9Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89SefpPkro1j5K6L08SOSbO0fgdzdC0U4zPcEsMjy9CQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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Mju6/zE6uf4yO7r/Mju6/zI6sP4zMzb/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjL+MzMz/zMzM/8yNWL+Mjq5/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mjq5/zI1Wv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIzOv4yOrX/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uv0yO7srAAAAAAAAAAAAAAAAAAAAAD1J54A+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/O0fg/zQ9wv4yO7r/Mju6/zE6uf4yO7r/Mju6/zI4lf4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjL+MzMz/zMzM/8yNEj+Mjq0/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mjqx/zIzQ/4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4yOZ3/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7uDAAAAAAAAAAAAAAAAPUnnCD1J5809Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/46Rdn+Mjy9/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jI3h/4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yM0P+Mjqx/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+Mjqt/jIzO/4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yOJP+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4yO7rPMju6CQAAAAAAAAAAPkroKD1J5/g+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Suf+NGPp/yWI5/4ei9n/HovY/x6L2P4ei9j/HovY/x6L2P4ei9j/JmrM/zI4kv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjL+MzMz/zMzM/8yNEf+MD+1/yCB1P8ei9j+HovY/x6L2P8ei9j+HovY/x6L2P8ei9j+HovY/x6L2P8ei9j+HovY/x6L2P8ei9j+HovY/x6L2P8ei9j+HovY/x6L2P4fhdb/MEGz/zIzQf4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4yOZz/KGPJ/x6L2P4ei9j/HovY/x6L2P4ei9j/HovY/x6L2P4eitj/JHLO/zBDvf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r5Mju6KgAAAAAAAAAAPkroaT1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P8xa+n+E7vs/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/HY3Z/zI6rv4zMzX/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjL+MzMz/zMzM/8yNV7+L0a9/xO26P8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Suur/Lke9/zI0V/4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIzOP4yOrT/H4jX/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xmg4P4xPLr/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6awAAAAAAAAAAPUnnrD1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1K5/4couv+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+GKPh/jE7uv4yNWL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyM/4yOJf+K1TD/hHB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+KlfE/jI4jf4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jIyMv4yMjL+MjIy/jI2af4xOrn+GKHg/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4oX8f+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+Mju7sAAAAAA+SugIPkro4D1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P8enuv+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/Errq/y1Pwf4yOaX/MjNA/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjL+MzMz/zI1Yf8xOrn+IX3T/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/IIPV/zE6uP4yNVr/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4zMzP/MjNE/zI5qv4tTMD/E7np/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xHB7P4qWcX/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju84DQ+xgg+SugpPkro8z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P8udOn+EcHt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/x+H1v4yO7r/MjiW/zIzQP4zMzP/MzMz/zIyMv4zMzP/MzMz/zMzM/8yMjP+MjVc/zI6sf8vRr7+FLLm/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/FLTo/y5Iv/4yOq3/MjRW/zIyM/4zMzP/MzMz/zIyMv4zMzP/MzMz/zIyMv4yM0P/Mjmd/zE6uf4ggtT/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xap4/4xO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7z/OUTW8zhD1Ck9SedOPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/46Uuj+FbXs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hHA7P4pX8f+MTq5/jI6rv4yNmv+MjND/jIzM/4yMjL+MjM3/jI0Tv4yN4f+MTq4/jE8uv4cktv+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/huW3P4xPbr+Mjq2/jI3hP4yNEz+MjM2/jIyMv4yMzT+MjRF/jI2b/4yOrD+MTq5/ildx/4Rv+z+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EcHs/iVvzf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jM9wP47R9/+PUnn/jtG3k0+Suh3Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+I5Hq/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Ttuj/KGHI/zE7uv4yOrn/Mjqx/zI5p/4yOZ7/Mjqq/zI6tf8xOrn+MEG8/x+G1v8Rwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xHB7P4eitj/MEG8/zE6uf4yOrX/Mjqq/zI5nv4yOaj/Mjqy/zE6uf4xO7r/KV/H/xO26P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/FLPn/y9Evf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/NT/I/zxI4/4+Suj/Pkro/zxI43c+SuibPkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+M2Xp/xHB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/Er3r/x+G1v4uSL7/Mju6/zE6uf4yO7r/Mju6/zI7uv8pX8f+GKLh/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/GKPh/yhgyP4yO7r/Mju6/zE6uf4yO7r/Mju6/y9Gvv4fhdb/Erzq/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/H4XW/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE7uv43QtD/PUnm/z1J5/4+Suj/Pkro/z1J5ps9See9PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PE7o/hmr6/4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Rv+z+GKLh/h6K1/4gg9X+HJLb/hWx5v4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Useb+HJLb/iCD1f4eidf+GaHg/hG/7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4SvOr+LFDB/jE6uf4xOrn+MTq5/jE6uf4xOrn+Mzy+/jpF2f49Sef+PUnn/j1J5/49Sef+PUnn/j1J570+SujWPkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/yiD6v4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4bmN3/MTy6/zE6uf4yO7r/Mju6/zE6uf40PsP/O0fg/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J59Y+SujpPkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/zhY6P4Rwe3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4oYcj/Mju6/zE6uf4yO7r/Mju6/zZAyf49SeX/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5+k9Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/4doev+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hWt5f4xOrn+MTq5/jE6uf4yO7v+OEPT/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4tden/EcHt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcHs/yN1z/4yO7r/Mju6/zM8v/46Rtv/PUnn/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/46U+j/Fbbs/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/E7bo/y5Hvv4yO7r/ND7E/zxH4f4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+HaHr/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+GZ3f/jE7uv43Qc7+PUnm/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/L3Hp/xK/7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/JmrM/ypYxf4qWMX/KljF/ypYxf8qWMX+KljF/ypYxf8qWMX+KljF/ypYxf8qWMX+KljF/yN20P8Qwez+EcLt/yJ80v8qWMX+KljF/ypYxf8qWMX+KljF/ypYxf8qWMX+KljF/ypYxf8qWMX+KljF/ypYxf4qWMX/KljF/ypYxf4qWMX/KljF/x6K2P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rwu3/EcLt/xDB7P4Rvuz/J2jO/zlE1f49Sef/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUvo/zBu6f4gmOv/HaDr/x2g6/4doOv/HaDr/x2g6/4doOv/FLjs/xDB7P4Rwu3/KljF/zE6uf4yO7r/Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/x2O2f4Rwu3/Eb7r/xme3/4anN7/Gpze/xqc3v4anN7/Gpze/xqc3v4anN7/Gpze/xud4v4doOv/HaDr/yCa6/4ua+L/Okfe/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/49SefpPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+Hpzr/hDB7P4Qwez+KljF/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/ihhyP4Qwez+EMHs/iZpy/4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MT27/hel4v4Qwez+Fqrk/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+ND7E/jxI4v49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5+k+SujWPkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/H5zr/xDB7P4Rwu3/KlvG/zE6uf4yO7r/Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/Lki//xO56f4Rwu3/HovY/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zE7uv41QMn/PUjk/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J59Y+Sui9Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/IpPr/xDB7P4Rwu3/J2XK/zE6uf4yO7r/Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mju6/zE6uf4yO7r/J2bK/xDB7P4Rwu3/KGDI/zE6uf4yO7r/Mju6/zE6uf4yO7r/Mju6/zZBzf49Seb/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5709SeebPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+JYrq/hDB7P4Qwez+JmfK/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/ihhyP4Qwez+EMHs/iZpy/4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4wP7v+GKXi/hDB7P4Wq+T+MEG8/jE6uf4xOrn+MTq5/jE6uf4yO7v+OEPU/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J55s+Suh3Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/K3zq/xDB7P4Rwu3/JHHO/zE6uf4yO7r/Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/Mju6/zE6uf4masz/EcDs/xDB7P4jdtD/Mju6/zE6uf4yO7r/Mju6/zI8vf46Rdr/PUnn/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J53c9SedOPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+MWzp/hDB7P4Qwez+InvS/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/ihhyP4Qwez+EMHs/iZpy/4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE8uv4WquT+EMHs/hO36P4wQrz+MTq5/jE6uf4xOrn+MzzA/jtG3v49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+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Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj4PkroKAAAAAAAAAAAPUnnCD1J5809Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/4kjOr+EMHs/hem4v4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/ihhyP4Qwez+EMHs/iZpy/4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/iRxzv4Qwez+EMHs/h2N2P4zPcD+O0fe/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49SefNPUnnCAAAAAAAAAAAAAAAAD1J538+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/44WOj/FLfs/xDB7P4nZ8v/Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+JmrL/xK96/4Rwu3/GKTh/zJGyP48SOP/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suh/AAAAAAAAAAAAAAAAAAAAAD1J5yg+Suj9Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Kn3q/xHA7P4Vsuf/LVHF/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/yhhyP8Qwez+EcLt/yZpy/8xOrn+Mju6/zI7uv8xOrn+Mju6/zI7uv8xOrn+Mju6/zE+u/8iedH+Erzq/xDB7P4WrOX/MVPR/z1J5f4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/0+SugoAAAAAAAAAAAAAAAAAAAAAAAAAAA9SefGPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PEzo/iKT6v4Qwez+FbHo/ihmzf4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xOrn+MTq5/ihhyP4Qwez+EMHs/iZpy/4xOrn+MTq5/jE6uf4xOrn+MTq5/jE6uf4xPbr+KGLJ/hmf4P4Qwez+EMHs/hes6P4zVNj+PUnm/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J58YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhdPkro/j1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1L5/4jkev/EcDt/xHC7f8UtOj+GZ7f/xqc3v8anN7+Gpze/xqc3v8anN7+Gpze/xem4v8Qwez+EcLt/xep4/8anN7+HJLa/x2P2f8fiNf+HY7Z/xqb3v8Tt+n+EcLt/xHC7f8Svuz+IpLr/zpS6P4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/j1J510AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugQPkro3z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/49TOj/L3Hp/xms7P8RwOz+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xHC7f8Rwez+Fbfs/yGW6/80Y+n+PUvo/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro3z1J5w8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnnfj1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/jxO6P4xa+n+JYzq/hqo6/4Tu+z+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EMHs/hDB7P4Qwez+EcHs/hS47P4Zq+z+H5zr/iaH6v4wben+OlTo/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnnewAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroGD1J5+g+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+O0/o/zlV6P85Vej+OVXo/zlV6P85Vej+OVXo/zlV6P89TOj+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+SujoPkroGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J53g+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suh4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J5w49SefkPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5+Q9SecOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhaPkro+z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro+z1J51oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugFPkrouD1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/PkrouD1J5wUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnnLj1J5/A9Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49SefwPUnnLgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J52o+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+SuhqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J5wM+SuixPkro/j5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/j1J57A+SugDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SecaPUnn2j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn2j1J5xoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroND5K6Ow9Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+SujsPkroNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6FM9Sef5Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/k+SuhTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SedxPUnn+j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn+j1J53EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkrodz1J5/w+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj8PkrodwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroBD1J53c+Suj6Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/o+Suh3PkroBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SedxPUnn+T1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn+T1J53EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroUz1J5+0+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+SujsPkroUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J5zU+SujaPkro/j1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/j1J59o+Sug0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SecaPUnnsT1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnnsD1J5xoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroAz1J52o+SujwPkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/A+SuhqPkroAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuguPkrouD1J5/s+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj7PkrouD1J5y4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnnBj1J51o9SefkPUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5+Q9SedaPUnnBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugOPkroeD1J5+g+Suj/Pkro/z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+SujoPkroeD1J5w4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J5xg+Suh8Pkro3z1J5/4+Suj/Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj+Pkro3z1J53s+SugYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnnDz1J5109SefGPUnn/T1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49Sef+PUnn/T1J58Y9SeddPUnnDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroKD5K6IA9SefNPkro+D5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/Pkro/z1J5/4+Suj/Pkro+D1J580+Suh/PkroKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SecIPkroKD5K6Gk9SeesPkro4D5K6PM9Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+SujzPkro4D1J56w+SuhpPkroKD1J5wgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnnBz1J5yk9SedNPUnndz1J55s9See9PUnn1j1J5+k9Sef+PUnn/j1J5/49Sef+PUnn/j1J5/49SefpPUnn1j1J5709SeebPUnndz1J5009SecpPUnnBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////+AAAH///////////gAAAAf/////////+AAAAAH/////////wAAAAAA/////////AAAAAAAP///////8AAAAAAAD///////wAAAAAAAA///////gAAAAAAAAf/////+AAAAAAAAAH/////8AAAAAAAAAD/////4AAAAAAAAAB/////wAAAAAAAAAA/////gAAAAAAAAAAf///+AAAAAAAAAAAH///+AAAAAAAAAAAH///8AAAAAAAAAAAD///4AAAAAAAAAAAB///wAAAAAAAAAAAA///gAAAAAAAAAAAAf//AAAAAAAAAAAAAP//AAAAAAAAAAAAAP/+AAAAAAAAAAAAAH/8AAAAAAAAAAAAAD/8AAAAAAAAAAAAAD/4AAAAAAAAAAAAAB/4AAAAAAAAAAAAAB/wAAAAAAAAAAAAAA/wAAAAAAAAAAAAAA/gAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAfAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAPgAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAfwAAAAAAAAAAAAAA/wAAAAAAAAAAAAAA/4AAAAAAAAAAAAAB/4AAAAAAAAAAAAAB/8AAAAAAAAAAAAAD/8AAAAAAAAAAAAAD/+AAAAAAAAAAAAAH//AAAAAAAAAAAAAP//AAAAAAAAAAAAAP//gAAAAAAAAAAAAf//wAAAAAAAAAAAA///4AAAAAAAAAAAB///8AAAAAAAAAAAD///+AAAAAAAAAAAH///+AAAAAAAAAAAH////gAAAAAAAAAAf////wAAAAAAAAAA/////4AAAAAAAAAB/////8AAAAAAAAAD/////+AAAAAAAAAH//////gAAAAAAAAf//////wAAAAAAAA///////8AAAAAAAD////////AAAAAAAP////////wAAAAAA/////////+AAAAAH//////////gAAAAf//////////+AAAH/////8oAAAASAAAAJAAAAABACAAAAAAAGBUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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Pkro/z5K6P8+Suj/Pkro/zlV6P8wW9X/K1XE/ytVxP8rVcT/K1XE/yxSw/8yOZf/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjVb/y9Hvv8rVcT/K1XE/ytVxP8rVcT/K1XE/ytVxP8rVcT/K1XE/ytVxP8rVcT/K1XE/ytVxP8rVcT/K1XE/y5Iv/8yNFP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Mjmf/yxSwv8rVcT/K1XE/ytVxP8rVcT/K1XE/yxPwf8xPbr/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uoAAAAAAAAAAAD5K6MU+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/LnHp/xO77P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xO26P8wQK//MzM0/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjZw/yF90v8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yCC1P8yNmr/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzb/MT20/xSz5/8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHA7P8bl9z/MTu6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uscAAAAAPkroFz5K6PE9Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Suj/Gavs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hG+6/8tTsH/MjVf/jMzM/8yMjL+MzMz/zIyMv4zMzP/MjIy/jMzM/8zMzX/Mjml/huW3P8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hqZ3f8yOZ/+MzM0/zMzM/8yMjL+MzMz/zIyMv4zMzP/MjIy/jMzM/8yNWX+LUzA/xG96/8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Qwez+KljF/zI7uv8xOrn+Mju6/zE6uf4yO7r/MTq5/jI7uvIzPL8YPkroQz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/IJjr/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8hfNL/Mjmq/zI0Rf8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzNP8yN37/Lki+/xO56f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xK66v8uS8D/MjZ3/zMzNP8zMzP/MzMz/zMzM/8zMzP/MzMz/zI0Sf8yOq3/InnR/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8SvOr/L0O9/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI8vf82Qc1DPkrodD5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/MWvp/hHB7P8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Suur/LU/B/jI6rf8yNmb+MjM8/zIyMv4zMzX/MjRN/jI4kP8xO7r/HJLa/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8clNv+MTy6/zI4jP8yNEz+MzM1/zIyMv4yMz7/MjZp/jI6sP8tTsH+E7np/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8ei9j+Mju6/zI7uv8xOrn+Mju6/zE6uf4yO7r/ND7D/jxH4f87R990PkronT5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PE7o/xex7P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Fa/l/ytWxP8xO7n/Mjqy/zI5p/8yOq3/Mjq3/zBBvP8fiNf/EcHs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwez/HorY/zBBvP8yOrf/Mjqt/zI5p/8yOrP/MTu6/ytUw/8Vr+X/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xG/7P8rVcP/Mju6/zI7uv8yO7r/Mju6/zI7uv82QMv/PUnl/z5K6P89SeWdPkrowT5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/iaI6v8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hK96/8djdn+KGPJ/yxSwv4qWcX/I3fQ/hWt5f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Qwez+EcLt/xWu5f8iedH+KlnF/yxSwv4oYsn/HY3Z/hK86/8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hmf3/8xO7r+Mju6/zI7uv8xOrn+Mju7/zhD1P49Sef/PUnn/j5K6P89SefBPkro3j5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zZd6P8Rwez/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHA7P8Rwez/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcHs/xHA7P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/ydnyv8yO7r/Mju6/zI7uv8zPL//O0bc/z1J5/8+Suj/Pkro/z5K6P8+SujePkro8j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j1K6P8bp+v+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4Rwu3/FbHm/jE+u/8xOrn+Mju6/zQ+xf88SOL+Pkro/z1J5/4+Suj/PUnn/j5K6P89SefyPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8reur/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/InvS/zI7uv8yO7r/N0HO/z1J5v8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P85VOj/E7vs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Su+r/Lkm//zI7vP85RNb/PUnn/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+G6Tr/xDB7P4Rwu3/EMHs/hHC7f8Rwu3/EMHs/hHC7f8Qwez+FLPn/xSy5/4Usuf/FLLn/hSy5/8Usuf/FLLn/hSy5/8Usuf+FLLn/xK96/4Rwu3/E7bo/hSy5/8Usuf/FLLn/hSy5/8Usuf+FLLn/xSy5/4Usuf/FLLn/hSy5/8Usuf+FLLn/xSz5/8Qwez+EcLt/xDB7P4Rwu3/EMHs/hHC7f8Qwez+EcLt/xHC7f8Qwez+EcLt/xDB7P4YoeD/Mz3A/jtH3/89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/M2Xp/xaz7P8Sv+z/Er/s/xK/7P8Sv+z/Eb/s/xHB7f8Rwu3/LFPD/zE/u/8xP7v/MT+7/zE/u/8xP7v/MT+7/zE/u/8xP7v/MT+7/xqc3v8Rwu3/KGDI/zE/u/8xP7v/MT+7/zE/u/8xP7v/MT+7/zE/u/8xP7v/MT+7/zE/u/8xP7v/MT+7/yxTw/8Rwu3/EcHs/xG+6/8Rvuv/Eb7r/xG+6/8Rvuv/Eb7r/xG+6/8Sv+z/Er/s/xay7P8uXtT/PEjk/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro8j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1K5/47Uej/O1Ho/jtR6P87Uej/N1ro/hO77P8Qwez+LFHC/zE6uf4yO7r/MTq5/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/xqb3v4Rwu3/KV3H/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/zE6uf4yO7r/MTq5/jI7uv8xOrn+Mju6/ydnyv8Qwez+HJTb/y9Dvf4wQ73/L0O9/jBDvf8vQ73+MEO9/zVJ0P87Uef+O1Ho/z1L5/49Sef/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89SefyPkro3j5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OlLo/xO67P8Rwu3/K1XD/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/xqb3v8Rwu3/KV3H/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/x+G1v8Rwu3/JHLO/zI7uv8yO7r/Mju6/zI7uv8yO7r/OEPU/z1J5/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujePkrowT5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PE3o/hW17P8Qwez+KlrG/zE6uf4yO7r/MTq5/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/xqb3v4Rwu3/KV3H/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/zE6uf4yO7r/MTq5/jI7uv8xOrn+MEG8/xWw5v8Su+r+Lkm//zE6uf4yO7r/MTq5/jI8vf86Rdn+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89SefBPkronT5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/xit7P8Rwu3/KGPJ/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/xqb3v8Rwu3/KV3H/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/I3fQ/xHB7f8dkNr/MTu6/zI7uv8yO7r/Mzy//ztH3/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuidPkrodD5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/h6d6/8Qwez+JmvM/zE6uf4yO7r/MTq5/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/xqb3v4Rwu3/KV3H/jI7uv8yO7r/MTq5/jI7uv8xOrn+Mju6/zE6uf4yO7r/MTq5/jI7uv8wQLz+FLTo/xG/7P8rU8P+Mju6/zE6uf40PsP/PEji/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sed0PkroQz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/yeG6v8Rwu3/InnR/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/xqb3v8Rwu3/KV3H/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8ieNH/EcLt/xyU2/8xO7r/Mju6/zU/yP89SeX/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/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PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J54YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6A4+SujfPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro3z5K6A4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhVPkro/T5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj9PkroVQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugCPUnnpD5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89SeekPkroAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroEz5K6Nw+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Nw+SugTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Dc+SujxPUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro8T5K6DcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuhYPkro+z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj7PkroWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnncz5K6Pw9Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6Pw9SedzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6H8+Suj8Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/D5K6H8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9SedzPkro+z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj7PUnncwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroWD5K6PI+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6PE+SuhYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Dc+SujcPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro3D5K6DcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugTPUnnpD5K6P0+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P09SeekPkroEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroAj5K6FU+SujfPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro3z5K6FU+SugCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugOPUnnhj5K6PA9Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6PA9SeeGPkroDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6B0+SuiNPkro7D5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujsPkrojT5K6B0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroFD1J52w+SujOPUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P8+Suj/PUnn/j5K6P89Sef+Pkro/z1J5/4+Suj/PUnn/j5K6P89Sef+Pkro/z5K6P89Sef+Pkrozj1J52w+SugUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugCPkroKz5K6H0+SujFPkro8T5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujxPkroxT5K6H0+SugrPkroAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUnnFz5K6EI9Sed0PkronT1J58E+SujePUnn8j5K6P8+Suj/PUnn/j5K6P89SefyPkro3j1J58E+SuidPUnndD5K6EI9SecXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////4AAH////AAAA///+AAAAf///AAAA///4AAAAH///AAAA///gAAAAB///AAAA//+AAAAAAf//AAAA//4AAAAAAH//AAAA//wAAAAAAD//AAAA//gAAAAAAB//AAAA//AAAAAAAA//AAAA/+AAAAAAAAf/AAAA/8AAAAAAAAP/AAAA/4AAAAAAAAH/AAAA/wAAAAAAAAD/AAAA/gAAAAAAAAB/AAAA/AAAAAAAAAA/AAAA+AAAAAAAAAAfAAAA+AAAAAAAAAAfAAAA8AAAAAAAAAAPAAAA8AAAAAAAAAAPAAAA4AAAAAAAAAAHAAAA4AAAAAAAAAAHAAAAwAAAAAAAAAADAAAAwAAAAAAAAAADAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAgAAAAAAAAAABAAAAwAAAAAAAAAADAAAAwAAAAAAAAAADAAAA4AAAAAAAAAAHAAAA4AAAAAAAAAAHAAAA8AAAAAAAAAAPAAAA8AAAAAAAAAAPAAAA+AAAAAAAAAAfAAAA+AAAAAAAAAAfAAAA/AAAAAAAAAA/AAAA/gAAAAAAAAB/AAAA/wAAAAAAAAD/AAAA/4AAAAAAAAH/AAAA/8AAAAAAAAP/AAAA/+AAAAAAAAf/AAAA//AAAAAAAA//AAAA//gAAAAAAB//AAAA//wAAAAAAD//AAAA//4AAAAAAH//AAAA//+AAAAAAf//AAAA///gAAAAB///AAAA///4AAAAH///AAAA///+AAAAf///AAAA////4AAH////AAAAKAAAAEAAAACAAAAAAQAgAAAAAAAAQgAA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Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6vTI7ugYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6J8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P88R+H/ND3B/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7uiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6G0+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P86Rdr/Mjy8/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7u3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6DA+Suj4Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z1J5/84QtH/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r4Mju7MgAAAAAAAAAAAAAAAAAAAAAAAAAA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EcLt/xHC7f8Rwu3/Fa7l/zI5pf8zMzX/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjVj/ypYxf8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/K1XE/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zM8vyk+SuhgPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/yGV6/8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8dkNr/Mjqt/zI0Sf8zMzP/MzMz/zMzM/8zMzP/MzM2/zI4i/8qWcX/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8pXcf/MjeF/zMzNf8zMzP/MzMz/zMzM/8zMzP/MjRM/zI6sP8ejNj/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/E7fo/zE+u/8yO7r/Mju6/zI7uv8yO7r/Mju6/zM8v/84QtJhPkrojz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8yaOn/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcHs/ydlyv8yOrT/Mjd9/zI1V/8yNFD/MjZp/zI5ov8vRL3/Fqzl/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Fa7l/y9Gvv8yOaD/MjZo/zI0UP8yNVj/Mjd//zI6tf8nZcn/EcHs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yCB1P8yO7r/Mju6/zI7uv8yO7r/Mju6/zU+xv89SOT/PEjijz5K6Lc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PUro/xay7P8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rv+z/InvS/zBAvP8yO7r/Mju6/zI7uv8pXcf/Fa7l/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8VruX/KV/H/zI7uv8yO7r/Mju6/zBAvP8ietL/Eb7r/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xG/7P8uSsD/Mju6/zI7uv8yO7r/Mju6/zdBzv89Sef/Pkro/z1J5rc+SujXPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8nhur/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8SvOr/GaDg/xqa3v8Vseb/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Vseb/Gpre/xmf4P8Su+r/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8bltz/Mju6/zI7uv8yO7r/Mju8/zpF2P8+Suj/Pkro/z5K6P8+SujXPkro7j5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/N1ro/xHB7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/KV3H/zI7uv8yO7r/Mz3B/zxH4P8+Suj/Pkro/z5K6P8+Suj/Pkro7j5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8bpev/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Fqvk/zI7uv8yO7r/NT/I/z1J5f8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/LHjp/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/yRxzv8yO7r/OELS/z1J5/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zlX6P8Rwez/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Ervq/xeo4/8XqOP/F6jj/xeo4/8XqOP/F6jj/xeo4/8XqOP/Fq3l/xHC7f8Ttuj/F6jj/xeo4/8XqOP/F6jj/xeo4/8XqOP/F6jj/xeo4/8XqOP/F6jj/xeo4/8VsOb/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHB7P8vS8L/Okbb/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/LHjq/xqo6/8Zq+z/Gavs/xmr7P8Yruz/EcLt/xeo4/8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/ytUw/8Rwu3/H4fW/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/JW7N/xHC7f8VsOb/F6jj/xeo4/8XqOP/F6jj/xeo4/8XqeX/Gavs/xqo6/8pdN//PEji/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujuPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/OFno/xHC7f8XqOP/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8rVMP/EcLt/x+H1v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/x+I1/8Rwu3/K1PD/zI7uv8yO7r/Mju6/zI7uv8zPL//O0ff/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujuPkro1z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/zlU6P8Rwu3/Fa/m/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/K1TD/xHC7f8fh9b/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8Wq+T/FLTn/zE8uv8yO7r/Mju6/zI7uv80PcL/PEjj/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro1z5K6Lc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P89S+j/EcDs/xS06P8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/ytUw/8Rwu3/H4fW/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8oY8n/EcLt/yGA1P8yO7r/Mju6/zI7uv81P8f/PUnm/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Lc+SuiPPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/xaz7P8Svev/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8rVMP/EcLt/x+H1v8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8xO7r/F6jj/xK96/8uR77/Mju6/zI7uv83Qc7/PUnn/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuiPPkroYD5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8enuv/EcLt/zBCvP8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/K1TD/xHC7f8fh9b/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8yO7r/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Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Pc+SugYAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuiVPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/O1Ho/ztR6P87Uej/O1Ho/ztR6P89Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuiVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroGT5K6PM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujzPkroGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+Suh3Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkrodwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroBT5K6NM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro0z5K6AUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugwPkro+D5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro+D5K6DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6G0+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6G0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkronz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6J8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6AY+Sui7Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Ls+SugGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroCj5K6Mg+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Mg+SugKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugKPkrouz5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Ls+SugKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6AY+SuigPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6J8+SugGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6G0+Suj4Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro+D5K6G0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroMD5K6NM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro0z5K6DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugFPkrodz5K6PM+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujzPkrodz5K6AUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugZPkrolT5K6Pc+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Pc+SuiVPkroGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugYPkrogT5K6OU+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro5T5K6IE+SugYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugDPkroRz5K6Jo+SujlPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6OU+SuiaPkroRz5K6AMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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EMHs/hDB7P4Rwu3/EMHs/huV3P4yOZ3/MjRN/jMzM/8yMzj+MjVl/i9Dtv8Vseb+EMHs/hHC7f8Qwez+EMHs/hen4v8xO7r+MTq5/jI7uv8xOrn+NT7F/jpG3Jo+SujEPUnn/j1J5/4+Suj/PUnn/j1J5/40Yun/EcHs/hDB7P4Rwu3/EMHs/hHC7f8XpeL+LFHC/jI6s/4yOq//L0O8/h6L2P4Rwez/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hHB7P4ejNj/L0S8/jI6r/8yOrP+LFDC/hil4v8Qwez+EMHs/hHC7f8Qwez+EMHs/iVuzf8xOrn+MTq5/jI7uv83Qc7+PUnm/j1J5sQ+SujkPkro/z5K6P8+Suj/Pkro/z5K6P89S+j/GKzs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcHs/xas5P8XpuL/Er3r/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/Eb7r/xem4v8Wq+T/EcHs/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/E7bo/zBAvP8yO7r/Mju8/zlE2P8+Suj/Pkro/z5K6OQ+Suj5PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/KYHq/hDB7P4Rwu3/EMHs/hHC7f8Qwez+EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hHC7f8Qwez+EMHs/hHC7f8Qwez+EMHs/hHC7f8Qwez+IILV/jI7uv8zPcD+O0ff/j5K6P89Sef+PUnn/j1J5/k+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/OVfo/hK/7P4Rwu3/EMHs/hHC7f8Qwez+EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hDB7P4Rwu3/EMHs/hHC7f8Qwez+EMHs/hHC7f8Qwez+EMHs/hHC7f8Rv+v+LUzA/jU/x/89SOT+PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/xul6/8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xyR2v8djdn/HY3Z/x2N2f8djdn/HY3Z/xyU2/8Rwu3/G5bc/x2N2f8djdn/HY3Z/x2N2f8djdn/HY3Z/x2N2f8djdn/FLTn/xHC7f8Rwu3/EcLt/xHC7f8Rwu3/EcLt/xHC7f8ZoeH/OELR/z1J5/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj5PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/jpT6P4uc+n/LXXp/i116f8jj+r+EMHs/i5Jv/4yO7r/MTq5/jE6uf4yO7r/MTq5/i1Owf4Rwu3/LFLC/jE6uf4yO7r/MTq5/jE6uf4yO7r/MTq5/jE6uf4xO7r/Fa7l/h2Q2v8ma8z+JmvM/iZrzP8mbM7+LHPl/i5z6f85UeT+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j1J5/k+SujkPUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P8vcOn+EMHs/i1Nwf4yO7r/MTq5/jE6uf4yO7r/MTq5/i1Owf4Rwu3/LFLC/jE6uf4yO7r/MTq5/jE6uf4yO7r/MTq5/jE6uf4uSb//Eb/s/ipYxf8xOrn+MTq5/jM8vv87R9/+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j1J5+Q+SujEPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8zZun/EcLt/ytTw/8yO7r/Mju6/zI7uv8yO7r/Mju6/y1Owf8Rwu3/LFLC/zI7uv8yO7r/Mju6/zI7uv8yO7r/Mju6/zI7uv8ghNX/F6nj/zE8uv8yO7r/ND7D/zxI4/8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6MQ+SuiaPUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P85Vuj+EcHs/ildx/4yO7r/MTq5/jE6uf4yO7r/MTq5/i1Owf4Rwu3/LFLC/jE6uf4yO7r/MTq5/jE6uf4yO7r/MTq5/i5Hvv4SvOr/JmvM/jI7uv81P8j+PUnl/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j1J55o+SuhlPUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89S+j+FrLs/iVtzf4yO7r/MTq5/jE6uf4yO7r/MTq5/i1Owf4Rwu3/LFLC/jE6uf4yO7r/MTq5/jE6uf4yO7r/MTq5/h+I1/4WquT/MT27/jdBzv89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j1J52U+SugkPkro/T5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/I4/q/x2O2f8yO7r/Mju6/zI7uv8yO7r/Mju6/y1Owf8Rwu3/LFLC/zI7uv8yO7r/Mju6/zI7uv8yO7r/K1XD/xG+6/8oYsn/OUPV/z5J6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/T5K6CQ+SugCPUnn0j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+Nl7o/hO46v4vRr7/MTq5/jE6uf4yO7r/MTq5/i1Owf4Rwu3/LFLC/jE6uf4yO7r/MTq5/jE6uf4vRr7/Fqzk/h6O3P46Rdr/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn0j1J5wIAAAAAPkroez5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/yaH6v8aneD/L0a+/zI7uv8yO7r/Mju6/y1Owf8Rwu3/LFLC/zI7uv8yO7r/MTu6/ylfx/8VruX/HJvk/zpL4f8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/PkroewAAAAAAAAAAPUnnGz1J5/Y+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1K5/4og+r/E7jr/hWv5v4Vr+X/Fa/l/hWx5v4Rwu3/FLLn/hep4/4XpuL/FLXo/ha07P4pf+r/PUzo/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef2PUnnGwAAAAAAAAAAAAAAAD1J558+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/OlPo/i5y6f4nher/JYvq/iWL6v4li+r/Jonq/iiD6v4tdun/NGLp/j1M6P4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89SeeeAAAAAAAAAAAAAAAAAAAAAD5K6CE+Suj4Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6Pg+SughAAAAAAAAAAAAAAAAAAAAAAAAAAA+SuiFPUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6IUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugLPUnn1j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn1j5K6AsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPkroMz5K6PU+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj1PkroMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J510+Suj9PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P09SeddAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+Suh4PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6HgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugBPkroeD5K6P0+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj9PkroeD5K6AEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1J510+Suj1PUnn/j5K6P89Sef+PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j1J5/4+Suj/PUnn/j5K6P89Sef+PUnn/j5K6P89Sef+PUnn/j5K6PU9SeddAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SuiTAAAAAAAAAAAAAAAAAAAAAD5K6Aw+SujYPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro2D5K6AwAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Ck+SujuPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6O4+SugpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Dc+SujuPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+SujuPkroNwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Ck+SujYPkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro2D5K6CkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5K6Aw+SuiTPkro/D5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/D5K6JM+SugMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+SugrPkrooz5K6Pg+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro/z5K6P8+Suj/Pkro+D5K6KM+SugrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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', + base64Icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAMAAABrrFhUAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAADMzMzszM0M0M0w0M1Q1M101M2U2M242M3Y3M383Moc4MpA4Mpg5MqE5Mqk6MrI6Mro7Mrw8Mr89M71DML5EO8I+NMU/NcBMLshANctBNs5CN8RULMddKsheKs9YLtBCONZEOdlFOtxGO99HPNhMNsplKM1nKM1uJtRhLddiLt5kMNJwJ9B2JNR/IeNIPeVJPehKPuRQOuhSO+lZOOlhNuloM+p3Lep/KupwMMFORsVYUcplXc1waNJ7delUSepgVexrYe12bdeHH9iIH9qQHd2YG+udH+OEJeuGJ+uOJeuVIuChGeSpF+aqGOykHOysGeeyFeuzFuyzFuq6E+27FO+Cee3CEdaGgdqTjvCNhfKYkvOkngAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJezdycAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjb9TgnoAAAQGElEQVR4Xt2d+WMUtxXHbS6bEGMPMcQQ04aEUnqYo9xJWvC6kAKmQLM2rdn//9+g0uir2Tl0PElPszP7+cnH7Fj6rPTeG2lmvfKld2azk8lk/36L/cnkZDbDIT3Sp4DZ8QS9dTI57tNDTwJOOu+4j/0TvDQz+QXMSG+7mUn+sZBZQELnNROcKhMZBXx+gS4k8+IzTpmBXAJOnqPxTDzPFRKyCODuvSKPgwwC2EZ+lxf4E4xwCzhBU7PBPQx4BWR88+fwDgNGAbMsM9/Ec8bygE3A5966L3nOlhiZBGSf+l2YggGLgBna1DMsE4FBQH9zvw1HLEgX0Evkt5GeEVIFMFztpJF6rZQm4DNasVDSEkKSgIVN/ibP0ZwoEgQsfPTPSZgH8QIG8vYr4gdBrIABvf2K2EEQKWBQb78ichBECRhE8O8SlQ5iBAQvcffFPhoYQoSAAQ5/TcQ0CBYw0OGvCZ4GoQIGF/3bhGaDQAELvfKhERgIwgQMePrPCQsEQQLwFwYPmksiQMCC1n1iCFgooQtYwLJfPPQFQ7KAUfU/wABVwMj6TzdAFDDY6tcOMR3SBIyw/1QDJAGj7D/RAEXA6Oa/hhIHCAJG23+SAb+AEfefYsArYET1nwlvTegVgBONFnTDik8ATjNi0BEbHgGjuP5147k6dgsYaQHQxF0OOAUMfv2LhnOVzCVg4OufdFwrpS4BePkSgA6ZcAhYggCocQRCu4ClCIAaeyC0CliaAKCwhgGrALxwaUC3OtgELFEAUNjCgEXAklQAdSzVgEUAXrRUoGstzAKWbgJIzJPAKGAJJ4DEOAmMAvCCpQPda2ASsJQTQGKa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', } TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) @@ -935,7 +882,7 @@ if Config.EnablePlayerManagement then end -- Create Blips -Citizen.CreateThread(function () +Citizen.CreateThread(function() local blip = AddBlipForCoord(Config.Zones.ShopEntering.Pos.x, Config.Zones.ShopEntering.Pos.y, Config.Zones.ShopEntering.Pos.z) SetBlipSprite (blip, 326) @@ -949,7 +896,7 @@ Citizen.CreateThread(function () end) -- Display markers -Citizen.CreateThread(function () +Citizen.CreateThread(function() while true do Citizen.Wait(0) @@ -1000,14 +947,11 @@ Citizen.CreateThread(function() if CurrentAction == nil then Citizen.Wait(500) else - ESX.ShowHelpNotification(CurrentActionMsg) if IsControlJustReleased(0, Keys['E']) then if CurrentAction == 'shop_menu' then - if Config.LicenseEnable then - ESX.TriggerServerCallback('esx_license:checkLicense', function(hasDriversLicense) if hasDriversLicense then OpenShopMenu() @@ -1015,15 +959,12 @@ Citizen.CreateThread(function() ESX.ShowNotification(_U('license_missing')) end end, GetPlayerServerId(PlayerId()), 'drive') - else OpenShopMenu() end - elseif CurrentAction == 'reseller_menu' then OpenResellerMenu() elseif CurrentAction == 'give_back_vehicle' then - ESX.TriggerServerCallback('esx_vehicleshop:giveBackVehicle', function(isRentedVehicle) if isRentedVehicle then ESX.Game.DeleteVehicle(CurrentActionData.vehicle) @@ -1032,20 +973,15 @@ Citizen.CreateThread(function() ESX.ShowNotification(_U('not_rental')) end end, ESX.Math.Trim(GetVehicleNumberPlateText(CurrentActionData.vehicle))) - elseif CurrentAction == 'resell_vehicle' then - ESX.TriggerServerCallback('esx_vehicleshop:resellVehicle', function(vehicleSold) - if vehicleSold then ESX.Game.DeleteVehicle(CurrentActionData.vehicle) ESX.ShowNotification(_U('vehicle_sold_for', CurrentActionData.label, ESX.Math.GroupDigits(CurrentActionData.price))) else ESX.ShowNotification(_U('not_yours')) end - end, CurrentActionData.plate, CurrentActionData.model) - elseif CurrentAction == 'boss_actions_menu' then OpenBossActionsMenu() end @@ -1067,10 +1003,9 @@ end) function drawLoadingText(text, red, green, blue, alpha) SetTextFont(4) - SetTextProportional(0) SetTextScale(0.0, 0.5) SetTextColour(red, green, blue, alpha) - SetTextDropShadow(0, 0, 0, 0, 255) + SetTextDropshadow(0, 0, 0, 0, 255) SetTextEdge(1, 0, 0, 0, 255) SetTextDropShadow() SetTextOutline() From f408e3a56a8c048c2379cdf7b8219a031498a859 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 20 May 2019 23:04:04 +0200 Subject: [PATCH 2207/3224] Proper hud natives --- client/main.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index e0797571..f273eea7 100644 --- a/client/main.lua +++ b/client/main.lua @@ -14,10 +14,9 @@ local voice = {default = 5.0, shout = 12.0, whisper = 1.0, current = 0, level = function drawLevel(r, g, b, a) SetTextFont(4) - SetTextProportional(1) SetTextScale(0.5, 0.5) SetTextColour(r, g, b, a) - SetTextDropShadow(0, 0, 0, 0, 255) + SetTextDropshadow(0, 0, 0, 0, 255) SetTextEdge(1, 0, 0, 0, 255) SetTextDropShadow() SetTextOutline() From 19d6e032af1137e91197ae2577619a90bbe4ed20 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 20 May 2019 23:04:48 +0200 Subject: [PATCH 2208/3224] Proper hud natives --- client/job.lua | 3 +-- client/main.lua | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/client/job.lua b/client/job.lua index 85be6428..94e5a782 100644 --- a/client/job.lua +++ b/client/job.lua @@ -846,10 +846,9 @@ end function drawLoadingText(text, red, green, blue, alpha) SetTextFont(4) - SetTextProportional(0) SetTextScale(0.0, 0.5) SetTextColour(red, green, blue, alpha) - SetTextDropShadow(0, 0, 0, 0, 255) + SetTextDropshadow(0, 0, 0, 0, 255) SetTextEdge(1, 0, 0, 0, 255) SetTextDropShadow() SetTextOutline() diff --git a/client/main.lua b/client/main.lua index adefb232..3a8f2c36 100644 --- a/client/main.lua +++ b/client/main.lua @@ -152,10 +152,9 @@ function StartDistressSignal() timer = timer - 30 SetTextFont(4) - SetTextProportional(1) SetTextScale(0.45, 0.45) SetTextColour(185, 185, 185, 255) - SetTextDropShadow(0, 0, 0, 0, 255) + SetTextDropshadow(0, 0, 0, 0, 255) SetTextEdge(1, 0, 0, 0, 255) SetTextDropShadow() SetTextOutline() @@ -193,7 +192,6 @@ end function DrawGenericTextThisFrame() SetTextFont(4) - SetTextProportional(0) SetTextScale(0.0, 0.5) SetTextColour(255, 255, 255, 255) SetTextDropshadow(0, 0, 0, 0, 255) From 4bbd1d952162c3c2117076f4dcb6fb7e566cd92c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 20 May 2019 23:05:10 +0200 Subject: [PATCH 2209/3224] Proper hud natives --- client/main.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index ac67c870..0bdb4283 100644 --- a/client/main.lua +++ b/client/main.lua @@ -641,10 +641,9 @@ end function drawLoadingText(text, red, green, blue, alpha) SetTextFont(4) - SetTextProportional(0) SetTextScale(0.0, 0.5) SetTextColour(red, green, blue, alpha) - SetTextDropShadow(0, 0, 0, 0, 255) + SetTextDropshadow(0, 0, 0, 0, 255) SetTextEdge(1, 0, 0, 0, 255) SetTextDropShadow() SetTextOutline() From 15489ec3c798199df945d6290d86a653299c249c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 20 May 2019 23:05:38 +0200 Subject: [PATCH 2210/3224] Proper hud natives --- client/functions.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/client/functions.lua b/client/functions.lua index ac6a6109..a8e3c3d1 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1010,7 +1010,6 @@ ESX.Game.Utils.DrawText3D = function(coords, text, size) if onScreen then SetTextScale(0.0 * scale, 0.55 * scale) SetTextFont(0) - SetTextProportional(1) SetTextColour(255, 255, 255, 255) SetTextDropshadow(0, 0, 0, 0, 255) SetTextEdge(2, 0, 0, 0, 150) From a18fa50463ce9402595360bf5268969b94b56926 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 20 May 2019 23:06:03 +0200 Subject: [PATCH 2211/3224] Proper hud natives --- client/main.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index 3ba23626..51595b65 100644 --- a/client/main.lua +++ b/client/main.lua @@ -24,10 +24,9 @@ end) function drawTxt(x,y, width, height, scale, text, r,g,b,a, outline) SetTextFont(0) - SetTextProportional(0) SetTextScale(scale, scale) SetTextColour(r, g, b, a) - SetTextDropShadow(0, 0, 0, 0,255) + SetTextDropshadow(0, 0, 0, 0,255) SetTextEdge(1, 0, 0, 0, 255) SetTextDropShadow() if outline then SetTextOutline() end From 3ea931b940c1be5cc399fd61e51dbe7a0f92ff0e Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 20 May 2019 23:13:41 +0200 Subject: [PATCH 2212/3224] Resized base64 image --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 27685af5..e6ede08b 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,6 +1,6 @@ ESX = nil -local base64MoneyIcon = 'data:image/png;base64,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/GMzLdsAADhgaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjUtYzAxNCA3OS4xNTE0ODEsIDIwMTMvMDMvMTMtMTI6MDk6MTUgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgICAgICAgICB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8eG1wOkNyZWF0b3JUb29sPkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cyk8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMTUtMTAtMDlUMjA6MTM6MTYrMDI6MDA8L3htcDpDcmVhdGVEYXRlPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxNS0xMC0wOVQyMDoxNDo0NyswMjowMDwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6TWV0YWRhdGFEYXRlPjIwMTUtMTAtMDlUMjA6MTQ6NDcrMDI6MDA8L3htcDpNZXRhZGF0YURhdGU+CiAgICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2UvcG5nPC9kYzpmb3JtYXQ+CiAgICAgICAgIDxwaG90b3Nob3A6Q29sb3JNb2RlPjM8L3Bob3Rvc2hvcDpDb2xvck1vZGU+CiAgICAgICAgIDxwaG90b3Nob3A6SUNDUHJvZmlsZT5zUkdCIElFQzYxOTY2LTIuMTwvcGhvdG9zaG9wOklDQ1Byb2ZpbGU+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6NmZkNGVlNjgtOWU3Mi1jYTQxLTg5NjMtMWRjMmI2M2EzYWExPC94bXBNTTpJbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD54bXAuZGlkOjZmZDRlZTY4LTllNzItY2E0MS04OTYzLTFkYzJiNjNhM2FhMTwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD54bXAuZGlkOjZmZDRlZTY4LTllNzItY2E0MS04OTYzLTFkYzJiNjNhM2FhMTwveG1wTU06T3JpZ2luYWxEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06SGlzdG9yeT4KICAgICAgICAgICAgPHJkZjpTZXE+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmNyZWF0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDo2ZmQ0ZWU2OC05ZTcyLWNhNDEtODk2My0xZGMyYjYzYTNhYTE8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTUtMTAtMDlUMjA6MTM6MTYrMDI6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpTZXE+CiAgICAgICAgIDwveG1wTU06SGlzdG9yeT4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WFJlc29sdXRpb24+OTYwMDAwLzEwMDAwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj45NjAwMDAvMTAwMDA8L3RpZmY6WVJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U+MTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+MTgwPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjE4MDwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAg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' +local base64MoneyIcon = 'iVBORw0KGgoAAAANSUhEUgAAAFoAAABaCAMAAAAPdrEwAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAMAUExURQAAACmvPCmwPCuwPiywPi2wPy6xQC6xQS+yQTCxQTCyQTCyQjGyQzKyRDOzRTSzRTSzRjW0RjW0Rza0SDe0STi0STm1Sjq1Szq2Szu2TDy2TDy2TT22Tj63Tz+3UEC4UEG4UUG4UkK4U0O5VES5VEW6VUa6Vke6V0i7WEm7WUu8Wku8W0y8W028XE29XU++XlC9X1C+X1G+YFK+YVO/YlW/ZFXAZFfAZVfAZljBZlnBZ1rBaVvCaVvCalzDal7CbF/DbV/EbWHEbmLEb2LEcGTFcWfGdGjHdWrHd2vId2vIeGzIeW3JenHKfXLKfnPLf3TLgHXLgXXMgHXMgXbMgnjNg3nMhHrNhnrOhnzOiH7PiYLQjYPRjoTRjoTRj4XRkIXSkIfSkojSk4rUlYzUlo7VmJDWmpHWm5LXnJTXnZTXnpXYnpbYn5nZopzapJ3bpZ7bpp7bp6DcqKLcqqPcq6Tcq6TdrKberqjfr6jfsKnfsavgs6zgs6zgtK7hta/htrDit7LiuLLiubPjurTjurXju7bkvLbkvbnlv7rlwLrmwLzmwr3nw77nxMDnxcLox8PpyMTpycXpysXqysbqy8fqzMnrzcrrz8vsz8vs0Mzs0c3t0tHu1dHu1tPv19Tv2NXv2dXw2dbw2tfw29jw3Nnx3drx3t7z4d/z4uD04+H05OP15eP15uT15uT15+X16OX26Of26en36+r37Ov37er47Ov47ez47e347u347+758PD58fD68fD68vL69PT79fX79vb79/b89vb89/f8+Pj9+fn9+vr9+/v++/v+/Pz+/P3+/f3+/v7//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALfZHJgAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjb9TgnoAAAGdUlEQVRoQ7WZ93sURRiAFZO76O1eklt215OgBwqJgmgCRhAhRrAAiogBK4gBJEFEgWAEYiGIYEGp1kjXQECkiF0OWyjJ/k34zcy3db7Zu8fHe3/KTXnzPbPT56orRTEYAhMLUFgNKkeiGH8BNaV1KWSPVXveU9s3LW9pvhdoblm+afspTHZi5Wo1BnzpaOfcnFmWSBv29YBtpBNlZm5u59FLPDsmdJUaxQeXNugZw5IwMnrD0oO8iFKuUHNx/+bGZLWNMgm7Otm4uZ/LsVIEUs3F+Y5a3USNAlOv7cgr5ZSamQffyOnKgH1sPdfFi2PVILKaReEcmKwVIWbY2uQDvApW95HULIb+Ng0rFoXWxppcCjyqZuZjk4oNWWBrk44R7oiamXdkC3w9GTO7Q3aH1cy8OkWFnHtitstM4j/bqdWSO6Rm5nYdS4e5FbKQwxlMC6G3Q1bIHVQz8+IKLBphJLdydlRjWpiKxZAXdAfUPOak4gOO4FZOdxWmhbGTkbh9NTOvoVsDuGmAaxkdlZgWRV8Dub7bV0PyzhQWkqk5z7WMdjpqILUTslEXUEPQJ7Lq7pz9WXiBZ4iZUGBnTwTCdtVgvjgxpj+b3vTvTEteq5KbEy/6blcNVZapR3cmdc9Z4QV6Pnxzdr1GF9aWQQFUohqCPqQc3ZV17X3C6tP31kyL+Jy2dsgLW6jBPDgVc6OkR3XxCV/i9IqRRFedylxc6qk30L3DNF7ikz1Jft0oLOaT2hBSg/l8jmwOo24/amimYzkfOwfdlLtdNT1YjIaf0EFzgGhuNnB8teNcqCWDvs3vzSSLqC9Ze0F0EqaGoDeSQWt7UaHgXA0WDKFvFGEzNRS6mxot6VZhUNJNdm7zbsgSagj6UAKTQ5hnhEHJffRISIi+LdRLyNn9cTSoOExP3FZmiat2nIF66t9Xb0GFz8Df+AenVTEF2vUwAzM1BN1LfsTkcVS4bJs+fnRj84z3joqf+eFYUELvZWFzdSfZHjeeEwqXl6/myWaZ0bSVDf3uJP9NkOn01HPISXIMTJAB/hiB6WBPN+xxBpvxl4wxR6ihll8pSL1QupwLLhR22YL9ysVGrKRcfZJeAu4QSo+1yWA3rla2NGCeZGpoj13lmBJm1F/odDm+fv68phorU0l+miDlu6BFmLqbHDCWdhqVQQb/zPesW1inqxdoRqIb1SvSmBJG+wR1BF+/NkmLWUnTK1DdQq+i5gvoIbn85QPqtdRoQfU0TIgy4h/UKOi+gZ5DgGmonqIoob2CDhXHblE0ij2lgNo2YMcSy7fkhF2E2rIm/IoOFV/Q+78i1JkJheJ+jOzjnlr1GRk18swa4iC9t3U/o6LzCVLTP4dlVM14LBfC63yKIYOYeuMqcRoneZFqEW/IKAY6Q8xumla3YP2+PNnNt1Jqb6Arpifg5kXuHjNTaVi1s5/eJs0r+6gFUkxP6kkV2mKBs8UMZSYMdmAJcpxqTTGpqpcCEO1znCMTwlPFNbuF0uUs1UVwKYAWoRcwGDHsbNS/algwu+J1bvToI9TuAgZqetm1roPVk/FDazbhjaryr0SiSw/R1oFll94sWNnfsLrzS1eTkawyjKrE6HcwyeVtIix3s6Dc4ljzsTbnx74P1na83+uf8ZBn5cb0tjgsbHJjlvoMa8dxWT4XBDZmoCa3k7eH9yE0u4l9jr+dZN2P2ASnVorK8TwoVwxsglnYxNY9852oHMseogMEt+4QtnzgGDoTa8eRH4ulA4QOHCxs6ZhUBdNAIS7NIjp1+JgEaulwZzwsnXCjDDxPzB+Rwx1zS0fSoVZb/Mp4/lFqQxk5kjI1cZDWa179HTUEe8eRW9XoQZq5qeN/5fCFigWmd14VNRXLx3/et8lLC7N8XNtH0VP6mXfvV+z4iEsLFrbqqkXXho2Z8dynwgo8NdZK0SXpqxbmjrsgquhCsXrhgOYgL4h4k8Rca5VvFV7gTkySUVxrsbBjLuOGfMy1jCZFa6gv47hbeYU4ZA/XMmbRy13MFaJwqy4+Ez1cy3iSVsddfGLcdJvo33Ato5VcSeOva4WbvmQ2v+daxkrqfqXQJbNwk1fj9kOPuNwlZxdxNS7c5IW+MdRFMhd3oS/cpXmG4EOnRI8nAAt8sKsETz4AK1yahyqAy0vxvAaU7lEQcJ8yj9BPmUf+81MmR8iB//kBllOyZ2NOqR67XUAVABNjuXLlX2rCcoFjOcGoAAAAAElFTkSuQmCC' Citizen.CreateThread(function() while ESX == nil do From 967cde347eb8383c46d25d21f0cc28ede8569dd7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 31 May 2019 12:35:09 +0200 Subject: [PATCH 2213/3224] Fix spawned vehicles not unloading from memory, closes #142 Co-Authored-By: Alex Garcio --- client/main.lua | 35 ++++++++++------------------------- locales/br.lua | 2 +- locales/en.lua | 2 +- locales/fi.lua | 2 +- locales/fr.lua | 2 +- locales/pl.lua | 2 +- locales/sv.lua | 2 +- 7 files changed, 16 insertions(+), 31 deletions(-) diff --git a/client/main.lua b/client/main.lua index aadd5b23..81ba51a1 100644 --- a/client/main.lua +++ b/client/main.lua @@ -365,6 +365,7 @@ function OpenShopMenu() table.insert(LastVehicles, vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) FreezeEntityPosition(vehicle, true) + SetModelAsNoLongerNeeded(vehicleData.model) end) end) @@ -375,6 +376,7 @@ function OpenShopMenu() table.insert(LastVehicles, vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) FreezeEntityPosition(vehicle, true) + SetModelAsNoLongerNeeded(firstVehicleData.model) end) end @@ -385,18 +387,16 @@ function WaitForVehicleToLoad(modelHash) if not HasModelLoaded(modelHash) then RequestModel(modelHash) + BeginTextCommandBusyString('STRING') + AddTextComponentSubstringPlayerName(_U('shop_awaiting_model')) + EndTextCommandBusyString(4) + while not HasModelLoaded(modelHash) do Citizen.Wait(1) - - DisableControlAction(0, Keys['TOP'], true) - DisableControlAction(0, Keys['DOWN'], true) - DisableControlAction(0, Keys['LEFT'], true) - DisableControlAction(0, Keys['RIGHT'], true) - DisableControlAction(0, 176, true) -- ENTER key - DisableControlAction(0, Keys['BACKSPACE'], true) - - drawLoadingText(_U('shop_awaiting_model'), 255, 255, 255, 255) + DisableAllControlActions(0) end + + RemoveLoadingPrompt() end end @@ -999,19 +999,4 @@ Citizen.CreateThread(function() LoadInterior(interiorID) EnableInteriorProp(interiorID, 'csr_beforeMission') -- Load large window RefreshInterior(interiorID) -end) - -function drawLoadingText(text, red, green, blue, alpha) - SetTextFont(4) - SetTextScale(0.0, 0.5) - SetTextColour(red, green, blue, alpha) - SetTextDropshadow(0, 0, 0, 0, 255) - SetTextEdge(1, 0, 0, 0, 255) - SetTextDropShadow() - SetTextOutline() - SetTextCentre(true) - - BeginTextCommandDisplayText("STRING") - AddTextComponentSubstringPlayerName(text) - EndTextCommandDisplayText(0.5, 0.5) -end \ No newline at end of file +end) \ No newline at end of file diff --git a/locales/br.lua b/locales/br.lua index eb72cf15..9001a2e2 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -11,7 +11,7 @@ Locales['br'] = { ['buy_vehicle_shop'] = 'comprar %s por $%s?', ['buy_vehicle'] = 'comprar veículo', ['car_dealer'] = 'Concessionária de carros', - ['shop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', + ['shop_awaiting_model'] = 'the vehicle is currently loading, please wait', ['create_bill'] = 'criar recibo', ['dealer_boss'] = 'Concessionária de carros - Chefe', ['delivered'] = 'veículo ~g~entregue~s~ para o revendedor', diff --git a/locales/en.lua b/locales/en.lua index 02078493..69197a9c 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -11,7 +11,7 @@ Locales['en'] = { ['buy_vehicle_shop'] = 'do you want to purchase %s for $%s?', ['buy_vehicle'] = 'buy vehicle', ['car_dealer'] = 'car Dealership', - ['shop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', + ['shop_awaiting_model'] = 'the vehicle is currently loading, please wait', ['create_bill'] = 'create bill', ['dealer_boss'] = 'car Dealer - Boss', ['delivered'] = 'the vehicle has been ~g~delivered~s~ to the dealer', diff --git a/locales/fi.lua b/locales/fi.lua index 3af97356..3eff6100 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -11,7 +11,7 @@ Locales['fi'] = { ['buy_vehicle_shop'] = 'haluatko ostaa ajoneuvon %s hintaan $%s?', ['buy_vehicle'] = 'osta ajoneuvo', ['car_dealer'] = 'autokauppa', - ['shop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', + ['shop_awaiting_model'] = 'the vehicle is currently loading, please wait', ['create_bill'] = 'tee lasku', ['dealer_boss'] = 'autokauppa - Pomo', ['delivered'] = 'ajoneuvo on ~g~kuljetettu~s~ myyjälle', diff --git a/locales/fr.lua b/locales/fr.lua index 6b5bb8d5..4c53116f 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -11,7 +11,7 @@ Locales['fr'] = { ['buy_vehicle_shop'] = 'acheter %s pour $%s?', ['buy_vehicle'] = 'acheter véhicule', ['car_dealer'] = 'concessionnaire', - ['shop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', + ['shop_awaiting_model'] = 'the vehicle is currently loading, please wait', ['create_bill'] = 'créer facture', ['dealer_boss'] = 'concessionnaire - Patron', ['delivered'] = 'véhicule ~g~rendu~s~ au concessionnaire', diff --git a/locales/pl.lua b/locales/pl.lua index bbc6f76e..c0b19aa7 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -11,7 +11,7 @@ Locales['pl'] = { ['buy_vehicle_shop'] = 'czy chcesz kupić %s za $%s?', ['buy_vehicle'] = 'kup pojazd', ['car_dealer'] = 'sprzedawca Aut', - ['shop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', + ['shop_awaiting_model'] = 'the vehicle is currently loading, please wait', ['create_bill'] = 'stwórz fakture', ['dealer_boss'] = 'salon samochodowy - Szef', ['delivered'] = 'pojazd został ~g~dostarczony~s~ do salonu', diff --git a/locales/sv.lua b/locales/sv.lua index 2d7e6a1e..15618054 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -11,7 +11,7 @@ Locales['sv'] = { ['buy_vehicle_shop'] = 'vill du köpa in %s för %s SEK?', ['buy_vehicle'] = 'Köp in fordon', ['car_dealer'] = 'bilförsäljare', - ['shop_awaiting_model'] = 'ditt fordon håller på att ~g~LADDA NER & LÄSA IN~s~ vänta tills det är klart', + ['shop_awaiting_model'] = 'fordon laddas in, vänligen vänta', ['create_bill'] = 'ge faktura', ['dealer_boss'] = 'chefmeny', ['delivered'] = 'fordonet har ~g~lämnats tillbaka~s~ till bilförsäljaren', From 06839cb1016daf5754666ee2757dba306547ae1b Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 31 May 2019 12:37:48 +0200 Subject: [PATCH 2214/3224] Updated native name --- client/main.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index 27d25394..0249ab82 100644 --- a/client/main.lua +++ b/client/main.lua @@ -269,7 +269,7 @@ Citizen.CreateThread(function() else -- open phone -- todo: is player busy (handcuffed, etc) - if IsControlJustReleased(0, Keys['F1']) and GetLastInputMethod(2) then + if IsControlJustReleased(0, Keys['F1']) and IsInputDisabled(0) then if not ESX.UI.Menu.IsOpen('phone', GetCurrentResourceName(), 'main') then ESX.UI.Menu.CloseAll() ESX.UI.Menu.Open('phone', GetCurrentResourceName(), 'main') @@ -295,7 +295,7 @@ Citizen.CreateThread(function() if CurrentAction ~= nil then ESX.ShowHelpNotification(CurrentActionMsg) - if IsControlJustReleased(0, Keys['E']) and GetLastInputMethod(2) then + if IsControlJustReleased(0, Keys['E']) and IsInputDisabled(0) then if CurrentAction == 'dispatch' then TriggerServerEvent('esx_phone:stopDispatch', CurrentDispatchRequestId) SetNewWaypoint(CurrentActionData.position.x, CurrentActionData.position.y) From 70b56fb7c441b19dbd6fdcec9fa6cee8e91e2e22 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 31 May 2019 12:38:07 +0200 Subject: [PATCH 2215/3224] Remove unused text native --- client/main.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index f273eea7..59e36e29 100644 --- a/client/main.lua +++ b/client/main.lua @@ -17,7 +17,6 @@ function drawLevel(r, g, b, a) SetTextScale(0.5, 0.5) SetTextColour(r, g, b, a) SetTextDropshadow(0, 0, 0, 0, 255) - SetTextEdge(1, 0, 0, 0, 255) SetTextDropShadow() SetTextOutline() From 0a347eda2aecf71f3b7f62521ffe4a4d9e5d3262 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 31 May 2019 12:40:18 +0200 Subject: [PATCH 2216/3224] Unused text native --- client/main.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 0bdb4283..5a245560 100644 --- a/client/main.lua +++ b/client/main.lua @@ -644,7 +644,6 @@ function drawLoadingText(text, red, green, blue, alpha) SetTextScale(0.0, 0.5) SetTextColour(red, green, blue, alpha) SetTextDropshadow(0, 0, 0, 0, 255) - SetTextEdge(1, 0, 0, 0, 255) SetTextDropShadow() SetTextOutline() SetTextCentre(true) From bb1c90f50dcd69d4bf6b1fd863576e3bc0816982 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 31 May 2019 12:41:20 +0200 Subject: [PATCH 2217/3224] Unused text native --- client/main.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 51595b65..896659a4 100644 --- a/client/main.lua +++ b/client/main.lua @@ -27,7 +27,6 @@ function drawTxt(x,y, width, height, scale, text, r,g,b,a, outline) SetTextScale(scale, scale) SetTextColour(r, g, b, a) SetTextDropshadow(0, 0, 0, 0,255) - SetTextEdge(1, 0, 0, 0, 255) SetTextDropShadow() if outline then SetTextOutline() end From 9f600e3787e3ecb5e455650dc530acd3becd5804 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 31 May 2019 12:53:53 +0200 Subject: [PATCH 2218/3224] Minor cleanup --- client/main.lua | 426 +++++++++++++++++++++--------------------------- config.lua | 99 ++++++----- 2 files changed, 231 insertions(+), 294 deletions(-) diff --git a/client/main.lua b/client/main.lua index c295072c..08c482ba 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,15 +1,3 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - local HasAlreadyEnteredMarker, LastZone = false, nil local CurrentAction, CurrentActionMsg, CurrentActionData = nil, '', {} local CurrentlyTowedVehicle, Blips, NPCOnJob, NPCTargetTowable, NPCTargetTowableZone = nil, {}, false, nil, nil @@ -80,7 +68,6 @@ function StopNPCJob(cancel) end function OpenMechanicActionsMenu() - local elements = { {label = _U('vehicle_list'), value = 'vehicle_list'}, {label = _U('work_wear'), value = 'cloakroom'}, @@ -101,7 +88,6 @@ function OpenMechanicActionsMenu() elements = elements }, function(data, menu) if data.current.value == 'vehicle_list' then - if Config.EnableSocietyOwnedVehicles then local elements = {} @@ -177,9 +163,7 @@ function OpenMechanicActionsMenu() end) end - elseif data.current.value == 'cloakroom' then - menu.close() ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) if skin.sex == 0 then @@ -188,14 +172,11 @@ function OpenMechanicActionsMenu() TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_female) end end) - elseif data.current.value == 'cloakroom2' then - menu.close() ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) TriggerEvent('skinchanger:loadSkin', skin) end) - elseif data.current.value == 'put_stock' then OpenPutStocksMenu() elseif data.current.value == 'get_stock' then @@ -205,7 +186,6 @@ function OpenMechanicActionsMenu() menu.close() end) end - end, function(data, menu) menu.close() @@ -216,9 +196,7 @@ function OpenMechanicActionsMenu() end function OpenMechanicHarvestMenu() - if Config.EnablePlayerManagement and ESX.PlayerData.job and ESX.PlayerData.job.grade_name ~= 'recrue' then - local elements = { {label = _U('gas_can'), value = 'gaz_bottle'}, {label = _U('repair_tools'), value = 'fix_tool'}, @@ -247,7 +225,6 @@ function OpenMechanicHarvestMenu() CurrentActionMsg = _U('harvest_menu') CurrentActionData = {} end) - else ESX.ShowNotification(_U('not_experienced_enough')) end @@ -255,7 +232,6 @@ end function OpenMechanicCraftMenu() if Config.EnablePlayerManagement and ESX.PlayerData.job and ESX.PlayerData.job.grade_name ~= 'recrue' then - local elements = { {label = _U('blowtorch'), value = 'blow_pipe'}, {label = _U('repair_kit'), value = 'fix_kit'}, @@ -285,14 +261,12 @@ function OpenMechanicCraftMenu() CurrentActionMsg = _U('craft_menu') CurrentActionData = {} end) - else ESX.ShowNotification(_U('not_experienced_enough')) end end function OpenMobileMechanicActionsMenu() - ESX.UI.Menu.CloseAll() ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'mobile_mechanic_actions', { @@ -306,12 +280,10 @@ function OpenMobileMechanicActionsMenu() {label = _U('imp_veh'), value = 'del_vehicle'}, {label = _U('flat_bed'), value = 'dep_vehicle'}, {label = _U('place_objects'), value = 'object_spawner'} - } - }, function(data, menu) + }}, function(data, menu) if isBusy then return end if data.current.value == 'billing' then - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'billing', { title = _U('invoice_amount') }, function(data, menu) @@ -331,229 +303,207 @@ function OpenMobileMechanicActionsMenu() end, function(data, menu) menu.close() end) - elseif data.current.value == 'hijack_vehicle' then + local playerPed = PlayerPedId() + local vehicle = ESX.Game.GetVehicleInDirection() + local coords = GetEntityCoords(playerPed) - local playerPed = PlayerPedId() - local vehicle = ESX.Game.GetVehicleInDirection() - local coords = GetEntityCoords(playerPed) - - if IsPedSittingInAnyVehicle(playerPed) then - ESX.ShowNotification(_U('inside_vehicle')) - return - end - - if DoesEntityExist(vehicle) then - isBusy = true - TaskStartScenarioInPlace(playerPed, 'WORLD_HUMAN_WELDING', 0, true) - Citizen.CreateThread(function() - Citizen.Wait(10000) - - SetVehicleDoorsLocked(vehicle, 1) - SetVehicleDoorsLockedForAllPlayers(vehicle, false) - ClearPedTasksImmediately(playerPed) - - ESX.ShowNotification(_U('vehicle_unlocked')) - isBusy = false - end) - else - ESX.ShowNotification(_U('no_vehicle_nearby')) - end - - elseif data.current.value == 'fix_vehicle' then - - local playerPed = PlayerPedId() - local vehicle = ESX.Game.GetVehicleInDirection() - local coords = GetEntityCoords(playerPed) - - if IsPedSittingInAnyVehicle(playerPed) then - ESX.ShowNotification(_U('inside_vehicle')) - return - end - - if DoesEntityExist(vehicle) then - isBusy = true - TaskStartScenarioInPlace(playerPed, 'PROP_HUMAN_BUM_BIN', 0, true) - Citizen.CreateThread(function() - Citizen.Wait(20000) - - SetVehicleFixed(vehicle) - SetVehicleDeformationFixed(vehicle) - SetVehicleUndriveable(vehicle, false) - SetVehicleEngineOn(vehicle, true, true) - ClearPedTasksImmediately(playerPed) - - ESX.ShowNotification(_U('vehicle_repaired')) - isBusy = false - end) - else - ESX.ShowNotification(_U('no_vehicle_nearby')) - end - - elseif data.current.value == 'clean_vehicle' then - - local playerPed = PlayerPedId() - local vehicle = ESX.Game.GetVehicleInDirection() - local coords = GetEntityCoords(playerPed) - - if IsPedSittingInAnyVehicle(playerPed) then - ESX.ShowNotification(_U('inside_vehicle')) - return - end - - if DoesEntityExist(vehicle) then - isBusy = true - TaskStartScenarioInPlace(playerPed, 'WORLD_HUMAN_MAID_CLEAN', 0, true) - Citizen.CreateThread(function() - Citizen.Wait(10000) - - SetVehicleDirtLevel(vehicle, 0) - ClearPedTasksImmediately(playerPed) - - ESX.ShowNotification(_U('vehicle_cleaned')) - isBusy = false - end) - else - ESX.ShowNotification(_U('no_vehicle_nearby')) - end - - elseif data.current.value == 'del_vehicle' then - - local playerPed = PlayerPedId() - - if IsPedSittingInAnyVehicle(playerPed) then - local vehicle = GetVehiclePedIsIn(playerPed, false) - - if GetPedInVehicleSeat(vehicle, -1) == playerPed then - ESX.ShowNotification(_U('vehicle_impounded')) - ESX.Game.DeleteVehicle(vehicle) - else - ESX.ShowNotification(_U('must_seat_driver')) + if IsPedSittingInAnyVehicle(playerPed) then + ESX.ShowNotification(_U('inside_vehicle')) + return end - else - local vehicle = ESX.Game.GetVehicleInDirection() if DoesEntityExist(vehicle) then - ESX.ShowNotification(_U('vehicle_impounded')) - ESX.Game.DeleteVehicle(vehicle) + isBusy = true + TaskStartScenarioInPlace(playerPed, 'WORLD_HUMAN_WELDING', 0, true) + Citizen.CreateThread(function() + Citizen.Wait(10000) + + SetVehicleDoorsLocked(vehicle, 1) + SetVehicleDoorsLockedForAllPlayers(vehicle, false) + ClearPedTasksImmediately(playerPed) + + ESX.ShowNotification(_U('vehicle_unlocked')) + isBusy = false + end) else - ESX.ShowNotification(_U('must_near')) + ESX.ShowNotification(_U('no_vehicle_nearby')) end - end + elseif data.current.value == 'fix_vehicle' then + local playerPed = PlayerPedId() + local vehicle = ESX.Game.GetVehicleInDirection() + local coords = GetEntityCoords(playerPed) - elseif data.current.value == 'dep_vehicle' then + if IsPedSittingInAnyVehicle(playerPed) then + ESX.ShowNotification(_U('inside_vehicle')) + return + end - local playerPed = PlayerPedId() - local vehicle = GetVehiclePedIsIn(playerPed, true) + if DoesEntityExist(vehicle) then + isBusy = true + TaskStartScenarioInPlace(playerPed, 'PROP_HUMAN_BUM_BIN', 0, true) + Citizen.CreateThread(function() + Citizen.Wait(20000) - local towmodel = GetHashKey('flatbed') - local isVehicleTow = IsVehicleModel(vehicle, towmodel) + SetVehicleFixed(vehicle) + SetVehicleDeformationFixed(vehicle) + SetVehicleUndriveable(vehicle, false) + SetVehicleEngineOn(vehicle, true, true) + ClearPedTasksImmediately(playerPed) - if isVehicleTow then - local targetVehicle = ESX.Game.GetVehicleInDirection() + ESX.ShowNotification(_U('vehicle_repaired')) + isBusy = false + end) + else + ESX.ShowNotification(_U('no_vehicle_nearby')) + end + elseif data.current.value == 'clean_vehicle' then + local playerPed = PlayerPedId() + local vehicle = ESX.Game.GetVehicleInDirection() + local coords = GetEntityCoords(playerPed) - if CurrentlyTowedVehicle == nil then - if targetVehicle ~= 0 then - if not IsPedInAnyVehicle(playerPed, true) then - if vehicle ~= targetVehicle then - AttachEntityToEntity(targetVehicle, vehicle, 20, -0.5, -5.0, 1.0, 0.0, 0.0, 0.0, false, false, false, false, 20, true) - CurrentlyTowedVehicle = targetVehicle - ESX.ShowNotification(_U('vehicle_success_attached')) + if IsPedSittingInAnyVehicle(playerPed) then + ESX.ShowNotification(_U('inside_vehicle')) + return + end - if NPCOnJob then - if NPCTargetTowable == targetVehicle then - ESX.ShowNotification(_U('please_drop_off')) - Config.Zones.VehicleDelivery.Type = 1 + if DoesEntityExist(vehicle) then + isBusy = true + TaskStartScenarioInPlace(playerPed, 'WORLD_HUMAN_MAID_CLEAN', 0, true) + Citizen.CreateThread(function() + Citizen.Wait(10000) - if Blips['NPCTargetTowableZone'] then - RemoveBlip(Blips['NPCTargetTowableZone']) - Blips['NPCTargetTowableZone'] = nil + SetVehicleDirtLevel(vehicle, 0) + ClearPedTasksImmediately(playerPed) + + ESX.ShowNotification(_U('vehicle_cleaned')) + isBusy = false + end) + else + ESX.ShowNotification(_U('no_vehicle_nearby')) + end + elseif data.current.value == 'del_vehicle' then + local playerPed = PlayerPedId() + + if IsPedSittingInAnyVehicle(playerPed) then + local vehicle = GetVehiclePedIsIn(playerPed, false) + + if GetPedInVehicleSeat(vehicle, -1) == playerPed then + ESX.ShowNotification(_U('vehicle_impounded')) + ESX.Game.DeleteVehicle(vehicle) + else + ESX.ShowNotification(_U('must_seat_driver')) + end + else + local vehicle = ESX.Game.GetVehicleInDirection() + + if DoesEntityExist(vehicle) then + ESX.ShowNotification(_U('vehicle_impounded')) + ESX.Game.DeleteVehicle(vehicle) + else + ESX.ShowNotification(_U('must_near')) + end + end + elseif data.current.value == 'dep_vehicle' then + local playerPed = PlayerPedId() + local vehicle = GetVehiclePedIsIn(playerPed, true) + + local towmodel = GetHashKey('flatbed') + local isVehicleTow = IsVehicleModel(vehicle, towmodel) + + if isVehicleTow then + local targetVehicle = ESX.Game.GetVehicleInDirection() + + if CurrentlyTowedVehicle == nil then + if targetVehicle ~= 0 then + if not IsPedInAnyVehicle(playerPed, true) then + if vehicle ~= targetVehicle then + AttachEntityToEntity(targetVehicle, vehicle, 20, -0.5, -5.0, 1.0, 0.0, 0.0, 0.0, false, false, false, false, 20, true) + CurrentlyTowedVehicle = targetVehicle + ESX.ShowNotification(_U('vehicle_success_attached')) + + if NPCOnJob then + if NPCTargetTowable == targetVehicle then + ESX.ShowNotification(_U('please_drop_off')) + Config.Zones.VehicleDelivery.Type = 1 + + if Blips['NPCTargetTowableZone'] then + RemoveBlip(Blips['NPCTargetTowableZone']) + Blips['NPCTargetTowableZone'] = nil + end + + Blips['NPCDelivery'] = AddBlipForCoord(Config.Zones.VehicleDelivery.Pos.x, Config.Zones.VehicleDelivery.Pos.y, Config.Zones.VehicleDelivery.Pos.z) + SetBlipRoute(Blips['NPCDelivery'], true) end - - Blips['NPCDelivery'] = AddBlipForCoord(Config.Zones.VehicleDelivery.Pos.x, Config.Zones.VehicleDelivery.Pos.y, Config.Zones.VehicleDelivery.Pos.z) - SetBlipRoute(Blips['NPCDelivery'], true) end + else + ESX.ShowNotification(_U('cant_attach_own_tt')) end - else - ESX.ShowNotification(_U('cant_attach_own_tt')) end + else + ESX.ShowNotification(_U('no_veh_att')) end else - ESX.ShowNotification(_U('no_veh_att')) + AttachEntityToEntity(CurrentlyTowedVehicle, vehicle, 20, -0.5, -12.0, 1.0, 0.0, 0.0, 0.0, false, false, false, false, 20, true) + DetachEntity(CurrentlyTowedVehicle, true, true) + + if NPCOnJob then + if NPCTargetDeleterZone then + + if CurrentlyTowedVehicle == NPCTargetTowable then + ESX.Game.DeleteVehicle(NPCTargetTowable) + TriggerServerEvent('esx_mechanicjob:onNPCJobMissionCompleted') + StopNPCJob() + NPCTargetDeleterZone = false + else + ESX.ShowNotification(_U('not_right_veh')) + end + + else + ESX.ShowNotification(_U('not_right_place')) + end + end + + CurrentlyTowedVehicle = nil + ESX.ShowNotification(_U('veh_det_succ')) end else + ESX.ShowNotification(_U('imp_flatbed')) + end + elseif data.current.value == 'object_spawner' then + local playerPed = PlayerPedId() - AttachEntityToEntity(CurrentlyTowedVehicle, vehicle, 20, -0.5, -12.0, 1.0, 0.0, 0.0, 0.0, false, false, false, false, 20, true) - DetachEntity(CurrentlyTowedVehicle, true, true) + if IsPedSittingInAnyVehicle(playerPed) then + ESX.ShowNotification(_U('inside_vehicle')) + return + end - if NPCOnJob then - if NPCTargetDeleterZone then + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'mobile_mechanic_actions_spawn', { + title = _U('objects'), + align = 'top-left', + elements = { + {label = _U('roadcone'), value = 'prop_roadcone02a'}, + {label = _U('toolbox'), value = 'prop_toolchest_01'} + }}, function(data2, menu2) + local model = data2.current.value + local coords = GetEntityCoords(playerPed) + local forward = GetEntityForwardVector(playerPed) + local x, y, z = table.unpack(coords + forward * 1.0) - if CurrentlyTowedVehicle == NPCTargetTowable then - ESX.Game.DeleteVehicle(NPCTargetTowable) - TriggerServerEvent('esx_mechanicjob:onNPCJobMissionCompleted') - StopNPCJob() - NPCTargetDeleterZone = false - else - ESX.ShowNotification(_U('not_right_veh')) - end - - else - ESX.ShowNotification(_U('not_right_place')) - end + if model == 'prop_roadcone02a' then + z = z - 2.0 + elseif model == 'prop_toolchest_01' then + z = z - 2.0 end - CurrentlyTowedVehicle = nil - ESX.ShowNotification(_U('veh_det_succ')) - - end - else - ESX.ShowNotification(_U('imp_flatbed')) - end - - elseif data.current.value == 'object_spawner' then - - local playerPed = PlayerPedId() - - if IsPedSittingInAnyVehicle(playerPed) then - ESX.ShowNotification(_U('inside_vehicle')) - return - end - - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'mobile_mechanic_actions_spawn', { - title = _U('objects'), - align = 'top-left', - elements = { - {label = _U('roadcone'), value = 'prop_roadcone02a'}, - {label = _U('toolbox'), value = 'prop_toolchest_01'} - } - }, function(data2, menu2) - local model = data2.current.value - local coords = GetEntityCoords(playerPed) - local forward = GetEntityForwardVector(playerPed) - local x, y, z = table.unpack(coords + forward * 1.0) - - if model == 'prop_roadcone02a' then - z = z - 2.0 - elseif model == 'prop_toolchest_01' then - z = z - 2.0 - end - - ESX.Game.SpawnObject(model, { - x = x, - y = y, - z = z - }, function(obj) - SetEntityHeading(obj, GetEntityHeading(playerPed)) - PlaceObjectOnGroundProperly(obj) + ESX.Game.SpawnObject(model, {x = x, y = y, z = z}, function(obj) + SetEntityHeading(obj, GetEntityHeading(playerPed)) + PlaceObjectOnGroundProperly(obj) + end) + end, function(data2, menu2) + menu2.close() end) - - end, function(data2, menu2) - menu2.close() - end) - - end - + end end, function(data, menu) menu.close() end) @@ -561,7 +511,6 @@ end function OpenGetStocksMenu() ESX.TriggerServerCallback('esx_mechanicjob:getStockItems', function(items) - local elements = {} for i=1, #items, 1 do @@ -571,13 +520,11 @@ function OpenGetStocksMenu() }) end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', { title = _U('mechanic_stock'), align = 'top-left', elements = elements }, function(data, menu) - local itemName = data.current.value ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'stocks_menu_get_item_count', { @@ -598,17 +545,13 @@ function OpenGetStocksMenu() end, function(data2, menu2) menu2.close() end) - end, function(data, menu) menu.close() end) - end) - end function OpenPutStocksMenu() - ESX.TriggerServerCallback('esx_mechanicjob:getPlayerInventory', function(inventory) local elements = {} @@ -629,7 +572,6 @@ function OpenPutStocksMenu() align = 'top-left', elements = elements }, function(data, menu) - local itemName = data.current.value ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'stocks_menu_put_item_count', { @@ -653,19 +595,16 @@ function OpenPutStocksMenu() end, function(data, menu) menu.close() end) - end) - end - RegisterNetEvent('esx_mechanicjob:onHijack') AddEventHandler('esx_mechanicjob:onHijack', function() local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then - local vehicle = nil + local vehicle if IsPedInAnyVehicle(playerPed, false) then vehicle = GetVehiclePedIsIn(playerPed, false) @@ -696,7 +635,6 @@ AddEventHandler('esx_mechanicjob:onHijack', function() ClearPedTasksImmediately(playerPed) end end) - end end end) @@ -707,7 +645,7 @@ AddEventHandler('esx_mechanicjob:onCarokit', function() local coords = GetEntityCoords(playerPed) if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then - local vehicle = nil + local vehicle if IsPedInAnyVehicle(playerPed, false) then vehicle = GetVehiclePedIsIn(playerPed, false) @@ -734,7 +672,7 @@ AddEventHandler('esx_mechanicjob:onFixkit', function() local coords = GetEntityCoords(playerPed) if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then - local vehicle = nil + local vehicle if IsPedInAnyVehicle(playerPed, false) then vehicle = GetVehiclePedIsIn(playerPed, false) @@ -767,7 +705,7 @@ AddEventHandler('esx:setJob', function(job) end) AddEventHandler('esx_mechanicjob:hasEnteredMarker', function(zone) - if zone == NPCJobTargetTowable then + if zone == 'NPCJobTargetTowable' then elseif zone =='VehicleDelivery' then NPCTargetDeleterZone = true @@ -995,7 +933,7 @@ Citizen.CreateThread(function() if CurrentAction then ESX.ShowHelpNotification(CurrentActionMsg) - if IsControlJustReleased(0, Keys['E']) and ESX.PlayerData.job and ESX.PlayerData.job.name == 'mechanic' then + if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == 'mechanic' then if CurrentAction == 'mechanic_actions_menu' then OpenMechanicActionsMenu() @@ -1032,11 +970,11 @@ Citizen.CreateThread(function() end end - if IsControlJustReleased(0, Keys['F6']) and not isDead and ESX.PlayerData.job and ESX.PlayerData.job.name == 'mechanic' then + if IsControlJustReleased(0, 167) and not isDead and ESX.PlayerData.job and ESX.PlayerData.job.name == 'mechanic' then OpenMobileMechanicActionsMenu() end - if IsControlJustReleased(0, Keys['DELETE']) and not isDead and ESX.PlayerData.job and ESX.PlayerData.job.name == 'mechanic' then + if IsControlJustReleased(0, 178) and not isDead and ESX.PlayerData.job and ESX.PlayerData.job.name == 'mechanic' then if NPCOnJob then if GetGameTimer() - NPCLastCancel > 5 * 60000 then StopNPCJob(true) diff --git a/config.lua b/config.lua index da6efb2c..d048056c 100644 --- a/config.lua +++ b/config.lua @@ -24,91 +24,90 @@ Config.Zones = { Pos = { x = -342.291, y = -133.370, z = 38.009 }, Size = { x = 1.5, y = 1.5, z = 1.0 }, Color = { r = 204, g = 204, b = 0 }, - Type = 1, + Type = 1 }, Garage = { Pos = { x = -97.5, y = 6496.1, z = 30.4 }, Size = { x = 1.5, y = 1.5, z = 1.0 }, Color = { r = 204, g = 204, b = 0 }, - Type = 1, + Type = 1 }, Craft = { Pos = { x = -323.140, y = -129.882, z = 37.999 }, Size = { x = 1.5, y = 1.5, z = 1.0 }, Color = { r = 204, g = 204, b = 0 }, - Type = 1, + Type = 1 }, VehicleSpawnPoint = { Pos = { x = -366.354, y = -110.766, z = 37.696 }, Size = { x = 1.5, y = 1.5, z = 1.0 }, - Type = -1, + Type = -1 }, VehicleDeleter = { Pos = { x = -386.899, y = -105.675, z = 37.683 }, Size = { x = 3.0, y = 3.0, z = 1.0 }, Color = { r = 204, g = 204, b = 0 }, - Type = 1, + Type = 1 }, VehicleDelivery = { Pos = { x = -382.925, y = -133.748, z = 37.685 }, Size = { x = 20.0, y = 20.0, z = 3.0 }, Color = { r = 204, g = 204, b = 0 }, - Type = -1, + Type = -1 } - } Config.Towables = { - { ['x'] = -2480.8720703125, ['y'] = -211.96409606934, ['z'] = 17.397672653198 }, - { ['x'] = -2723.392578125, ['y'] = 13.207388877869, ['z'] = 15.12806892395 }, - { ['x'] = -3169.6235351563, ['y'] = 976.18127441406, ['z'] = 15.038360595703 }, - { ['x'] = -3139.7568359375, ['y'] = 1078.7182617188, ['z'] = 20.189767837524 }, - { ['x'] = -1656.9357910156, ['y'] = -246.16479492188, ['z'] = 54.510955810547 }, - { ['x'] = -1586.6560058594, ['y'] = -647.56115722656, ['z'] = 29.441320419312 }, - { ['x'] = -1036.1470947266, ['y'] = -491.05856323242, ['z'] = 36.214912414551 }, - { ['x'] = -1029.1884765625, ['y'] = -475.53167724609, ['z'] = 36.416831970215 }, - { ['x'] = 75.212287902832, ['y'] = 164.8522644043, ['z'] = 104.69123077393 }, - { ['x'] = -534.60491943359, ['y'] = -756.71801757813, ['z'] = 31.599143981934 }, - { ['x'] = 487.24212646484, ['y'] = -30.827201843262, ['z'] = 88.856712341309 }, - { ['x'] = -772.20111083984, ['y'] = -1281.8114013672, ['z'] = 4.5642876625061 }, - { ['x'] = -663.84173583984, ['y'] = -1206.9936523438, ['z'] = 10.171216011047 }, - { ['x'] = 719.12451171875, ['y'] = -767.77545166016, ['z'] = 24.892364501953 }, - { ['x'] = -970.95465087891, ['y'] = -2410.4453125, ['z'] = 13.344270706177 }, - { ['x'] = -1067.5234375, ['y'] = -2571.4064941406, ['z'] = 13.211874008179 }, - { ['x'] = -619.23968505859, ['y'] = -2207.2927246094, ['z'] = 5.5659561157227 }, - { ['x'] = 1192.0831298828, ['y'] = -1336.9086914063, ['z'] = 35.106426239014 }, - { ['x'] = -432.81033325195, ['y'] = -2166.0505371094, ['z'] = 9.8885231018066 }, - { ['x'] = -451.82403564453, ['y'] = -2269.34765625, ['z'] = 7.1719741821289 }, - { ['x'] = 939.26702880859, ['y'] = -2197.5390625, ['z'] = 30.546691894531 }, - { ['x'] = -556.11486816406, ['y'] = -1794.7312011719, ['z'] = 22.043060302734 }, - { ['x'] = 591.73504638672, ['y'] = -2628.2197265625, ['z'] = 5.5735430717468 }, - { ['x'] = 1654.515625, ['y'] = -2535.8325195313, ['z'] = 74.491394042969 }, - { ['x'] = 1642.6146240234, ['y'] = -2413.3159179688, ['z'] = 93.139915466309 }, - { ['x'] = 1371.3223876953, ['y'] = -2549.525390625, ['z'] = 47.575256347656 }, - { ['x'] = 383.83779907227, ['y'] = -1652.8695068359, ['z'] = 37.278503417969 }, - { ['x'] = 27.219129562378, ['y'] = -1030.8818359375, ['z'] = 29.414621353149 }, - { ['x'] = 229.26435852051, ['y'] = -365.91101074219, ['z'] = 43.750762939453 }, - { ['x'] = -85.809432983398, ['y'] = -51.665500640869, ['z'] = 61.10591506958 }, - { ['x'] = -4.5967531204224, ['y'] = -670.27124023438, ['z'] = 31.85863494873 }, - { ['x'] = -111.89884185791, ['y'] = 91.96940612793, ['z'] = 71.080169677734 }, - { ['x'] = -314.26129150391, ['y'] = -698.23309326172, ['z'] = 32.545776367188 }, - { ['x'] = -366.90979003906, ['y'] = 115.53963470459, ['z'] = 65.575706481934 }, - { ['x'] = -592.06726074219, ['y'] = 138.20733642578, ['z'] = 60.074813842773 }, - { ['x'] = -1613.8572998047, ['y'] = 18.759860992432, ['z'] = 61.799819946289 }, - { ['x'] = -1709.7995605469, ['y'] = 55.105819702148, ['z'] = 65.706237792969 }, - { ['x'] = -521.88830566406, ['y'] = -266.7805480957, ['z'] = 34.940990447998 }, - { ['x'] = -451.08666992188, ['y'] = -333.52026367188, ['z'] = 34.021533966064 }, - { ['x'] = 322.36480712891, ['y'] = -1900.4990234375, ['z'] = 25.773607254028 } + vector3(-2480.9, -212.0, 17.4), + vector3(-2723.4, 13.2, 15.1), + vector3(-3169.6, 976.2, 15.0), + vector3(-3139.8, 1078.7, 20.2), + vector3(-1656.9, -246.2, 54.5), + vector3(-1586.7, -647.6, 29.4), + vector3(-1036.1, -491.1, 36.2), + vector3(-1029.2, -475.5, 36.4), + vector3(75.2, 164.9, 104.7), + vector3(-534.6, -756.7, 31.6), + vector3(487.2, -30.8, 88.9), + vector3(-772.2, -1281.8, 4.6), + vector3(-663.8, -1207.0, 10.2), + vector3(719.1, -767.8, 24.9), + vector3(-971.0, -2410.4, 13.3), + vector3(-1067.5, -2571.4, 13.2), + vector3(-619.2, -2207.3, 5.6), + vector3(1192.1, -1336.9, 35.1), + vector3(-432.8, -2166.1, 9.9), + vector3(-451.8, -2269.3, 7.2), + vector3(939.3, -2197.5, 30.5), + vector3(-556.1, -1794.7, 22.0), + vector3(591.7, -2628.2, 5.6), + vector3(1654.5, -2535.8, 74.5), + vector3(1642.6, -2413.3, 93.1), + vector3(1371.3, -2549.5, 47.6), + vector3(383.8, -1652.9, 37.3), + vector3(27.2, -1030.9, 29.4), + vector3(229.3, -365.9, 43.8), + vector3(-85.8, -51.7, 61.1), + vector3(-4.6, -670.3, 31.9), + vector3(-111.9, 92.0, 71.1), + vector3(-314.3, -698.2, 32.5), + vector3(-366.9, 115.5, 65.6), + vector3(-592.1, 138.2, 60.1), + vector3(-1613.9, 18.8, 61.8), + vector3(-1709.8, 55.1, 65.7), + vector3(-521.9, -266.8, 34.9), + vector3(-451.1, -333.5, 34.0), + vector3(322.4, -1900.5, 25.8) } -for i=1, #Config.Towables, 1 do - Config.Zones['Towable' .. i] = { - Pos = Config.Towables[i], +for k,v in ipairs(Config.Towables) do + Config.Zones['Towable' .. k] = { + Pos = v, Size = { x = 1.5, y = 1.5, z = 1.0 }, Color = { r = 204, g = 204, b = 0 }, Type = -1 From 1d2d7fbaa9d800159f57262064a062f763152cc6 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 31 May 2019 12:58:07 +0200 Subject: [PATCH 2219/3224] Config cleanup --- config.lua | 185 ++++++++++++++++++++++++++--------------------------- 1 file changed, 92 insertions(+), 93 deletions(-) diff --git a/config.lua b/config.lua index 82820e87..cebf1139 100644 --- a/config.lua +++ b/config.lua @@ -56,100 +56,99 @@ Config.Zones = { Color = {r = 204, g = 204, b = 0}, Type = 21, Rotate = true } - } Config.JobLocations = { - {x = 293.476, y = -590.163, z = 42.7371}, - {x = 253.404, y = -375.86, z = 44.0819}, - {x = 120.808, y = -300.416, z = 45.1399}, - {x = -38.4132, y = -381.576, z = 38.3456}, - {x = -107.442, y = -614.377, z = 35.6703}, - {x = -252.292, y = -856.474, z = 30.5626}, - {x = -236.138, y = -988.382, z = 28.7749}, - {x = -276.989, y = -1061.18, z = 25.6853}, - {x = -576.451, y = -998.989, z = 21.785}, - {x = -602.798, y = -952.63, z = 21.6353}, - {x = -790.653, y = -961.855, z = 14.8932}, - {x = -912.588, y = -864.756, z = 15.0057}, - {x = -1069.77, y = -792.513, z = 18.8075}, - {x = -1306.94, y = -854.085, z = 15.0959}, - {x = -1468.51, y = -681.363, z = 26.178}, - {x = -1380.89, y = -452.7, z = 34.0843}, - {x = -1326.35, y = -394.81, z = 36.0632}, - {x = -1383.68, y = -269.985, z = 42.4878}, - {x = -1679.61, y = -457.339, z = 39.4048}, - {x = -1812.45, y = -416.917, z = 43.6734}, - {x = -2043.64, y = -268.291, z = 22.9927}, - {x = -2186.45, y = -421.595, z = 12.6776}, - {x = -1862.08, y = -586.528, z = 11.1747}, - {x = -1859.5, y = -617.563, z = 10.8788}, - {x = -1634.95, y = -988.302, z = 12.6241}, - {x = -1283.99, y = -1154.16, z = 5.30998}, - {x = -1126.47, y = -1338.08, z = 4.63434}, - {x = -867.907, y = -1159.67, z = 5.00795}, - {x = -847.55, y = -1141.38, z = 6.27591}, - {x = -722.625, y = -1144.6, z = 10.2176}, - {x = -575.503, y = -318.446, z = 34.5273}, - {x = -592.309, y = -224.853, z = 36.1209}, - {x = -559.594, y = -162.873, z = 37.7547}, - {x = -534.992, y = -65.6695, z = 40.634}, - {x = -758.234, y = -36.6906, z = 37.2911}, - {x = -1375.88, y = 20.9516, z = 53.2255}, - {x = -1320.25, y = -128.018, z = 48.097}, - {x = -1285.71, y = 294.287, z = 64.4619}, - {x = -1245.67, y = 386.533, z = 75.0908}, - {x = -760.355, y = 285.015, z = 85.0667}, - {x = -626.786, y = 254.146, z = 81.0964}, - {x = -563.609, y = 267.962, z = 82.5116}, - {x = -486.806, y = 271.977, z = 82.8187}, - {x = 88.295, y = 250.867, z = 108.188}, - {x = 234.087, y = 344.678, z = 105.018}, - {x = 434.963, y = 96.707, z = 99.1713}, - {x = 482.617, y = -142.533, z = 58.1936}, - {x = 762.651, y = -786.55, z = 25.8915}, - {x = 809.06, y = -1290.8, z = 25.7946}, - {x = 490.819, y = -1751.37, z = 28.0987}, - {x = 432.351, y = -1856.11, z = 27.0352}, - {x = 164.348, y = -1734.54, z = 28.8982}, - {x = -57.6909, y = -1501.4, z = 31.1084}, - {x = 52.2241, y = -1566.65, z = 29.006}, - {x = 310.222, y = -1376.76, z = 31.4442}, - {x = 181.967, y = -1332.79, z = 28.8773}, - {x = -74.6091, y = -1100.64, z = 25.738}, - {x = -887.045, y = -2187.46, z = 8.13248}, - {x = -749.584, y = -2296.59, z = 12.4627}, - {x = -1064.83, y = -2560.66, z = 19.6811}, - {x = -1033.44, y = -2730.24, z = 19.6868}, - {x = -1018.67, y = -2732, z = 13.2687}, - {x = 797.354, y = -174.423, z = 72.708}, - {x = 508.156, y = -117.908, z = 60.78}, - {x = 159.458, y = -27.555, z = 67.38}, - {x = -36.382, y = -106.912, z = 56.982}, - {x = -355.801, y = -270.404, z = 33.011}, - {x = -831.196, y = -76.871, z = 37.323}, - {x = -1038.707, y = -214.593, z = 37}, - {x = 1918.448, y = 3691.41, z = 32.261}, - {x = 1820.217, y = 3697.115, z = 33.493}, - {x = 1619.323, y = 3827.162, z = 34.482}, - {x = 1418.628, y = 3602.243, z = 34.511}, - {x = 1944.858, y = 3856.252, z = 31.741}, - {x = 2285.278, y = 3839.444, z = 34.023}, - {x = 2760.945, y = 3387.813, z = 55.659}, - {x = 1952.819, y = 2627.731, z = 45.368}, - {x = 1051.414, y = 474.833, z = 93.653}, - {x = 866.393, y = 17.635, z = 78.654}, - {x = 318.985, y = 167.41, z = 103.335}, - {x = 88.836, y = 254.054, z = 108.236}, - {x = -44.852, y = 70.414, z = 72.437}, - {x = -115.496, y = 84.333, z = 70.792}, - {x = -384.806, y = 226.868, z = 83.548}, - {x = -578.669, y = 139.085, z = 61.337}, - {x = -651.334, y = -584.879, z = 34.116}, - {x = -571.847, y = -1195.648, z = 17.869}, - {x = -1513.271, y = -670.039, z = 28.362}, - {x = -1297.484, y = -654.913, z = 26.123}, - {x = -1645.546, y = 144.571, z = 61.664}, - {x = -1160.618, y = 744.418, z = 154.571}, - {x = -798.09, y = 831.699, z = 204.351}, + vector3(293.5, -590.2, 42.7), + vector3(253.4, -375.9, 44.1), + vector3(120.8, -300.4, 45.1), + vector3(-38.4, -381.6, 38.3), + vector3(-107.4, -614.4, 35.7), + vector3(-252.3, -856.5, 30.6), + vector3(-236.1, -988.4, 28.8), + vector3(-277.0, -1061.2, 25.7), + vector3(-576.5, -999.0, 21.8), + vector3(-602.8, -952.6, 21.6), + vector3(-790.7, -961.9, 14.9), + vector3(-912.6, -864.8, 15.0), + vector3(-1069.8, -792.5, 18.8), + vector3(-1306.9, -854.1, 15.1), + vector3(-1468.5, -681.4, 26.2), + vector3(-1380.9, -452.7, 34.1), + vector3(-1326.3, -394.8, 36.1), + vector3(-1383.7, -270.0, 42.5), + vector3(-1679.6, -457.3, 39.4), + vector3(-1812.5, -416.9, 43.7), + vector3(-2043.6, -268.3, 23.0), + vector3(-2186.4, -421.6, 12.7), + vector3(-1862.1, -586.5, 11.2), + vector3(-1859.5, -617.6, 10.9), + vector3(-1635.0, -988.3, 12.6), + vector3(-1284.0, -1154.2, 5.3), + vector3(-1126.5, -1338.1, 4.6), + vector3(-867.9, -1159.7, 5.0), + vector3(-847.5, -1141.4, 6.3), + vector3(-722.6, -1144.6, 10.2), + vector3(-575.5, -318.4, 34.5), + vector3(-592.3, -224.9, 36.1), + vector3(-559.6, -162.9, 37.8), + vector3(-535.0, -65.7, 40.6), + vector3(-758.2, -36.7, 37.3), + vector3(-1375.9, 21.0, 53.2), + vector3(-1320.3, -128.0, 48.1), + vector3(-1285.7, 294.3, 64.5), + vector3(-1245.7, 386.5, 75.1), + vector3(-760.4, 285.0, 85.1), + vector3(-626.8, 254.1, 81.1), + vector3(-563.6, 268.0, 82.5), + vector3(-486.8, 272.0, 82.8), + vector3(88.3, 250.9, 108.2), + vector3(234.1, 344.7, 105.0), + vector3(435.0, 96.7, 99.2), + vector3(482.6, -142.5, 58.2), + vector3(762.7, -786.5, 25.9), + vector3(809.1, -1290.8, 25.8), + vector3(490.8, -1751.4, 28.1), + vector3(432.4, -1856.1, 27.0), + vector3(164.3, -1734.5, 28.9), + vector3(-57.7, -1501.4, 31.1), + vector3(52.2, -1566.7, 29.0), + vector3(310.2, -1376.8, 31.4), + vector3(182.0, -1332.8, 28.9), + vector3(-74.6, -1100.6, 25.7), + vector3(-887.0, -2187.5, 8.1), + vector3(-749.6, -2296.6, 12.5), + vector3(-1064.8, -2560.7, 19.7), + vector3(-1033.4, -2730.2, 19.7), + vector3(-1018.7, -2732.0, 13.3), + vector3(797.4, -174.4, 72.7), + vector3(508.2, -117.9, 60.8), + vector3(159.5, -27.6, 67.4), + vector3(-36.4, -106.9, 57.0), + vector3(-355.8, -270.4, 33.0), + vector3(-831.2, -76.9, 37.3), + vector3(-1038.7, -214.6, 37.0), + vector3(1918.4, 3691.4, 32.3), + vector3(1820.2, 3697.1, 33.5), + vector3(1619.3, 3827.2, 34.5), + vector3(1418.6, 3602.2, 34.5), + vector3(1944.9, 3856.3, 31.7), + vector3(2285.3, 3839.4, 34.0), + vector3(2760.9, 3387.8, 55.7), + vector3(1952.8, 2627.7, 45.4), + vector3(1051.4, 474.8, 93.7), + vector3(866.4, 17.6, 78.7), + vector3(319.0, 167.4, 103.3), + vector3(88.8, 254.1, 108.2), + vector3(-44.9, 70.4, 72.4), + vector3(-115.5, 84.3, 70.8), + vector3(-384.8, 226.9, 83.5), + vector3(-578.7, 139.1, 61.3), + vector3(-651.3, -584.9, 34.1), + vector3(-571.8, -1195.6, 17.9), + vector3(-1513.3, -670.0, 28.4), + vector3(-1297.5, -654.9, 26.1), + vector3(-1645.5, 144.6, 61.7), + vector3(-1160.6, 744.4, 154.6), + vector3(-798.1, 831.7, 204.4) } From 2b354112846da7e0d2d7c693825e291d76506b10 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 31 May 2019 13:04:59 +0200 Subject: [PATCH 2220/3224] Minor cleanup --- client/main.lua | 111 ++++++++++++++++++------------------------------ 1 file changed, 42 insertions(+), 69 deletions(-) diff --git a/client/main.lua b/client/main.lua index e6a04f78..debf7487 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,31 +1,7 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} +local HasAlreadyEnteredMarker, OnJob, IsNearCustomer, CustomerIsEnteringVehicle, CustomerEnteredVehicle, IsDead, CurrentActionData = false, false, false, false, false, false, {} +local CurrentCustomer, CurrentCustomerBlip, DestinationBlip, targetCoords, LastZone, CurrentAction, CurrentActionMsg -local HasAlreadyEnteredMarker = false -local LastZone = nil -local CurrentAction = nil -local CurrentActionMsg = '' -local CurrentActionData = {} -local OnJob = false -local CurrentCustomer = nil -local CurrentCustomerBlip = nil -local DestinationBlip = nil -local IsNearCustomer = false -local CustomerIsEnteringVehicle = false -local CustomerEnteredVehicle = false -local TargetCoords = nil -local IsDead = false - -ESX = nil +ESX = nil Citizen.CreateThread(function() while ESX == nil do @@ -42,16 +18,17 @@ end) function DrawSub(msg, time) ClearPrints() - SetTextEntry_2("STRING") - AddTextComponentString(msg) - DrawSubtitleTimed(time, 1) + BeginTextCommandPrint('STRING') + AddTextComponentSubstringPlayerName(msg) + EndTextCommandPrint(time, 1) end function ShowLoadingPromt(msg, time, type) Citizen.CreateThread(function() Citizen.Wait(0) - BeginTextCommandBusyString("STRING") - AddTextComponentString(msg) + + BeginTextCommandBusyString('STRING') + AddTextComponentSubstringPlayerName(msg) EndTextCommandBusyString(type) Citizen.Wait(time) @@ -101,7 +78,7 @@ function ClearCurrentMission() IsNearCustomer = false CustomerIsEnteringVehicle = false CustomerEnteredVehicle = false - TargetCoords = nil + targetCoords = nil end function StartTaxiJob() @@ -119,7 +96,7 @@ function StopTaxiJob() TaskLeaveVehicle(CurrentCustomer, vehicle, 0) if CustomerEnteredVehicle then - TaskGoStraightToCoord(CurrentCustomer, TargetCoords.x, TargetCoords.y, TargetCoords.z, 1.0, -1, 0.0, 0.0) + TaskGoStraightToCoord(CurrentCustomer, targetCoords.x, targetCoords.y, targetCoords.z, 1.0, -1, 0.0, 0.0) end end @@ -269,8 +246,7 @@ function OpenTaxiActionsMenu() ESX.UI.Menu.CloseAll() - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'taxi_actions', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'taxi_actions', { title = 'Taxi', align = 'top-left', elements = elements @@ -298,15 +274,13 @@ end function OpenMobileTaxiActionsMenu() ESX.UI.Menu.CloseAll() - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'mobile_taxi_actions', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'mobile_taxi_actions', { title = 'Taxi', align = 'top-left', elements = { - { label = _U('billing'), value = 'billing' }, - { label = _U('start_job'), value = 'start_job' } - } - }, function(data, menu) + {label = _U('billing'), value = 'billing'}, + {label = _U('start_job'), value = 'start_job'} + }}, function(data, menu) if data.current.value == 'billing' then ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'billing', { @@ -389,8 +363,7 @@ function OpenGetStocksMenu() }) end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', { title = 'Taxi Stock', align = 'top-left', elements = elements @@ -400,7 +373,6 @@ function OpenGetStocksMenu() ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'stocks_menu_get_item_count', { title = _U('quantity') }, function(data2, menu2) - local count = tonumber(data2.value) if count == nil then @@ -414,7 +386,6 @@ function OpenGetStocksMenu() Citizen.Wait(1000) OpenGetStocksMenu() end - end, function(data2, menu2) menu2.close() end) @@ -441,8 +412,7 @@ function OpenPutStocksMenu() end end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', { title = _U('inventory'), align = 'top-left', elements = elements @@ -452,7 +422,6 @@ function OpenPutStocksMenu() ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'stocks_menu_put_item_count', { title = _U('quantity') }, function(data2, menu2) - local count = tonumber(data2.value) if count == nil then @@ -537,7 +506,7 @@ Citizen.CreateThread(function() SetBlipColour (blip, 5) SetBlipAsShortRange(blip, true) - BeginTextCommandSetBlipName("STRING") + BeginTextCommandSetBlipName('STRING') AddTextComponentSubstringPlayerName(_U('blip_taxi')) EndTextCommandSetBlipName(blip) end) @@ -549,12 +518,13 @@ Citizen.CreateThread(function() if ESX.PlayerData.job and ESX.PlayerData.job.name == 'taxi' then local coords = GetEntityCoords(PlayerPedId()) - local isInMarker, currentZone = false + local isInMarker, letSleep, currentZone = false, true for k,v in pairs(Config.Zones) do local distance = GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) if v.Type ~= -1 and distance < Config.DrawDistance then + letSleep = false DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, false, 2, v.Rotate, nil, nil, false) end @@ -572,6 +542,10 @@ Citizen.CreateThread(function() HasAlreadyEnteredMarker = false TriggerEvent('esx_taxijob:hasExitedMarker', LastZone) end + + if letSleep then + Citizen.Wait(500) + end else Citizen.Wait(1000) end @@ -632,25 +606,25 @@ Citizen.CreateThread(function() SetEntityAsMissionEntity(CurrentCustomer, false, true) - CurrentCustomer, CurrentCustomerBlip, DestinationBlip, IsNearCustomer, CustomerIsEnteringVehicle, CustomerEnteredVehicle, TargetCoords = nil, nil, nil, false, false, false, nil + CurrentCustomer, CurrentCustomerBlip, DestinationBlip, IsNearCustomer, CustomerIsEnteringVehicle, CustomerEnteredVehicle, targetCoords = nil, nil, nil, false, false, false, nil end if IsPedInAnyVehicle(playerPed, false) then local vehicle = GetVehiclePedIsIn(playerPed, false) local playerCoords = GetEntityCoords(playerPed) local customerCoords = GetEntityCoords(CurrentCustomer) - local customerDistance = GetDistanceBetweenCoords(playerCoords.x, playerCoords.y, playerCoords.z, customerCoords.x, customerCoords.y, customerCoords.z) + local customerDistance = #(playerCoords - customerCoords) if IsPedSittingInVehicle(CurrentCustomer, vehicle) then if CustomerEnteredVehicle then - local targetDistance = GetDistanceBetweenCoords(playerCoords.x, playerCoords.y, playerCoords.z, TargetCoords.x, TargetCoords.y, TargetCoords.z) + local targetDistance = #(playerCoords - targetCoords) if targetDistance <= 10.0 then TaskLeaveVehicle(CurrentCustomer, vehicle, 0) ESX.ShowNotification(_U('arrive_dest')) - TaskGoStraightToCoord(CurrentCustomer, TargetCoords.x, TargetCoords.y, TargetCoords.z, 1.0, -1, 0.0, 0.0) + TaskGoStraightToCoord(CurrentCustomer, targetCoords.x, targetCoords.y, targetCoords.z, 1.0, -1, 0.0, 0.0) SetEntityAsMissionEntity(CurrentCustomer, false, true) TriggerServerEvent('esx_taxijob:success') RemoveBlip(DestinationBlip) @@ -663,26 +637,25 @@ Citizen.CreateThread(function() scope(CurrentCustomer) - CurrentCustomer, CurrentCustomerBlip, DestinationBlip, IsNearCustomer, CustomerIsEnteringVehicle, CustomerEnteredVehicle, TargetCoords = nil, nil, nil, false, false, false, nil + CurrentCustomer, CurrentCustomerBlip, DestinationBlip, IsNearCustomer, CustomerIsEnteringVehicle, CustomerEnteredVehicle, targetCoords = nil, nil, nil, false, false, false, nil end - if TargetCoords then - DrawMarker(36, TargetCoords.x, TargetCoords.y, TargetCoords.z + 1.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 234, 223, 72, 155, false, false, 2, true, nil, nil, false) + if targetCoords then + DrawMarker(36, targetCoords.x, targetCoords.y, targetCoords.z + 1.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 234, 223, 72, 155, false, false, 2, true, nil, nil, false) end else RemoveBlip(CurrentCustomerBlip) CurrentCustomerBlip = nil - TargetCoords = Config.JobLocations[GetRandomIntInRange(1, #Config.JobLocations)] - local distance = GetDistanceBetweenCoords(playerCoords, TargetCoords.x, TargetCoords.y, TargetCoords.z, true) - + targetCoords = Config.JobLocations[GetRandomIntInRange(1, #Config.JobLocations)] + local distance = #(playerCoords - targetCoords) while distance < Config.MinimumDistance do Citizen.Wait(5) - TargetCoords = Config.JobLocations[GetRandomIntInRange(1, #Config.JobLocations)] - distance = GetDistanceBetweenCoords(playerCoords, TargetCoords.x, TargetCoords.y, TargetCoords.z, true) + targetCoords = Config.JobLocations[GetRandomIntInRange(1, #Config.JobLocations)] + distance = #(playerCoords - targetCoords) end - local street = table.pack(GetStreetNameAtCoord(TargetCoords.x, TargetCoords.y, TargetCoords.z)) + local street = table.pack(GetStreetNameAtCoord(targetCoords.x, targetCoords.y, targetCoords.z)) local msg = nil if street[2] ~= 0 and street[2] ~= nil then @@ -693,10 +666,10 @@ Citizen.CreateThread(function() ESX.ShowNotification(msg) - DestinationBlip = AddBlipForCoord(TargetCoords.x, TargetCoords.y, TargetCoords.z) + DestinationBlip = AddBlipForCoord(targetCoords.x, targetCoords.y, targetCoords.z) - BeginTextCommandSetBlipName("STRING") - AddTextComponentSubstringPlayerName("Destination") + BeginTextCommandSetBlipName('STRING') + AddTextComponentSubstringPlayerName('Destination') EndTextCommandSetBlipName(blip) SetBlipRoute(DestinationBlip, true) @@ -754,7 +727,7 @@ Citizen.CreateThread(function() if CurrentAction and not IsDead then ESX.ShowHelpNotification(CurrentActionMsg) - if IsControlJustReleased(0, Keys['E']) and ESX.PlayerData.job and ESX.PlayerData.job.name == 'taxi' then + if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == 'taxi' then if CurrentAction == 'taxi_actions_menu' then OpenTaxiActionsMenu() elseif CurrentAction == 'cloakroom' then @@ -769,7 +742,7 @@ Citizen.CreateThread(function() end end - if IsControlJustReleased(0, Keys['F6']) and IsInputDisabled(0) and not IsDead and Config.EnablePlayerManagement and ESX.PlayerData.job and ESX.PlayerData.job.name == 'taxi' then + if IsControlJustReleased(0, 167) and IsInputDisabled(0) and not IsDead and Config.EnablePlayerManagement and ESX.PlayerData.job and ESX.PlayerData.job.name == 'taxi' then OpenMobileTaxiActionsMenu() end end From 701b438433d6031e2fc19687f20fd432619570ef Mon Sep 17 00:00:00 2001 From: KandaSoranyan <32266067+KandaSoranyan@users.noreply.github.com> Date: Fri, 31 May 2019 13:12:53 +0200 Subject: [PATCH 2221/3224] missing translations --- locales/fr.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index 4d942293..bcceafae 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,15 +1,15 @@ Locales['fr'] = { -- cloakroom - ['cloakroom_menu'] = 'cloakroom', - ['cloakroom_prompt'] = 'press ~INPUT_CONTEXT~ to open the ~y~cloakroom~s~.', - ['wear_citizen'] = 'citizen wear', - ['wear_work'] = 'taxi wear', + ['cloakroom_menu'] = 'vestiaire', + ['cloakroom_prompt'] = 'appuyez sur ~INPUT_CONTEXT~ pour ouvrir le ~y~cloakroom~s~.', + ['wear_citizen'] = 'tenue civile', + ['wear_work'] = 'tenue de travail', -- garage - ['spawner_prompt'] = 'press ~INPUT_CONTEXT~ to open the ~y~garage~s~.', + ['spawner_prompt'] = 'appuyez sur ~INPUT_CONTEXT~ pour ouvrir le ~y~garage~s~.', ['store_veh'] = 'appuyez sur ~INPUT_CONTEXT~ pour ranger le véhicule', ['spawn_veh'] = 'sortir véhicule', - ['spawnpoint_blocked'] = 'there is a vehicle blocking the spawnpoint!', + ['spawnpoint_blocked'] = 'un véhicule bloque la sortie!!', ['only_taxi'] = 'vous ne pouvez ranger que les taxi', ['taking_service'] = 'prise de service : Taxi/Uber', @@ -46,4 +46,4 @@ Locales['fr'] = { ['player_cannot_hold'] = 'vous n\'avez pas assez ~y~de place~s~ dans votre inventaire!', ['blip_taxi'] = 'taxi', ['phone_taxi'] = 'taxi', -} \ No newline at end of file +} From 8be80eda4ec4ae535d6bb1539c06982011a5f501 Mon Sep 17 00:00:00 2001 From: KandaSoranyan <32266067+KandaSoranyan@users.noreply.github.com> Date: Fri, 31 May 2019 13:16:41 +0200 Subject: [PATCH 2222/3224] missing translation --- locales/fr.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index c4dcbf34..72206bac 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -22,7 +22,7 @@ Locales['fr'] = { ['blowtorch'] = 'chalumeaux', ['repair_kit'] = 'kit Réparation', ['body_kit'] = 'kit Carosserie', - ['craft'] = 'etabli', + ['craft'] = 'établi', ['craft_menu'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder au menu établi.', ['billing'] = 'facturation', ['hijack'] = 'crocheter', @@ -33,8 +33,8 @@ Locales['fr'] = { ['invoice_amount'] = 'montant de la facture', ['amount_invalid'] = 'montant invalide', ['no_players_nearby'] = 'aucun joueur à proximité', - ['no_vehicle_nearby'] = 'there is no nearby vehicle', - ['inside_vehicle'] = 'you can\'t do this from inside the vehicle!', + ['no_vehicle_nearby'] = 'aucun véhicule à proximité', + ['inside_vehicle'] = 'vous ne pouvez pas effectuer cette action depuis un véhicule!', ['vehicle_unlocked'] = 'véhicule ~g~déverouillé', ['vehicle_repaired'] = 'véhicule ~g~réparé', ['vehicle_cleaned'] = 'véhicule ~g~néttoyé', @@ -51,7 +51,7 @@ Locales['fr'] = { ['objects'] = 'objets', ['roadcone'] = 'plot', ['toolbox'] = 'boîte à outils', - ['mechanic_stock'] = 'mecano Stock', + ['mechanic_stock'] = 'coffre de l\'entreprise', ['quantity'] = 'quantité', ['invalid_quantity'] = 'quantité invalide', ['inventory'] = 'inventaire', @@ -82,5 +82,5 @@ Locales['fr'] = { ['you_used_body_kit'] = 'Vous avez utilisé un ~b~Kit de carosserie', ['have_withdrawn'] = 'vous avez pris ~y~x%s~s~ ~b~%s~s~', ['have_deposited'] = 'vous avez déposé ~y~x%s~s~ ~b~%s~s~', - ['player_cannot_hold'] = 'you do ~r~not~s~ have enough ~y~free space~s~ in your inventory!', + ['player_cannot_hold'] = 'vous n\'avez ~r~pas assez~s~ d\'~y~espace libre~s~ dans votre inventaire!', } From e762d6e0284d133223ab001c16b419a1c3fed651 Mon Sep 17 00:00:00 2001 From: KandaSoranyan <32266067+KandaSoranyan@users.noreply.github.com> Date: Fri, 31 May 2019 13:23:55 +0200 Subject: [PATCH 2223/3224] missing translation --- locales/fr.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index 79cba6c3..2165e130 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -15,8 +15,8 @@ Locales['fr'] = { ['buy_weapons'] = 'acheter Armes', ['armory'] = 'armurerie', ['open_armory'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder à l\'armurerie', - ['armory_owned'] = 'owned', - ['armory_free'] = 'free', + ['armory_owned'] = 'possédé', + ['armory_free'] = 'gratuit', ['armory_item'] = '$%s', ['armory_weapontitle'] = 'armurerie - Acheter une arme', ['armory_componenttitle'] = 'armurerie - Accessoires d\'armes', @@ -110,7 +110,7 @@ Locales['fr'] = { ['height'] = 'taille: %s', ['id'] = 'ID: %s', ['bac'] = 'BAC: %s', - ['unknown'] = 'unknown', + ['unknown'] = 'inconnu', ['male'] = 'homme', ['female'] = 'femme', -- Body Search Menu @@ -118,7 +118,7 @@ Locales['fr'] = { ['inventory_label'] = '--- Inventaire ---', ['license_label'] = ' --- Licenses ---', ['confiscate'] = 'confisquer %s', - ['confiscate_weapon'] = 'confiscate %s with %s bullets', + ['confiscate_weapon'] = 'confisqué %s avec %s balles', ['confiscate_inv'] = 'confisquer %sx %s', ['confiscate_dirty'] = 'confisquer argent sale: €%s', ['you_confiscated'] = 'vous avez confisqué ~y~%sx~s~ ~b~%s~s~ à ~b~%s~s~', @@ -143,11 +143,11 @@ Locales['fr'] = { ['have_deposited'] = 'vous avez déposé ~y~%sx~s~ ~b~%s~s~', ['quantity'] = 'quantité', ['inventory'] = 'inventaire', - ['police_stock'] = 'stock Police', + ['police_stock'] = 'coffre de la police', -- Misc ['remove_prop'] = 'appuyez sur ~INPUT_CONTEXT~ pour enlever l\'objet', ['map_blip'] = 'Commissariat', - ['unrestrained_timer'] = 'vous sentez que vos entraves se relachent.', + ['unrestrained_timer'] = 'vous sentez que vos menottes deviennent fragiles.', -- Notifications ['alert_police'] = 'alerte police', ['phone_police'] = 'police', From 7cfebdd843c359b1c838b663a4ad825c8e30fdc3 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 31 May 2019 22:40:10 +0200 Subject: [PATCH 2224/3224] Minor cleanup --- client/main.lua | 576 ++++++++++++++++-------------------------------- server/main.lua | 12 +- 2 files changed, 201 insertions(+), 387 deletions(-) diff --git a/client/main.lua b/client/main.lua index 5a245560..93bb1eff 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,32 +1,7 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - -local PlayerData = {} -local HasAlreadyEnteredMarker = false -local LastStation, LastPart, LastPartNum, LastEntity -local CurrentAction = nil -local CurrentActionMsg = '' -local CurrentActionData = {} -local IsHandcuffed = false -local HandcuffTimer = {} -local DragStatus = {} -DragStatus.IsDragged = false -local hasAlreadyJoined = false -local blipsCops = {} -local isDead = false -local CurrentTask = {} -local playerInService = false -local spawnedVehicles, isInShopMenu = {}, false - +local PlayerData, CurrentActionData, handcuffTimer, dragStatus, blipsCops, currentTask, spawnedVehicles = {}, {}, {}, {}, {}, {}, {} +local HasAlreadyEnteredMarker, isDead, IsHandcuffed, hasAlreadyJoined, playerInService, isInShopMenu = false, false, false, false, false, false +local LastStation, LastPart, LastPartNum, LastEntity, CurrentAction, CurrentActionMsg +dragStatus.isDragged = false ESX = nil Citizen.CreateThread(function() @@ -53,7 +28,7 @@ end function setUniform(job, playerPed) TriggerEvent('skinchanger:getSkin', function(skin) if skin.sex == 0 then - if Config.Uniforms[job].male ~= nil then + if Config.Uniforms[job].male then TriggerEvent('skinchanger:loadClothes', skin, Config.Uniforms[job].male) else ESX.ShowNotification(_U('no_outfit')) @@ -63,7 +38,7 @@ function setUniform(job, playerPed) SetPedArmour(playerPed, 100) end else - if Config.Uniforms[job].female ~= nil then + if Config.Uniforms[job].female then TriggerEvent('skinchanger:loadClothes', skin, Config.Uniforms[job].female) else ESX.ShowNotification(_U('no_outfit')) @@ -77,7 +52,6 @@ function setUniform(job, playerPed) end function OpenCloakroomMenu() - local playerPed = PlayerPedId() local grade = PlayerData.job.grade_name @@ -111,17 +85,14 @@ function OpenCloakroomMenu() ESX.UI.Menu.CloseAll() - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'cloakroom', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'cloakroom', { title = _U('cloakroom'), align = 'top-left', elements = elements }, function(data, menu) - cleanPlayer(playerPed) if data.current.value == 'citizen_wear' then - if Config.EnableNonFreemodePeds then ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) local isMale = skin.sex == 0 @@ -141,10 +112,8 @@ function OpenCloakroomMenu() end if Config.MaxInService ~= -1 then - ESX.TriggerServerCallback('esx_service:isInService', function(isInService) if isInService then - playerInService = false local notification = { @@ -162,7 +131,6 @@ function OpenCloakroomMenu() end end, 'police') end - end if Config.MaxInService ~= -1 and data.current.value ~= 'citizen_wear' then @@ -175,7 +143,6 @@ function OpenCloakroomMenu() if not canTakeService then ESX.ShowNotification(_U('service_max', inServiceCount, maxInService)) else - serviceOk = true playerInService = true @@ -185,7 +152,7 @@ function OpenCloakroomMenu() msg = _U('service_in_announce', GetPlayerName(PlayerId())), iconType = 1 } - + TriggerServerEvent('esx_service:notifyAllInService', notification, 'police') TriggerEvent('esx_policejob:updateBlip') ESX.ShowNotification(_U('service_in')) @@ -238,9 +205,7 @@ function OpenCloakroomMenu() TriggerEvent('esx:restoreLoadout') end) end) - end - end, function(data, menu) menu.close() @@ -264,8 +229,7 @@ function OpenArmoryMenu(station) ESX.UI.Menu.CloseAll() - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory', { title = _U('armory'), align = 'top-left', elements = elements @@ -306,7 +270,6 @@ function OpenVehicleSpawnerMenu(type, station, part, partNum) align = 'top-left', elements = elements }, function(data, menu) - if data.current.action == 'buy_vehicle' then local shopElements, shopCoords = {} @@ -411,20 +374,16 @@ function OpenVehicleSpawnerMenu(type, station, part, partNum) end, function(data2, menu2) menu2.close() end) - else ESX.ShowNotification(_U('garage_empty')) end end, type) - elseif data.current.action == 'store_garage' then StoreNearbyVehicle(playerCoords) end - end, function(data, menu) menu.close() end) - end function StoreNearbyVehicle(playerCoords) @@ -517,17 +476,13 @@ function OpenShopMenu(elements, restoreCoords, shopCoords) align = 'top-left', elements = elements }, function(data, menu) - - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop_confirm', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop_confirm', { title = _U('vehicleshop_confirm', data.current.name, data.current.price), align = 'top-left', elements = { - { label = _U('confirm_no'), value = 'no' }, - { label = _U('confirm_yes'), value = 'yes' } - } - }, function(data2, menu2) - + {label = _U('confirm_no'), value = 'no'}, + {label = _U('confirm_yes'), value = 'yes'} + }}, function(data2, menu2) if data2.current.value == 'yes' then local newPlate = exports['esx_vehicleshop']:GeneratePlate() local vehicle = GetVehiclePedIsIn(playerPed, false) @@ -540,11 +495,10 @@ function OpenShopMenu(elements, restoreCoords, shopCoords) isInShopMenu = false ESX.UI.Menu.CloseAll() - DeleteSpawnedVehicles() FreezeEntityPosition(playerPed, false) SetEntityVisible(playerPed, true) - + ESX.Game.Teleport(playerPed, restoreCoords) else ESX.ShowNotification(_U('vehicleshop_money')) @@ -554,12 +508,10 @@ function OpenShopMenu(elements, restoreCoords, shopCoords) else menu2.close() end - end, function(data2, menu2) menu2.close() end) - - end, function(data, menu) + end, function(data, menu) isInShopMenu = false ESX.UI.Menu.CloseAll() @@ -626,13 +578,7 @@ function WaitForVehicleToLoad(modelHash) while not HasModelLoaded(modelHash) do Citizen.Wait(0) - - DisableControlAction(0, Keys['TOP'], true) - DisableControlAction(0, Keys['DOWN'], true) - DisableControlAction(0, Keys['LEFT'], true) - DisableControlAction(0, Keys['RIGHT'], true) - DisableControlAction(0, 176, true) -- ENTER key - DisableControlAction(0, Keys['BACKSPACE'], true) + DisableAllControlActions(0) drawLoadingText(_U('vehicleshop_awaiting_model'), 255, 255, 255, 255) end @@ -648,7 +594,7 @@ function drawLoadingText(text, red, green, blue, alpha) SetTextOutline() SetTextCentre(true) - BeginTextCommandDisplayText("STRING") + BeginTextCommandDisplayText('STRING') AddTextComponentSubstringPlayerName(text) EndTextCommandDisplayText(0.5, 0.5) end @@ -656,36 +602,31 @@ end function OpenPoliceActionsMenu() ESX.UI.Menu.CloseAll() - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'police_actions', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'police_actions', { title = 'Police', align = 'top-left', elements = { - {label = _U('citizen_interaction'), value = 'citizen_interaction'}, - {label = _U('vehicle_interaction'), value = 'vehicle_interaction'}, - {label = _U('object_spawner'), value = 'object_spawner'} - } - }, function(data, menu) - + {label = _U('citizen_interaction'), value = 'citizen_interaction'}, + {label = _U('vehicle_interaction'), value = 'vehicle_interaction'}, + {label = _U('object_spawner'), value = 'object_spawner'} + }}, function(data, menu) if data.current.value == 'citizen_interaction' then local elements = { - {label = _U('id_card'), value = 'identity_card'}, - {label = _U('search'), value = 'body_search'}, - {label = _U('handcuff'), value = 'handcuff'}, - {label = _U('drag'), value = 'drag'}, - {label = _U('put_in_vehicle'), value = 'put_in_vehicle'}, - {label = _U('out_the_vehicle'), value = 'out_the_vehicle'}, - {label = _U('fine'), value = 'fine'}, - {label = _U('unpaid_bills'), value = 'unpaid_bills'} + {label = _U('id_card'), value = 'identity_card'}, + {label = _U('search'), value = 'body_search'}, + {label = _U('handcuff'), value = 'handcuff'}, + {label = _U('drag'), value = 'drag'}, + {label = _U('put_in_vehicle'), value = 'put_in_vehicle'}, + {label = _U('out_the_vehicle'), value = 'out_the_vehicle'}, + {label = _U('fine'), value = 'fine'}, + {label = _U('unpaid_bills'), value = 'unpaid_bills'} } - + if Config.EnableLicenses then table.insert(elements, { label = _U('license_check'), value = 'license' }) end - - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'citizen_interaction', - { + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'citizen_interaction', { title = _U('citizen_interaction'), align = 'top-left', elements = elements @@ -714,7 +655,6 @@ function OpenPoliceActionsMenu() elseif action == 'unpaid_bills' then OpenUnpaidBillsMenu(closestPlayer) end - else ESX.ShowNotification(_U('no_players_nearby')) end @@ -724,38 +664,34 @@ function OpenPoliceActionsMenu() elseif data.current.value == 'vehicle_interaction' then local elements = {} local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - local vehicle = ESX.Game.GetVehicleInDirection() - + local vehicle = ESX.Game.GetVehicleInDirection() + if DoesEntityExist(vehicle) then - table.insert(elements, {label = _U('vehicle_info'), value = 'vehicle_infos'}) - table.insert(elements, {label = _U('pick_lock'), value = 'hijack_vehicle'}) - table.insert(elements, {label = _U('impound'), value = 'impound'}) + table.insert(elements, {label = _U('vehicle_info'), value = 'vehicle_infos'}) + table.insert(elements, {label = _U('pick_lock'), value = 'hijack_vehicle'}) + table.insert(elements, {label = _U('impound'), value = 'impound'}) end - + table.insert(elements, {label = _U('search_database'), value = 'search_database'}) - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'vehicle_interaction', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_interaction', { title = _U('vehicle_interaction'), align = 'top-left', elements = elements }, function(data2, menu2) - coords = GetEntityCoords(playerPed) + local coords = GetEntityCoords(playerPed) vehicle = ESX.Game.GetVehicleInDirection() action = data2.current.value - + if action == 'search_database' then LookupVehicle() elseif DoesEntityExist(vehicle) then - local vehicleData = ESX.Game.GetVehicleProperties(vehicle) if action == 'vehicle_infos' then + local vehicleData = ESX.Game.GetVehicleProperties(vehicle) OpenVehicleInfosMenu(vehicleData) - elseif action == 'hijack_vehicle' then if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 3.0) then - TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_WELDING", 0, true) + TaskStartScenarioInPlace(playerPed, 'WORLD_HUMAN_WELDING', 0, true) Citizen.Wait(20000) ClearPedTasksImmediately(playerPed) @@ -764,34 +700,32 @@ function OpenPoliceActionsMenu() ESX.ShowNotification(_U('vehicle_unlocked')) end elseif action == 'impound' then - -- is the script busy? - if CurrentTask.Busy then + if currentTask.busy then return end ESX.ShowHelpNotification(_U('impound_prompt')) - TaskStartScenarioInPlace(playerPed, 'CODE_HUMAN_MEDIC_TEND_TO_DEAD', 0, true) - - CurrentTask.Busy = true - CurrentTask.Task = ESX.SetTimeout(10000, function() + + currentTask.busy = true + currentTask.task = ESX.SetTimeout(10000, function() ClearPedTasks(playerPed) ImpoundVehicle(vehicle) Citizen.Wait(100) -- sleep the entire script to let stuff sink back to reality end) - + -- keep track of that vehicle! Citizen.CreateThread(function() - while CurrentTask.Busy do + while currentTask.busy do Citizen.Wait(1000) - + vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 3.0, 0, 71) - if not DoesEntityExist(vehicle) and CurrentTask.Busy then + if not DoesEntityExist(vehicle) and currentTask.busy then ESX.ShowNotification(_U('impound_canceled_moved')) - ESX.ClearTimeout(CurrentTask.Task) + ESX.ClearTimeout(currentTask.task) ClearPedTasks(playerPed) - CurrentTask.Busy = false + currentTask.busy = false break end end @@ -804,73 +738,55 @@ function OpenPoliceActionsMenu() end, function(data2, menu2) menu2.close() end) - elseif data.current.value == 'object_spawner' then - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'citizen_interaction', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'citizen_interaction', { title = _U('traffic_interaction'), align = 'top-left', elements = { - {label = _U('cone'), value = 'prop_roadcone02a'}, - {label = _U('barrier'), value = 'prop_barrier_work05'}, - {label = _U('spikestrips'), value = 'p_ld_stinger_s'}, - {label = _U('box'), value = 'prop_boxpile_07d'}, - {label = _U('cash'), value = 'hei_prop_cash_crate_half_full'} - } - }, function(data2, menu2) - local model = data2.current.value + {label = _U('cone'), model = 'prop_roadcone02a'}, + {label = _U('barrier'), model = 'prop_barrier_work05'}, + {label = _U('spikestrips'), model = 'p_ld_stinger_s'}, + {label = _U('box'), model = 'prop_boxpile_07d'}, + {label = _U('cash'), model = 'hei_prop_cash_crate_half_full'} + }}, function(data2, menu2) local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) local forward = GetEntityForwardVector(playerPed) local x, y, z = table.unpack(coords + forward * 1.0) - if model == 'prop_roadcone02a' then + if data2.current.model == 'prop_roadcone02a' then z = z - 2.0 end - ESX.Game.SpawnObject(model, { - x = x, - y = y, - z = z - }, function(obj) + ESX.Game.SpawnObject(data2.current.model, {x = x, y = y, z = z}, function(obj) SetEntityHeading(obj, GetEntityHeading(playerPed)) PlaceObjectOnGroundProperly(obj) end) - end, function(data2, menu2) menu2.close() end) end - end, function(data, menu) menu.close() end) end function OpenIdentityCardMenu(player) - ESX.TriggerServerCallback('esx_policejob:getOtherPlayerData', function(data) + local elements = {} + local nameLabel = _U('name', data.name) + local jobLabel, sexLabel, dobLabel, heightLabel, idLabel - local elements = {} - local nameLabel = _U('name', data.name) - local jobLabel = nil - local sexLabel = nil - local dobLabel = nil - local heightLabel = nil - local idLabel = nil - - if data.job.grade_label ~= nil and data.job.grade_label ~= '' then + if data.job.grade_label and data.job.grade_label ~= '' then jobLabel = _U('job', data.job.label .. ' - ' .. data.job.grade_label) else jobLabel = _U('job', data.job.label) end - + if Config.EnableESXIdentity then - nameLabel = _U('name', data.firstname .. ' ' .. data.lastname) - - if data.sex ~= nil then + + if data.sex then if string.lower(data.sex) == 'm' then sexLabel = _U('sex', _U('male')) else @@ -879,78 +795,66 @@ function OpenIdentityCardMenu(player) else sexLabel = _U('sex', _U('unknown')) end - - if data.dob ~= nil then + + if data.dob then dobLabel = _U('dob', data.dob) else dobLabel = _U('dob', _U('unknown')) end - - if data.height ~= nil then + + if data.height then heightLabel = _U('height', data.height) else heightLabel = _U('height', _U('unknown')) end - - if data.name ~= nil then + + if data.name then idLabel = _U('id', data.name) else idLabel = _U('id', _U('unknown')) end - end - + local elements = { - {label = nameLabel, value = nil}, - {label = jobLabel, value = nil}, + {label = nameLabel}, + {label = jobLabel} } - + if Config.EnableESXIdentity then - table.insert(elements, {label = sexLabel, value = nil}) - table.insert(elements, {label = dobLabel, value = nil}) - table.insert(elements, {label = heightLabel, value = nil}) - table.insert(elements, {label = idLabel, value = nil}) + table.insert(elements, {label = sexLabel}) + table.insert(elements, {label = dobLabel}) + table.insert(elements, {label = heightLabel}) + table.insert(elements, {label = idLabel}) end - - if data.drunk ~= nil then - table.insert(elements, {label = _U('bac', data.drunk), value = nil}) + + if data.drunk then + table.insert(elements, {label = _U('bac', data.drunk)}) end - - if data.licenses ~= nil then - - table.insert(elements, {label = _U('license_label'), value = nil}) - + + if data.licenses then + table.insert(elements, {label = _U('license_label')}) + for i=1, #data.licenses, 1 do - table.insert(elements, {label = data.licenses[i].label, value = nil}) + table.insert(elements, {label = data.licenses[i].label}) end - end - - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'citizen_interaction', - { + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'citizen_interaction', { title = _U('citizen_interaction'), align = 'top-left', - elements = elements, - }, function(data, menu) - - end, function(data, menu) + elements = elements + }, nil, function(data, menu) menu.close() end) - end, GetPlayerServerId(player)) - end function OpenBodySearchMenu(player) - ESX.TriggerServerCallback('esx_policejob:getOtherPlayerData', function(data) - local elements = {} for i=1, #data.accounts, 1 do - if data.accounts[i].name == 'black_money' and data.accounts[i].money > 0 then - table.insert(elements, { label = _U('confiscate_dirty', ESX.Math.Round(data.accounts[i].money)), value = 'black_money', @@ -960,10 +864,9 @@ function OpenBodySearchMenu(player) break end - end - table.insert(elements, {label = _U('guns_label'), value = nil}) + table.insert(elements, {label = _U('guns_label')}) for i=1, #data.weapons, 1 do table.insert(elements, { @@ -974,7 +877,7 @@ function OpenBodySearchMenu(player) }) end - table.insert(elements, {label = _U('inventory_label'), value = nil}) + table.insert(elements, {label = _U('inventory_label')}) for i=1, #data.inventory, 1 do if data.inventory[i].count > 0 then @@ -987,35 +890,23 @@ function OpenBodySearchMenu(player) end end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'body_search', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'body_search', { title = _U('search'), align = 'top-left', - elements = elements, - }, - function(data, menu) - - local itemType = data.current.itemType - local itemName = data.current.value - local amount = data.current.amount - - if data.current.value ~= nil then - TriggerServerEvent('esx_policejob:confiscatePlayerItem', GetPlayerServerId(player), itemType, itemName, amount) + elements = elements + }, function(data, menu) + if data.current.value then + TriggerServerEvent('esx_policejob:confiscatePlayerItem', GetPlayerServerId(player), data.current.itemType, data.current.value, data.current.amount) OpenBodySearchMenu(player) end - end, function(data, menu) menu.close() end) - end, GetPlayerServerId(player)) - end function OpenFineMenu(player) - - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'fine', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'fine', { title = _U('fine'), align = 'top-left', elements = { @@ -1023,58 +914,46 @@ function OpenFineMenu(player) {label = _U('minor_offense'), value = 1}, {label = _U('average_offense'), value = 2}, {label = _U('major_offense'), value = 3} - } - }, function(data, menu) + }}, function(data, menu) OpenFineCategoryMenu(player, data.current.value) end, function(data, menu) menu.close() end) - end function OpenFineCategoryMenu(player, category) - ESX.TriggerServerCallback('esx_policejob:getFineList', function(fines) - local elements = {} - for i=1, #fines, 1 do + for k,fine in ipairs(fines) do table.insert(elements, { - label = fines[i].label .. ' $' .. fines[i].amount .. '', - value = fines[i].id, - amount = fines[i].amount, - fineLabel = fines[i].label + label = ('%s %s'):format(fine.label, _U('armory_item', ESX.Math.GroupDigits(fine.amount))), + value = fine.id, + amount = fine.amount, + fineLabel = fine.label }) end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'fine_category', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'fine_category', { title = _U('fine'), align = 'top-left', - elements = elements, + elements = elements }, function(data, menu) - - local label = data.current.fineLabel - local amount = data.current.amount - menu.close() if Config.EnablePlayerManagement then - TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(player), 'society_police', _U('fine_total', label), amount) + TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(player), 'society_police', _U('fine_total', data.current.fineLabel), data.current.amount) else - TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(player), '', _U('fine_total', label), amount) + TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(player), '', _U('fine_total', data.current.fineLabel), data.current.amount) end ESX.SetTimeout(300, function() OpenFineCategoryMenu(player, category) end) - end, function(data, menu) menu.close() end) - end, category) - end function LookupVehicle() @@ -1114,13 +993,13 @@ function ShowPlayerLicense(player) end end end - + if Config.EnableESXIdentity then targetName = data.firstname .. ' ' .. data.lastname else targetName = data.name end - + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'manage_license', { title = _U('license_revoke'), @@ -1129,9 +1008,9 @@ function ShowPlayerLicense(player) }, function(data, menu) ESX.ShowNotification(_U('licence_you_revoked', data.current.label, targetName)) TriggerServerEvent('esx_policejob:message', GetPlayerServerId(player), _U('license_revoked', data.current.label)) - + TriggerServerEvent('esx_license:removeLicense', GetPlayerServerId(player), data.current.type) - + ESX.SetTimeout(300, function() ShowPlayerLicense(player) end) @@ -1146,55 +1025,44 @@ function OpenUnpaidBillsMenu(player) local elements = {} ESX.TriggerServerCallback('esx_billing:getTargetBills', function(bills) - for i=1, #bills, 1 do + for k,bill in ipairs(bills) do table.insert(elements, { - label = bills[i].label .. ' - $' .. bills[i].amount .. '', - value = bills[i].id + label = ('%s - %s'):format(bill.label, _U('armory_item', ESX.Math.GroupDigits(bill.amount))), + billId = bills[i].id }) end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'billing', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'billing', { title = _U('unpaid_bills'), align = 'top-left', elements = elements - }, function(data, menu) - - end, function(data, menu) + }, nil, function(data, menu) menu.close() end) end, GetPlayerServerId(player)) end function OpenVehicleInfosMenu(vehicleData) - ESX.TriggerServerCallback('esx_policejob:getVehicleInfos', function(retrivedInfo) - - local elements = {} - - table.insert(elements, {label = _U('plate', retrivedInfo.plate), value = nil}) + local elements = {{label = _U('plate', retrivedInfo.plate)}} if retrivedInfo.owner == nil then - table.insert(elements, {label = _U('owner_unknown'), value = nil}) + table.insert(elements, {label = _U('owner_unknown')}) else - table.insert(elements, {label = _U('owner', retrivedInfo.owner), value = nil}) + table.insert(elements, {label = _U('owner', retrivedInfo.owner)}) end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_infos', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_infos', { title = _U('vehicle_info'), align = 'top-left', elements = elements }, nil, function(data, menu) menu.close() end) - end, vehicleData.plate) - end function OpenGetWeaponMenu() - ESX.TriggerServerCallback('esx_policejob:getArmoryWeapons', function(weapons) local elements = {} @@ -1207,24 +1075,20 @@ function OpenGetWeaponMenu() end end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory_get_weapon', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory_get_weapon', { title = _U('get_weapon_menu'), align = 'top-left', elements = elements }, function(data, menu) - menu.close() ESX.TriggerServerCallback('esx_policejob:removeArmoryWeapon', function() OpenGetWeaponMenu() end, data.current.value) - end, function(data, menu) menu.close() end) end) - end function OpenPutWeaponMenu() @@ -1243,26 +1107,22 @@ function OpenPutWeaponMenu() end end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory_put_weapon', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory_put_weapon', { title = _U('put_weapon_menu'), align = 'top-left', elements = elements }, function(data, menu) - menu.close() ESX.TriggerServerCallback('esx_policejob:addArmoryWeapon', function() OpenPutWeaponMenu() end, data.current.value, true) - end, function(data, menu) menu.close() end) end function OpenBuyWeaponsMenu() - local elements = {} local playerPed = PlayerPedId() PlayerData = ESX.GetPlayerData() @@ -1270,13 +1130,11 @@ function OpenBuyWeaponsMenu() for k,v in ipairs(Config.AuthorizedWeapons[PlayerData.job.grade_name]) do local weaponNum, weapon = ESX.GetWeapon(v.weapon) local components, label = {} - local hasWeapon = HasPedGotWeapon(playerPed, GetHashKey(v.weapon), false) if v.components then for i=1, #v.components do if v.components[i] then - local component = weapon.components[i] local hasComponent = HasPedGotWeaponComponent(playerPed, GetHashKey(v.weapon), component.hash) @@ -1330,7 +1188,6 @@ function OpenBuyWeaponsMenu() align = 'top-left', elements = elements }, function(data, menu) - if data.current.hasWeapon then if #data.current.components > 0 then OpenWeaponComponentShop(data.current.components, data.current.name, menu) @@ -1343,18 +1200,15 @@ function OpenBuyWeaponsMenu() end menu.close() - OpenBuyWeaponsMenu() else ESX.ShowNotification(_U('armory_money')) end end, data.current.name, 1) end - end, function(data, menu) menu.close() end) - end function OpenWeaponComponentShop(components, weaponName, parentShop) @@ -1363,7 +1217,6 @@ function OpenWeaponComponentShop(components, weaponName, parentShop) align = 'top-left', elements = components }, function(data, menu) - if data.current.hasComponent then ESX.ShowNotification(_U('armory_hascomponent')) else @@ -1375,23 +1228,19 @@ function OpenWeaponComponentShop(components, weaponName, parentShop) menu.close() parentShop.close() - OpenBuyWeaponsMenu() else ESX.ShowNotification(_U('armory_money')) end end, weaponName, 2, data.current.componentNum) end - end, function(data, menu) menu.close() end) end function OpenGetStocksMenu() - ESX.TriggerServerCallback('esx_policejob:getStockItems', function(items) - local elements = {} for i=1, #items, 1 do @@ -1401,19 +1250,16 @@ function OpenGetStocksMenu() }) end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', { title = _U('police_stock'), align = 'top-left', elements = elements }, function(data, menu) - local itemName = data.current.value ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'stocks_menu_get_item_count', { title = _U('quantity') }, function(data2, menu2) - local count = tonumber(data2.value) if count == nil then @@ -1426,23 +1272,17 @@ function OpenGetStocksMenu() Citizen.Wait(300) OpenGetStocksMenu() end - end, function(data2, menu2) menu2.close() end) - end, function(data, menu) menu.close() end) - end) - end function OpenPutStocksMenu() - ESX.TriggerServerCallback('esx_policejob:getPlayerInventory', function(inventory) - local elements = {} for i=1, #inventory.items, 1 do @@ -1457,19 +1297,16 @@ function OpenPutStocksMenu() end end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', { title = _U('inventory'), align = 'top-left', elements = elements }, function(data, menu) - local itemName = data.current.value ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'stocks_menu_put_item_count', { title = _U('quantity') }, function(data2, menu2) - local count = tonumber(data2.value) if count == nil then @@ -1482,22 +1319,19 @@ function OpenPutStocksMenu() Citizen.Wait(300) OpenPutStocksMenu() end - end, function(data2, menu2) menu2.close() end) - end, function(data, menu) menu.close() end) end) - end RegisterNetEvent('esx:setJob') AddEventHandler('esx:setJob', function(job) PlayerData.job = job - + Citizen.Wait(5000) TriggerServerEvent('esx_policejob:forceBlip') end) @@ -1515,7 +1349,7 @@ end) -- don't show dispatches if the player isn't in service AddEventHandler('esx_phone:cancelMessage', function(dispatchNumber) - if type(PlayerData.job.name) == 'string' and PlayerData.job.name == 'police' and PlayerData.job.name == dispatchNumber then + if PlayerData.job and PlayerData.job.name == 'police' and PlayerData.job.name == dispatchNumber then -- if esx_service is enabled if Config.MaxInService ~= -1 and not playerInService then CancelEvent() @@ -1524,38 +1358,27 @@ AddEventHandler('esx_phone:cancelMessage', function(dispatchNumber) end) AddEventHandler('esx_policejob:hasEnteredMarker', function(station, part, partNum) - if part == 'Cloakroom' then CurrentAction = 'menu_cloakroom' CurrentActionMsg = _U('open_cloackroom') CurrentActionData = {} - elseif part == 'Armory' then - CurrentAction = 'menu_armory' CurrentActionMsg = _U('open_armory') CurrentActionData = {station = station} - elseif part == 'Vehicles' then - CurrentAction = 'menu_vehicle_spawner' CurrentActionMsg = _U('garage_prompt') CurrentActionData = {station = station, part = part, partNum = partNum} - elseif part == 'Helicopters' then - CurrentAction = 'Helicopters' CurrentActionMsg = _U('helicopter_prompt') CurrentActionData = {station = station, part = part, partNum = partNum} - elseif part == 'BossActions' then - CurrentAction = 'menu_boss_actions' CurrentActionMsg = _U('open_bossmenu') CurrentActionData = {} - end - end) AddEventHandler('esx_policejob:hasExitedMarker', function(station, part, partNum) @@ -1569,7 +1392,7 @@ end) AddEventHandler('esx_policejob:hasEnteredEntityZone', function(entity) local playerPed = PlayerPedId() - if PlayerData.job ~= nil and PlayerData.job.name == 'police' and IsPedOnFoot(playerPed) then + if PlayerData.job and PlayerData.job.name == 'police' and IsPedOnFoot(playerPed) then CurrentAction = 'remove_entity' CurrentActionMsg = _U('remove_prop') CurrentActionData = {entity = entity} @@ -1618,18 +1441,15 @@ AddEventHandler('esx_policejob:handcuff', function() DisplayRadar(false) if Config.EnableHandcuffTimer then - - if HandcuffTimer.Active then - ESX.ClearTimeout(HandcuffTimer.Task) + if handcuffTimer.active then + ESX.ClearTimeout(handcuffTimer.task) end StartHandcuffTimer() end - else - - if Config.EnableHandcuffTimer and HandcuffTimer.Active then - ESX.ClearTimeout(HandcuffTimer.Task) + if Config.EnableHandcuffTimer and handcuffTimer.active then + ESX.ClearTimeout(handcuffTimer.task) end ClearPedSecondaryTask(playerPed) @@ -1640,7 +1460,6 @@ AddEventHandler('esx_policejob:handcuff', function() DisplayRadar(true) end end) - end) RegisterNetEvent('esx_policejob:unrestrain') @@ -1657,20 +1476,20 @@ AddEventHandler('esx_policejob:unrestrain', function() DisplayRadar(true) -- end timer - if Config.EnableHandcuffTimer and HandcuffTimer.Active then - ESX.ClearTimeout(HandcuffTimer.Task) + if Config.EnableHandcuffTimer and handcuffTimer.active then + ESX.ClearTimeout(handcuffTimer.task) end end end) RegisterNetEvent('esx_policejob:drag') -AddEventHandler('esx_policejob:drag', function(copID) +AddEventHandler('esx_policejob:drag', function(copId) if not IsHandcuffed then return end - DragStatus.IsDragged = not DragStatus.IsDragged - DragStatus.CopId = tonumber(copID) + dragStatus.isDragged = not dragStatus.isDragged + dragStatus.CopId = copId end) Citizen.CreateThread(function() @@ -1683,19 +1502,19 @@ Citizen.CreateThread(function() if IsHandcuffed then playerPed = PlayerPedId() - if DragStatus.IsDragged then - targetPed = GetPlayerPed(GetPlayerFromServerId(DragStatus.CopId)) + if dragStatus.isDragged then + targetPed = GetPlayerPed(GetPlayerFromServerId(dragStatus.CopId)) -- undrag if target is in an vehicle if not IsPedSittingInAnyVehicle(targetPed) then AttachEntityToEntity(playerPed, targetPed, 11816, 0.54, 0.54, 0.0, 0.0, 0.0, 0.0, false, false, false, false, 2, true) else - DragStatus.IsDragged = false + dragStatus.isDragged = false DetachEntity(playerPed, true, false) end if IsPedDeadOrDying(targetPed, true) then - DragStatus.IsDragged = false + dragStatus.isDragged = false DetachEntity(playerPed, true, false) end @@ -1732,7 +1551,7 @@ AddEventHandler('esx_policejob:putInVehicle', function() if freeSeat then TaskWarpPedIntoVehicle(playerPed, vehicle, freeSeat) - DragStatus.IsDragged = false + dragStatus.isDragged = false end end end @@ -1753,7 +1572,7 @@ end) -- Handcuff Citizen.CreateThread(function() while true do - Citizen.Wait(1) + Citizen.Wait(0) local playerPed = PlayerPedId() if IsHandcuffed then @@ -1763,32 +1582,32 @@ Citizen.CreateThread(function() DisableControlAction(0, 257, true) -- Attack 2 DisableControlAction(0, 25, true) -- Aim DisableControlAction(0, 263, true) -- Melee Attack 1 - DisableControlAction(0, Keys['W'], true) -- W - DisableControlAction(0, Keys['A'], true) -- A - DisableControlAction(0, 31, true) -- S (fault in Keys table!) - DisableControlAction(0, 30, true) -- D (fault in Keys table!) + DisableControlAction(0, 32, true) -- W + DisableControlAction(0, 34, true) -- A + DisableControlAction(0, 31, true) -- S + DisableControlAction(0, 30, true) -- D - DisableControlAction(0, Keys['R'], true) -- Reload - DisableControlAction(0, Keys['SPACE'], true) -- Jump - DisableControlAction(0, Keys['Q'], true) -- Cover - DisableControlAction(0, Keys['TAB'], true) -- Select Weapon - DisableControlAction(0, Keys['F'], true) -- Also 'enter'? + DisableControlAction(0, 45, true) -- Reload + DisableControlAction(0, 22, true) -- Jump + DisableControlAction(0, 44, true) -- Cover + DisableControlAction(0, 37, true) -- Select Weapon + DisableControlAction(0, 23, true) -- Also 'enter'? - DisableControlAction(0, Keys['F1'], true) -- Disable phone - DisableControlAction(0, Keys['F2'], true) -- Inventory - DisableControlAction(0, Keys['F3'], true) -- Animations - DisableControlAction(0, Keys['F6'], true) -- Job + DisableControlAction(0, 288, true) -- Disable phone + DisableControlAction(0, 289, true) -- Inventory + DisableControlAction(0, 170, true) -- Animations + DisableControlAction(0, 167, true) -- Job - DisableControlAction(0, Keys['V'], true) -- Disable changing view - DisableControlAction(0, Keys['C'], true) -- Disable looking behind - DisableControlAction(0, Keys['X'], true) -- Disable clearing animation - DisableControlAction(2, Keys['P'], true) -- Disable pause screen + DisableControlAction(0, 0, true) -- Disable changing view + DisableControlAction(0, 26, true) -- Disable looking behind + DisableControlAction(0, 73, true) -- Disable clearing animation + DisableControlAction(2, 199, true) -- Disable pause screen DisableControlAction(0, 59, true) -- Disable steering in vehicle DisableControlAction(0, 71, true) -- Disable driving forward in vehicle DisableControlAction(0, 72, true) -- Disable reversing in vehicle - DisableControlAction(2, Keys['LEFTCTRL'], true) -- Disable going stealth + DisableControlAction(2, 36, true) -- Disable going stealth DisableControlAction(0, 47, true) -- Disable weapon DisableControlAction(0, 264, true) -- Disable melee @@ -1833,10 +1652,9 @@ end) -- Display markers Citizen.CreateThread(function() while true do - Citizen.Wait(0) - if PlayerData.job ~= nil and PlayerData.job.name == 'police' then + if PlayerData.job and PlayerData.job.name == 'police' then local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) @@ -1914,9 +1732,8 @@ Citizen.CreateThread(function() end if isInMarker and not HasAlreadyEnteredMarker or (isInMarker and (LastStation ~= currentStation or LastPart ~= currentPart or LastPartNum ~= currentPartNum)) then - if - (LastStation ~= nil and LastPart ~= nil and LastPartNum ~= nil) and + (LastStation and LastPart and LastPartNum) and (LastStation ~= currentStation or LastPart ~= currentPart or LastPartNum ~= currentPartNum) then TriggerEvent('esx_policejob:hasExitedMarker', LastStation, LastPart, LastPartNum) @@ -1929,7 +1746,6 @@ Citizen.CreateThread(function() LastPartNum = currentPartNum TriggerEvent('esx_policejob:hasEnteredMarker', currentStation, currentPart, currentPartNum) - end if not hasExited and not isInMarker and HasAlreadyEnteredMarker then @@ -1944,7 +1760,6 @@ Citizen.CreateThread(function() else Citizen.Wait(500) end - end end) @@ -1987,7 +1802,7 @@ Citizen.CreateThread(function() LastEntity = closestEntity end else - if LastEntity ~= nil then + if LastEntity then TriggerEvent('esx_policejob:hasExitedEntityZone', LastEntity) LastEntity = nil end @@ -1998,13 +1813,12 @@ end) -- Key Controls Citizen.CreateThread(function() while true do - Citizen.Wait(0) - if CurrentAction ~= nil then + if CurrentAction then ESX.ShowHelpNotification(CurrentActionMsg) - if IsControlJustReleased(0, Keys['E']) and PlayerData.job ~= nil and PlayerData.job.name == 'police' then + if IsControlJustReleased(0, 38) and PlayerData.job and PlayerData.job.name == 'police' then if CurrentAction == 'menu_cloakroom' then OpenCloakroomMenu() @@ -2046,12 +1860,12 @@ Citizen.CreateThread(function() elseif CurrentAction == 'remove_entity' then DeleteEntity(CurrentActionData.entity) end - + CurrentAction = nil end end -- CurrentAction end - - if IsControlJustReleased(0, Keys['F6']) and not isDead and PlayerData.job ~= nil and PlayerData.job.name == 'police' and not ESX.UI.Menu.IsOpen('default', GetCurrentResourceName(), 'police_actions') then + + if IsControlJustReleased(0, 167) and not isDead and PlayerData.job and PlayerData.job.name == 'police' and not ESX.UI.Menu.IsOpen('default', GetCurrentResourceName(), 'police_actions') then if Config.MaxInService == -1 then OpenPoliceActionsMenu() elseif playerInService then @@ -2060,13 +1874,13 @@ Citizen.CreateThread(function() ESX.ShowNotification(_U('service_not')) end end - - if IsControlJustReleased(0, Keys['E']) and CurrentTask.Busy then + + if IsControlJustReleased(0, 38) and currentTask.busy then ESX.ShowNotification(_U('impound_canceled')) - ESX.ClearTimeout(CurrentTask.Task) + ESX.ClearTimeout(currentTask.task) ClearPedTasks(PlayerPedId()) - - CurrentTask.Busy = false + + currentTask.busy = false end end end) @@ -2084,19 +1898,19 @@ function createBlip(id) SetBlipNameToPlayerName(blip, id) -- update blip name SetBlipScale(blip, 0.85) -- set scale SetBlipAsShortRange(blip, true) - + table.insert(blipsCops, blip) -- add blip to array so we can remove it later end end RegisterNetEvent('esx_policejob:updateBlip') AddEventHandler('esx_policejob:updateBlip', function() - + -- Refresh all blips for k, existingBlip in pairs(blipsCops) do RemoveBlip(existingBlip) end - + -- Clean the blip table blipsCops = {} @@ -2108,9 +1922,9 @@ AddEventHandler('esx_policejob:updateBlip', function() if not Config.EnableJobBlip then return end - + -- Is the player a cop? In that case show all the blips for other cops - if PlayerData.job ~= nil and PlayerData.job.name == 'police' then + if PlayerData.job and PlayerData.job.name == 'police' then ESX.TriggerServerCallback('esx_society:getOnlinePlayers', function(players) for i=1, #players, 1 do if players[i].job.name == 'police' then @@ -2128,7 +1942,7 @@ end) AddEventHandler('playerSpawned', function(spawn) isDead = false TriggerEvent('esx_policejob:unrestrain') - + if not hasAlreadyJoined then TriggerServerEvent('esx_policejob:spawned') end @@ -2148,24 +1962,24 @@ AddEventHandler('onResourceStop', function(resource) TriggerServerEvent('esx_service:disableService', 'police') end - if Config.EnableHandcuffTimer and HandcuffTimer.Active then - ESX.ClearTimeout(HandcuffTimer.Task) + if Config.EnableHandcuffTimer and handcuffTimer.active then + ESX.ClearTimeout(handcuffTimer.task) end end end) -- handcuff timer, unrestrain the player after an certain amount of time function StartHandcuffTimer() - if Config.EnableHandcuffTimer and HandcuffTimer.Active then - ESX.ClearTimeout(HandcuffTimer.Task) + if Config.EnableHandcuffTimer and handcuffTimer.active then + ESX.ClearTimeout(handcuffTimer.task) end - HandcuffTimer.Active = true + handcuffTimer.active = true - HandcuffTimer.Task = ESX.SetTimeout(Config.HandcuffTimer, function() + handcuffTimer.task = ESX.SetTimeout(Config.handcuffTimer, function() ESX.ShowNotification(_U('unrestrained_timer')) TriggerEvent('esx_policejob:unrestrain') - HandcuffTimer.Active = false + handcuffTimer.active = false end) end @@ -2174,7 +1988,7 @@ end -- - message owner that his vehicle has been impounded function ImpoundVehicle(vehicle) --local vehicleName = GetLabelText(GetDisplayNameFromVehicleModel(GetEntityModel(vehicle))) - ESX.Game.DeleteVehicle(vehicle) + ESX.Game.DeleteVehicle(vehicle) ESX.ShowNotification(_U('impound_successful')) - CurrentTask.Busy = false + currentTask.busy = false end diff --git a/server/main.lua b/server/main.lua index b4898a9b..fb356401 100644 --- a/server/main.lua +++ b/server/main.lua @@ -26,7 +26,7 @@ AddEventHandler('esx_policejob:confiscatePlayerItem', function(target, itemType, -- does the target player have enough in their inventory? if targetItem.count > 0 and targetItem.count <= amount then - + -- can the player carry the said amount of x item? if sourceItem.limit ~= -1 and (sourceItem.count + amount) > sourceItem.limit then TriggerClientEvent('esx:showNotification', _source, _U('quantity_invalid')) @@ -112,7 +112,7 @@ AddEventHandler('esx_policejob:getStockItem', function(itemName, count) -- is there enough in the society? if count > 0 and inventoryItem.count >= count then - + -- can the player carry the said amount of x item? if sourceItem.limit ~= -1 and (sourceItem.count + count) > sourceItem.limit then TriggerClientEvent('esx:showNotification', _source, _U('quantity_invalid')) @@ -513,24 +513,24 @@ end) AddEventHandler('playerDropped', function() -- Save the source in case we lose it (which happens a lot) local _source = source - + -- Did the player ever join? if _source ~= nil then local xPlayer = ESX.GetPlayerFromId(_source) - + -- Is it worth telling all clients to refresh? if xPlayer ~= nil and xPlayer.job ~= nil and xPlayer.job.name == 'police' then Citizen.Wait(5000) TriggerClientEvent('esx_policejob:updateBlip', -1) end - end + end end) RegisterServerEvent('esx_policejob:spawned') AddEventHandler('esx_policejob:spawned', function() local _source = source local xPlayer = ESX.GetPlayerFromId(_source) - + if xPlayer ~= nil and xPlayer.job ~= nil and xPlayer.job.name == 'police' then Citizen.Wait(5000) TriggerClientEvent('esx_policejob:updateBlip', -1) From 9f21efed2deed478b99cec1507d6d1cdeb8c319d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 31 May 2019 23:09:40 +0200 Subject: [PATCH 2225/3224] Minor cleanup and added missing sql index --- client/main.lua | 47 +++++---------- esx_phone.sql | 17 +++--- html/ui.html | 13 ++-- html/ui_br.html | 13 ++-- html/ui_de.html | 13 ++-- html/ui_en.html | 13 ++-- html/ui_pl.html | 153 +++++++++++++++++++++++++----------------------- server/main.lua | 94 ++++++++++++++--------------- 8 files changed, 180 insertions(+), 183 deletions(-) diff --git a/client/main.lua b/client/main.lua index 0249ab82..dd69b91f 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,40 +1,21 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - -local GUI = {} -local PhoneData = { phoneNumber = 0, contacts = {} } -local CurrentAction = nil -local CurrentActionMsg = '' -local CurrentActionData = {} -local CurrentDispatchRequestId = -1 -local PhoneNumberSources = {} - -ESX = nil -GUI.PhoneIsShowed = false -GUI.MessagesIsShowed = false -GUI.AddContactIsShowed = false +local GUI, PhoneData, CurrentActionData, PhoneNumberSources, CurrentDispatchRequestId = {}, {phoneNumber = 0, contacts = {}}, {}, {}, -1 +local CurrentAction, CurrentActionMsg +GUI.PhoneIsShowed = false +GUI.MessagesIsShowed = false +GUI.AddContactIsShowed = false +ESX = nil Citizen.CreateThread(function() while ESX == nil do TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) Citizen.Wait(0) end - + ESX.UI.Menu.RegisterType('phone', OpenPhone, ClosePhone) end) function OpenPhone() local playerPed = PlayerPedId() - TriggerServerEvent('esx_phone:reload', PhoneData.phoneNumber) SendNUIMessage({ @@ -188,7 +169,7 @@ AddEventHandler('esx_phone:onMessage', function(phoneNumber, message, position, anonyme = anon, job = job } - + ESX.SetTimeout(15000, function() CurrentAction = nil end) @@ -222,7 +203,7 @@ RegisterNUICallback('send', function(data) local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) - if tonumber(phoneNumber) ~= nil then + if tonumber(phoneNumber) then phoneNumber = tonumber(phoneNumber) end @@ -231,7 +212,7 @@ RegisterNUICallback('send', function(data) y = coords.y, z = coords.z }) - + SendNUIMessage({ showMessageEditor = false }) @@ -269,7 +250,7 @@ Citizen.CreateThread(function() else -- open phone -- todo: is player busy (handcuffed, etc) - if IsControlJustReleased(0, Keys['F1']) and IsInputDisabled(0) then + if IsControlJustReleased(0, 288) and IsInputDisabled(0) then if not ESX.UI.Menu.IsOpen('phone', GetCurrentResourceName(), 'main') then ESX.UI.Menu.CloseAll() ESX.UI.Menu.Open('phone', GetCurrentResourceName(), 'main') @@ -292,10 +273,10 @@ Citizen.CreateThread(function() while true do Citizen.Wait(0) - if CurrentAction ~= nil then + if CurrentAction then ESX.ShowHelpNotification(CurrentActionMsg) - if IsControlJustReleased(0, Keys['E']) and IsInputDisabled(0) then + if IsControlJustReleased(0, 38) and IsInputDisabled(0) then if CurrentAction == 'dispatch' then TriggerServerEvent('esx_phone:stopDispatch', CurrentDispatchRequestId) SetNewWaypoint(CurrentActionData.position.x, CurrentActionData.position.y) @@ -307,4 +288,4 @@ Citizen.CreateThread(function() Citizen.Wait(500) end end -end) +end) \ No newline at end of file diff --git a/esx_phone.sql b/esx_phone.sql index 76da439f..220d5ad1 100644 --- a/esx_phone.sql +++ b/esx_phone.sql @@ -1,12 +1,15 @@ USE `essentialmode`; CREATE TABLE `user_contacts` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `identifier` varchar(255) NOT NULL, - `name` varchar(255) NOT NULL, - `number` int(11) NOT NULL, - - PRIMARY KEY (`id`) + `id` INT(11) NOT NULL AUTO_INCREMENT, + `identifier` VARCHAR(22) NOT NULL, + `name` VARCHAR(100) NOT NULL, + `number` INT(11) NOT NULL, + + PRIMARY KEY (`id`), + INDEX `index_user_contacts_identifier_name_number` (`identifier`, `name`, `number`) ); -ALTER TABLE `users`ADD COLUMN `phone_number` INT NULL; \ No newline at end of file +ALTER TABLE `users` + ADD COLUMN `phone_number` INT(11) NULL, + ADD UNIQUE INDEX `index_users_phone_number` (`phone_number`); \ No newline at end of file diff --git a/html/ui.html b/html/ui.html index e9023e74..d958ac00 100644 --- a/html/ui.html +++ b/html/ui.html @@ -25,9 +25,10 @@
    - -
    Répertoire
    +
    + Répertoire + +
    @@ -51,7 +52,8 @@
    -
    +
    @@ -64,7 +66,8 @@
    -
    Ajouter un contact
    +
    Ajouter + un contact
    diff --git a/html/ui_br.html b/html/ui_br.html index af05a98d..b0e2c9e3 100644 --- a/html/ui_br.html +++ b/html/ui_br.html @@ -25,9 +25,10 @@
    - -
    Agenda
    +
    + Agenda + +
    @@ -51,7 +52,8 @@
    -
    +
    @@ -64,7 +66,8 @@
    -
    Adicionar contato
    +
    Adicionar contato
    diff --git a/html/ui_de.html b/html/ui_de.html index 87faddcd..e8171754 100644 --- a/html/ui_de.html +++ b/html/ui_de.html @@ -25,9 +25,10 @@
    - -
    Kontakte
    +
    + Kontakte + +
    @@ -51,7 +52,8 @@
    -
    +
    @@ -64,7 +66,8 @@
    -
    Kontakt hinzufügen
    +
    Kontakt + hinzufügen
    diff --git a/html/ui_en.html b/html/ui_en.html index 469fb76a..18375822 100644 --- a/html/ui_en.html +++ b/html/ui_en.html @@ -25,9 +25,10 @@
    - -
    Contacts
    +
    + Contacts + +
    @@ -51,7 +52,8 @@
    -
    +
    @@ -64,7 +66,8 @@
    -
    Add a contact
    +
    Add a + contact
    diff --git a/html/ui_pl.html b/html/ui_pl.html index 0d731437..92448574 100644 --- a/html/ui_pl.html +++ b/html/ui_pl.html @@ -1,82 +1,91 @@ - - - - - - -
    + + + + + -
    + -
    - - #123456 -
    +
    - - -
    - -
    Kontakty
    -
    -
    -
    -

    Brak kontaktów

    -
    -
    -
    -
    - -
    -
    Wiadomości
    -
    -
    -
    -

    Brak wiadomości

    -
    -
    -
    -
    - -
    -
    -
    -
    - - - - - -
    -
    -
    - -
    -
    Dodaj kontakt
    -
    -
    - - - - -
    -
    -
    +
    +
    + + #123456
    + + + +
    +
    + Kontakty + +
    +
    +
    +
    +

    Brak kontaktów

    +
    +
    +
    +
    + +
    +
    Wiadomości + +
    +
    +
    +
    +

    Brak wiadomości

    +
    +
    +
    +
    + +
    +
    +
    +
    + + + + + +
    +
    +
    + +
    +
    Dodaj + kontakt
    +
    +
    + + + + +
    +
    +
    +
    +
    - - - - + + + + - - + + + \ No newline at end of file diff --git a/server/main.lua b/server/main.lua index f8c624cb..ee6b4e37 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,6 +1,15 @@ -ESX = nil -local DisptachRequestId = 0 -local PhoneNumbers = {} +ESX = nil +local DisptachRequestId, PhoneNumbers = 0, {} + +TriggerEvent('esx:getSharedObject', function(obj) + ESX = obj + + local xPlayers = ESX.GetPlayers() + + for i=1, #xPlayers, 1 do + LoadPlayer(xPlayers[i]) + end +end) function LoadPlayer(source) local xPlayer = ESX.GetPlayerFromId(source) @@ -21,8 +30,7 @@ function LoadPlayer(source) if phoneNumber == nil then phoneNumber = GenerateUniquePhoneNumber() - MySQL.Async.execute('UPDATE users SET phone_number = @phone_number WHERE identifier = @identifier', - { + MySQL.Async.execute('UPDATE users SET phone_number = @phone_number WHERE identifier = @identifier', { ['@identifier'] = xPlayer.identifier, ['@phone_number'] = phoneNumber }) @@ -42,7 +50,7 @@ function LoadPlayer(source) xPlayer.set('phoneNumber', phoneNumber) local contacts = {} - if PhoneNumbers[xPlayer.job.name] ~= nil then + if PhoneNumbers[xPlayer.job.name] then TriggerEvent('esx_phone:addSource', xPlayer.job.name, source) end @@ -62,16 +70,6 @@ function LoadPlayer(source) end) end -TriggerEvent('esx:getSharedObject', function(obj) - ESX = obj - - local xPlayers = ESX.GetPlayers() - - for i=1, #xPlayers, 1 do - LoadPlayer(xPlayers[i]) - end -end) - function GenerateUniquePhoneNumber() local foundNumber, phoneNumber = false, nil @@ -109,8 +107,8 @@ AddEventHandler('esx_phone:getDistpatchRequestId', function(cb) cb(GetDistpatchRequestId()) end) -AddEventHandler('esx:playerLoaded', function(source) - LoadPlayer(source) +AddEventHandler('esx:playerLoaded', function(playerId) + LoadPlayer(playerId) end) AddEventHandler('esx:playerDropped', function(source) @@ -120,39 +118,36 @@ AddEventHandler('esx:playerDropped', function(source) TriggerClientEvent('esx_phone:setPhoneNumberSource', -1, phoneNumber, -1) PhoneNumbers[phoneNumber] = nil - if PhoneNumbers[xPlayer.job.name] ~= nil then + if PhoneNumbers[xPlayer.job.name] then TriggerEvent('esx_phone:removeSource', xPlayer.job.name, source) end end) AddEventHandler('esx:setJob', function(source, job, lastJob) - if PhoneNumbers[lastJob.name] ~= nil then + if PhoneNumbers[lastJob.name] then TriggerEvent('esx_phone:removeSource', lastJob.name, source) end - if PhoneNumbers[job.name] ~= nil then + if PhoneNumbers[job.name] then TriggerEvent('esx_phone:addSource', job.name, source) end end) RegisterServerEvent('esx_phone:reload') AddEventHandler('esx_phone:reload', function(phoneNumber) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) + local playerId = source + local xPlayer = ESX.GetPlayerFromId(playerId) local contacts = xPlayer.get('contacts') - TriggerClientEvent('esx_phone:loaded', _source, phoneNumber, contacts) + TriggerClientEvent('esx_phone:loaded', playerId, phoneNumber, contacts) end) RegisterServerEvent('esx_phone:send') AddEventHandler('esx_phone:send', function(phoneNumber, message, anon, position) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) - + local xPlayer = ESX.GetPlayerFromId(source) print(('esx_phone: MESSAGE => %s@%s: %s'):format(xPlayer.name, phoneNumber, message)) - if PhoneNumbers[phoneNumber] ~= nil then - + if PhoneNumbers[phoneNumber] then for k,v in pairs(PhoneNumbers[phoneNumber].sources) do local numType = PhoneNumbers[phoneNumber].type local numHasDispatch = PhoneNumbers[phoneNumber].hasDispatch @@ -171,7 +166,6 @@ AddEventHandler('esx_phone:send', function(phoneNumber, message, anon, position) TriggerClientEvent('esx_phone:onMessage', numSource, xPlayer.get('phoneNumber'), message, numPosition, (numHide and true or anon), numType, false) end end - end end) @@ -203,29 +197,29 @@ end) RegisterServerEvent('esx_phone:addPlayerContact') AddEventHandler('esx_phone:addPlayerContact', function(phoneNumber, contactName) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) + local playerId = source + local xPlayer = ESX.GetPlayerFromId(playerId) phoneNumber = tonumber(phoneNumber) local playerOnline = false if phoneNumber == nil then - print(('esx_phone: %s attempted SQL injecting!'):format(xPlayer.identifier)) + print(('esx_phone: %s parsed invalid player contact number!'):format(xPlayer.identifier)) return end MySQL.Async.fetchAll('SELECT phone_number, identifier FROM users WHERE phone_number = @number', { ['@number'] = phoneNumber }, function(result) - if result[1] ~= nil then + if result[1] then if phoneNumber == xPlayer.get('phoneNumber') then - TriggerClientEvent('esx:showNotification', _source, _U('cannot_add_self')) + TriggerClientEvent('esx:showNotification', playerId, _U('cannot_add_self')) else local contacts = xPlayer.get('contacts') -- already added player? for i=1, #contacts, 1 do if contacts[i].number == phoneNumber then - TriggerClientEvent('esx:showNotification', _source, _U('number_in_contacts')) + TriggerClientEvent('esx:showNotification', playerId, _U('number_in_contacts')) return end end @@ -239,34 +233,33 @@ AddEventHandler('esx_phone:addPlayerContact', function(phoneNumber, contactName) -- is the player currently online? local xTarget = ESX.GetPlayerFromIdentifier(result[1].identifier) - playerOnline = (xTarget ~= nil) + playerOnline = xTarget ~= nil - MySQL.Async.execute('INSERT INTO user_contacts (identifier, name, number) VALUES (@identifier, @name, @number)', - { + MySQL.Async.execute('INSERT INTO user_contacts (identifier, name, number) VALUES (@identifier, @name, @number)', { ['@identifier'] = xPlayer.identifier, ['@name'] = contactName, ['@number'] = phoneNumber }, function(rowsChanged) - TriggerClientEvent('esx:showNotification', _source, _U('contact_added')) - TriggerClientEvent('esx_phone:addContact', _source, contactName, phoneNumber, playerOnline) + TriggerClientEvent('esx:showNotification', playerId, _U('contact_added')) + TriggerClientEvent('esx_phone:addContact', playerId, contactName, phoneNumber, playerOnline) end) end else - TriggerClientEvent('esx:showNotification', _source, _U('number_not_assigned')) + TriggerClientEvent('esx:showNotification', playerId, _U('number_not_assigned')) end end) end) RegisterServerEvent('esx_phone:removePlayerContact') AddEventHandler('esx_phone:removePlayerContact', function(phoneNumber, contactName) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) + local playerId = source + local xPlayer = ESX.GetPlayerFromId(playerId) local foundNumber = false MySQL.Async.fetchAll('SELECT phone_number FROM users WHERE phone_number = @number', { ['@number'] = phoneNumber }, function(result) - if result[1] ~= nil then + if result[1] then foundNumber = true end @@ -281,17 +274,16 @@ 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.Async.execute('DELETE FROM user_contacts WHERE identifier = @identifier AND name = @name AND number = @number', { ['@identifier'] = xPlayer.identifier, ['@name'] = contactName, ['@number'] = phoneNumber }, function(rowsChanged) - TriggerClientEvent('esx:showNotification', _source, _U('contact_removed')) - TriggerClientEvent('esx_phone:removeContact', _source, contactName, phoneNumber) + TriggerClientEvent('esx:showNotification', playerId, _U('contact_removed')) + TriggerClientEvent('esx_phone:removeContact', playerId, contactName, phoneNumber) end) else - TriggerClientEvent('esx:showNotification', _source, _U('number_not_assigned')) + TriggerClientEvent('esx:showNotification', playerId, _U('number_not_assigned')) end end) end) @@ -299,4 +291,4 @@ end) RegisterServerEvent('esx_phone:stopDispatch') AddEventHandler('esx_phone:stopDispatch', function(dispatchRequestId) TriggerClientEvent('esx_phone:stopDispatch', -1, dispatchRequestId, GetPlayerName(source)) -end) +end) \ No newline at end of file From 129223976aa16b01f9309c396681ed0670ec2e4a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 31 May 2019 23:18:39 +0200 Subject: [PATCH 2226/3224] Added missing mysql indexes --- README.md | 2 +- esx_addoninventory.sql | 20 +++++++++++--------- server/classes/addoninventory.lua | 6 ++---- server/main.lua | 16 ++++------------ 4 files changed, 18 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index a3863058..ffbf5477 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ end) ### License esx_addoninventory - inventories! -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2019 Jérémie N'gadi 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. diff --git a/esx_addoninventory.sql b/esx_addoninventory.sql index 7a664629..d0601743 100644 --- a/esx_addoninventory.sql +++ b/esx_addoninventory.sql @@ -1,19 +1,21 @@ USE `essentialmode`; CREATE TABLE `addon_inventory` ( - `name` varchar(60) NOT NULL, - `label` varchar(255) NOT NULL, - `shared` int(11) NOT NULL, + `name` VARCHAR(60) NOT NULL, + `label` VARCHAR(100) NOT NULL, + `shared` INT(11) NOT NULL, PRIMARY KEY (`name`) ); CREATE TABLE `addon_inventory_items` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `inventory_name` varchar(255) NOT NULL, - `name` varchar(255) NOT NULL, - `count` int(11) NOT NULL, - `owner` varchar(60) DEFAULT NULL, + `id` INT(11) NOT NULL AUTO_INCREMENT, + `inventory_name` VARCHAR(255) NOT NULL, + `name` VARCHAR(255) NOT NULL, + `count` INT(11) NOT NULL, + `owner` VARCHAR(60) DEFAULT NULL, - PRIMARY KEY (`id`) + PRIMARY KEY (`id`), + INDEX `index_addon_inventory_items_inventory_name_name` (`inventory_name`, `name`), + INDEX `index_addon_inventory_items_inventory_name_name_owner` (`inventory_name`, `name`, `owner`) ); \ No newline at end of file diff --git a/server/classes/addoninventory.lua b/server/classes/addoninventory.lua index 4fd7e9bf..75614d1e 100644 --- a/server/classes/addoninventory.lua +++ b/server/classes/addoninventory.lua @@ -63,15 +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.Async.execute('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.Async.execute('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/server/main.lua b/server/main.lua index 3fe3bb57..a1c59453 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,9 +1,5 @@ -ESX = nil -Items = {} -local InventoriesIndex = {} -local Inventories = {} -local SharedInventories = {} - +local InventoriesIndex, Inventories, SharedInventories, Items = {}, {}, {}, {} +ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) @@ -54,7 +50,6 @@ MySQL.ready(function() end else - local items = {} for j=1, #result2, 1 do @@ -67,7 +62,6 @@ MySQL.ready(function() local addonInventory = CreateAddonInventory(name, nil, items) SharedInventories[name] = addonInventory - end end end) @@ -92,15 +86,13 @@ AddEventHandler('esx_addoninventory:getSharedInventory', function(name, cb) cb(GetSharedInventory(name)) end) -AddEventHandler('esx:playerLoaded', function(source) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) +AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) local addonInventories = {} for i=1, #InventoriesIndex, 1 do local name = InventoriesIndex[i] local inventory = GetInventory(name, xPlayer.identifier) - + if inventory == nil then inventory = CreateAddonInventory(name, xPlayer.identifier, {}) table.insert(Inventories[name], inventory) From 8d47719dbfc4a7b2911e90f661550f81069bb4d9 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 31 May 2019 23:22:14 +0200 Subject: [PATCH 2227/3224] One more index --- esx_addoninventory.sql | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/esx_addoninventory.sql b/esx_addoninventory.sql index d0601743..770cda76 100644 --- a/esx_addoninventory.sql +++ b/esx_addoninventory.sql @@ -10,12 +10,13 @@ CREATE TABLE `addon_inventory` ( CREATE TABLE `addon_inventory_items` ( `id` INT(11) NOT NULL AUTO_INCREMENT, - `inventory_name` VARCHAR(255) NOT NULL, - `name` VARCHAR(255) NOT NULL, + `inventory_name` VARCHAR(100) NOT NULL, + `name` VARCHAR(100) NOT NULL, `count` INT(11) NOT NULL, `owner` VARCHAR(60) DEFAULT NULL, PRIMARY KEY (`id`), INDEX `index_addon_inventory_items_inventory_name_name` (`inventory_name`, `name`), - INDEX `index_addon_inventory_items_inventory_name_name_owner` (`inventory_name`, `name`, `owner`) + INDEX `index_addon_inventory_items_inventory_name_name_owner` (`inventory_name`, `name`, `owner`), + INDEX `index_addon_inventory_inventory_name` (`inventory_name`) ); \ No newline at end of file From 687c636595563222436a33cdf076fe1534d7a4eb Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 31 May 2019 23:27:35 +0200 Subject: [PATCH 2228/3224] Added missing indexes --- README.md | 2 +- esx_addonaccount.sql | 18 ++++++++++-------- server/classes/addonaccount.lua | 9 ++------- server/main.lua | 20 +++++--------------- 4 files changed, 18 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 8826cb16..5803bbf8 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ end) ### License esx_addonaccount - addon account for ESX -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2019 Jérémie N'gadi 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. diff --git a/esx_addonaccount.sql b/esx_addonaccount.sql index 5b42b181..e0e25a81 100644 --- a/esx_addonaccount.sql +++ b/esx_addonaccount.sql @@ -1,18 +1,20 @@ USE `essentialmode`; CREATE TABLE `addon_account` ( - `name` varchar(60) NOT NULL, - `label` varchar(255) NOT NULL, - `shared` int(11) NOT NULL, + `name` VARCHAR(60) NOT NULL, + `label` VARCHAR(100) NOT NULL, + `shared` INT(11) NOT NULL, PRIMARY KEY (`name`) ); CREATE TABLE `addon_account_data` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `account_name` varchar(255) DEFAULT NULL, - `money` double NOT NULL, - `owner` varchar(255) DEFAULT NULL, + `id` INT(11) NOT NULL AUTO_INCREMENT, + `account_name` VARCHAR(100) DEFAULT NULL, + `money` INT(11) NOT NULL, + `owner` VARCHAR(100) DEFAULT NULL, - PRIMARY KEY (`id`) + PRIMARY KEY (`id`), + UNIQUE INDEX `index_addon_account_data_account_name_owner` (`account_name`, `owner`), + INDEX `index_addon_account_data_account_name` (`account_name`) ); diff --git a/server/classes/addonaccount.lua b/server/classes/addonaccount.lua index cd9552ee..7f082cd4 100644 --- a/server/classes/addonaccount.lua +++ b/server/classes/addonaccount.lua @@ -7,7 +7,6 @@ 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) @@ -15,7 +14,6 @@ function CreateAddonAccount(name, owner, money) self.removeMoney = function(m) self.money = self.money - m - self.save() TriggerClientEvent('esx_addonaccount:setMoney', -1, self.name, self.money) @@ -23,7 +21,6 @@ function CreateAddonAccount(name, owner, money) self.setMoney = function(m) self.money = m - self.save() TriggerClientEvent('esx_addonaccount:setMoney', -1, self.name, self.money) @@ -31,14 +28,12 @@ function CreateAddonAccount(name, owner, money) self.save = function() if self.owner == nil then - MySQL.Async.execute('UPDATE addon_account_data SET money = @money WHERE account_name = @account_name', - { + MySQL.Async.execute('UPDATE addon_account_data SET money = @money WHERE account_name = @account_name', { ['@account_name'] = self.name, ['@money'] = self.money }) else - MySQL.Async.execute('UPDATE addon_account_data SET money = @money WHERE account_name = @account_name AND owner = @owner', - { + 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 diff --git a/server/main.lua b/server/main.lua index 5f47d6fc..b238a2f9 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,7 +1,5 @@ -ESX = nil -local AccountsIndex = {} -local Accounts = {} -local SharedAccounts = {} +local AccountsIndex, Accounts, SharedAccounts = {}, {}, {} +ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) @@ -18,7 +16,6 @@ MySQL.ready(function() }) if shared == 0 then - table.insert(AccountsIndex, name) Accounts[name] = {} @@ -26,14 +23,11 @@ MySQL.ready(function() 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)', - { + MySQL.Sync.execute('INSERT INTO addon_account_data (account_name, money, owner) VALUES (@account_name, @money, NULL)', { ['@account_name'] = name, ['@money'] = 0 }) @@ -45,7 +39,6 @@ MySQL.ready(function() local addonAccount = CreateAddonAccount(name, nil, money) SharedAccounts[name] = addonAccount - end end end) @@ -70,9 +63,7 @@ AddEventHandler('esx_addonaccount:getSharedAccount', function(name, cb) cb(GetSharedAccount(name)) end) -AddEventHandler('esx:playerLoaded', function(source) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) +AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) local addonAccounts = {} for i=1, #AccountsIndex, 1 do @@ -80,8 +71,7 @@ AddEventHandler('esx:playerLoaded', function(source) 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)', - { + 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 From 58a5e8f0462c3eaa7b1d54943cf5fa6ddf0e39c7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 1 Jun 2019 14:07:08 +0200 Subject: [PATCH 2229/3224] Added missing mysql keys --- README.md | 2 +- esx_datastore.sql | 21 ++++++++++----------- server/classes/datastore.lua | 6 ++---- server/main.lua | 17 ++++------------- 4 files changed, 17 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index c7da533d..7718912e 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ end) ### License esx_datastore - datastore inventory for ESX -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2019 Jérémie N'gadi 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. diff --git a/esx_datastore.sql b/esx_datastore.sql index 5b694f8a..1fdd9049 100644 --- a/esx_datastore.sql +++ b/esx_datastore.sql @@ -1,21 +1,20 @@ USE `essentialmode`; CREATE TABLE `datastore` ( - `name` varchar(60) NOT NULL, - `label` varchar(255) NOT NULL, - `shared` int(11) NOT NULL, + `name` VARCHAR(60) NOT NULL, + `label` VARCHAR(100) NOT NULL, + `shared` INT(11) NOT NULL, PRIMARY KEY (`name`) ); CREATE TABLE `datastore_data` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(60) NOT NULL, - `owner` varchar(60), - `data` longtext, + `id` INT(11) NOT NULL AUTO_INCREMENT, + `name` VARCHAR(60) NOT NULL, + `owner` VARCHAR(60), + `data` LONGTEXT, - INDEX index_datastore_name (`name`), - CONSTRAINT unique_datastore_owner_name UNIQUE (`owner`, `name`), - - PRIMARY KEY (`id`) + PRIMARY KEY (`id`), + UNIQUE INDEX `index_datastore_data_name_owner` (`name`, `owner`), + INDEX `index_datastore_data_name` (`name`) ); diff --git a/server/classes/datastore.lua b/server/classes/datastore.lua index 2c31e541..382689d8 100644 --- a/server/classes/datastore.lua +++ b/server/classes/datastore.lua @@ -68,14 +68,12 @@ 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', - { + MySQL.Async.execute('UPDATE datastore_data SET data = @data WHERE name = @name', { ['@data'] = json.encode(self.data), ['@name'] = self.name, }) else - MySQL.Async.execute('UPDATE datastore_data SET data = @data WHERE name = @name and owner = @owner', - { + 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, diff --git a/server/main.lua b/server/main.lua index c80e3135..37b4b8c2 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,7 +1,5 @@ -ESX = nil -local DataStoresIndex = {} -local DataStores = {} -local SharedDataStores = {} +local DataStores, DataStoresIndex, SharedDataStores = {}, {}, {} +ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) @@ -18,7 +16,6 @@ MySQL.ready(function() }) if shared == 0 then - table.insert(DataStoresIndex, name) DataStores[name] = {} @@ -30,9 +27,7 @@ MySQL.ready(function() table.insert(DataStores[name], dataStore) end - else - local data = nil if #result2 == 0 then @@ -47,7 +42,6 @@ MySQL.ready(function() local dataStore = CreateDataStore(name, nil, data) SharedDataStores[name] = dataStore - end end end) @@ -86,9 +80,7 @@ AddEventHandler('esx_datastore:getSharedDataStore', function(name, cb) cb(GetSharedDataStore(name)) end) -AddEventHandler('esx:playerLoaded', function(source) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) +AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) local dataStores = {} for i=1, #DataStoresIndex, 1 do @@ -96,8 +88,7 @@ AddEventHandler('esx:playerLoaded', function(source) local dataStore = GetDataStore(name, xPlayer.identifier) if dataStore == nil then - MySQL.Async.execute('INSERT INTO datastore_data (name, owner, data) VALUES (@name, @owner, @data)', - { + MySQL.Async.execute('INSERT INTO datastore_data (name, owner, data) VALUES (@name, @owner, @data)', { ['@name'] = name, ['@owner'] = xPlayer.identifier, ['@data'] = '{}' From 067f0b9145861b9a1958169dd65e52ba7f99818f Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 1 Jun 2019 14:15:27 +0200 Subject: [PATCH 2230/3224] Minor cleanup --- client/main.lua | 141 ++++++++++++------------------------------------ server/main.lua | 17 ++---- 2 files changed, 39 insertions(+), 119 deletions(-) diff --git a/client/main.lua b/client/main.lua index daa301ae..90c5e60e 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,28 +1,7 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - -ESX = nil -local OwnedProperties = {} -local Blips = {} -local CurrentProperty = nil -local CurrentPropertyOwner = nil -local LastProperty = nil -local LastPart = nil -local HasAlreadyEnteredMarker = false -local CurrentAction = nil -local CurrentActionMsg = '' -local CurrentActionData = {} -local FirstSpawn = true -local HasChest = false +local OwnedProperties, Blips, CurrentActionData = {}, {}, {} +local CurrentProperty, CurrentPropertyOwner, LastProperty, LastPart, CurrentAction, CurrentActionMsg +local firstSpawn, hasChest, hasAlreadyEnteredMarker = true, false, false +ESX = nil Citizen.CreateThread(function() while ESX == nil do @@ -60,9 +39,9 @@ end) function DrawSub(text, time) ClearPrints() - SetTextEntry_2('STRING') - AddTextComponentString(text) - DrawSubtitleTimed(time, 1) + BeginTextCommandPrint('STRING') + AddTextComponentSubstringPlayerName(text) + EndTextCommandPrint(time, 1) end function CreateBlips() @@ -78,7 +57,7 @@ function CreateBlips() SetBlipAsShortRange(Blips[property.name], true) BeginTextCommandSetBlipName("STRING") - AddTextComponentString(_U('free_prop')) + AddTextComponentSubstringPlayerName(_U('free_prop')) EndTextCommandSetBlipName(Blips[property.name]) end end @@ -204,7 +183,6 @@ function SetPropertyOwned(name, owned) end if owned then - OwnedProperties[name] = true RemoveBlip(Blips[enteringName]) @@ -213,11 +191,9 @@ function SetPropertyOwned(name, owned) SetBlipAsShortRange(Blips[enteringName], true) BeginTextCommandSetBlipName("STRING") - AddTextComponentString(_U('property')) + AddTextComponentSubstringPlayerName(_U('property')) EndTextCommandSetBlipName(Blips[enteringName]) - else - OwnedProperties[name] = nil local found = false @@ -241,12 +217,10 @@ function SetPropertyOwned(name, owned) SetBlipAsShortRange(Blips[enteringName], true) BeginTextCommandSetBlipName("STRING") - AddTextComponentString(_U('free_prop')) + AddTextComponentSubstringPlayerName(_U('free_prop')) EndTextCommandSetBlipName(Blips[enteringName]) end - end - end function PropertyIsOwned(property) @@ -271,8 +245,7 @@ function OpenPropertyMenu(property) table.insert(elements, {label = _U('visit'), value = 'visit'}) end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'property', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'property', { title = property.label, align = 'top-left', elements = elements @@ -304,15 +277,13 @@ function OpenGatewayMenu(property) OpenGatewayOwnedPropertiesMenu(gatewayProperties) else - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'gateway', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'gateway', { title = property.name, align = 'top-left', elements = { {label = _U('owned_properties'), value = 'owned_properties'}, {label = _U('available_properties'), value = 'available_properties'} - } - }, function(data, menu) + }}, function(data, menu) if data.current.value == 'owned_properties' then OpenGatewayOwnedPropertiesMenu(property) elseif data.current.value == 'available_properties' then @@ -325,7 +296,6 @@ function OpenGatewayMenu(property) CurrentActionMsg = _U('press_to_menu') CurrentActionData = {property = property} end) - end end @@ -342,8 +312,7 @@ function OpenGatewayOwnedPropertiesMenu(property) end end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'gateway_owned_properties', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'gateway_owned_properties', { title = property.name .. ' - ' .. _U('owned_properties'), align = 'top-left', elements = elements @@ -358,8 +327,7 @@ function OpenGatewayOwnedPropertiesMenu(property) table.insert(elements, {label = _U('leave'), value = 'leave'}) end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'gateway_owned_properties_actions', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'gateway_owned_properties_actions', { title = data.current.label, align = 'top-left', elements = elements @@ -375,7 +343,6 @@ function OpenGatewayOwnedPropertiesMenu(property) end, function(data2, menu2) menu2.close() end) - end, function(data, menu) menu.close() end) @@ -395,25 +362,21 @@ function OpenGatewayAvailablePropertiesMenu(property) end end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'gateway_available_properties', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'gateway_available_properties', { title = property.name .. ' - ' .. _U('available_properties'), align = 'top-left', elements = elements }, function(data, menu) - menu.close() - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'gateway_available_properties_actions', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'gateway_available_properties_actions', { title = property.label .. ' - ' .. _U('available_properties'), align = 'top-left', elements = { {label = _U('buy'), value = 'buy'}, {label = _U('rent'), value = 'rent'}, {label = _U('visit'), value = 'visit'} - } - }, function(data2, menu2) + }}, function(data2, menu2) menu2.close() if data2.current.value == 'buy' then @@ -426,7 +389,6 @@ function OpenGatewayAvailablePropertiesMenu(property) end, function(data2, menu2) menu2.close() end) - end, function(data, menu) menu.close() end) @@ -434,7 +396,7 @@ end function OpenRoomMenu(property, owner) local entering = nil - local elements = {} + local elements = {{label = _U('invite_player'), value = 'invite_player'}} if property.isSingle then entering = property.entering @@ -442,8 +404,6 @@ function OpenRoomMenu(property, owner) entering = GetGateway(property).entering end - table.insert(elements, {label = _U('invite_player'), value = 'invite_player'}) - if CurrentPropertyOwner == owner then table.insert(elements, {label = _U('player_clothes'), value = 'player_dressing'}) table.insert(elements, {label = _U('remove_cloth'), value = 'remove_cloth'}) @@ -454,8 +414,7 @@ function OpenRoomMenu(property, owner) ESX.UI.Menu.CloseAll() - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'room', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'room', { title = property.label, align = 'top-left', elements = elements @@ -472,8 +431,7 @@ function OpenRoomMenu(property, owner) end end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'room_invite', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'room_invite', { title = property.label .. ' - ' .. _U('invite'), align = 'top-left', elements = elements, @@ -496,13 +454,11 @@ function OpenRoomMenu(property, owner) }) end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'player_dressing', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'player_dressing', { title = property.label .. ' - ' .. _U('player_clothes'), align = 'top-left', elements = elements }, function(data2, menu2) - TriggerEvent('skinchanger:getSkin', function(skin) ESX.TriggerServerCallback('esx_property:getPlayerOutfit', function(clothes) TriggerEvent('skinchanger:loadClothes', skin, clothes) @@ -513,7 +469,6 @@ function OpenRoomMenu(property, owner) end) end, data2.current.value) end) - end, function(data2, menu2) menu2.close() end) @@ -560,9 +515,7 @@ function OpenRoomMenu(property, owner) end function OpenRoomInventoryMenu(property, owner) - ESX.TriggerServerCallback('esx_property:getPropertyInventory', function(inventory) - local elements = {} if inventory.blackMoney > 0 then @@ -596,24 +549,20 @@ function OpenRoomInventoryMenu(property, owner) }) end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'room_inventory', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'room_inventory', { title = property.label .. ' - ' .. _U('inventory'), align = 'top-left', elements = elements }, function(data, menu) if data.current.type == 'item_weapon' then - menu.close() TriggerServerEvent('esx_property:getItem', owner, data.current.type, data.current.value, data.current.ammo) ESX.SetTimeout(300, function() OpenRoomInventoryMenu(property, owner) end) - else - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'get_item_count', { title = _U('amount') }, function(data2, menu) @@ -629,25 +578,18 @@ function OpenRoomInventoryMenu(property, owner) OpenRoomInventoryMenu(property, owner) end) end - end, function(data2,menu) menu.close() end) - end - end, function(data, menu) menu.close() end) - end, owner) - end function OpenPlayerInventoryMenu(property, owner) - ESX.TriggerServerCallback('esx_property:getPlayerInventory', function(inventory) - local elements = {} if inventory.blackMoney > 0 then @@ -681,34 +623,28 @@ function OpenPlayerInventoryMenu(property, owner) }) end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'player_inventory', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'player_inventory', { title = property.label .. ' - ' .. _U('inventory'), align = 'top-left', elements = elements }, function(data, menu) if data.current.type == 'item_weapon' then - menu.close() TriggerServerEvent('esx_property:putItem', owner, data.current.type, data.current.value, data.current.ammo) ESX.SetTimeout(300, function() OpenPlayerInventoryMenu(property, owner) end) - else - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'put_item_count', { title = _U('amount') }, function(data2, menu2) - local quantity = tonumber(data2.value) if quantity == nil then ESX.ShowNotification(_U('amount_invalid')) else - menu2.close() TriggerServerEvent('esx_property:putItem', owner, data.current.type, data.current.value, tonumber(data2.value)) @@ -716,19 +652,14 @@ function OpenPlayerInventoryMenu(property, owner) OpenPlayerInventoryMenu(property, owner) end) end - end, function(data2, menu2) menu2.close() end) - end - end, function(data, menu) menu.close() end) - end) - end AddEventHandler('instance:loaded', function() @@ -740,10 +671,8 @@ AddEventHandler('instance:loaded', function() end) AddEventHandler('playerSpawned', function() - if FirstSpawn then - + if firstSpawn then Citizen.CreateThread(function() - while not ESX.IsPlayerLoaded() do Citizen.Wait(0) end @@ -767,7 +696,7 @@ AddEventHandler('playerSpawned', function() end) end) - FirstSpawn = false + firstSpawn = false end end) @@ -807,9 +736,9 @@ AddEventHandler('instance:onEnter', function(instance) end if isOwned or not isHost then - HasChest = true + hasChest = true else - HasChest = false + hasChest = false end end end) @@ -895,7 +824,7 @@ Citizen.CreateThread(function() end -- Room menu - if property.roomMenu and HasChest and not property.disabled then + if property.roomMenu and hasChest and not property.disabled then local distance = GetDistanceBetweenCoords(coords, property.roomMenu.x, property.roomMenu.y, property.roomMenu.z, true) if distance < Config.DrawDistance then @@ -911,16 +840,16 @@ Citizen.CreateThread(function() end end - if isInMarker and not HasAlreadyEnteredMarker or (isInMarker and (LastProperty ~= currentProperty or LastPart ~= currentPart) ) then - HasAlreadyEnteredMarker = true + if isInMarker and not hasAlreadyEnteredMarker or (isInMarker and (LastProperty ~= currentProperty or LastPart ~= currentPart) ) then + hasAlreadyEnteredMarker = true LastProperty = currentProperty LastPart = currentPart TriggerEvent('esx_property:hasEnteredMarker', currentProperty, currentPart) end - if not isInMarker and HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = false + if not isInMarker and hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = false TriggerEvent('esx_property:hasExitedMarker', LastProperty, LastPart) end @@ -938,8 +867,7 @@ Citizen.CreateThread(function() if CurrentAction then ESX.ShowHelpNotification(CurrentActionMsg) - if IsControlJustReleased(0, Keys['E']) then - + if IsControlJustReleased(0, 38) then if CurrentAction == 'property_menu' then OpenPropertyMenu(CurrentActionData.property) elseif CurrentAction == 'gateway_menu' then @@ -955,7 +883,6 @@ Citizen.CreateThread(function() end CurrentAction = nil - end else Citizen.Wait(500) diff --git a/server/main.lua b/server/main.lua index f6476416..1828aa3f 100644 --- a/server/main.lua +++ b/server/main.lua @@ -11,8 +11,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.Async.execute('INSERT INTO owned_properties (name, price, rented, owner) VALUES (@name, @price, @rented, @owner)', { ['@name'] = name, ['@price'] = price, ['@rented'] = (rented and 1 or 0), @@ -33,8 +32,7 @@ function SetPropertyOwned(name, price, rented, owner) end function RemoveOwnedProperty(name, owner) - MySQL.Async.execute('DELETE FROM owned_properties WHERE name = @name AND owner = @owner', - { + MySQL.Async.execute('DELETE FROM owned_properties WHERE name = @name AND owner = @owner', { ['@name'] = name, ['@owner'] = owner }, function(rowsChanged) @@ -117,7 +115,6 @@ MySQL.ready(function() TriggerClientEvent('esx_property:sendProperties', -1, Config.Properties) end) - end) ESX.RegisterServerCallback('esx_property:getProperties', function(source, cb) @@ -187,8 +184,7 @@ RegisterServerEvent('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.Async.execute('UPDATE users SET last_property = @last_property WHERE identifier = @identifier', { ['@last_property'] = property, ['@identifier'] = xPlayer.identifier }) @@ -267,7 +263,6 @@ AddEventHandler('esx_property:getItem', function(owner, type, item, count) end) end - end) RegisterServerEvent('esx_property:putItem') @@ -319,14 +314,13 @@ AddEventHandler('esx_property:putItem', function(owner, type, item, count) end) end - end) ESX.RegisterServerCallback('esx_property:getOwnedProperties', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) MySQL.Async.fetchAll('SELECT * FROM owned_properties WHERE owner = @owner', { - ['@owner'] = xPlayer.identifier + ['@owner'] = xPlayer.identifier }, function(ownedProperties) local properties = {} @@ -432,8 +426,7 @@ function PayRent(d, h, m) xPlayer.removeAccountMoney('bank', result[i].price) TriggerClientEvent('esx:showNotification', xPlayer.source, _U('paid_rent', ESX.Math.GroupDigits(result[i].price))) else -- pay rent either way - MySQL.Sync.execute('UPDATE users SET bank = bank - @bank WHERE identifier = @identifier', - { + MySQL.Sync.execute('UPDATE users SET bank = bank - @bank WHERE identifier = @identifier', { ['@bank'] = result[i].price, ['@identifier'] = result[i].owner }) From 3203d762da4f25aace8b2f21c150cc00475748b9 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 1 Jun 2019 14:23:00 +0200 Subject: [PATCH 2231/3224] Minor cleanup --- client/main.lua | 80 ++++++++++++++----------------------------------- 1 file changed, 22 insertions(+), 58 deletions(-) diff --git a/client/main.lua b/client/main.lua index d4450472..1c746766 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,22 +1,6 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - -local HasAlreadyEnteredMarker = false -local LastZone = nil -local CurrentAction = nil -local CurrentActionMsg = '' -local CurrentActionData = {} - -ESX = nil +local hasAlreadyEnteredMarker, CurrentActionData = false, {} +local CurrentAction, CurrentActionMsg, LastZone +ESX = nil Citizen.CreateThread(function() while ESX == nil do @@ -57,7 +41,6 @@ function OpenRealestateAgentMenu() align = 'top-left', elements = elements }, function(data, menu) - if data.current.value == 'properties' then OpenPropertyMenu() elseif data.current.value == 'customers' then @@ -67,7 +50,6 @@ function OpenRealestateAgentMenu() menu.close() end) end - end, function(data, menu) menu.close() @@ -75,7 +57,6 @@ function OpenRealestateAgentMenu() CurrentActionMsg = _U('press_to_access') CurrentActionData = {} end) - end function OpenPropertyMenu() @@ -97,9 +78,7 @@ function OpenPropertyMenu() end ESX.UI.Menu.Open('list', GetCurrentResourceName(), 'properties', elements, function(data, menu) - if data.value == 'sell' then - menu.close() ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'sell_property_amount', { @@ -124,9 +103,7 @@ function OpenPropertyMenu() end, function(data2, menu2) menu2.close() end) - elseif data.value == 'rent' then - menu.close() ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'rent_property_amount', { @@ -151,9 +128,7 @@ function OpenPropertyMenu() end, function(data2, menu2) menu2.close() end) - elseif data.value == 'gps' then - TriggerEvent('esx_property:getProperty', data.data.name, function(property) if property.isSingle then SetNewWaypoint(property.entering.x, property.entering.y) @@ -163,15 +138,11 @@ function OpenPropertyMenu() end) end end) - end - end, function(data, menu) menu.close() end) - end) - end function OpenCustomersMenu() @@ -194,7 +165,6 @@ function OpenCustomersMenu() end ESX.UI.Menu.Open('list', GetCurrentResourceName(), 'customers', elements, function(data, menu) - if data.value == 'revoke' then TriggerServerEvent('esx_realestateagentjob:revoke', data.data.propertyName, data.data.propertyOwner) OpenCustomersMenu() @@ -209,7 +179,6 @@ function OpenCustomersMenu() end end) end - end, function(data, menu) menu.close() end) @@ -246,17 +215,6 @@ AddEventHandler('esx_realestateagentjob:hasExitedMarker', function(zone) CurrentAction = nil end) -RegisterNetEvent('esx_phone:loaded') -AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) - local specialContact = { - name = _U('realtor'), - number = 'realestateagent', - base64Icon = 'data:image/png;base64,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' - } - - TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) -end) - -- Create Blips Citizen.CreateThread(function() local blip = AddBlipForCoord(Config.Zones.OfficeEnter.Pos.x, Config.Zones.OfficeEnter.Pos.y, Config.Zones.OfficeEnter.Pos.z) @@ -267,15 +225,14 @@ Citizen.CreateThread(function() SetBlipColour (blip, 59) SetBlipAsShortRange(blip, true) - BeginTextCommandSetBlipName("STRING") - AddTextComponentString(_U('realtors')) + BeginTextCommandSetBlipName('STRING') + AddTextComponentSubstringPlayerName(_U('realtors')) EndTextCommandSetBlipName(blip) end) -- Display markers Citizen.CreateThread(function() while true do - Citizen.Wait(0) local coords = GetEntityCoords(PlayerPedId()) @@ -285,14 +242,12 @@ Citizen.CreateThread(function() DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) end end - end end) -- Enter / Exit marker events Citizen.CreateThread(function() while true do - Citizen.Wait(0) local coords = GetEntityCoords(PlayerPedId()) @@ -306,17 +261,16 @@ Citizen.CreateThread(function() end end - if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then - HasAlreadyEnteredMarker = true + if (isInMarker and not hasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then + hasAlreadyEnteredMarker = true LastZone = currentZone TriggerEvent('esx_realestateagentjob:hasEnteredMarker', currentZone) end - if not isInMarker and HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = false + if not isInMarker and hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = false TriggerEvent('esx_realestateagentjob:hasExitedMarker', LastZone) end - end end) @@ -325,10 +279,10 @@ Citizen.CreateThread(function() while true do Citizen.Wait(0) - if CurrentAction ~= nil then + if CurrentAction then ESX.ShowHelpNotification(CurrentActionMsg) - if IsControlJustReleased(0, Keys['E']) then + if IsControlJustReleased(0, 38) then if CurrentAction == 'realestateagent_menu' then OpenRealestateAgentMenu() end @@ -344,6 +298,16 @@ end) -- Load IPLS Citizen.CreateThread(function() LoadMpDlcMaps() - EnableMpDlcMaps(true) RequestIpl('ex_dt1_02_office_02c') end) + +RegisterNetEvent('esx_phone:loaded') +AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) + local specialContact = { + name = _U('realtor'), + number = 'realestateagent', + base64Icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAMAAABHPGVmAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAAAkuhgkvhwowhgowhwwxhwowiAwxiAwyiA0yiQ4zig80iQ40ihA0iRA0ihA1ixE2ixI3jBM4ixM4jBQ4jBQ4jRY6jRY6jhg7jhg7jxg8jRk8jhk8jxo+jxo+kBw/kB1AkB1AkR9Bkh9CkR9CkiBDkSBCkiFEkyNElCNGlCVGlCZIlSdIlihJlipKlilKlytMlyxLlyxNlytMmCxMmC5OmS9PmjBPmTBPmjFQmTBQmjNSmzNSnDRTnDVUmzVUnDdVnjZWnTdWnjhXnjpYnjxZnj1bnztaoD1aoD5coT9dokBdoUBdokFeokNgo0NgpERgo0RhpEVipEZipUdkpUdkpkhkpEhkpkpmpUpmpkpmp0xnpk5qp0xoqE5pqU5qqVBrqFBrqVFrqlJsqVJsqlJuqlNuq1RuqlRurFZwrFdyrVhxrllyrVhyrlt0r1x1r112r1x1sF12sF94sWF5sGB4sWF5smJ6smR8s2V9tGZ+tGd/tWl/tWh/tmmAtWmAtmuCtmqCt2yDt2yDuG6EuG+GuXGGuXGGunGIunSJunSJu3WKvHeMvXiNvHmOvnuQvnyQvn6SwICTwYCUwICUwYKWwoSWw4SYw4WYxIeaxIiaxIqcxoydx4yex46fyI+gyJGiyZGiypOkypSky5amzJeozZinzZmozZmpzpqqzpysz5+u0KCu0KGw0aKw0qWz06a01Ki11Ki21aq31qu41qy41q2616+72LC82LG+2bK+2rS/27XA2rbB3LfC3LjD3LrE3brF3rvG3rzG3r7I37/I4MHK4MPM4cTN4sXO4sbP5MfQ48fQ5MjQ5MnS5cvT5szT5s3U5s7W587W6NDX6NHY6NPa6dPa6tTa6tXc6tfd7Nnf7drg7dvg7tzh7t3i7t/k7+Dl8OLm8OPo8ePo8uTo8eTo8ubq8ufr9Ons9Oru9ezu9ezv9u3w9u/y9+/x+PDy+PL0+PP1+vP2+fT1+fX2+vb4+/f4/Pj5+/j5/Pn6/Pv8/fz8/fz8/v7+/gAAACSdcMIAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAC4iAAAuIgGq4t2SAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjb9TgnoAAAKNUlEQVRoQ92af1hV5R3Ax/HuXI5eb9fimguQUEN3CbFEW1i51l2PVCJg6qTYapGhm1iaYm6r3O7UciQWmOkonWyOpWJkTh3TJobilIbKlETvvNvAS9zG3YTlxcvp/fE9v3/cK3uePXv2+eue97zn++Gc9/2+P87hS/x/gf89SfmKp+fm5eTMLFiwEkqiI1rJy9nJnJWRsFiHps1dBScjEY1k6fgRHMRWYrHH3/cKVDIjsuThL0NIA+IWQUVjIkieSJQ/IwOGpC6F6gaYSuY6IEwkYhJfhEt0MZE8HwchoiHG9QZcpoOhpOw2C1wfJdztcKUWI8mT16nA3FgKF6vRl6y/NQYuvC4sd8P1KnQlK/TTIgqSIIISPUkuXDEQLMshiBwdyZ0DaA6J2MchjAytZDzUNiFhlEkCxTwDgSQ0krFQ1xjn8hMtjXs3PPd110g7FCkYNBtCiaglke7DEpdzqLcfEe7r9Z+t31m28H7XyGEcy8J5zKAHIZiASnIn1DPCUVDTjRUi4VBve9Nvq17/UWFWRqJoegrCAUpJboQ2H7X70zBEVxLqCfq9LfWV30sh9WKVaamQrCA1jGAnec5BTCP+UjWJuRknmQMiUuSS9aY5mLyuLQSxDAhszbTZv7snGdceBTEJcsmtJJgc1soKD5B9dNuRCx2f9Yb1n1d/f7Aux2bP3hv8K+mfMfIuJpM8qR6vrPeXbVxdnHdvCsfYbmZZK3dTxqPLXnunpv6MrwciiwQPzI+zZVf5+/vbaRLEroGwCElSpm70wWsvhfo+vxLwtVZzWcfqN88fi3sPaxuWMG6Se+GW43KRryiBZSo68F2ChImF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' + } + + TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) +end) \ No newline at end of file From a4f28663c4e5bef42961396c51dcc3954b9b2175 Mon Sep 17 00:00:00 2001 From: JaroSound Date: Tue, 4 Jun 2019 18:22:24 +0200 Subject: [PATCH 2232/3224] Items cannot be local? https://github.com/ESX-Org/esx_addoninventory/issues/15 --- server/main.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index a1c59453..6a2eb0b0 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,4 +1,5 @@ -local InventoriesIndex, Inventories, SharedInventories, Items = {}, {}, {}, {} +Items = {} +local InventoriesIndex, Inventories, SharedInventories = {}, {}, {} ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) From b7c2e13578e919b70644a7c2a0b861af9dabd10c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 5 Jun 2019 21:47:45 +0200 Subject: [PATCH 2233/3224] Minor changes, Swedish locale --- __resource.lua | 2 + client/main.lua | 116 +++++++++++------------------- config.lua | 10 ++- locales/br.lua | 35 +++++---- locales/de.lua | 10 +-- locales/en.lua | 11 +-- locales/fi.lua | 9 +-- locales/fr.lua | 9 +-- locales/sv.lua | 18 +++++ localization/sv_esx_bankerjob.sql | 18 +++++ server/main.lua | 12 ++-- 11 files changed, 114 insertions(+), 136 deletions(-) create mode 100644 locales/sv.lua create mode 100644 localization/sv_esx_bankerjob.sql diff --git a/__resource.lua b/__resource.lua index 93ed9324..b03b19df 100644 --- a/__resource.lua +++ b/__resource.lua @@ -14,6 +14,7 @@ server_scripts { 'locales/en.lua', 'locales/fi.lua', 'locales/fr.lua', + 'locales/sv.lua', 'server/main.lua' } @@ -25,6 +26,7 @@ client_scripts { 'locales/en.lua', 'locales/fi.lua', 'locales/fr.lua', + 'locales/sv.lua', 'client/main.lua' } diff --git a/client/main.lua b/client/main.lua index 538414b9..8ec0e10c 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,22 +1,5 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - -local hasAlreadyEnteredMarker = false -local lastZone = nil -local CurrentAction = nil -local CurrentActionMsg = '' -local CurrentActionData = {} - -ESX = nil +local CurrentActionData, CurrentAction, CurrentActionMsg, hasAlreadyEnteredMarker, lastZone = {} +ESX = nil Citizen.CreateThread(function () while ESX == nil do @@ -82,13 +65,11 @@ function OpenBankActionsMenu() end, function(data, menu) menu.close() end) - elseif data.current.value == 'boss_actions' then TriggerEvent('esx_society:openBossMenu', 'banker', function (data, menu) menu.close() end, {wash = false}) end - end, function(data, menu) menu.close() @@ -105,7 +86,7 @@ function OpenCustomersMenu() rows = {} } - for i=1, #customers, 1 do + for i=1, #customers do table.insert(elements.rows, { data = customers[i], cols = { @@ -117,7 +98,6 @@ function OpenCustomersMenu() end ESX.UI.Menu.Open('list', GetCurrentResourceName(), 'customers', elements, function(data, menu) - local customer = data.data if data.value == 'deposit' then @@ -132,9 +112,7 @@ function OpenCustomersMenu() ESX.ShowNotification(_U('invalid_amount')) else menu2.close() - TriggerServerEvent('esx_bankerjob:customerDeposit', customer.source, amount) - OpenCustomersMenu() end end, function(data2, menu2) @@ -153,7 +131,6 @@ function OpenCustomersMenu() ESX.ShowNotification(_U('invalid_amount')) else menu2.close() - TriggerServerEvent('esx_bankerjob:customerWithdraw', customer.source, amount) OpenCustomersMenu() end @@ -162,17 +139,14 @@ function OpenCustomersMenu() OpenCustomersMenu() end) end - end, function(data, menu) menu.close() end) - end) - end AddEventHandler('esx_bankerjob:hasEnteredMarker', function (zone) - if zone == 'BankActions' and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'banker' then + if zone == 'BankActions' and ESX.PlayerData.job and ESX.PlayerData.job.name == 'banker' then CurrentAction = 'bank_actions_menu' CurrentActionMsg = _U('press_input_context_to_open_menu') CurrentActionData = {} @@ -184,67 +158,43 @@ AddEventHandler('esx_bankerjob:hasExitedMarker', function (zone) ESX.UI.Menu.CloseAll() end) -RegisterNetEvent('esx_phone:loaded') -AddEventHandler('esx_phone:loaded', function (phoneNumber, contacts) - local specialContact = { - name = 'Banque', - number = 'banker', - base64Icon = 'data:image/x-icon;base64,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RCU6uEMlDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4w41Qub+NULqfjVC7b41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/4FMt/8RIJ/+2QyX/tkMl/7ZDJf+2QyX/tkMl4LhEJay2QyVyuEQlNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyXfuUQlZLhEJQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4841Quz+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/gUy3/xkko/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/t0Ml07dDJUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4U41Quo+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/j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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC5341Qu++NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/2lAs/7tFJv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX8uEQlfQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4M41Qup+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/9FNKv+4QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/uEQlrLdDJQ4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuGONULsvjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+JTLf/ISSj/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/t0MlzrdDJRsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULijjVC7f41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/eUi3/v0Ym/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl4rZDJSsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4o41Qu5+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/1k8r/7pEJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl6rZDJSsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuPONULvPjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/85MKf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl9bpFJj8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULijjVC7z41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+BTLf/ESCf/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl8bZDJSsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4o41Qu5+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/cUSz/vUUm/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl6rZDJSsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuGONULt/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/1E4r/7hDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl4rdDJRsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgzjVC7L41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/4lMt/8pKKf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/t0MlzrdDJQ4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Qup+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/95SLf/BRyf/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/uEQlrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULnfjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/ZUCv/ukQm/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/uEQlfQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC5E41Qu++NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/0E0q/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX8uUQlSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuFONULuPjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/4FMt/8ZJKP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyXmt0MlFgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC6v41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/91RLP++Rib/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+4RCWzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuYONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/WTyv/uEQl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+5RCVlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhTjVC7v41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/zEsp/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJfG3QyUWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Quo+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/lZEH/9se6//78/P///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////vz7/+jEu/++Vz3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7lEJagAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULjzjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5WE+//rk3v////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////fq5/+8VDn/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7dDJUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4E41Quz+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/0v7H//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+S4rf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/t0Ml07hEJQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULmDjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//75+P///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Pn4/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/uUQlZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4I41Qu3+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyXfuEMlCQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULm/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/++fj///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////z5+P+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+5RCV0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4E41Qu3+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+6Xf//+/Pz////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+/Pv/0499/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJeO4RCUEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULlzjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+ZmRf/umYP/8amW//vn4v//////////////////////////////////////////////////////+vPx/9uklf/aoZL/2qGS/9qhkv/aoZL/2qGS/9qhkv/aoZL/2qGS/9qhkv/aoZL/8NnS///////////////////////////////////////////////////////8+fj/3qmc/9qhkv/aoZL/2qGS/9qhkv/aoZL/2qGS/9qhkv/aoZL/2qGS/9qhkv/rzcX///////////////////////////////////////////////////////78+//hsqb/1pWE/79aQP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Quz+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/riW//////////////////////////////////////////////////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTv/////////////////////////////////////////////////////////////////jua3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/u1E2//78+////////////////////////////////////////////////////////////+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/t0Ml0wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULjjjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+uJb//////////////////////////////////////////////////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/w2ZO/////////////////////////////////////////////////////////////////+O5rf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+7UTb//vz7////////////////////////////////////////////////////////////7NDI/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/uEQlPQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Qun+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+2Ref/xqZb/8amW//jUyv//////////////////////2qGS/9qhkv/aoZL/1pWE/7dGKP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/y3tl/9qhkv/aoZL/2qGS///////////////////////aoZL/2qGS/9qhkv/Ym4v/uUsv/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/Hb1j/2qGS/9qhkv/aoZL//////////////////////+zQyP/aoZL/2qGS/9mejv+8VDn/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+5RCWjAAAAAAAAAAAAAAAAAAAAAAAAAAAA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VC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7hEJawAAAAAAAAAAAAAAAAAAAAA41Qu7+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl8QAAAAAAAAAAAAAAAONULjDjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/uEQlNQAAAAAAAAAA41Qub+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyVyAAAAAAAAAADjVC6n41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7hEJawAAAAAAAAAAONULtvjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl4AAAAADjVC4M41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/vUUmDuNULjTjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/79GJv/QTCo141QuXONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/FSCf/4VMt/9ZPK1zjVC6D41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/zEsp/+NULv/jVC7/3lItg+NULp/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9JOKv/jVC7/41Qu/+NULv/jVC6f41Quv+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7pEJf/YUCv/41Qu/+NULv/jVC7/41Qu/+NULr/jVC7X41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+9RSb/3FEs/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu1+NULuPjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/wUcn/+BTLf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7j41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8hJKP/iUy3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/OTCr/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+4QyX/1U8r/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/ukQm/9pQLP/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/75GJv/eUi3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/DSCf/4FMt/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/y0op/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9FNKv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULuPjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7hEJf/XTyv/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7j41Qu1+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/xqZb//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl///////////////////////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+9RSb/3FEs/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULtfjVC6/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Gplv//////////////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/wEcn/99SLf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Quv+NULp/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8amW//////////////////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX//////////////////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf//////////////////////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8ZJKP/iUy3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC6f41Qug+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+h3WP/87+v//////////////////////////////////////////////////////+3QyP+4SSv/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/uk4y//Hc1v//////////////////////////////////////////////////////8t/Z/7tRNv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+3Rij/7M3F///////////////////////////////////////////////////////68/H/yHJb/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/NSyn/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULoPjVC5c41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/9Lyt/////////////////////////////////////////////////////////////////86BbP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/UkoH/////////////////////////////////////////////////////////////////15iI/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8t7Zv/////////////////////////////////////////////////////////////////juK3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+4QyX/004q/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuXONULjTjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5mZE/+ZpSP/voY3/////////////////////////////////////////////////////////////////y3tm/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9KMev/////////////////////////////////////////////////////////////////WlYT/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/yXVf////////////////////////////////////////////////////////////+/b1/9GJdv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/ukQl/9lQLP/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC4041QuDONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+qBZf////////////////////////////////////////////////////////////////////////////v29f/aoZL/2qGS/9qhkv/aoZL/2qGS/9qhkv/aoZL/2qGS/9qhkv/aoZL/3KeY//35+P///////////////////////////////////////////////////////vz7/9ynmP/aoZL/2qGS/9qhkv/aoZL/2qGS/9qhkv/Ym4v/0Yp3/9GKd//Rinf/+O3r///////////////////////////////////////////////////////////////////////58O7/vFQ5/7ZDJf+2QyX/tkMl/71GJv/eUi3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULgwAAAAA41Qu2+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/+NfO///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Ym4v/tkMl/7ZDJf/DSCf/4FMt/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7bAAAAAAAAAADjVC6n41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/76uX//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+O4rf+2QyX/yUop/+JTLf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULqcAAAAAAAAAAONULm/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//nc1P//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////2ZuL/9BNKv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QubwAAAAAAAAAA41QuMONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/7I92//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////nt6v/cYD//41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC4wAAAAAAAAAAAAAAAA41Qu7+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/6Xxf//rf2P/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////1xrr/5WlI/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu7wAAAAAAAAAAAAAAAAAAAADjVC6n41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Yx/+6Zg//88e7////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////64dv/6oFl/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC6nAAAAAAAAAAAAAAAAAAAAAONULlzjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+ReO//zt6f//vz8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////99PL/75yG/+NWMf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULlwAAAAAAAAAAAAAAAAAAAAA41QuFONULvvjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/ocVL/99HH///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+/Pz/87mq/+VhPv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7741QuFAAAAAAAAAAAAAAAAAAAAAAAAAAA41Quu+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/7Ixz//vp5f//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+NfO/+h0Vf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULrsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC5k41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5Fk0//Cnk//++fj/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////++nl/+yPdv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgzjVC7341Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+ZmRf/1xLf//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////vn4//Gplv/kWTT/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvfjVC4MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULp/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/pfF//+t/Y//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////XEt//maUj/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QunwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuOONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVjH/7peA//zx7v////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////rh2//qf2L/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC44AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Quz+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5F47//K0o//+/Pz///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////308v/umYP/41Yx/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuzwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC5c41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+dvTv/30cf///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////78/P/zt6f/5F47/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC5cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgTjVC7j41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/siW//++fi///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30cf/6HFS/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu3+NULgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULm/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/kWTT/8KeT//339f/////////////////////////////////////////////////////////////////////////////////////////////////76eX/7Ixz/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC5vAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuCONULt/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5mZF//XCtP/////////////////////////////////////////////////////////////////////////////////++fj/8KeT/+RZNP/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu3+NULggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuYONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+l8X//53NX/////////////////////////////////////////////////////////////////9cS3/+ZmRf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC5gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4E41Quz+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NWMf/ul4D//PHu////////////////////////////////////////////+dzV/+l8X//jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Quz+NULgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4841Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/kXjv/8rGg//78/P///////////////////////PHu/+6XgP/jVjH/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC48AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC6j41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/6HdY//fPxP/++fj//PLv//S8rf/mZkX/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuowAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhTjVC7v41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULu/jVC4UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULmDjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULq/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULq8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuFONULuPjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7j41QuFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuRONULvvjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu++NULkQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Qud+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC53AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Qup+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QupwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4M41Quy+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULsvjVC4MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4Y41Qu3+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7f41QuGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4o41Qu5+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu5+NULigAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4o41Qu8+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvPjVC4oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4841Qu8+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7z41QuPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4o41Qu5+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu5+NULigAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4o41Qu3+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULt/jVC4oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4Y41Quy+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7L41QuGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4M41Quq+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qup+NULgwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Qud+NULvvjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu++NULncAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuRONULuPjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULuPjVC5EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuFONULq/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC6v41QuFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULmDjVC7v41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7v41QuYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhTjVC6j41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Quo+NULhQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4841Quz+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Quz+NULjwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4E41QuYONULt/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu3+NULmDjVC4EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuCONULm/jVC7f41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu3+NULm/jVC4IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgTjVC5c41Quz+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Quz+NULlzjVC4EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuOONULp/jVC7341Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7341Qun+NULjgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgzjVC5k41Quu+NULvvjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvvjVC6741QuZONULgwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuFONULlzjVC6n41Qu7+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu7+NULqfjVC5c41QuFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuMONULm/jVC6n41Qu2+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULtvjVC6n41Qub+NULjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuDONULjTjVC5c41Qug+NULp/jVC6/41Qu1+NULuPjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULuPjVC7X41Quv+NULp/jVC6D41QuXONULjTjVC4MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////AAAA////////////////8AAAAA///////////////wAAAAAA//////////////gAAAAAAB/////////////gAAAAAAAH////////////AAAAAAAAAP///////////AAAAAAAAAA///////////AAAAAAAAAAD//////////gAAAAAAAAAAf/////////gAAAAAAAAAAB/////////wAAAAAAAAAAAP////////wAAAAAAAAAAAA////////4AAAAAAAAAAAAH///////8AAAAAAAAAAAAA///////8AAAAAAAAAAAAAD//////+AAAAAAAAAAAAAAf//////AAAAAAAAAAAAAAD//////gAAAAAAAAAAAAAAf/////wAAAAAAAAAAAAAAD/////4AAAAAAAAAAAAAAAf////8AAAAAAAAAAAAAAAD////+AAAAAAAAAAAAAAAAf////AAAAAAAAAAAAAAAAD////wAAAAAAAAAAAAAAAA////4AAAAAAAAAAAAAAAAH///8AAAAAAAAAAAAAAAAA///+AAAAAAAAAAAAAAAAAH///gAAAAAAAAAAAAAAAAB///wAAAAAAAAAAAAAAAAAP//4AAAAAAAAAAAAAAAAAB//+AAAAAAAAAAAAAAAAAAf//AAAAAAAAAAAAAAAAAAD//gAAAAAAAAAAAAAAAAAAf/4AAAAAAAAAAAAAAAAAAH/8AAAAAAAAAAAAAAAAAAA//AAAAAAAAAAAAAAAAAAAP/gAAAAAAAAAAAAAAAAAAB/4AAAAAAAAAAAAAAAAAAAf+AAAAAAAAAAAAAAAAAAAH/AAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAP4AAAAAAAAAAAAAAAAAAAB+AAAAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAAAAAAHwAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAAAABwAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAA+AAAAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAAAAAAH4AAAAAAAAAAAAAAAAAAAB/AAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAP+AAAAAAAAAAAAAAAAAAAH/gAAAAAAAAAAAAAAAAAAB/4AAAAAAAAAAAAAAAAAAAf/AAAAAAAAAAAAAAAAAAAP/wAAAAAAAAAAAAAAAAAAD/+AAAAAAAAAAAAAAAAAAB//gAAAAAAAAAAAAAAAAAAf/8AAAAAAAAAAAAAAAAAAP//gAAAAAAAAAAAAAAAAAH//4AAAAAAAAAAAAAAAAAB///AAAAAAAAAAAAAAAAAA///4AAAAAAAAAAAAAAAAAf//+AAAAAAAAAAAAAAAAAH///wAAAAAAAAAAAAAAAAD///+AAAAAAAAAAAAAAAAB////wAAAAAAAAAAAAAAAA////8AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAAH////8AAAAAAAAAAAAAAAD/////gAAAAAAAAAAAAAAB/////8AAAAAAAAAAAAAAA//////gAAAAAAAAAAAAAAf/////8AAAAAAAAAAAAAAP//////gAAAAAAAAAAAAAH//////8AAAAAAAAAAAAAD///////wAAAAAAAAAAAAD///////+AAAAAAAAAAAAB////////wAAAAAAAAAAAA/////////AAAAAAAAAAAA/////////4AAAAAAAAAAAf/////////gAAAAAAAAAAf/////////8AAAAAAAAAAP//////////wAAAAAAAAAP///////////AAAAAAAAAP///////////+AAAAAAAAf////////////4AAAAAAAf/////////////wAAAAAA///////////////wAAAAD////////////////wAAAP////////KAAAAGAAAADAAAAAAQAgAAAAAACAlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4I41QuKeJTLU7jVC5341Qum+JTLb3j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QiT+tUIk/rVCJP62QyX7tkMlXQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMtDuNULuTjVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/8a6c/v///////////v7+/v///////////v7+/v////////////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/tymmP+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tkMl5rdDJQ8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMteONULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/99PJ/v///////////v7+/v///////////v7+/v////////////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/uzOx/+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rhEJXsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy0Y4lMt6OJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+99HH/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/uvMxP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rZDJei3QyUaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC584lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/6Xlb/vrh2v/+/Pv//v7+/v///////////v7+/v////////////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v/////+/f3/8+Db/sZuVv+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+4RCV/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhDjVC7f4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uRbNv/nbk3/+NjP/v///////////v7+/v////////////////7+/v7+/Pz/2qCR/79aQP6/WkD/v1pA/79aQP6/WkD/v1pA/79aQP7bpJb//vz8//7+/v7///////////7+/v7///////////7+/v7t0sv/wV9F/79aQP6/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QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyVrAAAAAAAAAADiUy2s4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7maUj+/v7+/v7+/v7+/v7+yHFb/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7aoZL+/v7+/v7+/v7aoJH+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/shyW/7+/v7+/v7+/v7+/v6/WkD+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP63QyWwAAAAAONULgjjVC7g4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyXhtkMlCeNULinjVC7z4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX1uUQlLOJTLU7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7maUj+/v7+/v7+/v7+/v7+yHFb/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7aoZL+/v7+/v7+/v7aoJH+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/shyW/7+/v7+/v7+/v7+/v6/WkD+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+vkYmT+NULnfjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf/FSSf/1U4rd+NULpvjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/stLKf/hUy3/3lIsm+JTLb3iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7maUj+/v7+/v7+/v7+/v7+yHFb/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7aoZL+/v7+/v7+/v7aoJH+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/shyW/7+/v7+/v7+/v7+/v6/WkD+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP64QyX+0U0q/uJTLf7iUy3+4lMtveNULtbjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rpEJf/WTyv/4lMt/uNULv/jVC7/4lMt1uNULunjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/vEUm/ttRLP/jVC7/4lMt/uNULv/jVC7/4lMt6eJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7maUj+/v7+/v7+/v7+/v7+yHFb/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7aoZL+/v7+/v7+/v7aoJH+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/shyW/7+/v7+/v7+/v7+/v6/WkD+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7CRyf+31It/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tkMl/shJKP/gUy3/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/zUsp/uJTLf/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7maUj+/v7+/v7+/v7+/v7+yHFb/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7aoZL+/v7+/v7+/v7aoJH+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/shyW/7+/v7+/v7+/v7+/v6/WkD+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rhEJf7UTiv+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/u0Um/tlQK//iUy3/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+/Rib/3FEs/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uJTLeniUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7maUj+/v7+/v7+/v7+/v7+yHFb/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7aoZL+/v7+/v7+/v7aoJH+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/shyW/7+/v7+/v7+/v7+/v6/WkD+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/sRIJ/7gUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt6eNULtbjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/maUj//v7+/v//////////yHFb/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7aoZL///////7+/v7aoZH/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/shyW////////v7+/v////+/WkD/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/ykop/uFTLf/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt1uNULr3jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lQu/uNULv/maUj//v7+/v//////////yHJb/7ZDJf62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7ZDJf7aoZL///////7+/v7aoZL/tkMl/7ZDJf62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tkMl/shyW////////v7+/v////+/WkD/tkMl/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rZDJf+2QyX/tUIk/rdDJf/PTCn/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMtveJTLZviUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7lYkD++uLc/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v769PL+x29Y/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP7aoZL+/v39/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v79/f7cppj+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+tUIk/sZsVP768vD+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/vXm4v69Vjv+tUIk/rVCJP61QiT+tUIk/rVCJP61QiT+uUQl/tZPK/7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMtm+NULnfjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNYM//odFX//vz7/v///////////v7+/v////////////////7+/v7/////26KT/7VCJP62QyX/tkMl/7VCJP62QyX/tkMl/7VCJP7z4Nv///////7+/v7///////////7+/v7///////////7+/v7049//tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX/tUIk/tmfkP///////v7+/v///////////v7+/v///////////v7+/v35+P/DZEz/tUIk/rZDJf+2QyX/tUIk/rZDJf+9RSb/2lAs/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMtd+JTLU7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+521N/vnd1v764dr+/vr6/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/f3+3que/tGJdv7RiXb+0Yl2/tGJdv7RiXb+0Yl2/tGJdv7sz8f+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7u08z+0Yl2/tGJdv7RiXb+0Yl2/tGJdv7MfWj+ynhi/teaif79+/v+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/vr08v7t0sv+6ce+/rlMMP61QiT+tUIk/sBHJ/7eUiz+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMtTeNULinjVC7z4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/87mq/v///////////v7+/v///////////v7+/v////////////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/tGKeP+2QyX/xkko/uFTLf/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7z4lMtKeNULgjjVC7g4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/9MG0/v///////////v7+/v///////////v7+/v////////////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/taSgf/MSyn/4VMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7g4lMtBwAAAADiUy2s4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+7Ixy/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7++/Xz/ttmRv7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy2sAAAAAAAAAADjVC5p4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uqAZP/52tL//v7+/v///////////v7+/v////////////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v79/P/2zMD/53BR/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC5pAAAAAAAAAADjVC4o4lMt+ONULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/kXDj/7pmD/vzv6////v7//v7+/v////////////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v///////////v7+/v/////+/v7/+uTe/uuJb//jWDP/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULvjjVC4oAAAAAAAAAADiUy0I4lMtzeJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uVmRP7zuKj+/vr6/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v318/7wppL+5F06/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLc3iUy0IAAAAAAAAAAAAAAAA4lMtf+NULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/6HNU/vfRx//+/f3///////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v7+/v/////++vn/9cG0/uZmRP/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULn8AAAAAAAAAAAAAAAAAAAAA4lMtKONULv3jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNYM//sj3b/+uTf//7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////v7+/v///////////v39/vjXzv/pfWH/41Uw/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/eNULigAAAAAAAAAAAAAAAAAAAAAAAAAAOJTLcbiUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+5F87/vGrmP799/X+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v787er+7piC/uNYMv7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMtxgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULl3jVC7+4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7makn/9cG0//77+/7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v///////////fb1/vKwn//lYDz/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7+4lMtXQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhDjVC7f4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Yw/+qCZv752tL//v39//7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7///////////7+/v7//////v7+/v77+v/2y8D/6HRV/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7f4lMtDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy1+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7kWzb+7pqD/vzx7v7+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VC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+NULv7nb1D/76CL/+6Zgv7mZkT/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC644lMtBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy0u4lMt8OJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLfDiUy0uAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMtauNULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULmoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMtA+NULrHjVC7+41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7+4lMtsONULgMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOJTLRriUy3a4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3a4lMtGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4041Qu7OJTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULuzjVC40AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuU+JTLfnjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt+eNULlMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOJTLXHiUy364lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy364lMtcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC534lMt/ONULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULvzjVC53AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4E4lMtd+NULvrjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt+uNULnfjVC4EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOJTLXHiUy354lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy354lMtcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC5T4lMt7eNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULuzjVC5TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMtNeNULtrjVC7+4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7+4lMt2uNULjQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOJTLRriUy2x4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy2w4lMtGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4D4lMtauNULvDjVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt8ONULmrjVC4DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULi7jVC644lMt++NULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULvvjVC644lMtLgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy0G4lMtWuJTLeTiUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt5OJTLVriUy0FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULg7jVC544lMt6ONULv/jVC7/4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULujjVC544lMtDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMtGONULnzjVC7f4lMt/uNULv/jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC7/4lMt/uNULv7jVC7f4lMte+NULhgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy0P4lMtXeJTLcbiUy394lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLf7iUy394lMtxuJTLV3iUy0PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4o41QugOJTLc3jVC7441Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/jVC7/4lMt/uNULv/jVC744lMtzeNULn/jVC4oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOJTLQjjVC4o41QuaeJTLazjVC7g41Qu8+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULvPjVC7g4lMtrONULmnjVC4o4lMtCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy0H4lMtKeJTLU3iUy134lMtm+JTLb3iUy3W4lMt6eJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/uJTLeniUy3W4lMtveJTLZviUy134lMtTeJTLSniUy0HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////4AAAf//////////+AAAAB//////////4AAAAAf/////////AAAAAAD////////8AAAAAAA////////wAAAAAAAP///////AAAAAAAAD//////+AAAAAAAAB//////4AAAAAAAAAf/////wAAAAAAAAAP/////gAAAAAAAAAH/////AAAAAAAAAAD////+AAAAAAAAAAB////4AAAAAAAAAAAf///4AAAAAAAAAAAf///wAAAAAAAAAAAP///gAAAAAAAAAAAH///AAAAAAAAAAAAD//+AAAAAAAAAAAAB//8AAAAAAAAAAAAA//8AAAAAAAAAAAAA//4AAAAAAAAAAAAAf/wAAAAAAAAAAAAAP/wAAAAAAAAAAAAAP/gAAAAAAAAAAAAAH/gAAAAAAAAAAAAAH/AAAAAAAAAAAAAAD/AAAAAAAAAAAAAAD+AAAAAAAAAAAAAAB+AAAAAAAAAAAAAAB+AAAAAAAAAAAAAAB8AAAAAAAAAAAAAAA8AAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAA+AAAAAAAAAAAAAAB+AAAAAAAAAAAAAAB+AAAAAAAAAAAAAAB/AAAAAAAAAAAAAAD/AAAAAAAAAAAAAAD/gAAAAAAAAAAAAAH/gAAAAAAAAAAAAAH/wAAAAAAAAAAAAAP/wAAAAAAAAAAAAAP/4AAAAAAAAAAAAAf/8AAAAAAAAAAAAA//8AAAAAAAAAAAAA//+AAAAAAAAAAAAB///AAAAAAAAAAAAD///gAAAAAAAAAAAH///wAAAAAAAAAAAP///4AAAAAAAAAAAf///4AAAAAAAAAAAf///+AAAAAAAAAAB/////AAAAAAAAAAD/////gAAAAAAAAAH/////wAAAAAAAAAP/////4AAAAAAAAAf/////+AAAAAAAAB///////AAAAAAAAD///////wAAAAAAAP///////8AAAAAAA/////////AA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QiT+tkMl/7ZDJf+1QiT+tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7ZDJf+1QiT+tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7dDJaa2QyUCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULlXjVC7941Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVjH/42dF/8heQv+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/v1pA/79aQP+/WkD/vlk+/7dGKP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf23QyVXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuDuNULt/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NYM//2yLz//v39/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////v38/+nHv/+4SCv/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyXgtkMlDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMthuNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/++eiP/+/v7+//////7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+//////7+/v7///////////7+/v7//////v7+/v/////+/v7+//////7+/v7VlIP/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/t0MliQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4d41Qu8ONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//K0o//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////frJ//tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl8LdDJR4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC6N4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+p/Y//77On+/v7+//7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+//////7+/v7///////////7+/v7//////v7+/v/////+/v7+//////fs6f7JdF3/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rdDJZAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhXjVC7s41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/kWzf/76CL//7+/v///////////////////////////+W+s/+8VDn/vFQ5/7xUOf+8VDn/vFQ5/9aWhf/+/f3////////////////////////////mv7X/vFQ5/7xUOf+8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QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl8rZDJRjjVC5D41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/sjnX////////////DZk3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/v1pA////////////v1pA/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTf///////////8+Db/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7hDJUXjVC5041Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7sjnX//v7+/v/////DZk3+tkMl/7ZDJf+1QiT+tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+v1pA///////+/v7+v1pA/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/8NmTf7//////v7+/s+Db/+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7tFJXXjVC6d41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/sjnX////////////DZk3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/v1pA////////////v1pA/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTf///////////8+Db/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/wEYm/9ZPK53jVC7B41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7sjnX//v7+/v/////DZk3+tkMl/7ZDJf+1QiT+tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+v1pA///////+/v7+v1pA/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/8NmTf7//////v7+/s+Db/+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf/FSCf+4FMt/+FTLcHjVC7e41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/sjnX////////////DZk3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/v1pA////////////v1pA/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTf///////////8+Db/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8tLKf/iUy3/41Qu/+NULt7jVC7y41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7sjnX//v7+/v/////DZk3+tkMl/7ZDJf+1QiT+tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+v1pA///////+/v7+v1pA/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/8NmTf7//////v7+/s+Db/+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP63QyX/0U0q/uJTLf/iUy3+41Qu/+JTLfLjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/sjnX////////////DZk3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/v1pA////////////v1pA/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTf///////////8+Db/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7pEJf/XTyv/4lMt/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/sjnX////////////DZk3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/v1pA////////////v1pA/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTf///////////8+Db/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/vUUm/9tRLP/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7sjnX//v7+/v/////DZk3+tkMl/7ZDJf+1QiT+tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+v1pA///////+/v7+v1pA/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/8NmTf7//////v7+/s+Db/+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP7CRyf/31It/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/sjnX////////////DZk3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/v1pA////////////v1pA/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTf///////////8+Db/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8dJKP/hUy3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7y41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7sjnX//v7+/v/////DZk3+tkMl/7ZDJf+1QiT+tkMl/7VCJP62QyX/tUIk/rZDJf+1QiT+v1pA///////+/v7+v1pA/7VCJP62QyX/tUIk/rZDJf+1QiT+tkMl/7VCJP62QyX/tkMl/8NmTf7//////v7+/s+Db/+1QiT+tkMl/7VCJP62QyX/tkMl/7VCJP62QyX/tUIk/rZDJf+2QyX+zkwp/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLfLjVC7e41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/sjnX////////////DZk3/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/v1pA////////////v1pA/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8NmTf///////////8+Db/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7hEJf/UTir/4lMt/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULt7jVC7B41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+6HJT//Cplv71xrr//v7+/v/////hsqb+2qCR/8FfRv+1QiT+tkMl/7VCJP62QyX/tUIk/sBeRf/aoJH+36yf///////+/v7+36yf/9qgkf7BYEb/tUIk/rZDJf+1QiT+tkMl/7VCJP7AXkX/2p+Q/+Gypv7//////v7+/ufBt//aoJH+xGhQ/7VCJP62QyX/tkMl/7VCJP62QyX/u0Qm/tlQK//iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLcHjVC6d41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVzL/9L2v/////////////////////////////////+K2qv+2QyX/tkMl/7ZDJf+2QyX/tkMl/+K0qP/////////////////////////////////juKz/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/hs6f/////////////////////////////////47es/7ZDJf+2QyX/tkMl/7ZDJf+/Rib/3VEs/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULp3jVC5041Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+hyU//65uD+/PHu//7+/v7//////v7+/v/////+/v7+/////+zPx//cppj+3KaY/9ymmP7cppj/3KaY/uzOxv/+/v7+///////////+/v7+//////7+/v7s0Mj/3KaY/tymmP/cppj+26OU/9eZif7oxLr///////7+/v7//////v7+/v/////+/v7+9ujl/+/X0P68Uzj/tkMl/8NIJ/7gUi3/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLXTjVC5D41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//Cnk//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////OgGz/ykop/+JTLf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULkLjVC4X41Qu8eJTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+uHbP/+/v7+//////7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+//////7+/v7///////////7+/v7//////v7+/v/////+/v7+//////35+P7aZ0n/4lMt/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu8eJTLRcAAAAA41QuxeNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/qgWb/+d7W///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+/v7/99PJ/+h1Vv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuxQAAAAAAAAAA41QufeNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5Fk1/++diP/88e7//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////v7+//vq5f/skHf/41Yx/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QufQAAAAAAAAAA41QuK+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7lY0D/87mq/v76+f/+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+//////7+/v7///////////7+/v799vT/8auZ/uRcOP/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41QuKwAAAAAAAAAA41QuAuNULs7jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+h3Wf/41Mr//v79/////////////////////////////////////////////////////////////////////////////////////////////////////////////vz8//XGuv/nbEz/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7O41QuAgAAAAAAAAAAAAAAAOJTLWzjVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/jVTD+7ZB4//vo4//+/v7+//////7+/v7//////v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v/////+/v7+//////7+/v753tf/6oNn/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy1sAAAAAAAAAAAAAAAAAAAAAONULhTjVC7s41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+RcOP/xq5n//fXz/////////////////////////////////////////////////////////////////////////////O/s/++dh//jWDP/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULuzjVC4UAAAAAAAAAAAAAAAAAAAAAAAAAADjVC6P4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+5mxL//XGuv7+/f3//v7+/v/////+/v7+///////////+/v7+//////7+/v7//////v7+/v77+v/zuKj+5WNA/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULo0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4d41Qu8ONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NUL//qgWX/+d3W///+/v/////////////////////////////////+/f3/99LI/+h0Vv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu8ONULh0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMthuNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/41k1/u+ch//88u/+///////////+/v7+//////vo4/7sjnX/41Yx/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMthgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuDuNULt/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/lYT7/87us//349v/99PH/8aya/+RaNv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7f41QuDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULlXjVC7941Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+VjQf/lYT3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv3jVC5VAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgLiUy2k41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLaTjVC4CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4T41Qu3ONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu3ONULhMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuN+NULvHiUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7x41QuNwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULljjVC7741Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvvjVC5YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy1z41Qu/OJTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/OJTLXMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41Quf+NULvzjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7841QufwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOJTLXPjVC774lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULvviUy1zAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC5Y41Qu8uNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu8eNULlgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuN+NULtzjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7c41QuNwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhPiUy2k41Qu/eNULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/eJTLaTjVC4TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4C41QuVeNULt/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7f41QuVeNULgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULg7iUy2G41Qu8OJTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu8OJTLYbjVC4OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuHeNULo3jVC7s41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULuzjVC6N41QuHQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4U4lMtbONULs7iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+NULv/iUy3+41Qu/+JTLf7jVC7/4lMt/uNULv/iUy3+41Qu/+JTLf7jVC7/41Qu/+JTLf7jVC7O4lMtbONULhQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgLjVC4r41QufeNULsXjVC7x41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvHjVC7F41QufeNULivjVC4CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiUy0X41QuQuJTLXTjVC6d4lMtweNULt7iUy3y41Qu/+NULv/iUy3+41Qu/+JTLfLjVC7e4lMtweNULp3iUy1041QuQuJTLRcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD////gAAf///8AAAD///4AAAB///8AAAD///gAAAAf//8AAAD//+AAAAAH//8AAAD//4AAAAAB//8AAAD//gAAAAAAf/8AAAD//AAAAAAAP/8AAAD/+AAAAAAAH/8AAAD/8AAAAAAAD/8AAAD/4AAAAAAAB/8AAAD/wAAAAAAAA/8AAAD/gAAAAAAAAf8AAAD/AAAAAAAAAP8AAAD+AAAAAAAAAH8AAAD8AAAAAAAAAD8AAAD4AAAAAAAAAB8AAAD4AAAAAAAAAB8AAADwAAAAAAAAAA8AAADwAAAAAAAAAA8AAADgAAAAAAAAAAcAAADgAAAAAAAAAAcAAADAAAAAAAAAAAMAAADAAAAAAAAAAAMAAACAAAAAAAAAAAEAAACAAAAAAAAAAAEAAACAAAAAAAAAAAEAAACAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAEAAACAAAAAAAAAAAEAAACAAAAAAAAAAAEAAACAAAAAAAAAAAEAAADAAAAAAAAAAAMAAADAAAAAAAAAAAMAAADgAAAAAAAAAAcAAADgAAAAAAAAAAcAAADwAAAAAAAAAA8AAADwAAAAAAAAAA8AAAD4AAAAAAAAAB8AAAD4AAAAAAAAAB8AAAD8AAAAAAAAAD8AAAD+AAAAAAAAAH8AAAD/AAAAAAAAAP8AAAD/gAAAAAAAAf8AAAD/wAAAAAAAA/8AAAD/4AAAAAAAB/8AAAD/8AAAAAAAD/8AAAD/+AAAAAAAH/8AAAD/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QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJfi3QyUyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuBeNULtPjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/91RLP++Rib/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/t0Ml1bZDJQUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULnfjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41cy//XDtv/+/v7///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////7+/v/nwbf/t0cq/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+3QyV5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhnjVC7z41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+6Ygf///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9OOe/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl9LdDJRoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC6V41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/wqJT////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Zn5D/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+3QyWWAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4Y41Qu9+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5WRC//S/sP/6493////////////////////////////15eH/7NDI/+zQyP/s0Mj/7NDI/+zQyP/79fP///////////////////////79/f/t0sv/7NDI/+zQyP/s0Mj/7NDI//Hb1f////////////////////////////fr6P/kuq//vVY7/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl+LZDJRkAAAAAAAAAAAAAAAAAAAAA41QugeNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/9cS3////////////////////////////7NDI/7ZDJf+2QyX/tkMl/7ZDJf+8VDn/////////////////////////////////zH5p/7ZDJf+2QyX/tkMl/7ZDJf/cp5n////////////////////////////15+P/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyWEAAAAAAAAAAAAAAAA41QuA+NULuXjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+VjQP/qfmL/+d7X///////juK3/yHJb/75YPf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8RoUP/Iclv////////////Iclv/x3BZ/7ZFJ/+2QyX/tkMl/7ZDJf+2QyX/uk4x/8hyW//juK3///////Hb1v/Iclv/wF5E/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl5rZDJQMAAAAAAAAAAONULkfjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//jUyv//////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/2qGS///////s0Mj/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyVKAAAAAAAAAADjVC6a41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/41Mr//////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf///////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9qhkv//////7NDI/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMlnAAAAAAAAAAA41Qu5eNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/+NTK///////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX///////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/aoZL//////+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJecAAAAA41QuJ+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//jUyv//////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/2qGS///////s0Mj/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMlKeNULmDjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/41Mr//////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf///////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9qhkv//////7NDI/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7hDJWPjVC6P41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/+NTK///////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX///////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/aoZL//////+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/ARyeQ41Qut+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//jUyv//////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/2qGS///////s0Mj/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/KSin/3lItt+NULtfjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/41Mr//////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf///////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9qhkv//////7NDI/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7dDJf/RTSr/41Qu/+NULtfjVC7u41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/+NTK///////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX///////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/aoZL//////+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7hEJf/XTyv/41Qu/+NULv/jVC7u41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//jUyv//////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/2qGS///////s0Mj/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7xFJv/cUSz/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/41Mr//////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf///////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9qhkv//////7NDI/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8BHJ//fUi3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/+NTK///////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX///////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/aoZL//////+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/8ZJKP/hUy3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu//jUyv//////2qGS/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl////////////tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/2qGS///////s0Mj/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/81LKf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULu7jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/41Mr//////9qhkv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf///////////7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/9qhkv//////7NDI/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/t0Ml/9NOKv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULu7jVC7X41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/+NTK///////aoZL/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX///////////+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/aoZL//////+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/ukQl/9lQLP/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7X41Qut+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/2yLz////////////////////////////cppj/tkMl/7ZDJf+2QyX/tkMl/75ZP//79vT///////////////////////v39f+/XEL/tkMl/7ZDJf+2QyX/tkMl/9ujlP///////////////////////////+nHvv+2QyX/tkMl/7ZDJf+2QyX/vUYm/91RLP/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qut+NULo/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+RfO//ys6L/++fi////////////////////////////6MS7/8hyW//Iclv/yHJb/8hyW//QhXL//v39///////////////////////+/v7/0Ih1/8hyW//Iclv/x3BZ/8NmTv/kurD////////////////////////////y39r/2Z2N/7dHKv+2QyX/wkcn/+BTLf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULo/jVC5g41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/umoP////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////KdmD/yUoo/+JTLf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC5g41QuJ+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/64Rp///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9+vn/2mdI/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuJwAAAADjVC7l41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/qgWX/+uLb///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////42M//6HVX/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu5QAAAAAAAAAA41QumuNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NWMf/vnoj//fPx//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////zt6f/tkXn/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULpoAAAAAAAAAAONULkfjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+ViP//zuqr//v39/////////////////////////////////////////////////////////////////////////////////////////////////////////////vn4//GunP/kXDf/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC5HAAAAAAAAAADjVC4D41Qu5eNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+h0Vv/41s3/////////////////////////////////////////////////////////////////////////////////////////////////9sm9/+ZqSf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7l41QuAwAAAAAAAAAAAAAAAONULoHjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+yOdf/76+f////////////////////////////////////////////////////////////////////////////649z/6oJn/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QugQAAAAAAAAAAAAAAAAAAAADjVC4Y41Qu+ONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5Fo2//Grmf/++ff///////////////////////////////////////////////////////3z8f/vnoj/41Yx/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu9+NULhgAAAAAAAAAAAAAAAAAAAAAAAAAAONULpXjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5mpI//XHu////////////////////////////////////////v39//O6qv/lYj//41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULpUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4Z41Qu8+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/6oBk//rh2///////////////////////+NXM/+h0Vv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvPjVC4ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULnfjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVjH/756I//zx7v/76+b/7JB4/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC53AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4F41Qu0+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7T41QuBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULjDjVC7441Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7441QuMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QubeNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QubQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC6f41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QunwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuBuNULrvjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Quu+NULgYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4K41QuyONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuyONULgoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgrjVC6741Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Quu+NULgoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuBuNULqDjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qun+NULgYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QubeNULvjjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7441QubQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4w41Qu0+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7T41QuMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgXjVC5341Qu8+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvPjVC5341QuBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhnjVC6V41Qu9+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu9+NULpXjVC4ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULhjjVC6B41Qu5eNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7l41QugeNULhgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgPjVC5H41QumuNULuXjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu5eNULprjVC5H41QuAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA41QuJ+NULmDjVC6P41Qut+NULtfjVC7u41Qu/+NULv/jVC7/41Qu/+NULu7jVC7X41Qut+NULo/jVC5g41QuJwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAA///////wAAAP/////8AAAAP/////AAAAAP////wAAAAAP///+AAAAAAf///wAAAAAA///8AAAAAAA///gAAAAAAB//8AAAAAAAD//gAAAAAAAH/+AAAAAAAAf/wAAAAAAAA/+AAAAAAAAB/wAAAAAAAAD/AAAAAAAAAP4AAAAAAAAAfgAAAAAAAAB8AAAAAAAAADwAAAAAAAAAOAAAAAAAAAAYAAAAAAAAABgAAAAAAAAAGAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAGAAAAAAAAAAYAAAAAAAAABgAAAAAAAAAHAAAAAAAAAA8AAAAAAAAAD4AAAAAAAAAfgAAAAAAAAB/AAAAAAAAAP8AAAAAAAAA/4AAAAAAAAH/wAAAAAAAA//gAAAAAAAH/+AAAAAAAAf/8AAAAAAAD//4AAAAAAAf//wAAAAAAD///wAAAAAA////gAAAAAH////AAAAAA/////AAAAAP/////AAAAD//////AAAA///////wAA////KAAAADAAAABgAAAAAQAgAAAAAACAJQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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QyX/tkMlZuNULpriUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+8rSj/v////+/WkD+tUIk/rZDJf+1QiT+tUIk/rZDJf+1QiT+7M/I/uzPyP+1QiT+tUIk/rZDJf+1QiT+tUIk/rZDJf+/WkD+/////9+sn/61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+uEQlm+NULsTiUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+8rSj/v////+/WkD+tUIk/rZDJf+1QiT+tUIk/rZDJf+1QiT+7M/I/uzPyP+1QiT+tUIk/rZDJf+1QiT+tUIk/rZDJf+/WkD+/////9+sn/61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP67RSb+1k8rxONULuTjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8rSj//////+/WkD/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/7NDI/+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+/WkD//////9+sn/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/79GJv/eUi3/41Qu5ONULvniUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+8rSj/v////+/WkD+tUIk/rZDJf+1QiT+tUIk/rZDJf+1QiT+7M/I/uzPyP+1QiT+tUIk/rZDJf+1QiT+tUIk/rZDJf+/WkD+/////9+sn/61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+xUgn/+FTLf7iUy3+4lMt+eNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+8rSj/v////+/WkD+tUIk/rZDJf+1QiT+tUIk/rZDJf+1QiT+7M/I/uzPyP+1QiT+tUIk/rZDJf+1QiT+tUIk/rZDJf+/WkD+/////9+sn/61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP61QiT+tkMl/7ZDJf7LSyn+4lMt/+JTLf7iUy3+4lMt/uNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/8rSj//////+/WkD/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/7NDI/+zQyP+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+/WkD//////9+sn/+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/t0Ml/9JNKv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvniUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+8rSj/v////+/WkD+tUIk/rZDJf+1QiT+tUIk/rZDJf+1QiT+7M/I/uzPyP+1QiT+tUIk/rZDJf+1QiT+tUIk/rZDJf+/WkD+/////9+sn/61QiT+tkMl/7VCJP61QiT+tkMl/7VCJP65RCX+108r/+JTLf7iUy3+41Qu/+JTLf7iUy3+4lMt+eNULuTiUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+8rSj/v////+/WkD+tUIk/rZDJf+1QiT+tUIk/rZDJf+1QiT+7M/I/uzPyP+1QiT+tUIk/rZDJf+1QiT+tUIk/rZDJf+/WkD+/////9+sn/61QiT+tkMl/7VCJP61QiT+tkMl/71FJv7cUSz+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+4lMt5ONULsTjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+VhPf/99/X/////////////////58G3/7ZDJf+2QyX/tkMl/86Bbf/+/v7////////////+/v7/z4Rw/7ZDJf+2QyX/tkMl/+a/tf/////////////////89/b/u1A0/7ZDJf+2QyX/wUcn/99SLf/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41QuxONULpriUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+6HNU//zv6/7+/f3+/v7+/v/////+/v7+9unm/ujEuv/oxLr+6MS6/u/Vz//+/v7+/v7+/v/////+/v7+79bQ/ujEuv/oxLr+5byy/vTk4P/+/v7+//////7+/v79/Pv+9ebi/75XPP7HSSj+4VMt/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+4lMtmuNULmXiUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+6X1g//7+/v7+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+//////7+/v7+/v7+/vz8/9hmR/7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+4lMtZeNULiTjVC7941Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+qCZ//64dv///7+//////////////////////////////////////////////////////////////////////////////////////////////////7+/v/52tL/6Xpc/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7941QuJONULgLiUy3S4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7jWDP+756J/v3z8P/+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/O7q/+2Vff7jVjH+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3S4lMtAgAAAADjVC5741Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+VjQf/zu6z//v38//////////////////////////////////////////////////////////////////76+f/ysaD/5F47/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC57AAAAAAAAAADiUy0b4lMt9uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+4lMt/uNULv/iUy3+6HVW/vjWzP/+/v7+/v7+/v/////+/v7+/v7+/v/////+/v7+/v7+/v/////+/v3+9s3C/uduTv/iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLfbiUy0bAAAAAAAAAAAAAAAA4lMtn+NULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+4lMt/uNULv/iUy3+4lMt/uNVMP/skHf+++rm/v/////+/v7+/v7+/v/////+/v7+/v7+/vrk3v/rhmz+41Qu/uNULv/iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLZ4AAAAAAAAAAAAAAAAAAAAA41QuIeNULvjjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5Fw4//Gtm//++fj////////////99fL/76OO/+NZNP/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu+ONULiEAAAAAAAAAAAAAAAAAAAAAAAAAAONULoXiUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/makn+9MGz/vO7q//lZEL+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41QuhQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgviUy3W4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3W41QuCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADjVC4z41Qu9eNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULvXjVC4zAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMtXeNULv3iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/eJTLV0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULnjiUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41Qu/+JTLf7iUy3+41QueAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONULgHjVC5441Qu/eNULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv3jVC5441QuAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4lMtXeNULvXiUy3+41Qu/+JTLf7iUy3+4lMt/uNULv/iUy3+4lMt/uNULv/i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iXb/0Yl2/+jGvf///////////+3TzP/RiXb/0Yl2//Lg2////////////+G0qP+3Ryr/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyWlAAAAAONULhLjVC7441Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41cy/++hjP/v1c//vFQ4/7ZDJf+2QyX/uUwv/9+sn//frJ//uk4y/7ZDJf+2QyX/u1E1/+/Vz//XmIf/uEks/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJfi2QyUT41QuX+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/7ZR8/+zQyP+2QyX/tkMl/7ZDJf+2QyX/2qGS/9qhkv+2QyX/tkMl/7ZDJf+2QyX/7NDI/9GJdv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJWDjVC6h41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/tlHz/7NDI/7ZDJf+2QyX/tkMl/7ZDJf/aoZL/2qGS/7ZDJf+2QyX/tkMl/7ZDJf/s0Mj/0Yl2/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMlouNULtHjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+2UfP/s0Mj/tkMl/7ZDJf+2QyX/tkMl/9qhkv/aoZL/tkMl/7ZDJf+2QyX/tkMl/+zQyP/RiXb/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf/HSSjR41Qu8ONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/7ZR8/+zQyP+2QyX/tkMl/7ZDJf+2QyX/2qGS/9qhkv+2QyX/tkMl/7ZDJf+2QyX/7NDI/9GJdv+2QyX/tkMl/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/0E0q/+NULvDjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/tlHz/7NDI/7ZDJf+2QyX/tkMl/7ZDJf/aoZL/2qGS/7ZDJf+2QyX/tkMl/7ZDJf/s0Mj/0Yl2/7ZDJf+2QyX/tkMl/7ZDJf+2QyX/uEQl/9ZPK//jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+2UfP/s0Mj/tkMl/7ZDJf+2QyX/tkMl/9qhkv/aoZL/tkMl/7ZDJf+2QyX/tkMl/+zQyP/RiXb/tkMl/7ZDJf+2QyX/tkMl/7tFJv/bUSz/41Qu/+NULv/jVC7/41Qu8ONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/7ZR8/+zQyP+2QyX/tkMl/7ZDJf+2QyX/2qGS/9qhkv+2QyX/tkMl/7ZDJf+2QyX/7NDI/9GJdv+2QyX/tkMl/7ZDJf/ARif/31It/+NULv/jVC7/41Qu/+NULvDjVC7R41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Yx//Gtm/////////////Da1P+/WkD/v1pA/+K0qf///////////+K2qv+/WkD/vVc8/+/X0P///////////9qhkv+2RCb/xUko/+FTLf/jVC7/41Qu/+NULv/jVC7/41Qu0eNULqHjVC7/41Qu/+NULv/jVC7/41Qu/+NULv/ncVL//////////////////////////////////////////////////////////////////////////////////v39/9RfQP/iUy3/41Qu/+NULv/jVC7/41Qu/+NULv/jVC6h41QuX+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/qg2j/+uPd//////////////////////////////////////////////////////////////////nf2P/pfWH/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULl/jVC4S41Qu+ONULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVzL/76CL//308v////////////////////////////////////////////zx7v/umYP/41Yw/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7441QuEgAAAADjVC6k41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/5WJA//S8rf/+/f3///////////////////////78+//ztaX/5F88/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULqMAAAAAAAAAAONULivjVC7841Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+NULv/jVC7/41Qu/+h2WP/4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iXb+0Yl2/tGJdv7NgGz+tkMl/rVCJP61QiT+tkMl9bdDJSQAAAAAAAAAAONULq7iUy3+41Qu/+NULv/ma0v+/vz8///////+/v7+/////////////////v7+/v/////+/v7+///////////+/Pz+wF1D/7ZDJf+1QiT+tkMl/7ZDJa4AAAAA4FMtJeNULvziUy3+41Qu/+NULv/iUy3+6oRp//zv7P/dqZv+uEgr/71WO//sz8f/7M/H/sBeRP+4SCv+2qCR//ju6//OgW3+tkMl/7ZDJf+1QiT+tkMl/7ZDJf22QyUm4lMtfeJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/vjZ0f66TjL+tUIk/rVCJP7RiXb+0Yl2/rVCJP61QiT+uk4y/u/Vz/61QiT+tUIk/rVCJP61QiT+tUIk/rVCJP62QyV+41Quv+NULv/iUy3+41Qu/+NULv/iUy3+41Qu//jZ0f+6TjL+tkMl/7ZDJf/RiXb/0Yl2/rZDJf+1QiT+uk4y/+/Vz/+1QiT+tkMl/7ZDJf+1QiT+tkMl/7ZDJf+2QyXA41Qu6eNULv/iUy3+41Qu/+NULv/iUy3+41Qu//jZ0f+6TjL+tkMl/7ZDJf/RiXb/0Yl2/rZDJf+1QiT+uk4y/+/Vz/+1QiT+tkMl/7ZDJf+1QiT+tkMl/7hDJf/UTivp41Qu/eNULv/iUy3+41Qu/+NULv/iUy3+41Qu//jZ0f+6TjL+tkMl/7ZDJf/RiXb/0Yl2/rZDJf+1QiT+uk4y/+/Vz/+1QiT+tkMl/7ZDJf+1QiT+u0Um/9pQLP/iUy394lMt/eJTLf7iUy3+4lMt/uJTLf7iUy3+4lMt/vjZ0f66TjL+tUIk/rVCJP7RiXb+0Yl2/rVCJP61QiT+uk4y/u/Vz/61QiT+tUIk/rVCJP6/Rib+3lIt/uJTLf7iUy3941Qu6eNULv/iUy3+41Qu/+NULv/iUy3+6oBj//vs6P/Wl4b+tkMl/7xSN//oxLr/6MS6/rxTN/+1QiT+1paG//fq5//Ic13+tkMl/8VIKP/hUy3+41Qu/+NULv/iUy3p4lMtv+JTLf7iUy3+4lMt/uJTLf7lZkT+/vr5/v7+/v78+fj+8+Hc/vXm4v7+/v7+/v7+/vXm4v7y39r+/Pj3/v7+/v789/b+0FY2/uJTLf7iUy3+4lMt/uJTLf7i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' - } - - TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) -end) - -- Create Blips Citizen.CreateThread(function() - local blip = AddBlipForCoord(Config.Zones.BankActions.Pos.x, Config.Zones.BankActions.Pos.y, Config.Zones.BankActions.Pos.z) + local blip = AddBlipForCoord(Config.Zones.BankActions.Coords) - SetBlipSprite (blip, 108) - SetBlipDisplay(blip, 4) - SetBlipScale (blip, 1.0) - SetBlipColour (blip, 30) + SetBlipSprite(blip, 108) + SetBlipColour(blip, 30) SetBlipAsShortRange(blip, true) BeginTextCommandSetBlipName('STRING') - AddTextComponentString(_U('bank')) + AddTextComponentSubstringPlayerName(_U('bank')) EndTextCommandSetBlipName(blip) end) --- Display markers +-- Draw marker & activate menu when player is inside marker Citizen.CreateThread(function() while true do Citizen.Wait(0) - local coords = GetEntityCoords(PlayerPedId()) - - for k,v in pairs(Config.Zones) do - if(ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'banker' and v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then - DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) - end - end - end -end) - --- Activate menu when player is inside marker -Citizen.CreateThread(function() - while true do - Citizen.Wait(100) - - if(ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'banker') then - local coords = GetEntityCoords(PlayerPedId()) - local isInMarker = false - local currentZone = nil + if ESX.PlayerData.job and ESX.PlayerData.job.name == 'banker' then + local playerCoords = GetEntityCoords(PlayerPedId()) + local isInMarker, letSleep, currentZone = false, true for k,v in pairs(Config.Zones) do - if GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x then - isInMarker = true - currentZone = k + local distance = #(playerCoords - v.Coords) + + if v.Type ~= -1 and distance < Config.DrawDistance then + letSleep = false + DrawMarker(v.Type, v.Coords, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, nil, nil, false) + end + + if distance < v.Size.x then + isInMarker, currentZone, letSleep = true, k, false end end if isInMarker and not hasAlreadyEnteredMarker then - hasAlreadyEnteredMarker = true - lastZone = currentZone + hasAlreadyEnteredMarker, lastZone = true, currentZone TriggerEvent('esx_bankerjob:hasEnteredMarker', currentZone) end @@ -252,8 +202,13 @@ Citizen.CreateThread(function() hasAlreadyEnteredMarker = false TriggerEvent('esx_bankerjob:hasExitedMarker', lastZone) end - end + if letSleep then + Citizen.Wait(500) + end + else + Citizen.Wait(500) + end end end) @@ -262,10 +217,10 @@ Citizen.CreateThread(function() while true do Citizen.Wait(0) - if CurrentAction ~= nil then + if CurrentAction then ESX.ShowHelpNotification(CurrentActionMsg) - if IsControlJustReleased(0, Keys['E']) and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'banker' then + if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == 'banker' then if CurrentAction == 'bank_actions_menu' then OpenBankActionsMenu() end @@ -277,3 +232,14 @@ Citizen.CreateThread(function() end end end) + +RegisterNetEvent('esx_phone:loaded') +AddEventHandler('esx_phone:loaded', function (phoneNumber, contacts) + local specialContact = { + name = _U('phone_label'), + number = 'banker', + base64Icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAMAAAD04JH5AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAJUO2JUS4JkW7Jka+L0y5M0+7O1e9J0fBKEjEKEnHKUrJKUvMKk3PK07SK0/VLFHaLVLeLVPgLlTjOl7kO1/lQFu/RmDBTmbEU2vHXHLIR2jmSGnnVHPoVXToaX7NYX7pYn/qbIHPd4rReYzTbojre5PtfZTuhZbWh5jYiJ7vkqHblqnwl6rxoK3fpLXzsb/1u8Xovsr2ydHty9X419zy5Oj25ur88vT78vT88/X9////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATuU7PwAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNv1OCegAAAUoSURBVHhe5ZvrdtQ2FEZjoCmFltsQ2gYCA4VA06GUhktK3v+5ppK8bUu2jnTk26zV7l+JbH1nR7Y0QglH+zHstpsBb7hWSLHAjnpxttylp0zgKXWSXHCzjgKBxxRQcE4XBVqBc6LV0C+LTqDgh+/Y0TmNRoDAcjRPIi8w6qdvyI9CTiAy4csgRyQjQMoUHhMlkBSYNPodpMVJCdB/OqlBkAXO6D0LZEYQBeg5F+L6LAnQbz7OCO4jCNBrVojuERUoXvh1kB4SE1ioftwgIjDr6x9CBZ+hwGI/v4UaHgOBRetHDAYC3LgYlGnpC3DbcvSX5Z4Ady1Jb+McCnDPslALAoEFJ6AP1WoCAW5YHMo5fAEuL4//GngCM+1/NFDR4glwcRUoaegEuFTEp+vr6298XUS3P2kFRuy/X5rylvd8XwJVPQEu6Dn5Rn3Dc9r0PKVsK1D8BtrR7yh/DtRtBWjWckHhjr+5oobCCNCo5BlFQ95yVUldeJTAVyoOOOEGFXws1gIlb8AHqsX4yj0qXGUEaFLQTD2JgilZTwQnoN6G+VNP4iX35ukEaMgSTj0J9ZQsFRhOPYlP9MjRCKhewfjUk9BNyUaAb5OIU0/iGR1T2EMsncBfpJagmZK1QPb8NTf1JD7QX6YW4BuJE+LGkJuSGgHd1JP4hxQJK5A+f1esPGkeEBTHCvClADHjOb5HUpQVBE6rH4iKsYJAVVU3yIpwlhV4Tg58NnnwhCbLFW0WmuCjayMswv4o/Q5agvfQ5TmuaHHQZvhIi+MJjdUjsgbsj/LbccJqCDQElWgzvKPFcUpjVUmTYX/EFwn8legX8izeEPxGk+UzbYZLmix3SeuhEbC4PKJ8CppvERWyokB8MuxWFIhOhu2qAtVD4jrO1hWohuvyygLVHQJb1haobpLYsLpA/1U8gEC4Lh9CIFiXDyJQ/USs4TAC1W1yDybQrssrr4Q+dfD54QTqybDuh1GP+yZ4zY/jIWZd3h+9oUQamzi/gNmkZHfFYBMXEKiq/73Aq0ML2H+aqc7pbeJSAqohsIn/RYFfDy1QH9FcUCSFTVxMQDMENnF+ge8OLWBqOwHFYblNXE5AMQQ2cXaB77UC3hGJ/y/+L7QZvtBkuaTN4J/cRLCla4G0QXBU2Z1Q/EGL4x2NVXVKi6M+IZJwpRUC70lz0NcQVGoPg6pjWhwvaIziKiOQOKl6O+ms9PKYahFcZQTkISBoPOIgvK4rIyDORGImQL0BdeFGQBwCUiZAvT6/U7gRkN4CUsbjz1Af6rYC0hBMPq4X3kKqegKSATlj+ZOCfSjqC0i/vBvzC6uGq259CKGmoROQp+I9es2H2Qk1eAKywSP6zQYFLb5A4jeoN+g5D9Rz+ALyEGw2d+g7B6yBNYFAyuABvadjN2IdoUByf0r/yVALQoH0H/TdImEaVGroCaQewmbzIxlToE5LXyBt8JCU8TSfQS0DgbTB1BfhFUU6hgIZg9tEjcJbARsiAhmD+4SN4GcK+MQEMgajF+bh+BuiAhmDkQvz4P1zxAVyf1hzl8wSSO4jCOQObsoXZnIHSALZx0CuknD995EFcgYlC3Pw+ReSEMg9Bv1GibwoKYGZ5mNk9fFIC+TOjzTzkSSJjEDu76yyGyVSZLICmeeQno/xtSdAIZBZlqgVQVFeKZB+EMJ8pGcOpYCBchEiGyV3/qRCL5A4ROhtlORlL0KJgIWSfShtSM/6IaUCltjW2W2Uoh/4GcYI1Oy2rcj2XPe/rIfs9/8CuOBqaLBm2ZcAAAAASUVORK5CYII=' + } + + TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) +end) \ No newline at end of file diff --git a/config.lua b/config.lua index 391f8ce5..d692b0aa 100644 --- a/config.lua +++ b/config.lua @@ -4,12 +4,10 @@ Config.BankSavingPercentage = 2.5 Config.Locale = 'fr' Config.Zones = { - BankActions = { - Pos = { x = 260.130, y = 204.308, z = 109.287 }, - Size = { x = 1.5, y = 1.5, z = 1.0 }, - Color = { r = 102, g = 102, b = 204 }, - Type = 1 + Coords = vector3(260.1, 204.3, 109.2), + Size = {x = 1.5, y = 1.5, z = 1.0}, + Color = {r = 102, g = 102, b = 204}, + Type = 1 } - } diff --git a/locales/br.lua b/locales/br.lua index 46b7e208..d712da29 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,21 +1,18 @@ Locales['br'] = { - ['actions'] = 'Ações', - ['amount'] = 'Quantidade', - ['balance'] = 'Saldo', - ['bank'] = 'Banco', - ['bill_amount'] = 'Montante de dinheiro', - ['billing'] = 'Faturamento', - ['customer'] = 'Cliente', - ['customers'] = 'Clientes', - ['deposit'] = 'Depositar', - ['deposit_amount'] = 'Quantidade para depositar', - ['deposit_society_money'] = 'Depositar dinheiro da sociedade', - ['invalid_amount'] = 'Quantidade inválida', - ['no_player_nearby'] = 'Nenhum jogador nas proximidades', - ['press_input_context_to_open_menu'] = 'Pressione ~INPUT_CONTEXT~ para abrir o menu', - ['property'] = 'Propriedade', - ['wash_money'] = 'Lavagem de dinheiro', - ['withdraw'] = 'Sacar', - ['withdraw_amount'] = 'Quantidade para sacar', - ['withdraw_society_money'] = 'Sacar dinheiro da sociedade', + ['actions'] = 'ações', + ['amount'] = 'quantidade', + ['balance'] = 'saldo', + ['bank'] = 'banco', + ['bill_amount'] = 'montante de dinheiro', + ['billing'] = 'faturamento', + ['customer'] = 'cliente', + ['customers'] = 'clientes', + ['deposit'] = 'depositar', + ['invalid_amount'] = 'quantidade inválida', + ['no_player_nearby'] = 'nenhum jogador nas proximidades', + ['press_input_context_to_open_menu'] = 'pressione ~INPUT_CONTEXT~ para abrir o menu', + ['withdraw'] = 'sacar', + ['boss_actions'] = 'boss Actions', + ['phone_receive'] = 'bank Customer', + ['phone_label'] = 'bank', } diff --git a/locales/de.lua b/locales/de.lua index bbd6e9b4..900975f0 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -8,15 +8,11 @@ Locales['de'] = { ['customer'] = 'Kunde', ['customers'] = 'Client', ['deposit'] = 'einzahlen', - ['deposit_amount'] = 'Einzahlungsbetrag', - ['deposit_society_money'] = 'Geld in Firma einzahlen', ['invalid_amount'] = 'ungültiger Betrag', ['no_player_nearby'] = 'kein Spieler in der Nähe', ['press_input_context_to_open_menu'] = 'Drücke ~INPUT_CONTEXT~ um das Menü zu öffnen', - ['property'] = 'Immobilie', - ['wash_money'] = 'Geld waschen', ['withdraw'] = 'Abheben', - ['withdraw_amount'] = 'Abhebebetrag', - ['withdraw_society_money'] = 'Firmengeld abheben', - ['bank_customer'] = 'Bankkunde', + ['boss_actions'] = 'boss Actions', + ['phone_receive'] = 'Bankkunde', + ['phone_label'] = 'bank', } diff --git a/locales/en.lua b/locales/en.lua index 82a3a550..0cd40693 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -8,16 +8,11 @@ Locales['en'] = { ['customer'] = 'customer', ['customers'] = 'clients', ['deposit'] = 'deposit', - ['deposit_amount'] = 'deposit amount', - ['deposit_society_money'] = 'deposit society money', ['invalid_amount'] = 'invalid amount', ['no_player_nearby'] = 'no player nearby', - ['press_input_context_to_open_menu'] = 'press ~INPUT_CONTEXT~ to open menu', - ['property'] = 'property', - ['wash_money'] = 'wash money', + ['press_input_context_to_open_menu'] = 'press ~INPUT_CONTEXT~ to open the ~g~Bank Menu~s~.', ['withdraw'] = 'withdraw', - ['withdraw_amount'] = 'withdraw amount', - ['withdraw_society_money'] = 'withdraw society money', - ['bank_customer'] = 'bank Customer', ['boss_actions'] = 'boss Actions', + ['phone_receive'] = 'bank Customer', + ['phone_label'] = 'bank', } diff --git a/locales/fi.lua b/locales/fi.lua index 3d00bc97..2865bcb2 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -8,16 +8,11 @@ Locales['fi'] = { ['customer'] = 'asiakas', ['customers'] = 'asiakkaat', ['deposit'] = 'talletus', - ['deposit_amount'] = 'talletus summa', - ['deposit_society_money'] = 'talleta yhteiskunta rahaa', ['invalid_amount'] = 'virheellinen määrä', ['no_player_nearby'] = 'ei pelaajia lähettyvillä', ['press_input_context_to_open_menu'] = 'Paina ~INPUT_CONTEXT~ avataksesi valikon', - ['property'] = 'kiinteistö', - ['wash_money'] = 'pese rahaa', ['withdraw'] = 'nosta', - ['withdraw_amount'] = 'noston määrä', - ['withdraw_society_money'] = 'nosta yhteiskunnan rahaa', - ['bank_customer'] = 'pankin asiakas', ['boss_actions'] = 'pomo valinnat', + ['phone_receive'] = 'pankin asiakas', + ['phone_label'] = 'bank', } diff --git a/locales/fr.lua b/locales/fr.lua index e8f70c34..864c9ff4 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -8,16 +8,11 @@ Locales['fr'] = { ['customer'] = 'client', ['customers'] = 'clients', ['deposit'] = 'virement', - ['deposit_amount'] = 'montant du dépôt', - ['deposit_society_money'] = 'déposer argent société', ['invalid_amount'] = 'montant invalide', ['no_player_nearby'] = 'aucun joueur à proximité', ['press_input_context_to_open_menu'] = 'appuyez sur ~INPUT_CONTEXT~ pour ouvrir le menu', - ['property'] = 'propriété', - ['wash_money'] = 'blanchir argent', ['withdraw'] = 'retrait', - ['withdraw_amount'] = 'montant du retrait', - ['withdraw_society_money'] = 'retirer argent société', - ['bank_customer'] = 'client Banque', ['boss_actions'] = 'action Patron', + ['phone_receive'] = 'client Banque', + ['phone_label'] = 'banque', } diff --git a/locales/sv.lua b/locales/sv.lua new file mode 100644 index 00000000..eaef4ade --- /dev/null +++ b/locales/sv.lua @@ -0,0 +1,18 @@ +Locales['sv'] = { + ['actions'] = 'handling', + ['amount'] = 'belopp', + ['balance'] = 'balans', + ['bank'] = 'bank', + ['bill_amount'] = 'räkning belopp', + ['billing'] = 'räkning', + ['customer'] = 'kund', + ['customers'] = 'kunder', + ['deposit'] = 'insättning', + ['invalid_amount'] = 'ogiltig belopp', + ['no_player_nearby'] = 'det hittades inga spelare i närheten.', + ['press_input_context_to_open_menu'] = 'tryck ~INPUT_CONTEXT~ för att öppna ~g~bankmenyn~s~.', + ['withdraw'] = 'ta ut', + ['boss_actions'] = 'chef handlingar', + ['phone_receive'] = 'bank meddelande mottaget', + ['phone_label'] = 'bank', +} diff --git a/localization/sv_esx_bankerjob.sql b/localization/sv_esx_bankerjob.sql new file mode 100644 index 00000000..81105ea6 --- /dev/null +++ b/localization/sv_esx_bankerjob.sql @@ -0,0 +1,18 @@ +USE `essentialmode`; + +INSERT INTO `addon_account` (name, label, shared) VALUES + ('society_banker','Bank',1), + ('bank_savings','Bank',0) +; + +INSERT INTO `jobs` (name, label) VALUES + ('banker','Banktjänsteman') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('banker',0,'advisor','Rådgivare',10,'{}','{}'), + ('banker',1,'banker','Banktjänsteman',20,'{}','{}'), + ('banker',2,'business_banker','Företagstjänsteman',30,'{}','{}'), + ('banker',3,'trader','Köpman',40,'{}','{}'), + ('banker',4,'boss','VD',0,'{}','{}') +; diff --git a/server/main.lua b/server/main.lua index faeff15c..96f5130e 100644 --- a/server/main.lua +++ b/server/main.lua @@ -2,8 +2,8 @@ ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) -TriggerEvent('esx_phone:registerNumber', 'banker', _('bank_customer'), false, false) -TriggerEvent('esx_society:registerSociety', 'banker', 'Banquier', 'society_banker', 'society_banker', 'society_banker', {type = 'public'}) +TriggerEvent('esx_phone:registerNumber', 'banker', _('phone_receive'), false, false) +TriggerEvent('esx_society:registerSociety', 'banker', _U('phone_label'), 'society_banker', 'society_banker', 'society_banker', {type = 'public'}) RegisterServerEvent('esx_bankerjob:customerDeposit') AddEventHandler('esx_bankerjob:customerDeposit', function (target, amount) @@ -43,7 +43,7 @@ ESX.RegisterServerCallback('esx_bankerjob:getCustomers', function (source, cb) local xPlayers = ESX.GetPlayers() local customers = {} - for i=1, #xPlayers, 1 do + for i=1, #xPlayers do local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) TriggerEvent('esx_addonaccount:getAccount', 'bank_savings', xPlayer.identifier, function(account) @@ -81,12 +81,11 @@ function CalculateBankSavings(d, h, m) else local interests = math.floor(result[i].money / 100 * Config.BankSavingPercentage) local newMoney = result[i].money + interests - bankInterests = bankInterests + interests + bankInterests = bankInterests + interests 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.Async.execute('UPDATE addon_account_data SET money = @money WHERE owner = @owner AND account_name = @account_name', { ['@money'] = newMoney, ['@owner'] = owner, ['@account_name'] = 'bank_savings', @@ -107,7 +106,6 @@ function CalculateBankSavings(d, h, m) Async.parallelLimit(asyncTasks, 5, function(results) print('[BANK] Calculated interests') end) - end) end From 77a7080e38c01274aa1fd76bc3d891759eb17659 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 8 Jun 2019 13:11:28 +0200 Subject: [PATCH 2234/3224] Implemented unregisterStatus and fixed restarting script midgame --- client/classes/status.lua | 2 +- client/main.lua | 20 ++++++++++++++++++-- server/main.lua | 38 +++++++++++++++++++++++++++----------- 3 files changed, 46 insertions(+), 14 deletions(-) diff --git a/client/classes/status.lua b/client/classes/status.lua index c478a98d..b71f6889 100644 --- a/client/classes/status.lua +++ b/client/classes/status.lua @@ -1,5 +1,5 @@ function CreateStatus(name, default, color, visible, tickCallback) - + local self = {} self.val = default diff --git a/client/main.lua b/client/main.lua index 3376614b..c97b61db 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,5 +1,12 @@ -local Status = {} -local isPaused = false +ESX = nil +local Status, isPaused = {}, false + +Citizen.CreateThread(function() + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end +end) function GetStatusData(minimal) local status = {} @@ -31,6 +38,15 @@ AddEventHandler('esx_status:registerStatus', function(name, default, color, visi table.insert(Status, status) end) +AddEventHandler('esx_status:unregisterStatus', function(name) + for k,v in ipairs(Status) do + if v.name == name then + table.remove(Status, k) + break + end + end +end) + RegisterNetEvent('esx_status:load') AddEventHandler('esx_status:load', function(status) for i=1, #Status, 1 do diff --git a/server/main.lua b/server/main.lua index ab6b18c5..246800dc 100644 --- a/server/main.lua +++ b/server/main.lua @@ -2,28 +2,45 @@ ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) -AddEventHandler('esx:playerLoaded', function(source) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) +Citizen.CreateThread(function() + Citizen.Wait(1000) + local players = ESX.GetPlayers() - MySQL.Async.fetchAll('SELECT status FROM users WHERE identifier = @identifier', { + for _,playerId in ipairs(players) do + local xPlayer = ESX.GetPlayerFromId(playerId) + + 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) + TriggerClientEvent('esx_status:load', playerId, data) + 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 ~= nil then + if result[1].status then data = json.decode(result[1].status) end xPlayer.set('status', data) - TriggerClientEvent('esx_status:load', _source, data) + TriggerClientEvent('esx_status:load', playerId, data) end) end) -AddEventHandler('esx:playerDropped', function(source) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) - local data = {} +AddEventHandler('esx:playerDropped', function(playerId, reason) + local xPlayer = ESX.GetPlayerFromId(playerId) local status = xPlayer.get('status') MySQL.Async.execute('UPDATE users SET status = @status WHERE identifier = @identifier', { @@ -58,7 +75,6 @@ function SaveData() for i=1, #xPlayers, 1 do local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) - local data = {} local status = xPlayer.get('status') MySQL.Async.execute('UPDATE users SET status = @status WHERE identifier = @identifier', { From 954572c93406be752779153434911f8e13573df8 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 8 Jun 2019 22:24:20 +0200 Subject: [PATCH 2235/3224] Minor changes, removed keys table --- client/functions.lua | 26 ++---------- client/main.lua | 97 +++++++++++++++----------------------------- 2 files changed, 36 insertions(+), 87 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index a8e3c3d1..f7fc4107 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -298,11 +298,7 @@ ESX.Game.SpawnObject = function(model, coords, cb) local model = (type(model) == 'number' and model or GetHashKey(model)) Citizen.CreateThread(function() - RequestModel(model) - - while not HasModelLoaded(model) do - Citizen.Wait(0) - end + ESX.Streaming.RequestModel(model) local obj = CreateObject(model, coords.x, coords.y, coords.z, true, false, true) @@ -316,11 +312,7 @@ ESX.Game.SpawnLocalObject = function(model, coords, cb) local model = (type(model) == 'number' and model or GetHashKey(model)) Citizen.CreateThread(function() - RequestModel(model) - - while not HasModelLoaded(model) do - Citizen.Wait(0) - end + ESX.Streaming.RequestModel(model) local obj = CreateObject(model, coords.x, coords.y, coords.z, false, false, true) @@ -344,11 +336,7 @@ ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) Citizen.CreateThread(function() - RequestModel(model) - - while not HasModelLoaded(model) do - Citizen.Wait(0) - end + ESX.Streaming.RequestModel(model) local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, true, false) local id = NetworkGetNetworkIdFromEntity(vehicle) @@ -378,11 +366,7 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) Citizen.CreateThread(function() - RequestModel(model) - - while not HasModelLoaded(model) do - Citizen.Wait(0) - end + ESX.Streaming.RequestModel(model) local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, false, false) @@ -390,7 +374,6 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetVehicleNeedsToBeHotwired(vehicle, false) SetModelAsNoLongerNeeded(model) - RequestCollisionAtCoord(coords.x, coords.y, coords.z) while not HasCollisionLoadedAroundEntity(vehicle) do @@ -1012,7 +995,6 @@ ESX.Game.Utils.DrawText3D = function(coords, text, size) SetTextFont(0) SetTextColour(255, 255, 255, 255) SetTextDropshadow(0, 0, 0, 0, 255) - SetTextEdge(2, 0, 0, 0, 150) SetTextDropShadow() SetTextOutline() SetTextEntry('STRING') diff --git a/client/main.lua b/client/main.lua index fbb010c0..d7bb1f43 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,29 +1,13 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} -local LoadoutLoaded = false -local IsPaused = false -local PlayerSpawned = false -local LastLoadout = {} -local Pickups = {} -local isDead = false +local isLoadoutLoaded, isPaused, isPlayerSpawned, isDead = false, false, false, false +local lastLoadout, pickups = {}, {} RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) ESX.PlayerLoaded = true - ESX.PlayerData = xPlayer + ESX.PlayerData = xPlayer if Config.EnableHud then - for i=1, #xPlayer.accounts, 1 do local accountTpl = '
     {{money}}
    ' @@ -51,7 +35,6 @@ AddEventHandler('esx:playerLoaded', function(xPlayer) job_label = xPlayer.job.label, grade_label = xPlayer.job.grade_label }) - else TriggerEvent('es:setMoneyDisplay', 0.0) end @@ -65,14 +48,14 @@ AddEventHandler('playerSpawned', function() local playerPed = PlayerPedId() -- Restore position - if ESX.PlayerData.lastPosition ~= nil then + if ESX.PlayerData.lastPosition then SetEntityCoords(playerPed, ESX.PlayerData.lastPosition.x, ESX.PlayerData.lastPosition.y, ESX.PlayerData.lastPosition.z) end TriggerEvent('esx:restoreLoadout') -- restore loadout - LoadoutLoaded = true - PlayerSpawned = true + isLoadoutLoaded = true + isPlayerSpawned = true isDead = false end) @@ -81,7 +64,7 @@ AddEventHandler('esx:onPlayerDeath', function() end) AddEventHandler('skinchanger:loadDefaultModel', function() - LoadoutLoaded = false + isLoadoutLoaded = false end) AddEventHandler('skinchanger:modelLoaded', function() @@ -118,7 +101,7 @@ AddEventHandler('esx:restoreLoadout', function() end end - LoadoutLoaded = true + isLoadoutLoaded = true end) RegisterNetEvent('esx:setAccountMoney') @@ -334,7 +317,7 @@ AddEventHandler('esx:pickup', function(id, label, player) SetEntityAsMissionEntity(obj, true, false) PlaceObjectOnGroundProperly(obj) - Pickups[id] = { + pickups[id] = { id = id, obj = obj, label = label, @@ -350,8 +333,8 @@ end) RegisterNetEvent('esx:removePickup') AddEventHandler('esx:removePickup', function(id) - ESX.Game.DeleteObject(Pickups[id].obj) - Pickups[id] = nil + ESX.Game.DeleteObject(pickups[id].obj) + pickups[id] = nil end) RegisterNetEvent('esx:pickupWeapon') @@ -402,12 +385,12 @@ if Config.EnableHud then while true do Citizen.Wait(300) - if IsPauseMenuActive() and not IsPaused then - IsPaused = true + if IsPauseMenuActive() and not isPaused then + isPaused = true TriggerEvent('es:setMoneyDisplay', 0.0) ESX.UI.HUD.SetDisplay(0.0) - elseif not IsPauseMenuActive() and IsPaused then - IsPaused = false + elseif not IsPauseMenuActive() and isPaused then + isPaused = false TriggerEvent('es:setMoneyDisplay', 1.0) ESX.UI.HUD.SetDisplay(1.0) end @@ -418,7 +401,6 @@ end -- Save loadout Citizen.CreateThread(function() while true do - Citizen.Wait(5000) local playerPed = PlayerPedId() @@ -426,11 +408,10 @@ Citizen.CreateThread(function() local loadoutChanged = false if IsPedDeadOrDying(playerPed) then - LoadoutLoaded = false + isLoadoutLoaded = false end - for i=1, #Config.Weapons, 1 do - + for i=1, #Config.Weapons do local weaponName = Config.Weapons[i].name local weaponHash = GetHashKey(weaponName) local weaponComponents = {} @@ -439,17 +420,17 @@ Citizen.CreateThread(function() local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) local components = Config.Weapons[i].components - for j=1, #components, 1 do + for j=1, #components do if HasPedGotWeaponComponent(playerPed, weaponHash, components[j].hash) then table.insert(weaponComponents, components[j].name) end end - if LastLoadout[weaponName] == nil or LastLoadout[weaponName] ~= ammo then + if not lastLoadout[weaponName] or lastLoadout[weaponName] ~= ammo then loadoutChanged = true end - LastLoadout[weaponName] = ammo + lastLoadout[weaponName] = ammo table.insert(loadout, { name = weaponName, @@ -458,42 +439,36 @@ Citizen.CreateThread(function() components = weaponComponents }) else - if LastLoadout[weaponName] ~= nil then + if lastLoadout[weaponName] then loadoutChanged = true end - LastLoadout[weaponName] = nil + lastLoadout[weaponName] = nil end - end - if loadoutChanged and LoadoutLoaded then + if loadoutChanged and isLoadoutLoaded then ESX.PlayerData.loadout = loadout TriggerServerEvent('esx:updateLoadout', loadout) end - end end) -- Menu interactions Citizen.CreateThread(function() while true do - Citizen.Wait(0) - if IsControlJustReleased(0, Keys['F2']) and IsInputDisabled(0) and not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then + if IsControlJustReleased(0, 289) and IsInputDisabled(0) and not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then ESX.ShowInventory() end - end end) -- Dot above head if Config.ShowDotAbovePlayer then - Citizen.CreateThread(function() while true do - Citizen.Wait(1) local players = ESX.Game.GetPlayers() @@ -503,15 +478,12 @@ if Config.ShowDotAbovePlayer then local headId = CreateMpGamerTag(ped, ('·'), false, false, '', false) end end - end end) - end -- Disable wanted level if Config.DisableWantedLevel then - Citizen.CreateThread(function() while true do Citizen.Wait(0) @@ -523,25 +495,22 @@ if Config.DisableWantedLevel then end end end) - end --- Pickups +-- pickups Citizen.CreateThread(function() while true do - Citizen.Wait(0) local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) + local coords = GetEntityCoords(playerPed) -- if there's no nearby pickups we can wait a bit to save performance - if next(Pickups) == nil then + if next(pickups) == nil then Citizen.Wait(500) end - for k,v in pairs(Pickups) do - + for k,v in pairs(pickups) do local distance = GetDistanceBetweenCoords(coords, v.coords.x, v.coords.y, v.coords.z, true) local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() @@ -553,14 +522,12 @@ Citizen.CreateThread(function() }, v.label) end - if (closestDistance == -1 or closestDistance > 3) and distance <= 1.0 and not v.inRange and not IsPedSittingInAnyVehicle(playerPed) then + if (closestDistance == -1 or closestDistance > 3) and distance <= 1.0 and not v.inRange and IsPedOnFoot(playerPed) then TriggerServerEvent('esx:onPickup', v.id) PlaySoundFrontend(-1, 'PICK_UP', 'HUD_FRONTEND_DEFAULT_SOUNDSET', false) v.inRange = true end - end - end end) @@ -569,7 +536,7 @@ Citizen.CreateThread(function() while true do Citizen.Wait(1000) - if ESX.PlayerLoaded and PlayerSpawned then + if ESX.PlayerLoaded and isPlayerSpawned then local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) @@ -585,8 +552,8 @@ Citizen.CreateThread(function() Citizen.Wait(1000) local playerPed = PlayerPedId() - if IsEntityDead(playerPed) and PlayerSpawned then - PlayerSpawned = false + if IsEntityDead(playerPed) and isPlayerSpawned then + isPlayerSpawned = false end end end) From 2c5f4e1ba60a833cb74bdc474f146719e3fcf8eb Mon Sep 17 00:00:00 2001 From: depp <50743267+Zeedfy@users.noreply.github.com> Date: Fri, 14 Jun 2019 17:20:59 +0700 Subject: [PATCH 2236/3224] Update main.lua --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index e6ede08b..e1d55c6b 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,6 +1,6 @@ ESX = nil -local base64MoneyIcon = 'iVBORw0KGgoAAAANSUhEUgAAAFoAAABaCAMAAAAPdrEwAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAMAUExURQAAACmvPCmwPCuwPiywPi2wPy6xQC6xQS+yQTCxQTCyQTCyQjGyQzKyRDOzRTSzRTSzRjW0RjW0Rza0SDe0STi0STm1Sjq1Szq2Szu2TDy2TDy2TT22Tj63Tz+3UEC4UEG4UUG4UkK4U0O5VES5VEW6VUa6Vke6V0i7WEm7WUu8Wku8W0y8W028XE29XU++XlC9X1C+X1G+YFK+YVO/YlW/ZFXAZFfAZVfAZljBZlnBZ1rBaVvCaVvCalzDal7CbF/DbV/EbWHEbmLEb2LEcGTFcWfGdGjHdWrHd2vId2vIeGzIeW3JenHKfXLKfnPLf3TLgHXLgXXMgHXMgXbMgnjNg3nMhHrNhnrOhnzOiH7PiYLQjYPRjoTRjoTRj4XRkIXSkIfSkojSk4rUlYzUlo7VmJDWmpHWm5LXnJTXnZTXnpXYnpbYn5nZopzapJ3bpZ7bpp7bp6DcqKLcqqPcq6Tcq6TdrKberqjfr6jfsKnfsavgs6zgs6zgtK7hta/htrDit7LiuLLiubPjurTjurXju7bkvLbkvbnlv7rlwLrmwLzmwr3nw77nxMDnxcLox8PpyMTpycXpysXqysbqy8fqzMnrzcrrz8vsz8vs0Mzs0c3t0tHu1dHu1tPv19Tv2NXv2dXw2dbw2tfw29jw3Nnx3drx3t7z4d/z4uD04+H05OP15eP15uT15uT15+X16OX26Of26en36+r37Ov37er47Ov47ez47e347u347+758PD58fD68fD68vL69PT79fX79vb79/b89vb89/f8+Pj9+fn9+vr9+/v++/v+/Pz+/P3+/f3+/v7//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALfZHJgAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjb9TgnoAAAGdUlEQVRoQ7WZ93sURRiAFZO76O1eklt215OgBwqJgmgCRhAhRrAAiogBK4gBJEFEgWAEYiGIYEGp1kjXQECkiF0OWyjJ/k34zcy3db7Zu8fHe3/KTXnzPbPT56orRTEYAhMLUFgNKkeiGH8BNaV1KWSPVXveU9s3LW9pvhdoblm+afspTHZi5Wo1BnzpaOfcnFmWSBv29YBtpBNlZm5u59FLPDsmdJUaxQeXNugZw5IwMnrD0oO8iFKuUHNx/+bGZLWNMgm7Otm4uZ/LsVIEUs3F+Y5a3USNAlOv7cgr5ZSamQffyOnKgH1sPdfFi2PVILKaReEcmKwVIWbY2uQDvApW95HULIb+Ng0rFoXWxppcCjyqZuZjk4oNWWBrk44R7oiamXdkC3w9GTO7Q3aH1cy8OkWFnHtitstM4j/bqdWSO6Rm5nYdS4e5FbKQwxlMC6G3Q1bIHVQz8+IKLBphJLdydlRjWpiKxZAXdAfUPOak4gOO4FZOdxWmhbGTkbh9NTOvoVsDuGmAaxkdlZgWRV8Dub7bV0PyzhQWkqk5z7WMdjpqILUTslEXUEPQJ7Lq7pz9WXiBZ4iZUGBnTwTCdtVgvjgxpj+b3vTvTEteq5KbEy/6blcNVZapR3cmdc9Z4QV6Pnxzdr1GF9aWQQFUohqCPqQc3ZV17X3C6tP31kyL+Jy2dsgLW6jBPDgVc6OkR3XxCV/i9IqRRFedylxc6qk30L3DNF7ikz1Jft0oLOaT2hBSg/l8jmwOo24/amimYzkfOwfdlLtdNT1YjIaf0EFzgGhuNnB8teNcqCWDvs3vzSSLqC9Ze0F0EqaGoDeSQWt7UaHgXA0WDKFvFGEzNRS6mxot6VZhUNJNdm7zbsgSagj6UAKTQ5hnhEHJffRISIi+LdRLyNn9cTSoOExP3FZmiat2nIF66t9Xb0GFz8Df+AenVTEF2vUwAzM1BN1LfsTkcVS4bJs+fnRj84z3joqf+eFYUELvZWFzdSfZHjeeEwqXl6/myWaZ0bSVDf3uJP9NkOn01HPISXIMTJAB/hiB6WBPN+xxBpvxl4wxR6ihll8pSL1QupwLLhR22YL9ysVGrKRcfZJeAu4QSo+1yWA3rla2NGCeZGpoj13lmBJm1F/odDm+fv68phorU0l+miDlu6BFmLqbHDCWdhqVQQb/zPesW1inqxdoRqIb1SvSmBJG+wR1BF+/NkmLWUnTK1DdQq+i5gvoIbn85QPqtdRoQfU0TIgy4h/UKOi+gZ5DgGmonqIoob2CDhXHblE0ij2lgNo2YMcSy7fkhF2E2rIm/IoOFV/Q+78i1JkJheJ+jOzjnlr1GRk18swa4iC9t3U/o6LzCVLTP4dlVM14LBfC63yKIYOYeuMqcRoneZFqEW/IKAY6Q8xumla3YP2+PNnNt1Jqb6Arpifg5kXuHjNTaVi1s5/eJs0r+6gFUkxP6kkV2mKBs8UMZSYMdmAJcpxqTTGpqpcCEO1znCMTwlPFNbuF0uUs1UVwKYAWoRcwGDHsbNS/algwu+J1bvToI9TuAgZqetm1roPVk/FDazbhjaryr0SiSw/R1oFll94sWNnfsLrzS1eTkawyjKrE6HcwyeVtIix3s6Dc4ljzsTbnx74P1na83+uf8ZBn5cb0tjgsbHJjlvoMa8dxWT4XBDZmoCa3k7eH9yE0u4l9jr+dZN2P2ASnVorK8TwoVwxsglnYxNY9852oHMseogMEt+4QtnzgGDoTa8eRH4ulA4QOHCxs6ZhUBdNAIS7NIjp1+JgEaulwZzwsnXCjDDxPzB+Rwx1zS0fSoVZb/Mp4/lFqQxk5kjI1cZDWa179HTUEe8eRW9XoQZq5qeN/5fCFigWmd14VNRXLx3/et8lLC7N8XNtH0VP6mXfvV+z4iEsLFrbqqkXXho2Z8dynwgo8NdZK0SXpqxbmjrsgquhCsXrhgOYgL4h4k8Rca5VvFV7gTkySUVxrsbBjLuOGfMy1jCZFa6gv47hbeYU4ZA/XMmbRy13MFaJwqy4+Ez1cy3iSVsddfGLcdJvo33Ato5VcSeOva4WbvmQ2v+daxkrqfqXQJbNwk1fj9kOPuNwlZxdxNS7c5IW+MdRFMhd3oS/cpXmG4EOnRI8nAAt8sKsETz4AK1yahyqAy0vxvAaU7lEQcJ8yj9BPmUf+81MmR8iB//kBllOyZ2NOqR67XUAVABNjuXLlX2rCcoFjOcGoAAAAAElFTkSuQmCC' +local base64MoneyIcon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAABaCAMAAAAPdrEwAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAMAUExURQAAACmvPCmwPCuwPiywPi2wPy6xQC6xQS+yQTCxQTCyQTCyQjGyQzKyRDOzRTSzRTSzRjW0RjW0Rza0SDe0STi0STm1Sjq1Szq2Szu2TDy2TDy2TT22Tj63Tz+3UEC4UEG4UUG4UkK4U0O5VES5VEW6VUa6Vke6V0i7WEm7WUu8Wku8W0y8W028XE29XU++XlC9X1C+X1G+YFK+YVO/YlW/ZFXAZFfAZVfAZljBZlnBZ1rBaVvCaVvCalzDal7CbF/DbV/EbWHEbmLEb2LEcGTFcWfGdGjHdWrHd2vId2vIeGzIeW3JenHKfXLKfnPLf3TLgHXLgXXMgHXMgXbMgnjNg3nMhHrNhnrOhnzOiH7PiYLQjYPRjoTRjoTRj4XRkIXSkIfSkojSk4rUlYzUlo7VmJDWmpHWm5LXnJTXnZTXnpXYnpbYn5nZopzapJ3bpZ7bpp7bp6DcqKLcqqPcq6Tcq6TdrKberqjfr6jfsKnfsavgs6zgs6zgtK7hta/htrDit7LiuLLiubPjurTjurXju7bkvLbkvbnlv7rlwLrmwLzmwr3nw77nxMDnxcLox8PpyMTpycXpysXqysbqy8fqzMnrzcrrz8vsz8vs0Mzs0c3t0tHu1dHu1tPv19Tv2NXv2dXw2dbw2tfw29jw3Nnx3drx3t7z4d/z4uD04+H05OP15eP15uT15uT15+X16OX26Of26en36+r37Ov37er47Ov47ez47e347u347+758PD58fD68fD68vL69PT79fX79vb79/b89vb89/f8+Pj9+fn9+vr9+/v++/v+/Pz+/P3+/f3+/v7//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALfZHJgAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjb9TgnoAAAGdUlEQVRoQ7WZ93sURRiAFZO76O1eklt215OgBwqJgmgCRhAhRrAAiogBK4gBJEFEgWAEYiGIYEGp1kjXQECkiF0OWyjJ/k34zcy3db7Zu8fHe3/KTXnzPbPT56orRTEYAhMLUFgNKkeiGH8BNaV1KWSPVXveU9s3LW9pvhdoblm+afspTHZi5Wo1BnzpaOfcnFmWSBv29YBtpBNlZm5u59FLPDsmdJUaxQeXNugZw5IwMnrD0oO8iFKuUHNx/+bGZLWNMgm7Otm4uZ/LsVIEUs3F+Y5a3USNAlOv7cgr5ZSamQffyOnKgH1sPdfFi2PVILKaReEcmKwVIWbY2uQDvApW95HULIb+Ng0rFoXWxppcCjyqZuZjk4oNWWBrk44R7oiamXdkC3w9GTO7Q3aH1cy8OkWFnHtitstM4j/bqdWSO6Rm5nYdS4e5FbKQwxlMC6G3Q1bIHVQz8+IKLBphJLdydlRjWpiKxZAXdAfUPOak4gOO4FZOdxWmhbGTkbh9NTOvoVsDuGmAaxkdlZgWRV8Dub7bV0PyzhQWkqk5z7WMdjpqILUTslEXUEPQJ7Lq7pz9WXiBZ4iZUGBnTwTCdtVgvjgxpj+b3vTvTEteq5KbEy/6blcNVZapR3cmdc9Z4QV6Pnxzdr1GF9aWQQFUohqCPqQc3ZV17X3C6tP31kyL+Jy2dsgLW6jBPDgVc6OkR3XxCV/i9IqRRFedylxc6qk30L3DNF7ikz1Jft0oLOaT2hBSg/l8jmwOo24/amimYzkfOwfdlLtdNT1YjIaf0EFzgGhuNnB8teNcqCWDvs3vzSSLqC9Ze0F0EqaGoDeSQWt7UaHgXA0WDKFvFGEzNRS6mxot6VZhUNJNdm7zbsgSagj6UAKTQ5hnhEHJffRISIi+LdRLyNn9cTSoOExP3FZmiat2nIF66t9Xb0GFz8Df+AenVTEF2vUwAzM1BN1LfsTkcVS4bJs+fnRj84z3joqf+eFYUELvZWFzdSfZHjeeEwqXl6/myWaZ0bSVDf3uJP9NkOn01HPISXIMTJAB/hiB6WBPN+xxBpvxl4wxR6ihll8pSL1QupwLLhR22YL9ysVGrKRcfZJeAu4QSo+1yWA3rla2NGCeZGpoj13lmBJm1F/odDm+fv68phorU0l+miDlu6BFmLqbHDCWdhqVQQb/zPesW1inqxdoRqIb1SvSmBJG+wR1BF+/NkmLWUnTK1DdQq+i5gvoIbn85QPqtdRoQfU0TIgy4h/UKOi+gZ5DgGmonqIoob2CDhXHblE0ij2lgNo2YMcSy7fkhF2E2rIm/IoOFV/Q+78i1JkJheJ+jOzjnlr1GRk18swa4iC9t3U/o6LzCVLTP4dlVM14LBfC63yKIYOYeuMqcRoneZFqEW/IKAY6Q8xumla3YP2+PNnNt1Jqb6Arpifg5kXuHjNTaVi1s5/eJs0r+6gFUkxP6kkV2mKBs8UMZSYMdmAJcpxqTTGpqpcCEO1znCMTwlPFNbuF0uUs1UVwKYAWoRcwGDHsbNS/algwu+J1bvToI9TuAgZqetm1roPVk/FDazbhjaryr0SiSw/R1oFll94sWNnfsLrzS1eTkawyjKrE6HcwyeVtIix3s6Dc4ljzsTbnx74P1na83+uf8ZBn5cb0tjgsbHJjlvoMa8dxWT4XBDZmoCa3k7eH9yE0u4l9jr+dZN2P2ASnVorK8TwoVwxsglnYxNY9852oHMseogMEt+4QtnzgGDoTa8eRH4ulA4QOHCxs6ZhUBdNAIS7NIjp1+JgEaulwZzwsnXCjDDxPzB+Rwx1zS0fSoVZb/Mp4/lFqQxk5kjI1cZDWa179HTUEe8eRW9XoQZq5qeN/5fCFigWmd14VNRXLx3/et8lLC7N8XNtH0VP6mXfvV+z4iEsLFrbqqkXXho2Z8dynwgo8NdZK0SXpqxbmjrsgquhCsXrhgOYgL4h4k8Rca5VvFV7gTkySUVxrsbBjLuOGfMy1jCZFa6gv47hbeYU4ZA/XMmbRy13MFaJwqy4+Ez1cy3iSVsddfGLcdJvo33Ato5VcSeOva4WbvmQ2v+daxkrqfqXQJbNwk1fj9kOPuNwlZxdxNS7c5IW+MdRFMhd3oS/cpXmG4EOnRI8nAAt8sKsETz4AK1yahyqAy0vxvAaU7lEQcJ8yj9BPmUf+81MmR8iB//kBllOyZ2NOqR67XUAVABNjuXLlX2rCcoFjOcGoAAAAAElFTkSuQmCC' Citizen.CreateThread(function() while ESX == nil do From 01787edb2f28c2a5591312f06ed36c696a2ed0a2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 16 Jun 2019 13:07:33 +0200 Subject: [PATCH 2237/3224] Minor cleanup --- client/main.lua | 48 +++++++++++++++--------------------------------- config.lua | 1 + server/main.lua | 10 ++++------ 3 files changed, 20 insertions(+), 39 deletions(-) diff --git a/client/main.lua b/client/main.lua index f89fb1aa..c2189568 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,24 +1,6 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - -ESX = nil -local FirstSpawn = true -local LastSkin = nil -local PlayerLoaded = false -local cam = nil -local isCameraActive = false -local zoomOffset = 0.0 -local camOffset = 0.0 -local heading = 90.0 +ESX = nil +local lastSkin, playerLoaded, cam, isCameraActive +local firstSpawn, zoomOffset, camOffset, heading = true, 0.0, 0.0, 90.0 Citizen.CreateThread(function() while ESX == nil do @@ -31,7 +13,7 @@ function OpenMenu(submitCb, cancelCb, restrict) local playerPed = PlayerPedId() TriggerEvent('skinchanger:getSkin', function(skin) - LastSkin = skin + lastSkin = skin end) TriggerEvent('skinchanger:getData', function(components, maxVals) @@ -99,7 +81,7 @@ function OpenMenu(submitCb, cancelCb, restrict) elements = elements }, function(data, menu) TriggerEvent('skinchanger:getSkin', function(skin) - LastSkin = skin + lastSkin = skin end) submitCb(data, menu) @@ -107,7 +89,7 @@ function OpenMenu(submitCb, cancelCb, restrict) end, function(data, menu) menu.close() DeleteSkinCam() - TriggerEvent('skinchanger:loadSkin', LastSkin) + TriggerEvent('skinchanger:loadSkin', lastSkin) if cancelCb ~= nil then cancelCb(data, menu) @@ -235,7 +217,7 @@ Citizen.CreateThread(function() Citizen.Wait(0) if isCameraActive then - if IsControlPressed(0, Keys['N4']) then + if IsControlPressed(0, 108) then angle = angle - 1 elseif IsControlPressed(0, 109) then angle = angle + 1 @@ -256,7 +238,7 @@ end) function OpenSaveableMenu(submitCb, cancelCb, restrict) TriggerEvent('skinchanger:getSkin', function(skin) - LastSkin = skin + lastSkin = skin end) OpenMenu(function(data, menu) @@ -276,11 +258,11 @@ end AddEventHandler('playerSpawned', function() Citizen.CreateThread(function() - while not PlayerLoaded do - Citizen.Wait(10) + while not playerLoaded do + Citizen.Wait(100) end - if FirstSpawn then + if firstSpawn then ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) if skin == nil then TriggerEvent('skinchanger:loadSkin', {sex = 0}, OpenSaveableMenu) @@ -289,22 +271,22 @@ AddEventHandler('playerSpawned', function() end end) - FirstSpawn = false + firstSpawn = false end end) end) RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) - PlayerLoaded = true + playerLoaded = true end) AddEventHandler('esx_skin:getLastSkin', function(cb) - cb(LastSkin) + cb(lastSkin) end) AddEventHandler('esx_skin:setLastSkin', function(skin) - LastSkin = skin + lastSkin = skin end) RegisterNetEvent('esx_skin:openMenu') diff --git a/config.lua b/config.lua index 56a8b5e9..1875b978 100644 --- a/config.lua +++ b/config.lua @@ -1,2 +1,3 @@ Config = {} + Config.Locale = 'fr' diff --git a/server/main.lua b/server/main.lua index 7141a161..b2dc4b12 100644 --- a/server/main.lua +++ b/server/main.lua @@ -6,9 +6,8 @@ RegisterServerEvent('esx_skin:save') AddEventHandler('esx_skin:save', function(skin) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.execute('UPDATE users SET `skin` = @skin WHERE identifier = @identifier', - { - ['@skin'] = json.encode(skin), + MySQL.Async.execute('UPDATE users SET skin = @skin WHERE identifier = @identifier', { + ['@skin'] = json.encode(skin), ['@identifier'] = xPlayer.identifier }) end) @@ -38,15 +37,14 @@ ESX.RegisterServerCallback('esx_skin:getPlayerSkin', function(source, cb) MySQL.Async.fetchAll('SELECT skin FROM users WHERE identifier = @identifier', { ['@identifier'] = xPlayer.identifier }, function(users) - local user = users[1] - local skin = nil + local user, skin = users[1] local jobSkin = { skin_male = xPlayer.job.skin_male, skin_female = xPlayer.job.skin_female } - if user.skin ~= nil then + if user.skin then skin = json.decode(user.skin) end From 4778307d7f60d1ff4322ae6cc5dc72cea1635304 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 6 Jul 2019 13:57:13 +0200 Subject: [PATCH 2238/3224] Fixed #315, use loading prompt instead of drawing text --- client/main.lua | 45 +++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/client/main.lua b/client/main.lua index 93bb1eff..67bac8ab 100644 --- a/client/main.lua +++ b/client/main.lua @@ -277,8 +277,8 @@ function OpenVehicleSpawnerMenu(type, station, part, partNum) shopCoords = Config.PoliceStations[station].Vehicles[partNum].InsideShop local authorizedVehicles = Config.AuthorizedVehicles[PlayerData.job.grade_name] - if #Config.AuthorizedVehicles['Shared'] > 0 then - for k,vehicle in ipairs(Config.AuthorizedVehicles['Shared']) do + if #Config.AuthorizedVehicles.Shared > 0 then + for k,vehicle in ipairs(Config.AuthorizedVehicles.Shared) do table.insert(shopElements, { label = ('%s - %s'):format(vehicle.label, _U('shop_item', ESX.Math.GroupDigits(vehicle.price))), name = vehicle.label, @@ -300,7 +300,7 @@ function OpenVehicleSpawnerMenu(type, station, part, partNum) }) end else - if #Config.AuthorizedVehicles['Shared'] == 0 then + if #Config.AuthorizedVehicles.Shared == 0 then return end end @@ -413,10 +413,15 @@ function StoreNearbyVehicle(playerCoords) IsBusy = true Citizen.CreateThread(function() + BeginTextCommandBusyString('STRING') + AddTextComponentSubstringPlayerName(_U('garage_storing')) + EndTextCommandBusyString(4) + while IsBusy do - Citizen.Wait(0) - drawLoadingText(_U('garage_storing'), 255, 255, 255, 255) + Citizen.Wait(100) end + + RemoveLoadingPrompt() end) -- Workaround for vehicle not deleting when other players are near it. @@ -522,12 +527,13 @@ function OpenShopMenu(elements, restoreCoords, shopCoords) ESX.Game.Teleport(playerPed, restoreCoords) end, function(data, menu) DeleteSpawnedVehicles() - WaitForVehicleToLoad(data.current.model) + ESX.Game.SpawnLocalVehicle(data.current.model, shopCoords, 0.0, function(vehicle) table.insert(spawnedVehicles, vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) FreezeEntityPosition(vehicle, true) + SetModelAsNoLongerNeeded(data.current.model) if data.current.livery then SetVehicleModKit(vehicle, 0) @@ -541,10 +547,11 @@ function OpenShopMenu(elements, restoreCoords, shopCoords) table.insert(spawnedVehicles, vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) FreezeEntityPosition(vehicle, true) + SetModelAsNoLongerNeeded(elements[1].model) if elements[1].livery then SetVehicleModKit(vehicle, 0) - SetVehicleLivery(vehicle,elements[1].livery) + SetVehicleLivery(vehicle, elements[1].livery) end end) end @@ -576,29 +583,19 @@ function WaitForVehicleToLoad(modelHash) if not HasModelLoaded(modelHash) then RequestModel(modelHash) + BeginTextCommandBusyString('STRING') + AddTextComponentSubstringPlayerName(_U('vehicleshop_awaiting_model')) + EndTextCommandBusyString(4) + while not HasModelLoaded(modelHash) do Citizen.Wait(0) DisableAllControlActions(0) - - drawLoadingText(_U('vehicleshop_awaiting_model'), 255, 255, 255, 255) end + + RemoveLoadingPrompt() end end -function drawLoadingText(text, red, green, blue, alpha) - SetTextFont(4) - SetTextScale(0.0, 0.5) - SetTextColour(red, green, blue, alpha) - SetTextDropshadow(0, 0, 0, 0, 255) - SetTextDropShadow() - SetTextOutline() - SetTextCentre(true) - - BeginTextCommandDisplayText('STRING') - AddTextComponentSubstringPlayerName(text) - EndTextCommandDisplayText(0.5, 0.5) -end - function OpenPoliceActionsMenu() ESX.UI.Menu.CloseAll() @@ -1642,7 +1639,7 @@ Citizen.CreateThread(function() SetBlipColour (blip, v.Blip.Colour) SetBlipAsShortRange(blip, true) - BeginTextCommandSetBlipName("STRING") + BeginTextCommandSetBlipName('STRING') AddTextComponentString(_U('map_blip')) EndTextCommandSetBlipName(blip) end From 8a6f3d9e2fa8488780c0056193645323642a5236 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 6 Jul 2019 14:00:27 +0200 Subject: [PATCH 2239/3224] Fixed #331 --- client/main.lua | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/client/main.lua b/client/main.lua index 67bac8ab..99314b7d 100644 --- a/client/main.lua +++ b/client/main.lua @@ -977,8 +977,8 @@ function LookupVehicle() end function ShowPlayerLicense(player) - local elements = {} - local targetName + local elements, targetName = {} + ESX.TriggerServerCallback('esx_policejob:getOtherPlayerData', function(data) if data.licenses then for i=1, #data.licenses, 1 do @@ -997,8 +997,7 @@ function ShowPlayerLicense(player) targetName = data.name end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'manage_license', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'manage_license', { title = _U('license_revoke'), align = 'top-left', elements = elements, @@ -1025,7 +1024,7 @@ function OpenUnpaidBillsMenu(player) for k,bill in ipairs(bills) do table.insert(elements, { label = ('%s - %s'):format(bill.label, _U('armory_item', ESX.Math.GroupDigits(bill.amount))), - billId = bills[i].id + billId = bill.id }) end From dd436587ae60445cdcc75cba845c85bcfb37ab52 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 16 Jul 2019 11:07:28 +0200 Subject: [PATCH 2240/3224] Performance improvments, enforce 2 space indent, vector3 coords --- __resource.lua | 2 +- client/main.lua | 162 ++++++++++++++++++------------------------------ config.lua | 41 +++++------- locales/br.lua | 20 +++--- locales/de.lua | 20 +++--- locales/en.lua | 20 +++--- locales/es.lua | 20 +++--- locales/fi.lua | 20 +++--- locales/fr.lua | 20 +++--- locales/pl.lua | 20 +++--- locales/sv.lua | 20 +++--- server/main.lua | 3 +- 12 files changed, 158 insertions(+), 210 deletions(-) diff --git a/__resource.lua b/__resource.lua index 3fd222de..7a772331 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,6 +1,6 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' -description 'ESX ClotheShop' +description 'ESX Clothes Shop' version '1.1.0' diff --git a/client/main.lua b/client/main.lua index 95df9283..689e81cb 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,22 +1,7 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} -ESX = nil -local HasAlreadyEnteredMarker = false -local LastZone = nil -local CurrentAction = nil -local CurrentActionMsg = '' -local CurrentActionData = {} -local HasPaid = false +local hasAlreadyEnteredMarker, hasPaid, currentActionData = false, false, {} +local lastZone, currentAction, currentActionMsg +ESX = nil Citizen.CreateThread(function() while ESX == nil do @@ -26,20 +11,18 @@ Citizen.CreateThread(function() end) function OpenShopMenu() - HasPaid = false + hasPaid = false TriggerEvent('esx_skin:openRestrictedMenu', function(data, menu) menu.close() - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'shop_confirm', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'shop_confirm', { title = _U('valid_this_purchase'), align = 'top-left', elements = { {label = _U('no'), value = 'no'}, {label = _U('yes'), value = 'yes'} - } - }, function(data, menu) + }}, function(data, menu) menu.close() if data.current.value == 'yes' then @@ -49,19 +32,17 @@ function OpenShopMenu() TriggerServerEvent('esx_skin:save', skin) end) - HasPaid = true + hasPaid = true ESX.TriggerServerCallback('esx_clotheshop:checkPropertyDataStore', function(foundStore) if foundStore then - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'save_dressing', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'save_dressing', { title = _U('save_in_dressing'), align = 'top-left', elements = { {label = _U('no'), value = 'no'}, {label = _U('yes'), value = 'yes'} - } - }, function(data2, menu2) + }}, function(data2, menu2) menu2.close() if data2.current.value == 'yes' then @@ -72,9 +53,8 @@ function OpenShopMenu() TriggerEvent('skinchanger:getSkin', function(skin) TriggerServerEvent('esx_clotheshop:saveOutfit', data3.value, skin) + ESX.ShowNotification(_U('saved_outfit')) end) - - ESX.ShowNotification(_U('saved_outfit')) end, function(data3, menu3) menu3.close() end) @@ -97,56 +77,47 @@ function OpenShopMenu() end) end - CurrentAction = 'shop_menu' - CurrentActionMsg = _U('press_menu') - CurrentActionData = {} + currentAction = 'shop_menu' + currentActionMsg = _U('press_menu') + currentActionData = {} end, function(data, menu) menu.close() - CurrentAction = 'shop_menu' - CurrentActionMsg = _U('press_menu') - CurrentActionData = {} + currentAction = 'shop_menu' + currentActionMsg = _U('press_menu') + currentActionData = {} end) end, function(data, menu) menu.close() - CurrentAction = 'shop_menu' - CurrentActionMsg = _U('press_menu') - CurrentActionData = {} + currentAction = 'shop_menu' + currentActionMsg = _U('press_menu') + currentActionData = {} end, { - 'tshirt_1', - 'tshirt_2', - 'torso_1', - 'torso_2', - 'decals_1', - 'decals_2', + 'tshirt_1', 'tshirt_2', + 'torso_1', 'torso_2', + 'decals_1', 'decals_2', 'arms', - 'pants_1', - 'pants_2', - 'shoes_1', - 'shoes_2', - 'chain_1', - 'chain_2', - 'helmet_1', - 'helmet_2', - 'glasses_1', - 'glasses_2' + 'pants_1', 'pants_2', + 'shoes_1', 'shoes_2', + 'chain_1', 'chain_2', + 'helmet_1', 'helmet_2', + 'glasses_1', 'glasses_2' }) - end AddEventHandler('esx_clotheshop:hasEnteredMarker', function(zone) - CurrentAction = 'shop_menu' - CurrentActionMsg = _U('press_menu') - CurrentActionData = {} + currentAction = 'shop_menu' + currentActionMsg = _U('press_menu') + currentActionData = {} end) AddEventHandler('esx_clotheshop:hasExitedMarker', function(zone) ESX.UI.Menu.CloseAll() - CurrentAction = nil + currentAction = nil - if not HasPaid then + if not hasPaid then TriggerEvent('esx_skin:getLastSkin', function(skin) TriggerEvent('skinchanger:loadSkin', skin) end) @@ -155,61 +126,50 @@ end) -- Create Blips Citizen.CreateThread(function() - for i=1, #Config.Shops, 1 do - local blip = AddBlipForCoord(Config.Shops[i].x, Config.Shops[i].y, Config.Shops[i].z) + for k,v in ipairs(Config.Shops) do + local blip = AddBlipForCoord(v) SetBlipSprite (blip, 73) - SetBlipDisplay(blip, 4) - SetBlipScale (blip, 1.0) SetBlipColour (blip, 47) SetBlipAsShortRange(blip, true) - BeginTextCommandSetBlipName("STRING") - AddTextComponentString(_U('clothes')) + BeginTextCommandSetBlipName('STRING') + AddTextComponentSubstringPlayerName(_U('clothes')) EndTextCommandSetBlipName(blip) end end) --- Display markers +-- Enter / Exit marker events & draw markers Citizen.CreateThread(function() while true do - Citizen.Wait(1) + Citizen.Wait(0) + local playerCoords, isInMarker, currentZone, letSleep = GetEntityCoords(PlayerPedId()), false, nil, true - local coords = GetEntityCoords(PlayerPedId()) + for k,v in pairs(Config.Shops) do + local distance = #(playerCoords - v) - for k,v in pairs(Config.Zones) do - if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then - DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) - end - end - end -end) + if distance < Config.DrawDistance then + letSleep = false + DrawMarker(Config.MarkerType, v, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Config.MarkerSize.x, Config.MarkerSize.y, Config.MarkerSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, nil, nil, false) --- Enter / Exit marker events -Citizen.CreateThread(function() - while true do - Citizen.Wait(100) - - local coords = GetEntityCoords(PlayerPedId()) - local isInMarker = false - local currentZone = nil - - for k,v in pairs(Config.Zones) do - if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then - isInMarker = true - currentZone = k + if distance < Config.MarkerSize.x then + isInMarker, currentZone = true, k + end end end - if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then - HasAlreadyEnteredMarker = true - LastZone = currentZone + if (isInMarker and not hasAlreadyEnteredMarker) or (isInMarker and lastZone ~= currentZone) then + hasAlreadyEnteredMarker, lastZone = true, currentZone TriggerEvent('esx_clotheshop:hasEnteredMarker', currentZone) end - if not isInMarker and HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = false - TriggerEvent('esx_clotheshop:hasExitedMarker', LastZone) + if not isInMarker and hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = false + TriggerEvent('esx_clotheshop:hasExitedMarker', lastZone) + end + + if letSleep then + Citizen.Wait(500) end end end) @@ -219,15 +179,15 @@ Citizen.CreateThread(function() while true do Citizen.Wait(0) - if CurrentAction ~= nil then - ESX.ShowHelpNotification(CurrentActionMsg) + if currentAction then + ESX.ShowHelpNotification(currentActionMsg) - if IsControlJustReleased(0, Keys['E']) then - if CurrentAction == 'shop_menu' then + if IsControlJustReleased(0, 38) then + if currentAction == 'shop_menu' then OpenShopMenu() end - CurrentAction = nil + currentAction = nil end else Citizen.Wait(500) diff --git a/config.lua b/config.lua index 9a8daa48..46f870b4 100644 --- a/config.lua +++ b/config.lua @@ -8,30 +8,19 @@ Config.MarkerSize = {x = 1.5, y = 1.5, z = 1.0} Config.MarkerColor = {r = 102, g = 102, b = 204} Config.MarkerType = 1 -Config.Zones = {} - Config.Shops = { - {x=72.254, y=-1399.102, z=28.376}, - {x=-703.776, y=-152.258, z=36.415}, - {x=-167.863, y=-298.969, z=38.733}, - {x=428.694, y=-800.106, z=28.491}, - {x=-829.413, y=-1073.710, z=10.328}, - {x=-1447.797, y=-242.461, z=48.820}, - {x=11.632, y=6514.224, z=30.877}, - {x=123.646, y=-219.440, z=53.557}, - {x=1696.291, y=4829.312, z=41.063}, - {x=618.093, y=2759.629, z=41.088}, - {x=1190.550, y=2713.441, z=37.222}, - {x=-1193.429, y=-772.262, z=16.324}, - {x=-3172.496, y=1048.133, z=19.863}, - {x=-1108.441, y=2708.923, z=18.107} -} - -for i=1, #Config.Shops, 1 do - Config.Zones['Shop_' .. i] = { - Pos = Config.Shops[i], - Size = Config.MarkerSize, - Color = Config.MarkerColor, - Type = Config.MarkerType - } -end + vector3(72.3, -1399.1, 28.4), + vector3(-703.8, -152.3, 36.4), + vector3(-167.9, -299.0, 38.7), + vector3(428.7, -800.1, 28.5), + vector3(-829.4, -1073.7, 10.3), + vector3(-1447.8, -242.5, 48.8), + vector3(11.6, 6514.2, 30.9), + vector3(123.6, -219.4, 53.6), + vector3(1696.3, 4829.3, 41.1), + vector3(618.1, 2759.6, 41.1), + vector3(1190.6, 2713.4, 37.2), + vector3(-1193.4, -772.3, 16.3), + vector3(-3172.5, 1048.1, 19.9), + vector3(-1108.4, 2708.9, 18.1) +} \ No newline at end of file diff --git a/locales/br.lua b/locales/br.lua index ec49be27..fbdfd24c 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,12 +1,12 @@ Locales['br'] = { - ['valid_this_purchase'] = 'validar esta compra?', - ['yes'] = 'sim', - ['no'] = 'não', - ['not_enough_money'] = 'você não tem dinheiro suficiente', - ['press_menu'] = 'pressione ~INPUT_CONTEXT~ para acessar o menu', - ['clothes'] = 'roupas', - ['you_paid'] = 'você pagou ~g~$%s~s~', - ['save_in_dressing'] = 'você quer salvar essa roupa?', - ['name_outfit'] = 'nome da roupa?', - ['saved_outfit'] = 'roupa salva', + ['valid_this_purchase'] = 'validar esta compra?', + ['yes'] = 'sim', + ['no'] = 'não', + ['not_enough_money'] = 'você não tem dinheiro suficiente', + ['press_menu'] = 'pressione ~INPUT_CONTEXT~ para acessar o menu', + ['clothes'] = 'roupas', + ['you_paid'] = 'você pagou ~g~$%s~s~', + ['save_in_dressing'] = 'você quer salvar essa roupa?', + ['name_outfit'] = 'nome da roupa?', + ['saved_outfit'] = 'roupa salva', } \ No newline at end of file diff --git a/locales/de.lua b/locales/de.lua index 6e93f504..df63afd1 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -1,12 +1,12 @@ Locales['de'] = { - ['valid_this_purchase'] = 'einkauf bestätigen?', - ['yes'] = 'ja', - ['no'] = 'nein', - ['not_enough_money'] = 'du hast nicht genug Geld', - ['press_menu'] = 'drücke ~INPUT_CONTEXT~ um das Menü zu öffnen', - ['clothes'] = 'kleidung', - ['you_paid'] = 'du bezahlst ~g~$%s~s~', - ['save_in_dressing'] = 'do you want to save the outfit in your property?', - ['name_outfit'] = 'name des outfits?', - ['saved_outfit'] = 'the outfit has been saved!', + ['valid_this_purchase'] = 'einkauf bestätigen?', + ['yes'] = 'ja', + ['no'] = 'nein', + ['not_enough_money'] = 'du hast nicht genug Geld', + ['press_menu'] = 'drücke ~INPUT_CONTEXT~ um das Menü zu öffnen', + ['clothes'] = 'kleidung', + ['you_paid'] = 'du bezahlst ~g~$%s~s~', + ['save_in_dressing'] = 'do you want to save the outfit in your property?', + ['name_outfit'] = 'name des outfits?', + ['saved_outfit'] = 'the outfit has been saved!', } \ No newline at end of file diff --git a/locales/en.lua b/locales/en.lua index 7f8ea521..3d2e481a 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,12 +1,12 @@ Locales['en'] = { - ['valid_this_purchase'] = 'validate this purchase?', - ['yes'] = 'yes', - ['no'] = 'no', - ['not_enough_money'] = 'you do not have enough money', - ['press_menu'] = 'press ~INPUT_CONTEXT~ to access the menu', - ['clothes'] = 'clothes', - ['you_paid'] = 'you paid ~g~$%s~s~', - ['save_in_dressing'] = 'do you want to save the outfit in your property?', - ['name_outfit'] = 'name your outfit', - ['saved_outfit'] = 'the outfit has been saved!', + ['valid_this_purchase'] = 'validate this purchase?', + ['yes'] = 'yes', + ['no'] = 'no', + ['not_enough_money'] = 'you do not have enough money', + ['press_menu'] = 'press ~INPUT_CONTEXT~ to access the ~y~Clothing Shop~s~.', + ['clothes'] = 'clothing Shop', + ['you_paid'] = 'you paid ~g~$%s~s~', + ['save_in_dressing'] = 'do you want to save the outfit in your property?', + ['name_outfit'] = 'name your outfit', + ['saved_outfit'] = 'the outfit has been saved!', } \ No newline at end of file diff --git a/locales/es.lua b/locales/es.lua index c4f84700..959fb5f8 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -1,12 +1,12 @@ Locales['es'] = { - ['valid_this_purchase'] = '¿Validar esta compra?', - ['yes'] = 'Si', - ['no'] = 'No', - ['not_enough_money'] = 'No tienes suficiente dinero', - ['press_menu'] = 'Presiona ~INPUT_CONTEXT~ para acceder al menú', - ['clothes'] = 'Ropa', - ['you_paid'] = 'Has pagado ~g~€%s~s~', - ['save_in_dressing'] = '¿Quieres darle un nombre a tu vestuario?', - ['name_outfit'] = 'nombre del traje?', - ['saved_outfit'] = 'the outfit has been saved!', + ['valid_this_purchase'] = '¿Validar esta compra?', + ['yes'] = 'Si', + ['no'] = 'No', + ['not_enough_money'] = 'No tienes suficiente dinero', + ['press_menu'] = 'Presiona ~INPUT_CONTEXT~ para acceder al menú', + ['clothes'] = 'Ropa', + ['you_paid'] = 'Has pagado ~g~€%s~s~', + ['save_in_dressing'] = '¿Quieres darle un nombre a tu vestuario?', + ['name_outfit'] = 'nombre del traje?', + ['saved_outfit'] = 'the outfit has been saved!', } \ No newline at end of file diff --git a/locales/fi.lua b/locales/fi.lua index 27182c28..9dffde05 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -1,12 +1,12 @@ Locales['fi'] = { - ['valid_this_purchase'] = 'varmista tämä ostos?', - ['yes'] = 'kyllä', - ['no'] = 'ei', - ['not_enough_money'] = 'sinulla ei ole tarpeeksi rahaa', - ['press_menu'] = 'paina ~INPUT_CONTEXT~ avataksesi menu', - ['clothes'] = 'vaatekauppa', - ['you_paid'] = 'sinä maksoit ~g~$%s~s~', - ['save_in_dressing'] = 'haluatko antaa nimen asulle ?', - ['name_outfit'] = 'asun nimi?', - ['saved_outfit'] = 'the outfit has been saved!', + ['valid_this_purchase'] = 'varmista tämä ostos?', + ['yes'] = 'kyllä', + ['no'] = 'ei', + ['not_enough_money'] = 'sinulla ei ole tarpeeksi rahaa', + ['press_menu'] = 'paina ~INPUT_CONTEXT~ avataksesi menu', + ['clothes'] = 'vaatekauppa', + ['you_paid'] = 'sinä maksoit ~g~$%s~s~', + ['save_in_dressing'] = 'haluatko antaa nimen asulle ?', + ['name_outfit'] = 'asun nimi?', + ['saved_outfit'] = 'the outfit has been saved!', } \ No newline at end of file diff --git a/locales/fr.lua b/locales/fr.lua index 98fe7a88..8416b758 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,12 +1,12 @@ Locales['fr'] = { - ['valid_this_purchase'] = 'valider cet achat ?', - ['yes'] = 'oui', - ['no'] = 'non', - ['not_enough_money'] = 'vous n\'avez pas assez d\'argent', - ['press_menu'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder au menu', - ['clothes'] = 'vêtements', - ['you_paid'] = 'vous avez payé ~g~$%s~s~', - ['save_in_dressing'] = 'voulez-vous donner un nom à votre tenue?', - ['name_outfit'] = 'nom de la tenue?', - ['saved_outfit'] = 'the outfit has been saved!', + ['valid_this_purchase'] = 'valider cet achat ?', + ['yes'] = 'oui', + ['no'] = 'non', + ['not_enough_money'] = 'vous n\'avez pas assez d\'argent', + ['press_menu'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder au menu', + ['clothes'] = 'vêtements', + ['you_paid'] = 'vous avez payé ~g~$%s~s~', + ['save_in_dressing'] = 'voulez-vous donner un nom à votre tenue?', + ['name_outfit'] = 'nom de la tenue?', + ['saved_outfit'] = 'the outfit has been saved!', } \ No newline at end of file diff --git a/locales/pl.lua b/locales/pl.lua index 56dd513e..acfca072 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -1,12 +1,12 @@ Locales['pl'] = { - ['valid_this_purchase'] = 'potwierdzić ten zakup?', - ['yes'] = 'tak', - ['no'] = 'nie', - ['not_enough_money'] = 'nie masz wystarczająco pieniędzy', - ['press_menu'] = 'naciśnij ~INPUT_CONTEXT~ aby uzyskać dostęp do menu.', - ['clothes'] = 'ubranie', - ['you_paid'] = 'płacisz ~g~%s $~s~', - ['save_in_dressing'] = 'czy chcesz zapisać te ubranie w swojej posiadłości?', - ['name_outfit'] = 'nazwij swój strój', - ['saved_outfit'] = 'strój został zapisany!', + ['valid_this_purchase'] = 'potwierdzić ten zakup?', + ['yes'] = 'tak', + ['no'] = 'nie', + ['not_enough_money'] = 'nie masz wystarczająco pieniędzy', + ['press_menu'] = 'naciśnij ~INPUT_CONTEXT~ aby uzyskać dostęp do menu.', + ['clothes'] = 'ubranie', + ['you_paid'] = 'płacisz ~g~%s $~s~', + ['save_in_dressing'] = 'czy chcesz zapisać te ubranie w swojej posiadłości?', + ['name_outfit'] = 'nazwij swój strój', + ['saved_outfit'] = 'strój został zapisany!', } \ No newline at end of file diff --git a/locales/sv.lua b/locales/sv.lua index 1f5c37d1..63ee2e6d 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -1,12 +1,12 @@ Locales['sv'] = { - ['valid_this_purchase'] = 'vill du köpa dessa kläder?', - ['yes'] = 'ja', - ['no'] = 'nej', - ['not_enough_money'] = 'du har ~r~inte råd~s~ för att köpa detta', - ['press_menu'] = 'tryck ~INPUT_CONTEXT~ för att komma åt menyn', - ['clothes'] = 'kläder', - ['you_paid'] = 'du har betalat ~g~$%s~s~', - ['save_in_dressing'] = 'vill du spara outfiten i din fastighet?', - ['name_outfit'] = 'vad ska din outfit heta?', - ['saved_outfit'] = 'outfit har sparats!', + ['valid_this_purchase'] = 'vill du köpa dessa kläder?', + ['yes'] = 'ja', + ['no'] = 'nej', + ['not_enough_money'] = 'du har ~r~inte råd~s~ för att köpa detta', + ['press_menu'] = 'tryck ~INPUT_CONTEXT~ för att öppna ~y~klädesaffären~s~.', + ['clothes'] = 'klädesaffär', + ['you_paid'] = 'du har betalat ~g~$%s~s~', + ['save_in_dressing'] = 'vill du spara outfiten i din fastighet?', + ['name_outfit'] = 'vad ska din outfit heta?', + ['saved_outfit'] = 'outfit har sparats!', } \ No newline at end of file diff --git a/server/main.lua b/server/main.lua index e3e45da9..b2b476f6 100644 --- a/server/main.lua +++ b/server/main.lua @@ -4,8 +4,7 @@ TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) RegisterServerEvent('esx_clotheshop:saveOutfit') AddEventHandler('esx_clotheshop:saveOutfit', function(label, skin) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) + local xPlayer = ESX.GetPlayerFromId(source) TriggerEvent('esx_datastore:getDataStore', 'property', xPlayer.identifier, function(store) local dressing = store.get('dressing') From d0ac5c8da604b154f39b486a3948f985ef2c58e6 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 16 Jul 2019 11:08:12 +0200 Subject: [PATCH 2241/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 354ec1cd..a7085aab 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ start esx_clotheshop ### License esx_clotheshop - clothing store -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2019 Jérémie N'gadi 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. From 9fa0c12e02efcbec33c018e8c55801dd2c59df08 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 20 Jul 2019 13:09:42 +0200 Subject: [PATCH 2242/3224] =?UTF-8?q?Replaced=20MaxPlayers=20with=20GetAct?= =?UTF-8?q?ivePlayers=20for=20all=20babies=20=F0=9F=91=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/functions.lua | 10 ++++------ config.lua | 1 - 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index f7fc4107..083a4160 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -454,15 +454,13 @@ ESX.Game.GetClosestObject = function(filter, coords) end ESX.Game.GetPlayers = function() - local maxPlayers = Config.MaxPlayers - local players = {} + local players = {} - for i=0, maxPlayers, 1 do - - local ped = GetPlayerPed(i) + for _,player in ipairs(GetActivePlayers()) do + local ped = GetPlayerPed(player) if DoesEntityExist(ped) then - table.insert(players, i) + table.insert(players, player) end end diff --git a/config.lua b/config.lua index 95cd34be..223afade 100644 --- a/config.lua +++ b/config.lua @@ -10,6 +10,5 @@ Config.DisableWantedLevel = true Config.EnableHud = true -- enable the default hud? Display current job and accounts (black, bank & cash) Config.PaycheckInterval = 7 * 60000 -Config.MaxPlayers = GetConvarInt('sv_maxclients', 32) -- set this value to 255 if you're running OneSync Config.EnableDebug = false From 134d24aea1faf448d150e5c5b3b2d3f4c2baae79 Mon Sep 17 00:00:00 2001 From: RikoDEV <18230443+RikoDEV@users.noreply.github.com> Date: Sat, 20 Jul 2019 14:32:40 +0200 Subject: [PATCH 2243/3224] Remove keys table --- client/main.lua | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/client/main.lua b/client/main.lua index a10c2e4a..93a982c4 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,15 +1,3 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - ESX = nil local HasAlreadyEnteredMarker = false local LastZone = nil @@ -238,7 +226,7 @@ Citizen.CreateThread(function() if CurrentAction ~= nil then ESX.ShowHelpNotification(CurrentActionMsg) - if IsControlJustReleased(0, Keys['E']) and CurrentActionData.accessory then + if IsControlJustReleased(0, 38) and CurrentActionData.accessory then OpenShopMenu(CurrentActionData.accessory) CurrentAction = nil end @@ -247,10 +235,10 @@ Citizen.CreateThread(function() end if Config.EnableControls then - if IsControlJustReleased(0, Keys['K']) and IsInputDisabled(0) and not isDead then + if IsControlJustReleased(0, 311) and IsInputDisabled(0) and not isDead then OpenAccessoryMenu() end end end -end) \ No newline at end of file +end) From 63bdd6daef734c9478ca569926c3f33dd657b748 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 20 Jul 2019 14:34:13 +0200 Subject: [PATCH 2244/3224] Removed Show Dot Above Player --- client/main.lua | 17 ----------------- config.lua | 1 - 2 files changed, 18 deletions(-) diff --git a/client/main.lua b/client/main.lua index d7bb1f43..f04422d7 100644 --- a/client/main.lua +++ b/client/main.lua @@ -465,23 +465,6 @@ Citizen.CreateThread(function() end end) --- Dot above head -if Config.ShowDotAbovePlayer then - Citizen.CreateThread(function() - while true do - Citizen.Wait(1) - - local players = ESX.Game.GetPlayers() - for i = 1, #players, 1 do - if players[i] ~= PlayerId() then - local ped = GetPlayerPed(players[i]) - local headId = CreateMpGamerTag(ped, ('·'), false, false, '', false) - end - end - end - end) -end - -- Disable wanted level if Config.DisableWantedLevel then Citizen.CreateThread(function() diff --git a/config.lua b/config.lua index 223afade..453d052a 100644 --- a/config.lua +++ b/config.lua @@ -5,7 +5,6 @@ Config.Accounts = { 'bank', 'black_money' } Config.AccountLabels = { bank = _U('bank'), black_money = _U('black_money') } Config.EnableSocietyPayouts = false -- pay from the society account that the player is employed at? Requirement: esx_society -Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true Config.EnableHud = true -- enable the default hud? Display current job and accounts (black, bank & cash) From b3d26ae02f4cd1bd371f1931d969ca0da26b5a05 Mon Sep 17 00:00:00 2001 From: Lerk Date: Sat, 20 Jul 2019 14:44:55 +0200 Subject: [PATCH 2245/3224] hide "press e to modify" hint when in the menu --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index eb7de0ce..2eed92c9 100644 --- a/client/main.lua +++ b/client/main.lua @@ -390,7 +390,7 @@ Citizen.CreateThread(function() local lastZone = nil if (PlayerData.job ~= nil and PlayerData.job.name == 'mechanic') or Config.IsMechanicJobOnly == false then for k,v in pairs(Config.Zones) do - if GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x then + if GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x and not lsMenuIsShowed then isInLSMarker = true ESX.ShowHelpNotification(v.Hint) break From 8bb102c843a66395be68711cb2f21de4237e1940 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 25 Jul 2019 12:24:02 +0200 Subject: [PATCH 2246/3224] Performance improvements, removed keys table --- client/main.lua | 191 +++++++++++++++++------------------------------- config.lua | 6 +- server/main.lua | 68 ++++++++--------- 3 files changed, 99 insertions(+), 166 deletions(-) diff --git a/client/main.lua b/client/main.lua index 214455fa..43e0ce69 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,21 +1,6 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - -local Instance = {} -local InstanceInvite = nil -local InstancedPlayers = {} -local RegisteredInstanceTypes = {} -local InsideInstance = false -ESX = nil +local instance, instancedPlayers, registeredInstanceTypes = {}, {}, {} +local instanceInvite, insideInstance +ESX = nil Citizen.CreateThread(function() while ESX == nil do @@ -25,7 +10,7 @@ Citizen.CreateThread(function() end) function GetInstance() - return Instance + return instance end function CreateInstance(type, data) @@ -33,43 +18,42 @@ function CreateInstance(type, data) end function CloseInstance() - Instance = {} + instance = {} TriggerServerEvent('instance:close') - InsideInstance = false + insideInstance = false end function EnterInstance(instance) - InsideInstance = true + insideInstance = true TriggerServerEvent('instance:enter', instance.host) - if RegisteredInstanceTypes[instance.type].enter ~= nil then - RegisteredInstanceTypes[instance.type].enter(instance) + if registeredInstanceTypes[instance.type].enter then + registeredInstanceTypes[instance.type].enter(instance) end end function LeaveInstance() - if Instance.host ~= nil then - - if #Instance.players > 1 then + if instance.host then + if #instance.players > 1 then ESX.ShowNotification(_U('left_instance')) end - if RegisteredInstanceTypes[Instance.type].exit ~= nil then - RegisteredInstanceTypes[Instance.type].exit(Instance) + if registeredInstanceTypes[instance.type].exit then + registeredInstanceTypes[instance.type].exit(instance) end - TriggerServerEvent('instance:leave', Instance.host) + TriggerServerEvent('instance:leave', instance.host) end - InsideInstance = false + insideInstance = false end function InviteToInstance(type, player, data) - TriggerServerEvent('instance:invite', Instance.host, type, player, data) + TriggerServerEvent('instance:invite', instance.host, type, player, data) end function RegisterInstanceType(type, enter, exit) - RegisteredInstanceTypes[type] = { + registeredInstanceTypes[type] = { enter = enter, exit = exit } @@ -87,8 +71,8 @@ AddEventHandler('instance:close', function() CloseInstance() end) -AddEventHandler('instance:enter', function(instance) - EnterInstance(instance) +AddEventHandler('instance:enter', function(_instance) + EnterInstance(_instance) end) AddEventHandler('instance:leave', function() @@ -104,157 +88,114 @@ AddEventHandler('instance:registerType', function(name, enter, exit) end) RegisterNetEvent('instance:onInstancedPlayersData') -AddEventHandler('instance:onInstancedPlayersData', function(instancedPlayers) - InstancedPlayers = instancedPlayers +AddEventHandler('instance:onInstancedPlayersData', function(_instancedPlayers) + instancedPlayers = _instancedPlayers end) RegisterNetEvent('instance:onCreate') -AddEventHandler('instance:onCreate', function(instance) - Instance = {} +AddEventHandler('instance:onCreate', function(_instance) + instance = {} end) RegisterNetEvent('instance:onEnter') -AddEventHandler('instance:onEnter', function(instance) - Instance = instance +AddEventHandler('instance:onEnter', function(_instance) + instance = _instance end) RegisterNetEvent('instance:onLeave') -AddEventHandler('instance:onClose', function(instance) - Instance = {} +AddEventHandler('instance:onLeave', function(_instance) + instance = {} end) RegisterNetEvent('instance:onClose') -AddEventHandler('instance:onClose', function(instance) - Instance = {} +AddEventHandler('instance:onClose', function(_instance) + instance = {} end) RegisterNetEvent('instance:onPlayerEntered') -AddEventHandler('instance:onPlayerEntered', function(instance, player) - Instance = instance +AddEventHandler('instance:onPlayerEntered', function(_instance, player) + instance = _instance local playerName = GetPlayerName(GetPlayerFromServerId(player)) ESX.ShowNotification(_('entered_into', playerName)) end) RegisterNetEvent('instance:onPlayerLeft') -AddEventHandler('instance:onPlayerLeft', function(instance, player) - Instance = instance +AddEventHandler('instance:onPlayerLeft', function(_instance, player) + instance = _instance local playerName = GetPlayerName(GetPlayerFromServerId(player)) ESX.ShowNotification(_('left_out', playerName)) end) RegisterNetEvent('instance:onInvite') -AddEventHandler('instance:onInvite', function(instance, type, data) - InstanceInvite = { +AddEventHandler('instance:onInvite', function(_instance, type, data) + instanceInvite = { type = type, - host = instance, + host = _instance, data = data } Citizen.CreateThread(function() Citizen.Wait(10000) - if InstanceInvite ~= nil then + if instanceInvite then ESX.ShowNotification(_U('invite_expired')) - InstanceInvite = nil + instanceInvite = nil end end) end) RegisterInstanceType('default') --- Input invites +-- Controls for invite Citizen.CreateThread(function() while true do Citizen.Wait(0) - if InstanceInvite ~= nil then + if instanceInvite then ESX.ShowHelpNotification(_U('press_to_enter')) + + if IsControlJustReleased(0, 38) then + EnterInstance(instanceInvite) + ESX.ShowNotification(_U('entered_instance')) + instanceInvite = nil + end else Citizen.Wait(500) end - end end) --- Controls -Citizen.CreateThread(function() - while true do - - Citizen.Wait(0) - - if InstanceInvite ~= nil and IsControlJustReleased(0, Keys['E']) then - local playerPed = PlayerPedId() - - EnterInstance(InstanceInvite) - ESX.ShowNotification(_U('entered_instance')) - InstanceInvite = nil - - elseif InstanceInvite == nil then - Citizen.Wait(500) - end - - end - -end) - -- Instance players Citizen.CreateThread(function() while true do + Citizen.Wait(10) + local playerPed = PlayerPedId() + local playersToHide = {} - Citizen.Wait(0) - - if Instance.host ~= nil then - - local playerPed = PlayerPedId() - - for i=0, Config.MaxPlayers, 1 do - - local found = false - for j=1, #Instance.players, 1 do - instancePlayer = GetPlayerFromServerId(Instance.players[j]) - - if i == instancePlayer then - found = true - end - end - - if not found then - local otherPlayerPed = GetPlayerPed(i) - - SetEntityLocallyInvisible(otherPlayerPed) - SetEntityNoCollisionEntity(playerPed, otherPlayerPed, true) - end - + if instance.host then + -- Get players and sets them as pairs + for k,v in ipairs(GetActivePlayers()) do + playersToHide[v] = true end + -- Dont set our instanced players invisible + for _,player in ipairs(instance.players) do + playersToHide[GetPlayerFromServerId(player)] = nil + end else - - local playerPed = PlayerPedId() - - for i=0, Config.MaxPlayers, 1 do - - local found = false - for j=1, #InstancedPlayers, 1 do - instancePlayer = GetPlayerFromServerId(InstancedPlayers[j]) - - if i == instancePlayer then - found = true - end - end - - if found then - local otherPlayerPed = GetPlayerPed(i) - - SetEntityLocallyInvisible(otherPlayerPed) - SetEntityNoCollisionEntity(playerPed, otherPlayerPed, true) - end - + for player,_ in pairs(instancedPlayers) do + playersToHide[GetPlayerFromServerId(player)] = true end - end + -- Hide all these players + for player,_ in pairs(playersToHide) do + local otherPlayerPed = GetPlayerPed(player) + SetEntityVisible(otherPlayerPed, false, false) + SetEntityNoCollisionEntity(playerPed, otherPlayerPed, false) + end end end) @@ -267,7 +208,7 @@ Citizen.CreateThread(function() while true do Citizen.Wait(0) -- must be run every frame - if InsideInstance then + if insideInstance then SetVehicleDensityMultiplierThisFrame(0.0) SetParkedVehicleDensityMultiplierThisFrame(0.0) diff --git a/config.lua b/config.lua index 4a13c6bf..ef4f22f6 100644 --- a/config.lua +++ b/config.lua @@ -1,3 +1,3 @@ -Config = {} -Config.Locale = 'fr' -Config.MaxPlayers = 32 +Config = {} + +Config.Locale = 'fr' \ No newline at end of file diff --git a/server/main.lua b/server/main.lua index fa2949ce..b7fcf132 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,11 +1,11 @@ -local Instances = {} +local instances = {} function GetInstancedPlayers() local players = {} - for k,v in pairs(Instances) do - for i=1, #v.players, 1 do - table.insert(players, v.players[i]) + for k,v in pairs(instances) do + for k2,v2 in ipairs(v.players) do + players[v2] = true end end @@ -13,26 +13,26 @@ function GetInstancedPlayers() end function CreateInstance(type, player, data) - Instances[player] = { + instances[player] = { type = type, host = player, players = {}, data = data } - TriggerEvent('instance:onCreate', Instances[player]) - TriggerClientEvent('instance:onCreate', player, Instances[player]) + TriggerEvent('instance:onCreate', instances[player]) + TriggerClientEvent('instance:onCreate', player, instances[player]) TriggerClientEvent('instance:onInstancedPlayersData', -1, GetInstancedPlayers()) end function CloseInstance(instance) - if Instances[instance] ~= nil then + if instances[instance] then - for i=1, #Instances[instance].players, 1 do - TriggerClientEvent('instance:onClose', Instances[instance].players[i]) + for i=1, #instances[instance].players do + TriggerClientEvent('instance:onClose', instances[instance].players[i]) end - Instances[instance] = nil + instances[instance] = nil TriggerClientEvent('instance:onInstancedPlayersData', -1, GetInstancedPlayers()) TriggerEvent('instance:onClose', instance) @@ -42,22 +42,22 @@ end function AddPlayerToInstance(instance, player) local found = false - for i=1, #Instances[instance].players, 1 do - if Instances[instance].players[i] == player then + for i=1, #instances[instance].players do + if instances[instance].players[i] == player then found = true break end end if not found then - table.insert(Instances[instance].players, player) + table.insert(instances[instance].players, player) end - TriggerClientEvent('instance:onEnter', player, Instances[instance]) + TriggerClientEvent('instance:onEnter', player, instances[instance]) - for i=1, #Instances[instance].players, 1 do - if Instances[instance].players[i] ~= player then - TriggerClientEvent('instance:onPlayerEntered', Instances[instance].players[i], Instances[instance], player) + for i=1, #instances[instance].players do + if instances[instance].players[i] ~= player then + TriggerClientEvent('instance:onPlayerEntered', instances[instance].players[i], instances[instance], player) end end @@ -65,42 +65,34 @@ function AddPlayerToInstance(instance, player) end function RemovePlayerFromInstance(instance, player) + if instances[instance] then + TriggerClientEvent('instance:onLeave', player, instances[instance]) - if Instances[instance] ~= nil then - - TriggerClientEvent('instance:onLeave', player, Instances[instance]) - - if Instances[instance].host == player then - - for i=1, #Instances[instance].players, 1 do - if Instances[instance].players[i] ~= player then - TriggerClientEvent('instance:onPlayerLeft', Instances[instance].players[i], Instances[instance], player) + if instances[instance].host == player then + for i=1, #instances[instance].players do + if instances[instance].players[i] ~= player then + TriggerClientEvent('instance:onPlayerLeft', instances[instance].players[i], instances[instance], player) end end CloseInstance(instance) - else - - for i=1, #Instances[instance].players, 1 do - if Instances[instance].players[i] == player then - Instances[instance].players[i] = nil + for i=1, #instances[instance].players do + if instances[instance].players[i] == player then + instances[instance].players[i] = nil end end - for i=1, #Instances[instance].players, 1 do - if Instances[instance].players[i] ~= player then - TriggerClientEvent('instance:onPlayerLeft', Instances[instance].players[i], Instances[instance], player) + for i=1, #instances[instance].players do + if instances[instance].players[i] ~= player then + TriggerClientEvent('instance:onPlayerLeft', instances[instance].players[i], instances[instance], player) end end TriggerClientEvent('instance:onInstancedPlayersData', -1, GetInstancedPlayers()) - end - end - end function InvitePlayerToInstance(instance, type, player, data) From 0cafd722a963902f705012a692582ab78d921eaa Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 27 Jul 2019 16:49:14 +0200 Subject: [PATCH 2247/3224] Seperate code to improve performance --- client/main.lua | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/client/main.lua b/client/main.lua index 43e0ce69..189d77d6 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,4 +1,4 @@ -local instance, instancedPlayers, registeredInstanceTypes = {}, {}, {} +local instance, instancedPlayers, registeredInstanceTypes, playersToHide = {}, {}, {}, {} local instanceInvite, insideInstance ESX = nil @@ -114,7 +114,7 @@ end) RegisterNetEvent('instance:onPlayerEntered') AddEventHandler('instance:onPlayerEntered', function(_instance, player) - instance = _instance + instance = _instance local playerName = GetPlayerName(GetPlayerFromServerId(player)) ESX.ShowNotification(_('entered_into', playerName)) @@ -170,9 +170,8 @@ end) -- Instance players Citizen.CreateThread(function() while true do - Citizen.Wait(10) - local playerPed = PlayerPedId() - local playersToHide = {} + Citizen.Wait(1000) + playersToHide = {} if instance.host then -- Get players and sets them as pairs @@ -189,6 +188,13 @@ Citizen.CreateThread(function() playersToHide[GetPlayerFromServerId(player)] = true end end + end +end) + +Citizen.CreateThread(function() + while true do + Citizen.Wait(10) + local playerPed = PlayerPedId() -- Hide all these players for player,_ in pairs(playersToHide) do @@ -207,7 +213,7 @@ end) Citizen.CreateThread(function() while true do Citizen.Wait(0) -- must be run every frame - + if insideInstance then SetVehicleDensityMultiplierThisFrame(0.0) SetParkedVehicleDensityMultiplierThisFrame(0.0) From 633268330cca0174c41a87b5d1d19aa4804c7e1a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 28 Jul 2019 20:56:39 +0200 Subject: [PATCH 2248/3224] Fixed handcuffing, closes #314 and #316 --- client/main.lua | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/client/main.lua b/client/main.lua index 99314b7d..fabe8c79 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,5 +1,5 @@ local PlayerData, CurrentActionData, handcuffTimer, dragStatus, blipsCops, currentTask, spawnedVehicles = {}, {}, {}, {}, {}, {}, {} -local HasAlreadyEnteredMarker, isDead, IsHandcuffed, hasAlreadyJoined, playerInService, isInShopMenu = false, false, false, false, false, false +local HasAlreadyEnteredMarker, isDead, isHandcuffed, hasAlreadyJoined, playerInService, isInShopMenu = false, false, false, false, false, false local LastStation, LastPart, LastPartNum, LastEntity, CurrentAction, CurrentActionMsg dragStatus.isDragged = false ESX = nil @@ -1416,11 +1416,11 @@ end) RegisterNetEvent('esx_policejob:handcuff') AddEventHandler('esx_policejob:handcuff', function() - IsHandcuffed = not IsHandcuffed + isHandcuffed = not isHandcuffed local playerPed = PlayerPedId() Citizen.CreateThread(function() - if IsHandcuffed then + if isHandcuffed then RequestAnimDict('mp_arresting') while not HasAnimDictLoaded('mp_arresting') do @@ -1460,9 +1460,9 @@ end) RegisterNetEvent('esx_policejob:unrestrain') AddEventHandler('esx_policejob:unrestrain', function() - if IsHandcuffed then + if isHandcuffed then local playerPed = PlayerPedId() - IsHandcuffed = false + isHandcuffed = false ClearPedSecondaryTask(playerPed) SetEnableHandcuffs(playerPed, false) @@ -1480,7 +1480,7 @@ end) RegisterNetEvent('esx_policejob:drag') AddEventHandler('esx_policejob:drag', function(copId) - if not IsHandcuffed then + if not isHandcuffed then return end @@ -1495,7 +1495,7 @@ Citizen.CreateThread(function() while true do Citizen.Wait(1) - if IsHandcuffed then + if isHandcuffed then playerPed = PlayerPedId() if dragStatus.isDragged then @@ -1528,7 +1528,7 @@ AddEventHandler('esx_policejob:putInVehicle', function() local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) - if not IsHandcuffed then + if not isHandcuffed then return end @@ -1571,7 +1571,7 @@ Citizen.CreateThread(function() Citizen.Wait(0) local playerPed = PlayerPedId() - if IsHandcuffed then + if isHandcuffed then DisableControlAction(0, 1, true) -- Disable pan DisableControlAction(0, 2, true) -- Disable tilt DisableControlAction(0, 24, true) -- Attack @@ -1972,7 +1972,7 @@ function StartHandcuffTimer() handcuffTimer.active = true - handcuffTimer.task = ESX.SetTimeout(Config.handcuffTimer, function() + handcuffTimer.task = ESX.SetTimeout(Config.HandcuffTimer, function() ESX.ShowNotification(_U('unrestrained_timer')) TriggerEvent('esx_policejob:unrestrain') handcuffTimer.active = false From e850da085e694a17235501873d11635be2fa43c0 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 30 Jul 2019 20:40:39 +0200 Subject: [PATCH 2249/3224] See description for changes Fixed the "health" problems on vehicles. It seems like you shouldn't use the `GetEntityHealth()` on vehicles at all since it is linked to the `GetVehicleBodyHealth()` native. But if you use the `SetEntityHealth()` native on an vehicle it breaks the link. Instead there's both body health and engine health that ESX has missed out on. Since the new used `GetVehicle***` natives return decimal values we round them to 1 decmial. Also dirt levels are now rounded to one decimal since they make 0 visable difference. --- client/functions.lua | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 083a4160..3b54aee4 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -638,15 +638,15 @@ ESX.Game.GetVehicleProperties = function(vehicle) end return { - model = GetEntityModel(vehicle), plate = ESX.Math.Trim(GetVehicleNumberPlateText(vehicle)), plateIndex = GetVehicleNumberPlateTextIndex(vehicle), - health = GetEntityHealth(vehicle), - dirtLevel = GetVehicleDirtLevel(vehicle), + bodyHealth = ESX.Math.Round(GetVehicleBodyHealth(vehicle), 1), + engineHealth = ESX.Math.Round(GetVehicleEngineHealth(vehicle), 1), + dirtLevel = ESX.Math.Round(GetVehicleDirtLevel(vehicle), 1), color1 = color1, color2 = color2, @@ -731,8 +731,12 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex) end - if props.health ~= nil then - SetEntityHealth(vehicle, props.health) + if props.bodyHealth ~= nil then + SetVehicleBodyHealth(vehicle, props.bodyHealth) + end + + if props.engineHealth ~= nil then + SetVehicleEngineHealth(vehicle, props.engineHealth) end if props.dirtLevel ~= nil then From 9557ff1a4f8a1cb8b5aef834ec794ac30d7c135b Mon Sep 17 00:00:00 2001 From: MajorMarcin Date: Wed, 31 Jul 2019 11:55:16 +0200 Subject: [PATCH 2250/3224] add pl translation and update repo links in README --- README.md | 6 +++--- __resource.lua | 1 + locales/fr.lua | 2 +- locales/pl.lua | 5 +++++ 4 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 locales/pl.lua diff --git a/README.md b/README.md index ee834e50..a1740479 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,14 @@ FXServer ESX Optional Needs [REQUIREMENTS] -- esx_status https://github.com/FXServer-ESX/fxserver-esx_status +- esx_status https://github.com/ESX-Org/esx_status [INSTALLATION] -1) CD in your resources/[esx] folder +1) CD in your resources folder 2) Clone the repository ``` -git clone https://github.com/FXServer-ESX/fxserver-esx_optionalneeds esx_optionalneeds +git clone https://github.com/ESX-Org/esx_optionalneeds [esx]/esx_optionalneeds ``` 3) Add this in your server.cfg : diff --git a/__resource.lua b/__resource.lua index 1ca03d72..b85dfa97 100644 --- a/__resource.lua +++ b/__resource.lua @@ -9,6 +9,7 @@ server_scripts { 'locales/en.lua', 'locales/fi.lua', 'locales/fr.lua', + 'locales/pl.lua', 'config.lua', 'server/main.lua' } diff --git a/locales/fr.lua b/locales/fr.lua index 528abb41..f028c329 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,5 +1,5 @@ Locales['fr'] = { - ['used_beer'] = 'Vous avez utilisé 1x ~y~Bière~s~', + ['used_beer'] = 'vous avez utilisé 1x ~y~Bière~s~', } \ No newline at end of file diff --git a/locales/pl.lua b/locales/pl.lua new file mode 100644 index 00000000..e5758dc9 --- /dev/null +++ b/locales/pl.lua @@ -0,0 +1,5 @@ +Locales['pl'] = { + + ['used_beer'] = 'używasz 1x ~y~Piwo~s~', + +} \ No newline at end of file From 44c05b8fae757870e3d4a37f0919da462d3d74ad Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 2 Aug 2019 11:33:10 +0200 Subject: [PATCH 2251/3224] Added fuel to veh properties and ensure decimal value --- client/functions.lua | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 3b54aee4..486d5551 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -646,6 +646,7 @@ ESX.Game.GetVehicleProperties = function(vehicle) bodyHealth = ESX.Math.Round(GetVehicleBodyHealth(vehicle), 1), engineHealth = ESX.Math.Round(GetVehicleEngineHealth(vehicle), 1), + fuelLevel = ESX.Math.Round(GetVehicleFuelLevel(vehicle), 1), dirtLevel = ESX.Math.Round(GetVehicleDirtLevel(vehicle), 1), color1 = color1, color2 = color2, @@ -732,15 +733,19 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) end if props.bodyHealth ~= nil then - SetVehicleBodyHealth(vehicle, props.bodyHealth) + SetVehicleBodyHealth(vehicle, props.bodyHealth + 0.0) end if props.engineHealth ~= nil then - SetVehicleEngineHealth(vehicle, props.engineHealth) + SetVehicleEngineHealth(vehicle, props.engineHealth + 0.0) + end + + if props.fuelLevel ~= nil then + SetVehicleFuelLevel(vehicle, props.fuelLevel + 0.0) end if props.dirtLevel ~= nil then - SetVehicleDirtLevel(vehicle, props.dirtLevel) + SetVehicleDirtLevel(vehicle, props.dirtLevel + 0.0) end if props.color1 ~= nil then From ee007077a9c98d41250ac211793218036590fce9 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 3 Aug 2019 10:28:05 +0200 Subject: [PATCH 2252/3224] Enforced 2 space locale indent --- locales/pl.lua | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/locales/pl.lua b/locales/pl.lua index facf48aa..db81b639 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -1,19 +1,19 @@ Locales ['pl'] = { - ['valid_purchase'] = 'czy napewno chcesz to zakupić?', - ['yes'] = 'tak (%s $)', - ['no'] = 'nie', - ['helmet'] = 'hełm / Czapka', - ['glasses'] = 'okulary', - ['mask'] = 'maska', - ['ears'] = 'akcesoria uszu', - ['shop'] = 'sklep %s ', - ['set_unset'] = 'załóż / Zdejmij', - ['not_enough_money'] = 'nie masz wystarczająco pieniędzy', - ['press_access'] = 'wciśnij ~INPUT_CONTEXT~ aby otworzyć menu', - ['accessories_blip'] = 'akcesoria', - ['no_ears'] = 'nie posiadasz akcesorii uszu', - ['no_glasses'] = 'nie posiadasz okularów', - ['no_helmet'] = 'nie posiadasz nakrycia głowy', - ['no_mask'] = 'nie posiadasz maski', - ['you_paid'] = 'płacisz ~g~%s $~s~', + ['valid_purchase'] = 'czy napewno chcesz to zakupić?', + ['yes'] = 'tak (%s $)', + ['no'] = 'nie', + ['helmet'] = 'hełm / Czapka', + ['glasses'] = 'okulary', + ['mask'] = 'maska', + ['ears'] = 'akcesoria uszu', + ['shop'] = 'sklep %s ', + ['set_unset'] = 'załóż / Zdejmij', + ['not_enough_money'] = 'nie masz wystarczająco pieniędzy', + ['press_access'] = 'wciśnij ~INPUT_CONTEXT~ aby otworzyć menu', + ['accessories_blip'] = 'akcesoria', + ['no_ears'] = 'nie posiadasz akcesorii uszu', + ['no_glasses'] = 'nie posiadasz okularów', + ['no_helmet'] = 'nie posiadasz nakrycia głowy', + ['no_mask'] = 'nie posiadasz maski', + ['you_paid'] = 'płacisz ~g~%s $~s~', } From 8bd77249d5fe2d0f58fe5334cb04d9d9f3496577 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 3 Aug 2019 10:41:30 +0200 Subject: [PATCH 2253/3224] Removed keys table, minor improvements, final commit v1.0.0 --- __resource.lua | 2 +- client/main.lua | 57 +++++++++++------------------------------------ client/marker.lua | 14 +++--------- config.lua | 6 +---- locales/en.lua | 2 +- locales/sv.lua | 2 +- server/main.lua | 10 ++++----- 7 files changed, 25 insertions(+), 68 deletions(-) diff --git a/__resource.lua b/__resource.lua index 3c677db1..91e2d952 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,7 +2,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ESX Boat' -version '0.5.0' +version '1.0.0' server_scripts { '@mysql-async/lib/MySQL.lua', diff --git a/client/main.lua b/client/main.lua index 71029844..63eacd3e 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,15 +1,3 @@ -Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - ESX = nil isInShopMenu = false local spawnedVehicles = {} @@ -20,7 +8,7 @@ Citizen.CreateThread(function() Citizen.Wait(0) end - while ESX.GetPlayerData().job == nil do + while not ESX.GetPlayerData().job do Citizen.Wait(10) end @@ -28,7 +16,6 @@ Citizen.CreateThread(function() end) function OpenBoatShop(shop) - isInShopMenu = true local playerPed = PlayerPedId() @@ -49,26 +36,20 @@ function OpenBoatShop(shop) align = 'top-left', elements = elements }, function (data, menu) - - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'boat_shop_confirm', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'boat_shop_confirm', { title = _U('boat_shop_confirm', data.current.name, ESX.Math.GroupDigits(data.current.price)), align = 'top-left', elements = { - { label = _U('confirm_no'), value = 'no' }, - { label = _U('confirm_yes'), value = 'yes' } - } - }, function (data2, menu2) - + {label = _U('confirm_no'), value = 'no'}, + {label = _U('confirm_yes'), value = 'yes'} + }}, function (data2, menu2) if data2.current.value == 'yes' then + local plate = exports['esx_vehicleshop']:GeneratePlate() + local vehicle = GetVehiclePedIsIn(playerPed, false) + local props = ESX.Game.GetVehicleProperties(vehicle) + props.plate = plate - local plate = exports['esx_vehicleshop']:GeneratePlate() - local vehicle = GetVehiclePedIsIn(playerPed, false) - local props = ESX.Game.GetVehicleProperties(vehicle) - props.plate = plate - - ESX.TriggerServerCallback('esx_boat:buyBoat', function (bought) - + ESX.TriggerServerCallback('esx_boat:buyBoat', function(bought) if bought then ESX.ShowNotification(_U('boat_shop_bought', data.current.name, ESX.Math.GroupDigits(data.current.price))) @@ -86,17 +67,13 @@ function OpenBoatShop(shop) ESX.ShowNotification(_U('boat_shop_nomoney')) menu2.close() end - end, props) - else menu2.close() end - end, function (data2, menu2) menu2.close() end) - end, function (data, menu) menu.close() isInShopMenu = false @@ -108,7 +85,6 @@ function OpenBoatShop(shop) FreezeEntityPosition(playerPed, false) SetEntityVisible(playerPed, true) SetEntityCoords(playerPed, shop.Outside.x, shop.Outside.y, shop.Outside.z) - end, function (data, menu) DeleteSpawnedVehicles() @@ -138,13 +114,10 @@ function OpenBoatShop(shop) end function OpenBoatGarage(garage) - ESX.TriggerServerCallback('esx_boat:getGarage', function (ownedBoats) - if #ownedBoats == 0 then ESX.ShowNotification(_U('garage_noboats')) else - -- get all available boats local elements = {} for i=1, #ownedBoats, 1 do @@ -161,7 +134,6 @@ function OpenBoatGarage(garage) align = 'top-left', elements = elements }, function (data, menu) - -- make sure the spawn point isn't blocked local playerPed = PlayerPedId() local vehicleProps = data.current.vehicleProps @@ -179,7 +151,6 @@ function OpenBoatGarage(garage) else ESX.ShowNotification(_U('garage_blocked')) end - end, function (data, menu) menu.close() @@ -187,7 +158,6 @@ function OpenBoatGarage(garage) CurrentActionMsg = _U('garage_open') end) end - end) end @@ -196,10 +166,9 @@ function OpenLicenceMenu(shop) title = _U('license_menu'), align = 'top-left', elements = { - { label = _U('license_buy_no'), value = 'no' }, - { label = _U('license_buy_yes', ESX.Math.GroupDigits(Config.LicensePrice)), value = 'yes' } - } - }, function (data, menu) + {label = _U('license_buy_no'), value = 'no'}, + {label = _U('license_buy_yes', ESX.Math.GroupDigits(Config.LicensePrice)), value = 'yes'} + }}, function (data, menu) if data.current.value == 'yes' then ESX.TriggerServerCallback('esx_boat:buyBoatLicense', function (boughtLicense) if boughtLicense then diff --git a/client/marker.lua b/client/marker.lua index fd850ff0..46e18481 100644 --- a/client/marker.lua +++ b/client/marker.lua @@ -10,14 +10,11 @@ Citizen.CreateThread(function() while true do Citizen.Wait(0) - if CurrentAction ~= nil then - + if CurrentAction then ESX.ShowHelpNotification(CurrentActionMsg) - if IsControlJustReleased(0, Keys['E']) then - + if IsControlJustReleased(0, 38) then if CurrentAction == 'boat_shop' then - if not Config.LicenseEnable then OpenBoatShop(Config.Zones.BoatShops[CurrentActionData.zoneNum]) else -- check for license @@ -29,9 +26,7 @@ Citizen.CreateThread(function() OpenLicenceMenu(Config.Zones.BoatShops[CurrentActionData.zoneNum]) end end, GetPlayerServerId(PlayerId()), 'boat') - end - elseif CurrentAction == 'garage_out' then OpenBoatGarage(Config.Zones.Garages[CurrentActionData.zoneNum]) elseif CurrentAction == 'garage_in' then @@ -156,13 +151,11 @@ Citizen.CreateThread(function() if letSleep then Citizen.Wait(500) end - end end) -- Blips Citizen.CreateThread(function() - local blipList = {} for i=1, #Config.Zones.Garages, 1 do @@ -188,7 +181,6 @@ Citizen.CreateThread(function() for i=1, #blipList, 1 do CreateBlip(blipList[i].coords, blipList[i].text, blipList[i].sprite, blipList[i].color, blipList[i].scale) end - end) function CreateBlip(coords, text, sprite, color, scale) @@ -203,4 +195,4 @@ function CreateBlip(coords, text, sprite, color, scale) BeginTextCommandSetBlipName('STRING') AddTextComponentSubstringPlayerName(text) EndTextCommandSetBlipName(blip) -end \ No newline at end of file +end diff --git a/config.lua b/config.lua index 46aac300..1577e976 100644 --- a/config.lua +++ b/config.lua @@ -21,7 +21,6 @@ Config.StoreMarker = { Config.Zones = { Garages = { - { -- Shank St, nearby campaign boat garage GaragePos = vector3(-772.4, -1430.9, 0.5), SpawnPoint = vector4(-785.39, -1426.3, 0.0, 146.0), @@ -62,17 +61,14 @@ Config.Zones = { SpawnPoint = vector4(-3448.9, 953.8, 0.0, 75.0), StorePos = vector3(-3436.5, 946.6, 0.3), StoreTP = vector4(-3427.0, 952.6, 8.3, 0.0) - }, - + } }, BoatShops = { - { -- Shank St, nearby campaign boat garage Outside = vector3(-773.7, -1495.2, 1.6), Inside = vector4(-798.5, -1503.1, -0.4, 120.0) } - } } diff --git a/locales/en.lua b/locales/en.lua index fd1f44ac..0c981825 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -28,4 +28,4 @@ Locales['en'] = { -- blips ['blip_garage'] = 'boat Garage', ['blip_shop'] = 'boat Shop', -} \ No newline at end of file +} diff --git a/locales/sv.lua b/locales/sv.lua index c4803dcc..f4f194a5 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -28,4 +28,4 @@ Locales['sv'] = { -- blips ['blip_garage'] = 'båtgarage', ['blip_shop'] = 'båtaffär', -} \ No newline at end of file +} diff --git a/server/main.lua b/server/main.lua index 24295b96..4ebad086 100644 --- a/server/main.lua +++ b/server/main.lua @@ -70,7 +70,7 @@ ESX.RegisterServerCallback('esx_boat:storeVehicle', function (source, cb, plate) end) ESX.RegisterServerCallback('esx_boat:getGarage', function(source, cb) - MySQL.Async.fetchAll('SELECT * FROM owned_vehicles WHERE owner = @owner AND type = @type AND `stored` = @stored', { + MySQL.Async.fetchAll('SELECT vehicle FROM owned_vehicles WHERE owner = @owner AND type = @type AND `stored` = @stored', { ['@owner'] = GetPlayerIdentifiers(source)[1], ['@type'] = 'boat', ['@stored'] = true @@ -100,11 +100,11 @@ ESX.RegisterServerCallback('esx_boat:buyBoatLicense', function(source, cb) end) function getPriceFromModel(model) - for i=1, #Config.Vehicles, 1 do - if GetHashKey(Config.Vehicles[i].model) == model then - return Config.Vehicles[i].price + for k,v in ipairs(Config.Vehicles) do + if GetHashKey(v.model) == model then + return v.price end end return 0 -end \ No newline at end of file +end From a07b4a7e9c4bae66513c95fc8ab11217e5ceea23 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 3 Aug 2019 10:42:12 +0200 Subject: [PATCH 2254/3224] Very final commit v1.0.0 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2acdcb11..7477c962 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ start esx_boat ### License esx_boat - Boat shop and garage for ESX -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2019 Jérémie N'gadi 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. From 06d3ee286f52169693b063164d1bed400e50680d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 4 Aug 2019 14:55:04 +0200 Subject: [PATCH 2255/3224] Replaced for i= loops with ipairs --- client/main.lua | 65 +++++++++++++---------------- server/classes/player.lua | 86 +++++++++++++++++++-------------------- 2 files changed, 69 insertions(+), 82 deletions(-) diff --git a/client/main.lua b/client/main.lua index f04422d7..722d4041 100644 --- a/client/main.lua +++ b/client/main.lua @@ -8,15 +8,15 @@ AddEventHandler('esx:playerLoaded', function(xPlayer) ESX.PlayerData = xPlayer if Config.EnableHud then - for i=1, #xPlayer.accounts, 1 do - local accountTpl = '
     {{money}}
    ' + for k,v in ipairs(xPlayer.accounts) do + local accountTpl = '
     {{money}}
    ' - ESX.UI.HUD.RegisterElement('account_' .. xPlayer.accounts[i].name, i-1, 0, accountTpl, { + ESX.UI.HUD.RegisterElement('account_' .. v.name, k - 1, 0, accountTpl, { money = 0 }) - ESX.UI.HUD.UpdateElement('account_' .. xPlayer.accounts[i].name, { - money = ESX.Math.GroupDigits(xPlayer.accounts[i].money) + ESX.UI.HUD.UpdateElement('account_' .. v.name, { + money = ESX.Math.GroupDigits(v.money) }) end @@ -81,22 +81,21 @@ AddEventHandler('esx:restoreLoadout', function() RemoveAllPedWeapons(playerPed, true) - for i=1, #ESX.PlayerData.loadout, 1 do - local weaponName = ESX.PlayerData.loadout[i].name + for k,v in ipairs(ESX.PlayerData.loadout) do + local weaponName = v.name local weaponHash = GetHashKey(weaponName) GiveWeaponToPed(playerPed, weaponHash, 0, false, false) local ammoType = GetPedAmmoTypeFromWeapon(playerPed, weaponHash) - for j=1, #ESX.PlayerData.loadout[i].components, 1 do - local weaponComponent = ESX.PlayerData.loadout[i].components[j] - local componentHash = ESX.GetWeaponComponent(weaponName, weaponComponent).hash + for k2,v2 in ipairs(v.components) do + local componentHash = ESX.GetWeaponComponent(weaponName, v2).hash GiveWeaponComponentToPed(playerPed, weaponHash, componentHash) end if not ammoTypes[ammoType] then - AddAmmoToPed(playerPed, weaponHash, ESX.PlayerData.loadout[i].ammo) + AddAmmoToPed(playerPed, weaponHash, v.ammo) ammoTypes[ammoType] = true end end @@ -106,9 +105,9 @@ end) RegisterNetEvent('esx:setAccountMoney') AddEventHandler('esx:setAccountMoney', function(account) - for i=1, #ESX.PlayerData.accounts, 1 do - if ESX.PlayerData.accounts[i].name == account.name then - ESX.PlayerData.accounts[i] = account + for k,v in ipairs(ESX.PlayerData.accounts) do + if v.name == account.name then + ESX.PlayerData.accounts[k] = account break end end @@ -127,9 +126,9 @@ end) RegisterNetEvent('esx:addInventoryItem') AddEventHandler('esx:addInventoryItem', function(item, count) - for i=1, #ESX.PlayerData.inventory, 1 do - if ESX.PlayerData.inventory[i].name == item.name then - ESX.PlayerData.inventory[i] = item + for k,v in ipairs(ESX.PlayerData.inventory) do + if v.name == item.name then + ESX.PlayerData.inventory[k] = item break end end @@ -143,9 +142,9 @@ end) RegisterNetEvent('esx:removeInventoryItem') AddEventHandler('esx:removeInventoryItem', function(item, count) - for i=1, #ESX.PlayerData.inventory, 1 do - if ESX.PlayerData.inventory[i].name == item.name then - ESX.PlayerData.inventory[i] = item + for k,v in ipairs(ESX.PlayerData.inventory) do + if v.name == item.name then + ESX.PlayerData.inventory[k] = item break end end @@ -411,18 +410,17 @@ Citizen.CreateThread(function() isLoadoutLoaded = false end - for i=1, #Config.Weapons do - local weaponName = Config.Weapons[i].name + for k,v in ipairs(Config.Weapons) do + local weaponName = v.name local weaponHash = GetHashKey(weaponName) local weaponComponents = {} if HasPedGotWeapon(playerPed, weaponHash, false) and weaponName ~= 'WEAPON_UNARMED' then local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) - local components = Config.Weapons[i].components - for j=1, #components do - if HasPedGotWeaponComponent(playerPed, weaponHash, components[j].hash) then - table.insert(weaponComponents, components[j].name) + for k2,v2 in ipairs(v.components) do + if HasPedGotWeaponComponent(playerPed, weaponHash, v2.hash) then + table.insert(weaponComponents, v2.name) end end @@ -435,7 +433,7 @@ Citizen.CreateThread(function() table.insert(loadout, { name = weaponName, ammo = ammo, - label = Config.Weapons[i].label, + label = v.label, components = weaponComponents }) else @@ -480,7 +478,7 @@ if Config.DisableWantedLevel then end) end --- pickups +-- Pickups Citizen.CreateThread(function() while true do Citizen.Wait(0) @@ -518,23 +516,16 @@ end) Citizen.CreateThread(function() while true do Citizen.Wait(1000) + local playerPed = PlayerPedId() if ESX.PlayerLoaded and isPlayerSpawned then - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) + local coords = GetEntityCoords(playerPed) if not IsEntityDead(playerPed) then ESX.PlayerData.lastPosition = {x = coords.x, y = coords.y, z = coords.z} end end - end -end) -Citizen.CreateThread(function() - while true do - Citizen.Wait(1000) - - local playerPed = PlayerPedId() if IsEntityDead(playerPed) and isPlayerSpawned then isPlayerSpawned = false end diff --git a/server/classes/player.lua b/server/classes/player.lua index 5642c527..15bd7057 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -139,23 +139,19 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.getAccounts = function() local accounts = {} - for i=1, #Config.Accounts, 1 do - if Config.Accounts[i] == 'bank' then - + for k,v in ipairs(Config.Accounts) do + if v == 'bank' then table.insert(accounts, { name = 'bank', money = self.get('bank'), - label = Config.AccountLabels['bank'] + label = Config.AccountLabels.bank }) - else - - for j=1, #self.accounts, 1 do - if self.accounts[j].name == Config.Accounts[i] then - table.insert(accounts, self.accounts[j]) + for k2,v2 in ipairs(self.accounts) do + if v2 == v then + table.insert(accounts, v2) end end - end end @@ -167,13 +163,13 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l return { name = 'bank', money = self.get('bank'), - label = Config.AccountLabels['bank'] + label = Config.AccountLabels.bank } end - for i=1, #self.accounts, 1 do - if self.accounts[i].name == a then - return self.accounts[i] + for k,v in ipairs(self.accounts) do + if v.name == a then + return v end end end @@ -213,24 +209,24 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.getMissingAccounts = function(cb) - MySQL.Async.fetchAll('SELECT * FROM `user_accounts` WHERE `identifier` = @identifier', { + MySQL.Async.fetchAll('SELECT name FROM user_accounts WHERE identifier = @identifier', { ['@identifier'] = self.getIdentifier() }, function(result) local missingAccounts = {} - for i=1, #Config.Accounts, 1 do - if Config.Accounts[i] ~= 'bank' then + for k,v in ipairs(Config.Accounts) do + if v ~= 'bank' then local found = false - for j=1, #result, 1 do - if Config.Accounts[i] == result[j].name then + for k2,v2 in ipairs(result) do + if v == v2.name then found = true break end end if not found then - table.insert(missingAccounts, Config.Accounts[i]) + table.insert(missingAccounts, v) end end end @@ -240,12 +236,12 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.createAccounts = function(missingAccounts, cb) - for i=1, #missingAccounts, 1 do - MySQL.Async.execute('INSERT INTO `user_accounts` (identifier, name) VALUES (@identifier, @name)', { + for k,v in ipairs(missingAccounts) do + MySQL.Async.execute('INSERT INTO user_accounts (identifier, name) VALUES (@identifier, @name)', { ['@identifier'] = self.getIdentifier(), - ['@name'] = missingAccounts[i] + ['@name'] = v }, function(rowsChanged) - if cb ~= nil then + if cb then cb() end end) @@ -308,9 +304,9 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.getInventoryItem = function(name) - for i=1, #self.inventory, 1 do - if self.inventory[i].name == name then - return self.inventory[i] + for k,v in ipairs(self.inventory) do + if v.name == name then + return v end end end @@ -366,11 +362,11 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.job.skin_male = {} self.job.skin_female = {} - if gradeObject.skin_male ~= nil then + if gradeObject.skin_male then self.job.skin_male = json.decode(gradeObject.skin_male) end - if gradeObject.skin_female ~= nil then + if gradeObject.skin_female then self.job.skin_female = json.decode(gradeObject.skin_female) end @@ -412,15 +408,15 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.removeWeapon = function(weaponName, ammo) local weaponLabel - for i=1, #self.loadout, 1 do - if self.loadout[i].name == weaponName then - weaponLabel = self.loadout[i].label + for k,v in ipairs(self.loadout) do + if v.name == weaponName then + weaponLabel = v.label - for j=1, #self.loadout[i].components, 1 do - TriggerClientEvent('esx:removeWeaponComponent', self.source, weaponName, self.loadout[i].components[j]) + for k2,v2 in ipairs(v.components) do + TriggerClientEvent('esx:removeWeaponComponent', self.source, weaponName, v2) end - table.remove(self.loadout, i) + table.remove(self.loadout, k) break end end @@ -438,9 +434,9 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l return end - for i=1, #self.loadout[loadoutNum].components, 1 do - if self.loadout[loadoutNum].components.name == weaponComponent then - table.remove(self.loadout[loadoutNum].components, i) + for k,v in ipairs(self.loadout[loadoutNum].components) do + if v.name == weaponComponent then + table.remove(self.loadout[loadoutNum].components, k) break end end @@ -455,8 +451,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l return false end - for i=1, #weapon.components, 1 do - if weapon.components[i] == weaponComponent then + for k,v in ipairs(weapon.components) do + if v == weaponComponent then return true end end @@ -465,8 +461,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.hasWeapon = function(weaponName) - for i=1, #self.loadout, 1 do - if self.loadout[i].name == weaponName then + for k,v in ipairs(self.loadout) do + if v.name == weaponName then return true end end @@ -475,9 +471,9 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.getWeapon = function(weaponName) - for i=1, #self.loadout, 1 do - if self.loadout[i].name == weaponName then - return i, self.loadout[i] + for k,v in ipairs(self.loadout) do + if v.name == weaponName then + return k, v end end From 2e39e3d01a79d246738be266f8cad390767bad1c Mon Sep 17 00:00:00 2001 From: Viktor <35453587+LifeGoal@users.noreply.github.com> Date: Sun, 4 Aug 2019 16:47:33 +0200 Subject: [PATCH 2256/3224] Fixed loadout flaw when confiscated while dead --- client/main.lua | 4 ---- 1 file changed, 4 deletions(-) diff --git a/client/main.lua b/client/main.lua index 722d4041..f7e0f47f 100644 --- a/client/main.lua +++ b/client/main.lua @@ -406,10 +406,6 @@ Citizen.CreateThread(function() local loadout = {} local loadoutChanged = false - if IsPedDeadOrDying(playerPed) then - isLoadoutLoaded = false - end - for k,v in ipairs(Config.Weapons) do local weaponName = v.name local weaponHash = GetHashKey(weaponName) From adfb9f65229cb8f3859eecdf5838c9ebfa56a58f Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 4 Aug 2019 17:54:18 +0200 Subject: [PATCH 2257/3224] Fixed xplayer typo --- server/classes/player.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 15bd7057..bad6436c 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -148,7 +148,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l }) else for k2,v2 in ipairs(self.accounts) do - if v2 == v then + if v2.name == v then table.insert(accounts, v2) end end From 48cf1d56be977d6b78f0e75b893d73b4eb72dee3 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 4 Aug 2019 17:54:46 +0200 Subject: [PATCH 2258/3224] removed old ESX.TableContainsValue --- common/functions.lua | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/common/functions.lua b/common/functions.lua index 755ae468..ed9deb82 100644 --- a/common/functions.lua +++ b/common/functions.lua @@ -59,16 +59,6 @@ ESX.GetWeaponComponent = function(weaponName, weaponComponent) end end -ESX.TableContainsValue = function(table, value) - for k, v in pairs(table) do - if v == value then - return true - end - end - - return false -end - ESX.DumpTable = function(table, nb) if nb == nil then nb = 0 From e31d51b157a16f144f5b22fa82fa2863a7e53e92 Mon Sep 17 00:00:00 2001 From: Damyan <45739302+HexagoneM@users.noreply.github.com> Date: Tue, 6 Aug 2019 12:24:24 +0300 Subject: [PATCH 2259/3224] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a7085aab..c14470b5 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # esx_clotheshop ## Requirements -- [esx_skin](https://github.com/ESX-Org/esx_clotheshop) +- [esx_skin](https://github.com/ESX-Org/esx_skin) ## Download & Installation @@ -37,4 +37,4 @@ This program Is free software: you can redistribute it And/Or modify it under th 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 http://www.gnu.org/licenses/. \ No newline at end of file +You should have received a copy Of the GNU General Public License along with this program. If Not, see http://www.gnu.org/licenses/. From 3177493519536c3d7de30324258d8fc98c762da3 Mon Sep 17 00:00:00 2001 From: David Date: Wed, 7 Aug 2019 15:22:45 +0200 Subject: [PATCH 2260/3224] Optimized the code a bit --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 59e36e29..9f03719d 100644 --- a/client/main.lua +++ b/client/main.lua @@ -63,7 +63,7 @@ Citizen.CreateThread(function() if NetworkIsPlayerTalking(PlayerId()) then drawLevel(41, 128, 185, 255) - elseif not NetworkIsPlayerTalking(PlayerId()) then + else drawLevel(185, 185, 185, 255) end end From 5159e892fe1ecc5758600dbbaa342299206720db Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 10 Aug 2019 12:43:09 +0200 Subject: [PATCH 2261/3224] Removed unneeded backticks --- server/functions.lua | 6 +++--- server/main.lua | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/server/functions.lua b/server/functions.lua index 621692d8..351c0511 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -44,7 +44,7 @@ ESX.SavePlayer = function(xPlayer, cb) for i=1, #xPlayer.accounts, 1 do if ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] ~= xPlayer.accounts[i].money then table.insert(asyncTasks, function(cb) - MySQL.Async.execute('UPDATE user_accounts SET `money` = @money WHERE identifier = @identifier AND name = @name', { + MySQL.Async.execute('UPDATE user_accounts SET money = @money WHERE identifier = @identifier AND name = @name', { ['@money'] = xPlayer.accounts[i].money, ['@identifier'] = xPlayer.identifier, ['@name'] = xPlayer.accounts[i].name @@ -61,7 +61,7 @@ ESX.SavePlayer = function(xPlayer, cb) for i=1, #xPlayer.inventory, 1 do if ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] ~= xPlayer.inventory[i].count then table.insert(asyncTasks, function(cb) - MySQL.Async.execute('UPDATE user_inventory SET `count` = @count WHERE identifier = @identifier AND item = @item', { + MySQL.Async.execute('UPDATE user_inventory SET count = @count WHERE identifier = @identifier AND item = @item', { ['@count'] = xPlayer.inventory[i].count, ['@identifier'] = xPlayer.identifier, ['@item'] = xPlayer.inventory[i].name @@ -76,7 +76,7 @@ ESX.SavePlayer = function(xPlayer, cb) -- Job, loadout and position table.insert(asyncTasks, function(cb) - MySQL.Async.execute('UPDATE users SET `job` = @job, `job_grade` = @job_grade, `loadout` = @loadout, `position` = @position WHERE identifier = @identifier', { + MySQL.Async.execute('UPDATE users SET job = @job, job_grade = @job_grade, loadout = @loadout, position = @position WHERE identifier = @identifier', { ['@job'] = xPlayer.job.name, ['@job_grade'] = xPlayer.job.grade, ['@loadout'] = json.encode(xPlayer.getLoadout()), diff --git a/server/main.lua b/server/main.lua index 3e42442a..57e4b615 100644 --- a/server/main.lua +++ b/server/main.lua @@ -14,7 +14,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) TriggerEvent('es:getPlayerFromId', _source, function(player) -- Update user name in DB table.insert(tasks, function(cb) - MySQL.Async.execute('UPDATE `users` SET `name` = @name WHERE `identifier` = @identifier', { + MySQL.Async.execute('UPDATE users SET name = @name WHERE identifier = @identifier', { ['@identifier'] = player.getIdentifier(), ['@name'] = userData.playerName }, function(rowsChanged) @@ -24,7 +24,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) -- Get accounts table.insert(tasks, function(cb) - MySQL.Async.fetchAll('SELECT * FROM `user_accounts` WHERE `identifier` = @identifier', { + MySQL.Async.fetchAll('SELECT * FROM user_accounts WHERE identifier = @identifier', { ['@identifier'] = player.getIdentifier() }, function(accounts) for i=1, #Config.Accounts, 1 do @@ -47,7 +47,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) -- Get inventory table.insert(tasks, function(cb) - MySQL.Async.fetchAll('SELECT * FROM `user_inventory` WHERE `identifier` = @identifier', { + MySQL.Async.fetchAll('SELECT * FROM user_inventory WHERE identifier = @identifier', { ['@identifier'] = player.getIdentifier() }, function(inventory) local tasks2 = {} @@ -127,7 +127,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) -- Get job name, grade and last position table.insert(tasks2, function(cb2) - MySQL.Async.fetchAll('SELECT job, job_grade, loadout, position FROM `users` WHERE `identifier` = @identifier', { + MySQL.Async.fetchAll('SELECT job, job_grade, loadout, position FROM users WHERE identifier = @identifier', { ['@identifier'] = player.getIdentifier() }, function(result) local job, grade = result[1].job, tostring(result[1].job_grade) From 9be9b07e7584b4791b19dfa4a8410a0188ef5ca3 Mon Sep 17 00:00:00 2001 From: nearbyplayer <3721216+nearbyplayer@users.noreply.github.com> Date: Thu, 29 Aug 2019 17:25:04 -0400 Subject: [PATCH 2262/3224] Update README.md Add Warning --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 51162faa..90125428 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # fxserver-esx_sit +### Warning: This resource is not actively maintained. The ESX Teams has higher priorties than this particular add-on, if you have a suggestion open a PR. The likelihood of the ESX Team making feature based updates to esx_sit are unlikely. Thanks for understanding! + This script allow you to sit almost everywhere. If the player has many props around him, the game camera might become crazy. @@ -18,4 +20,4 @@ start esx_sit ``` [CREDITS] -- Original code by CmJustice https://github.com/CmJustice \ No newline at end of file +- Original code by CmJustice https://github.com/CmJustice From 01d2768df9e1afcdf57a8dc43e027dfcf3ffcc84 Mon Sep 17 00:00:00 2001 From: JHyeok Date: Sun, 1 Sep 2019 16:23:48 +0900 Subject: [PATCH 2263/3224] Added Korean Language --- html/ko_index.html | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 html/ko_index.html diff --git a/html/ko_index.html b/html/ko_index.html new file mode 100644 index 00000000..c04fe9b7 --- /dev/null +++ b/html/ko_index.html @@ -0,0 +1,22 @@ + + + + + + + +
    +
    +

    등록

    +
    +
    +
    +
    + 남자 + 여자
    + +
    +
    + + + \ No newline at end of file From 9e80de864f2632b058dce8077887deba0b60840d Mon Sep 17 00:00:00 2001 From: JHyeok Date: Tue, 3 Sep 2019 00:45:37 +0900 Subject: [PATCH 2264/3224] Add Korean Language --- __resource.lua | 1 + locales/ko.lua | 6 ++++++ 2 files changed, 7 insertions(+) create mode 100644 locales/ko.lua diff --git a/__resource.lua b/__resource.lua index d314d63b..7d4e3ed8 100644 --- a/__resource.lua +++ b/__resource.lua @@ -12,6 +12,7 @@ client_scripts { 'locales/fr.lua', 'locales/pl.lua', 'locales/sv.lua', + 'locales/ko.lua', 'config.lua', 'client/main.lua' } diff --git a/locales/ko.lua b/locales/ko.lua new file mode 100644 index 00000000..c4c7fc64 --- /dev/null +++ b/locales/ko.lua @@ -0,0 +1,6 @@ +Locales ['ko'] = { + ['voice'] = '~y~목소리: ~s~%s', + ['normal'] = '보통', + ['shout'] = '외침', + ['whisper'] = '속삭임', +} From cf39f7c7d76242958ff88b255758d172df1681d9 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 8 Sep 2019 13:22:09 +0200 Subject: [PATCH 2265/3224] Fixed invisable bug once and for all, closes #13 --- client/main.lua | 18 +++++++++++------- server/main.lua | 6 ++++++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/client/main.lua b/client/main.lua index 189d77d6..c8336ea8 100644 --- a/client/main.lua +++ b/client/main.lua @@ -176,16 +176,16 @@ Citizen.CreateThread(function() if instance.host then -- Get players and sets them as pairs for k,v in ipairs(GetActivePlayers()) do - playersToHide[v] = true + playersToHide[GetPlayerServerId(v)] = true end -- Dont set our instanced players invisible for _,player in ipairs(instance.players) do - playersToHide[GetPlayerFromServerId(player)] = nil + playersToHide[player] = nil end else for player,_ in pairs(instancedPlayers) do - playersToHide[GetPlayerFromServerId(player)] = true + playersToHide[player] = true end end end @@ -197,10 +197,14 @@ Citizen.CreateThread(function() local playerPed = PlayerPedId() -- Hide all these players - for player,_ in pairs(playersToHide) do - local otherPlayerPed = GetPlayerPed(player) - SetEntityVisible(otherPlayerPed, false, false) - SetEntityNoCollisionEntity(playerPed, otherPlayerPed, false) + for serverId,_ in pairs(playersToHide) do + local player = GetPlayerFromServerId(serverId) + + if NetworkIsPlayerActive(player) then + local otherPlayerPed = GetPlayerPed(player) + SetEntityVisible(otherPlayerPed, false, false) + SetEntityNoCollisionEntity(playerPed, otherPlayerPed, false) + end end end end) diff --git a/server/main.lua b/server/main.lua index b7fcf132..3f51be44 100644 --- a/server/main.lua +++ b/server/main.lua @@ -12,6 +12,12 @@ function GetInstancedPlayers() return players end +AddEventHandler('playerDropped', function(reason) + if instances[source] then + CloseInstance(source) + end +end) + function CreateInstance(type, player, data) instances[player] = { type = type, From 8586fdcce24eb98ba06cab046424382483236fe0 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 18 Sep 2019 13:47:41 +0200 Subject: [PATCH 2266/3224] Fix thrown items not synced with mid-joined players --- client/main.lua | 18 ++++++++++++++++++ server/functions.lua | 9 ++++++--- server/main.lua | 1 + 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/client/main.lua b/client/main.lua index 722d4041..b71d5cf1 100644 --- a/client/main.lua +++ b/client/main.lua @@ -40,6 +40,24 @@ AddEventHandler('esx:playerLoaded', function(xPlayer) end end) +RegisterNetEvent('esx:createMissingPickups') +AddEventHandler('esx:createMissingPickups', function(pickups) + for pickupId,v in pairs(pickups) do + ESX.Game.SpawnLocalObject('prop_money_bag_01', v.coords, function(obj) + SetEntityAsMissionEntity(obj, true, false) + PlaceObjectOnGroundProperly(obj) + + Pickups[pickupId] = { + id = pickupId, + obj = obj, + label = v.label, + inRange = false, + coords = v.coords + } + end) + end +end) + AddEventHandler('playerSpawned', function() while not ESX.PlayerLoaded do Citizen.Wait(1) diff --git a/server/functions.lua b/server/functions.lua index 351c0511..3ab80291 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -162,16 +162,19 @@ ESX.GetItemLabel = function(item) end end -ESX.CreatePickup = function(type, name, count, label, player) +ESX.CreatePickup = function(type, name, count, label, playerId) local pickupId = (ESX.PickupId == 65635 and 0 or ESX.PickupId + 1) + local xPlayer = ESX.GetPlayerFromId(playerId) ESX.Pickups[pickupId] = { type = type, name = name, - count = count + count = count, + label = label, + coords = xPlayer.getCoords() } - TriggerClientEvent('esx:pickup', -1, pickupId, label, player) + TriggerClientEvent('esx:pickup', -1, pickupId, label, playerId) ESX.PickupId = pickupId end diff --git a/server/main.lua b/server/main.lua index 57e4b615..86d7f2f4 100644 --- a/server/main.lua +++ b/server/main.lua @@ -234,6 +234,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) }) xPlayer.displayMoney(xPlayer.getMoney()) + TriggerClientEvent('esx:createMissingPickups', _source, ESX.Pickups) end) end) From 96f9dab2a8a0f88fa5ecd0b0c9a61fbe152b306b Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 18 Sep 2019 18:39:21 +0200 Subject: [PATCH 2267/3224] Dont let model be changed, as it cant be changed in LS anyways and is used to cheat Co-Authored-By: danishrp --- server/main.lua | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/server/main.lua b/server/main.lua index 50e5145a..23432b8e 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,6 +1,7 @@ ESX = nil +local Vehicles + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) -local Vehicles = nil RegisterServerEvent('esx_lscustom:buyMod') AddEventHandler('esx_lscustom:buyMod', function(price) @@ -9,11 +10,12 @@ AddEventHandler('esx_lscustom:buyMod', function(price) price = tonumber(price) if Config.IsMechanicJobOnly then + local societyAccount - local societyAccount = nil TriggerEvent('esx_addonaccount:getSharedAccount', 'society_mechanic', function(account) societyAccount = account end) + if price < societyAccount.money then TriggerClientEvent('esx_lscustom:installMod', _source) TriggerClientEvent('esx:showNotification', _source, _U('purchased')) @@ -22,9 +24,7 @@ AddEventHandler('esx_lscustom:buyMod', function(price) TriggerClientEvent('esx_lscustom:cancelInstallMod', _source) TriggerClientEvent('esx:showNotification', _source, _U('not_enough_money')) end - else - if price < xPlayer.getMoney() then TriggerClientEvent('esx_lscustom:installMod', _source) TriggerClientEvent('esx:showNotification', _source, _U('purchased')) @@ -33,21 +33,33 @@ AddEventHandler('esx_lscustom:buyMod', function(price) TriggerClientEvent('esx_lscustom:cancelInstallMod', _source) TriggerClientEvent('esx:showNotification', _source, _U('not_enough_money')) end - end end) RegisterServerEvent('esx_lscustom:refreshOwnedVehicle') -AddEventHandler('esx_lscustom:refreshOwnedVehicle', function(myCar) - MySQL.Async.execute('UPDATE `owned_vehicles` SET `vehicle` = @vehicle WHERE `plate` = @plate', - { - ['@plate'] = myCar.plate, - ['@vehicle'] = json.encode(myCar) - }) +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) + + 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) + }) + else + print(('esx_lscustom: %s attempted to upgrade vehicle with mismatching vehicle model!'):format(xPlayer.identifier)) + end + end + end) end) ESX.RegisterServerCallback('esx_lscustom:getVehiclesPrices', function(source, cb) - if Vehicles == nil then + if not Vehicles then MySQL.Async.fetchAll('SELECT * FROM vehicles', {}, function(result) local vehicles = {} From cceee68ca7271a14aac5556f6055ef9ad1f15e01 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 18 Sep 2019 18:39:36 +0200 Subject: [PATCH 2268/3224] Minor cleanup Co-Authored-By: danishrp --- client/main.lua | 78 ++++++++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 43 deletions(-) diff --git a/client/main.lua b/client/main.lua index eb7de0ce..0593c62d 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,21 +1,9 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - -ESX = nil -local Vehicles = {} -local PlayerData = {} -local lsMenuIsShowed = false -local isInLSMarker = false -local myCar = {} +ESX = nil +local Vehicles = {} +local PlayerData = {} +local lsMenuIsShowed = false +local isInLSMarker = false +local myCar = {} Citizen.CreateThread(function() while ESX == nil do @@ -27,6 +15,7 @@ end) RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) PlayerData = xPlayer + ESX.TriggerServerCallback('esx_lscustom:getVehiclesPrices', function(vehicles) Vehicles = vehicles end) @@ -83,16 +72,16 @@ function OpenLSMenu(elems, menuName, menuTitle, parent) if isRimMod then price = math.floor(vehiclePrice * data.current.price / 100) - TriggerServerEvent("esx_lscustom:buyMod", price) + TriggerServerEvent('esx_lscustom:buyMod', price) elseif v.modType == 11 or v.modType == 12 or v.modType == 13 or v.modType == 15 or v.modType == 16 then price = math.floor(vehiclePrice * v.price[data.current.modNum + 1] / 100) - TriggerServerEvent("esx_lscustom:buyMod", price) + TriggerServerEvent('esx_lscustom:buyMod', price) elseif v.modType == 17 then price = math.floor(vehiclePrice * v.price[1] / 100) - TriggerServerEvent("esx_lscustom:buyMod", price) + TriggerServerEvent('esx_lscustom:buyMod', price) else price = math.floor(vehiclePrice * v.price / 100) - TriggerServerEvent("esx_lscustom:buyMod", price) + TriggerServerEvent('esx_lscustom:buyMod', price) end end @@ -128,10 +117,10 @@ end function UpdateMods(data) local vehicle = GetVehiclePedIsIn(PlayerPedId(), false) - if data.modType ~= nil then + if data.modType then local props = {} - if data.wheelType ~= nil then + if data.wheelType then props['wheels'] = data.wheelType ESX.Game.SetVehicleProperties(vehicle, props) props = {} @@ -199,7 +188,7 @@ function GetAction(data) menuTitle = v.label parent = v.parent - if v.modType ~= nil then + if v.modType then if v.modType == 22 then table.insert(elements, {label = " " .. _U('by_default'), modType = k, modNum = false}) @@ -283,7 +272,7 @@ function GetAction(data) local modCount = GetNumVehicleMods(vehicle, v.modType) for j = 0, modCount, 1 do local modName = GetModTextLabel(vehicle, v.modType, j) - if modName ~= nil then + if modName then local _label = '' if j == currentMods.modFrontWheels then _label = GetLabelText(modName) .. ' - '.. _U('installed') ..'' @@ -321,7 +310,7 @@ function GetAction(data) local modCount = GetNumVehicleMods(vehicle, v.modType) -- BODYPARTS for j = 0, modCount, 1 do local modName = GetModTextLabel(vehicle, v.modType, j) - if modName ~= nil then + if modName then local _label = '' if j == currentMods[k] then _label = GetLabelText(modName) .. ' - '.. _U('installed') ..'' @@ -369,11 +358,13 @@ end Citizen.CreateThread(function() for k,v in pairs(Config.Zones) do local blip = AddBlipForCoord(v.Pos.x, v.Pos.y, v.Pos.z) + SetBlipSprite(blip, 72) SetBlipScale(blip, 0.8) SetBlipAsShortRange(blip, true) - BeginTextCommandSetBlipName("STRING") - AddTextComponentString(v.Name) + + BeginTextCommandSetBlipName('STRING') + AddTextComponentSubstringPlayerName(v.Name) EndTextCommandSetBlipName(blip) end end) @@ -383,12 +374,12 @@ Citizen.CreateThread(function() while true do Citizen.Wait(0) local playerPed = PlayerPedId() + if IsPedInAnyVehicle(playerPed, false) then - local coords = GetEntityCoords(PlayerPedId()) - local currentZone = nil - local zone = nil - local lastZone = nil - if (PlayerData.job ~= nil and PlayerData.job.name == 'mechanic') or Config.IsMechanicJobOnly == false then + local coords = GetEntityCoords(PlayerPedId()) + local currentZone, zone, lastZone + + if (PlayerData.job and PlayerData.job.name == 'mechanic') or not Config.IsMechanicJobOnly then for k,v in pairs(Config.Zones) do if GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x then isInLSMarker = true @@ -400,8 +391,8 @@ Citizen.CreateThread(function() end end - if IsControlJustReleased(0, Keys['E']) and not lsMenuIsShowed and isInLSMarker then - if (PlayerData.job ~= nil and PlayerData.job.name == 'mechanic') or Config.IsMechanicJobOnly == false then + if IsControlJustReleased(0, 38) and not lsMenuIsShowed and isInLSMarker then + if (PlayerData.job and PlayerData.job.name == 'mechanic') or not Config.IsMechanicJobOnly then lsMenuIsShowed = true local vehicle = GetVehiclePedIsIn(playerPed, false) @@ -429,14 +420,15 @@ end) -- Prevent Free Tunning Bug Citizen.CreateThread(function() while true do - Citizen.Wait(1) + Citizen.Wait(0) + if lsMenuIsShowed then - DisableControlAction(2, Keys['F1'], true) - DisableControlAction(2, Keys['F2'], true) - DisableControlAction(2, Keys['F3'], true) - DisableControlAction(2, Keys['F6'], true) - DisableControlAction(2, Keys['F7'], true) - DisableControlAction(2, Keys['F'], true) + DisableControlAction(2, 288, true) + DisableControlAction(2, 289, true) + DisableControlAction(2, 170, true) + DisableControlAction(2, 167, true) + DisableControlAction(2, 168, true) + DisableControlAction(2, 23, true) DisableControlAction(0, 75, true) -- Disable exit vehicle DisableControlAction(27, 75, true) -- Disable exit vehicle else From 440769caedbd1340069e3045590dd8011775011c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 22 Sep 2019 13:00:24 +0200 Subject: [PATCH 2269/3224] Further cleanup --- client/main.lua | 206 ++++++++++++++++++------------------------------ config.lua | 29 +++---- locales/en.lua | 6 +- server/main.lua | 2 +- 4 files changed, 91 insertions(+), 152 deletions(-) diff --git a/client/main.lua b/client/main.lua index 7be8e70a..a6cf415c 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,24 +1,5 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - -ESX = nil -local GUI = {} -GUI.Time = 0 -local HasAlreadyEnteredMarker = false -local LastZone = nil -local CurrentAction = nil -local CurrentActionMsg = '' -local CurrentActionData = {} -local HasPaid = false +ESX = nil +local hasAlreadyEnteredMarker, lastZone, currentAction, currentActionMsg, hasPaid Citizen.CreateThread(function() while ESX == nil do @@ -28,71 +9,55 @@ Citizen.CreateThread(function() end) function OpenShopMenu() - - HasPaid = false + hasPaid = false TriggerEvent('esx_skin:openRestrictedMenu', function(data, menu) - menu.close() - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'shop_confirm', - { - title = _U('valid_purchase'), - align = 'top-left', - elements = { - {label = _U('no'), value = 'no'}, - {label = _U('yes'), value = 'yes'} - } - }, - function(data, menu) - menu.close() - - if data.current.value == 'yes' then - - ESX.TriggerServerCallback('esx_barbershop:checkMoney', function(hasEnoughMoney) - if hasEnoughMoney then - TriggerEvent('skinchanger:getSkin', function(skin) - TriggerServerEvent('esx_skin:save', skin) - end) - - TriggerServerEvent('esx_barbershop:pay') - - HasPaid = true - else - ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin) - TriggerEvent('skinchanger:loadSkin', skin) - end) - - ESX.ShowNotification(_U('not_enough_money')) - end - end) - - elseif data.current.value == 'no' then - - ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin) - TriggerEvent('skinchanger:loadSkin', skin) - end) - - end - - CurrentAction = 'shop_menu' - CurrentActionMsg = _U('press_access') - CurrentActionData = {} - end, function(data, menu) - menu.close() - - CurrentAction = 'shop_menu' - CurrentActionMsg = _U('press_access') - CurrentActionData = {} - end) - - end, function(data, menu) + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'shop_confirm', { + title = _U('valid_purchase'), + align = 'top-left', + elements = { + {label = _U('no'), value = 'no'}, + {label = _U('yes'), value = 'yes'} + }}, function(data, menu) menu.close() - CurrentAction = 'shop_menu' - CurrentActionMsg = _U('press_access') - CurrentActionData = {} + if data.current.value == 'yes' then + ESX.TriggerServerCallback('esx_barbershop:checkMoney', function(hasEnoughMoney) + if hasEnoughMoney then + TriggerEvent('skinchanger:getSkin', function(skin) + TriggerServerEvent('esx_skin:save', skin) + end) + + TriggerServerEvent('esx_barbershop:pay') + hasPaid = true + else + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin) + TriggerEvent('skinchanger:loadSkin', skin) + end) + + ESX.ShowNotification(_U('not_enough_money')) + end + end) + elseif data.current.value == 'no' then + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin) + TriggerEvent('skinchanger:loadSkin', skin) + end) + end + + currentAction = 'shop_menu' + currentActionMsg = _U('press_access') + end, function(data, menu) + menu.close() + currentAction = 'shop_menu' + currentActionMsg = _U('press_access') + end) + end, function(data, menu) + menu.close() + + currentAction = 'shop_menu' + currentActionMsg = _U('press_access') end, { 'beard_1', 'beard_2', @@ -117,85 +82,70 @@ function OpenShopMenu() 'ears_1', 'ears_2', }) - end AddEventHandler('esx_barbershop:hasEnteredMarker', function(zone) - CurrentAction = 'shop_menu' - CurrentActionMsg = _U('press_access') - CurrentActionData = {} + currentAction = 'shop_menu' + currentActionMsg = _U('press_access') end) AddEventHandler('esx_barbershop:hasExitedMarker', function(zone) ESX.UI.Menu.CloseAll() - CurrentAction = nil + currentAction = nil - if not HasPaid then + if not hasPaid then ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin) - TriggerEvent('skinchanger:loadSkin', skin) + TriggerEvent('skinchanger:loadSkin', skin) end) end end) -- Create Blips Citizen.CreateThread(function() - for i=1, #Config.Shops, 1 do - - local blip = AddBlipForCoord(Config.Shops[i].x, Config.Shops[i].y, Config.Shops[i].z) + for k,v in ipairs(Config.Shops) do + local blip = AddBlipForCoord(v) SetBlipSprite (blip, 71) - SetBlipDisplay(blip, 4) - SetBlipScale (blip, 1.0) SetBlipColour (blip, 51) SetBlipAsShortRange(blip, true) - BeginTextCommandSetBlipName("STRING") - AddTextComponentString(_U('barber_blip')) + BeginTextCommandSetBlipName('STRING') + AddTextComponentSubstringPlayerName(_U('barber_blip')) EndTextCommandSetBlipName(blip) - end end) --- Display markers +-- Enter / Exit marker events and draw marker Citizen.CreateThread(function() while true do Citizen.Wait(0) + local playerCoords, isInMarker, currentZone, letSleep = GetEntityCoords(PlayerPedId()), nil, nil, true - local coords = GetEntityCoords(PlayerPedId()) + for k,v in ipairs(Config.Shops) do + local distnace = #(playerCoords - v) - for k,v in pairs(Config.Zones) do - if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then - DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) - end - end - end -end) + if distance < Config.DrawDistance then + letSleep = false + DrawMarker(Config.MarkerType, v, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Config.MarkerSize, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, nil, nil, false) --- Enter / Exit marker events -Citizen.CreateThread(function() - while true do - Citizen.Wait(200) - - local coords = GetEntityCoords(PlayerPedId()) - local isInMarker = false - local currentZone = nil - - for k,v in pairs(Config.Zones) do - if GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x then - isInMarker = true - currentZone = k + if distnace < 1.5 then + isInMarker, currentZone = true, k + end end end - if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then - HasAlreadyEnteredMarker = true - LastZone = currentZone + if (isInMarker and not hasAlreadyEnteredMarker) or (isInMarker and lastZone ~= currentZone) then + hasAlreadyEnteredMarker, lastZone = true, currentZone TriggerEvent('esx_barbershop:hasEnteredMarker', currentZone) end - if not isInMarker and HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = false - TriggerEvent('esx_barbershop:hasExitedMarker', LastZone) + if not isInMarker and hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = false + TriggerEvent('esx_barbershop:hasExitedMarker', lastZone) + end + + if letSleep then + Citizen.Wait(500) end end end) @@ -205,15 +155,15 @@ Citizen.CreateThread(function() while true do Citizen.Wait(0) - if CurrentAction ~= nil then - ESX.ShowHelpNotification(CurrentActionMsg) + if currentAction then + ESX.ShowHelpNotification(currentActionMsg) - if IsControlJustReleased(0, Keys['E']) then - if CurrentAction == 'shop_menu' then + if IsControlJustReleased(0, 38) then + if currentAction == 'shop_menu' then OpenShopMenu() end - CurrentAction = nil + currentAction = nil end else Citizen.Wait(500) diff --git a/config.lua b/config.lua index 4ec366dc..2a4b6787 100644 --- a/config.lua +++ b/config.lua @@ -3,29 +3,18 @@ Config = {} Config.Price = 100 Config.DrawDistance = 100.0 -Config.MarkerSize = {x = 1.5, y = 1.5, z = 1.0} +Config.MarkerSize = vector3(1.5, 1.5, 1.0) Config.MarkerColor = {r = 102, g = 102, b = 204} Config.MarkerType = 1 Config.Locale = 'fr' -Config.Zones = {} - Config.Shops = { - {x = -814.308, y = -183.823, z = 36.568}, - {x = 136.826, y = -1708.373, z = 28.291}, - {x = -1282.604, y = -1116.757, z = 5.990}, - {x = 1931.513, y = 3729.671, z = 31.844}, - {x = 1212.840, y = -472.921, z = 65.208}, - {x = -32.885, y = -152.319, z = 56.076}, - {x = -278.077, y = 6228.463, z = 30.695} -} - -for i=1, #Config.Shops, 1 do - Config.Zones['Shop_' .. i] = { - Pos = Config.Shops[i], - Size = Config.MarkerSize, - Color = Config.MarkerColor, - Type = Config.MarkerType - } -end + vector3(-814.3, -183.8, 36.6), + vector3(136.8, -1708.4, 28.3), + vector3(-1282.6, -1116.8, 6.0), + vector3(1931.5, 3729.7, 31.8), + vector3(1212.8, -472.9, 65.2), + vector3(-32.9, -152.3, 56.1), + vector3(-278.1, 6228.5, 30.7) +} \ No newline at end of file diff --git a/locales/en.lua b/locales/en.lua index 0dc26ab0..684323e4 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -3,7 +3,7 @@ Locales['en'] = { ['yes'] = 'yes', ['no'] = 'no', ['not_enough_money'] = 'you do not have enough money', - ['press_access'] = 'press ~INPUT_CONTEXT~ to access the menu', - ['barber_blip'] = 'barber shop', - ['you_paid'] = 'you paid $%s', + ['press_access'] = 'press ~INPUT_CONTEXT~ to access the ~y~Barber Shop~s~.', + ['barber_blip'] = 'barber Shop', + ['you_paid'] = 'you paid ~g~$%s~s~', } diff --git a/server/main.lua b/server/main.lua index b6fbf525..516beaa5 100644 --- a/server/main.lua +++ b/server/main.lua @@ -14,5 +14,5 @@ end) ESX.RegisterServerCallback('esx_barbershop:checkMoney', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) - cb(xPlayer.get('money') >= Config.Price) + cb(xPlayer.getMoney() >= Config.Price) end) From 1d6cf75c6335ab0049e155fead9af52e67ec2a62 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 22 Sep 2019 13:08:17 +0200 Subject: [PATCH 2270/3224] Fixed typo --- client/main.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index a6cf415c..c2dee892 100644 --- a/client/main.lua +++ b/client/main.lua @@ -122,13 +122,13 @@ Citizen.CreateThread(function() local playerCoords, isInMarker, currentZone, letSleep = GetEntityCoords(PlayerPedId()), nil, nil, true for k,v in ipairs(Config.Shops) do - local distnace = #(playerCoords - v) + local distance = #(playerCoords - v) if distance < Config.DrawDistance then letSleep = false DrawMarker(Config.MarkerType, v, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Config.MarkerSize, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, nil, nil, false) - if distnace < 1.5 then + if distance < 1.5 then isInMarker, currentZone = true, k end end From 06952418bf3b5ae86fb7f7de3de2ada498b5f927 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 29 Sep 2019 11:30:21 +0200 Subject: [PATCH 2271/3224] DrawText3D: use SetDrawOrigin() instead of World3dToScreen2d() that was one frame behind --- client/functions.lua | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 486d5551..726c7311 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -984,32 +984,30 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) end ESX.Game.Utils.DrawText3D = function(coords, text, size) - local onScreen, x, y = World3dToScreen2d(coords.x, coords.y, coords.z) - local camCoords = GetGameplayCamCoords() - local dist = GetDistanceBetweenCoords(camCoords, coords.x, coords.y, coords.z, true) - local size = size + coords = vector3(coords.x, coords.y, coords.z) - if size == nil then - size = 1 - end + local camCoords = GetGameplayCamCoords() + local distance = #(coords - camCoords) - local scale = (size / dist) * 2 - local fov = (1 / GetGameplayCamFov()) * 100 - local scale = scale * fov + if not size then size = 1 end + + local scale = (size / distance) * 2 + local fov = (1 / GetGameplayCamFov()) * 100 + scale = scale * fov - if onScreen then - SetTextScale(0.0 * scale, 0.55 * scale) - SetTextFont(0) - SetTextColour(255, 255, 255, 255) - SetTextDropshadow(0, 0, 0, 0, 255) - SetTextDropShadow() - SetTextOutline() - SetTextEntry('STRING') - SetTextCentre(1) + SetTextScale(0.0 * scale, 0.55 * scale) + SetTextFont(0) + SetTextColour(255, 255, 255, 255) + SetTextDropshadow(0, 0, 0, 0, 255) + SetTextDropShadow() + SetTextOutline() + SetTextCentre(true) - AddTextComponentString(text) - DrawText(x, y) - end + SetDrawOrigin(coords, 0) + BeginTextCommandDisplayText('STRING') + AddTextComponentSubstringPlayerName(text) + EndTextCommandDisplayText(0.0, 0.0) + ClearDrawOrigin() end ESX.ShowInventory = function() From 8a7cf56497285285b76ed54157ea24766edf5bed Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 29 Sep 2019 11:30:42 +0200 Subject: [PATCH 2272/3224] xPlayer.getCoords() round to one decimal from ES --- server/classes/player.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index bad6436c..0c5158f8 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -41,7 +41,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.getCoords = function() - return self.player.get('coords') + local coords = self.player.get('coords') + return {x = ESX.Math.Round(coords.x, 1), y = ESX.Math.Round(coords.y, 1), z = ESX.Math.Round(coords.z, 1)} end self.setCoords = function(x, y, z) From 4000e1eb34e5779c3020db2e91843da85b45efc7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 6 Oct 2019 20:29:21 +0200 Subject: [PATCH 2273/3224] Added DrawText3D() optional font argument --- client/functions.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 726c7311..a167c934 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -983,20 +983,21 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) end end -ESX.Game.Utils.DrawText3D = function(coords, text, size) +ESX.Game.Utils.DrawText3D = function(coords, text, size, font) coords = vector3(coords.x, coords.y, coords.z) local camCoords = GetGameplayCamCoords() local distance = #(coords - camCoords) if not size then size = 1 end + if not font then font = 0 end local scale = (size / distance) * 2 local fov = (1 / GetGameplayCamFov()) * 100 scale = scale * fov SetTextScale(0.0 * scale, 0.55 * scale) - SetTextFont(0) + SetTextFont(font) SetTextColour(255, 255, 255, 255) SetTextDropshadow(0, 0, 0, 0, 255) SetTextDropShadow() From 546ac33b1a82bed78ada9e922a6324745c15a0c8 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 6 Oct 2019 20:29:56 +0200 Subject: [PATCH 2274/3224] Added xPlayer .showNotification() and .showHelpNotification() --- server/classes/player.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/server/classes/player.lua b/server/classes/player.lua index 0c5158f8..f4e75e1a 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -481,5 +481,13 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l return nil end + self.showNotification = function(msg) + TriggerClientEvent('esx:showNotification', self.source, msg) + end + + self.showHelpNotification = function(msg) + TriggerClientEvent('esx:showHelpNotification', self.source, msg) + end + return self end From 322fb19034add1dfbcaf03c2e092ce73de7035bf Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 9 Oct 2019 21:55:44 +0200 Subject: [PATCH 2275/3224] Fixed #350 --- client/main.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/main.lua b/client/main.lua index b4819a15..2950bcda 100644 --- a/client/main.lua +++ b/client/main.lua @@ -41,13 +41,13 @@ AddEventHandler('esx:playerLoaded', function(xPlayer) end) RegisterNetEvent('esx:createMissingPickups') -AddEventHandler('esx:createMissingPickups', function(pickups) - for pickupId,v in pairs(pickups) do +AddEventHandler('esx:createMissingPickups', function(missingPickups) + for pickupId,v in pairs(missingPickups) do ESX.Game.SpawnLocalObject('prop_money_bag_01', v.coords, function(obj) SetEntityAsMissionEntity(obj, true, false) PlaceObjectOnGroundProperly(obj) - Pickups[pickupId] = { + pickups[pickupId] = { id = pickupId, obj = obj, label = v.label, From a791aebfd4d616ccaf9766a23b1fefd442bd56ed Mon Sep 17 00:00:00 2001 From: userMacieG Date: Fri, 11 Oct 2019 11:25:31 +0200 Subject: [PATCH 2276/3224] Update README.md --- README.md | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 1588f62b..fc5e3235 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,28 @@ # esx_voice -FXServer ESX Voice - - -#### Description This is a proximity voice controller script. The default control for this is `Left Shift + H` (QWERTY). -#### Download +## Download & Installation -**1) Using [fvm](https://github.com/qlaffont/fvm-installer)** +### Using [fvm](https://github.com/qlaffont/fvm-installer) ``` fvm install --save --folder=esx esx-org/esx_voice ``` -**2) Manually** -- Download https://github.com/ESX-Org/esx_voice/releases/latest -- Put it in resource/[esx] directory - -**3) Using Git** - +### Using Git ``` -cd resouces -git clone https://github.com/ESX-Org/esx_voice +cd resources +git clone https://github.com/ESX-Org/esx_voice [esx]/esx_voice ``` -#### Installation +### Manually +- Download https://github.com/ESX-Org/esx_voice/archive/master.zip +- Put it in the `[esx]` directory -1) Add `start esx_voice` to your server.cfg +## Installation +Add this into your `server.cfg` +``` +start esx_voice +``` - -#### Credits -Original Script by [aabbfive](https://github.com/aabbfive/voicecontroller) +## Credits +[aabbfive](https://github.com/aabbfive/voicecontroller) - Original author From f438ea21dbb4744c65b88cb6e9a7be977f02424a Mon Sep 17 00:00:00 2001 From: userMacieG Date: Fri, 11 Oct 2019 14:35:49 +0200 Subject: [PATCH 2277/3224] Update pl.lua --- locales/pl.lua | 61 +++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/locales/pl.lua b/locales/pl.lua index c898ca26..ee840465 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -5,20 +5,20 @@ Locales['pl'] = { ['use'] = 'użyj', ['give'] = 'daj', ['remove'] = 'usuń', - ['return'] = 'return', - ['give_to'] = 'give to', - ['amount'] = 'amount', - ['giveammo'] = 'give ammo', + ['return'] = 'wróć', + ['give_to'] = 'daj dla', + ['amount'] = 'ilość', + ['giveammo'] = 'daj amunicje', ['amountammo'] = 'ilość amunicji', - ['noammo'] = 'nie masz wystarczającej ilości amunicji!', + ['noammo'] = 'nie posiadasz wystarczającej ilości amunicji!', ['gave_item'] = 'dajesz ~y~%sx~s~ ~b~%s~s~ dla ~y~%s~s~', ['received_item'] = 'otrzymujesz ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', - ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ to ~y~%s~s~.', - ['gave_weapon_ammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', - ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', - ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ from ~b~%s~s~.', - ['received_weapon_ammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', - ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one.', + ['gave_weapon'] = 'dajesz ~y~1x~s~ ~b~%s~s~ dla ~y~%s~s~.', + ['gave_weapon_ammo'] = 'dałeś/aś ~y~1x~s~ ~b~%s~s~ z ~o~%sx~s~ nabojami dla ~y~%s~s~.', + ['gave_weapon_hasalready'] = '~y~%s~s~ już posiada ~y~%s~s~', + ['received_weapon'] = 'otrzymałeś/aś ~y~1x~s~ ~b~%s~s~ od ~b~%s~s~.', + ['received_weapon_ammo'] = 'otrzymałeś/aś ~y~1x~s~ ~b~%s~s~ z ~o~%sx~s~ nabojami od ~b~%s~s~.', + ['received_weapon_hasalready'] = '~b~%s~s~ próbował/a przekazać ci ~y~%s~s~, lecz już posiadasz jedno.', ['gave_ammo'] = 'dajesz ~o~%sx~s~ naboje dla ~y~%s~s~.', ['received_ammo'] = 'otrzymujesz ~o~%sx~s~ naboje od ~b~%s~s~.', ['gave_money'] = 'dajesz ~g~%s$~s~ dla ~y~%s~s~', @@ -30,11 +30,12 @@ Locales['pl'] = { ['ex_inv_lim'] = 'akcja nie jest możliwa, nie możesz mieć więcej ~y~%s~s~', ['imp_invalid_quantity'] = 'akcja jest niemożliwa, nieprawidłowa ilość', ['imp_invalid_amount'] = 'akcja jest niemożliwa, nieprawidłowa kwota', - ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', - ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', - ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_standard'] = 'wyrzuciłeś/aś ~y~%sx~s~ ~b~%s~s~', + ['threw_money'] = 'wyrzuciłeś/aś ~r~$%s~s~ ~b~gotówki~s~', + ['threw_account'] = 'wyrzuciłeś/aś ~r~$%s~s~ ~b~%s~s~', + ['threw_weapon'] = 'wyrzuciłeś/aś ~y~1x~s~ ~b~%s~s~', + ['threw_weapon_ammo'] = 'wyrzuciłeś/aś ~y~1x~s~ ~b~%s~s~ z ~o~%sx~s~ nabojami', + -- Salary related ['received_salary'] = 'otrzymałeś wynagrodzenie: ~g~%s$~s~', ['received_help'] = 'otrzymałem zapomogę: ~g~$%s~s~', @@ -42,14 +43,13 @@ Locales['pl'] = { ['received_paycheck'] = 'otrzymana wypłata', ['bank'] = 'bank', ['black_money'] = 'brudne pieniądze', - ['act_imp'] = 'działanie niemożliwe', ['in_vehicle'] = 'nie możesz przekazywać przedmiotów w pojeździe', ['cannot_pickup_room'] = 'nie masz wystarczająco dużo miejsca w ekwipunku, aby podnieść ~y~%s~s~!', -- Commands ['setjob'] = 'przydziel prace użytkownikowi', - ['id_param'] = 'iD użyszkodnika', + ['id_param'] = 'ID użytkownika', ['setjob_param2'] = 'praca, którą chcesz przydzielić', ['setjob_param3'] = 'poziom pracy', ['load_ipl'] = 'załaduj IPL', @@ -76,11 +76,12 @@ Locales['pl'] = { ['weapon'] = 'broń', ['giveweapon'] = 'daj broń', ['disconnect'] = 'odłącz się od serwera', - ['chat_clear'] = 'clear the chat', - ['chat_clear_all'] = 'clear the chat for everyone', - ['command_clearinventory'] = 'clear all items from inventory', - ['command_clearloadout'] = 'remove all weapons from loadout', - ['command_playerid_param'] = 'specify playerId or leave blank for yourself', + ['chat_clear'] = 'wyczyść czat', + ['chat_clear_all'] = 'wyczyść czat dla wszystkich', + ['command_clearinventory'] = 'usuń wszystkie przedmioty z ekwipunku', + ['command_clearloadout'] = 'usuń wszystkie bronie z wyposażenia', + ['command_playerid_param'] = 'id gracza lub zostaw puste dla siebie', + -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', @@ -167,14 +168,14 @@ Locales['pl'] = { ['weapon_doubleaction'] = 'double-Action Revolver', -- Weapon Components - ['component_clip_default'] = 'default Grip', - ['component_clip_extended'] = 'extended Grip', + ['component_clip_default'] = 'domyślny tłumik', + ['component_clip_extended'] = 'rozszerzony tłumik', ['component_clip_drum'] = 'drum Magazine', ['component_clip_box'] = 'box Magazine', - ['component_flashlight'] = 'flashlight', - ['component_scope'] = 'scope', - ['component_scope_advanced'] = 'advanced Scope', - ['component_suppressor'] = 'suppressor', - ['component_grip'] = 'grip', + ['component_flashlight'] = 'latarka', + ['component_scope'] = 'luneta', + ['component_scope_advanced'] = 'zaawansowana luneta', + ['component_suppressor'] = 'tłumik', + ['component_grip'] = 'uchwyt', ['component_luxary_finish'] = 'luxary Weapon Finish', } From 64a954a61b5d3bb9e564d81a739ee5a0da2784f1 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 12 Oct 2019 23:41:40 +0200 Subject: [PATCH 2278/3224] Dont use misleading keys table --- client/main.lua | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/client/main.lua b/client/main.lua index d5e4f6d6..f5cb316e 100644 --- a/client/main.lua +++ b/client/main.lua @@ -6,21 +6,8 @@ Citizen.CreateThread(function() Citizen.Wait(0) end - local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 - } - - local GUI = {} - GUI.Time = 0 - local MenuType = 'default' + local GUI, MenuType = {}, 'default' + GUI.Time = 0 local openMenu = function(namespace, name, data) SendNUIMessage({ @@ -29,7 +16,6 @@ Citizen.CreateThread(function() name = name, data = data }) - end local closeMenu = function(namespace, name) @@ -46,7 +32,7 @@ Citizen.CreateThread(function() RegisterNUICallback('menu_submit', function(data, cb) local menu = ESX.UI.Menu.GetOpened(MenuType, data._namespace, data._name) - if menu.submit ~= nil then + if menu.submit then menu.submit(data, menu) end @@ -56,7 +42,7 @@ Citizen.CreateThread(function() RegisterNUICallback('menu_cancel', function(data, cb) local menu = ESX.UI.Menu.GetOpened(MenuType, data._namespace, data._name) - if menu.cancel ~= nil then + if menu.cancel then menu.cancel(data, menu) end @@ -77,7 +63,7 @@ Citizen.CreateThread(function() end - if menu.change ~= nil then + if menu.change then menu.change(data, menu) end @@ -89,7 +75,7 @@ Citizen.CreateThread(function() Citizen.Wait(10) - if IsControlPressed(0, Keys['ENTER']) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 150 then + if IsControlPressed(0, 18) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 150 then SendNUIMessage({ action = 'controlPressed', control = 'ENTER' @@ -98,7 +84,7 @@ Citizen.CreateThread(function() GUI.Time = GetGameTimer() end - if IsControlPressed(0, Keys['BACKSPACE']) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 150 then + if IsControlPressed(0, 177) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 150 then SendNUIMessage({ action = 'controlPressed', control = 'BACKSPACE' @@ -107,7 +93,7 @@ Citizen.CreateThread(function() GUI.Time = GetGameTimer() end - if IsControlPressed(0, Keys['TOP']) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 200 then + if IsControlPressed(0, 27) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 200 then SendNUIMessage({ action = 'controlPressed', control = 'TOP' @@ -116,7 +102,7 @@ Citizen.CreateThread(function() GUI.Time = GetGameTimer() end - if IsControlPressed(0, Keys['DOWN']) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 200 then + if IsControlPressed(0, 173) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 200 then SendNUIMessage({ action = 'controlPressed', control = 'DOWN' @@ -125,7 +111,7 @@ Citizen.CreateThread(function() GUI.Time = GetGameTimer() end - if IsControlPressed(0, Keys['LEFT']) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 150 then + if IsControlPressed(0, 174) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 150 then SendNUIMessage({ action = 'controlPressed', control = 'LEFT' @@ -134,7 +120,7 @@ Citizen.CreateThread(function() GUI.Time = GetGameTimer() end - if IsControlPressed(0, Keys['RIGHT']) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 150 then + if IsControlPressed(0, 175) and IsInputDisabled(0) and (GetGameTimer() - GUI.Time) > 150 then SendNUIMessage({ action = 'controlPressed', control = 'RIGHT' From 18b16dea70d070dfca8e0573506457d070490126 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 12 Oct 2019 23:42:21 +0200 Subject: [PATCH 2279/3224] Removed keys table --- client/main.lua | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/client/main.lua b/client/main.lua index 5d66a8b6..7e039a26 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,15 +1,3 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - ESX = nil local HasAlreadyEnteredMarker = false local LastZone = nil @@ -167,7 +155,7 @@ Citizen.CreateThread(function() if CurrentAction ~= nil then ESX.ShowHelpNotification(CurrentActionMsg) - if IsControlJustReleased(0, Keys['E']) then + if IsControlJustReleased(0, 38) then if CurrentAction == 'shop_menu' then OpenShopMenu(CurrentActionData.zone) end From 6d2b30a511fd3ebf3853fa4605bc9e149eb69418 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 12 Oct 2019 23:46:05 +0200 Subject: [PATCH 2280/3224] Removed keys table --- client/main.lua | 32 +++++++------------------------- 1 file changed, 7 insertions(+), 25 deletions(-) diff --git a/client/main.lua b/client/main.lua index 2f23cacb..7b37ae4e 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,15 +1,3 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - local isDead = false local inAnim = false ESX = nil @@ -21,13 +9,9 @@ Citizen.CreateThread(function() end end) -AddEventHandler('esx:onPlayerDeath', function(data) - isDead = true -end) +AddEventHandler('esx:onPlayerDeath', function(data) isDead = true end) -AddEventHandler('playerSpawned', function(spawn) - isDead = false -end) +AddEventHandler('playerSpawned', function(spawn) isDead = false end) function startAttitude(lib, anim) ESX.Streaming.RequestAnimSet(lib, function() @@ -37,7 +21,7 @@ end function startAnim(lib, anim) ESX.Streaming.RequestAnimDict(lib, function() - TaskPlayAnim(PlayerPedId(), lib, anim, 8.0, -8.0, -1, 0, 0, false, false, false) + TaskPlayAnim(PlayerPedId(), lib, anim, 8.0, -8.0, -1, 0, 0.0, false, false, false) end) end @@ -52,8 +36,7 @@ function OpenAnimationsMenu() table.insert(elements, {label = Config.Animations[i].label, value = Config.Animations[i].name}) end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'animations', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'animations', { title = 'Animations', align = 'top-left', elements = elements @@ -85,8 +68,7 @@ function OpenAnimationsSubMenu(menu) end end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'animations_sub', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'animations_sub', { title = title, align = 'top-left', elements = elements @@ -112,11 +94,11 @@ Citizen.CreateThread(function() while true do Citizen.Wait(0) - if IsControlJustReleased(0, Keys['F3']) and IsInputDisabled(0) and not isDead then + if IsControlJustReleased(0, 170) and IsInputDisabled(0) and not isDead then OpenAnimationsMenu() end - if IsControlJustReleased(0, Keys['X']) and IsInputDisabled(0) and not isDead then + if IsControlJustReleased(0, 73) and IsInputDisabled(0) and not isDead then ClearPedTasks(PlayerPedId()) end From 61fe6e7323aafdbbee7a4319e2642703c50bc3e9 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 13 Oct 2019 16:38:56 +0200 Subject: [PATCH 2281/3224] Removed ES links, see #356 --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3c1d49ea..06cbe1ba 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,8 @@ # es_extended -es_extended is a roleplay framework for FiveM. It is developed on top of [EssentialMode](https://essentialmode.com/) (aka ES), thus commonly named ESX - the **Es**sentialMode E**x**tended framework for FiveM. +es_extended is a roleplay framework for FiveM. It is developed on top of EssentialMode (aka ES), thus commonly named ESX - the **Es**sentialMode E**x**tended framework for FiveM. ### Links & Read more - [ESX Documentation](https://esx-org.github.io/) -- [ES Documentation](https://docs.essentialmode.com/) - [ESX Discord Community](https://discord.gg/MsWzPqE) - [FiveM Forum Thread](https://forum.fivem.net/t/release-esx-base/39881) - [FiveM Native Reference](https://runtime.fivem.net/doc/reference.html) @@ -13,7 +12,7 @@ es_extended is a roleplay framework for FiveM. It is developed on top of [Essent ![screenshot](http://i.imgur.com/aPFdJl3.jpg) ### Features -- Accounts (bank / black money). You can add further accounts +- Accounts (comes with bank / black money), you can add more accounts - Advanced inventory system (press `F2` ingame) - Job system - Loadouts and position synced in database @@ -78,7 +77,7 @@ start esx_menu_dialog ### License es_extended - EssentialMode Extended framework for FiveM -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2019 Jérémie N'gadi 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. From 32e6c7edc216051d71750359cddb3d937a17c84c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 13 Oct 2019 16:39:29 +0200 Subject: [PATCH 2282/3224] Added optional xPlayer.getCoords() argument to return vector3 type --- server/classes/player.lua | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index f4e75e1a..6fc49b8a 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -40,9 +40,15 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l return self.player.get('bank') end - self.getCoords = function() + self.getCoords = function(vectorType) local coords = self.player.get('coords') - return {x = ESX.Math.Round(coords.x, 1), y = ESX.Math.Round(coords.y, 1), z = ESX.Math.Round(coords.z, 1)} + coords = {x = ESX.Math.Round(coords.x, 1), y = ESX.Math.Round(coords.y, 1), z = ESX.Math.Round(coords.z, 1)} + + if vectorType then + return vector3(coords.x, coords.y, coords.z) + else + return coords + end end self.setCoords = function(x, y, z) From 0e5dda5779c9a9191bb0e8a9f02aef17ded4ac4a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 13 Oct 2019 19:18:22 +0200 Subject: [PATCH 2283/3224] Added pvp to esx, fixes #302 --- client/main.lua | 9 ++++++--- config.lua | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/client/main.lua b/client/main.lua index 2950bcda..e829044f 100644 --- a/client/main.lua +++ b/client/main.lua @@ -72,9 +72,12 @@ AddEventHandler('playerSpawned', function() TriggerEvent('esx:restoreLoadout') -- restore loadout - isLoadoutLoaded = true - isPlayerSpawned = true - isDead = false + isLoadoutLoaded, isPlayerSpawned, isDead = true, true, false + + if Config.EnablePvP then + SetCanAttackFriendly(playerPed, true, false) + NetworkSetFriendlyFireOption(true) + end end) AddEventHandler('esx:onPlayerDeath', function() diff --git a/config.lua b/config.lua index 453d052a..ee531780 100644 --- a/config.lua +++ b/config.lua @@ -7,6 +7,7 @@ Config.AccountLabels = { bank = _U('bank'), black_money = _U('black_money Config.EnableSocietyPayouts = false -- pay from the society account that the player is employed at? Requirement: esx_society Config.DisableWantedLevel = true Config.EnableHud = true -- enable the default hud? Display current job and accounts (black, bank & cash) +Config.EnablePvP = true -- enable pvp? Config.PaycheckInterval = 7 * 60000 From e962b1daae1e053795ce67dbf07dd99f9ba9a1dd Mon Sep 17 00:00:00 2001 From: userMacieG Date: Sun, 13 Oct 2019 19:20:40 +0200 Subject: [PATCH 2284/3224] Update pl.lua --- locales/pl.lua | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/locales/pl.lua b/locales/pl.lua index 84c6d3d2..2004680d 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -1,16 +1,16 @@ Locales['pl'] = { - ['shop_robbery'] = 'napad Na Sklep', - ['press_to_rob'] = 'Wciśnij ~INPUT_CONTEXT~ aby ~o~napaść~s~ na ~b~%s~s~', - ['robbery_timer'] = 'napad na sklep: ~r~%s~s~ sekund do końca', - ['recently_robbed'] = 'ten sklep niedawno został obrabowany. Proszę poczekać ~y~%s~s~ sekund przed kolejnym napadem', - ['rob_in_prog'] = '~r~napad w toku w ~b~%s~s~', - ['started_to_rob'] = 'rozpoczałeś/aś napad ~y~%s~s~', - ['alarm_triggered'] = 'alarm został włączony', - ['robbery_complete'] = '~r~Napad udany~s~, ~o~obrabowałeś/aś~s~ ~g~$%s~s~', - ['robbery_complete_at'] = '~r~Napad udany w ~y~%s~s~', - ['robbery_cancelled'] = 'napad został anulowany!', - ['robbery_cancelled_at'] = '~r~Napad w ~b~%s~s~ został anulowany!', - ['min_police'] = 'minimalnie musi być ~b~%s policjantów~s~ w mieście aby obrabować.', - ['robbery_already'] = '~r~Napad jest już w toku.', - ['no_threat'] = 'nie tworzysz zagrożenia dla tego sklepu', + ['shop_robbery'] = 'napad na sklep', + ['press_to_rob'] = 'naciśnij ~INPUT_CONTEXT~ aby rozpocząc ~o~napad~s~ na ~b~%s~s~', + ['robbery_timer'] = 'napad na sklep: ~r~%s~s~ sekund do końca', + ['recently_robbed'] = 'ten sklep niedawno został obrabowany. Proszę poczekać ~y~%s~s~ sekund przed kolejnym napadem', + ['rob_in_prog'] = '~r~napad w toku w ~b~%s~s~', + ['started_to_rob'] = 'rozpoczałeś/aś napad ~y~%s~s~', + ['alarm_triggered'] = 'alarm został włączony', + ['robbery_complete'] = '~r~Napad udany~s~, ~o~obrabowałeś/aś~s~ ~g~$%s~s~', + ['robbery_complete_at'] = '~r~Napad udany w ~y~%s~s~', + ['robbery_cancelled'] = 'napad został anulowany!', + ['robbery_cancelled_at'] = '~r~Napad w ~b~%s~s~ został anulowany!', + ['min_police'] = 'minimalnie musi być ~b~%s policjantów~s~ w mieście aby obrabować.', + ['robbery_already'] = '~r~Napad jest już w toku.', + ['no_threat'] = 'nie stwarzasz zagrożenia dla tego sklepu', } From 130df3f18f0e248623060a87399ed710022d715a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 13 Oct 2019 20:20:12 +0200 Subject: [PATCH 2285/3224] Fixed notification 99 char limit by using TextEntry, fixes #286 You can also split up strings each 99 chars and still use AddTextComponentSubstringPlayerName --- client/functions.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index a167c934..75b9d68b 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -45,22 +45,22 @@ ESX.SetPlayerData = function(key, val) end ESX.ShowNotification = function(msg) - SetNotificationTextEntry('STRING') - AddTextComponentSubstringPlayerName(msg) + AddTextEntry('esxNotification', msg) + SetNotificationTextEntry('esxNotification') DrawNotification(false, true) end ESX.ShowAdvancedNotification = function(title, subject, msg, icon, iconType) - SetNotificationTextEntry('STRING') - AddTextComponentSubstringPlayerName(msg) + AddTextEntry('esxAdvancedNotification', msg) + SetNotificationTextEntry('esxAdvancedNotification') SetNotificationMessage(icon, icon, false, iconType, title, subject) DrawNotification(false, false) end ESX.ShowHelpNotification = function(msg) --if not IsHelpMessageBeingDisplayed() then - BeginTextCommandDisplayHelp('STRING') - AddTextComponentSubstringPlayerName(msg) + AddTextEntry('esxHelpNotification', msg) + BeginTextCommandDisplayHelp('esxHelpNotification') EndTextCommandDisplayHelp(0, false, true, -1) --end end From 145f8ebe755670dba185ce86ddcf2b0bca266926 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 13 Oct 2019 20:56:09 +0200 Subject: [PATCH 2286/3224] Breaking changes: implemented global weight inventory system, read description before updating! - Fixed #256 - Implements #173 __NO OFFICIAL ESX SCRIPT WILL WORK WITH THIS AT THE MOMENT__ This commit will break your entire ESX if you dont use the new SQL format, follow the new one if you want it all to work properly. Scripts using `item.limit` will break too, instead use `xPlayer.canCarryItem(item, count)` --- client/functions.lua | 491 ++++++++++++++--------------- client/main.lua | 20 +- config.lua | 1 + config.weapons.lua | 632 ++++++++++++-------------------------- es_extended.sql | 48 +-- locales/br.lua | 27 +- locales/cs.lua | 27 +- locales/de.lua | 23 +- locales/en.lua | 27 +- locales/fi.lua | 25 +- locales/fr.lua | 21 +- locales/pl.lua | 27 +- locales/sv.lua | 29 +- server/classes/player.lua | 82 +++-- server/common.lua | 32 +- server/main.lua | 178 +++++------ 16 files changed, 723 insertions(+), 967 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 75b9d68b..95b89359 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -157,14 +157,14 @@ ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change, ESX.UI.Menu.RegisteredTypes[type].close(namespace, name) for i=1, #ESX.UI.Menu.Opened, 1 do - if ESX.UI.Menu.Opened[i] ~= nil then + if ESX.UI.Menu.Opened[i] then if ESX.UI.Menu.Opened[i].type == type and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then ESX.UI.Menu.Opened[i] = nil end end end - if close ~= nil then + if close then close() end @@ -224,7 +224,7 @@ end ESX.UI.Menu.Close = function(type, namespace, name) for i=1, #ESX.UI.Menu.Opened, 1 do - if ESX.UI.Menu.Opened[i] ~= nil then + if ESX.UI.Menu.Opened[i] then if ESX.UI.Menu.Opened[i].type == type and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then ESX.UI.Menu.Opened[i].close() ESX.UI.Menu.Opened[i] = nil @@ -235,7 +235,7 @@ end ESX.UI.Menu.CloseAll = function() for i=1, #ESX.UI.Menu.Opened, 1 do - if ESX.UI.Menu.Opened[i] ~= nil then + if ESX.UI.Menu.Opened[i] then ESX.UI.Menu.Opened[i].close() ESX.UI.Menu.Opened[i] = nil end @@ -244,7 +244,7 @@ end ESX.UI.Menu.GetOpened = function(type, namespace, name) for i=1, #ESX.UI.Menu.Opened, 1 do - if ESX.UI.Menu.Opened[i] ~= nil then + if ESX.UI.Menu.Opened[i] then if ESX.UI.Menu.Opened[i].type == type and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then return ESX.UI.Menu.Opened[i] end @@ -289,7 +289,7 @@ ESX.Game.Teleport = function(entity, coords, cb) SetEntityCoords(entity, coords.x, coords.y, coords.z) - if cb ~= nil then + if cb then cb() end end @@ -302,7 +302,7 @@ ESX.Game.SpawnObject = function(model, coords, cb) local obj = CreateObject(model, coords.x, coords.y, coords.z, true, false, true) - if cb ~= nil then + if cb then cb(obj) end end) @@ -316,7 +316,7 @@ ESX.Game.SpawnLocalObject = function(model, coords, cb) local obj = CreateObject(model, coords.x, coords.y, coords.z, false, false, true) - if cb ~= nil then + if cb then cb(obj) end end) @@ -356,7 +356,7 @@ ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) SetVehRadioStation(vehicle, 'OFF') - if cb ~= nil then + if cb then cb(vehicle) end end) @@ -383,7 +383,7 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) SetVehRadioStation(vehicle, 'OFF') - if cb ~= nil then + if cb then cb(vehicle) end end) @@ -407,11 +407,9 @@ ESX.Game.GetObjects = function() end ESX.Game.GetClosestObject = function(filter, coords) - local objects = ESX.Game.GetObjects() - local closestDistance = -1 - local closestObject = -1 - local filter = filter - local coords = coords + local objects = ESX.Game.GetObjects() + local closestDistance, closestObject = -1, -1 + local filter, coords = filter, coords if type(filter) == 'string' then if filter ~= '' then @@ -419,9 +417,11 @@ ESX.Game.GetClosestObject = function(filter, coords) end end - if coords == nil then + if coords then + coords = vector3(coords.x, coords.y, coords.z) + else local playerPed = PlayerPedId() - coords = GetEntityCoords(playerPed) + coords = GetEntityCoords(playerPed) end for i=1, #objects, 1 do @@ -435,16 +435,17 @@ ESX.Game.GetClosestObject = function(filter, coords) for j=1, #filter, 1 do if objectModel == GetHashKey(filter[j]) then foundObject = true + break end end end if foundObject then local objectCoords = GetEntityCoords(objects[i]) - local distance = GetDistanceBetweenCoords(objectCoords, coords.x, coords.y, coords.z, true) + local distance = #(objectCoords - coords) if closestDistance == -1 or closestDistance > distance then - closestObject = objects[i] + closestObject = objects[i] closestDistance = distance end end @@ -468,17 +469,15 @@ ESX.Game.GetPlayers = function() end ESX.Game.GetClosestPlayer = function(coords) - local players = ESX.Game.GetPlayers() - local closestDistance = -1 - local closestPlayer = -1 - local coords = coords - local usePlayerPed = false - local playerPed = PlayerPedId() - local playerId = PlayerId() + local players, closestDistance, closestPlayer = ESX.Game.GetPlayers(), -1, -1 + local coords, usePlayerPed = coords, false + local playerPed, playerId = PlayerPedId(), PlayerId() - if coords == nil then + if coords then + coords = vector3(coords.x, coords.y, coords.z) + else usePlayerPed = true - coords = GetEntityCoords(playerPed) + coords = GetEntityCoords(playerPed) end for i=1, #players, 1 do @@ -486,10 +485,10 @@ ESX.Game.GetClosestPlayer = function(coords) if not usePlayerPed or (usePlayerPed and players[i] ~= playerId) then local targetCoords = GetEntityCoords(target) - local distance = GetDistanceBetweenCoords(targetCoords, coords.x, coords.y, coords.z, true) + local distance = #(coords - targetCoords) if closestDistance == -1 or closestDistance > distance then - closestPlayer = players[i] + closestPlayer = players[i] closestDistance = distance end end @@ -724,66 +723,66 @@ end ESX.Game.SetVehicleProperties = function(vehicle, props) SetVehicleModKit(vehicle, 0) - if props.plate ~= nil then + if props.plate then SetVehicleNumberPlateText(vehicle, props.plate) end - if props.plateIndex ~= nil then + if props.plateIndex then SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex) end - if props.bodyHealth ~= nil then + if props.bodyHealth then SetVehicleBodyHealth(vehicle, props.bodyHealth + 0.0) end - if props.engineHealth ~= nil then + if props.engineHealth then SetVehicleEngineHealth(vehicle, props.engineHealth + 0.0) end - if props.fuelLevel ~= nil then + if props.fuelLevel then SetVehicleFuelLevel(vehicle, props.fuelLevel + 0.0) end - if props.dirtLevel ~= nil then + if props.dirtLevel then SetVehicleDirtLevel(vehicle, props.dirtLevel + 0.0) end - if props.color1 ~= nil then + if props.color1 then local color1, color2 = GetVehicleColours(vehicle) SetVehicleColours(vehicle, props.color1, color2) end - if props.color2 ~= nil then + if props.color2 then local color1, color2 = GetVehicleColours(vehicle) SetVehicleColours(vehicle, color1, props.color2) end - if props.pearlescentColor ~= nil then + if props.pearlescentColor then local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) SetVehicleExtraColours(vehicle, props.pearlescentColor, wheelColor) end - if props.wheelColor ~= nil then + if props.wheelColor then local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) SetVehicleExtraColours(vehicle, pearlescentColor, props.wheelColor) end - if props.wheels ~= nil then + if props.wheels then SetVehicleWheelType(vehicle, props.wheels) end - if props.windowTint ~= nil then + if props.windowTint then SetVehicleWindowTint(vehicle, props.windowTint) end - if props.neonEnabled ~= nil then + if props.neonEnabled then SetVehicleNeonLightEnabled(vehicle, 0, props.neonEnabled[1]) SetVehicleNeonLightEnabled(vehicle, 1, props.neonEnabled[2]) SetVehicleNeonLightEnabled(vehicle, 2, props.neonEnabled[3]) SetVehicleNeonLightEnabled(vehicle, 3, props.neonEnabled[4]) end - if props.extras ~= nil then + if props.extras then for id,enabled in pairs(props.extras) do if enabled then SetVehicleExtra(vehicle, tonumber(id), 0) @@ -793,191 +792,191 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) end end - if props.neonColor ~= nil then + if props.neonColor then SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) end - if props.modSmokeEnabled ~= nil then + if props.modSmokeEnabled then ToggleVehicleMod(vehicle, 20, true) end - if props.tyreSmokeColor ~= nil then + if props.tyreSmokeColor then SetVehicleTyreSmokeColor(vehicle, props.tyreSmokeColor[1], props.tyreSmokeColor[2], props.tyreSmokeColor[3]) end - if props.modSpoilers ~= nil then + if props.modSpoilers then SetVehicleMod(vehicle, 0, props.modSpoilers, false) end - if props.modFrontBumper ~= nil then + if props.modFrontBumper then SetVehicleMod(vehicle, 1, props.modFrontBumper, false) end - if props.modRearBumper ~= nil then + if props.modRearBumper then SetVehicleMod(vehicle, 2, props.modRearBumper, false) end - if props.modSideSkirt ~= nil then + if props.modSideSkirt then SetVehicleMod(vehicle, 3, props.modSideSkirt, false) end - if props.modExhaust ~= nil then + if props.modExhaust then SetVehicleMod(vehicle, 4, props.modExhaust, false) end - if props.modFrame ~= nil then + if props.modFrame then SetVehicleMod(vehicle, 5, props.modFrame, false) end - if props.modGrille ~= nil then + if props.modGrille then SetVehicleMod(vehicle, 6, props.modGrille, false) end - if props.modHood ~= nil then + if props.modHood then SetVehicleMod(vehicle, 7, props.modHood, false) end - if props.modFender ~= nil then + if props.modFender then SetVehicleMod(vehicle, 8, props.modFender, false) end - if props.modRightFender ~= nil then + if props.modRightFender then SetVehicleMod(vehicle, 9, props.modRightFender, false) end - if props.modRoof ~= nil then + if props.modRoof then SetVehicleMod(vehicle, 10, props.modRoof, false) end - if props.modEngine ~= nil then + if props.modEngine then SetVehicleMod(vehicle, 11, props.modEngine, false) end - if props.modBrakes ~= nil then + if props.modBrakes then SetVehicleMod(vehicle, 12, props.modBrakes, false) end - if props.modTransmission ~= nil then + if props.modTransmission then SetVehicleMod(vehicle, 13, props.modTransmission, false) end - if props.modHorns ~= nil then + if props.modHorns then SetVehicleMod(vehicle, 14, props.modHorns, false) end - if props.modSuspension ~= nil then + if props.modSuspension then SetVehicleMod(vehicle, 15, props.modSuspension, false) end - if props.modArmor ~= nil then + if props.modArmor then SetVehicleMod(vehicle, 16, props.modArmor, false) end - if props.modTurbo ~= nil then + if props.modTurbo then ToggleVehicleMod(vehicle, 18, props.modTurbo) end - if props.modXenon ~= nil then + if props.modXenon then ToggleVehicleMod(vehicle, 22, props.modXenon) end - if props.modFrontWheels ~= nil then + if props.modFrontWheels then SetVehicleMod(vehicle, 23, props.modFrontWheels, false) end - if props.modBackWheels ~= nil then + if props.modBackWheels then SetVehicleMod(vehicle, 24, props.modBackWheels, false) end - if props.modPlateHolder ~= nil then + if props.modPlateHolder then SetVehicleMod(vehicle, 25, props.modPlateHolder, false) end - if props.modVanityPlate ~= nil then + if props.modVanityPlate then SetVehicleMod(vehicle, 26, props.modVanityPlate, false) end - if props.modTrimA ~= nil then + if props.modTrimA then SetVehicleMod(vehicle, 27, props.modTrimA, false) end - if props.modOrnaments ~= nil then + if props.modOrnaments then SetVehicleMod(vehicle, 28, props.modOrnaments, false) end - if props.modDashboard ~= nil then + if props.modDashboard then SetVehicleMod(vehicle, 29, props.modDashboard, false) end - if props.modDial ~= nil then + if props.modDial then SetVehicleMod(vehicle, 30, props.modDial, false) end - if props.modDoorSpeaker ~= nil then + if props.modDoorSpeaker then SetVehicleMod(vehicle, 31, props.modDoorSpeaker, false) end - if props.modSeats ~= nil then + if props.modSeats then SetVehicleMod(vehicle, 32, props.modSeats, false) end - if props.modSteeringWheel ~= nil then + if props.modSteeringWheel then SetVehicleMod(vehicle, 33, props.modSteeringWheel, false) end - if props.modShifterLeavers ~= nil then + if props.modShifterLeavers then SetVehicleMod(vehicle, 34, props.modShifterLeavers, false) end - if props.modAPlate ~= nil then + if props.modAPlate then SetVehicleMod(vehicle, 35, props.modAPlate, false) end - if props.modSpeakers ~= nil then + if props.modSpeakers then SetVehicleMod(vehicle, 36, props.modSpeakers, false) end - if props.modTrunk ~= nil then + if props.modTrunk then SetVehicleMod(vehicle, 37, props.modTrunk, false) end - if props.modHydrolic ~= nil then + if props.modHydrolic then SetVehicleMod(vehicle, 38, props.modHydrolic, false) end - if props.modEngineBlock ~= nil then + if props.modEngineBlock then SetVehicleMod(vehicle, 39, props.modEngineBlock, false) end - if props.modAirFilter ~= nil then + if props.modAirFilter then SetVehicleMod(vehicle, 40, props.modAirFilter, false) end - if props.modStruts ~= nil then + if props.modStruts then SetVehicleMod(vehicle, 41, props.modStruts, false) end - if props.modArchCover ~= nil then + if props.modArchCover then SetVehicleMod(vehicle, 42, props.modArchCover, false) end - if props.modAerials ~= nil then + if props.modAerials then SetVehicleMod(vehicle, 43, props.modAerials, false) end - if props.modTrimB ~= nil then + if props.modTrimB then SetVehicleMod(vehicle, 44, props.modTrimB, false) end - if props.modTank ~= nil then + if props.modTank then SetVehicleMod(vehicle, 45, props.modTank, false) end - if props.modWindows ~= nil then + if props.modWindows then SetVehicleMod(vehicle, 46, props.modWindows, false) end - if props.modLivery ~= nil then + if props.modLivery then SetVehicleMod(vehicle, 48, props.modLivery, false) SetVehicleLivery(vehicle, props.modLivery) end @@ -1013,7 +1012,7 @@ end ESX.ShowInventory = function() local playerPed = PlayerPedId() - local elements = {} + local elements, currentWeight = {}, 0 if ESX.PlayerData.money > 0 then local formattedMoney = _U('locale_currency', ESX.Math.GroupDigits(ESX.PlayerData.money)) @@ -1029,16 +1028,16 @@ ESX.ShowInventory = function() }) end - for i=1, #ESX.PlayerData.accounts, 1 do - if ESX.PlayerData.accounts[i].money > 0 then - local formattedMoney = _U('locale_currency', ESX.Math.GroupDigits(ESX.PlayerData.accounts[i].money)) - local canDrop = ESX.PlayerData.accounts[i].name ~= 'bank' + for k,v in pairs(ESX.PlayerData.accounts) do + if v.money > 0 then + local formattedMoney = _U('locale_currency', ESX.Math.GroupDigits(v.money)) + local canDrop = v.name ~= 'bank' table.insert(elements, { - label = ('%s: %s'):format(ESX.PlayerData.accounts[i].label, formattedMoney), - count = ESX.PlayerData.accounts[i].money, + label = ('%s: %s'):format(v.label, formattedMoney), + count = v.money, type = 'item_account', - value = ESX.PlayerData.accounts[i].name, + value = v.name, usable = false, rare = false, canRemove = canDrop @@ -1046,30 +1045,32 @@ ESX.ShowInventory = function() end end - for i=1, #ESX.PlayerData.inventory, 1 do - if ESX.PlayerData.inventory[i].count > 0 then + for k,v in ipairs(ESX.PlayerData.inventory) do + if v.count > 0 then + currentWeight = currentWeight + (v.weight * v.count) table.insert(elements, { - label = ESX.PlayerData.inventory[i].label .. ' x' .. ESX.PlayerData.inventory[i].count, - count = ESX.PlayerData.inventory[i].count, + label = ('%s x%s'):format(v.label, v.count), + count = v.count, type = 'item_standard', - value = ESX.PlayerData.inventory[i].name, - usable = ESX.PlayerData.inventory[i].usable, - rare = ESX.PlayerData.inventory[i].rare, - canRemove = ESX.PlayerData.inventory[i].canRemove + value = v.name, + usable = v.usable, + rare = v.rare, + canRemove = v.canRemove }) end end - for i=1, #Config.Weapons, 1 do - local weaponHash = GetHashKey(Config.Weapons[i].name) + for k,v in ipairs(Config.Weapons) do + local weaponHash = GetHashKey(v.name) - if HasPedGotWeapon(playerPed, weaponHash, false) and Config.Weapons[i].name ~= 'WEAPON_UNARMED' then + if HasPedGotWeapon(playerPed, weaponHash, false) then local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) + table.insert(elements, { - label = Config.Weapons[i].label .. ' [' .. ammo .. ']', + label = ('%s [%s]'):format(v.label, ammo), count = 1, type = 'item_weapon', - value = Config.Weapons[i].name, + value = v.name, ammo = ammo, usable = false, rare = false, @@ -1080,14 +1081,12 @@ ESX.ShowInventory = function() ESX.UI.Menu.CloseAll() - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'inventory', - { - title = _U('inventory'), + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'inventory', { + title = _U('inventory', currentWeight, ESX.PlayerData.maxWeight), align = 'bottom-right', - elements = elements, + elements = elements }, function(data, menu) menu.close() - local player, distance = ESX.Game.GetClosestPlayer() local elements = {} @@ -1104,207 +1103,169 @@ ESX.ShowInventory = function() end if data.current.type == 'item_weapon' and data.current.ammo > 0 and player ~= -1 and distance <= 3.0 then - table.insert(elements, {label = _U('giveammo'), action = 'giveammo', type = data.current.type, value = data.current.value}) + table.insert(elements, {label = _U('giveammo'), action = 'give_ammo', type = data.current.type, value = data.current.value}) end table.insert(elements, {label = _U('return'), action = 'return'}) - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'inventory_item', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'inventory_item', { title = data.current.label, align = 'bottom-right', elements = elements, }, function(data1, menu1) - local item = data1.current.value local type = data1.current.type - local playerPed = PlayerPedId() if data1.current.action == 'give' then + local playersInArea = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) + local foundPlayers, elements = false, {} - local players = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) - local foundPlayers = false - local elements = {} - - for i=1, #players, 1 do - if players[i] ~= PlayerId() then + for k,v in ipairs(playersInArea) do + if v ~= PlayerId() then foundPlayers = true table.insert(elements, { - label = GetPlayerName(players[i]), - player = players[i] + label = GetPlayerName(v), + player = v }) end end - if not foundPlayers then + if foundPlayers then + foundPlayers = false + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'give_item_to', { + title = _U('give_to'), + align = 'bottom-right', + elements = elements + }, function(data2, menu2) + local playersInArea, nearbyPlayer = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) + + for k,v in ipairs(playersInArea) do + if v ~= PlayerId() then + + if v == data2.current.player then + foundPlayers = true + nearbyPlayer = v + break + end + end + end + + if foundPlayers then + if type == 'item_weapon' then + local closestPed = GetPlayerPed(nearbyPlayer) + local sourceAmmo = GetAmmoInPedWeapon(playerPed, GetHashKey(item)) + + if IsPedOnFoot(closestPed) then + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(nearbyPlayer), type, item, sourceAmmo) + menu2.close() + menu1.close() + else + ESX.ShowNotification(_U('in_vehicle')) + end + else + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', { + title = _U('amount') + }, function(data3, menu3) + local quantity = tonumber(data3.value) + local closestPed = GetPlayerPed(nearbyPlayer) + + if IsPedOnFoot(closestPed) then + if quantity then + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(nearbyPlayer), type, item, quantity) + menu3.close() + menu2.close() + menu1.close() + else + ESX.ShowNotification(_U('amount_invalid')) + end + else + ESX.ShowNotification(_U('in_vehicle')) + end + end, function(data3, menu3) + menu3.close() + end) + end + else + ESX.ShowNotification(_U('players_nearby')) + menu2.close() + end + end, function(data2, menu2) + menu2.close() + end) -- give end + else ESX.ShowNotification(_U('players_nearby')) - return end - - foundPlayers = false - - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'give_item_to', - { - title = _U('give_to'), - align = 'bottom-right', - elements = elements - }, function(data2, menu2) - - local players, nearbyPlayer = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) - - for i=1, #players, 1 do - if players[i] ~= PlayerId() then - - if players[i] == data2.current.player then - foundPlayers = true - nearbyPlayer = players[i] - break - end - end - end - - if not foundPlayers then - ESX.ShowNotification(_U('players_nearby')) - menu2.close() - return - end - + elseif data1.current.action == 'remove' then + if IsPedOnFoot(playerPed) then if type == 'item_weapon' then - - local closestPed = GetPlayerPed(nearbyPlayer) - local sourceAmmo = GetAmmoInPedWeapon(PlayerPedId(), GetHashKey(item)) - - if IsPedSittingInAnyVehicle(closestPed) then - ESX.ShowNotification(_U('in_vehicle')) - return - end - - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(nearbyPlayer), type, item, sourceAmmo) - menu2.close() + TriggerServerEvent('esx:removeInventoryItem', type, item) menu1.close() - - else - - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', { + else -- type: item_standard + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_remove', { title = _U('amount') - }, function(data3, menu3) - local quantity = tonumber(data3.value) - local closestPed = GetPlayerPed(nearbyPlayer) - - if IsPedSittingInAnyVehicle(closestPed) then - ESX.ShowNotification(_U('in_vehicle')) - return - end - - if quantity ~= nil then - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(nearbyPlayer), type, item, quantity) - - menu3.close() + }, function(data2, menu2) + local quantity = tonumber(data2.value) + + if quantity then + TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) menu2.close() menu1.close() else ESX.ShowNotification(_U('amount_invalid')) end - - end, function(data3, menu3) - menu3.close() + end, function(data2, menu2) + menu2.close() end) end - end, function(data2, menu2) - menu2.close() - end) -- give end - - elseif data1.current.action == 'remove' then - - if IsPedSittingInAnyVehicle(playerPed) then - return end - - if type == 'item_weapon' then - - TriggerServerEvent('esx:removeInventoryItem', type, item) - menu1.close() - - else -- type: item_standard - - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_remove', { - title = _U('amount') - }, function(data2, menu2) - local quantity = tonumber(data2.value) - - if quantity == nil then - ESX.ShowNotification(_U('amount_invalid')) - else - TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) - menu2.close() - menu1.close() - end - - end, function(data2, menu2) - menu2.close() - end) - end - elseif data1.current.action == 'use' then TriggerServerEvent('esx:useItem', item) - elseif data1.current.action == 'return' then ESX.UI.Menu.CloseAll() ESX.ShowInventory() - elseif data1.current.action == 'giveammo' then + elseif data1.current.action == 'give_ammo' then local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() local closestPed = GetPlayerPed(closestPlayer) local pedAmmo = GetAmmoInPedWeapon(playerPed, GetHashKey(item)) - if IsPedSittingInAnyVehicle(closestPed) then - ESX.ShowNotification(_U('in_vehicle')) - return - end - - if closestPlayer ~= -1 and closestDistance < 3.0 then - if pedAmmo > 0 then - - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', { - title = _U('amountammo') - }, function(data2, menu2) - - local quantity = tonumber(data2.value) - - if quantity ~= nil then - if quantity <= pedAmmo and quantity >= 0 then - - local finalAmmoSource = math.floor(pedAmmo - quantity) - SetPedAmmo(playerPed, item, finalAmmoSource) - AddAmmoToPed(closestPed, item, quantity) - - ESX.ShowNotification(_U('gave_ammo', quantity, GetPlayerName(closestPlayer))) - -- todo notify target that he received ammo - menu2.close() - menu1.close() + if IsPedOnFoot(closestPed) then + if closestPlayer ~= -1 and closestDistance < 3.0 then + if pedAmmo > 0 then + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', { + title = _U('amountammo') + }, function(data2, menu2) + local quantity = tonumber(data2.value) + + if quantity then + if pedAmmo >= quantity and quantity > 0 then + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), 'item_ammo', item, quantity) + menu2.close() + menu1.close() + else + ESX.ShowNotification(_U('noammo')) + end else - ESX.ShowNotification(_U('noammo')) + ESX.ShowNotification(_U('amount_invalid')) end - else - ESX.ShowNotification(_U('amount_invalid')) - end - - end, function(data2, menu2) - menu2.close() - end) + end, function(data2, menu2) + menu2.close() + end) + else + ESX.ShowNotification(_U('noammo')) + end else - ESX.ShowNotification(_U('noammo')) + ESX.ShowNotification(_U('players_nearby')) end else - ESX.ShowNotification(_U('players_nearby')) + ESX.ShowNotification(_U('in_vehicle')) end end - end, function(data1, menu1) ESX.UI.Menu.CloseAll() ESX.ShowInventory() end) - end, function(data, menu) menu.close() end) diff --git a/client/main.lua b/client/main.lua index e829044f..9c8019c3 100644 --- a/client/main.lua +++ b/client/main.lua @@ -40,6 +40,11 @@ AddEventHandler('esx:playerLoaded', function(xPlayer) end end) +RegisterNetEvent('esx:setMaxWeight') +AddEventHandler('esx:setMaxWeight', function(newMaxWeight) + ESX.PlayerData.maxWeight = newMaxWeight +end) + RegisterNetEvent('esx:createMissingPickups') AddEventHandler('esx:createMissingPickups', function(missingPickups) for pickupId,v in pairs(missingPickups) do @@ -200,6 +205,14 @@ AddEventHandler('esx:addWeaponComponent', function(weaponName, weaponComponent) GiveWeaponComponentToPed(playerPed, weaponHash, componentHash) end) +RegisterNetEvent('esx:setWeaponAmmo') +AddEventHandler('esx:setWeaponAmmo', function(weaponName, weaponAmmo) + local playerPed = PlayerPedId() + local weaponHash = GetHashKey(weaponName) + + SetPedAmmo(playerPed, weaponHash, weaponAmmo) +end) + RegisterNetEvent('esx:removeWeapon') AddEventHandler('esx:removeWeapon', function(weaponName, ammo) local playerPed = PlayerPedId() @@ -256,7 +269,6 @@ end) RegisterNetEvent('esx:loadIPL') AddEventHandler('esx:loadIPL', function(name) Citizen.CreateThread(function() - LoadMpDlcMaps() RequestIpl(name) end) end) @@ -342,11 +354,7 @@ AddEventHandler('esx:pickup', function(id, label, player) obj = obj, label = label, inRange = false, - coords = { - x = x, - y = y, - z = z - } + coords = {x = x, y = y, z = z} } end) end) diff --git a/config.lua b/config.lua index ee531780..a332cf44 100644 --- a/config.lua +++ b/config.lua @@ -8,6 +8,7 @@ Config.EnableSocietyPayouts = false -- pay from the society account that the pla Config.DisableWantedLevel = true Config.EnableHud = true -- enable the default hud? Display current job and accounts (black, bank & cash) Config.EnablePvP = true -- enable pvp? +Config.MaxWeight = 24 -- the max inventory weight without backpack Config.PaycheckInterval = 7 * 60000 diff --git a/config.weapons.lua b/config.weapons.lua index 320a9da5..8dd7676c 100644 --- a/config.weapons.lua +++ b/config.weapons.lua @@ -1,50 +1,20 @@ Config.Weapons = { - - { - name = 'WEAPON_KNIFE', - label = _U('weapon_knife'), - components = {} - }, - - { - name = 'WEAPON_NIGHTSTICK', - label = _U('weapon_nightstick'), - components = {} - }, - - { - name = 'WEAPON_HAMMER', - label = _U('weapon_hammer'), - components = {} - }, - - { - name = 'WEAPON_BAT', - label = _U('weapon_bat'), - components = {} - }, - - { - name = 'WEAPON_GOLFCLUB', - label = _U('weapon_golfclub'), - components = {} - }, - - { - name = 'WEAPON_CROWBAR', - label = _U('weapon_crowbar'), - components = {} - }, + {name = 'WEAPON_KNIFE', label = _U('weapon_knife'), components = {}}, + {name = 'WEAPON_NIGHTSTICK', label = _U('weapon_nightstick'), components = {}}, + {name = 'WEAPON_HAMMER', label = _U('weapon_hammer'), components = {}}, + {name = 'WEAPON_BAT', label = _U('weapon_bat'), components = {}}, + {name = 'WEAPON_GOLFCLUB', label = _U('weapon_golfclub'), components = {}}, + {name = 'WEAPON_CROWBAR', label = _U('weapon_crowbar'), components = {}}, { name = 'WEAPON_PISTOL', label = _U('weapon_pistol'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_PISTOL_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_PISTOL_CLIP_02') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP_02') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_PISTOL_VARMOD_LUXE') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_PISTOL_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_PISTOL_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP_02')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_PISTOL_VARMOD_LUXE')} } }, @@ -52,11 +22,11 @@ Config.Weapons = { name = 'WEAPON_COMBATPISTOL', label = _U('weapon_combatpistol'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATPISTOL_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATPISTOL_CLIP_02') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_COMBATPISTOL_VARMOD_LOWRIDER') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATPISTOL_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATPISTOL_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_COMBATPISTOL_VARMOD_LOWRIDER')} } }, @@ -64,11 +34,11 @@ Config.Weapons = { name = 'WEAPON_APPISTOL', label = _U('weapon_appistol'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_APPISTOL_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_APPISTOL_CLIP_02') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_APPISTOL_VARMOD_LUXE') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_APPISTOL_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_APPISTOL_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_APPISTOL_VARMOD_LUXE')} } }, @@ -76,27 +46,23 @@ Config.Weapons = { name = 'WEAPON_PISTOL50', label = _U('weapon_pistol50'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_PISTOL50_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_PISTOL50_CLIP_02') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_PISTOL50_VARMOD_LUXE') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_PISTOL50_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_PISTOL50_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_PISTOL50_VARMOD_LUXE')} } }, - { - name = 'WEAPON_REVOLVER', - label = _U('weapon_revolver'), - components = {} - }, + {name = 'WEAPON_REVOLVER', label = _U('weapon_revolver'), components = {}}, { name = 'WEAPON_SNSPISTOL', label = _U('weapon_snspistol'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SNSPISTOL_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SNSPISTOL_CLIP_02') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SNSPISTOL_VARMOD_LOWRIDER') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SNSPISTOL_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SNSPISTOL_CLIP_02')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SNSPISTOL_VARMOD_LOWRIDER')} } }, @@ -104,11 +70,11 @@ Config.Weapons = { name = 'WEAPON_HEAVYPISTOL', label = _U('weapon_heavypistol'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_HEAVYPISTOL_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_HEAVYPISTOL_CLIP_02') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_HEAVYPISTOL_VARMOD_LUXE') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_HEAVYPISTOL_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_HEAVYPISTOL_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_HEAVYPISTOL_VARMOD_LUXE')} } }, @@ -116,9 +82,9 @@ Config.Weapons = { name = 'WEAPON_VINTAGEPISTOL', label = _U('weapon_vintagepistol'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_VINTAGEPISTOL_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_VINTAGEPISTOL_CLIP_02') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_VINTAGEPISTOL_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_VINTAGEPISTOL_CLIP_02')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP')} } }, @@ -126,12 +92,12 @@ Config.Weapons = { name = 'WEAPON_MICROSMG', label = _U('weapon_microsmg'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MICROSMG_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MICROSMG_CLIP_02') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_MICROSMG_VARMOD_LUXE') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MICROSMG_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MICROSMG_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_MICROSMG_VARMOD_LUXE')} } }, @@ -139,13 +105,13 @@ Config.Weapons = { name = 'WEAPON_SMG', label = _U('weapon_smg'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SMG_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SMG_CLIP_02') }, - { name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_SMG_CLIP_03') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO_02') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SMG_VARMOD_LUXE') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SMG_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SMG_CLIP_02')}, + {name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_SMG_CLIP_03')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO_02')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SMG_VARMOD_LUXE')} } }, @@ -153,12 +119,12 @@ Config.Weapons = { name = 'WEAPON_ASSAULTSMG', label = _U('weapon_assaultsmg'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTSMG_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTSMG_CLIP_02') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_ASSAULTSMG_VARMOD_LOWRIDER') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTSMG_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTSMG_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_ASSAULTSMG_VARMOD_LOWRIDER')} } }, @@ -166,8 +132,8 @@ Config.Weapons = { name = 'WEAPON_MINISMG', label = _U('weapon_minismg'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MINISMG_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MINISMG_CLIP_02') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MINISMG_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MINISMG_CLIP_02')} } }, @@ -175,10 +141,10 @@ Config.Weapons = { name = 'WEAPON_MACHINEPISTOL', label = _U('weapon_machinepistol'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_02') }, - { name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_03') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_02')}, + {name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_03')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP')} } }, @@ -186,12 +152,12 @@ Config.Weapons = { name = 'WEAPON_COMBATPDW', label = _U('weapon_combatpdw'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATPDW_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATPDW_CLIP_02') }, - { name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_COMBATPDW_CLIP_03') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_SMALL') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATPDW_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATPDW_CLIP_02')}, + {name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_COMBATPDW_CLIP_03')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_SMALL')} } }, @@ -199,9 +165,9 @@ Config.Weapons = { name = 'WEAPON_PUMPSHOTGUN', label = _U('weapon_pumpshotgun'), components = { - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_SR_SUPP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_PUMPSHOTGUN_VARMOD_LOWRIDER') } + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_SR_SUPP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_PUMPSHOTGUN_VARMOD_LOWRIDER')} } }, @@ -209,7 +175,7 @@ Config.Weapons = { name = 'WEAPON_SAWNOFFSHOTGUN', label = _U('weapon_sawnoffshotgun'), components = { - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SAWNOFFSHOTGUN_VARMOD_LUXE') } + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SAWNOFFSHOTGUN_VARMOD_LUXE')} } }, @@ -217,11 +183,11 @@ Config.Weapons = { name = 'WEAPON_ASSAULTSHOTGUN', label = _U('weapon_assaultshotgun'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTSHOTGUN_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTSHOTGUN_CLIP_02') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP') }, - { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTSHOTGUN_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTSHOTGUN_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP')}, + {name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP')} } }, @@ -229,9 +195,9 @@ Config.Weapons = { name = 'WEAPON_BULLPUPSHOTGUN', label = _U('weapon_bullpupshotgun'), components = { - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, - { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') } + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, + {name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP')} } }, @@ -239,12 +205,12 @@ Config.Weapons = { name = 'WEAPON_HEAVYSHOTGUN', label = _U('weapon_heavyshotgun'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_HEAVYSHOTGUN_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_HEAVYSHOTGUN_CLIP_02') }, - { name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_HEAVYSHOTGUN_CLIP_03') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, - { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_HEAVYSHOTGUN_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_HEAVYSHOTGUN_CLIP_02')}, + {name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_HEAVYSHOTGUN_CLIP_03')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, + {name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP')} } }, @@ -252,14 +218,14 @@ Config.Weapons = { name = 'WEAPON_ASSAULTRIFLE', label = _U('weapon_assaultrifle'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_CLIP_02') }, - { name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_CLIP_03') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, - { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_VARMOD_LUXE') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_CLIP_02')}, + {name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_CLIP_03')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, + {name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_VARMOD_LUXE')} } }, @@ -267,14 +233,14 @@ Config.Weapons = { name = 'WEAPON_CARBINERIFLE', label = _U('weapon_carbinerifle'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_CARBINERIFLE_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_CARBINERIFLE_CLIP_02') }, - { name = 'clip_box', label = _U('component_clip_box'), hash = GetHashKey('COMPONENT_CARBINERIFLE_CLIP_03') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MEDIUM') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP') }, - { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_CARBINERIFLE_VARMOD_LUXE') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_CARBINERIFLE_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_CARBINERIFLE_CLIP_02')}, + {name = 'clip_box', label = _U('component_clip_box'), hash = GetHashKey('COMPONENT_CARBINERIFLE_CLIP_03')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MEDIUM')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP')}, + {name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_CARBINERIFLE_VARMOD_LUXE')} } }, @@ -282,12 +248,12 @@ Config.Weapons = { name = 'WEAPON_ADVANCEDRIFLE', label = _U('weapon_advancedrifle'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ADVANCEDRIFLE_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ADVANCEDRIFLE_CLIP_02') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_SMALL') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_ADVANCEDRIFLE_VARMOD_LUXE') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ADVANCEDRIFLE_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ADVANCEDRIFLE_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_SMALL')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_ADVANCEDRIFLE_VARMOD_LUXE')} } }, @@ -295,14 +261,14 @@ Config.Weapons = { name = 'WEAPON_SPECIALCARBINE', label = _U('weapon_specialcarbine'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_CLIP_02') }, - { name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_CLIP_03') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MEDIUM') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, - { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_VARMOD_LOWRIDER') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_CLIP_02')}, + {name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_CLIP_03')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MEDIUM')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, + {name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_VARMOD_LOWRIDER')} } }, @@ -310,13 +276,13 @@ Config.Weapons = { name = 'WEAPON_BULLPUPRIFLE', label = _U('weapon_bullpuprifle'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_BULLPUPRIFLE_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_BULLPUPRIFLE_CLIP_02') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_SMALL') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP') }, - { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_BULLPUPRIFLE_VARMOD_LOW') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_BULLPUPRIFLE_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_BULLPUPRIFLE_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_SMALL')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP')}, + {name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_BULLPUPRIFLE_VARMOD_LOW')} } }, @@ -324,9 +290,9 @@ Config.Weapons = { name = 'WEAPON_COMPACTRIFLE', label = _U('weapon_compactrifle'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMPACTRIFLE_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMPACTRIFLE_CLIP_02') }, - { name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_COMPACTRIFLE_CLIP_03') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMPACTRIFLE_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMPACTRIFLE_CLIP_02')}, + {name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_COMPACTRIFLE_CLIP_03')} } }, @@ -334,10 +300,10 @@ Config.Weapons = { name = 'WEAPON_MG', label = _U('weapon_mg'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MG_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MG_CLIP_02') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_SMALL_02') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_MG_VARMOD_LOWRIDER') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MG_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MG_CLIP_02')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_SMALL_02')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_MG_VARMOD_LOWRIDER')} } }, @@ -345,11 +311,11 @@ Config.Weapons = { name = 'WEAPON_COMBATMG', label = _U('weapon_combatmg'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATMG_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATMG_CLIP_02') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MEDIUM') }, - { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_COMBATMG_VARMOD_LOWRIDER') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATMG_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATMG_CLIP_02')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MEDIUM')}, + {name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_COMBATMG_VARMOD_LOWRIDER')} } }, @@ -357,8 +323,8 @@ Config.Weapons = { name = 'WEAPON_GUSENBERG', label = _U('weapon_gusenberg'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_GUSENBERG_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_GUSENBERG_CLIP_02') }, + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_GUSENBERG_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_GUSENBERG_CLIP_02')}, } }, @@ -366,10 +332,10 @@ Config.Weapons = { name = 'WEAPON_SNIPERRIFLE', label = _U('weapon_sniperrifle'), components = { - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_LARGE') }, - { name = 'scope_advanced', label = _U('component_scope_advanced'), hash = GetHashKey('COMPONENT_AT_SCOPE_MAX') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SNIPERRIFLE_VARMOD_LUXE') } + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_LARGE')}, + {name = 'scope_advanced', label = _U('component_scope_advanced'), hash = GetHashKey('COMPONENT_AT_SCOPE_MAX')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SNIPERRIFLE_VARMOD_LUXE')} } }, @@ -377,8 +343,8 @@ Config.Weapons = { name = 'WEAPON_HEAVYSNIPER', label = _U('weapon_heavysniper'), components = { - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_LARGE') }, - { name = 'scope_advanced', label = _U('component_scope_advanced'), hash = GetHashKey('COMPONENT_AT_SCOPE_MAX') } + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_LARGE')}, + {name = 'scope_advanced', label = _U('component_scope_advanced'), hash = GetHashKey('COMPONENT_AT_SCOPE_MAX')} } }, @@ -386,266 +352,56 @@ Config.Weapons = { name = 'WEAPON_MARKSMANRIFLE', label = _U('weapon_marksmanrifle'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MARKSMANRIFLE_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MARKSMANRIFLE_CLIP_02') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_LARGE_FIXED_ZOOM') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP') }, - { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_MARKSMANRIFLE_VARMOD_LUXE') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MARKSMANRIFLE_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MARKSMANRIFLE_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_LARGE_FIXED_ZOOM')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP')}, + {name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_MARKSMANRIFLE_VARMOD_LUXE')} } }, - { - name = 'WEAPON_GRENADELAUNCHER', - label = _U('weapon_grenadelauncher'), - components = {} - }, - - { - name = 'WEAPON_RPG', - label = _U('weapon_rpg'), - components = {} - }, - - { - name = 'WEAPON_STINGER', - label = _U('weapon_stinger'), - components = {} - }, - - { - name = 'WEAPON_MINIGUN', - label = _U('weapon_minigun'), - components = {} - }, - - { - name = 'WEAPON_GRENADE', - label = _U('weapon_grenade'), - components = {} - }, - - { - name = 'WEAPON_STICKYBOMB', - label = _U('weapon_stickybomb'), - components = {} - }, - - { - name = 'WEAPON_SMOKEGRENADE', - label = _U('weapon_smokegrenade'), - components = {} - }, - - { - name = 'WEAPON_BZGAS', - label = _U('weapon_bzgas'), - components = {} - }, - - { - name = 'WEAPON_MOLOTOV', - label = _U('weapon_molotov'), - components = {} - }, - - { - name = 'WEAPON_FIREEXTINGUISHER', - label = _U('weapon_fireextinguisher'), - components = {} - }, - - { - name = 'WEAPON_PETROLCAN', - label = _U('weapon_petrolcan'), - components = {} - }, - - { - name = 'WEAPON_DIGISCANNER', - label = _U('weapon_digiscanner'), - components = {} - }, - - { - name = 'WEAPON_BALL', - label = _U('weapon_ball'), - components = {} - }, - - { - name = 'WEAPON_BOTTLE', - label = _U('weapon_bottle'), - components = {} - }, - - { - name = 'WEAPON_DAGGER', - label = _U('weapon_dagger'), - components = {} - }, - - { - name = 'WEAPON_FIREWORK', - label = _U('weapon_firework'), - components = {} - }, - - { - name = 'WEAPON_MUSKET', - label = _U('weapon_musket'), - components = {} - }, - - { - name = 'WEAPON_STUNGUN', - label = _U('weapon_stungun'), - components = {} - }, - - { - name = 'WEAPON_HOMINGLAUNCHER', - label = _U('weapon_hominglauncher'), - components = {} - }, - - { - name = 'WEAPON_PROXMINE', - label = _U('weapon_proxmine'), - components = {} - }, - - { - name = 'WEAPON_SNOWBALL', - label = _U('weapon_snowball'), - components = {} - }, - - { - name = 'WEAPON_FLAREGUN', - label = _U('weapon_flaregun'), - components = {} - }, - - { - name = 'WEAPON_GARBAGEBAG', - label = _U('weapon_garbagebag'), - components = {} - }, - - { - name = 'WEAPON_HANDCUFFS', - label = _U('weapon_handcuffs'), - components = {} - }, - - { - name = 'WEAPON_MARKSMANPISTOL', - label = _U('weapon_marksmanpistol'), - components = {} - }, - - { - name = 'WEAPON_KNUCKLE', - label = _U('weapon_knuckle'), - components = {} - }, - - { - name = 'WEAPON_HATCHET', - label = _U('weapon_hatchet'), - components = {} - }, - - { - name = 'WEAPON_RAILGUN', - label = _U('weapon_railgun'), - components = {} - }, - - { - name = 'WEAPON_MACHETE', - label = _U('weapon_machete'), - components = {} - }, - - { - name = 'WEAPON_SWITCHBLADE', - label = _U('weapon_switchblade'), - components = {} - }, - - { - name = 'WEAPON_DBSHOTGUN', - label = _U('weapon_dbshotgun'), - components = {} - }, - - { - name = 'WEAPON_AUTOSHOTGUN', - label = _U('weapon_autoshotgun'), - components = {} - }, - - { - name = 'WEAPON_BATTLEAXE', - label = _U('weapon_battleaxe'), - components = {} - }, - - { - name = 'WEAPON_COMPACTLAUNCHER', - label = _U('weapon_compactlauncher'), - components = {} - }, - - { - name = 'WEAPON_PIPEBOMB', - label = _U('weapon_pipebomb'), - components = {} - }, - - { - name = 'WEAPON_POOLCUE', - label = _U('weapon_poolcue'), - components = {} - }, - - { - name = 'WEAPON_WRENCH', - label = _U('weapon_wrench'), - components = {} - }, - - { - name = 'WEAPON_FLASHLIGHT', - label = _U('weapon_flashlight'), - components = {} - }, - - { - name = 'GADGET_NIGHTVISION', - label = _U('gadget_nightvision'), - components = {} - }, - - { - name = 'GADGET_PARACHUTE', - label = _U('gadget_parachute'), - components = {} - }, - - { - name = 'WEAPON_FLARE', - label = _U('weapon_flare'), - components = {} - }, - - { - name = 'WEAPON_DOUBLEACTION', - label = _U('weapon_doubleaction'), - components = {} - } - -} + {name = 'WEAPON_GRENADELAUNCHER', label = _U('weapon_grenadelauncher'), components = {}}, + {name = 'WEAPON_RPG', label = _U('weapon_rpg'), components = {}}, + {name = 'WEAPON_STINGER', label = _U('weapon_stinger'), components = {}}, + {name = 'WEAPON_MINIGUN', label = _U('weapon_minigun'), components = {}}, + {name = 'WEAPON_GRENADE', label = _U('weapon_grenade'), components = {}}, + {name = 'WEAPON_STICKYBOMB', label = _U('weapon_stickybomb'), components = {}}, + {name = 'WEAPON_SMOKEGRENADE', label = _U('weapon_smokegrenade'), components = {}}, + {name = 'WEAPON_BZGAS', label = _U('weapon_bzgas'), components = {}}, + {name = 'WEAPON_MOLOTOV', label = _U('weapon_molotov'), components = {}}, + {name = 'WEAPON_FIREEXTINGUISHER', label = _U('weapon_fireextinguisher'), components = {}}, + {name = 'WEAPON_PETROLCAN', label = _U('weapon_petrolcan'), components = {}}, + {name = 'WEAPON_DIGISCANNER', label = _U('weapon_digiscanner'), components = {}}, + {name = 'WEAPON_BALL', label = _U('weapon_ball'), components = {}}, + {name = 'WEAPON_BOTTLE', label = _U('weapon_bottle'), components = {}}, + {name = 'WEAPON_DAGGER', label = _U('weapon_dagger'), components = {}}, + {name = 'WEAPON_FIREWORK', label = _U('weapon_firework'), components = {}}, + {name = 'WEAPON_MUSKET', label = _U('weapon_musket'), components = {}}, + {name = 'WEAPON_STUNGUN', label = _U('weapon_stungun'), components = {}}, + {name = 'WEAPON_HOMINGLAUNCHER', label = _U('weapon_hominglauncher'), components = {}}, + {name = 'WEAPON_PROXMINE', label = _U('weapon_proxmine'), components = {}}, + {name = 'WEAPON_SNOWBALL', label = _U('weapon_snowball'), components = {}}, + {name = 'WEAPON_FLAREGUN', label = _U('weapon_flaregun'), components = {}}, + {name = 'WEAPON_GARBAGEBAG', label = _U('weapon_garbagebag'), components = {}}, + {name = 'WEAPON_HANDCUFFS', label = _U('weapon_handcuffs'), components = {}}, + {name = 'WEAPON_MARKSMANPISTOL', label = _U('weapon_marksmanpistol'), components = {}}, + {name = 'WEAPON_KNUCKLE', label = _U('weapon_knuckle'), components = {}}, + {name = 'WEAPON_HATCHET', label = _U('weapon_hatchet'), components = {}}, + {name = 'WEAPON_RAILGUN', label = _U('weapon_railgun'), components = {}}, + {name = 'WEAPON_MACHETE', label = _U('weapon_machete'), components = {}}, + {name = 'WEAPON_SWITCHBLADE', label = _U('weapon_switchblade'), components = {}}, + {name = 'WEAPON_DBSHOTGUN', label = _U('weapon_dbshotgun'), components = {}}, + {name = 'WEAPON_AUTOSHOTGUN', label = _U('weapon_autoshotgun'), components = {}}, + {name = 'WEAPON_BATTLEAXE', label = _U('weapon_battleaxe'), components = {}}, + {name = 'WEAPON_COMPACTLAUNCHER', label = _U('weapon_compactlauncher'), components = {}}, + {name = 'WEAPON_PIPEBOMB', label = _U('weapon_pipebomb'), components = {}}, + {name = 'WEAPON_POOLCUE', label = _U('weapon_poolcue'), components = {}}, + {name = 'WEAPON_WRENCH', label = _U('weapon_wrench'), components = {}}, + {name = 'WEAPON_FLASHLIGHT', label = _U('weapon_flashlight'), components = {}}, + {name = 'GADGET_NIGHTVISION', label = _U('gadget_nightvision'), components = {}}, + {name = 'GADGET_PARACHUTE', label = _U('gadget_parachute'), components = {}}, + {name = 'WEAPON_FLARE', label = _U('weapon_flare'), components = {}}, + {name = 'WEAPON_DOUBLEACTION', label = _U('weapon_doubleaction'), components = {}} +} \ No newline at end of file diff --git a/es_extended.sql b/es_extended.sql index 6ea1ce6f..38fc2f9d 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -3,31 +3,31 @@ USE `essentialmode`; ALTER TABLE `users` ADD COLUMN `name` VARCHAR(50) NULL DEFAULT '' AFTER `money`, ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, - ADD COLUMN `job` varchar(50) NULL DEFAULT 'unemployed' AFTER `skin`, + ADD COLUMN `job` VARCHAR(50) NULL DEFAULT 'unemployed' AFTER `skin`, ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, ADD COLUMN `position` VARCHAR(36) NULL AFTER `loadout` ; CREATE TABLE `items` ( - `name` varchar(50) NOT NULL, - `label` varchar(50) NOT NULL, - `limit` int(11) NOT NULL DEFAULT '-1', - `rare` int(11) NOT NULL DEFAULT '0', - `can_remove` int(11) NOT NULL DEFAULT '1', + `name` VARCHAR(50) NOT NULL, + `label` VARCHAR(50) NOT NULL, + `weight` TINYINT(1) NOT NULL DEFAULT 1, + `rare` TINYINT(1) NOT NULL DEFAULT 0, + `can_remove` TINYINT(1) NOT NULL DEFAULT 1, PRIMARY KEY (`name`) ); CREATE TABLE `job_grades` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `job_name` varchar(50) DEFAULT NULL, - `grade` int(11) NOT NULL, - `name` varchar(50) NOT NULL, - `label` varchar(50) NOT NULL, - `salary` int(11) NOT NULL, - `skin_male` longtext NOT NULL, - `skin_female` longtext NOT NULL, + `id` INT(11) NOT NULL AUTO_INCREMENT, + `job_name` VARCHAR(50) DEFAULT NULL, + `grade` INT(11) NOT NULL, + `name` VARCHAR(50) NOT NULL, + `label` VARCHAR(50) NOT NULL, + `salary` INT(11) NOT NULL, + `skin_male` LONGTEXT NOT NULL, + `skin_female` LONGTEXT NOT NULL, PRIMARY KEY (`id`) ); @@ -35,8 +35,8 @@ CREATE TABLE `job_grades` ( INSERT INTO `job_grades` VALUES (1,'unemployed',0,'unemployed','Unemployed',200,'{}','{}'); CREATE TABLE `jobs` ( - `name` varchar(50) NOT NULL, - `label` varchar(50) DEFAULT NULL, + `name` VARCHAR(50) NOT NULL, + `label` VARCHAR(50) DEFAULT NULL, PRIMARY KEY (`name`) ); @@ -44,19 +44,19 @@ CREATE TABLE `jobs` ( INSERT INTO `jobs` VALUES ('unemployed','Unemployed'); CREATE TABLE `user_accounts` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `identifier` varchar(22) NOT NULL, - `name` varchar(50) NOT NULL, - `money` double NOT NULL DEFAULT '0', + `id` INT(11) NOT NULL AUTO_INCREMENT, + `identifier` VARCHAR(22) NOT NULL, + `name` VARCHAR(50) NOT NULL, + `money` INT(11) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ); CREATE TABLE `user_inventory` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `identifier` varchar(22) NOT NULL, - `item` varchar(50) NOT NULL, - `count` int(11) NOT NULL, + `id` INT(11) NOT NULL AUTO_INCREMENT, + `identifier` VARCHAR(22) NOT NULL, + `item` VARCHAR(50) NOT NULL, + `count` INT(11) NOT NULL, PRIMARY KEY (`id`) ); diff --git a/locales/br.lua b/locales/br.lua index 9ef7555e..7a044fb7 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,7 +1,7 @@ Locales['br'] = { -- Inventory ['cash'] = 'efectivo', - ['inventory'] = 'inventario', + ['inventory'] = 'inventario %s / %s', ['use'] = 'usar', ['give'] = 'dar', ['remove'] = 'remover', @@ -13,14 +13,18 @@ Locales['br'] = { ['noammo'] = 'voce nao tem todas essas muniçoes!', ['gave_item'] = 'voce deu ~y~%sx~s~ ~b~%s~s~ para ~y~%s~s~', ['received_item'] = 'voce recebeu ~y~%sx~s~ ~b~%s~s~ de ~b~%s~s~', - ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ to ~y~%s~s~.', - ['gave_weapon_ammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', + ['gave_weapon'] = 'you gave ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'you gave ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', - ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ from ~b~%s~s~.', - ['received_weapon_ammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', - ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one.', - ['gave_ammo'] = 'voce deu ~o~%sx~s~ balas para ~y~%s~s~.', - ['received_ammo'] = 'voce recebeu ~o~%sx~s~ balas de ~b~%s~s~.', + ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['received_weapon'] = 'you received ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', + ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['gave_ammo'] = 'voce deu ~o~%sx~s~ balas para ~y~%s~s~', + ['received_ammo'] = 'voce recebeu ~o~%sx~s~ balas de ~b~%s~s~', ['gave_money'] = 'voce deu ~g~$%s~s~ para ~y~%s~s~', ['received_money'] = 'voce recebeu ~g~$%s~s~ de ~b~%s~s~', ['gave_account_money'] = 'voce deu ~g~$%s~s~ (%s) para ~y~%s~s~', @@ -33,19 +37,18 @@ Locales['br'] = { ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', - ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon'] = 'you threw ~b~%s~s~', + ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', -- Salary related ['received_salary'] = 'voce recebeu seu salario: ~g~$%s~s~ ', ['received_help'] = 'voce recebeu seu cheque de bem-estar: ~g~$%s~s~ ', - ['company_nomoney'] = 'a empresa em que voce esta empregado esta muito pobre para pagar seu salario.', + ['company_nomoney'] = 'a empresa em que voce esta empregado esta muito pobre para pagar seu salario', ['received_paycheck'] = 'recebeu dinheiro', ['bank'] = 'banco', ['black_money'] = 'dinheiro sujo', ['act_imp'] = 'acao impossivel', ['in_vehicle'] = 'voce nao pode dar nada para alguem no veiculo', - ['cannot_pickup_room'] = 'voce nao tem espaço suficiente no seu inventario para pegar ~y~%s~s~!', -- Commands ['setjob'] = 'atribuir um trabalho a um usuario', diff --git a/locales/cs.lua b/locales/cs.lua index 0b3b3e07..a620792c 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -1,7 +1,7 @@ Locales['cs'] = { -- Inventory ['cash'] = 'hotovost', - ['inventory'] = 'inventář', + ['inventory'] = 'inventář %s / %s', ['use'] = 'použít', ['give'] = 'dát', ['remove'] = 'zahodit', @@ -13,14 +13,18 @@ Locales['cs'] = { ['noammo'] = 'nemáte dostatek munice!', ['gave_item'] = 'dali jste ~y~%sx~s~ ~b~%s~s~ ~y~%s~s~', ['received_item'] = 'obdrželi jste ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', - ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ to ~y~%s~s~.', - ['gave_weapon_ammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', + ['gave_weapon'] = 'you gave ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'you gave ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', - ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ from ~b~%s~s~.', - ['received_weapon_ammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', - ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one.', - ['gave_ammo'] = 'dali jste ~o~%sx~s~ nábojů ~y~%s~s~.', - ['received_ammo'] = 'obdrželi jste ~o~%sx~s~ nábojů od ~b~%s~s~.', + ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['received_weapon'] = 'you received ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', + ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['gave_ammo'] = 'dali jste ~o~%sx~s~ nábojů ~y~%s~s~', + ['received_ammo'] = 'obdrželi jste ~o~%sx~s~ nábojů od ~b~%s~s~', ['gave_money'] = 'dali jste ~g~$%s~s~ ~y~%s~s~', ['received_money'] = 'obdrželi jste ~g~$%s~s~ od ~b~%s~s~', ['gave_account_money'] = 'dali jste ~g~$%s~s~ (%s) ~y~%s~s~', @@ -33,19 +37,18 @@ Locales['cs'] = { ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', - ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon'] = 'you threw ~b~%s~s~', + ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', -- Salary related ['received_salary'] = 'obdrželi jste výplatu: ~g~$%s~s~', ['received_help'] = 'obdrželi jste sociální dávku: ~g~$%s~s~', - ['company_nomoney'] = 'společnost u které jste zaměstananí nemá peníze na váš plat.', + ['company_nomoney'] = 'společnost u které jste zaměstananí nemá peníze na váš plat', ['received_paycheck'] = 'obdržena výplata', ['bank'] = 'bankovní účet', ['black_money'] = 'špinavé peníze', ['act_imp'] = 'akce není možná', ['in_vehicle'] = 'nemůže nic dát osobě ve vozidle', - ['cannot_pickup_room'] = 've vašem inventáři není dostatek místa pro ~y~%s~s~!', -- Commands ['setjob'] = 'přiřadit práci hráči', diff --git a/locales/de.lua b/locales/de.lua index 1aa9b2ed..10d67f5e 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -1,7 +1,7 @@ Locales['de'] = { -- Inventory ['cash'] = 'bargeld', - ['inventory'] = 'inventar', + ['inventory'] = 'inventar %s / %s', ['use'] = 'benutzen', ['give'] = 'geben', ['remove'] = 'entfernen', @@ -13,12 +13,16 @@ Locales['de'] = { ['noammo'] = 'du hast keine munition!', ['gave_item'] = 'du gibst ~y~%sx~s~ ~b~%s~s~ an ~y~%s~s~', ['received_item'] = 'du empfängst ~y~%sx~s~ ~b~%s~s~ von ~b~%s~s~', - ['gave_weapon'] = 'du gibst ~y~1x~s~ ~b~%s~s~ an ~y~%s~s~', - ['gave_weapon_ammo'] = 'du gibst ~y~1x~s~ ~b~%s~s~ mit ~o~%sx~s~ Schuss an ~y~%s~s~', + ['gave_weapon'] = 'du gibst ~b~%s~s~ an ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'du gibst ~b~%s~s~ mit ~o~%sx~s~ Schuss an ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ hat bereits eine(n) ~y~%s~s~', - ['received_weapon'] = 'du erhälst ~y~1x~s~ ~b~%s~s~ von ~b~%s~s~', - ['received_weapon_ammo'] = 'du erhälst ~y~1x~s~ ~b~%s~s~ mit ~o~%sx~s~ Schuss von ~b~%s~s~', + ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['received_weapon'] = 'du erhälst ~b~%s~s~ von ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'du erhälst ~b~%s~s~ mit ~o~%sx~s~ Schuss von ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ hat versucht dir eine(n) ~y~%s~s~ zu geben, aber du hast bereits eine(n)', + ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', ['gave_ammo'] = 'du gibst ~o~%sx~s~ Schuss an ~y~%s~s~', ['received_ammo'] = 'du erhälst ~o~%sx~s~ Schuss von ~b~%s~s~', ['gave_money'] = 'du gibst ~g~$%s~s~ an ~y~%s~s~', @@ -33,19 +37,18 @@ Locales['de'] = { ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', - ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon'] = 'you threw ~b~%s~s~', + ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', -- Salary related ['received_salary'] = 'du hast dein Gehalt erhalten: ~g~$%s~s~', - ['received_help'] = 'du hast deine Sozialhilfe erhalten.: ~g~$%s~s~', - ['company_nomoney'] = 'die Firma in der du angestellt bist, ist zu arm um dein Gehalt zu zahlen.', + ['received_help'] = 'du hast deine Sozialhilfe erhalten: ~g~$%s~s~', + ['company_nomoney'] = 'die Firma in der du angestellt bist, ist zu arm um dein Gehalt zu zahlen', ['received_paycheck'] = 'erhaltener Gehaltsscheck', ['bank'] = 'bank', ['black_money'] = 'schwarzgeld', ['act_imp'] = 'Aktion nicht möglich', ['in_vehicle'] = 'you can\'t give anything to someone in a vehicle', - ['cannot_pickup_room'] = 'you do not have enough space in your inventory to pick up ~y~%s~s~!', -- Commands ['setjob'] = 'assign a job to a user', diff --git a/locales/en.lua b/locales/en.lua index 1ccf6f37..91c9eca2 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,7 +1,7 @@ Locales['en'] = { -- Inventory ['cash'] = 'cash', - ['inventory'] = 'inventory', + ['inventory'] = 'inventory %s / %s', ['use'] = 'use', ['give'] = 'give', ['remove'] = 'throw', @@ -13,14 +13,18 @@ Locales['en'] = { ['noammo'] = 'you do not have enough ammo!', ['gave_item'] = 'you gave ~y~%sx~s~ ~b~%s~s~ to ~y~%s~s~', ['received_item'] = 'you received ~y~%sx~s~ ~b~%s~s~ from ~b~%s~s~', - ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ to ~y~%s~s~.', - ['gave_weapon_ammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', + ['gave_weapon'] = 'you gave ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'you gave ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', - ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ from ~b~%s~s~.', - ['received_weapon_ammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', - ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one.', - ['gave_ammo'] = 'you gave ~o~%sx~s~ bullets to ~y~%s~s~.', - ['received_ammo'] = 'you received ~o~%sx~s~ bullets from ~b~%s~s~.', + ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['received_weapon'] = 'you received ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', + ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['gave_ammo'] = 'you gave ~o~%sx~s~ bullets to ~y~%s~s~', + ['received_ammo'] = 'you received ~o~%sx~s~ bullets from ~b~%s~s~', ['gave_money'] = 'you gave ~g~$%s~s~ to ~y~%s~s~', ['received_money'] = 'you received ~g~$%s~s~ from ~b~%s~s~', ['gave_account_money'] = 'you gave ~g~$%s~s~ (%s) to ~y~%s~s~', @@ -33,19 +37,18 @@ Locales['en'] = { ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', - ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon'] = 'you threw ~b~%s~s~', + ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', -- Salary related ['received_salary'] = 'you received your salary: ~g~$%s~s~', ['received_help'] = 'you recieved your welfare check: ~g~$%s~s~', - ['company_nomoney'] = 'the company you\'re employeed at is too poor to pay out your salary.', + ['company_nomoney'] = 'the company you\'re employeed at is too poor to pay out your salary', ['received_paycheck'] = 'received paycheck', ['bank'] = 'bank', ['black_money'] = 'dirty Money', ['act_imp'] = 'action impossible', ['in_vehicle'] = 'you can\'t give anything to someone in a vehicle', - ['cannot_pickup_room'] = 'you do not have enough space in your inventory to pick up ~y~%s~s~!', -- Commands ['setjob'] = 'assign a job to a user', diff --git a/locales/fi.lua b/locales/fi.lua index 08adfa48..eb3ac49f 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -1,7 +1,7 @@ Locales['fi'] = { -- Inventory ['cash'] = 'käteinen', - ['inventory'] = 'reppu', + ['inventory'] = 'reppu %s / %s', ['use'] = 'käytä', ['give'] = 'anna', ['remove'] = 'poista', @@ -13,14 +13,18 @@ Locales['fi'] = { ['noammo'] = 'sinulla ei ole ammuksia!', ['gave_item'] = 'sinä annoit ~y~%sx~s~ ~b~%s~s~ henkilölle ~y~%s~s~', ['received_item'] = 'sinä sait ~y~%sx~s~ ~b~%s~s~ henkilöltä ~b~%s~s~', - ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ to ~y~%s~s~.', - ['gave_weapon_ammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', + ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', - ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ from ~b~%s~s~.', - ['received_weapon_ammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', - ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one.', - ['gave_ammo'] = 'sinä annoit ~o~%sx~s~ ammuksia henkilölle ~y~%s~s~.', - ['received_ammo'] = 'sinä sait ~o~%sx~s~ ammuksia henkilöltä ~b~%s~s~.', + ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', + ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['gave_ammo'] = 'sinä annoit ~o~%sx~s~ ammuksia henkilölle ~y~%s~s~', + ['received_ammo'] = 'sinä sait ~o~%sx~s~ ammuksia henkilöltä ~b~%s~s~', ['gave_money'] = 'sinä annoit ~g~$%s~s~ henkilölle ~y~%s~s~', ['received_money'] = 'sinä sait ~g~$%s~s~ henkilöltä ~b~%s~s~', ['gave_account_money'] = 'sinä annoit ~g~$%s~s~ (%s) henkilölle ~y~%s~s~', @@ -38,14 +42,13 @@ Locales['fi'] = { -- Salary related ['received_salary'] = 'sinä vastaanotit palkkaa: ~g~$%s~s~', ['received_help'] = 'sinä vastaanotit valtion tukea: ~g~$%s~s~', - ['company_nomoney'] = 'yritys jolle teet töitä on köyhä eikä voi maksaa palkkaasi.', + ['company_nomoney'] = 'yritys jolle teet töitä on köyhä eikä voi maksaa palkkaasi', ['received_paycheck'] = 'sait palkan', ['bank'] = 'pankki', ['black_money'] = 'likainen Raha', ['act_imp'] = 'toiminto mahdoton', - ['in_vehicle'] = 'et voi antaa ajoneuvossa olevalle mitään.', - ['cannot_pickup_room'] = 'sinulla ei ole tilaa repussa nostaaksesi ~y~%s~s~!', + ['in_vehicle'] = 'et voi antaa ajoneuvossa olevalle mitään', -- Commands ['setjob'] = 'määritä työ käyttäjälle', diff --git a/locales/fr.lua b/locales/fr.lua index f7c1fedd..11bfd194 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,7 +1,7 @@ Locales['fr'] = { -- Inventory ['cash'] = 'espèces', - ['inventory'] = 'inventaire', + ['inventory'] = 'inventaire %s / %s', ['use'] = 'utiliser', ['give'] = 'donner', ['remove'] = 'jeter', @@ -13,14 +13,18 @@ Locales['fr'] = { ['noammo'] = 'tu n\'as pas toutes ces munitions!', ['gave_item'] = 'vous avez donné ~y~%sx~s~ ~b~%s~s~ à ~y~%s~s~', ['received_item'] = 'vous avez reçu ~y~%sx~s~ ~b~%s~s~ par ~b~%s~s~', - ['gave_weapon'] = 'vous avez donné ~y~1x~s~ ~b~%s~s~ à ~y~%s~s~.', - ['gave_weapon_ammo'] = 'vous avez donné ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles à ~y~%s~s~.', + ['gave_weapon'] = 'vous avez donné ~y~1x~s~ ~b~%s~s~ à ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'vous avez donné ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles à ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ a déjà ~y~%s~s~', - ['received_weapon'] = 'vous recevez ~y~1x~s~ ~b~%s~s~ de ~b~%s~s~.', - ['received_weapon_ammo'] = 'vous avez reçu ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles de ~b~%s~s~.', - ['received_weapon_hasalready'] = '~b~%s~s~ a tenté de vous donner ~y~%s~s~, mais vous en aviez déjà un exemplaire.', - ['gave_ammo'] = 'vous donnez ~o~%sx~s~ munitions à ~y~%s~s~.', - ['received_ammo'] = 'vous recevez ~o~%sx~s~ munitions de ~b~%s~s~.', + ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['received_weapon'] = 'vous recevez ~y~1x~s~ ~b~%s~s~ de ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'vous avez reçu ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles de ~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~ a tenté de vous donner ~y~%s~s~, mais vous en aviez déjà un exemplaire', + ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['gave_ammo'] = 'vous donnez ~o~%sx~s~ munitions à ~y~%s~s~', + ['received_ammo'] = 'vous recevez ~o~%sx~s~ munitions de ~b~%s~s~', ['gave_money'] = 'vous avez donné ~g~$%s~s~ à ~y~%s~s~', ['received_money'] = 'vous avez reçu ~g~$%s~s~ par ~b~%s~s~', ['gave_account_money'] = 'vous avez donné ~g~$%s~s~ (%s) à ~y~%s~s~', @@ -45,7 +49,6 @@ Locales['fr'] = { ['act_imp'] = 'action impossible', ['in_vehicle'] = 'Vous ne pouvez rien donner à quelqu\'un dans un véhicule', - ['cannot_pickup_room'] = 'vous n\'avez plus de place pour ~y~%s~s~!', -- Commands ['setjob'] = 'assigner job', diff --git a/locales/pl.lua b/locales/pl.lua index ee840465..f4e927c4 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -1,7 +1,7 @@ Locales['pl'] = { -- Inventory ['cash'] = 'gotówka', - ['inventory'] = 'ekwipunek', + ['inventory'] = 'ekwipunek %s / %s', ['use'] = 'użyj', ['give'] = 'daj', ['remove'] = 'usuń', @@ -13,14 +13,18 @@ Locales['pl'] = { ['noammo'] = 'nie posiadasz wystarczającej ilości amunicji!', ['gave_item'] = 'dajesz ~y~%sx~s~ ~b~%s~s~ dla ~y~%s~s~', ['received_item'] = 'otrzymujesz ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', - ['gave_weapon'] = 'dajesz ~y~1x~s~ ~b~%s~s~ dla ~y~%s~s~.', - ['gave_weapon_ammo'] = 'dałeś/aś ~y~1x~s~ ~b~%s~s~ z ~o~%sx~s~ nabojami dla ~y~%s~s~.', + ['gave_weapon'] = 'dajesz ~b~%s~s~ dla ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'dałeś/aś ~b~%s~s~ z ~o~%sx~s~ nabojami dla ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ już posiada ~y~%s~s~', - ['received_weapon'] = 'otrzymałeś/aś ~y~1x~s~ ~b~%s~s~ od ~b~%s~s~.', - ['received_weapon_ammo'] = 'otrzymałeś/aś ~y~1x~s~ ~b~%s~s~ z ~o~%sx~s~ nabojami od ~b~%s~s~.', - ['received_weapon_hasalready'] = '~b~%s~s~ próbował/a przekazać ci ~y~%s~s~, lecz już posiadasz jedno.', - ['gave_ammo'] = 'dajesz ~o~%sx~s~ naboje dla ~y~%s~s~.', - ['received_ammo'] = 'otrzymujesz ~o~%sx~s~ naboje od ~b~%s~s~.', + ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['received_weapon'] = 'otrzymałeś/aś ~b~%s~s~ od ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'otrzymałeś/aś ~b~%s~s~ z ~o~%sx~s~ nabojami od ~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~ próbował/a przekazać ci ~y~%s~s~, lecz już posiadasz jedno', + ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['gave_ammo'] = 'dajesz ~o~%sx~s~ naboje dla ~y~%s~s~', + ['received_ammo'] = 'otrzymujesz ~o~%sx~s~ naboje od ~b~%s~s~', ['gave_money'] = 'dajesz ~g~%s$~s~ dla ~y~%s~s~', ['received_money'] = 'otrzymujesz ~g~%s$~s~ od ~b~%s~s~', ['gave_account_money'] = 'dajesz ~g~%s$~s~ (%s) dla ~y~%s~s~', @@ -33,19 +37,18 @@ Locales['pl'] = { ['threw_standard'] = 'wyrzuciłeś/aś ~y~%sx~s~ ~b~%s~s~', ['threw_money'] = 'wyrzuciłeś/aś ~r~$%s~s~ ~b~gotówki~s~', ['threw_account'] = 'wyrzuciłeś/aś ~r~$%s~s~ ~b~%s~s~', - ['threw_weapon'] = 'wyrzuciłeś/aś ~y~1x~s~ ~b~%s~s~', - ['threw_weapon_ammo'] = 'wyrzuciłeś/aś ~y~1x~s~ ~b~%s~s~ z ~o~%sx~s~ nabojami', + ['threw_weapon'] = 'wyrzuciłeś/aś ~b~%s~s~', + ['threw_weapon_ammo'] = 'wyrzuciłeś/aś ~b~%s~s~ z ~o~%sx~s~ nabojami', -- Salary related ['received_salary'] = 'otrzymałeś wynagrodzenie: ~g~%s$~s~', ['received_help'] = 'otrzymałem zapomogę: ~g~$%s~s~', - ['company_nomoney'] = 'firma, w której pracujesz, jest zbyt biedna, by wypłacić twoją pensję.', + ['company_nomoney'] = 'firma, w której pracujesz, jest zbyt biedna, by wypłacić twoją pensję', ['received_paycheck'] = 'otrzymana wypłata', ['bank'] = 'bank', ['black_money'] = 'brudne pieniądze', ['act_imp'] = 'działanie niemożliwe', ['in_vehicle'] = 'nie możesz przekazywać przedmiotów w pojeździe', - ['cannot_pickup_room'] = 'nie masz wystarczająco dużo miejsca w ekwipunku, aby podnieść ~y~%s~s~!', -- Commands ['setjob'] = 'przydziel prace użytkownikowi', diff --git a/locales/sv.lua b/locales/sv.lua index 647dd50b..38d9d115 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -1,7 +1,7 @@ Locales['sv'] = { -- Inventory ['cash'] = 'kontanter', - ['inventory'] = 'mitt förråd', + ['inventory'] = 'mitt förråd %s / %s', ['use'] = 'använd', ['give'] = 'ge', ['remove'] = 'kasta', @@ -13,14 +13,18 @@ Locales['sv'] = { ['noammo'] = 'du har inte tillräckligt med ammunition!', ['gave_item'] = 'du gav ~y~%sx~s~ ~b~%s~s~ till ~y~%s~s~', ['received_item'] = 'du tog emot ~y~%sx~s~ ~b~%s~s~ från ~b~%s~s~', - ['gave_weapon'] = 'du gav ~y~1x~s~ ~b~%s~s~ till ~y~%s~s~.', - ['gave_weapon_ammo'] = 'du gav ~y~1x~s~ ~b~%s~s~ med ~o~%sx~s~ skott till ~y~%s~s~.', + ['gave_weapon'] = 'du gav ~b~%s~s~ till ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'du gav ~b~%s~s~ med ~o~%sx~s~ skott till ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ har redan en ~y~%s~s~', - ['received_weapon'] = 'du tog emot ~y~1x~s~ ~b~%s~s~ från ~b~%s~s~.', - ['received_weapon_ammo'] = 'du tog emot ~y~1x~s~ ~b~%s~s~ med ~o~%sx~s~ skott från ~b~%s~s~.', - ['received_weapon_hasalready'] = '~b~%s~s~ försökte ge dig en ~y~%s~s~, men det har du redan.', - ['gave_ammo'] = 'du gav ~o~%sx~s~ skott till ~y~%s~s~.', - ['received_ammo'] = 'du tog emot ~o~%sx~s~ skott från ~b~%s~s~.', + ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['received_weapon'] = 'du tog emot ~b~%s~s~ från ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'du tog emot ~b~%s~s~ med ~o~%sx~s~ skott från ~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~ försökte ge dig en ~y~%s~s~, men det har du redan', + ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['gave_ammo'] = 'du gav ~o~%sx~s~ skott till ~y~%s~s~', + ['received_ammo'] = 'du tog emot ~o~%sx~s~ skott från ~b~%s~s~', ['gave_money'] = 'du gav ~g~%s SEK~s~ till ~y~%s~s~', ['received_money'] = 'du tog emot ~g~%s SEK~s~ från ~b~%s~s~', ['gave_account_money'] = 'du gav ~g~%s SEK~s~ (%s) till ~y~%s~s~', @@ -33,22 +37,21 @@ Locales['sv'] = { ['threw_standard'] = 'du kastade ~y~%sx~s~ ~b~%s~s~', ['threw_money'] = 'du kastade ~r~$%s~s~ ~b~kontanter~s~', ['threw_account'] = 'du kastade ~r~$%s~s~ ~b~%s~s~', - ['threw_weapon'] = 'du kastade ~y~1x~s~ ~b~%s~s~', - ['threw_weapon_ammo'] = 'du kastade ~y~1x~s~ ~b~%s~s~ med ~o~%sx~s~ skott', + ['threw_weapon'] = 'du kastade ~b~%s~s~', + ['threw_weapon_ammo'] = 'du kastade ~b~%s~s~ med ~o~%sx~s~ skott', -- Salary related ['received_salary'] = 'du har mottagit din lön på ~g~%s SEK~s~', ['received_help'] = 'du har mottagit bidrag på ~g~%s SEK~s~', - ['company_nomoney'] = 'företaget du är anställt hos har inte råd att betala ut din lön.', + ['company_nomoney'] = 'företaget du är anställt hos har inte råd att betala ut din lön', ['received_paycheck'] = 'mottagit lön', ['bank'] = 'bank', ['black_money'] = 'svarta pengar', ['act_imp'] = 'åtgärd omöjlig', ['in_vehicle'] = 'du kan inte ge saker till en som sitter i ett fordon!', - ['cannot_pickup_room'] = 'du har inte plats för att plocka upp ~y~%s~s~!', -- Commands - ['setjob'] = 'tilldela ett jobb till en användare', + ['setjob'] = 'tilldela ett jobb till en spelare', ['id_param'] = 'spelarens ID', ['setjob_param2'] = 'det jobb du vill tilldela', ['setjob_param3'] = 'job level', diff --git a/server/classes/player.lua b/server/classes/player.lua index 6fc49b8a..8e67fe7f 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -8,6 +8,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.loadout = loadout self.name = name self.lastPosition = lastPosition + self.maxWeight = Config.MaxWeight self.source = self.player.get('source') self.identifier = self.player.get('identifier') @@ -350,6 +351,28 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end end + self.getWeight = function() + local inventoryWeight = 0 + + for k,v in ipairs(self.inventory) do + inventoryWeight = inventoryWeight + (v.count * v.weight) + end + + return inventoryWeight + end + + self.canCarryItem = function(name, count) + local currentWeight, itemWeight = self.getWeight(), ESX.Items[name].weight + local newWeight = currentWeight + (itemWeight * count) + + return newWeight <= self.maxWeight + end + + self.setMaxWeight = function(newWeight) + self.maxWeight = newWeight + TriggerClientEvent('esx:setMaxWeight', self.source, self.maxWeight) + end + self.setJob = function(job, grade) grade = tostring(grade) local lastJob = json.decode(json.encode(self.job)) @@ -403,13 +426,21 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.addWeaponComponent = function(weaponName, weaponComponent) local loadoutNum, weapon = self.getWeapon(weaponName) - if self.hasWeaponComponent(weaponName, weaponComponent) then - return + if weapon then + if not self.hasWeaponComponent(weaponName, weaponComponent) then + table.insert(self.loadout[loadoutNum].components, weaponComponent) + TriggerClientEvent('esx:addWeaponComponent', self.source, weaponName, weaponComponent) + end end + end - table.insert(self.loadout[loadoutNum].components, weaponComponent) + self.addWeaponAmmo = function(weaponName, ammoCount) + local loadoutNum, weapon = self.getWeapon(weaponName) - TriggerClientEvent('esx:addWeaponComponent', self.source, weaponName, weaponComponent) + if weapon then + weapon.ammo = weapon.ammo + ammoCount + TriggerClientEvent('esx:setWeaponAmmo', self.source, weaponName, weapon.ammo) + end end self.removeWeapon = function(weaponName, ammo) @@ -437,34 +468,41 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.removeWeaponComponent = function(weaponName, weaponComponent) local loadoutNum, weapon = self.getWeapon(weaponName) - if not weapon then - return - end - - for k,v in ipairs(self.loadout[loadoutNum].components) do - if v.name == weaponComponent then - table.remove(self.loadout[loadoutNum].components, k) - break + if weapon then + for k,v in ipairs(self.loadout[loadoutNum].components) do + if v.name == weaponComponent then + table.remove(self.loadout[loadoutNum].components, k) + break + end end + + TriggerClientEvent('esx:removeWeaponComponent', self.source, weaponName, weaponComponent) end + end - TriggerClientEvent('esx:removeWeaponComponent', self.source, weaponName, weaponComponent) + self.removeWeaponAmmo = function(weaponName, ammoCount) + local loadoutNum, weapon = self.getWeapon(weaponName) + + if weapon then + weapon.ammo = weapon.ammo - ammoCount + TriggerClientEvent('esx:setWeaponAmmo', self.source, weaponName, weapon.ammo) + end end self.hasWeaponComponent = function(weaponName, weaponComponent) local loadoutNum, weapon = self.getWeapon(weaponName) - if not weapon then + if weapon then + for k,v in ipairs(weapon.components) do + if v == weaponComponent then + return true + end + end + + return false + else return false end - - for k,v in ipairs(weapon.components) do - if v == weaponComponent then - return true - end - end - - return false end self.hasWeapon = function(weaponName) diff --git a/server/common.lua b/server/common.lua index 9009735f..ed937f54 100644 --- a/server/common.lua +++ b/server/common.lua @@ -1,14 +1,14 @@ -ESX = {} -ESX.Players = {} +ESX = {} +ESX.Players = {} ESX.UsableItemsCallbacks = {} -ESX.Items = {} -ESX.ServerCallbacks = {} -ESX.TimeoutCount = -1 -ESX.CancelledTimeouts = {} -ESX.LastPlayerData = {} -ESX.Pickups = {} -ESX.PickupId = 0 -ESX.Jobs = {} +ESX.Items = {} +ESX.ServerCallbacks = {} +ESX.TimeoutCount = -1 +ESX.CancelledTimeouts = {} +ESX.LastPlayerData = {} +ESX.Pickups = {} +ESX.PickupId = 0 +ESX.Jobs = {} AddEventHandler('esx:getSharedObject', function(cb) cb(ESX) @@ -20,12 +20,12 @@ end MySQL.ready(function() MySQL.Async.fetchAll('SELECT * FROM items', {}, function(result) - for i=1, #result, 1 do - ESX.Items[result[i].name] = { - label = result[i].label, - limit = result[i].limit, - rare = (result[i].rare == 1 and true or false), - canRemove = (result[i].can_remove == 1 and true or false), + for k,v in ipairs(result) do + ESX.Items[v.name] = { + label = v.label, + weight = v.weight, + rare = v.rare, + canRemove = v.can_remove } end end) diff --git a/server/main.lua b/server/main.lua index 86d7f2f4..48821a4d 100644 --- a/server/main.lua +++ b/server/main.lua @@ -47,26 +47,26 @@ AddEventHandler('es:playerLoaded', function(source, _player) -- Get inventory table.insert(tasks, function(cb) - MySQL.Async.fetchAll('SELECT * FROM user_inventory WHERE identifier = @identifier', { + MySQL.Async.fetchAll('SELECT item, count FROM user_inventory WHERE identifier = @identifier', { ['@identifier'] = player.getIdentifier() }, function(inventory) local tasks2 = {} - for i=1, #inventory do - local item = ESX.Items[inventory[i].item] + for k,v in ipairs(inventory) do + local item = ESX.Items[v.item] if item then table.insert(userData.inventory, { - name = inventory[i].item, - count = inventory[i].count, + name = v.item, + count = v.count, label = item.label, - limit = item.limit, - usable = ESX.UsableItemsCallbacks[inventory[i].item] ~= nil, + weight = item.weight, + usable = ESX.UsableItemsCallbacks[v.item] ~= nil, rare = item.rare, canRemove = item.canRemove }) else - print(('es_extended: invalid item "%s" ignored!'):format(inventory[i].item)) + print(('es_extended: invalid item "%s" ignored!'):format(v.item)) end end @@ -85,7 +85,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) name = k, count = 0, label = ESX.Items[k].label, - limit = ESX.Items[k].limit, + weight = ESX.Items[k].weight, usable = ESX.UsableItemsCallbacks[k] ~= nil, rare = ESX.Items[k].rare, canRemove = ESX.Items[k].canRemove @@ -230,7 +230,8 @@ AddEventHandler('es:playerLoaded', function(source, _player) job = xPlayer.getJob(), loadout = xPlayer.getLoadout(), lastPosition = xPlayer.getLastPosition(), - money = xPlayer.getMoney() + money = xPlayer.getMoney(), + maxWeight = xPlayer.maxWeight }) xPlayer.displayMoney(xPlayer.getMoney()) @@ -269,179 +270,161 @@ end) RegisterServerEvent('esx:giveInventoryItem') AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCount) - local _source = source - - local sourceXPlayer = ESX.GetPlayerFromId(_source) + local playerId = source + local sourceXPlayer = ESX.GetPlayerFromId(playerId) local targetXPlayer = ESX.GetPlayerFromId(target) if type == 'item_standard' then - local sourceItem = sourceXPlayer.getInventoryItem(itemName) local targetItem = targetXPlayer.getInventoryItem(itemName) if itemCount > 0 and sourceItem.count >= itemCount then - - if targetItem.limit ~= -1 and (targetItem.count + itemCount) > targetItem.limit then - TriggerClientEvent('esx:showNotification', _source, _U('ex_inv_lim', targetXPlayer.name)) - else + if targetXPlayer.canCarryItem(itemName, itemCount) then sourceXPlayer.removeInventoryItem(itemName, itemCount) targetXPlayer.addInventoryItem (itemName, itemCount) - TriggerClientEvent('esx:showNotification', _source, _U('gave_item', itemCount, ESX.Items[itemName].label, targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('received_item', itemCount, ESX.Items[itemName].label, sourceXPlayer.name)) + sourceXPlayer.showNotification(_U('gave_item', itemCount, sourceItem.label, targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_item', itemCount, sourceItem.label, sourceXPlayer.name)) + else + sourceXPlayer.showNotification(_U('ex_inv_lim', targetXPlayer.name)) end - else - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) + sourceXPlayer.showNotification(_U('imp_invalid_quantity')) end - elseif type == 'item_money' then - if itemCount > 0 and sourceXPlayer.getMoney() >= itemCount then sourceXPlayer.removeMoney(itemCount) targetXPlayer.addMoney (itemCount) - TriggerClientEvent('esx:showNotification', _source, _U('gave_money', ESX.Math.GroupDigits(itemCount), targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('received_money', ESX.Math.GroupDigits(itemCount), sourceXPlayer.name)) + sourceXPlayer.showNotification(_U('gave_money', ESX.Math.GroupDigits(itemCount), targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_money', ESX.Math.GroupDigits(itemCount), sourceXPlayer.name)) else - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + sourceXPlayer.showNotification(_U('imp_invalid_amount')) end - elseif type == 'item_account' then - if itemCount > 0 and sourceXPlayer.getAccount(itemName).money >= itemCount then sourceXPlayer.removeAccountMoney(itemName, itemCount) targetXPlayer.addAccountMoney (itemName, itemCount) - TriggerClientEvent('esx:showNotification', _source, _U('gave_account_money', ESX.Math.GroupDigits(itemCount), Config.AccountLabels[itemName], targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('received_account_money', ESX.Math.GroupDigits(itemCount), Config.AccountLabels[itemName], sourceXPlayer.name)) + sourceXPlayer.showNotification(_U('gave_account_money', ESX.Math.GroupDigits(itemCount), Config.AccountLabels[itemName], targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_account_money', ESX.Math.GroupDigits(itemCount), Config.AccountLabels[itemName], sourceXPlayer.name)) else - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + sourceXPlayer.showNotification(_U('imp_invalid_amount')) end - elseif type == 'item_weapon' then - if not targetXPlayer.hasWeapon(itemName) then sourceXPlayer.removeWeapon(itemName) targetXPlayer.addWeapon(itemName, itemCount) - local weaponLabel = ESX.GetWeaponLabel(itemName) if itemCount > 0 then - TriggerClientEvent('esx:showNotification', _source, _U('gave_weapon_ammo', weaponLabel, itemCount, targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('received_weapon_ammo', weaponLabel, itemCount, sourceXPlayer.name)) + sourceXPlayer.showNotification(_U('gave_weapon_withammo', weaponLabel, itemCount, targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_weapon_withammo', weaponLabel, itemCount, sourceXPlayer.name)) else - TriggerClientEvent('esx:showNotification', _source, _U('gave_weapon', weaponLabel, targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('received_weapon', weaponLabel, sourceXPlayer.name)) + sourceXPlayer.showNotification(_U('gave_weapon', weaponLabel, targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_weapon', weaponLabel, sourceXPlayer.name)) end else - TriggerClientEvent('esx:showNotification', _source, _U('gave_weapon_hasalready', targetXPlayer.name, weaponLabel)) - TriggerClientEvent('esx:showNotification', target, _U('received_weapon_hasalready', sourceXPlayer.name, weaponLabel)) + sourceXPlayer.showNotification(_U('gave_weapon_hasalready', targetXPlayer.name, weaponLabel)) + targetXPlayer.showNotification(_U('received_weapon_hasalready', sourceXPlayer.name, weaponLabel)) end + elseif type == 'item_ammo' then + if sourceXPlayer.hasWeapon(itemName) then + if targetXPlayer.hasWeapon(itemName) then + local weaponNum, weapon = sourceXPlayer.getWeapon(itemName) + if weapon.ammo >= itemCount then + sourceXPlayer.removeWeaponAmmo(itemName, itemCount) + targetXPlayer.addWeaponAmmo(itemName, itemCount) + + sourceXPlayer.showNotification(_U('gave_weapon_ammo', itemCount, weapon.label, targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_weapon_ammo', itemCount, weapon.label, sourceXPlayer.name)) + end + else + sourceXPlayer.showNotification(_U('gave_weapon_noweapon', targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_weapon_noweapon', sourceXPlayer.name, weapon.label)) + end + end end end) RegisterServerEvent('esx:removeInventoryItem') AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) - local _source = source + local playerId = source + local xPlayer = ESX.GetPlayerFromId(source) if type == 'item_standard' then - if itemCount == nil or itemCount < 1 then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) + xPlayer.showNotification(_U('imp_invalid_quantity')) else - local xPlayer = ESX.GetPlayerFromId(source) local xItem = xPlayer.getInventoryItem(itemName) if (itemCount > xItem.count or xItem.count < 1) then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) + xPlayer.showNotification(_U('imp_invalid_quantity')) else xPlayer.removeInventoryItem(itemName, itemCount) - local pickupLabel = ('~y~%s~s~ [~b~%s~s~]'):format(xItem.label, itemCount) - ESX.CreatePickup('item_standard', itemName, itemCount, pickupLabel, _source) - TriggerClientEvent('esx:showNotification', _source, _U('threw_standard', itemCount, xItem.label)) + ESX.CreatePickup('item_standard', itemName, itemCount, pickupLabel, playerId) + xPlayer.showNotification(_U('threw_standard', itemCount, xItem.label)) end end - elseif type == 'item_money' then - if itemCount == nil or itemCount < 1 then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + xPlayer.showNotification(_U('imp_invalid_amount')) else - local xPlayer = ESX.GetPlayerFromId(source) local playerCash = xPlayer.getMoney() if (itemCount > playerCash or playerCash < 1) then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + xPlayer.showNotification(_U('imp_invalid_amount')) else xPlayer.removeMoney(itemCount) - local pickupLabel = ('~y~%s~s~ [~g~%s~s~]'):format(_U('cash'), _U('locale_currency', ESX.Math.GroupDigits(itemCount))) - ESX.CreatePickup('item_money', 'money', itemCount, pickupLabel, _source) - TriggerClientEvent('esx:showNotification', _source, _U('threw_money', ESX.Math.GroupDigits(itemCount))) + ESX.CreatePickup('item_money', 'money', itemCount, pickupLabel, playerId) + xPlayer.showNotification(_U('threw_money', ESX.Math.GroupDigits(itemCount))) end end - elseif type == 'item_account' then - if itemCount == nil or itemCount < 1 then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + xPlayer.showNotification(_U('imp_invalid_amount')) else - local xPlayer = ESX.GetPlayerFromId(source) local account = xPlayer.getAccount(itemName) if (itemCount > account.money or account.money < 1) then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + xPlayer.showNotification(_U('imp_invalid_amount')) else xPlayer.removeAccountMoney(itemName, itemCount) - local pickupLabel = ('~y~%s~s~ [~g~%s~s~]'):format(account.label, _U('locale_currency', ESX.Math.GroupDigits(itemCount))) - ESX.CreatePickup('item_account', itemName, itemCount, pickupLabel, _source) - TriggerClientEvent('esx:showNotification', _source, _U('threw_account', ESX.Math.GroupDigits(itemCount), string.lower(account.label))) + ESX.CreatePickup('item_account', itemName, itemCount, pickupLabel, playerId) + xPlayer.showNotification(_U('threw_account', ESX.Math.GroupDigits(itemCount), string.lower(account.label))) end end - elseif type == 'item_weapon' then - - local xPlayer = ESX.GetPlayerFromId(source) - local loadout = xPlayer.getLoadout() - - for i=1, #loadout, 1 do - if loadout[i].name == itemName then - itemCount = loadout[i].ammo - break - end - end - if xPlayer.hasWeapon(itemName) then - local weaponLabel, weaponPickup = ESX.GetWeaponLabel(itemName), 'PICKUP_' .. string.upper(itemName) - + local weaponNum, weapon = xPlayer.getWeapon(itemName) + local weaponPickup = 'PICKUP_' .. string.upper(itemName) xPlayer.removeWeapon(itemName) - if itemCount > 0 then - TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, itemName, itemCount) - TriggerClientEvent('esx:showNotification', _source, _U('threw_weapon_ammo', weaponLabel, itemCount)) + if weapon.ammo > 0 then + TriggerClientEvent('esx:pickupWeapon', playerId, weaponPickup, itemName, weapon.ammo) + xPlayer.showNotification(_U('threw_weapon_ammo', weapon.label, weapon.ammo)) else -- workaround for CreateAmbientPickup() giving 30 rounds of ammo when you drop the weapon with 0 ammo - TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, itemName, 1) - TriggerClientEvent('esx:showNotification', _source, _U('threw_weapon', weaponLabel)) + TriggerClientEvent('esx:pickupWeapon', playerId, weaponPickup, itemName, 1) + xPlayer.showNotification(_U('threw_weapon', weapon.label)) end end - end end) RegisterServerEvent('esx:useItem') AddEventHandler('esx:useItem', function(itemName) local xPlayer = ESX.GetPlayerFromId(source) - local count = xPlayer.getInventoryItem(itemName).count + local count = xPlayer.getInventoryItem(itemName).count if count > 0 then ESX.UseItem(source, itemName) else - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('act_imp')) + xPlayer.showNotification(_U('act_imp')) end end) @@ -452,25 +435,10 @@ AddEventHandler('esx:onPickup', function(id) local xPlayer = ESX.GetPlayerFromId(_source) if pickup.type == 'item_standard' then - - local item = xPlayer.getInventoryItem(pickup.name) - local canTake = ((item.limit == -1) and (pickup.count)) or ((item.limit - item.count > 0) and (item.limit - item.count)) or 0 - local total = pickup.count < canTake and pickup.count or canTake - local remaining = pickup.count - total - - TriggerClientEvent('esx:removePickup', -1, id) - - if total > 0 then - xPlayer.addInventoryItem(pickup.name, total) + if xPlayer.canCarryItem(pickup.name, pickup.count) then + xPlayer.addInventoryItem(pickup.name, pickup.count) + TriggerClientEvent('esx:removePickup', -1, id) end - - if remaining > 0 then - TriggerClientEvent('esx:showNotification', _source, _U('cannot_pickup_room', item.label)) - - local pickupLabel = ('~y~%s~s~ [~b~%s~s~]'):format(item.label, remaining) - ESX.CreatePickup('item_standard', pickup.name, remaining, pickupLabel, _source) - end - elseif pickup.type == 'item_money' then TriggerClientEvent('esx:removePickup', -1, id) xPlayer.addMoney(pickup.count) From e530a6d39ceb8220fd2828c399a82f20bf86c084 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 13 Oct 2019 20:59:11 +0200 Subject: [PATCH 2287/3224] Add support for new esx weight --- config.lua | 4 ++++ server/main.lua | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/config.lua b/config.lua index 1875b978..79d7c815 100644 --- a/config.lua +++ b/config.lua @@ -1,3 +1,7 @@ Config = {} Config.Locale = 'fr' + +Config.BackpackWeight = { + [40] = 16, [41] = 20, [44] = 25, [45] = 23 +} \ No newline at end of file diff --git a/server/main.lua b/server/main.lua index b2dc4b12..ee80b636 100644 --- a/server/main.lua +++ b/server/main.lua @@ -5,6 +5,14 @@ TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) RegisterServerEvent('esx_skin:save') AddEventHandler('esx_skin:save', function(skin) local xPlayer = ESX.GetPlayerFromId(source) + local defaultMaxWeight = ESX.GetConfig().MaxWeight + local backpackModifier = Config.BackpackWeight[skin.bags_1] + + if backpackModifier then + xPlayer.setMaxWeight(defaultMaxWeight + backpackModifier) + else + xPlayer.setMaxWeight(defaultMaxWeight) + end MySQL.Async.execute('UPDATE users SET skin = @skin WHERE identifier = @identifier', { ['@skin'] = json.encode(skin), From d9a545727f3834580d540a733ede2de19fb04549 Mon Sep 17 00:00:00 2001 From: BenjiM <34999231+BenjiM@users.noreply.github.com> Date: Mon, 14 Oct 2019 01:34:47 +0200 Subject: [PATCH 2288/3224] Update fr.lua --- locales/fr.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index 11bfd194..45362203 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -14,15 +14,15 @@ Locales['fr'] = { ['gave_item'] = 'vous avez donné ~y~%sx~s~ ~b~%s~s~ à ~y~%s~s~', ['received_item'] = 'vous avez reçu ~y~%sx~s~ ~b~%s~s~ par ~b~%s~s~', ['gave_weapon'] = 'vous avez donné ~y~1x~s~ ~b~%s~s~ à ~y~%s~s~', - ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_ammo'] = 'vous avez donné ~o~%sx~s~ balles pour ~b~%s~s~ à ~y~%s~s~', ['gave_weapon_withammo'] = 'vous avez donné ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles à ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ a déjà ~y~%s~s~', - ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['gave_weapon_noweapon'] = '~y~%s~s~ n\'a pas cette arme', ['received_weapon'] = 'vous recevez ~y~1x~s~ ~b~%s~s~ de ~b~%s~s~', - ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_ammo'] = 'vous avez reçu ~o~%sx~s~ balles pour votre ~b~%s~s~ de ~b~%s~s~', ['received_weapon_withammo'] = 'vous avez reçu ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles de ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ a tenté de vous donner ~y~%s~s~, mais vous en aviez déjà un exemplaire', - ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['received_weapon_noweapon'] = '~b~%s~s~ tente de vous donner des munitions pour ~y~%s~s~, mais vous n\'en avez pas', ['gave_ammo'] = 'vous donnez ~o~%sx~s~ munitions à ~y~%s~s~', ['received_ammo'] = 'vous recevez ~o~%sx~s~ munitions de ~b~%s~s~', ['gave_money'] = 'vous avez donné ~g~$%s~s~ à ~y~%s~s~', From 9ac7d39884faee4775d2f6afdc0b12e0656f7f34 Mon Sep 17 00:00:00 2001 From: userMacieG Date: Mon, 14 Oct 2019 14:07:27 +0200 Subject: [PATCH 2289/3224] Update pl.lua --- locales/pl.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/locales/pl.lua b/locales/pl.lua index f4e927c4..57ee9a5b 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -14,15 +14,15 @@ Locales['pl'] = { ['gave_item'] = 'dajesz ~y~%sx~s~ ~b~%s~s~ dla ~y~%s~s~', ['received_item'] = 'otrzymujesz ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', ['gave_weapon'] = 'dajesz ~b~%s~s~ dla ~y~%s~s~', - ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_ammo'] = 'dałeś/aś ~o~%sx~s~ naboi do ~b~%s~s~ dla ~y~%s~s~', ['gave_weapon_withammo'] = 'dałeś/aś ~b~%s~s~ z ~o~%sx~s~ nabojami dla ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ już posiada ~y~%s~s~', - ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['gave_weapon_noweapon'] = '~y~%s~s~ nie posiada tej broni', ['received_weapon'] = 'otrzymałeś/aś ~b~%s~s~ od ~b~%s~s~', - ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_ammo'] = 'otrzymałeś/aś ~o~%sx~s~ naboi do twojego ~b~%s~s~ od ~b~%s~s~', ['received_weapon_withammo'] = 'otrzymałeś/aś ~b~%s~s~ z ~o~%sx~s~ nabojami od ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ próbował/a przekazać ci ~y~%s~s~, lecz już posiadasz jedno', - ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['received_weapon_noweapon'] = '~b~%s~s~ próbował/a przekazać ci amunicje do ~y~%s~s~, lecz nie posiadasz tej broni', ['gave_ammo'] = 'dajesz ~o~%sx~s~ naboje dla ~y~%s~s~', ['received_ammo'] = 'otrzymujesz ~o~%sx~s~ naboje od ~b~%s~s~', ['gave_money'] = 'dajesz ~g~%s$~s~ dla ~y~%s~s~', From 4efea53b37479be788886a7d6dff5d29a9c9c478 Mon Sep 17 00:00:00 2001 From: Poggu <45881722+Poggicek@users.noreply.github.com> Date: Sat, 19 Oct 2019 19:35:54 +0200 Subject: [PATCH 2290/3224] Added weight support (#65) * Added weight support --- client/main.lua | 8 ++------ server/main.lua | 15 +++++---------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/client/main.lua b/client/main.lua index 7e039a26..c07ad686 100644 --- a/client/main.lua +++ b/client/main.lua @@ -25,10 +25,6 @@ function OpenShopMenu(zone) for i=1, #Config.Zones[zone].Items, 1 do local item = Config.Zones[zone].Items[i] - if item.limit == -1 then - item.limit = 100 - end - table.insert(elements, { label = ('%s - %s'):format(item.label, _U('shop_item', ESX.Math.GroupDigits(item.price))), label_real = item.label, @@ -39,7 +35,7 @@ function OpenShopMenu(zone) value = 1, type = 'slider', min = 1, - max = item.limit + max = 100 }) end @@ -166,4 +162,4 @@ Citizen.CreateThread(function() Citizen.Wait(500) end end -end) +end) \ No newline at end of file diff --git a/server/main.lua b/server/main.lua index 8c1ec5f5..dfb052b0 100644 --- a/server/main.lua +++ b/server/main.lua @@ -11,15 +11,10 @@ MySQL.ready(function() ShopItems[shopResult[i].store] = {} end - if shopResult[i].limit == -1 then - shopResult[i].limit = 30 - end - table.insert(ShopItems[shopResult[i].store], { label = shopResult[i].label, item = shopResult[i].item, price = shopResult[i].price, - limit = shopResult[i].limit }) else print(('esx_shops: invalid item "%s" found!'):format(shopResult[i].item)) @@ -63,15 +58,15 @@ AddEventHandler('esx_shops:buyItem', function(itemName, amount, zone) -- can the player afford this item? if xPlayer.getMoney() >= price then -- can the player carry the said amount of x item? - if sourceItem.limit ~= -1 and (sourceItem.count + amount) > sourceItem.limit then - TriggerClientEvent('esx:showNotification', _source, _U('player_cannot_hold')) - else + if xPlayer.canCarryItem(itemName, amount) then xPlayer.removeMoney(price) xPlayer.addInventoryItem(itemName, amount) - TriggerClientEvent('esx:showNotification', _source, _U('bought', amount, itemLabel, ESX.Math.GroupDigits(price))) + xPlayer.showNotification(_U('bought', amount, itemLabel, ESX.Math.GroupDigits(price)) + else + xPlayer.showNotification(_U('player_cannot_hold')) end else local missingMoney = price - xPlayer.getMoney() - TriggerClientEvent('esx:showNotification', _source, _U('not_enough', ESX.Math.GroupDigits(missingMoney))) + xPlayer.showNotification(_U('not_enough', ESX.Math.GroupDigits(missingMoney)) end end) From f33c317d6f5618764eb60f7e22e15755d3075687 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 19 Oct 2019 19:38:54 +0200 Subject: [PATCH 2291/3224] Fixed sql file inproper weight type --- es_extended.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/es_extended.sql b/es_extended.sql index 38fc2f9d..52534684 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -12,7 +12,7 @@ ALTER TABLE `users` CREATE TABLE `items` ( `name` VARCHAR(50) NOT NULL, `label` VARCHAR(50) NOT NULL, - `weight` TINYINT(1) NOT NULL DEFAULT 1, + `weight` INT(11) NOT NULL DEFAULT 1, `rare` TINYINT(1) NOT NULL DEFAULT 0, `can_remove` TINYINT(1) NOT NULL DEFAULT 1, From 87fb7b657194291e0bfd7bc6d655220276d90574 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 19 Oct 2019 19:48:34 +0200 Subject: [PATCH 2292/3224] Removed old locales, updated Swedish locale --- locales/br.lua | 2 -- locales/cs.lua | 2 -- locales/de.lua | 2 -- locales/en.lua | 2 -- locales/fi.lua | 2 -- locales/fr.lua | 2 -- locales/pl.lua | 2 -- locales/sv.lua | 12 +++++------- 8 files changed, 5 insertions(+), 21 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index 7a044fb7..6dc07cba 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -23,8 +23,6 @@ Locales['br'] = { ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', - ['gave_ammo'] = 'voce deu ~o~%sx~s~ balas para ~y~%s~s~', - ['received_ammo'] = 'voce recebeu ~o~%sx~s~ balas de ~b~%s~s~', ['gave_money'] = 'voce deu ~g~$%s~s~ para ~y~%s~s~', ['received_money'] = 'voce recebeu ~g~$%s~s~ de ~b~%s~s~', ['gave_account_money'] = 'voce deu ~g~$%s~s~ (%s) para ~y~%s~s~', diff --git a/locales/cs.lua b/locales/cs.lua index a620792c..92e3c5f4 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -23,8 +23,6 @@ Locales['cs'] = { ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', - ['gave_ammo'] = 'dali jste ~o~%sx~s~ nábojů ~y~%s~s~', - ['received_ammo'] = 'obdrželi jste ~o~%sx~s~ nábojů od ~b~%s~s~', ['gave_money'] = 'dali jste ~g~$%s~s~ ~y~%s~s~', ['received_money'] = 'obdrželi jste ~g~$%s~s~ od ~b~%s~s~', ['gave_account_money'] = 'dali jste ~g~$%s~s~ (%s) ~y~%s~s~', diff --git a/locales/de.lua b/locales/de.lua index 10d67f5e..91cf4c82 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -23,8 +23,6 @@ Locales['de'] = { ['received_weapon_withammo'] = 'du erhälst ~b~%s~s~ mit ~o~%sx~s~ Schuss von ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ hat versucht dir eine(n) ~y~%s~s~ zu geben, aber du hast bereits eine(n)', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', - ['gave_ammo'] = 'du gibst ~o~%sx~s~ Schuss an ~y~%s~s~', - ['received_ammo'] = 'du erhälst ~o~%sx~s~ Schuss von ~b~%s~s~', ['gave_money'] = 'du gibst ~g~$%s~s~ an ~y~%s~s~', ['received_money'] = 'du erhälst ~g~$%s~s~ von ~b~%s~s~', ['gave_account_money'] = 'du gibst ~g~$%s~s~ (%s) an ~y~%s~s~', diff --git a/locales/en.lua b/locales/en.lua index 91c9eca2..ecb89bff 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -23,8 +23,6 @@ Locales['en'] = { ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', - ['gave_ammo'] = 'you gave ~o~%sx~s~ bullets to ~y~%s~s~', - ['received_ammo'] = 'you received ~o~%sx~s~ bullets from ~b~%s~s~', ['gave_money'] = 'you gave ~g~$%s~s~ to ~y~%s~s~', ['received_money'] = 'you received ~g~$%s~s~ from ~b~%s~s~', ['gave_account_money'] = 'you gave ~g~$%s~s~ (%s) to ~y~%s~s~', diff --git a/locales/fi.lua b/locales/fi.lua index eb3ac49f..5cbca385 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -23,8 +23,6 @@ Locales['fi'] = { ['received_weapon_withammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', - ['gave_ammo'] = 'sinä annoit ~o~%sx~s~ ammuksia henkilölle ~y~%s~s~', - ['received_ammo'] = 'sinä sait ~o~%sx~s~ ammuksia henkilöltä ~b~%s~s~', ['gave_money'] = 'sinä annoit ~g~$%s~s~ henkilölle ~y~%s~s~', ['received_money'] = 'sinä sait ~g~$%s~s~ henkilöltä ~b~%s~s~', ['gave_account_money'] = 'sinä annoit ~g~$%s~s~ (%s) henkilölle ~y~%s~s~', diff --git a/locales/fr.lua b/locales/fr.lua index 45362203..b3f77b7c 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -23,8 +23,6 @@ Locales['fr'] = { ['received_weapon_withammo'] = 'vous avez reçu ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles de ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ a tenté de vous donner ~y~%s~s~, mais vous en aviez déjà un exemplaire', ['received_weapon_noweapon'] = '~b~%s~s~ tente de vous donner des munitions pour ~y~%s~s~, mais vous n\'en avez pas', - ['gave_ammo'] = 'vous donnez ~o~%sx~s~ munitions à ~y~%s~s~', - ['received_ammo'] = 'vous recevez ~o~%sx~s~ munitions de ~b~%s~s~', ['gave_money'] = 'vous avez donné ~g~$%s~s~ à ~y~%s~s~', ['received_money'] = 'vous avez reçu ~g~$%s~s~ par ~b~%s~s~', ['gave_account_money'] = 'vous avez donné ~g~$%s~s~ (%s) à ~y~%s~s~', diff --git a/locales/pl.lua b/locales/pl.lua index 57ee9a5b..09e61c5a 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -23,8 +23,6 @@ Locales['pl'] = { ['received_weapon_withammo'] = 'otrzymałeś/aś ~b~%s~s~ z ~o~%sx~s~ nabojami od ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ próbował/a przekazać ci ~y~%s~s~, lecz już posiadasz jedno', ['received_weapon_noweapon'] = '~b~%s~s~ próbował/a przekazać ci amunicje do ~y~%s~s~, lecz nie posiadasz tej broni', - ['gave_ammo'] = 'dajesz ~o~%sx~s~ naboje dla ~y~%s~s~', - ['received_ammo'] = 'otrzymujesz ~o~%sx~s~ naboje od ~b~%s~s~', ['gave_money'] = 'dajesz ~g~%s$~s~ dla ~y~%s~s~', ['received_money'] = 'otrzymujesz ~g~%s$~s~ od ~b~%s~s~', ['gave_account_money'] = 'dajesz ~g~%s$~s~ (%s) dla ~y~%s~s~', diff --git a/locales/sv.lua b/locales/sv.lua index 38d9d115..d15ce060 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -14,23 +14,21 @@ Locales['sv'] = { ['gave_item'] = 'du gav ~y~%sx~s~ ~b~%s~s~ till ~y~%s~s~', ['received_item'] = 'du tog emot ~y~%sx~s~ ~b~%s~s~ från ~b~%s~s~', ['gave_weapon'] = 'du gav ~b~%s~s~ till ~y~%s~s~', - ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_ammo'] = 'du gav ~o~%sx~s~ skott för ~b~%s~s~ till ~y~%s~s~', ['gave_weapon_withammo'] = 'du gav ~b~%s~s~ med ~o~%sx~s~ skott till ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ har redan en ~y~%s~s~', - ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['gave_weapon_noweapon'] = '~y~%s~s~ har inte det vapnet', ['received_weapon'] = 'du tog emot ~b~%s~s~ från ~b~%s~s~', - ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_ammo'] = 'du tog emot ~o~%sx~s~ skott för ~b~%s~s~ från ~b~%s~s~', ['received_weapon_withammo'] = 'du tog emot ~b~%s~s~ med ~o~%sx~s~ skott från ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ försökte ge dig en ~y~%s~s~, men det har du redan', - ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', - ['gave_ammo'] = 'du gav ~o~%sx~s~ skott till ~y~%s~s~', - ['received_ammo'] = 'du tog emot ~o~%sx~s~ skott från ~b~%s~s~', + ['received_weapon_noweapon'] = '~b~%s~s~ försökte ge dig ammunition för ett ~y~%s~s~, men du har inget sådant vapen', ['gave_money'] = 'du gav ~g~%s SEK~s~ till ~y~%s~s~', ['received_money'] = 'du tog emot ~g~%s SEK~s~ från ~b~%s~s~', ['gave_account_money'] = 'du gav ~g~%s SEK~s~ (%s) till ~y~%s~s~', ['received_account_money'] = 'du tog emot ~g~%s SEK~s~ (%s) från ~b~%s~s~', ['amount_invalid'] = 'ogiltig mängd', - ['players_nearby'] = 'inga spelare nära', + ['players_nearby'] = 'det finns inga spelare nära', ['ex_inv_lim'] = 'åtgärd inte möjligt, översteg förråd gräns för ~y~%s~s~', ['imp_invalid_quantity'] = 'åtgärd omöjlig, ogiltig mängd', ['imp_invalid_amount'] = 'åtgärd omöjlig, ogiltig belopp', From 549c28ff617ee48059b7fb2dd9e69b9c3fd95f56 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 20 Oct 2019 09:50:32 +0200 Subject: [PATCH 2293/3224] Fixed #66, cleanup code --- client/main.lua | 101 ++++++++++++++++++++++-------------------------- server/main.lua | 4 +- 2 files changed, 49 insertions(+), 56 deletions(-) diff --git a/client/main.lua b/client/main.lua index c07ad686..c6df4379 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,9 +1,6 @@ -ESX = nil -local HasAlreadyEnteredMarker = false -local LastZone = nil -local CurrentAction = nil -local CurrentActionMsg = '' -local CurrentActionData = {} +ESX = nil +local hasAlreadyEnteredMarker, lastZone +local currentAction, currentActionMsg, currentActionData = nil, nil, {} Citizen.CreateThread(function() while ESX == nil do @@ -27,7 +24,7 @@ function OpenShopMenu(zone) table.insert(elements, { label = ('%s - %s'):format(item.label, _U('shop_item', ESX.Math.GroupDigits(item.price))), - label_real = item.label, + itemLabel = item.label, item = item.item, price = item.price, @@ -40,19 +37,19 @@ function OpenShopMenu(zone) end ESX.UI.Menu.CloseAll() + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'shop', { title = _U('shop'), align = 'bottom-right', elements = elements }, function(data, menu) ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'shop_confirm', { - title = _U('shop_confirm', data.current.value, data.current.label_real, ESX.Math.GroupDigits(data.current.price * data.current.value)), + title = _U('shop_confirm', data.current.value, data.current.itemLabel, ESX.Math.GroupDigits(data.current.price * data.current.value)), align = 'bottom-right', elements = { {label = _U('no'), value = 'no'}, {label = _U('yes'), value = 'yes'} - } - }, function(data2, menu2) + }}, function(data2, menu2) if data2.current.value == 'yes' then TriggerServerEvent('esx_shops:buyItem', data.current.item, data.current.value, zone) end @@ -64,20 +61,20 @@ function OpenShopMenu(zone) end, function(data, menu) menu.close() - CurrentAction = 'shop_menu' - CurrentActionMsg = _U('press_menu') - CurrentActionData = {zone = zone} + currentAction = 'shop_menu' + currentActionMsg = _U('press_menu') + currentActionData = {zone = zone} end) end AddEventHandler('esx_shops:hasEnteredMarker', function(zone) - CurrentAction = 'shop_menu' - CurrentActionMsg = _U('press_menu') - CurrentActionData = {zone = zone} + currentAction = 'shop_menu' + currentActionMsg = _U('press_menu') + currentActionData = {zone = zone} end) AddEventHandler('esx_shops:hasExitedMarker', function(zone) - CurrentAction = nil + currentAction = nil ESX.UI.Menu.CloseAll() end) @@ -86,59 +83,55 @@ Citizen.CreateThread(function() for k,v in pairs(Config.Zones) do for i = 1, #v.Pos, 1 do local blip = AddBlipForCoord(v.Pos[i].x, v.Pos[i].y, v.Pos[i].z) + SetBlipSprite (blip, 52) - SetBlipDisplay(blip, 4) SetBlipScale (blip, 1.0) SetBlipColour (blip, 2) SetBlipAsShortRange(blip, true) - BeginTextCommandSetBlipName("STRING") - AddTextComponentString(_U('shops')) + + BeginTextCommandSetBlipName('STRING') + AddTextComponentSubstringPlayerName(_U('shops')) EndTextCommandSetBlipName(blip) end end end) --- Display markers -Citizen.CreateThread(function() - while true do - Citizen.Wait(0) - local coords = GetEntityCoords(PlayerPedId()) - - for k,v in pairs(Config.Zones) do - for i = 1, #v.Pos, 1 do - if(Config.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos[i].x, v.Pos[i].y, v.Pos[i].z, true) < Config.DrawDistance) then - DrawMarker(Config.Type, v.Pos[i].x, v.Pos[i].y, v.Pos[i].z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.Size.x, Config.Size.y, Config.Size.z, Config.Color.r, Config.Color.g, Config.Color.b, 100, false, true, 2, false, false, false, false) - end - end - end - end -end) - -- Enter / Exit marker events Citizen.CreateThread(function() while true do Citizen.Wait(0) - local coords = GetEntityCoords(PlayerPedId()) - local isInMarker = false - local currentZone = nil + local playerCoords = GetEntityCoords(PlayerPedId()) + local isInMarker, letSleep, currentZone = false, false for k,v in pairs(Config.Zones) do for i = 1, #v.Pos, 1 do - if(GetDistanceBetweenCoords(coords, v.Pos[i].x, v.Pos[i].y, v.Pos[i].z, true) < Config.Size.x) then - isInMarker = true - ShopItems = v.Items - currentZone = k - LastZone = k + local distance = GetDistanceBetweenCoords(playerCoords, v.Pos[i].x, v.Pos[i].y, v.Pos[i].z, true) + + if distance < Config.DrawDistance then + DrawMarker(Config.Type, v.Pos[i].x, v.Pos[i].y, v.Pos[i].z, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Config.Size.x, Config.Size.y, Config.Size.z, Config.Color.r, Config.Color.g, Config.Color.b, 100, false, true, 2, false, nil, nil, false) + letSleep = false + + if distance < Config.Size.x then + isInMarker = true + currentZone = k + lastZone = k + end end end end - if isInMarker and not HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = true + + if isInMarker and not hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = true TriggerEvent('esx_shops:hasEnteredMarker', currentZone) end - if not isInMarker and HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = false - TriggerEvent('esx_shops:hasExitedMarker', LastZone) + + if not isInMarker and hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = false + TriggerEvent('esx_shops:hasExitedMarker', lastZone) + end + + if letSleep then + Citizen.Wait(500) end end end) @@ -148,15 +141,15 @@ Citizen.CreateThread(function() while true do Citizen.Wait(0) - if CurrentAction ~= nil then - ESX.ShowHelpNotification(CurrentActionMsg) + if currentAction then + ESX.ShowHelpNotification(currentActionMsg) if IsControlJustReleased(0, 38) then - if CurrentAction == 'shop_menu' then - OpenShopMenu(CurrentActionData.zone) + if currentAction == 'shop_menu' then + OpenShopMenu(currentActionData.zone) end - CurrentAction = nil + currentAction = nil end else Citizen.Wait(500) diff --git a/server/main.lua b/server/main.lua index dfb052b0..9660dd18 100644 --- a/server/main.lua +++ b/server/main.lua @@ -61,12 +61,12 @@ AddEventHandler('esx_shops:buyItem', function(itemName, amount, zone) if xPlayer.canCarryItem(itemName, amount) then xPlayer.removeMoney(price) xPlayer.addInventoryItem(itemName, amount) - xPlayer.showNotification(_U('bought', amount, itemLabel, ESX.Math.GroupDigits(price)) + xPlayer.showNotification(_U('bought', amount, itemLabel, ESX.Math.GroupDigits(price))) else xPlayer.showNotification(_U('player_cannot_hold')) end else local missingMoney = price - xPlayer.getMoney() - xPlayer.showNotification(_U('not_enough', ESX.Math.GroupDigits(missingMoney)) + xPlayer.showNotification(_U('not_enough', ESX.Math.GroupDigits(missingMoney))) end end) From 7ca8779b90c5afb31bfcb5c565e5f61e6660019b Mon Sep 17 00:00:00 2001 From: Poggu Date: Sun, 20 Oct 2019 11:00:06 +0200 Subject: [PATCH 2294/3224] Added weight support and amount sliders to pharmacy menu --- client/job.lua | 12 ++++++------ esx_ambulancejob.sql | 6 +++--- localization/cs_esx_ambulancejob.sql | 6 +++--- localization/de_esx_ambulancejob.sql | 6 +++--- localization/en_esx_ambulancejob.sql | 6 +++--- localization/fi_esx_ambulancejob.sql | 6 +++--- localization/pl_esx_ambulancejob.sql | 6 +++--- server/main.lua | 27 ++++++++++----------------- 8 files changed, 34 insertions(+), 41 deletions(-) diff --git a/client/job.lua b/client/job.lua index 94e5a782..d93a96aa 100644 --- a/client/job.lua +++ b/client/job.lua @@ -78,7 +78,7 @@ function OpenMobileAmbulanceActionsMenu() for i=1, 15, 1 do Citizen.Wait(900) - + ESX.Streaming.RequestAnimDict(lib, function() TaskPlayAnim(PlayerPedId(), lib, anim, 8.0, -8.0, -1, 0, 0, false, false, false) end) @@ -755,11 +755,11 @@ function OpenShopMenu(elements, restoreCoords, shopCoords) isInShopMenu = false ESX.UI.Menu.CloseAll() - + DeleteSpawnedVehicles() FreezeEntityPosition(playerPed, false) SetEntityVisible(playerPed, true) - + ESX.Game.Teleport(playerPed, restoreCoords) else ESX.ShowNotification(_U('vehicleshop_money')) @@ -866,11 +866,11 @@ function OpenPharmacyMenu() title = _U('pharmacy_menu_title'), align = 'top-left', elements = { - {label = _U('pharmacy_take', _U('medikit')), value = 'medikit'}, - {label = _U('pharmacy_take', _U('bandage')), value = 'bandage'} + {label = _U('pharmacy_take', _U('medikit')), item = 'medikit', type = 'slider', value = 1, min = 1, max = 100}, + {label = _U('pharmacy_take', _U('bandage')), item = 'bandage', type = 'slider', value = 1, min = 1, max = 100} } }, function(data, menu) - TriggerServerEvent('esx_ambulancejob:giveItem', data.current.value) + TriggerServerEvent('esx_ambulancejob:giveItem', data.current.item, data.current.value) end, function(data, menu) menu.close() end) diff --git a/esx_ambulancejob.sql b/esx_ambulancejob.sql index d88d5676..c7a4097e 100644 --- a/esx_ambulancejob.sql +++ b/esx_ambulancejob.sql @@ -23,9 +23,9 @@ INSERT INTO `jobs` (name, label) VALUES ('ambulance','Ambulance') ; -INSERT INTO `items` (name, label, `limit`) VALUES - ('bandage','Bandage', 20), - ('medikit','Medikit', 5) +INSERT INTO `items` (name, label, weight) VALUES + ('bandage','Bandage', 2), + ('medikit','Medikit', 2) ; ALTER TABLE `users` diff --git a/localization/cs_esx_ambulancejob.sql b/localization/cs_esx_ambulancejob.sql index a8af1939..b5264a06 100644 --- a/localization/cs_esx_ambulancejob.sql +++ b/localization/cs_esx_ambulancejob.sql @@ -23,9 +23,9 @@ INSERT INTO `jobs` (name, label) VALUES ('ambulance','Záchranka') ; -INSERT INTO `items` (name, label, `limit`) VALUES - ('bandage','Obvaz', 20), - ('medikit','Lékarnička', 5) +INSERT INTO `items` (name, label, weight) VALUES + ('bandage','Obvaz', 2), + ('medikit','Lékarnička', 2) ; ALTER TABLE `users` diff --git a/localization/de_esx_ambulancejob.sql b/localization/de_esx_ambulancejob.sql index 0ebf079d..bd1ff039 100644 --- a/localization/de_esx_ambulancejob.sql +++ b/localization/de_esx_ambulancejob.sql @@ -23,9 +23,9 @@ INSERT INTO `jobs` (name, label) VALUES ('ambulance','Notdienst') ; -INSERT INTO `items` (name, label, `limit`) VALUES - ('bandage','Bandage', 20), - ('medikit','Medikit', 5) +INSERT INTO `items` (name, label, weight) VALUES + ('bandage','Bandage', 2), + ('medikit','Medikit', 2) ; ALTER TABLE `users` diff --git a/localization/en_esx_ambulancejob.sql b/localization/en_esx_ambulancejob.sql index 6bb4ecf1..6ba8b1a6 100644 --- a/localization/en_esx_ambulancejob.sql +++ b/localization/en_esx_ambulancejob.sql @@ -23,9 +23,9 @@ INSERT INTO `jobs` (name, label) VALUES ('ambulance','EMS') ; -INSERT INTO `items` (name, label, `limit`) VALUES - ('bandage','Bandage', 20), - ('medikit','Medikit', 5) +INSERT INTO `items` (name, label, weight) VALUES + ('bandage','Bandage', 2), + ('medikit','Medikit', 2) ; ALTER TABLE `users` diff --git a/localization/fi_esx_ambulancejob.sql b/localization/fi_esx_ambulancejob.sql index 7c001e0d..1508ad3d 100644 --- a/localization/fi_esx_ambulancejob.sql +++ b/localization/fi_esx_ambulancejob.sql @@ -23,9 +23,9 @@ INSERT INTO `jobs` (name, label) VALUES ('ambulance','Ensihoito') ; -INSERT INTO `items` (name, label, `limit`) VALUES - ('bandage','Sideharso', 20), - ('medikit','Ensiapupakkaus', 5) +INSERT INTO `items` (name, label, weight) VALUES + ('bandage','Sideharso', 2), + ('medikit','Ensiapupakkaus', 2) ; ALTER TABLE `users` diff --git a/localization/pl_esx_ambulancejob.sql b/localization/pl_esx_ambulancejob.sql index c3715181..2f52bad6 100644 --- a/localization/pl_esx_ambulancejob.sql +++ b/localization/pl_esx_ambulancejob.sql @@ -23,9 +23,9 @@ INSERT INTO `jobs` (name, label) VALUES ('ambulance','Pogotowie ratunkowe') ; -INSERT INTO `items` (name, label, `limit`) VALUES - ('bandage','Bandaż', 20), - ('medikit','Defibrylator', 5) +INSERT INTO `items` (name, label, weight) VALUES + ('bandage','Bandaż', 2), + ('medikit','Defibrylator', 2) ; ALTER TABLE `users` diff --git a/server/main.lua b/server/main.lua index 0f5b78d9..2003be0d 100644 --- a/server/main.lua +++ b/server/main.lua @@ -99,7 +99,7 @@ if Config.EarlyRespawnFine then local xPlayer = ESX.GetPlayerFromId(source) local fineAmount = Config.EarlyRespawnFineAmount - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('respawn_bleedout_fine_msg', ESX.Math.GroupDigits(fineAmount))) + xPlayer.showNotification(_U('respawn_bleedout_fine_msg', ESX.Math.GroupDigits(fineAmount))) xPlayer.removeAccountMoney('bank', fineAmount) end) end @@ -122,7 +122,7 @@ ESX.RegisterServerCallback('esx_ambulancejob:buyJobVehicle', function(source, cb else 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), @@ -205,14 +205,14 @@ AddEventHandler('esx_ambulancejob:removeItem', function(item) xPlayer.removeInventoryItem(item, 1) if item == 'bandage' then - TriggerClientEvent('esx:showNotification', _source, _U('used_bandage')) + xPlayer.showNotification(_U('used_bandage')) elseif item == 'medikit' then - TriggerClientEvent('esx:showNotification', _source, _U('used_medikit')) + xPlayer.showNotification(_U('used_medikit')) end end) RegisterServerEvent('esx_ambulancejob:giveItem') -AddEventHandler('esx_ambulancejob:giveItem', function(itemName) +AddEventHandler('esx_ambulancejob:giveItem', function(itemName, amount) local xPlayer = ESX.GetPlayerFromId(source) if xPlayer.job.name ~= 'ambulance' then @@ -223,17 +223,10 @@ AddEventHandler('esx_ambulancejob:giveItem', function(itemName) return end - local xItem = xPlayer.getInventoryItem(itemName) - local count = 1 - - if xItem.limit ~= -1 then - count = xItem.limit - xItem.count - end - - if xItem.count < xItem.limit then - xPlayer.addInventoryItem(itemName, count) + if xPlayer.canCarryItem(itemName, amount) then + xPlayer.addInventoryItem(itemName, amount) else - TriggerClientEvent('esx:showNotification', source, _U('max_item')) + xPlayer.showNotification(_U('max_item')) end end) @@ -254,7 +247,7 @@ ESX.RegisterUsableItem('medikit', function(source) if not playersHealing[source] then local xPlayer = ESX.GetPlayerFromId(source) xPlayer.removeInventoryItem('medikit', 1) - + playersHealing[source] = true TriggerClientEvent('esx_ambulancejob:useItem', source, 'medikit') @@ -267,7 +260,7 @@ ESX.RegisterUsableItem('bandage', function(source) if not playersHealing[source] then local xPlayer = ESX.GetPlayerFromId(source) xPlayer.removeInventoryItem('bandage', 1) - + playersHealing[source] = true TriggerClientEvent('esx_ambulancejob:useItem', source, 'bandage') From 40f9d2aa1f4789db5dbd248462f901e4abff615c Mon Sep 17 00:00:00 2001 From: Petr Sopf Date: Wed, 23 Oct 2019 21:47:35 +0200 Subject: [PATCH 2295/3224] Fix pickups not syncing server sided --- server/main.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/main.lua b/server/main.lua index 48821a4d..5b61ae49 100644 --- a/server/main.lua +++ b/server/main.lua @@ -437,12 +437,15 @@ AddEventHandler('esx:onPickup', function(id) if pickup.type == 'item_standard' then if xPlayer.canCarryItem(pickup.name, pickup.count) then xPlayer.addInventoryItem(pickup.name, pickup.count) + ESX.Pickups[id] = nil TriggerClientEvent('esx:removePickup', -1, id) end elseif pickup.type == 'item_money' then + ESX.Pickups[id] = nil TriggerClientEvent('esx:removePickup', -1, id) xPlayer.addMoney(pickup.count) elseif pickup.type == 'item_account' then + ESX.Pickups[id] = nil TriggerClientEvent('esx:removePickup', -1, id) xPlayer.addAccountMoney(pickup.name, pickup.count) end From 88b284f925682b93b5e53078e8dae249468dcfb8 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 27 Oct 2019 00:12:36 +0200 Subject: [PATCH 2296/3224] Minor changes --- client/job.lua | 27 +++++++++++++-------------- client/main.lua | 38 +++++++++++++++++++------------------- locales/br.lua | 4 +++- locales/cs.lua | 4 +++- locales/en.lua | 4 +++- locales/es.lua | 4 +++- locales/fi.lua | 4 +++- locales/fr.lua | 6 ++++-- locales/pl.lua | 4 +++- locales/sv.lua | 4 +++- 10 files changed, 57 insertions(+), 42 deletions(-) diff --git a/client/job.lua b/client/job.lua index 94e5a782..961eba05 100644 --- a/client/job.lua +++ b/client/job.lua @@ -1,6 +1,6 @@ local CurrentAction, CurrentActionMsg, CurrentActionData = nil, '', {} local HasAlreadyEnteredMarker, LastHospital, LastPart, LastPartNum -local IsBusy = false +local isBusy = false local spawnedVehicles, isInShopMenu = {}, false function OpenAmbulanceActionsMenu() @@ -53,7 +53,7 @@ function OpenMobileAmbulanceActionsMenu() {label = _U('ems_menu_putincar'), value = 'put_in_vehicle'} } }, function(data, menu) - if IsBusy then return end + if isBusy then return end local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() @@ -63,7 +63,7 @@ function OpenMobileAmbulanceActionsMenu() if data.current.value == 'revive' then - IsBusy = true + isBusy = true ESX.TriggerServerCallback('esx_ambulancejob:getItemAmount', function(quantity) if quantity > 0 then @@ -100,7 +100,7 @@ function OpenMobileAmbulanceActionsMenu() ESX.ShowNotification(_U('not_enough_medikit')) end - IsBusy = false + isBusy = false end, 'medikit') @@ -114,7 +114,7 @@ function OpenMobileAmbulanceActionsMenu() if health > 0 then local playerPed = PlayerPedId() - IsBusy = true + isBusy = true ESX.ShowNotification(_U('heal_inprogress')) TaskStartScenarioInPlace(playerPed, 'CODE_HUMAN_MEDIC_TEND_TO_DEAD', 0, true) Citizen.Wait(10000) @@ -123,7 +123,7 @@ function OpenMobileAmbulanceActionsMenu() TriggerServerEvent('esx_ambulancejob:removeItem', 'bandage') TriggerServerEvent('esx_ambulancejob:heal', GetPlayerServerId(closestPlayer), 'small') ESX.ShowNotification(_U('heal_complete', GetPlayerName(closestPlayer))) - IsBusy = false + isBusy = false else ESX.ShowNotification(_U('player_not_conscious')) end @@ -142,7 +142,7 @@ function OpenMobileAmbulanceActionsMenu() if health > 0 then local playerPed = PlayerPedId() - IsBusy = true + isBusy = true ESX.ShowNotification(_U('heal_inprogress')) TaskStartScenarioInPlace(playerPed, 'CODE_HUMAN_MEDIC_TEND_TO_DEAD', 0, true) Citizen.Wait(10000) @@ -151,7 +151,7 @@ function OpenMobileAmbulanceActionsMenu() TriggerServerEvent('esx_ambulancejob:removeItem', 'medikit') TriggerServerEvent('esx_ambulancejob:heal', GetPlayerServerId(closestPlayer), 'big') ESX.ShowNotification(_U('heal_complete', GetPlayerName(closestPlayer))) - IsBusy = false + isBusy = false else ESX.ShowNotification(_U('player_not_conscious')) end @@ -379,7 +379,7 @@ Citizen.CreateThread(function() end - elseif ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'ambulance' and not IsDead then + elseif ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'ambulance' and not isDead then if IsControlJustReleased(0, Keys['F6']) then OpenMobileAmbulanceActionsMenu() end @@ -566,10 +566,10 @@ function StoreNearbyVehicle(playerCoords) local vehicleId = vehiclePlates[foundNum] local attempts = 0 ESX.Game.DeleteVehicle(vehicleId.vehicle) - IsBusy = true + isBusy = true Citizen.CreateThread(function() - while IsBusy do + while isBusy do Citizen.Wait(0) drawLoadingText(_U('garage_storing'), 255, 255, 255, 255) end @@ -596,7 +596,7 @@ function StoreNearbyVehicle(playerCoords) end end - IsBusy = false + isBusy = false ESX.ShowNotification(_U('garage_has_stored')) else ESX.ShowNotification(_U('garage_has_notstored')) @@ -774,7 +774,7 @@ function OpenShopMenu(elements, restoreCoords, shopCoords) menu2.close() end) - end, function(data, menu) + end, function(data, menu) isInShopMenu = false ESX.UI.Menu.CloseAll() @@ -849,7 +849,6 @@ function drawLoadingText(text, red, green, blue, alpha) SetTextScale(0.0, 0.5) SetTextColour(red, green, blue, alpha) SetTextDropshadow(0, 0, 0, 0, 255) - SetTextEdge(1, 0, 0, 0, 255) SetTextDropShadow() SetTextOutline() SetTextCentre(true) diff --git a/client/main.lua b/client/main.lua index 3a8f2c36..deb877e3 100644 --- a/client/main.lua +++ b/client/main.lua @@ -10,9 +10,9 @@ Keys = { ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 } -local FirstSpawn, PlayerLoaded = true, false +local firstSpawn, PlayerLoaded = true, false -IsDead = false +isDead = false ESX = nil Citizen.CreateThread(function() @@ -41,14 +41,14 @@ AddEventHandler('esx:setJob', function(job) end) AddEventHandler('playerSpawned', function() - IsDead = false + isDead = false - if FirstSpawn then + if firstSpawn then exports.spawnmanager:setAutoSpawn(false) -- disable respawn - FirstSpawn = false + firstSpawn = false - ESX.TriggerServerCallback('esx_ambulancejob:getDeathStatus', function(isDead) - if isDead and Config.AntiCombatLog then + ESX.TriggerServerCallback('esx_ambulancejob:getDeathStatus', function(shouldDie) + if shouldDie and Config.AntiCombatLog then while not PlayerLoaded do Citizen.Wait(1000) end @@ -57,6 +57,8 @@ AddEventHandler('playerSpawned', function() RemoveItemsAfterRPDeath() end end) + else + TriggerServerEvent('esx_ambulancejob:onPlayerSpawn') end end) @@ -71,7 +73,7 @@ Citizen.CreateThread(function() SetBlipAsShortRange(blip, true) BeginTextCommandSetBlipName('STRING') - AddTextComponentSubstringPlayerName(_U('hospital')) + AddTextComponentSubstringPlayerName(_U('blip_hospital')) EndTextCommandSetBlipName(blip) end end) @@ -81,7 +83,7 @@ Citizen.CreateThread(function() while true do Citizen.Wait(0) - if IsDead then + if isDead then DisableAllControlActions(0) EnableControlAction(0, Keys['G'], true) EnableControlAction(0, Keys['T'], true) @@ -93,7 +95,7 @@ Citizen.CreateThread(function() end) function OnPlayerDeath() - IsDead = true + isDead = true ESX.UI.Menu.CloseAll() TriggerServerEvent('esx_ambulancejob:setDeathStatus', true) @@ -147,7 +149,7 @@ function StartDistressSignal() Citizen.CreateThread(function() local timer = Config.BleedoutTimer - while timer > 0 and IsDead do + while timer > 0 and isDead do Citizen.Wait(2) timer = timer - 30 @@ -155,7 +157,6 @@ function StartDistressSignal() SetTextScale(0.45, 0.45) SetTextColour(185, 185, 185, 255) SetTextDropshadow(0, 0, 0, 0, 255) - SetTextEdge(1, 0, 0, 0, 255) SetTextDropShadow() SetTextOutline() BeginTextCommandDisplayText('STRING') @@ -167,7 +168,7 @@ function StartDistressSignal() Citizen.CreateThread(function() Citizen.Wait(1000 * 60 * 5) - if IsDead then + if isDead then StartDistressSignal() end end) @@ -195,7 +196,6 @@ function DrawGenericTextThisFrame() SetTextScale(0.0, 0.5) SetTextColour(255, 255, 255, 255) SetTextDropshadow(0, 0, 0, 0, 255) - SetTextEdge(1, 0, 0, 0, 255) SetTextDropShadow() SetTextOutline() SetTextCentre(true) @@ -229,7 +229,7 @@ function StartDeathTimer() Citizen.CreateThread(function() -- early respawn timer - while earlySpawnTimer > 0 and IsDead do + while earlySpawnTimer > 0 and isDead do Citizen.Wait(1000) if earlySpawnTimer > 0 then @@ -238,7 +238,7 @@ function StartDeathTimer() end -- bleedout timer - while bleedoutTimer > 0 and IsDead do + while bleedoutTimer > 0 and isDead do Citizen.Wait(1000) if bleedoutTimer > 0 then @@ -251,7 +251,7 @@ function StartDeathTimer() local text, timeHeld -- early respawn timer - while earlySpawnTimer > 0 and IsDead do + while earlySpawnTimer > 0 and isDead do Citizen.Wait(0) text = _U('respawn_available_in', secondsToClock(earlySpawnTimer)) @@ -263,7 +263,7 @@ function StartDeathTimer() end -- bleedout timer - while bleedoutTimer > 0 and IsDead do + while bleedoutTimer > 0 and isDead do Citizen.Wait(0) text = _U('respawn_bleedout_in', secondsToClock(bleedoutTimer)) @@ -297,7 +297,7 @@ function StartDeathTimer() DrawText(0.5, 0.8) end - if bleedoutTimer < 1 and IsDead then + if bleedoutTimer < 1 and isDead then RemoveItemsAfterRPDeath() end end) diff --git a/locales/br.lua b/locales/br.lua index be0dbc50..1cd0b382 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -36,7 +36,6 @@ Locales['br'] = { ['confirm_no'] = 'no', ['confirm_yes'] = 'yes', -- Action Menu - ['hospital'] = 'Hôspital', ['revive_inprogress'] = 'Reanimação em andamento', ['revive_complete'] = 'você ressuscitou ~y~%s~s~', ['revive_complete_award'] = 'você ressuscitou ~y~%s~s~, ~g~$%s~s~', @@ -87,4 +86,7 @@ Locales['br'] = { ['not_enough_medikit'] = 'Você não tem ~b~Seringa~s~.', ['not_enough_bandage'] = 'Você não tem ~b~Vendagem~s~.', ['healed'] = 'Você foi tratado.', + -- Blips + ['blip_hospital'] = 'Hôspital', + ['blip_dead'] = 'unconscious player', } diff --git a/locales/cs.lua b/locales/cs.lua index 48dc7cc2..aa2f664f 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -36,7 +36,6 @@ Locales['cs'] = { ['confirm_no'] = 'no', ['confirm_yes'] = 'yes', -- Action Menu - ['hospital'] = 'nemocnice', ['revive_inprogress'] = 'probíhá oživení!', ['revive_complete'] = 'oživili jste ~y~%s~s~', ['revive_complete_award'] = 'oživili jste ~y~%s~s~ a dostali jste ~g~$%s~s~!', @@ -87,4 +86,7 @@ Locales['cs'] = { ['not_enough_medikit'] = 'nemáte ~b~medikit~s~.', ['not_enough_bandage'] = 'nemáte~b~bandage~s~.', ['healed'] = 'byli jste ošetřeni.', + -- Blips + ['blip_hospital'] = 'nemocnice', + ['blip_dead'] = 'unconscious player', } diff --git a/locales/en.lua b/locales/en.lua index b13f48fe..36848986 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -36,7 +36,6 @@ Locales['en'] = { ['confirm_no'] = 'no', ['confirm_yes'] = 'yes', -- Action Menu - ['hospital'] = 'hospital', ['revive_inprogress'] = 'a revive is in progress!', ['revive_complete'] = 'you have revived ~y~%s~s~', ['revive_complete_award'] = 'you have revived ~y~%s~s~ and earned ~g~$%s~s~!', @@ -87,4 +86,7 @@ Locales['en'] = { ['not_enough_medikit'] = 'You do not have ~b~medikit~s~.', ['not_enough_bandage'] = 'You do not have ~b~bandage~s~.', ['healed'] = 'you have been treated.', + -- Blips + ['blip_hospital'] = 'hospital', + ['blip_dead'] = 'unconscious player', } diff --git a/locales/es.lua b/locales/es.lua index 5b1e4ecb..a197d2ac 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -36,7 +36,6 @@ Locales['es'] = { ['confirm_no'] = 'no', ['confirm_yes'] = 'yes', -- Action Menu - ['hospital'] = 'hospital', ['revive_inprogress'] = 'reanimación en curso', ['revive_complete'] = 'has sido reanimado ~y~%s~s~', ['revive_complete_award'] = 'has sido reanimado ~y~%s~s~, ~g~$%s~s~', @@ -87,4 +86,7 @@ Locales['es'] = { ['not_enough_medikit'] = 'You do not have ~b~medikit~s~.', ['not_enough_bandage'] = 'You do not have ~b~bandage~s~.', ['healed'] = 'you have been treated.', + -- Blips + ['blip_hospital'] = 'hospital', + ['blip_dead'] = 'unconscious player', } diff --git a/locales/fi.lua b/locales/fi.lua index ac99fc65..2068b318 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -36,7 +36,6 @@ Locales['fi'] = { ['confirm_no'] = 'no', ['confirm_yes'] = 'yes', -- Action Menu - ['hospital'] = 'sairaala', ['revive_inprogress'] = 'elvytys on menossa!', ['revive_complete'] = 'sinä elvytit henkilön ~y~%s~s~', ['revive_complete_award'] = 'sinä elvytit henkilön ~y~%s~s~ ja tienasit ~g~$%s~s~!', @@ -87,4 +86,7 @@ Locales['fi'] = { ['not_enough_medikit'] = 'ei tarpeeksi ~b~ensiapupakkauksia~s~.', ['not_enough_bandage'] = 'ei tarpeeksi ~b~sideharsoja~s~.', ['healed'] = 'sinua parannettiin', + -- Blips + ['blip_hospital'] = 'sairaala', + ['blip_dead'] = 'unconscious player', } diff --git a/locales/fr.lua b/locales/fr.lua index b56c17f7..94f62665 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -36,7 +36,6 @@ Locales['fr'] = { ['confirm_no'] = 'non', ['confirm_yes'] = 'oui', -- Action Menu - ['hospital'] = 'hôpital', ['revive_inprogress'] = 'réanimation en cours', ['revive_complete'] = 'vous avez réanimé ~y~%s~s~', ['revive_complete_award'] = 'vous avez réanimé ~y~%s~s~, ~g~$%s~s~', @@ -49,7 +48,7 @@ Locales['fr'] = { -- Boss Menu ['boss_actions'] = 'action Patron', -- Misc - ['invalid_amount'] = '~r~montant invalide', + ['invalid_amount'] = '~r~montant invalide~s~', ['actions_prompt'] = 'press ~INPUT_CONTEXT~ access the ~y~Ambulance Actions~s~.', ['deposit_amount'] = 'montant du dépôt', ['money_withdraw'] = 'montant du retrait', @@ -87,4 +86,7 @@ Locales['fr'] = { ['not_enough_medikit'] = 'vous n\'avez pas de ~b~kit de soin~s~.', ['not_enough_bandage'] = 'vous n\'avez pas de ~b~bandage~s~.', ['healed'] = 'vous avez été soigné.', + -- Blips + ['blip_hospital'] = 'hôpital', + ['blip_dead'] = 'unconscious player', } diff --git a/locales/pl.lua b/locales/pl.lua index 61778ccc..ebf75ce1 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -36,7 +36,6 @@ Locales['pl'] = { ['confirm_no'] = 'no', ['confirm_yes'] = 'yes', -- Action Menu - ['hospital'] = 'szpital', ['revive_inprogress'] = 'trwa wskrzeszenie', ['revive_complete'] = 'zostałeś wskrzeszony ~y~%s~s~', ['revive_complete_award'] = 'zostałeś wskrzeszony ~y~%s~s~ i zarobiono ~g~$%s~s~!', @@ -87,4 +86,7 @@ Locales['pl'] = { ['not_enough_medikit'] = 'nie posiadasz ~b~apteczki~s~.', ['not_enough_bandage'] = 'nie posiadasz ~b~bandaża~s~.', ['healed'] = 'zostałeś potraktowany', + -- Blips + ['blip_hospital'] = 'szpital', + ['blip_dead'] = 'unconscious player', } diff --git a/locales/sv.lua b/locales/sv.lua index 0693cfd1..501e602c 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -36,7 +36,6 @@ Locales['sv'] = { ['confirm_no'] = 'no', ['confirm_yes'] = 'yes', -- Action Menu - ['hospital'] = 'sjukhus', ['revive_inprogress'] = 'en återupplivning har börjats', ['revive_complete'] = 'du har återupplivat ~y~%s~s~, bra jobbat!', ['revive_complete_award'] = 'du har återupplivat ~y~%s~s~ och tjärnat ~g~%s SEK~s~ för dina tjänster, bra jobbat!', @@ -87,4 +86,7 @@ Locales['sv'] = { ['not_enough_medikit'] = 'du har inget ~b~Medecinkit~s~.', ['not_enough_bandage'] = 'du har inget ~b~Bandage~s~.', ['healed'] = 'dina skador har blivit behandlade.', + -- Blips + ['blip_hospital'] = 'sjukhus', + ['blip_dead'] = 'medvetslös människa', } From a2daba053d85f8ffecad8db3f0cdd7ad39fbf181 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 27 Oct 2019 00:40:50 +0200 Subject: [PATCH 2297/3224] use new esx carry limit code --- client/main.lua | 15 +--------- client/weed.lua | 21 ++++---------- localization/en_esx_drugs.sql | 6 ++-- localization/es_esx_drugs.sql | 6 ++-- server/main.lua | 52 +++++++++++++++-------------------- 5 files changed, 34 insertions(+), 66 deletions(-) diff --git a/client/main.lua b/client/main.lua index c7c00efd..c6ec9a38 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,15 +1,3 @@ -Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - ESX = nil local menuOpen = false local wasOpen = false @@ -37,7 +25,7 @@ Citizen.CreateThread(function() if not menuOpen then ESX.ShowHelpNotification(_U('dealer_prompt')) - if IsControlJustReleased(0, Keys['E']) then + if IsControlJustReleased(0, 38) then wasOpen = true OpenDrugShop() end @@ -163,7 +151,6 @@ end Citizen.CreateThread(function() for k,zone in pairs(Config.CircleZones) do - CreateBlipCircle(zone.coords, zone.name, zone.radius, zone.color, zone.sprite) end end) \ No newline at end of file diff --git a/client/weed.lua b/client/weed.lua index 41e48a56..78cfe74d 100644 --- a/client/weed.lua +++ b/client/weed.lua @@ -2,17 +2,13 @@ local spawnedWeeds = 0 local weedPlants = {} local isPickingUp, isProcessing = false, false - Citizen.CreateThread(function() while true do - Citizen.Wait(10) + Citizen.Wait(500) local coords = GetEntityCoords(PlayerPedId()) if GetDistanceBetweenCoords(coords, Config.CircleZones.WeedField.coords, true) < 50 then SpawnWeedPlants() - Citizen.Wait(500) - else - Citizen.Wait(500) end end end) @@ -28,8 +24,7 @@ Citizen.CreateThread(function() ESX.ShowHelpNotification(_U('weed_processprompt')) end - if IsControlJustReleased(0, Keys['E']) and not isProcessing then - + if IsControlJustReleased(0, 38) and not isProcessing then if Config.LicenseEnable then ESX.TriggerServerCallback('esx_license:checkLicense', function(hasProcessingLicense) if hasProcessingLicense then @@ -41,7 +36,6 @@ Citizen.CreateThread(function() else ProcessWeed() end - end else Citizen.Wait(500) @@ -74,6 +68,7 @@ end Citizen.CreateThread(function() while true do Citizen.Wait(0) + local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) local nearbyObject, nearbyID @@ -85,16 +80,14 @@ Citizen.CreateThread(function() end if nearbyObject and IsPedOnFoot(playerPed) then - if not isPickingUp then ESX.ShowHelpNotification(_U('weed_pickupprompt')) end - if IsControlJustReleased(0, Keys['E']) and not isPickingUp then + if IsControlJustReleased(0, 38) and not isPickingUp then isPickingUp = true ESX.TriggerServerCallback('esx_drugs:canPickUp', function(canPickUp) - if canPickUp then TaskStartScenarioInPlace(playerPed, 'world_human_gardener_plant', 0, false) @@ -113,16 +106,12 @@ Citizen.CreateThread(function() end isPickingUp = false - end, 'cannabis') end - else Citizen.Wait(500) end - end - end) AddEventHandler('onResourceStop', function(resource) @@ -206,4 +195,4 @@ function GetCoordZ(x, y) end return 43.0 -end \ No newline at end of file +end diff --git a/localization/en_esx_drugs.sql b/localization/en_esx_drugs.sql index fe2a3b18..aa88673d 100644 --- a/localization/en_esx_drugs.sql +++ b/localization/en_esx_drugs.sql @@ -1,8 +1,8 @@ USE `essentialmode`; -INSERT INTO `items` (`name`, `label`, `limit`, `rare`, `can_remove`) VALUES - ('cannabis', 'Cannabis', 40, 0, 1), - ('marijuana', 'Marijuana', 14, 0, 1) +INSERT INTO `items` (`name`, `label`, `weight`, `rare`, `can_remove`) VALUES + ('cannabis', 'Cannabis', 3, 0, 1), + ('marijuana', 'Marijuana', 2, 0, 1) ; INSERT INTO `licenses` (`type`, `label`) VALUES diff --git a/localization/es_esx_drugs.sql b/localization/es_esx_drugs.sql index 496d860a..4c3bec8a 100644 --- a/localization/es_esx_drugs.sql +++ b/localization/es_esx_drugs.sql @@ -1,8 +1,8 @@ USE `essentialmode`; -INSERT INTO `items` (`name`, `label`, `limit`, `rare`, `can_remove`) VALUES - ('cannabis', 'Marijuana húmeda', 40, 0, 1), - ('marijuana', 'Marijuana', 14, 0, 1) +INSERT INTO `items` (`name`, `label`, `weight`, `rare`, `can_remove`) VALUES + ('cannabis', 'Marijuana húmeda', 3, 0, 1), + ('marijuana', 'Marijuana', 2, 0, 1) ; INSERT INTO `licenses` (`type`, `label`) VALUES diff --git a/server/main.lua b/server/main.lua index 44eded52..6a6fc240 100644 --- a/server/main.lua +++ b/server/main.lua @@ -15,7 +15,7 @@ AddEventHandler('esx_drugs:sellDrug', function(itemName, amount) end if xItem.count < amount then - TriggerClientEvent('esx:showNotification', source, _U('dealer_notenough')) + xPlayer.showNotification(_U('dealer_notenough')) return end @@ -28,26 +28,25 @@ AddEventHandler('esx_drugs:sellDrug', function(itemName, amount) end xPlayer.removeInventoryItem(xItem.name, amount) - - TriggerClientEvent('esx:showNotification', source, _U('dealer_sold', amount, xItem.label, ESX.Math.GroupDigits(price))) + xPlayer.showNotification(_U('dealer_sold', amount, xItem.label, ESX.Math.GroupDigits(price))) end) ESX.RegisterServerCallback('esx_drugs:buyLicense', function(source, cb, licenseName) local xPlayer = ESX.GetPlayerFromId(source) local license = Config.LicensePrices[licenseName] - if license == nil then - print(('esx_drugs: %s attempted to buy an invalid license!'):format(xPlayer.identifier)) - cb(false) - end - - if xPlayer.getMoney() >= license.price then - xPlayer.removeMoney(license.price) - - TriggerEvent('esx_license:addLicense', source, licenseName, function() - cb(true) - end) + if license then + if xPlayer.getMoney() >= license.price then + xPlayer.removeMoney(license.price) + + TriggerEvent('esx_license:addLicense', source, licenseName, function() + cb(true) + end) + else + cb(false) + end else + print(('esx_drugs: %s attempted to buy an invalid license!'):format(xPlayer.identifier)) cb(false) end end) @@ -55,24 +54,17 @@ end) RegisterServerEvent('esx_drugs:pickedUpCannabis') AddEventHandler('esx_drugs:pickedUpCannabis', function() local xPlayer = ESX.GetPlayerFromId(source) - local xItem = xPlayer.getInventoryItem('cannabis') - if xItem.limit ~= -1 and (xItem.count + 1) > xItem.limit then - TriggerClientEvent('esx:showNotification', _source, _U('weed_inventoryfull')) + if xPlayer.canCarryItem('cannabis', 1) then + xPlayer.showNotification(_U('weed_inventoryfull')) else - xPlayer.addInventoryItem(xItem.name, 1) + xPlayer.addInventoryItem('cannabis', 1) end end) ESX.RegisterServerCallback('esx_drugs:canPickUp', function(source, cb, item) local xPlayer = ESX.GetPlayerFromId(source) - local xItem = xPlayer.getInventoryItem(item) - - if xItem.limit ~= -1 and xItem.count >= xItem.limit then - cb(false) - else - cb(true) - end + cb(xPlayer.canCarryItem(item, 1)) end) RegisterServerEvent('esx_drugs:processCannabis') @@ -82,17 +74,17 @@ AddEventHandler('esx_drugs:processCannabis', function() playersProcessingCannabis[_source] = ESX.SetTimeout(Config.Delays.WeedProcessing, function() local xPlayer = ESX.GetPlayerFromId(_source) - local xCannabis, xMarijuana = xPlayer.getInventoryItem('cannabis'), xPlayer.getInventoryItem('marijuana') + local xCannabis = xPlayer.getInventoryItem('cannabis') - if xMarijuana.limit ~= -1 and (xMarijuana.count + 1) >= xMarijuana.limit then - TriggerClientEvent('esx:showNotification', _source, _U('weed_processingfull')) + if not xPlayer.canCarryItem('marijuana', 1) then + xPlayer.showNotification(_U('weed_processingfull')) elseif xCannabis.count < 3 then - TriggerClientEvent('esx:showNotification', _source, _U('weed_processingenough')) + xPlayer.showNotification(_U('weed_processingenough')) else xPlayer.removeInventoryItem('cannabis', 3) xPlayer.addInventoryItem('marijuana', 1) - TriggerClientEvent('esx:showNotification', _source, _U('weed_processed')) + xPlayer.showNotification(_U('weed_processed')) end playersProcessingCannabis[_source] = nil From a35a3b8b8486005a025dc306df1b5256d974d480 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 29 Oct 2019 20:45:50 +0100 Subject: [PATCH 2298/3224] Fixed statement --- server/main.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/main.lua b/server/main.lua index 6a6fc240..7edbbf2a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -56,9 +56,9 @@ AddEventHandler('esx_drugs:pickedUpCannabis', function() local xPlayer = ESX.GetPlayerFromId(source) if xPlayer.canCarryItem('cannabis', 1) then - xPlayer.showNotification(_U('weed_inventoryfull')) - else xPlayer.addInventoryItem('cannabis', 1) + else + xPlayer.showNotification(_U('weed_inventoryfull')) end end) From cbc5113d7b30afbac743a33c7225bcd2fbaa64bb Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 2 Nov 2019 11:01:26 +0100 Subject: [PATCH 2299/3224] Minor statement fix --- server/main.lua | 50 +++++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/server/main.lua b/server/main.lua index 6fd3fbf1..772fbb3a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -49,36 +49,32 @@ ESX.RegisterServerCallback('esx_weaponshop:buyWeapon', function(source, cb, weap if price == 0 then print(('esx_weaponshop: %s attempted to buy a unknown weapon!'):format(xPlayer.identifier)) cb(false) - end - - if xPlayer.hasWeapon(weaponName) then - TriggerClientEvent('esx:showNotification', source, _U('already_owned')) - cb(false) else - if zone == 'BlackWeashop' then - - if xPlayer.getAccount('black_money').money >= price then - xPlayer.removeAccountMoney('black_money', price) - xPlayer.addWeapon(weaponName, 42) - - cb(true) - else - TriggerClientEvent('esx:showNotification', source, _U('not_enough_black')) - cb(false) - end - + if xPlayer.hasWeapon(weaponName) then + TriggerClientEvent('esx:showNotification', source, _U('already_owned')) + cb(false) else - - if xPlayer.getMoney() >= price then - xPlayer.removeMoney(price) - xPlayer.addWeapon(weaponName, 42) - - cb(true) - else - TriggerClientEvent('esx:showNotification', source, _U('not_enough')) - cb(false) - end + if zone == 'BlackWeashop' then + if xPlayer.getAccount('black_money').money >= price then + xPlayer.removeAccountMoney('black_money', price) + xPlayer.addWeapon(weaponName, 42) + cb(true) + else + TriggerClientEvent('esx:showNotification', source, _U('not_enough_black')) + cb(false) + end + else + if xPlayer.getMoney() >= price then + xPlayer.removeMoney(price) + xPlayer.addWeapon(weaponName, 42) + + cb(true) + else + TriggerClientEvent('esx:showNotification', source, _U('not_enough')) + cb(false) + end + end end end end) From 956fe5f183e2a58a2b21c982bb321668734344b9 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 9 Nov 2019 17:25:41 +0100 Subject: [PATCH 2300/3224] Minor code cleanup --- client/main.lua | 192 +++++++++++++++++++++-------------------------- client/utils.lua | 4 +- config.lua | 24 +++--- server/main.lua | 142 ++++++++++++++++------------------- 4 files changed, 164 insertions(+), 198 deletions(-) diff --git a/client/main.lua b/client/main.lua index 81ba51a1..a6d2a2b8 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,29 +1,17 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - local HasAlreadyEnteredMarker = false -local LastZone = nil -local CurrentAction = nil +local LastZone +local CurrentAction local CurrentActionMsg = '' local CurrentActionData = {} local IsInShopMenu = false local Categories = {} local Vehicles = {} local LastVehicles = {} -local CurrentVehicleData = nil +local CurrentVehicleData -ESX = nil +ESX = nil -Citizen.CreateThread(function () +Citizen.CreateThread(function() while ESX == nil do TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) Citizen.Wait(0) @@ -31,11 +19,11 @@ Citizen.CreateThread(function () Citizen.Wait(10000) - ESX.TriggerServerCallback('esx_vehicleshop:getCategories', function (categories) + ESX.TriggerServerCallback('esx_vehicleshop:getCategories', function(categories) Categories = categories end) - ESX.TriggerServerCallback('esx_vehicleshop:getVehicles', function (vehicles) + ESX.TriggerServerCallback('esx_vehicleshop:getVehicles', function(vehicles) Vehicles = vehicles end) @@ -74,12 +62,12 @@ AddEventHandler('esx:playerLoaded', function(xPlayer) end) RegisterNetEvent('esx_vehicleshop:sendCategories') -AddEventHandler('esx_vehicleshop:sendCategories', function (categories) +AddEventHandler('esx_vehicleshop:sendCategories', function(categories) Categories = categories end) RegisterNetEvent('esx_vehicleshop:sendVehicles') -AddEventHandler('esx_vehicleshop:sendVehicles', function (vehicles) +AddEventHandler('esx_vehicleshop:sendVehicles', function(vehicles) Vehicles = vehicles end) @@ -93,9 +81,10 @@ function DeleteShopInsideVehicles() end function ReturnVehicleProvider() - ESX.TriggerServerCallback('esx_vehicleshop:getCommercialVehicles', function (vehicles) + ESX.TriggerServerCallback('esx_vehicleshop:getCommercialVehicles', function(vehicles) local elements = {} local returnPrice + for i=1, #vehicles, 1 do returnPrice = ESX.Math.Round(vehicles[i].price * 0.75) @@ -109,13 +98,13 @@ function ReturnVehicleProvider() title = _U('return_provider_menu'), align = 'top-left', elements = elements - }, function (data, menu) + }, function(data, menu) TriggerServerEvent('esx_vehicleshop:returnProvider', data.current.value) Citizen.Wait(300) menu.close() ReturnVehicleProvider() - end, function (data, menu) + end, function(data, menu) menu.close() end) end) @@ -124,7 +113,7 @@ end function StartShopRestriction() Citizen.CreateThread(function() while IsInShopMenu do - Citizen.Wait(1) + Citizen.Wait(0) DisableControlAction(0, 75, true) -- Disable exit vehicle DisableControlAction(27, 75, true) -- Disable exit vehicle @@ -142,7 +131,7 @@ function OpenShopMenu() FreezeEntityPosition(playerPed, true) SetEntityVisible(playerPed, false) - SetEntityCoords(playerPed, Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z) + SetEntityCoords(playerPed, Config.Zones.ShopInside.Pos) local vehiclesByCategory = {} local elements = {} @@ -189,7 +178,7 @@ function OpenShopMenu() title = _U('car_dealer'), align = 'top-left', elements = elements - }, function (data, menu) + }, function(data, menu) local vehicleData = vehiclesByCategory[data.current.name][data.current.value + 1] ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'shop_confirm', { @@ -198,8 +187,7 @@ function OpenShopMenu() elements = { {label = _U('no'), value = 'no'}, {label = _U('yes'), value = 'yes'} - } - }, function(data2, menu2) + }}, function(data2, menu2) if data2.current.value == 'yes' then if Config.EnablePlayerManagement then ESX.TriggerServerCallback('esx_vehicleshop:buyVehicleSociety', function(hasEnoughMoney) @@ -216,7 +204,7 @@ function OpenShopMenu() FreezeEntityPosition(playerPed, false) SetEntityVisible(playerPed, true) - SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos.x, Config.Zones.ShopEntering.Pos.y, Config.Zones.ShopEntering.Pos.z) + SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos) menu2.close() menu.close() @@ -236,7 +224,7 @@ function OpenShopMenu() elements = { {label = _U('staff_type'), value = 'personnal'}, {label = _U('society_type'), value = 'society'} - }}, function (data3, menu3) + }}, function(data3, menu3) if data3.current.value == 'personnal' then @@ -249,7 +237,7 @@ function OpenShopMenu() menu.close() DeleteShopInsideVehicles() - ESX.Game.SpawnVehicle(vehicleData.model, Config.Zones.ShopOutside.Pos, Config.Zones.ShopOutside.Heading, function (vehicle) + ESX.Game.SpawnVehicle(vehicleData.model, Config.Zones.ShopOutside.Pos, Config.Zones.ShopOutside.Heading, function(vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) local newPlate = GeneratePlate() @@ -273,7 +261,7 @@ function OpenShopMenu() elseif data3.current.value == 'society' then - ESX.TriggerServerCallback('esx_vehicleshop:buyVehicleSociety', function (hasEnoughMoney) + ESX.TriggerServerCallback('esx_vehicleshop:buyVehicleSociety', function(hasEnoughMoney) if hasEnoughMoney then IsInShopMenu = false @@ -283,7 +271,7 @@ function OpenShopMenu() DeleteShopInsideVehicles() - ESX.Game.SpawnVehicle(vehicleData.model, Config.Zones.ShopOutside.Pos, Config.Zones.ShopOutside.Heading, function (vehicle) + ESX.Game.SpawnVehicle(vehicleData.model, Config.Zones.ShopOutside.Pos, Config.Zones.ShopOutside.Heading, function(vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) local newPlate = GeneratePlate() @@ -302,18 +290,18 @@ function OpenShopMenu() end, playerData.job.name, vehicleData.model) end - end, function (data3, menu3) + end, function(data3, menu3) menu3.close() end) else - ESX.TriggerServerCallback('esx_vehicleshop:buyVehicle', function (hasEnoughMoney) + ESX.TriggerServerCallback('esx_vehicleshop:buyVehicle', function(hasEnoughMoney) if hasEnoughMoney then IsInShopMenu = false menu2.close() menu.close() DeleteShopInsideVehicles() - ESX.Game.SpawnVehicle(vehicleData.model, Config.Zones.ShopOutside.Pos, Config.Zones.ShopOutside.Heading, function (vehicle) + ESX.Game.SpawnVehicle(vehicleData.model, Config.Zones.ShopOutside.Pos, Config.Zones.ShopOutside.Heading, function(vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) local newPlate = GeneratePlate() @@ -337,10 +325,10 @@ function OpenShopMenu() end end end - end, function (data2, menu2) + end, function(data2, menu2) menu2.close() end) - end, function (data, menu) + end, function(data, menu) menu.close() DeleteShopInsideVehicles() local playerPed = PlayerPedId() @@ -351,17 +339,17 @@ function OpenShopMenu() FreezeEntityPosition(playerPed, false) SetEntityVisible(playerPed, true) - SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos.x, Config.Zones.ShopEntering.Pos.y, Config.Zones.ShopEntering.Pos.z) + SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos) IsInShopMenu = false - end, function (data, menu) + end, function(data, menu) local vehicleData = vehiclesByCategory[data.current.name][data.current.value + 1] local playerPed = PlayerPedId() DeleteShopInsideVehicles() WaitForVehicleToLoad(vehicleData.model) - ESX.Game.SpawnLocalVehicle(vehicleData.model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function (vehicle) + ESX.Game.SpawnLocalVehicle(vehicleData.model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function(vehicle) table.insert(LastVehicles, vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) FreezeEntityPosition(vehicle, true) @@ -372,13 +360,12 @@ function OpenShopMenu() DeleteShopInsideVehicles() WaitForVehicleToLoad(firstVehicleData.model) - ESX.Game.SpawnLocalVehicle(firstVehicleData.model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function (vehicle) + ESX.Game.SpawnLocalVehicle(firstVehicleData.model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function(vehicle) table.insert(LastVehicles, vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) FreezeEntityPosition(vehicle, true) SetModelAsNoLongerNeeded(firstVehicleData.model) end) - end function WaitForVehicleToLoad(modelHash) @@ -392,7 +379,7 @@ function WaitForVehicleToLoad(modelHash) EndTextCommandBusyString(4) while not HasModelLoaded(modelHash) do - Citizen.Wait(1) + Citizen.Wait(0) DisableAllControlActions(0) end @@ -418,8 +405,7 @@ function OpenResellerMenu() {label = _U('set_vehicle_owner_sell_society'), value = 'set_vehicle_owner_sell_society'}, {label = _U('deposit_stock'), value = 'put_stock'}, {label = _U('take_stock'), value = 'get_stock'} - } - }, function (data, menu) + }}, function(data, menu) local action = data.current.value if action == 'buy_vehicle' then @@ -444,7 +430,7 @@ function OpenResellerMenu() ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'set_vehicle_owner_sell_amount', { title = _U('invoice_amount') - }, function (data2, menu2) + }, function(data2, menu2) local amount = tonumber(data2.value) if amount == nil then @@ -459,7 +445,7 @@ function OpenResellerMenu() TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_cardealer', _U('car_dealer'), tonumber(data2.value)) end end - end, function (data2, menu2) + end, function(data2, menu2) menu2.close() end) @@ -496,7 +482,7 @@ function OpenResellerMenu() if closestPlayer == -1 or closestDistance > 3.0 then ESX.ShowNotification(_U('no_players')) else - ESX.TriggerServerCallback('esx:getOtherPlayerData', function (xPlayer) + ESX.TriggerServerCallback('esx:getOtherPlayerData', function(xPlayer) local newPlate = GeneratePlate() local vehicleProps = ESX.Game.GetVehicleProperties(LastVehicles[#LastVehicles]) @@ -520,7 +506,7 @@ function OpenResellerMenu() ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'set_vehicle_owner_rent_amount', { title = _U('rental_amount') - }, function (data2, menu2) + }, function(data2, menu2) local amount = tonumber(data2.value) if amount == nil then @@ -545,14 +531,13 @@ function OpenResellerMenu() end ESX.ShowNotification(_U('vehicle_set_rented', vehicleProps.plate, GetPlayerName(closestPlayer))) - TriggerServerEvent('esx_vehicleshop:setVehicleForAllPlayers', vehicleProps, Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 5.0) end end - end, function (data2, menu2) + end, function(data2, menu2) menu2.close() end) end - end, function (data, menu) + end, function(data, menu) menu.close() CurrentAction = 'reseller_menu' @@ -562,7 +547,7 @@ function OpenResellerMenu() end function OpenPopVehicleMenu() - ESX.TriggerServerCallback('esx_vehicleshop:getCommercialVehicles', function (vehicles) + ESX.TriggerServerCallback('esx_vehicleshop:getCommercialVehicles', function(vehicles) local elements = {} for i=1, #vehicles, 1 do @@ -576,12 +561,12 @@ function OpenPopVehicleMenu() title = _U('vehicle_dealer'), align = 'top-left', elements = elements - }, function (data, menu) + }, function(data, menu) local model = data.current.value DeleteShopInsideVehicles() - ESX.Game.SpawnVehicle(model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function (vehicle) + ESX.Game.SpawnVehicle(model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function(vehicle) table.insert(LastVehicles, vehicle) for i=1, #Vehicles, 1 do @@ -591,14 +576,14 @@ function OpenPopVehicleMenu() end end end) - end, function (data, menu) + end, function(data, menu) menu.close() end) end) end function OpenRentedVehiclesMenu() - ESX.TriggerServerCallback('esx_vehicleshop:getRentedVehicles', function (vehicles) + ESX.TriggerServerCallback('esx_vehicleshop:getRentedVehicles', function(vehicles) local elements = {} for i=1, #vehicles, 1 do @@ -612,7 +597,7 @@ function OpenRentedVehiclesMenu() title = _U('rent_vehicle'), align = 'top-left', elements = elements - }, nil, function (data, menu) + }, nil, function(data, menu) menu.close() end) end) @@ -627,7 +612,7 @@ function OpenBossActionsMenu() elements = { {label = _U('boss_actions'), value = 'boss_actions'}, {label = _U('boss_sold'), value = 'sold_vehicles'} - }}, function (data, menu) + }}, function(data, menu) if data.current.value == 'boss_actions' then TriggerEvent('esx_society:openBossMenu', 'cardealer', function(data2, menu2) menu2.close() @@ -661,7 +646,7 @@ function OpenBossActionsMenu() end) end - end, function (data, menu) + end, function(data, menu) menu.close() CurrentAction = 'boss_actions_menu' @@ -671,7 +656,7 @@ function OpenBossActionsMenu() end function OpenGetStocksMenu() - ESX.TriggerServerCallback('esx_vehicleshop:getStockItems', function (items) + ESX.TriggerServerCallback('esx_vehicleshop:getStockItems', function(items) local elements = {} for i=1, #items, 1 do @@ -685,12 +670,12 @@ function OpenGetStocksMenu() title = _U('dealership_stock'), align = 'top-left', elements = elements - }, function (data, menu) + }, function(data, menu) local itemName = data.current.value ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'stocks_menu_get_item_count', { title = _U('amount') - }, function (data2, menu2) + }, function(data2, menu2) local count = tonumber(data2.value) if count == nil then @@ -701,18 +686,17 @@ function OpenGetStocksMenu() menu.close() OpenGetStocksMenu() end - end, function (data2, menu2) + end, function(data2, menu2) menu2.close() end) - - end, function (data, menu) + end, function(data, menu) menu.close() end) end) end function OpenPutStocksMenu() - ESX.TriggerServerCallback('esx_vehicleshop:getPlayerInventory', function (inventory) + ESX.TriggerServerCallback('esx_vehicleshop:getPlayerInventory', function(inventory) local elements = {} for i=1, #inventory.items, 1 do @@ -731,12 +715,12 @@ function OpenPutStocksMenu() title = _U('inventory'), align = 'top-left', elements = elements - }, function (data, menu) + }, function(data, menu) local itemName = data.current.value ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'stocks_menu_put_item_count', { title = _U('amount') - }, function (data2, menu2) + }, function(data2, menu2) local count = tonumber(data2.value) if count == nil then @@ -747,17 +731,17 @@ function OpenPutStocksMenu() menu.close() OpenPutStocksMenu() end - end, function (data2, menu2) + end, function(data2, menu2) menu2.close() end) - end, function (data, menu) + end, function(data, menu) menu.close() end) end) end RegisterNetEvent('esx:setJob') -AddEventHandler('esx:setJob', function (job) +AddEventHandler('esx:setJob', function(job) ESX.PlayerData.job = job if Config.EnablePlayerManagement then @@ -774,7 +758,7 @@ AddEventHandler('esx:setJob', function (job) end end) -AddEventHandler('esx_vehicleshop:hasEnteredMarker', function (zone) +AddEventHandler('esx_vehicleshop:hasEnteredMarker', function(zone) if zone == 'ShopEntering' then if Config.EnablePlayerManagement then @@ -845,7 +829,7 @@ AddEventHandler('esx_vehicleshop:hasEnteredMarker', function (zone) end end) -AddEventHandler('esx_vehicleshop:hasExitedMarker', function (zone) +AddEventHandler('esx_vehicleshop:hasExitedMarker', function(zone) if not IsInShopMenu then ESX.UI.Menu.CloseAll() end @@ -863,14 +847,14 @@ AddEventHandler('onResourceStop', function(resource) FreezeEntityPosition(playerPed, false) SetEntityVisible(playerPed, true) - SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos.x, Config.Zones.ShopEntering.Pos.y, Config.Zones.ShopEntering.Pos.z) + SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos) end end end) if Config.EnablePlayerManagement then RegisterNetEvent('esx_phone:loaded') - AddEventHandler('esx_phone:loaded', function (phoneNumber, contacts) + AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) local specialContact = { name = _U('dealership'), number = 'cardealer', @@ -883,7 +867,7 @@ end -- Create Blips Citizen.CreateThread(function() - local blip = AddBlipForCoord(Config.Zones.ShopEntering.Pos.x, Config.Zones.ShopEntering.Pos.y, Config.Zones.ShopEntering.Pos.z) + local blip = AddBlipForCoord(Config.Zones.ShopEntering.Pos) SetBlipSprite (blip, 326) SetBlipDisplay(blip, 4) @@ -895,40 +879,32 @@ Citizen.CreateThread(function() EndTextCommandSetBlipName(blip) end) --- Display markers +-- Enter / Exit marker events & Draw Markers Citizen.CreateThread(function() while true do Citizen.Wait(0) - - local coords = GetEntityCoords(PlayerPedId()) + local playerCoords = GetEntityCoords(PlayerPedId()) + local isInMarker, letSleep, currentZone = false, true for k,v in pairs(Config.Zones) do - if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then - DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) - end - end - end -end) + local distance = #(playerCoords - v.Pos) --- Enter / Exit marker events -Citizen.CreateThread(function () - while true do - Citizen.Wait(0) + if distance < Config.DrawDistance then + letSleep = false - local coords = GetEntityCoords(PlayerPedId()) - local isInMarker = false - local currentZone = nil + if v.Type ~= -1 then + DrawMarker(v.Type, v.Pos, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, nil, nil, false) + end - for k,v in pairs(Config.Zones) do - if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then - isInMarker = true - currentZone = k + if distance < v.Size.x then + isInMarker, currentZone = true, k + end end end if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then - HasAlreadyEnteredMarker = true - LastZone = currentZone + HasAlreadyEnteredMarker, LastZone = true, currentZone + LastZone = currentZone TriggerEvent('esx_vehicleshop:hasEnteredMarker', currentZone) end @@ -936,20 +912,22 @@ Citizen.CreateThread(function () HasAlreadyEnteredMarker = false TriggerEvent('esx_vehicleshop:hasExitedMarker', LastZone) end + + if letSleep then + Citizen.Wait(500) + end end end) -- Key controls Citizen.CreateThread(function() while true do - Citizen.Wait(10) + Citizen.Wait(0) - if CurrentAction == nil then - Citizen.Wait(500) - else + if CurrentAction then ESX.ShowHelpNotification(CurrentActionMsg) - if IsControlJustReleased(0, Keys['E']) then + if IsControlJustReleased(0, 38) then if CurrentAction == 'shop_menu' then if Config.LicenseEnable then ESX.TriggerServerCallback('esx_license:checkLicense', function(hasDriversLicense) @@ -988,6 +966,8 @@ Citizen.CreateThread(function() CurrentAction = nil end + else + Citizen.Wait(500) end end end) diff --git a/client/utils.lua b/client/utils.lua index cfb4b114..26e586bb 100644 --- a/client/utils.lua +++ b/client/utils.lua @@ -49,7 +49,7 @@ function IsPlateTaken(plate) end function GetRandomNumber(length) - Citizen.Wait(1) + Citizen.Wait(0) math.randomseed(GetGameTimer()) if length > 0 then return GetRandomNumber(length - 1) .. NumberCharset[math.random(1, #NumberCharset)] @@ -59,7 +59,7 @@ function GetRandomNumber(length) end function GetRandomLetter(length) - Citizen.Wait(1) + Citizen.Wait(0) math.randomseed(GetGameTimer()) if length > 0 then return GetRandomLetter(length - 1) .. Charset[math.random(1, #Charset)] diff --git a/config.lua b/config.lua index bcf88181..0c87297e 100644 --- a/config.lua +++ b/config.lua @@ -19,40 +19,40 @@ Config.PlateUseSpace = true Config.Zones = { ShopEntering = { - Pos = { x = -33.777, y = -1102.021, z = 25.422 }, - Size = { x = 1.5, y = 1.5, z = 1.0 }, + Pos = vector3(-33.7, -1102.0, 25.4), + Size = {x = 1.5, y = 1.5, z = 1.0}, Type = 1 }, ShopInside = { - Pos = { x = -47.570, y = -1097.221, z = 25.422 }, - Size = { x = 1.5, y = 1.5, z = 1.0 }, + Pos = vector3(-47.5, -1097.2, 25.4), + Size = {x = 1.5, y = 1.5, z = 1.0}, Heading = -20.0, Type = -1 }, ShopOutside = { - Pos = { x = -28.637, y = -1085.691, z = 25.565 }, - Size = { x = 1.5, y = 1.5, z = 1.0 }, + Pos = vector3(-28.6, -1085.6, 25.5), + Size = {x = 1.5, y = 1.5, z = 1.0}, Heading = 330.0, Type = -1 }, BossActions = { - Pos = { x = -32.065, y = -1114.277, z = 25.422 }, - Size = { x = 1.5, y = 1.5, z = 1.0 }, + Pos = vector3(-32.0, -1114.2, 25.4), + Size = {x = 1.5, y = 1.5, z = 1.0}, Type = -1 }, GiveBackVehicle = { - Pos = { x = -18.227, y = -1078.558, z = 25.675 }, - Size = { x = 3.0, y = 3.0, z = 1.0 }, + Pos = vector3(-18.2, -1078.5, 25.6), + Size = {x = 3.0, y = 3.0, z = 1.0}, Type = (Config.EnablePlayerManagement and 1 or -1) }, ResellVehicle = { - Pos = { x = -44.630, y = -1080.738, z = 25.683 }, - Size = { x = 3.0, y = 3.0, z = 1.0 }, + Pos = vector3(-44.6, -1080.7, 25.6), + Size = {x = 3.0, y = 3.0, z = 1.0}, Type = 1 } diff --git a/server/main.lua b/server/main.lua index 2773e180..ed3182b2 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,6 +1,5 @@ -ESX = nil -local Categories = {} -local Vehicles = {} +ESX = nil +local Categories, Vehicles = {}, {} TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) @@ -46,7 +45,7 @@ MySQL.ready(function() end) RegisterServerEvent('esx_vehicleshop:setVehicleOwned') -AddEventHandler('esx_vehicleshop:setVehicleOwned', function (vehicleProps) +AddEventHandler('esx_vehicleshop:setVehicleOwned', function(vehicleProps) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) @@ -55,13 +54,13 @@ AddEventHandler('esx_vehicleshop:setVehicleOwned', function (vehicleProps) ['@owner'] = xPlayer.identifier, ['@plate'] = vehicleProps.plate, ['@vehicle'] = json.encode(vehicleProps) - }, function (rowsChanged) + }, function(rowsChanged) TriggerClientEvent('esx:showNotification', _source, _U('vehicle_belongs', vehicleProps.plate)) end) end) RegisterServerEvent('esx_vehicleshop:setVehicleOwnedPlayerId') -AddEventHandler('esx_vehicleshop:setVehicleOwnedPlayerId', function (playerId, vehicleProps) +AddEventHandler('esx_vehicleshop:setVehicleOwnedPlayerId', function(playerId, vehicleProps) local xPlayer = ESX.GetPlayerFromId(playerId) MySQL.Async.execute('INSERT INTO owned_vehicles (owner, plate, vehicle) VALUES (@owner, @plate, @vehicle)', @@ -69,31 +68,28 @@ AddEventHandler('esx_vehicleshop:setVehicleOwnedPlayerId', function (playerId, v ['@owner'] = xPlayer.identifier, ['@plate'] = vehicleProps.plate, ['@vehicle'] = json.encode(vehicleProps) - }, function (rowsChanged) + }, function(rowsChanged) TriggerClientEvent('esx:showNotification', playerId, _U('vehicle_belongs', vehicleProps.plate)) end) end) RegisterServerEvent('esx_vehicleshop:setVehicleOwnedSociety') -AddEventHandler('esx_vehicleshop:setVehicleOwnedSociety', function (society, vehicleProps) +AddEventHandler('esx_vehicleshop:setVehicleOwnedSociety', function(society, vehicleProps) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) - MySQL.Async.execute('INSERT INTO owned_vehicles (owner, plate, vehicle) VALUES (@owner, @plate, @vehicle)', - { + MySQL.Async.execute('INSERT INTO owned_vehicles (owner, plate, vehicle) VALUES (@owner, @plate, @vehicle)', { ['@owner'] = 'society:' .. society, ['@plate'] = vehicleProps.plate, ['@vehicle'] = json.encode(vehicleProps), - }, function (rowsChanged) - - end) + }, function(rowsChanged) end) end) RegisterServerEvent('esx_vehicleshop:sellVehicle') -AddEventHandler('esx_vehicleshop:sellVehicle', function (vehicle) +AddEventHandler('esx_vehicleshop:sellVehicle', function(vehicle) MySQL.Async.fetchAll('SELECT * FROM cardealer_vehicles WHERE vehicle = @vehicle LIMIT 1', { ['@vehicle'] = vehicle - }, function (result) + }, function(result) local id = result[1].id MySQL.Async.execute('DELETE FROM cardealer_vehicles WHERE id = @id', { @@ -107,34 +103,32 @@ AddEventHandler('esx_vehicleshop:addToList', function(target, model, plate) local xPlayer, xTarget = ESX.GetPlayerFromId(source), ESX.GetPlayerFromId(target) local dateNow = os.date('%Y-%m-%d %H:%M') - if xPlayer.job.name ~= 'cardealer' then + if xPlayer.job.name == 'cardealer' then + MySQL.Async.execute('INSERT INTO vehicle_sold (client, model, plate, soldby, date) VALUES (@client, @model, @plate, @soldby, @date)', { + ['@client'] = xTarget.getName(), + ['@model'] = model, + ['@plate'] = plate, + ['@soldby'] = xPlayer.getName(), + ['@date'] = dateNow + }) + else print(('esx_vehicleshop: %s attempted to add a sold vehicle to list!'):format(xPlayer.identifier)) - return end - - MySQL.Async.execute('INSERT INTO vehicle_sold (client, model, plate, soldby, date) VALUES (@client, @model, @plate, @soldby, @date)', { - ['@client'] = xTarget.getName(), - ['@model'] = model, - ['@plate'] = plate, - ['@soldby'] = xPlayer.getName(), - ['@date'] = dateNow - }) end) -ESX.RegisterServerCallback('esx_vehicleshop:getSoldVehicles', function (source, cb) - +ESX.RegisterServerCallback('esx_vehicleshop:getSoldVehicles', function(source, cb) MySQL.Async.fetchAll('SELECT * FROM vehicle_sold', {}, function(result) cb(result) end) end) RegisterServerEvent('esx_vehicleshop:rentVehicle') -AddEventHandler('esx_vehicleshop:rentVehicle', function (vehicle, plate, playerName, basePrice, rentPrice, target) +AddEventHandler('esx_vehicleshop:rentVehicle', function(vehicle, plate, playerName, basePrice, rentPrice, target) local xPlayer = ESX.GetPlayerFromId(target) MySQL.Async.fetchAll('SELECT * FROM cardealer_vehicles WHERE vehicle = @vehicle LIMIT 1', { ['@vehicle'] = vehicle - }, function (result) + }, function(result) local id = result[1].id local price = result[1].price local owner = xPlayer.identifier @@ -143,8 +137,7 @@ AddEventHandler('esx_vehicleshop:rentVehicle', function (vehicle, plate, playerN ['@id'] = id }) - 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)', - { + 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'] = playerName, @@ -156,12 +149,12 @@ AddEventHandler('esx_vehicleshop:rentVehicle', function (vehicle, plate, playerN end) RegisterServerEvent('esx_vehicleshop:getStockItem') -AddEventHandler('esx_vehicleshop:getStockItem', function (itemName, count) +AddEventHandler('esx_vehicleshop:getStockItem', function(itemName, count) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) local sourceItem = xPlayer.getInventoryItem(itemName) - TriggerEvent('esx_addoninventory:getSharedInventory', 'society_cardealer', function (inventory) + TriggerEvent('esx_addoninventory:getSharedInventory', 'society_cardealer', function(inventory) local item = inventory.getItem(itemName) -- is there enough in the society? @@ -182,11 +175,11 @@ AddEventHandler('esx_vehicleshop:getStockItem', function (itemName, count) end) RegisterServerEvent('esx_vehicleshop:putStockItems') -AddEventHandler('esx_vehicleshop:putStockItems', function (itemName, count) +AddEventHandler('esx_vehicleshop:putStockItems', function(itemName, count) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) - TriggerEvent('esx_addoninventory:getSharedInventory', 'society_cardealer', function (inventory) + TriggerEvent('esx_addoninventory:getSharedInventory', 'society_cardealer', function(inventory) local item = inventory.getItem(itemName) if item.count >= 0 then @@ -199,17 +192,17 @@ AddEventHandler('esx_vehicleshop:putStockItems', function (itemName, count) end) end) -ESX.RegisterServerCallback('esx_vehicleshop:getCategories', function (source, cb) +ESX.RegisterServerCallback('esx_vehicleshop:getCategories', function(source, cb) cb(Categories) end) -ESX.RegisterServerCallback('esx_vehicleshop:getVehicles', function (source, cb) +ESX.RegisterServerCallback('esx_vehicleshop:getVehicles', function(source, cb) cb(Vehicles) end) -ESX.RegisterServerCallback('esx_vehicleshop:buyVehicle', function (source, cb, vehicleModel) - local xPlayer = ESX.GetPlayerFromId(source) - local vehicleData = nil +ESX.RegisterServerCallback('esx_vehicleshop:buyVehicle', function(source, cb, vehicleModel) + local xPlayer = ESX.GetPlayerFromId(source) + local vehicleData for i=1, #Vehicles, 1 do if Vehicles[i].model == vehicleModel then @@ -218,7 +211,7 @@ ESX.RegisterServerCallback('esx_vehicleshop:buyVehicle', function (source, cb, v end end - if xPlayer.getMoney() >= vehicleData.price then + if vehicleData and xPlayer.getMoney() >= vehicleData.price then xPlayer.removeMoney(vehicleData.price) cb(true) else @@ -226,8 +219,8 @@ ESX.RegisterServerCallback('esx_vehicleshop:buyVehicle', function (source, cb, v end end) -ESX.RegisterServerCallback('esx_vehicleshop:buyVehicleSociety', function (source, cb, society, vehicleModel) - local vehicleData = nil +ESX.RegisterServerCallback('esx_vehicleshop:buyVehicleSociety', function(source, cb, society, vehicleModel) + local vehicleData for i=1, #Vehicles, 1 do if Vehicles[i].model == vehicleModel then @@ -236,7 +229,7 @@ ESX.RegisterServerCallback('esx_vehicleshop:buyVehicleSociety', function (source end end - TriggerEvent('esx_addonaccount:getSharedAccount', 'society_' .. society, function (account) + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_' .. society, function(account) if account.money >= vehicleData.price then account.removeMoney(vehicleData.price) @@ -246,15 +239,14 @@ ESX.RegisterServerCallback('esx_vehicleshop:buyVehicleSociety', function (source }, function(rowsChanged) cb(true) end) - else cb(false) end end) end) -ESX.RegisterServerCallback('esx_vehicleshop:getCommercialVehicles', function (source, cb) - MySQL.Async.fetchAll('SELECT * FROM cardealer_vehicles ORDER BY vehicle ASC', {}, function (result) +ESX.RegisterServerCallback('esx_vehicleshop:getCommercialVehicles', function(source, cb) + MySQL.Async.fetchAll('SELECT * FROM cardealer_vehicles ORDER BY vehicle ASC', {}, function(result) local vehicles = {} for i=1, #result, 1 do @@ -275,10 +267,9 @@ AddEventHandler('esx_vehicleshop:returnProvider', function(vehicleModel) MySQL.Async.fetchAll('SELECT * FROM cardealer_vehicles WHERE vehicle = @vehicle LIMIT 1', { ['@vehicle'] = vehicleModel - }, function (result) - + }, function(result) if result[1] then - local id = result[1].id + local id = result[1].id local price = ESX.Math.Round(result[1].price * 0.75) TriggerEvent('esx_addonaccount:getSharedAccount', 'society_cardealer', function(account) @@ -291,21 +282,19 @@ AddEventHandler('esx_vehicleshop:returnProvider', function(vehicleModel) TriggerClientEvent('esx:showNotification', _source, _U('vehicle_sold_for', vehicleModel, ESX.Math.GroupDigits(price))) else - print(('esx_vehicleshop: %s attempted selling an invalid vehicle!'):format(GetPlayerIdentifiers(_source)[1])) end - end) end) -ESX.RegisterServerCallback('esx_vehicleshop:getRentedVehicles', function (source, cb) - MySQL.Async.fetchAll('SELECT * FROM rented_vehicles ORDER BY player_name ASC', {}, function (result) +ESX.RegisterServerCallback('esx_vehicleshop:getRentedVehicles', function(source, cb) + MySQL.Async.fetchAll('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, + name = result[i].vehicle, + plate = result[i].plate, playerName = result[i].player_name }) end @@ -314,12 +303,12 @@ ESX.RegisterServerCallback('esx_vehicleshop:getRentedVehicles', function (source end) end) -ESX.RegisterServerCallback('esx_vehicleshop:giveBackVehicle', function (source, cb, plate) +ESX.RegisterServerCallback('esx_vehicleshop:giveBackVehicle', function(source, cb, plate) MySQL.Async.fetchAll('SELECT * FROM rented_vehicles WHERE plate = @plate', { ['@plate'] = plate - }, function (result) - if result[1] ~= nil then - local vehicle = result[1].vehicle + }, function(result) + if result[1] then + local vehicle = result[1].vehicle local basePrice = result[1].base_price MySQL.Async.execute('INSERT INTO cardealer_vehicles (vehicle, price) VALUES (@vehicle, @price)', { @@ -339,7 +328,7 @@ ESX.RegisterServerCallback('esx_vehicleshop:giveBackVehicle', function (source, end) end) -ESX.RegisterServerCallback('esx_vehicleshop:resellVehicle', function (source, cb, plate, model) +ESX.RegisterServerCallback('esx_vehicleshop:resellVehicle', function(source, cb, plate, model) local resellPrice = 0 -- calculate the resell price @@ -356,7 +345,7 @@ ESX.RegisterServerCallback('esx_vehicleshop:resellVehicle', function (source, cb else MySQL.Async.fetchAll('SELECT * FROM rented_vehicles WHERE plate = @plate', { ['@plate'] = plate - }, function (result) + }, function(result) if result[1] then -- is it a rented vehicle? cb(false) -- it is, don't let the player sell it since he doesn't own it else @@ -365,7 +354,7 @@ ESX.RegisterServerCallback('esx_vehicleshop:resellVehicle', function (source, cb MySQL.Async.fetchAll('SELECT * FROM owned_vehicles WHERE owner = @owner AND @plate = plate', { ['@owner'] = xPlayer.identifier, ['@plate'] = plate - }, function (result) + }, function(result) if result[1] then -- does the owner match? local vehicle = json.decode(result[1].vehicle) @@ -387,7 +376,7 @@ ESX.RegisterServerCallback('esx_vehicleshop:resellVehicle', function (source, cb MySQL.Async.fetchAll('SELECT * FROM owned_vehicles WHERE owner = @owner AND @plate = plate', { ['@owner'] = 'society:' .. xPlayer.job.name, ['@plate'] = plate - }, function (result) + }, function(result) if result[1] then local vehicle = json.decode(result[1].vehicle) @@ -418,36 +407,35 @@ ESX.RegisterServerCallback('esx_vehicleshop:resellVehicle', function (source, cb end end) - -ESX.RegisterServerCallback('esx_vehicleshop:getStockItems', function (source, cb) +ESX.RegisterServerCallback('esx_vehicleshop:getStockItems', function(source, cb) TriggerEvent('esx_addoninventory:getSharedInventory', 'society_cardealer', function(inventory) cb(inventory.items) end) end) -ESX.RegisterServerCallback('esx_vehicleshop:getPlayerInventory', function (source, cb) +ESX.RegisterServerCallback('esx_vehicleshop:getPlayerInventory', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) local items = xPlayer.inventory cb({items = items}) end) -ESX.RegisterServerCallback('esx_vehicleshop:isPlateTaken', function (source, cb, plate) +ESX.RegisterServerCallback('esx_vehicleshop:isPlateTaken', function(source, cb, plate) MySQL.Async.fetchAll('SELECT 1 FROM owned_vehicles WHERE plate = @plate', { ['@plate'] = plate - }, function (result) + }, function(result) cb(result[1] ~= nil) end) end) -ESX.RegisterServerCallback('esx_vehicleshop:retrieveJobVehicles', function (source, cb, type) +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) + }, function(result) cb(result) end) end) @@ -468,18 +456,16 @@ AddEventHandler('esx_vehicleshop:setJobVehicleState', function(plate, state) end) function PayRent(d, h, m) - MySQL.Async.fetchAll('SELECT * FROM rented_vehicles', {}, function (result) + MySQL.Async.fetchAll('SELECT * FROM rented_vehicles', {}, function(result) for i=1, #result, 1 do local xPlayer = ESX.GetPlayerFromIdentifier(result[i].owner) - -- message player if connected - if xPlayer ~= nil then + if xPlayer then -- message player if connected xPlayer.removeAccountMoney('bank', result[i].rent_price) TriggerClientEvent('esx:showNotification', xPlayer.source, _U('paid_rental', ESX.Math.GroupDigits(result[i].rent_price))) - else -- pay rent either way - MySQL.Sync.execute('UPDATE users SET bank = bank - @bank WHERE identifier = @identifier', - { - ['@bank'] = result[i].rent_price, + else -- pay rent by updating SQL + MySQL.Sync.execute('UPDATE users SET bank = bank - @bank WHERE identifier = @identifier', { + ['@bank'] = result[i].rent_price, ['@identifier'] = result[i].owner }) end From 591aba63250ee9e1158c9548c7e058906eff93b1 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Tue, 12 Nov 2019 20:46:15 +0100 Subject: [PATCH 2301/3224] Add support for new ESX weight system (#75) * Support for new ESX * Fix --- server/main.lua | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/server/main.lua b/server/main.lua index 1828aa3f..fd82be43 100644 --- a/server/main.lua +++ b/server/main.lua @@ -23,9 +23,9 @@ function SetPropertyOwned(name, price, rented, owner) TriggerClientEvent('esx_property:setPropertyOwned', xPlayer.source, name, true) if rented then - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('rented_for', ESX.Math.GroupDigits(price))) + xPlayer.showNotification(_U('rented_for', ESX.Math.GroupDigits(price))) else - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('purchased_for', ESX.Math.GroupDigits(price))) + xPlayer.showNotification(_U('purchased_for', ESX.Math.GroupDigits(price))) end end end) @@ -40,7 +40,7 @@ function RemoveOwnedProperty(name, owner) if xPlayer then TriggerClientEvent('esx_property:setPropertyOwned', xPlayer.source, name, false) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('made_property')) + xPlayer.showNotification(_U('made_property')) end end) end @@ -166,7 +166,7 @@ AddEventHandler('esx_property:buyProperty', function(propertyName) xPlayer.removeMoney(property.price) SetPropertyOwned(propertyName, property.price, false, xPlayer.identifier) else - TriggerClientEvent('esx:showNotification', source, _U('not_enough')) + xPlayer.showNotification(_U('not_enough')) end end) @@ -216,15 +216,15 @@ AddEventHandler('esx_property:getItem', function(owner, type, item, count) if count > 0 and inventoryItem.count >= count then -- can the player carry the said amount of x item? - if sourceItem.limit ~= -1 and (sourceItem.count + count) > sourceItem.limit then - TriggerClientEvent('esx:showNotification', _source, _U('player_cannot_hold')) - else + if xPlayer.canCarryItem(item, count) then inventory.removeItem(item, count) xPlayer.addInventoryItem(item, count) - TriggerClientEvent('esx:showNotification', _source, _U('have_withdrawn', count, inventoryItem.label)) + xPlayer.showNotification(_U('have_withdrawn', count, inventoryItem.label)) + else + xPlayer.showNotification(_U('player_cannot_hold')) end else - TriggerClientEvent('esx:showNotification', _source, _U('not_enough_in_property')) + xPlayer.showNotification(_U('not_enough_in_property')) end end) @@ -237,7 +237,7 @@ AddEventHandler('esx_property:getItem', function(owner, type, item, count) account.removeMoney(count) xPlayer.addAccountMoney(item, count) else - TriggerClientEvent('esx:showNotification', _source, _U('amount_invalid')) + xPlayer.showNotification(_U('amount_invalid')) end end) @@ -279,10 +279,10 @@ AddEventHandler('esx_property:putItem', function(owner, type, item, count) TriggerEvent('esx_addoninventory:getInventory', 'property', xPlayerOwner.identifier, function(inventory) xPlayer.removeInventoryItem(item, count) inventory.addItem(item, count) - TriggerClientEvent('esx:showNotification', _source, _U('have_deposited', count, inventory.getItem(item).label)) + xPlayer.showNotification(_U('have_deposited', count, inventory.getItem(item).label)) end) else - TriggerClientEvent('esx:showNotification', _source, _U('invalid_quantity')) + xPlayer.showNotification(_U('invalid_quantity')) end elseif type == 'item_account' then @@ -296,7 +296,7 @@ AddEventHandler('esx_property:putItem', function(owner, type, item, count) account.addMoney(count) end) else - TriggerClientEvent('esx:showNotification', _source, _U('amount_invalid')) + xPlayer.showNotification(_U('amount_invalid')) end elseif type == 'item_weapon' then @@ -424,7 +424,7 @@ function PayRent(d, h, m) -- message player if connected if xPlayer then xPlayer.removeAccountMoney('bank', result[i].price) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('paid_rent', ESX.Math.GroupDigits(result[i].price))) + xPlayer.showNotification(_U('paid_rent', ESX.Math.GroupDigits(result[i].price))) else -- pay rent either way MySQL.Sync.execute('UPDATE users SET bank = bank - @bank WHERE identifier = @identifier', { ['@bank'] = result[i].price, From 1b7721641c391145178670ea969508ef3dbab8b6 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Tue, 12 Nov 2019 20:55:05 +0100 Subject: [PATCH 2302/3224] Removed letftover variable (#77) --- server/main.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index fd82be43..2e0a6e5a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -207,7 +207,6 @@ AddEventHandler('esx_property:getItem', function(owner, type, item, count) if type == 'item_standard' then - local sourceItem = xPlayer.getInventoryItem(item) TriggerEvent('esx_addoninventory:getInventory', 'property', xPlayerOwner.identifier, function(inventory) local inventoryItem = inventory.getItem(item) From 68a9f126ebfc0728ddb1e40969764d9b80109a90 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Tue, 12 Nov 2019 20:55:27 +0100 Subject: [PATCH 2303/3224] Support for new ESX weight system (#224) * Support for new ESX * Fix * Fix 2 and removed sourceItem variable --- server/main.lua | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/server/main.lua b/server/main.lua index ed3182b2..00108026 100644 --- a/server/main.lua +++ b/server/main.lua @@ -55,7 +55,7 @@ AddEventHandler('esx_vehicleshop:setVehicleOwned', function(vehicleProps) ['@plate'] = vehicleProps.plate, ['@vehicle'] = json.encode(vehicleProps) }, function(rowsChanged) - TriggerClientEvent('esx:showNotification', _source, _U('vehicle_belongs', vehicleProps.plate)) + xPlayer.showNotification(_U('vehicle_belongs', vehicleProps.plate)) end) end) @@ -69,7 +69,7 @@ AddEventHandler('esx_vehicleshop:setVehicleOwnedPlayerId', function(playerId, ve ['@plate'] = vehicleProps.plate, ['@vehicle'] = json.encode(vehicleProps) }, function(rowsChanged) - TriggerClientEvent('esx:showNotification', playerId, _U('vehicle_belongs', vehicleProps.plate)) + xPlayer.showNotification(_U('vehicle_belongs', vehicleProps.plate)) end) end) @@ -152,7 +152,6 @@ RegisterServerEvent('esx_vehicleshop:getStockItem') AddEventHandler('esx_vehicleshop:getStockItem', function(itemName, count) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) - local sourceItem = xPlayer.getInventoryItem(itemName) TriggerEvent('esx_addoninventory:getSharedInventory', 'society_cardealer', function(inventory) local item = inventory.getItem(itemName) @@ -161,15 +160,15 @@ AddEventHandler('esx_vehicleshop:getStockItem', function(itemName, count) if count > 0 and item.count >= count then -- can the player carry the said amount of x item? - if sourceItem.limit ~= -1 and (sourceItem.count + count) > sourceItem.limit then - TriggerClientEvent('esx:showNotification', _source, _U('player_cannot_hold')) - else + if xPlayer.canCarryItem(itemName, count) then inventory.removeItem(itemName, count) xPlayer.addInventoryItem(itemName, count) - TriggerClientEvent('esx:showNotification', _source, _U('have_withdrawn', count, item.label)) + xPlayer.showNotification(_U('have_withdrawn', count, item.label)) + else + xPlayer.showNotification(_U('player_cannot_hold')) end else - TriggerClientEvent('esx:showNotification', _source, _U('not_enough_in_society')) + xPlayer.showNotification(_U('not_enough_in_society')) end end) end) @@ -185,9 +184,9 @@ AddEventHandler('esx_vehicleshop:putStockItems', function(itemName, count) if item.count >= 0 then xPlayer.removeInventoryItem(itemName, count) inventory.addItem(itemName, count) - TriggerClientEvent('esx:showNotification', _source, _U('have_deposited', count, item.label)) + xPlayer.showNotification(_U('have_deposited', count, item.label)) else - TriggerClientEvent('esx:showNotification', _source, _U('invalid_amount')) + xPlayer.showNotification(_U('invalid_amount')) end end) end) @@ -280,7 +279,7 @@ AddEventHandler('esx_vehicleshop:returnProvider', function(vehicleModel) ['@id'] = id }) - TriggerClientEvent('esx:showNotification', _source, _U('vehicle_sold_for', vehicleModel, ESX.Math.GroupDigits(price))) + xPlayer.showNotification(_U('vehicle_sold_for', vehicleModel, ESX.Math.GroupDigits(price))) else print(('esx_vehicleshop: %s attempted selling an invalid vehicle!'):format(GetPlayerIdentifiers(_source)[1])) end @@ -462,7 +461,7 @@ function PayRent(d, h, m) if xPlayer then -- message player if connected xPlayer.removeAccountMoney('bank', result[i].rent_price) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('paid_rental', ESX.Math.GroupDigits(result[i].rent_price))) + xPlayer.showNotification(_U('paid_rental', ESX.Math.GroupDigits(result[i].rent_price))) else -- pay rent by updating SQL MySQL.Sync.execute('UPDATE users SET bank = bank - @bank WHERE identifier = @identifier', { ['@bank'] = result[i].rent_price, From ea4dace2326246dbf0d1139850b516fb9fc00611 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Tue, 12 Nov 2019 21:01:26 +0100 Subject: [PATCH 2304/3224] New ESX support --- server/main.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/main.lua b/server/main.lua index 772fbb3a..dc403f25 100644 --- a/server/main.lua +++ b/server/main.lua @@ -37,7 +37,7 @@ ESX.RegisterServerCallback('esx_weaponshop:buyLicense', function(source, cb) cb(true) end) else - TriggerClientEvent('esx:showNotification', source, _U('not_enough')) + xPlayer.showNotification(_U('not_enough')) cb(false) end end) @@ -51,7 +51,7 @@ ESX.RegisterServerCallback('esx_weaponshop:buyWeapon', function(source, cb, weap cb(false) else if xPlayer.hasWeapon(weaponName) then - TriggerClientEvent('esx:showNotification', source, _U('already_owned')) + xPlayer.showNotification(_U('already_owned')) cb(false) else if zone == 'BlackWeashop' then @@ -61,7 +61,7 @@ ESX.RegisterServerCallback('esx_weaponshop:buyWeapon', function(source, cb, weap cb(true) else - TriggerClientEvent('esx:showNotification', source, _U('not_enough_black')) + xPlayer.showNotification(_U('not_enough_black')) cb(false) end else @@ -71,7 +71,7 @@ ESX.RegisterServerCallback('esx_weaponshop:buyWeapon', function(source, cb, weap cb(true) else - TriggerClientEvent('esx:showNotification', source, _U('not_enough')) + xPlayer.showNotification(_U('not_enough')) cb(false) end end From 3eb220ad5ac47a36af2cde5c066f02ba20e93633 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Tue, 12 Nov 2019 21:36:12 +0100 Subject: [PATCH 2305/3224] Removed unused variable --- server/main.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 9660dd18..6b9a2bb5 100644 --- a/server/main.lua +++ b/server/main.lua @@ -31,7 +31,6 @@ RegisterServerEvent('esx_shops:buyItem') AddEventHandler('esx_shops:buyItem', function(itemName, amount, zone) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) - local sourceItem = xPlayer.getInventoryItem(itemName) amount = ESX.Math.Round(amount) From 2f8df295b48a541d6042b95d43ddca8c570f3582 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Wed, 13 Nov 2019 16:39:28 +0100 Subject: [PATCH 2306/3224] Add support for new ESX weight system --- server/main.lua | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/server/main.lua b/server/main.lua index ff8ec2a6..ab64c9f0 100644 --- a/server/main.lua +++ b/server/main.lua @@ -38,10 +38,10 @@ AddEventHandler('esx_taxijob:success', function() xPlayer.addMoney(playerMoney) societyAccount.addMoney(societyMoney) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('comp_earned', societyMoney, playerMoney)) + xPlayer.showNotification(_U('comp_earned', societyMoney, playerMoney)) else xPlayer.addMoney(total) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('have_earned', total)) + xPlayer.showNotification(_U('have_earned', total)) end end) @@ -57,21 +57,20 @@ AddEventHandler('esx_taxijob:getStockItem', function(itemName, count) TriggerEvent('esx_addoninventory:getSharedInventory', 'society_taxi', function(inventory) local item = inventory.getItem(itemName) - local sourceItem = xPlayer.getInventoryItem(itemName) -- is there enough in the society? if count > 0 and item.count >= count then -- can the player carry the said amount of x item? - if sourceItem.limit ~= -1 and (sourceItem.count + count) > sourceItem.limit then - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('player_cannot_hold')) - else + if xPlayer.canCarryItem(itemName, count) then inventory.removeItem(itemName, count) xPlayer.addInventoryItem(itemName, count) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('have_withdrawn', count, item.label)) + xPlayer.showNotification(_U('have_withdrawn', count, item.label)) + else + xPlayer.showNotification(_U('player_cannot_hold')) end else - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('quantity_invalid')) + xPlayer.showNotification(_U('quantity_invalid')) end end) end) @@ -97,9 +96,9 @@ AddEventHandler('esx_taxijob:putStockItems', function(itemName, count) if item.count >= 0 then xPlayer.removeInventoryItem(itemName, count) inventory.addItem(itemName, count) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('have_deposited', count, item.label)) + xPlayer.showNotification(_U('have_deposited', count, item.label)) else - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('quantity_invalid')) + xPlayer.showNotification(_U('quantity_invalid')) end end) From 0d4833d1d772c25acf21d2e05452c9f698e6fdf1 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Wed, 13 Nov 2019 16:52:17 +0100 Subject: [PATCH 2307/3224] Support for new ESX --- server/main.lua | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/server/main.lua b/server/main.lua index ad8b4f1a..62ec3046 100644 --- a/server/main.lua +++ b/server/main.lua @@ -76,9 +76,9 @@ AddEventHandler('esx_society:withdrawMoney', function(society, amount) account.removeMoney(amount) xPlayer.addMoney(amount) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('have_withdrawn', ESX.Math.GroupDigits(amount))) + xPlayer.showNotification(_U('have_withdrawn', ESX.Math.GroupDigits(amount))) else - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('invalid_amount')) + xPlayer.showNotification(_U('invalid_amount')) end end) end) @@ -100,9 +100,9 @@ AddEventHandler('esx_society:depositMoney', function(society, amount) account.addMoney(amount) end) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('have_deposited', ESX.Math.GroupDigits(amount))) + xPlayer.showNotification(_U('have_deposited', ESX.Math.GroupDigits(amount))) else - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('invalid_amount')) + xPlayer.showNotification(_U('invalid_amount')) end end) @@ -125,10 +125,10 @@ AddEventHandler('esx_society:washMoney', function(society, amount) ['@society'] = society, ['@amount'] = amount }, function(rowsChanged) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('you_have', ESX.Math.GroupDigits(amount))) + xPlayer.showNotification(_U('you_have', ESX.Math.GroupDigits(amount))) end) else - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('invalid_amount')) + xPlayer.showNotification(_U('invalid_amount')) end end) @@ -253,11 +253,11 @@ ESX.RegisterServerCallback('esx_society:setJob', function(source, cb, identifier xTarget.setJob(job, grade) if type == 'hire' then - TriggerClientEvent('esx:showNotification', xTarget.source, _U('you_have_been_hired', job)) + xPlayer.showNotification(_U('you_have_been_hired', job)) elseif type == 'promote' then - TriggerClientEvent('esx:showNotification', xTarget.source, _U('you_have_been_promoted')) + xPlayer.showNotification(_U('you_have_been_promoted')) elseif type == 'fire' then - TriggerClientEvent('esx:showNotification', xTarget.source, _U('you_have_been_fired', xTarget.getJob().label)) + xPlayer.showNotification(_U('you_have_been_fired', xTarget.getJob().label)) end cb() @@ -364,7 +364,7 @@ function WashMoneyCRON(d, h, m) -- send notification if player is online if xPlayer then - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('you_have_laundered', ESX.Math.GroupDigits(result[i].amount))) + xPlayer.showNotification(_U('you_have_laundered', ESX.Math.GroupDigits(result[i].amount))) end MySQL.Async.execute('DELETE FROM society_moneywash WHERE id = @id', { From 935f54c8e3b651b9cf193fa15414371e9de1103b Mon Sep 17 00:00:00 2001 From: rex2630 Date: Wed, 13 Nov 2019 16:57:03 +0100 Subject: [PATCH 2308/3224] Support for new ESX --- server/main.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/main.lua b/server/main.lua index cded8b57..b383a65b 100644 --- a/server/main.lua +++ b/server/main.lua @@ -26,9 +26,9 @@ local function Work(source, item) end if item[i].name ~= _U('delivery') and itemQtty >= item[i].max then - TriggerClientEvent('esx:showNotification', source, _U('max_limit', item[i].name)) + xPlayer.showNotification(_U('max_limit', item[i].name)) elseif item[i].requires ~= "nothing" and requiredItemQtty <= 0 then - TriggerClientEvent('esx:showNotification', source, _U('not_enough', item[1].requires_name)) + xPlayer.showNotification(_U('not_enough', item[1].requires_name)) else if item[i].name ~= _U('delivery') then -- Chances to drop the item @@ -84,7 +84,7 @@ AddEventHandler('esx_jobs:caution', function(cautionType, cautionAmount, spawnPo account.addMoney(cautionAmount) end) - TriggerClientEvent('esx:showNotification', source, _U('bank_deposit_taken', ESX.Math.GroupDigits(cautionAmount))) + xPlayer.showNotification(_U('bank_deposit_taken', ESX.Math.GroupDigits(cautionAmount))) TriggerClientEvent('esx_jobs:spawnJobVehicle', source, spawnPoint, vehicle) elseif cautionType == "give_back" then @@ -99,7 +99,7 @@ AddEventHandler('esx_jobs:caution', function(cautionType, cautionAmount, spawnPo xPlayer.addAccountMoney('bank', toGive) account.removeMoney(toGive) - TriggerClientEvent('esx:showNotification', source, _U('bank_deposit_returned', ESX.Math.GroupDigits(toGive))) + xPlayer.showNotification(_U('bank_deposit_returned', ESX.Math.GroupDigits(toGive))) end) end end) From 0e5497b91483373174be401874b0950dc73ca687 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Wed, 13 Nov 2019 21:31:49 +0100 Subject: [PATCH 2309/3224] Added Czech locale (#83) * Czech file lang added * Added czech language * Fix --- __resource.lua | 2 ++ locales/cs.lua | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 locales/cs.lua diff --git a/__resource.lua b/__resource.lua index 69f31ce0..a0ea656d 100644 --- a/__resource.lua +++ b/__resource.lua @@ -12,6 +12,7 @@ server_scripts { 'locales/fr.lua', 'locales/sv.lua', 'locales/pl.lua', + 'locales/cs.lua', 'config.lua', 'server/main.lua' } @@ -23,6 +24,7 @@ client_scripts { 'locales/fr.lua', 'locales/sv.lua', 'locales/pl.lua', + 'locales/cs.lua', 'config.lua', 'client/main.lua' } diff --git a/locales/cs.lua b/locales/cs.lua new file mode 100644 index 00000000..46eb10a9 --- /dev/null +++ b/locales/cs.lua @@ -0,0 +1,37 @@ +Locales['cs'] = { + ['actions'] = 'akce', + ['boss_menu'] = 'akce šéfa', + ['money_generic'] = '$%s', + ['deposit_amount'] = 'množství vkladu', + ['deposit_society_money'] = 'vložit peníze do společnosti', + ['do_you_want_to_recruit'] = 'chceš najmout %s?', + ['employee'] = 'zaměstnanec', + ['employee_list'] = 'seznam zaměstnanců', + ['employee_management'] = 'správa zaměstnanců', + ['fire'] = 'vyhodit', + ['grade'] = 'povýšit', + ['have_deposited'] = 'vložil jsi ~r~$%s~s~', + ['have_withdrawn'] = 'vybral jsi ~g~$%s~s~', + ['invalid_amount'] = 'neplatná částka', + ['invalid_amount_max'] = 'tento plat není povolen', + ['no'] = 'ne', + ['promote'] = 'povýšit', + ['promote_employee'] = 'povýšit %s', + ['recruit'] = 'najmout', + ['recruiting'] = 'najímání', + ['salary_amount'] = 'váše platu', + ['salary_management'] = 'správa platů', + ['wash_money'] = 'vyprat peníze', + ['wash_money_amount'] = 'množství na vyprání', + ['withdraw_amount'] = 'výběr peněz', + ['withdraw_society_money'] = 'vybrat peníze společnosti', + ['yes'] = 'ano', + ['you_have'] = 'máš ~g~$%s~s~ čekajících na vyprání~s~ (24h).', + ['you_have_laundered'] = '~r~Vypral jsi~s~ tvé peníze: ~g~$%s~s~', + ['you_have_hired'] = 'najmul jsi %s', + ['you_have_been_hired'] = 'byl jsi najmut hráčem %s', + ['you_have_fired'] = 'vyhodil jsi %s', + ['you_have_been_fired'] = 'byl jsi vyhozen hráčem %s', + ['you_have_promoted'] = 'byl jsi povýšen hráčem %s na %s', + ['you_have_been_promoted'] = 'byl jsi ~b~povýšen~s~!', +} From 08000e4afbe41cbbd691b2fd061accde466af46a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 13 Nov 2019 21:40:49 +0100 Subject: [PATCH 2310/3224] Fixed xPlayer notification mistake, rewrote statements --- server/main.lua | 87 +++++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 46 deletions(-) diff --git a/server/main.lua b/server/main.lua index 62ec3046..4cb443e4 100644 --- a/server/main.lua +++ b/server/main.lua @@ -36,7 +36,7 @@ AddEventHandler('esx_society:registerSociety', function(name, label, account, da account = account, datastore = datastore, inventory = inventory, - data = data, + data = data } for i=1, #RegisteredSocieties, 1 do @@ -66,21 +66,20 @@ AddEventHandler('esx_society:withdrawMoney', function(society, amount) local society = GetSociety(society) amount = ESX.Math.Round(tonumber(amount)) - if xPlayer.job.name ~= society.name then + if xPlayer.job.name == society.name then + TriggerEvent('esx_addonaccount:getSharedAccount', society.account, function(account) + if amount > 0 and account.money >= amount then + account.removeMoney(amount) + xPlayer.addMoney(amount) + + xPlayer.showNotification(_U('have_withdrawn', ESX.Math.GroupDigits(amount))) + else + xPlayer.showNotification(_U('invalid_amount')) + end + end) + else print(('esx_society: %s attempted to call withdrawMoney!'):format(xPlayer.identifier)) - return end - - TriggerEvent('esx_addonaccount:getSharedAccount', society.account, function(account) - if amount > 0 and account.money >= amount then - account.removeMoney(amount) - xPlayer.addMoney(amount) - - xPlayer.showNotification(_U('have_withdrawn', ESX.Math.GroupDigits(amount))) - else - xPlayer.showNotification(_U('invalid_amount')) - end - end) end) RegisterServerEvent('esx_society:depositMoney') @@ -89,20 +88,19 @@ AddEventHandler('esx_society:depositMoney', function(society, amount) local society = GetSociety(society) amount = ESX.Math.Round(tonumber(amount)) - if xPlayer.job.name ~= society.name then - print(('esx_society: %s attempted to call depositMoney!'):format(xPlayer.identifier)) - return - end + if xPlayer.job.name == society.name then + if amount > 0 and xPlayer.getMoney() >= amount then + TriggerEvent('esx_addonaccount:getSharedAccount', society.account, function(account) + xPlayer.removeMoney(amount) + account.addMoney(amount) + end) - if amount > 0 and xPlayer.getMoney() >= amount then - TriggerEvent('esx_addonaccount:getSharedAccount', society.account, function(account) - xPlayer.removeMoney(amount) - account.addMoney(amount) - end) - - xPlayer.showNotification(_U('have_deposited', ESX.Math.GroupDigits(amount))) + xPlayer.showNotification(_U('have_deposited', ESX.Math.GroupDigits(amount))) + else + xPlayer.showNotification(_U('invalid_amount')) + end else - xPlayer.showNotification(_U('invalid_amount')) + print(('esx_society: %s attempted to call depositMoney!'):format(xPlayer.identifier)) end end) @@ -112,25 +110,23 @@ AddEventHandler('esx_society:washMoney', function(society, amount) local account = xPlayer.getAccount('black_money') amount = ESX.Math.Round(tonumber(amount)) - if xPlayer.job.name ~= society then - print(('esx_society: %s attempted to call washMoney!'):format(xPlayer.identifier)) - return - end + if xPlayer.job.name == society then + if amount and amount > 0 and account.money >= amount then + xPlayer.removeAccountMoney('black_money', 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) - xPlayer.showNotification(_U('you_have', ESX.Math.GroupDigits(amount))) - end) + MySQL.Async.execute('INSERT INTO society_moneywash (identifier, society, amount) VALUES (@identifier, @society, @amount)', { + ['@identifier'] = xPlayer.identifier, + ['@society'] = society, + ['@amount'] = amount + }, function(rowsChanged) + xPlayer.showNotification(_U('you_have', ESX.Math.GroupDigits(amount))) + end) + else + xPlayer.showNotification(_U('invalid_amount')) + end else - xPlayer.showNotification(_U('invalid_amount')) + print(('esx_society: %s attempted to call washMoney!'):format(xPlayer.identifier)) end - end) RegisterServerEvent('esx_society:putVehicleInGarage') @@ -241,7 +237,6 @@ ESX.RegisterServerCallback('esx_society:getJob', function(source, cb, society) cb(job) end) - ESX.RegisterServerCallback('esx_society:setJob', function(source, cb, identifier, job, grade, type) local xPlayer = ESX.GetPlayerFromId(source) local isBoss = xPlayer.job.grade_name == 'boss' @@ -253,11 +248,11 @@ ESX.RegisterServerCallback('esx_society:setJob', function(source, cb, identifier xTarget.setJob(job, grade) if type == 'hire' then - xPlayer.showNotification(_U('you_have_been_hired', job)) + xTarget.showNotification(_U('you_have_been_hired', job)) elseif type == 'promote' then - xPlayer.showNotification(_U('you_have_been_promoted')) + xTarget.showNotification(_U('you_have_been_promoted')) elseif type == 'fire' then - xPlayer.showNotification(_U('you_have_been_fired', xTarget.getJob().label)) + xTarget.showNotification(_U('you_have_been_fired', xTarget.getJob().label)) end cb() From e8f98e03ebfc07319d3b677abc5fc6b7ff56389c Mon Sep 17 00:00:00 2001 From: Poggu <45881722+Poggicek@users.noreply.github.com> Date: Wed, 13 Nov 2019 21:46:48 +0100 Subject: [PATCH 2311/3224] Add support for new ESX weight system (#63) * Added weight support * Update main.lua * Removed unused variable --- config.lua | 2 +- esx_mechanicjob.sql | 12 ++++++------ localization/en_esx_mecanojob.sql | 12 ++++++------ localization/fi_esx_mecanojob.sql | 12 ++++++------ localization/pl_esx_mecanojob.sql | 12 ++++++------ localization/sv_esx_mecanojob.sql | 12 ++++++------ server/main.lua | 15 +++++++-------- 7 files changed, 38 insertions(+), 39 deletions(-) diff --git a/config.lua b/config.lua index d048056c..9e716a49 100644 --- a/config.lua +++ b/config.lua @@ -112,4 +112,4 @@ for k,v in ipairs(Config.Towables) do Color = { r = 204, g = 204, b = 0 }, Type = -1 } -end +end \ No newline at end of file diff --git a/esx_mechanicjob.sql b/esx_mechanicjob.sql index fc98ce84..651cab5e 100644 --- a/esx_mechanicjob.sql +++ b/esx_mechanicjob.sql @@ -20,11 +20,11 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ('mechanic',4,'boss','Patron',0,'{}','{}') ; -INSERT INTO `items` (name, label, `limit`) VALUES - ('gazbottle', 'bouteille de gaz', 11), - ('fixtool', 'outils réparation', 6), - ('carotool', 'outils carosserie', 4), - ('blowpipe', 'Chalumeaux', 10), - ('fixkit', 'Kit réparation', 5), +INSERT INTO `items` (name, label, weight) VALUES + ('gazbottle', 'bouteille de gaz', 2), + ('fixtool', 'outils réparation', 2), + ('carotool', 'outils carosserie', 2), + ('blowpipe', 'Chalumeaux', 2), + ('fixkit', 'Kit réparation', 3), ('carokit', 'Kit carosserie', 3) ; diff --git a/localization/en_esx_mecanojob.sql b/localization/en_esx_mecanojob.sql index 524338fc..038e2bf6 100644 --- a/localization/en_esx_mecanojob.sql +++ b/localization/en_esx_mecanojob.sql @@ -20,11 +20,11 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ('mechanic',4,'boss','Boss',0,'{}','{}') ; -INSERT INTO `items` (name, label, `limit`) VALUES - ('gazbottle', 'Gas Bottle', 11), - ('fixtool', 'Repair Tools', 6), - ('carotool', 'Tools', 4), - ('blowpipe', 'Blowtorch', 10), - ('fixkit', 'Repair Kit', 5), +INSERT INTO `items` (name, label, weight) VALUES + ('gazbottle', 'Gas Bottle', 2), + ('fixtool', 'Repair Tools', 2), + ('carotool', 'Tools', 2), + ('blowpipe', 'Blowtorch', 2), + ('fixkit', 'Repair Kit', 3), ('carokit', 'Body Kit', 3) ; diff --git a/localization/fi_esx_mecanojob.sql b/localization/fi_esx_mecanojob.sql index 66e013f3..c3dadaa5 100644 --- a/localization/fi_esx_mecanojob.sql +++ b/localization/fi_esx_mecanojob.sql @@ -20,11 +20,11 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ('mechanic',4,'boss','Pomo',0,'{}','{}') ; -INSERT INTO `items` (name, label, `limit`) VALUES - ('gazbottle', 'Kaasupullo', 11), - ('fixtool', 'Korjaustyökalut', 6), - ('carotool', 'Työkalut', 4), - ('blowpipe', 'Polttoleikkuri', 10), - ('fixkit', 'Korjauskitti', 5), +INSERT INTO `items` (name, label, weight) VALUES + ('gazbottle', 'Kaasupullo', 2), + ('fixtool', 'Korjaustyökalut', 2), + ('carotool', 'Työkalut', 2), + ('blowpipe', 'Polttoleikkuri', 2), + ('fixkit', 'Korjauskitti', 3), ('carokit', 'Korikitti', 3) ; diff --git a/localization/pl_esx_mecanojob.sql b/localization/pl_esx_mecanojob.sql index a58b4bbf..b741fb45 100644 --- a/localization/pl_esx_mecanojob.sql +++ b/localization/pl_esx_mecanojob.sql @@ -20,11 +20,11 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ('mechanic',4,'boss','Szef',0,'{}','{}') ; -INSERT INTO `items` (name, label, `limit`) VALUES - ('gazbottle', 'Butelka z gazem', 11), - ('fixtool', 'Zestaw do naprawy', 6), - ('carotool', 'Częsci naprawcze', 4), - ('blowpipe', 'Palnik', 10), - ('fixkit', 'Narzedzia naprawcze', 5), +INSERT INTO `items` (name, label, weight) VALUES + ('gazbottle', 'Butelka z gazem', 2), + ('fixtool', 'Zestaw do naprawy', 2), + ('carotool', 'Częsci naprawcze', 2), + ('blowpipe', 'Palnik', 2), + ('fixkit', 'Narzedzia naprawcze', 3), ('carokit', 'Części blacharskie', 3) ; diff --git a/localization/sv_esx_mecanojob.sql b/localization/sv_esx_mecanojob.sql index a4d3bd69..181d3ad7 100644 --- a/localization/sv_esx_mecanojob.sql +++ b/localization/sv_esx_mecanojob.sql @@ -20,11 +20,11 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ('mechanic',4,'boss','Ägare',0,'{}','{}') ; -INSERT INTO `items` (name, label, `limit`) VALUES - ('gazbottle', 'Gas Flaska', 11), - ('fixtool', 'Reparationsverktyg', 6), - ('carotool', 'Verktyg', 4), - ('blowpipe', 'Blåslampa', 10), - ('fixkit', 'Reparationssats', 5), +INSERT INTO `items` (name, label, weight) VALUES + ('gazbottle', 'Gas Flaska', 2), + ('fixtool', 'Reparationsverktyg', 2), + ('carotool', 'Verktyg', 2), + ('blowpipe', 'Blåslampa', 2), + ('fixkit', 'Reparationssats', 3), ('carokit', 'Karosskit', 3) ; diff --git a/server/main.lua b/server/main.lua index 5c18d441..604eb082 100644 --- a/server/main.lua +++ b/server/main.lua @@ -262,21 +262,20 @@ AddEventHandler('esx_mechanicjob:getStockItem', function(itemName, count) TriggerEvent('esx_addoninventory:getSharedInventory', 'society_mechanic', function(inventory) local item = inventory.getItem(itemName) - local sourceItem = xPlayer.getInventoryItem(itemName) -- is there enough in the society? if count > 0 and item.count >= count then -- can the player carry the said amount of x item? - if sourceItem.limit ~= -1 and (sourceItem.count + count) > sourceItem.limit then - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('player_cannot_hold')) - else + if xPlayer.canCarryItem(itemName, count) then inventory.removeItem(itemName, count) xPlayer.addInventoryItem(itemName, count) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('have_withdrawn', count, item.label)) + xPlayer.showNotification(_U('have_withdrawn', count, item.label)) + else + xPlayer.showNotification(_U('player_cannot_hold')) end else - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('invalid_quantity')) + xPlayer.showNotification(_U('invalid_quantity')) end end) end) @@ -299,10 +298,10 @@ AddEventHandler('esx_mechanicjob:putStockItems', function(itemName, count) xPlayer.removeInventoryItem(itemName, count) inventory.addItem(itemName, count) else - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('invalid_quantity')) + xPlayer.showNotification(_U('invalid_quantity')) end - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('have_deposited', count, item.label)) + xPlayer.showNotification(_U('have_deposited', count, item.label)) end) end) From f32f44f5021e46f1013b783c1d2a2cfe675385c3 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 14 Nov 2019 21:25:16 +0100 Subject: [PATCH 2312/3224] Fixed trailing spaces, and commands.lua use apostrof --- server/commands.lua | 36 ++++++++++++++++++------------------ server/main.lua | 9 ++++----- server/paycheck.lua | 2 +- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/server/commands.lua b/server/commands.lua index 36617956..20044962 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -2,7 +2,7 @@ TriggerEvent('es:addGroupCommand', 'tp', 'admin', function(source, args, user) local x = tonumber(args[1]) local y = tonumber(args[2]) local z = tonumber(args[3]) - + if x and y and z then TriggerClientEvent('esx:teleport', source, { x = x, @@ -10,11 +10,11 @@ TriggerEvent('es:addGroupCommand', 'tp', 'admin', function(source, args, user) z = z }) else - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Invalid coordinates!") + TriggerClientEvent('chatMessage', source, 'SYSTEM', {255, 0, 0}, 'Invalid coordinates!') end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = "Teleport to coordinates", params = {{name = "x", help = "X coords"}, {name = "y", help = "Y coords"}, {name = "z", help = "Z coords"}}}) +end, {help = 'Teleport to coordinates', params = {{name = 'x', help = 'X coords'}, {name = 'y', help = 'Y coords'}, {name = 'z', help = 'Z coords'}}}) TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, user) if tonumber(args[1]) and args[2] and tonumber(args[3]) then @@ -35,7 +35,7 @@ TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('setjob'), params = {{name = "id", help = _U('id_param')}, {name = "job", help = _U('setjob_param2')}, {name = "grade_id", help = _U('setjob_param3')}}}) +end, {help = _U('setjob'), params = {{name = 'id', help = _U('id_param')}, {name = 'job', help = _U('setjob_param2')}, {name = 'grade_id', help = _U('setjob_param3')}}}) TriggerEvent('es:addGroupCommand', 'loadipl', 'admin', function(source, args, user) TriggerClientEvent('esx:loadIPL', -1, args[1]) @@ -65,7 +65,7 @@ TriggerEvent('es:addGroupCommand', 'car', 'admin', function(source, args, user) TriggerClientEvent('esx:spawnVehicle', source, args[1]) end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('spawn_car'), params = {{name = "car", help = _U('spawn_car_param')}}}) +end, {help = _U('spawn_car'), params = {{name = 'car', help = _U('spawn_car_param')}}}) TriggerEvent('es:addGroupCommand', 'cardel', 'admin', function(source, args, user) TriggerClientEvent('esx:deleteVehicle', source) @@ -83,20 +83,20 @@ TriggerEvent('es:addGroupCommand', 'spawnped', 'admin', function(source, args, u TriggerClientEvent('esx:spawnPed', source, args[1]) end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('spawn_ped'), params = {{name = "name", help = _U('spawn_ped_param')}}}) +end, {help = _U('spawn_ped'), params = {{name = 'name', help = _U('spawn_ped_param')}}}) TriggerEvent('es:addGroupCommand', 'spawnobject', 'admin', function(source, args, user) TriggerClientEvent('esx:spawnObject', source, args[1]) end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('spawn_object'), params = {{name = "name"}}}) +end, {help = _U('spawn_object'), params = {{name = 'name'}}}) TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, user) local _source = source local target = tonumber(args[1]) local money_type = args[2] local money_amount = tonumber(args[3]) - + local xPlayer = ESX.GetPlayerFromId(target) if target and money_type and money_amount and xPlayer ~= nil then @@ -107,22 +107,22 @@ TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, u elseif money_type == 'black' then xPlayer.setAccountMoney('black_money', money_amount) else - TriggerClientEvent('chatMessage', _source, "SYSTEM", {255, 0, 0}, "^2" .. money_type .. " ^0 is not a valid money type!") + TriggerClientEvent('chatMessage', _source, 'SYSTEM', {255, 0, 0}, '^2' .. money_type .. ' ^0 is not a valid money type!') return end else - TriggerClientEvent('chatMessage', _source, "SYSTEM", {255, 0, 0}, "Invalid arguments.") + TriggerClientEvent('chatMessage', _source, 'SYSTEM', {255, 0, 0}, 'Invalid arguments.') return end - + print('es_extended: ' .. GetPlayerName(source) .. ' just set $' .. money_amount .. ' (' .. money_type .. ') to ' .. xPlayer.name) - + if xPlayer.source ~= _source then TriggerClientEvent('esx:showNotification', xPlayer.source, _U('money_set', money_amount, money_type)) end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('setmoney'), params = {{name = "id", help = _U('id_param')}, {name = "money type", help = _U('money_type')}, {name = "amount", help = _U('money_amount')}}}) +end, {help = _U('setmoney'), params = {{name = 'id', help = _U('id_param')}, {name = 'money type', help = _U('money_type')}, {name = 'amount', help = _U('money_amount')}}}) TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, args, user) local _source = source @@ -141,7 +141,7 @@ TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('giveaccountmoney'), params = {{name = "id", help = _U('id_param')}, {name = "account", help = _U('account')}, {name = "amount", help = _U('money_amount')}}}) +end, {help = _U('giveaccountmoney'), params = {{name = 'id', help = _U('id_param')}, {name = 'account', help = _U('account')}, {name = 'amount', help = _U('money_amount')}}}) TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, user) local _source = source @@ -160,7 +160,7 @@ TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, u end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('giveitem'), params = {{name = "id", help = _U('id_param')}, {name = "item", help = _U('item')}, {name = "amount", help = _U('amount')}}}) +end, {help = _U('giveitem'), params = {{name = 'id', help = _U('id_param')}, {name = 'item', help = _U('item')}, {name = 'amount', help = _U('amount')}}}) TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, user) local xPlayer = ESX.GetPlayerFromId(args[1]) @@ -169,7 +169,7 @@ TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, xPlayer.addWeapon(weaponName, tonumber(args[3])) end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('giveweapon'), params = {{name = "id", help = _U('id_param')}, {name = "weapon", help = _U('weapon')}, {name = "ammo", help = _U('amountammo')}}}) +end, {help = _U('giveweapon'), params = {{name = 'id', help = _U('id_param')}, {name = 'weapon', help = _U('weapon')}, {name = 'ammo', help = _U('amountammo')}}}) TriggerEvent('es:addGroupCommand', 'disc', 'admin', function(source, args, user) DropPlayer(source, 'You have been disconnected') @@ -228,7 +228,7 @@ TriggerEvent('es:addGroupCommand', 'clearinventory', 'admin', function(source, a end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('command_clearinventory'), params = {{name = "playerId", help = _U('command_playerid_param')}}}) +end, {help = _U('command_clearinventory'), params = {{name = 'playerId', help = _U('command_playerid_param')}}}) TriggerEvent('es:addGroupCommand', 'clearloadout', 'admin', function(source, args, user) local xPlayer @@ -249,4 +249,4 @@ TriggerEvent('es:addGroupCommand', 'clearloadout', 'admin', function(source, arg end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('command_clearloadout'), params = {{name = "playerId", help = _U('command_playerid_param')}}}) +end, {help = _U('command_clearloadout'), params = {{name = 'playerId', help = _U('command_playerid_param')}}}) diff --git a/server/main.lua b/server/main.lua index 5b61ae49..bf0eeaeb 100644 --- a/server/main.lua +++ b/server/main.lua @@ -152,7 +152,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) if gradeObject.skin_male ~= nil then userData.job.skin_male = json.decode(gradeObject.skin_male) end - + if gradeObject.skin_female ~= nil then userData.job.skin_female = json.decode(gradeObject.skin_female) end @@ -167,12 +167,12 @@ AddEventHandler('es:playerLoaded', function(source, _player) 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 = {} end @@ -207,7 +207,6 @@ AddEventHandler('es:playerLoaded', function(source, _player) xPlayer.getMissingAccounts(function(missingAccounts) if #missingAccounts > 0 then - for i=1, #missingAccounts, 1 do table.insert(xPlayer.accounts, { name = missingAccounts[i], @@ -282,7 +281,7 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo if targetXPlayer.canCarryItem(itemName, itemCount) then sourceXPlayer.removeInventoryItem(itemName, itemCount) targetXPlayer.addInventoryItem (itemName, itemCount) - + sourceXPlayer.showNotification(_U('gave_item', itemCount, sourceItem.label, targetXPlayer.name)) targetXPlayer.showNotification(_U('received_item', itemCount, sourceItem.label, sourceXPlayer.name)) else diff --git a/server/paycheck.lua b/server/paycheck.lua index 04719d3b..8df7bf95 100644 --- a/server/paycheck.lua +++ b/server/paycheck.lua @@ -19,7 +19,7 @@ ESX.StartPayCheck = function() if account.money >= salary then -- does the society money to pay its employees? xPlayer.addAccountMoney('bank', salary) account.removeMoney(salary) - + TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('received_paycheck'), _U('received_salary', salary), 'CHAR_BANK_MAZE', 9) else TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), '', _U('company_nomoney'), 'CHAR_BANK_MAZE', 1) From aa1ad0a1e8feba8236e3436c308f1b8500ac95a0 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 14 Nov 2019 22:26:13 +0100 Subject: [PATCH 2313/3224] Minor code improvements --- server/functions.lua | 21 +++++++++--------- server/main.lua | 51 +++++++++++++++++--------------------------- 2 files changed, 30 insertions(+), 42 deletions(-) diff --git a/server/functions.lua b/server/functions.lua index 3ab80291..07fa9501 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -41,36 +41,36 @@ ESX.SavePlayer = function(xPlayer, cb) xPlayer.setLastPosition(xPlayer.getCoords()) -- User accounts - for i=1, #xPlayer.accounts, 1 do - if ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] ~= xPlayer.accounts[i].money then + for k,v in ipairs(xPlayer.accounts) do + if ESX.LastPlayerData[xPlayer.source].accounts[v.name] ~= v.money then table.insert(asyncTasks, function(cb) MySQL.Async.execute('UPDATE user_accounts SET money = @money WHERE identifier = @identifier AND name = @name', { - ['@money'] = xPlayer.accounts[i].money, + ['@money'] = v.money, ['@identifier'] = xPlayer.identifier, - ['@name'] = xPlayer.accounts[i].name + ['@name'] = v.name }, function(rowsChanged) cb() end) end) - ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] = xPlayer.accounts[i].money + ESX.LastPlayerData[xPlayer.source].accounts[v.name] = v.money end end -- Inventory items - for i=1, #xPlayer.inventory, 1 do - if ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] ~= xPlayer.inventory[i].count then + for k,v in ipairs(xPlayer.inventory) do + if ESX.LastPlayerData[xPlayer.source].items[v.name] ~= v.count then table.insert(asyncTasks, function(cb) MySQL.Async.execute('UPDATE user_inventory SET count = @count WHERE identifier = @identifier AND item = @item', { - ['@count'] = xPlayer.inventory[i].count, + ['@count'] = v.count, ['@identifier'] = xPlayer.identifier, - ['@item'] = xPlayer.inventory[i].name + ['@item'] = v.name }, function(rowsChanged) cb() end) end) - ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] = xPlayer.inventory[i].count + ESX.LastPlayerData[xPlayer.source].items[v.name] = v.count end end @@ -135,7 +135,6 @@ ESX.GetPlayers = function() return sources end - ESX.GetPlayerFromId = function(source) return ESX.Players[tonumber(source)] end diff --git a/server/main.lua b/server/main.lua index bf0eeaeb..946b4d1c 100644 --- a/server/main.lua +++ b/server/main.lua @@ -24,19 +24,16 @@ AddEventHandler('es:playerLoaded', function(source, _player) -- Get accounts table.insert(tasks, function(cb) - MySQL.Async.fetchAll('SELECT * FROM user_accounts WHERE identifier = @identifier', { + MySQL.Async.fetchAll('SELECT name, money FROM user_accounts WHERE identifier = @identifier', { ['@identifier'] = player.getIdentifier() }, function(accounts) - for i=1, #Config.Accounts, 1 do - for j=1, #accounts, 1 do - if accounts[j].name == Config.Accounts[i] then - table.insert(userData.accounts, { - name = accounts[j].name, - money = accounts[j].money, - label = Config.AccountLabels[accounts[j].name] - }) - break - end + for k,v in ipairs(accounts) do + if Config.Accounts[v.name] then + table.insert(userData.accounts, { + name = v.name, + money = v.money, + label = Config.AccountLabels[v.name] + }) end end @@ -50,12 +47,14 @@ AddEventHandler('es:playerLoaded', function(source, _player) MySQL.Async.fetchAll('SELECT item, count FROM user_inventory WHERE identifier = @identifier', { ['@identifier'] = player.getIdentifier() }, function(inventory) - local tasks2 = {} + local tasks2, foundItems = {}, {} for k,v in ipairs(inventory) do local item = ESX.Items[v.item] if item then + foundItems[v.item] = true + table.insert(userData.inventory, { name = v.item, count = v.count, @@ -70,25 +69,16 @@ AddEventHandler('es:playerLoaded', function(source, _player) end end - for k,v in pairs(ESX.Items) do - local found = false - - for j=1, #userData.inventory do - if userData.inventory[j].name == k then - found = true - break - end - end - - if not found then + for itemName,item in pairs(ESX.Items) do + if not foundItems[itemName] then table.insert(userData.inventory, { - name = k, + name = itemName, count = 0, - label = ESX.Items[k].label, - weight = ESX.Items[k].weight, - usable = ESX.UsableItemsCallbacks[k] ~= nil, - rare = ESX.Items[k].rare, - canRemove = ESX.Items[k].canRemove + label = item.label, + weight = item.weight, + usable = ESX.UsableItemsCallbacks[itemName] ~= nil, + rare = item.rare, + canRemove = item.canRemove }) local scope = function(item, identifier) @@ -103,9 +93,8 @@ AddEventHandler('es:playerLoaded', function(source, _player) end) end - scope(k, player.getIdentifier()) + scope(itemName, player.getIdentifier()) end - end Async.parallelLimit(tasks2, 5, function(results) end) From c7a30efdd1b1d245d9ac8c42512f1c4512c4b3fa Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 16 Nov 2019 17:41:41 +0100 Subject: [PATCH 2314/3224] Added ESX.Table.Set() function and fixed accounts not loading http://www.lua.org/pil/11.5.html --- common/modules/table.lua | 6 ++++++ server/main.lua | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/common/modules/table.lua b/common/modules/table.lua index ea7dad28..3741e01e 100644 --- a/common/modules/table.lua +++ b/common/modules/table.lua @@ -11,6 +11,12 @@ function ESX.Table.SizeOf(t) return count end +function ESX.Table.Set(t) + local set = {} + for k,v in ipairs(t) do set[v] = true end + return set +end + function ESX.Table.IndexOf(t, value) for i=1, #t, 1 do if t[i] == value then diff --git a/server/main.lua b/server/main.lua index 946b4d1c..689e8b35 100644 --- a/server/main.lua +++ b/server/main.lua @@ -27,8 +27,9 @@ AddEventHandler('es:playerLoaded', function(source, _player) MySQL.Async.fetchAll('SELECT name, money FROM user_accounts WHERE identifier = @identifier', { ['@identifier'] = player.getIdentifier() }, function(accounts) + local validAccounts = ESX.Table.Set(Config.Accounts) for k,v in ipairs(accounts) do - if Config.Accounts[v.name] then + if validAccounts[v.name] then table.insert(userData.accounts, { name = v.name, money = v.money, From 3aa7ada4827defde105114ffa0278a8b8935cd71 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 16 Nov 2019 18:26:36 +0100 Subject: [PATCH 2315/3224] Follow markdown standard --- README.md | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 06cbe1ba..1b15eacc 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ # es_extended + es_extended is a roleplay framework for FiveM. It is developed on top of EssentialMode (aka ES), thus commonly named ESX - the **Es**sentialMode E**x**tended framework for FiveM. -### Links & Read more +## Links & Read more + - [ESX Documentation](https://esx-org.github.io/) - [ESX Discord Community](https://discord.gg/MsWzPqE) - [FiveM Forum Thread](https://forum.fivem.net/t/release-esx-base/39881) @@ -11,7 +13,8 @@ es_extended is a roleplay framework for FiveM. It is developed on top of Essenti ![screenshot](http://i.imgur.com/aPFdJl3.jpg) -### Features +## Features + - Accounts (comes with bank / black money), you can add more accounts - Advanced inventory system (press `F2` ingame) - Job system @@ -20,7 +23,8 @@ es_extended is a roleplay framework for FiveM. It is developed on top of Essenti - i18n (locale) system - Plenty of plugins available -### Requirements +## Requirements + This order also applies in the startup order. - [mysql-async](https://github.com/brouznouf/fivem-mysql-async) @@ -28,9 +32,10 @@ This order also applies in the startup order. - [esplugin_mysql](https://github.com/kanersps/esplugin_mysql) - [async](https://github.com/ESX-Org/async) -### Download & Installation +## Download & Installation ### Using [fvm](https://github.com/qlaffont/fvm-installer) + ``` fvm install --save --folder=essential esx-org/es_extended fvm install --save --folder=esx esx-org/esx_menu_default @@ -49,6 +54,7 @@ git clone https://github.com/ESX-Org/esx_menu_list [esx]/[ui]/esx_menu_list ``` ### Manually + - Download https://github.com/ESX-Org/es_extended/releases/latest - Put it in the `resource/[essential]` directory - Download https://github.com/ESX-Org/esx_menu_default/releases/latest @@ -58,7 +64,8 @@ git clone https://github.com/ESX-Org/esx_menu_list [esx]/[ui]/esx_menu_list - Download https://github.com/ESX-Org/esx_menu_list/releases/latest - Put it in the `resource/[esx]/[ui]` directory -## Installation +### Installation + - Import `es_extended.sql` in your database - Configure your `server.cfg` to look like this @@ -73,8 +80,11 @@ start esx_menu_default start esx_menu_list start esx_menu_dialog ``` -# Legal + +## Legal + ### License + es_extended - EssentialMode Extended framework for FiveM Copyright (C) 2015-2019 Jérémie N'gadi From 92c5b103438138f6fb0066ae41ffcd54c868f9a1 Mon Sep 17 00:00:00 2001 From: Tinky <48660658+Tinky124@users.noreply.github.com> Date: Tue, 19 Nov 2019 20:46:01 +0100 Subject: [PATCH 2316/3224] Removed local keys --- client/main.lua | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/client/main.lua b/client/main.lua index a9101d0f..af8971f3 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,11 +1,4 @@ -local Keys = { - ["ESC"] = 322, ["BACKSPACE"] = 177, ["E"] = 38, ["ENTER"] = 18, ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173 -} - -local menuIsShowed = false -local hasAlreadyEnteredMarker = false -local isInMarker = false - +local menuIsShowed, hasAlreadyEnteredMarker, isInMarker = false, false, false ESX = nil Citizen.CreateThread(function() @@ -99,7 +92,7 @@ Citizen.CreateThread(function() while true do Citizen.Wait(0) - if IsControlJustReleased(0, Keys['E']) and isInMarker and not menuIsShowed then + if IsControlJustReleased(0, 38) and isInMarker and not menuIsShowed then ESX.UI.Menu.CloseAll() ShowJobListingMenu() end From 5c5dcf764348d45cc9dc1753f12c1811b38c50be Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 24 Nov 2019 18:05:16 +0100 Subject: [PATCH 2317/3224] Removed keys table --- client/main.lua | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/client/main.lua b/client/main.lua index 2bd89fd8..8d2ec4b5 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,15 +1,3 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - ESX = nil local HasAlreadyEnteredMarker = false local LastZone = nil @@ -223,7 +211,7 @@ Citizen.CreateThread(function() if CurrentAction ~= nil then ESX.ShowHelpNotification(CurrentActionMsg) - if IsControlJustReleased(0, Keys['E']) then + if IsControlJustReleased(0, 38) then if CurrentAction == 'shop_menu' then if Config.LicenseEnable and Config.Zones[CurrentActionData.zone].Legal then From b9ea9478c3714e7b7ab5437d31c131b10bd0a4a8 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 24 Nov 2019 18:06:28 +0100 Subject: [PATCH 2318/3224] Added Czech locale (#55) * Czech language support * Fix * Czech lang support --- __resource.lua | 4 +++- locales/cs.lua | 13 +++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 locales/cs.lua diff --git a/__resource.lua b/__resource.lua index a45e385f..0b512cd0 100644 --- a/__resource.lua +++ b/__resource.lua @@ -15,6 +15,7 @@ server_scripts { 'locales/es.lua', 'locales/pl.lua', 'locales/sv.lua', + 'locales/cs.lua', 'config.lua', 'server/main.lua' } @@ -29,8 +30,9 @@ client_scripts { 'locales/es.lua', 'locales/pl.lua', 'locales/sv.lua', + 'locales/cs.lua', 'config.lua', 'client/main.lua' } -dependency 'es_extended' \ No newline at end of file +dependency 'es_extended' diff --git a/locales/cs.lua b/locales/cs.lua new file mode 100644 index 00000000..a40074d5 --- /dev/null +++ b/locales/cs.lua @@ -0,0 +1,13 @@ +Locales ['cs'] = { + ['buy_license'] = 'zakoupit zbrojni prukaz?', + ['yes'] = '%s', + ['no'] = 'ne', + ['weapon_bought'] = 'zakoupeno za $%s', + ['not_enough_black'] = 'nemas dostatek spinavych penez', + ['not_enough'] = 'nemas dostatek penez', + ['already_owned'] = 'tuhle zbran jiz vlastnis!', + ['shop_menu_title'] = 'ammu-Nation', + ['shop_menu_prompt'] = 'stiskni ~INPUT_CONTEXT~ pro pristup do ~y~Ammu-Nationu~s~.', + ['shop_menu_item'] = '$%s', + ['map_blip'] = 'ammu-Nation', +} From 5a38d951e87d39993eabde2ca2c5d56b64dfdd68 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 7 Dec 2019 11:22:40 +0100 Subject: [PATCH 2319/3224] Initial code cleanup --- client/jobs/fisherman.lua | 34 +-- client/jobs/fueler.lua | 80 +++---- client/jobs/lumberjack.lua | 80 +++---- client/jobs/miner.lua | 128 +++++------ client/jobs/reporter.lua | 20 +- client/jobs/slaughterer.lua | 80 +++---- client/jobs/tailor.lua | 80 +++---- client/main.lua | 443 +++++++++++++----------------------- locales/en.lua | 2 +- server/main.lua | 10 +- 10 files changed, 421 insertions(+), 536 deletions(-) diff --git a/client/jobs/fisherman.lua b/client/jobs/fisherman.lua index 01cb8ca1..207bc146 100644 --- a/client/jobs/fisherman.lua +++ b/client/jobs/fisherman.lua @@ -9,15 +9,15 @@ Config.Jobs.fisherman = { Truck = { Spawner = 1, - Hash = "benson", - Trailer = "none", + Hash = 'benson', + Trailer = 'none', HasCaution = true }, Boat = { Spawner = 2, - Hash = "tug", - Trailer = "none", + Hash = 'tug', + Trailer = 'none', HasCaution = false } @@ -32,7 +32,7 @@ Config.Jobs.fisherman = { Marker= 1, Blip = true, Name = _U('fm_fish_locker'), - Type = "cloakroom", + Type = 'cloakroom', Hint = _U('cloak_change'), GPS = {x = 880.74, y = -1663.96, z = 29.37} }, @@ -44,19 +44,19 @@ Config.Jobs.fisherman = { Marker= 1, Blip = true, Name = _U('fm_fish_area'), - Type = "work", + Type = 'work', Hint = _U('fm_fish_button'), GPS = {x = 3859.43, y = 4448.83, z = 0.39}, Item = { { name = _U('fm_fish'), - db_name= "fish", + db_name= 'fish', time = 2000, max = 100, add = 1, remove = 1, - requires = "nothing", - requires_name = "Nothing", + requires = 'nothing', + requires_name = 'Nothing', drop = 100 } }, @@ -70,7 +70,7 @@ Config.Jobs.fisherman = { Marker= 1, Blip = true, Name = _U('fm_spawnboat_title'), - Type = "vehspawner", + Type = 'vehspawner', Spawner = 2, Hint = _U('fm_spawnboat'), Caution = 0, @@ -83,7 +83,7 @@ Config.Jobs.fisherman = { Marker= -1, Blip = false, Name = _U('fm_boat_title'), - Type = "vehspawnpt", + Type = 'vehspawnpt', Spawner = 2, GPS = 0, Heading = 270.1 @@ -96,7 +96,7 @@ Config.Jobs.fisherman = { Marker= 1, Blip = false, Name = _U('fm_boat_return_title'), - Type = "vehdelete", + Type = 'vehdelete', Hint = _U('fm_boat_return_button'), Spawner = 2, Caution = 0, @@ -111,7 +111,7 @@ Config.Jobs.fisherman = { Marker= 1, Blip = false, Name = _U('spawn_veh'), - Type = "vehspawner", + Type = 'vehspawner', Spawner = 1, Hint = _U('spawn_veh_button'), Caution = 2000, @@ -124,7 +124,7 @@ Config.Jobs.fisherman = { Marker= -1, Blip = false, Name = _U('service_vh'), - Type = "vehspawnpt", + Type = 'vehspawnpt', Spawner = 1, GPS = 0, Heading = 70.1 @@ -137,7 +137,7 @@ Config.Jobs.fisherman = { Marker= 1, Blip = false, Name = _U('return_vh'), - Type = "vehdelete", + Type = 'vehdelete', Hint = _U('return_vh_button'), Spawner = 1, Caution = 2000, @@ -153,7 +153,7 @@ Config.Jobs.fisherman = { Marker= 1, Blip = true, Name = _U('delivery_point'), - Type = "delivery", + Type = 'delivery', Spawner = 2, Hint = _U('fm_deliver_fish'), GPS = {x = 3867.44, y = 4463.62, z = 1.72}, @@ -164,7 +164,7 @@ Config.Jobs.fisherman = { remove = 1, max = 100, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 11, - requires = "fish", + requires = 'fish', requires_name = _U('fm_fish'), drop = 100 } diff --git a/client/jobs/fueler.lua b/client/jobs/fueler.lua index 3f9c681d..f34922c5 100644 --- a/client/jobs/fueler.lua +++ b/client/jobs/fueler.lua @@ -9,8 +9,8 @@ Config.Jobs.fueler = { Truck = { Spawner = 1, - Hash = "phantom", - Trailer = "tanker", + Hash = 'phantom', + Trailer = 'tanker', HasCaution = true } @@ -24,9 +24,9 @@ Config.Jobs.fueler = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = true, - Name = _U("f_oil_refiner"), - Type = "cloakroom", - Hint = _U("cloak_change"), + Name = _U('f_oil_refiner'), + Type = 'cloakroom', + Hint = _U('cloak_change'), GPS = {x = 554.59, y = -2314.43, z = 4.86} }, @@ -36,22 +36,22 @@ Config.Jobs.fueler = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = true, - Name = _U("f_drill_oil"), - Type = "work", + Name = _U('f_drill_oil'), + Type = 'work', Item = { { - name = _U("f_fuel"), - db_name = "petrol", + name = _U('f_fuel'), + db_name = 'petrol', time = 5000, max = 24, add = 1, remove = 1, - requires = "nothing", - requires_name = "Nothing", + requires = 'nothing', + requires_name = 'Nothing', drop = 100 } }, - Hint = _U("f_drillbutton"), + Hint = _U('f_drillbutton'), GPS = {x = 2736.94, y = 1417.99, z = 23.48} }, @@ -61,22 +61,22 @@ Config.Jobs.fueler = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = true, - Name = _U("f_fuel_refine"), - Type = "work", + Name = _U('f_fuel_refine'), + Type = 'work', Item = { { - name = _U("f_fuel_refine"), - db_name = "petrol_raffin", + name = _U('f_fuel_refine'), + db_name = 'petrol_raffin', time = 5000, max = 24, add = 1, remove = 2, - requires = "petrol", - requires_name = _U("f_fuel"), + requires = 'petrol', + requires_name = _U('f_fuel'), drop = 100 } }, - Hint = _U("f_refine_fuel_button"), + Hint = _U('f_refine_fuel_button'), GPS = {x = 265.75, y = -3013.39, z = 4.73} }, @@ -86,22 +86,22 @@ Config.Jobs.fueler = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = true, - Name = _U("f_fuel_mixture"), - Type = "work", + Name = _U('f_fuel_mixture'), + Type = 'work', Item = { { - name = _U("f_gas"), - db_name = "essence", + name = _U('f_gas'), + db_name = 'essence', time = 5000, max = 24, add = 2, remove = 1, - requires = "petrol_raffin", - requires_name = _U("f_fuel_refine"), + requires = 'petrol_raffin', + requires_name = _U('f_fuel_refine'), drop = 100 } }, - Hint = _U("f_fuel_mixture_button"), + Hint = _U('f_fuel_mixture_button'), GPS = {x = 491.40, y = -2163.37, z = 4.91} }, @@ -111,10 +111,10 @@ Config.Jobs.fueler = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = false, - Name = _U("spawn_veh"), - Type = "vehspawner", + Name = _U('spawn_veh'), + Type = 'vehspawner', Spawner = 1, - Hint = _U("spawn_truck_button"), + Hint = _U('spawn_truck_button'), Caution = 2000, GPS = {x = 602.25, y = 2926.62, z = 39.68} }, @@ -124,8 +124,8 @@ Config.Jobs.fueler = { Size = {x = 3.0, y = 3.0, z = 1.0}, Marker = -1, Blip = false, - Name = _U("service_vh"), - Type = "vehspawnpt", + Name = _U('service_vh'), + Type = 'vehspawnpt', Spawner = 1, GPS = 0, Heading = 0 @@ -137,9 +137,9 @@ Config.Jobs.fueler = { Color = {r = 255, g = 0, b = 0}, Marker = 1, Blip = false, - Name = _U("return_vh"), - Type = "vehdelete", - Hint = _U("return_vh_button"), + Name = _U('return_vh'), + Type = 'vehdelete', + Hint = _U('return_vh_button'), Spawner = 1, Caution = 2000, GPS = 0, @@ -152,23 +152,23 @@ Config.Jobs.fueler = { Size = {x = 10.0, y = 10.0, z = 1.0}, Marker = 1, Blip = true, - Name = _U("f_deliver_gas"), - Type = "delivery", + Name = _U('f_deliver_gas'), + Type = 'delivery', Spawner = 1, Item = { { - name = _U("delivery"), + name = _U('delivery'), time = 500, remove = 1, max = 100, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 61, - requires = "essence", - requires_name = _U("f_gas"), + requires = 'essence', + requires_name = _U('f_gas'), drop = 100 } }, - Hint = _U("f_deliver_gas_button"), + Hint = _U('f_deliver_gas_button'), GPS = {x = 609.58, y = 2856.74, z = 39.49} } diff --git a/client/jobs/lumberjack.lua b/client/jobs/lumberjack.lua index b76fec5d..e6892c27 100644 --- a/client/jobs/lumberjack.lua +++ b/client/jobs/lumberjack.lua @@ -9,8 +9,8 @@ Config.Jobs.lumberjack = { Truck = { Spawner = 1, - Hash = "phantom", - Trailer = "trailers", + Hash = 'phantom', + Trailer = 'trailers', HasCaution = true } @@ -24,9 +24,9 @@ Config.Jobs.lumberjack = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = true, - Name = _U("lj_locker_room"), - Type = "cloakroom", - Hint = _U("cloak_change") + Name = _U('lj_locker_room'), + Type = 'cloakroom', + Hint = _U('cloak_change') }, Wood = { @@ -35,22 +35,22 @@ Config.Jobs.lumberjack = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = true, - Name = _U("lj_mapblip"), - Type = "work", + Name = _U('lj_mapblip'), + Type = 'work', Item = { { - name = _U("lj_wood"), - db_name = "wood", + name = _U('lj_wood'), + db_name = 'wood', time = 3000, max = 20, add = 1, remove = 1, - requires = "nothing", - requires_name = "Nothing", + requires = 'nothing', + requires_name = 'Nothing', drop = 100 } }, - Hint = _U("lj_pickup") + Hint = _U('lj_pickup') }, CuttedWood = { @@ -59,22 +59,22 @@ Config.Jobs.lumberjack = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = false, - Name = _U("lj_cutwood"), - Type = "work", + Name = _U('lj_cutwood'), + Type = 'work', Item = { { - name = _U("lj_cutwood"), - db_name = "cutted_wood", + name = _U('lj_cutwood'), + db_name = 'cutted_wood', time = 5000, max = 20, add = 1, remove = 1, - requires = "wood", - requires_name = _U("lj_wood"), + requires = 'wood', + requires_name = _U('lj_wood'), drop = 100 } }, - Hint = _U("lj_cutwood_button") + Hint = _U('lj_cutwood_button') }, Planks = { @@ -83,22 +83,22 @@ Config.Jobs.lumberjack = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = false, - Name = _U("lj_board"), - Type = "work", + Name = _U('lj_board'), + Type = 'work', Item = { { - name = _U("lj_planks"), - db_name = "packaged_plank", + name = _U('lj_planks'), + db_name = 'packaged_plank', time = 4000, max = 100, add = 5, remove = 1, - requires = "cutted_wood", - requires_name = _U("lj_cutwood"), + requires = 'cutted_wood', + requires_name = _U('lj_cutwood'), drop = 100 } }, - Hint = _U("lj_pick_boards") + Hint = _U('lj_pick_boards') }, VehicleSpawner = { @@ -107,10 +107,10 @@ Config.Jobs.lumberjack = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = false, - Name = _U("spawn_veh"), - Type = "vehspawner", + Name = _U('spawn_veh'), + Type = 'vehspawner', Spawner = 1, - Hint = _U("spawn_veh_button"), + Hint = _U('spawn_veh_button'), Caution = 2000 }, @@ -119,8 +119,8 @@ Config.Jobs.lumberjack = { Size = {x = 3.0, y = 3.0, z = 1.0}, Marker = -1, Blip = false, - Name = _U("service_vh"), - Type = "vehspawnpt", + Name = _U('service_vh'), + Type = 'vehspawnpt', Spawner = 1, Heading = 264.40 }, @@ -131,9 +131,9 @@ Config.Jobs.lumberjack = { Color = {r = 255, g = 0, b = 0}, Marker = 1, Blip = false, - Name = _U("return_vh"), - Type = "vehdelete", - Hint = _U("return_vh_button"), + Name = _U('return_vh'), + Type = 'vehdelete', + Hint = _U('return_vh_button'), Spawner = 1, Caution = 2000, GPS = 0, @@ -146,22 +146,22 @@ Config.Jobs.lumberjack = { Size = {x = 5.0, y = 5.0, z = 3.0}, Marker = 1, Blip = true, - Name = _U("delivery_point"), - Type = "delivery", + Name = _U('delivery_point'), + Type = 'delivery', Spawner = 1, Item = { { - name = _U("delivery"), + name = _U('delivery'), time = 500, remove = 1, max = 100, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 13, - requires = "packaged_plank", - requires_name = _U("lj_planks"), + requires = 'packaged_plank', + requires_name = _U('lj_planks'), drop = 100 } }, - Hint = _U("lj_deliver_button") + Hint = _U('lj_deliver_button') } } diff --git a/client/jobs/miner.lua b/client/jobs/miner.lua index 20e7520e..a26041fe 100644 --- a/client/jobs/miner.lua +++ b/client/jobs/miner.lua @@ -9,8 +9,8 @@ Config.Jobs.miner = { Truck = { Spawner = 1, - Hash = "rubble", - Trailer = "none", + Hash = 'rubble', + Trailer = 'none', HasCaution = true } @@ -24,9 +24,9 @@ Config.Jobs.miner = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = true, - Name = _U("m_miner_locker"), - Type = "cloakroom", - Hint = _U("cloak_change"), + Name = _U('m_miner_locker'), + Type = 'cloakroom', + Hint = _U('cloak_change'), GPS = {x = 884.86, y = -2176.51, z = 29.51} }, @@ -36,22 +36,22 @@ Config.Jobs.miner = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = true, - Name = _U("m_rock"), - Type = "work", + Name = _U('m_rock'), + Type = 'work', Item = { { - name = _U("m_rock"), - db_name = "stone", + name = _U('m_rock'), + db_name = 'stone', time = 3000, max = 7, add = 1, remove = 1, - requires = "nothing", - requires_name = "Nothing", + requires = 'nothing', + requires_name = 'Nothing', drop = 100 } }, - Hint = _U("m_pickrocks"), + Hint = _U('m_pickrocks'), GPS = {x = 289.24, y = 2862.90, z = 42.64} }, @@ -61,22 +61,22 @@ Config.Jobs.miner = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = true, - Name = _U("m_washrock"), - Type = "work", + Name = _U('m_washrock'), + Type = 'work', Item = { { - name = _U("m_washrock"), - db_name = "washed_stone", + name = _U('m_washrock'), + db_name = 'washed_stone', time = 5000, max = 7, add = 1, remove = 1, - requires = "stone", - requires_name = _U("m_rock"), + requires = 'stone', + requires_name = _U('m_rock'), drop = 100 } }, - Hint = _U("m_rock_button"), + Hint = _U('m_rock_button'), GPS = {x = 1109.14, y = -2007.87, z = 30.01} }, @@ -86,43 +86,43 @@ Config.Jobs.miner = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = true, - Name = _U("m_rock_smelting"), - Type = "work", + Name = _U('m_rock_smelting'), + Type = 'work', Item = { { - name = _U("m_copper"), - db_name = "copper", + name = _U('m_copper'), + db_name = 'copper', time = 4000, max = 56, add = 8, remove = 1, - requires = "washed_stone", - requires_name = _U("m_washrock"), + requires = 'washed_stone', + requires_name = _U('m_washrock'), drop = 100 }, { - name = _U("m_iron"), - db_name = "iron", + name = _U('m_iron'), + db_name = 'iron', max = 42, add = 6, drop = 100 }, { - name = _U("m_gold"), - db_name = "gold", + name = _U('m_gold'), + db_name = 'gold', max = 21, add = 3, drop = 100 }, { - name = _U("m_diamond"), - db_name = "diamond", + name = _U('m_diamond'), + db_name = 'diamond', max = 50, add = 1, drop = 5 } }, - Hint = _U("m_melt_button"), + Hint = _U('m_melt_button'), GPS = {x = -169.48, y = -2659.16, z = 5.00} }, @@ -132,10 +132,10 @@ Config.Jobs.miner = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = false, - Name = _U("spawn_veh"), - Type = "vehspawner", + Name = _U('spawn_veh'), + Type = 'vehspawner', Spawner = 1, - Hint = _U("spawn_veh_button"), + Hint = _U('spawn_veh_button'), Caution = 2000, GPS = {x = 2962.40, y = 2746.20, z = 42.39} }, @@ -145,8 +145,8 @@ Config.Jobs.miner = { Size = {x = 5.0, y = 5.0, z = 1.0}, Marker = -1, Blip = false, - Name = _U("service_vh"), - Type = "vehspawnpt", + Name = _U('service_vh'), + Type = 'vehspawnpt', Spawner = 1, Heading = 90.1, GPS = 0 @@ -158,9 +158,9 @@ Config.Jobs.miner = { Color = {r = 255, g = 0, b = 0}, Marker = 1, Blip = false, - Name = _U("return_vh"), - Type = "vehdelete", - Hint = _U("return_vh_button"), + Name = _U('return_vh'), + Type = 'vehdelete', + Hint = _U('return_vh_button'), Spawner = 1, Caution = 2000, GPS = 0, @@ -173,22 +173,22 @@ Config.Jobs.miner = { Size = {x = 5.0, y = 5.0, z = 3.0}, Marker = 1, Blip = true, - Name = _U("m_sell_copper"), - Type = "delivery", + Name = _U('m_sell_copper'), + Type = 'delivery', Spawner = 1, Item = { { - name = _U("delivery"), + name = _U('delivery'), time = 500, remove = 1, max = 56, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 5, - requires = "copper", - requires_name = _U("m_copper"), + requires = 'copper', + requires_name = _U('m_copper'), drop = 100 } }, - Hint = _U("m_deliver_copper"), + Hint = _U('m_deliver_copper'), GPS = {x = -148.78, y = -1040.38, z = 26.27} }, @@ -199,22 +199,22 @@ Config.Jobs.miner = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = true, - Name = _U("m_sell_iron"), - Type = "delivery", + Name = _U('m_sell_iron'), + Type = 'delivery', Spawner = 1, Item = { { - name = _U("delivery"), + name = _U('delivery'), time = 500, remove = 1, max = 42, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 9, - requires = "iron", - requires_name = _U("m_iron"), + requires = 'iron', + requires_name = _U('m_iron'), drop = 100 } }, - Hint = _U("m_deliver_iron"), + Hint = _U('m_deliver_iron'), GPS = {x = 261.48, y = 207.35, z = 109.28} }, @@ -225,22 +225,22 @@ Config.Jobs.miner = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = true, - Name = _U("m_sell_gold"), - Type = "delivery", + Name = _U('m_sell_gold'), + Type = 'delivery', Spawner = 1, Item = { { - name = _U("delivery"), + name = _U('delivery'), time = 500, remove = 1, max = 21, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 25, - requires = "gold", - requires_name = _U("m_gold"), + requires = 'gold', + requires_name = _U('m_gold'), drop = 100 } }, - Hint = _U("m_deliver_gold"), + Hint = _U('m_deliver_gold'), GPS = {x = -621.04, y = -228.53, z = 37.05} }, @@ -251,22 +251,22 @@ Config.Jobs.miner = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = true, - Name = _U("m_sell_diamond"), - Type = "delivery", + Name = _U('m_sell_diamond'), + Type = 'delivery', Spawner = 1, Item = { { - name = _U("delivery"), + name = _U('delivery'), time = 500, remove = 1, max = 50, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 250, - requires = "diamond", - requires_name = _U("m_diamond"), + requires = 'diamond', + requires_name = _U('m_diamond'), drop = 100 } }, - Hint = _U("m_deliver_diamond"), + Hint = _U('m_deliver_diamond'), GPS = {x = 2962.40, y = 2746.20, z = 42.39} } diff --git a/client/jobs/reporter.lua b/client/jobs/reporter.lua index 6cc12b9a..71766d2e 100644 --- a/client/jobs/reporter.lua +++ b/client/jobs/reporter.lua @@ -9,8 +9,8 @@ Config.Jobs.reporter = { Truck = { Spawner = 1, - Hash = "rumpo", - Trailer = "none", + Hash = 'rumpo', + Trailer = 'none', HasCaution = true } @@ -24,10 +24,10 @@ Config.Jobs.reporter = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = true, - Name = _U("reporter_name"), - Type = "vehspawner", + Name = _U('reporter_name'), + Type = 'vehspawner', Spawner = 1, - Hint = _U("reporter_garage"), + Hint = _U('reporter_garage'), Caution = 2000 }, @@ -36,8 +36,8 @@ Config.Jobs.reporter = { Size = {x = 3.0, y = 3.0, z = 1.0}, Marker = -1, Blip = false, - Name = _U("service_vh"), - Type = "vehspawnpt", + Name = _U('service_vh'), + Type = 'vehspawnpt', Spawner = 1, Heading = 200.1 }, @@ -48,9 +48,9 @@ Config.Jobs.reporter = { Color = {r = 255, g = 0, b = 0}, Marker = 1, Blip = false, - Name = _U("return_vh"), - Type = "vehdelete", - Hint = _U("return_vh_button"), + Name = _U('return_vh'), + Type = 'vehdelete', + Hint = _U('return_vh_button'), Spawner = 1, Caution = 2000, GPS = 0, diff --git a/client/jobs/slaughterer.lua b/client/jobs/slaughterer.lua index 9de175da..1f7c26f2 100644 --- a/client/jobs/slaughterer.lua +++ b/client/jobs/slaughterer.lua @@ -9,8 +9,8 @@ Config.Jobs.slaughterer = { Truck = { Spawner = 1, - Hash = "benson", - Trailer = "none", + Hash = 'benson', + Trailer = 'none', HasCaution = true } }, @@ -23,9 +23,9 @@ Config.Jobs.slaughterer = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = true, - Name = _U("s_slaughter_locker"), - Type = "cloakroom", - Hint = _U("cloak_change") + Name = _U('s_slaughter_locker'), + Type = 'cloakroom', + Hint = _U('cloak_change') }, AliveChicken = { @@ -34,22 +34,22 @@ Config.Jobs.slaughterer = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = true, - Name = _U("s_hen"), - Type = "work", + Name = _U('s_hen'), + Type = 'work', Item = { { - name = _U("s_alive_chicken"), - db_name = "alive_chicken", + name = _U('s_alive_chicken'), + db_name = 'alive_chicken', time = 3000, max = 20, add = 1, remove = 1, - requires = "nothing", - requires_name = "Nothing", + requires = 'nothing', + requires_name = 'Nothing', drop = 100 } }, - Hint = _U("s_catch_hen") + Hint = _U('s_catch_hen') }, SlaughterHouse = { @@ -58,22 +58,22 @@ Config.Jobs.slaughterer = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = false, - Name = _U("s_slaughtered"), - Type = "work", + Name = _U('s_slaughtered'), + Type = 'work', Item = { { - name = _U("s_slaughtered_chicken"), - db_name = "slaughtered_chicken", + name = _U('s_slaughtered_chicken'), + db_name = 'slaughtered_chicken', time = 5000, max = 20, add = 1, remove = 1, - requires = "alive_chicken", - requires_name = _U("s_alive_chicken"), + requires = 'alive_chicken', + requires_name = _U('s_alive_chicken'), drop = 100 } }, - Hint = _U("s_chop_animal") + Hint = _U('s_chop_animal') }, Packaging = { @@ -82,22 +82,22 @@ Config.Jobs.slaughterer = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = false, - Name = _U("s_package"), - Type = "work", + Name = _U('s_package'), + Type = 'work', Item = { { - name = _U("s_packagechicken"), - db_name = "packaged_chicken", + name = _U('s_packagechicken'), + db_name = 'packaged_chicken', time = 4000, max = 100, add = 5, remove = 1, - requires = "slaughtered_chicken", - requires_name = _U("s_unpackaged"), + requires = 'slaughtered_chicken', + requires_name = _U('s_unpackaged'), drop = 100 } }, - Hint = _U("s_unpackaged_button") + Hint = _U('s_unpackaged_button') }, VehicleSpawner = { @@ -106,10 +106,10 @@ Config.Jobs.slaughterer = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = false, - Name = _U("spawn_veh"), - Type = "vehspawner", + Name = _U('spawn_veh'), + Type = 'vehspawner', Spawner = 1, - Hint = _U("spawn_veh_button"), + Hint = _U('spawn_veh_button'), Caution = 2000 }, @@ -118,8 +118,8 @@ Config.Jobs.slaughterer = { Size = {x = 3.0, y = 3.0, z = 1.0}, Marker = -1, Blip = false, - Name = _U("service_vh"), - Type = "vehspawnpt", + Name = _U('service_vh'), + Type = 'vehspawnpt', Spawner = 1, Heading = 130.1 }, @@ -130,9 +130,9 @@ Config.Jobs.slaughterer = { Color = {r = 255, g = 0, b = 0}, Marker = 1, Blip = false, - Name = _U("return_vh"), - Type = "vehdelete", - Hint = _U("return_vh_button"), + Name = _U('return_vh'), + Type = 'vehdelete', + Hint = _U('return_vh_button'), Spawner = 1, Caution = 2000, GPS = 0, @@ -145,22 +145,22 @@ Config.Jobs.slaughterer = { Size = {x = 5.0, y = 5.0, z = 1.0}, Marker = 1, Blip = true, - Name = _U("delivery_point"), - Type = "delivery", + Name = _U('delivery_point'), + Type = 'delivery', Spawner = 1, Item = { { - name = _U("delivery"), + name = _U('delivery'), time = 500, remove = 1, max = 100, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 23, - requires = "packaged_chicken", - requires_name = _U("s_packagechicken"), + requires = 'packaged_chicken', + requires_name = _U('s_packagechicken'), drop = 100 } }, - Hint = _U("s_deliver") + Hint = _U('s_deliver') } } } diff --git a/client/jobs/tailor.lua b/client/jobs/tailor.lua index 73204220..2d805c7e 100644 --- a/client/jobs/tailor.lua +++ b/client/jobs/tailor.lua @@ -9,8 +9,8 @@ Config.Jobs.tailor = { Truck = { Spawner = 1, - Hash = "youga2", - Trailer = "none", + Hash = 'youga2', + Trailer = 'none', HasCaution = true } @@ -24,9 +24,9 @@ Config.Jobs.tailor = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = true, - Name = _U("dd_dress_locker"), - Type = "cloakroom", - Hint = _U("cloak_change"), + Name = _U('dd_dress_locker'), + Type = 'cloakroom', + Hint = _U('cloak_change'), GPS = {x = 740.80, y = -970.06, z = 23.46} }, @@ -36,22 +36,22 @@ Config.Jobs.tailor = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = true, - Name = _U("dd_wool"), - Type = "work", + Name = _U('dd_wool'), + Type = 'work', Item = { { - name = _U("dd_wool"), - db_name = "wool", + name = _U('dd_wool'), + db_name = 'wool', time = 3000, max = 40, add = 1, remove = 1, - requires = "nothing", - requires_name = "Nothing", + requires = 'nothing', + requires_name = 'Nothing', drop = 100 } }, - Hint = _U("dd_pickup"), + Hint = _U('dd_pickup'), GPS = {x = 715.95, y = -959.63, z = 29.39} }, @@ -61,22 +61,22 @@ Config.Jobs.tailor = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = false, - Name = _U("dd_fabric"), - Type = "work", + Name = _U('dd_fabric'), + Type = 'work', Item = { { - name = _U("dd_fabric"), - db_name = "fabric", + name = _U('dd_fabric'), + db_name = 'fabric', time = 5000, max = 80, add = 2, remove = 1, - requires = "wool", - requires_name = _U("dd_wool"), + requires = 'wool', + requires_name = _U('dd_wool'), drop = 100 } }, - Hint = _U("dd_makefabric"), + Hint = _U('dd_makefabric'), GPS = {x = 712.92, y = -970.58, z = 29.39} }, @@ -86,22 +86,22 @@ Config.Jobs.tailor = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = false, - Name = _U("dd_clothing"), - Type = "work", + Name = _U('dd_clothing'), + Type = 'work', Item = { { - name = _U("dd_clothing"), - db_name = "clothe", + name = _U('dd_clothing'), + db_name = 'clothe', time = 4000, max = 40, add = 1, remove = 2, - requires = "fabric", - requires_name = _U("dd_fabric"), + requires = 'fabric', + requires_name = _U('dd_fabric'), drop = 100 } }, - Hint = _U("dd_makeclothing"), + Hint = _U('dd_makeclothing'), GPS = {x = 429.59, y = -807.34, z = 28.49} }, @@ -111,10 +111,10 @@ Config.Jobs.tailor = { Color = {r = 204, g = 204, b = 0}, Marker = 1, Blip = false, - Name = _U("spawn_veh"), - Type = "vehspawner", + Name = _U('spawn_veh'), + Type = 'vehspawner', Spawner = 1, - Hint = _U("spawn_veh_button"), + Hint = _U('spawn_veh_button'), Caution = 2000, GPS = {x = 1978.92, y = 5171.70, z = 46.63} }, @@ -124,8 +124,8 @@ Config.Jobs.tailor = { Size = {x = 3.0, y = 3.0, z = 1.0}, Marker = -1, Blip = false, - Name = _U("service_vh"), - Type = "vehspawnpt", + Name = _U('service_vh'), + Type = 'vehspawnpt', Spawner = 1, Heading = 270.1, GPS = 0 @@ -137,9 +137,9 @@ Config.Jobs.tailor = { Color = {r = 255, g = 0, b = 0}, Marker = 1, Blip = false, - Name = _U("return_vh"), - Type = "vehdelete", - Hint = _U("return_vh_button"), + Name = _U('return_vh'), + Type = 'vehdelete', + Hint = _U('return_vh_button'), Spawner = 1, Caution = 2000, GPS = 0, @@ -152,22 +152,22 @@ Config.Jobs.tailor = { Size = {x = 5.0, y = 5.0, z = 3.0}, Marker = 1, Blip = true, - Name = _U("delivery_point"), - Type = "delivery", + Name = _U('delivery_point'), + Type = 'delivery', Spawner = 1, Item = { { - name = _U("delivery"), + name = _U('delivery'), time = 500, remove = 1, max = 100, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 40, - requires = "clothe", - requires_name = _U("dd_clothing"), + requires = 'clothe', + requires_name = _U('dd_clothing'), drop = 100 } }, - Hint = _U("dd_deliver_clothes"), + Hint = _U('dd_deliver_clothes'), GPS = {x = 1978.92, y = 5171.70, z = 46.63} } } diff --git a/client/main.lua b/client/main.lua index fc710ac3..1db333c1 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,33 +1,5 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - -local PlayerData = {} -local menuIsShowed = false -local hintIsShowed = false -local hasAlreadyEnteredMarker = false -local Blips = {} -local JobBlips = {} -local isInMarker = false -local isInPublicMarker = false - -local hintToDisplay = "no hint to display" -local onDuty = false -local spawner = 0 -local myPlate = {} - -local vehicleObjInCaseofDrop = nil -local vehicleInCaseofDrop = nil - -local vehicleMaxHealth = nil +local menuIsShowed, hintIsShowed, hintToDisplay, hasAlreadyEnteredMarker, isInMarker, onDuty, vehicleObjInCaseofDrop, vehicleInCaseofDrop, vehicleMaxHealth +local PlayerData, Blips, JobBlips, myPlate, spawner = {}, {}, {}, {}, 0 ESX = nil @@ -54,14 +26,13 @@ end) function OpenMenu() ESX.UI.Menu.CloseAll() - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'cloakroom', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'cloakroom', { title = _U('cloakroom'), + align = 'top-left', elements = { {label = _U('job_wear'), value = 'job_wear'}, {label = _U('citizen_wear'), value = 'citizen_wear'} - } - }, function(data, menu) + }}, function(data, menu) if data.current.value == 'citizen_wear' then onDuty = false ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin) @@ -86,136 +57,121 @@ end AddEventHandler('esx_jobs:action', function(job, zone) menuIsShowed = true - if zone.Type == "cloakroom" then + if zone.Type == 'cloakroom' then OpenMenu() - elseif zone.Type == "work" then - hintToDisplay = "no hint to display" + elseif zone.Type == 'work' then + hintToDisplay = nil hintIsShowed = false local playerPed = PlayerPedId() - if IsPedInAnyVehicle(playerPed, false) then - ESX.ShowNotification(_U('foot_work')) - else + if IsPedOnFoot(playerPed) then TriggerServerEvent('esx_jobs:startWork', zone.Item) + else + ESX.ShowNotification(_U('foot_work')) end - elseif zone.Type == "vehspawner" then - local spawnPoint = nil - local vehicle = nil + elseif zone.Type == 'vehspawner' then + local jobObject, spawnPoint, vehicle = Config.Jobs[PlayerData.job.name] - for k,v in pairs(Config.Jobs) do - if PlayerData.job.name == k then - for l,w in pairs(v.Zones) do - if w.Type == "vehspawnpt" and w.Spawner == zone.Spawner then - spawnPoint = w - spawner = w.Spawner - end + if jobObject then + for k,v in pairs(jobObject.Zones) do + if v.Type == 'vehspawnpt' and v.Spawner == zone.Spawner then + spawnPoint = v + spawner = v.Spawner + break end + end - for m,x in pairs(v.Vehicles) do - if x.Spawner == zone.Spawner then - vehicle = x - end + for k,v in pairs(jobObject.Vehicles) do + if v.Spawner == zone.Spawner then + vehicle = v + break end end end - if ESX.Game.IsSpawnPointClear(spawnPoint.Pos, 5.0) then + if jobObject and spawnPoint and vehicle and ESX.Game.IsSpawnPointClear(spawnPoint.Pos, 5.0) then spawnVehicle(spawnPoint, vehicle, zone.Caution) else ESX.ShowNotification(_U('spawn_blocked')) end - elseif zone.Type == "vehdelete" then - local looping = true + elseif zone.Type == 'vehdelete' then + local jobObject = Config.Jobs[PlayerData.job.name] - for k,v in pairs(Config.Jobs) do - if PlayerData.job.name == k then - for l,w in pairs(v.Zones) do - if w.Type == "vehdelete" and w.Spawner == zone.Spawner then - local playerPed = PlayerPedId() + if jobObject then + for k,v in pairs(jobObject.Zones) do + if v.Type == 'vehdelete' and v.Spawner == zone.Spawner then + local playerPed = PlayerPedId() - if IsPedInAnyVehicle(playerPed, false) then + if IsPedInAnyVehicle(playerPed, false) then + local vehicle = GetVehiclePedIsIn(playerPed, false) + local plate = ESX.Math.Trim(GetVehicleNumberPlateText(vehicle)) + local driverPed = GetPedInVehicleSeat(vehicle, -1) - local vehicle = GetVehiclePedIsIn(playerPed, false) - local plate = GetVehicleNumberPlateText(vehicle) - plate = string.gsub(plate, " ", "") - local driverPed = GetPedInVehicleSeat(vehicle, -1) + if playerPed == driverPed then + if myPlate[plate] then + myPlate[plate] = nil - if playerPed == driverPed then + local vehicleHealth = GetVehicleEngineHealth(vehicleInCaseofDrop) - for i=1, #myPlate, 1 do - if myPlate[i] == plate then - - local vehicleHealth = GetVehicleEngineHealth(vehicleInCaseofDrop) - local giveBack = ESX.Math.Round(vehicleHealth / vehicleMaxHealth, 2) - - TriggerServerEvent('esx_jobs:caution', "give_back", giveBack, 0, 0) - DeleteVehicle(GetVehiclePedIsIn(playerPed, false)) - - if w.Teleport ~= 0 then - ESX.Game.Teleport(playerPed, w.Teleport) - end - - table.remove(myPlate, i) - - if vehicleObjInCaseofDrop.HasCaution then - vehicleInCaseofDrop = nil - vehicleObjInCaseofDrop = nil - vehicleMaxHealth = nil - end - - break - end + -- fix for people using cheat engine to modify engine health + if vehicleHealth > vehicleMaxHealth then + vehicleHealth = vehicleMaxHealth end - else - ESX.ShowNotification(_U('not_your_vehicle')) - end + local giveBack = ESX.Math.Round(vehicleHealth / vehicleMaxHealth, 2) + TriggerServerEvent('esx_jobs:caution', 'give_back', giveBack, 0, 0) + DeleteVehicle(GetVehiclePedIsIn(playerPed, false)) + + if v.Teleport ~= 0 then + ESX.Game.Teleport(playerPed, v.Teleport) + end + + if vehicleObjInCaseofDrop.HasCaution then + vehicleInCaseofDrop, vehicleObjInCaseofDrop, vehicleMaxHealth = nil, nil, nil + end + end + else + ESX.ShowNotification(_U('not_your_vehicle')) end - looping = false - break end - if looping == false then - break - end + break end end - if looping == false then - break - end end - elseif zone.Type == "delivery" then - if Blips['delivery'] ~= nil then - RemoveBlip(Blips['delivery']) - Blips['delivery'] = nil + elseif zone.Type == 'delivery' then + if Blips.delivery then + RemoveBlip(Blips.delivery) + Blips.delivery = nil end - hintToDisplay = "no hint to display" + hintToDisplay = nil hintIsShowed = false TriggerServerEvent('esx_jobs:startWork', zone.Item) end + --nextStep(zone.GPS) end) function nextStep(gps) if gps ~= 0 then - if Blips['delivery'] ~= nil then - RemoveBlip(Blips['delivery']) - Blips['delivery'] = nil + if Blips.delivery then + RemoveBlip(Blips.delivery) + Blips.delivery = nil end - Blips['delivery'] = AddBlipForCoord(gps.x, gps.y, gps.z) - SetBlipRoute(Blips['delivery'], true) + Blips.delivery = AddBlipForCoord(gps.x, gps.y, gps.z) + SetBlipRoute(Blips.delivery, true) ESX.ShowNotification(_U('next_point')) end end AddEventHandler('esx_jobs:hasExitedMarker', function(zone) TriggerServerEvent('esx_jobs:stopWork') - hintToDisplay = "no hint to display" + hintToDisplay = nil menuIsShowed = false hintIsShowed = false isInMarker = false @@ -232,11 +188,9 @@ AddEventHandler('esx:setJob', function(job) end) function deleteBlips() - if JobBlips[1] ~= nil then - for i=1, #JobBlips, 1 do - RemoveBlip(JobBlips[i]) - JobBlips[i] = nil - end + for k,v in ipairs(JobBlips) do + RemoveBlip(v) + JobBlips[k] = nil end end @@ -244,7 +198,7 @@ function refreshBlips() local zones = {} local blipInfo = {} - if PlayerData.job ~= nil then + if PlayerData.job then for jobKey,jobValues in pairs(Config.Jobs) do if jobKey == PlayerData.job.name then @@ -253,14 +207,13 @@ function refreshBlips() if zoneValues.Blip then local blip = AddBlipForCoord(zoneValues.Pos.x, zoneValues.Pos.y, zoneValues.Pos.z) SetBlipSprite (blip, jobValues.BlipInfos.Sprite) - SetBlipDisplay (blip, 4) SetBlipScale (blip, 1.2) SetBlipCategory(blip, 3) SetBlipColour (blip, jobValues.BlipInfos.Color) SetBlipAsShortRange(blip, true) - BeginTextCommandSetBlipName("STRING") - AddTextComponentString(zoneValues.Name) + BeginTextCommandSetBlipName('STRING') + AddTextComponentSubstringPlayerName(zoneValues.Name) EndTextCommandSetBlipName(blip) table.insert(JobBlips, blip) end @@ -271,7 +224,7 @@ function refreshBlips() end function spawnVehicle(spawnPoint, vehicle, vehicleCaution) - hintToDisplay = 'no hint to display' + hintToDisplay = nil hintIsShowed = false TriggerServerEvent('esx_jobs:caution', 'take', vehicleCaution, spawnPoint, vehicle) end @@ -282,7 +235,7 @@ AddEventHandler('esx_jobs:spawnJobVehicle', function(spawnPoint, vehicle) ESX.Game.SpawnVehicle(vehicle.Hash, spawnPoint.Pos, spawnPoint.Heading, function(spawnedVehicle) - if vehicle.Trailer ~= "none" then + if vehicle.Trailer ~= 'none' then ESX.Game.SpawnVehicle(vehicle.Trailer, spawnPoint.Pos, spawnPoint.Heading, function(trailer) AttachVehicleToTrailer(spawnedVehicle, trailer, 1.1) end) @@ -291,8 +244,7 @@ AddEventHandler('esx_jobs:spawnJobVehicle', function(spawnPoint, vehicle) -- save & set plate local plate = 'WORK' .. math.random(100, 900) SetVehicleNumberPlateText(spawnedVehicle, plate) - table.insert(myPlate, plate) - plate = string.gsub(plate, " ", "") + myPlate[plate] = true TaskWarpPedIntoVehicle(playerPed, spawnedVehicle, -1) @@ -307,9 +259,9 @@ end) -- Show top left hint Citizen.CreateThread(function() while true do - Citizen.Wait(10) + Citizen.Wait(0) - if hintIsShowed then + if hintIsShowed and hintToDisplay then ESX.ShowHelpNotification(hintToDisplay) else Citizen.Wait(500) @@ -317,185 +269,118 @@ Citizen.CreateThread(function() end end) --- Display markers (only if on duty and the player's job ones) +-- Draw markers (only if on duty and the player's job ones) Citizen.CreateThread(function() while true do - Citizen.Wait(1) - local zones = {} + Citizen.Wait(0) + local zones, currentZone, isInMarker = {} + local letSleep, playerPed = true, PlayerPedId() + local playerCoords = GetEntityCoords(playerPed) - if PlayerData.job ~= nil then - for k,v in pairs(Config.Jobs) do - if PlayerData.job.name == k then - zones = v.Zones - end + if PlayerData.job then + if Config.Jobs[PlayerData.job.name] then + zones = Config.Jobs[PlayerData.job.name].Zones end - local coords = GetEntityCoords(PlayerPedId()) for k,v in pairs(zones) do - if onDuty or v.Type == "cloakroom" or PlayerData.job.name == "reporter" then - if(v.Marker ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then - DrawMarker(v.Marker, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) - end - end - end - end - end -end) + local distance = GetDistanceBetweenCoords(playerCoords, v.Pos.x, v.Pos.y, v.Pos.z, true) --- Display public markers -Citizen.CreateThread(function() - while true do - Citizen.Wait(0) - local coords = GetEntityCoords(PlayerPedId()) - for k,v in pairs(Config.PublicZones) do - if(v.Marker ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then - DrawMarker(v.Marker, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false) - end - end - end -end) - --- Activate public marker -Citizen.CreateThread(function() - while true do - Citizen.Wait(0) - local coords = GetEntityCoords(PlayerPedId()) - local position = nil - local zone = nil - - for k,v in pairs(Config.PublicZones) do - if GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x/2 then - isInPublicMarker = true - position = v.Teleport - zone = v - break - else - isInPublicMarker = false - end - end - - if IsControlJustReleased(0, Keys['E']) and isInPublicMarker then - ESX.Game.Teleport(PlayerPedId(), position) - isInPublicMarker = false - end - - -- hide or show top left zone hints - if isInPublicMarker then - hintToDisplay = zone.Hint - hintIsShowed = true - else - if not isInMarker then - hintToDisplay = "no hint to display" - hintIsShowed = false - end - end - end -end) - --- Activate menu when player is inside marker -Citizen.CreateThread(function() - while true do - - Citizen.Wait(1) - - if PlayerData.job ~= nil and PlayerData.job.name ~= 'unemployed' then - local zones = nil - local job = nil - - for k,v in pairs(Config.Jobs) do - if PlayerData.job.name == k then - job = v - zones = v.Zones - end - end - - if zones ~= nil then - local coords = GetEntityCoords(PlayerPedId()) - local currentZone = nil - local zone = nil - local lastZone = nil - - for k,v in pairs(zones) do - if GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x then - isInMarker = true - currentZone = k - zone = v - break - else - isInMarker = false + if onDuty or v.Type == 'cloakroom' or PlayerData.job.name == 'reporter' then + if(v.Marker ~= -1 and distance < Config.DrawDistance) then + letSleep = false + DrawMarker(v.Marker, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, nil, nil, false) end end - if IsControlJustReleased(0, Keys['E']) and not menuIsShowed and isInMarker then - if onDuty or zone.Type == "cloakroom" or PlayerData.job.name == "reporter" then - TriggerEvent('esx_jobs:action', job, zone) - end + if distance < v.Size.x then + letSleep, isInMarker, currentZone = false, true, v + break end + end - -- hide or show top left zone hints - if isInMarker and not menuIsShowed then + if IsControlJustReleased(0, 38) and not menuIsShowed and isInMarker then + if onDuty or currentZone.Type == 'cloakroom' or PlayerData.job.name == 'reporter' then + TriggerEvent('esx_jobs:action', PlayerData.job.name, currentZone) + end + end + + -- hide or show top left zone hints + if isInMarker and not menuIsShowed then + hintIsShowed = true + if (onDuty or currentZone.Type == 'cloakroom' or PlayerData.job.name == 'reporter') and currentZone.Type ~= 'vehdelete' then + hintToDisplay = currentZone.Hint hintIsShowed = true - if (onDuty or zone.Type == "cloakroom" or PlayerData.job.name == "reporter") and zone.Type ~= "vehdelete" then - hintToDisplay = zone.Hint - hintIsShowed = true - elseif zone.Type == "vehdelete" and (onDuty or PlayerData.job.name == "reporter") then - local playerPed = PlayerPedId() + elseif currentZone.Type == 'vehdelete' and (onDuty or PlayerData.job.name == 'reporter') then + local playerPed = PlayerPedId() - if IsPedInAnyVehicle(playerPed, false) then - local vehicle = GetVehiclePedIsIn(playerPed, false) - local driverPed = GetPedInVehicleSeat(vehicle, -1) - local plate = GetVehicleNumberPlateText(vehicle) - plate = string.gsub(plate, " ", "") + if IsPedInAnyVehicle(playerPed, false) then + local vehicle = GetVehiclePedIsIn(playerPed, false) + local driverPed = GetPedInVehicleSeat(vehicle, -1) + local plate = ESX.Math.Trim(GetVehicleNumberPlateText(vehicle)) - if playerPed == driverPed then - - for i=1, #myPlate, 1 do - if myPlate[i] == plate then - hintToDisplay = zone.Hint - break - end - end - - else - hintToDisplay = _U('not_your_vehicle') + if playerPed == driverPed then + if myPlate[plate] then + hintToDisplay = currentZone.Hint end else - hintToDisplay = _U('in_vehicle') + hintToDisplay = _U('not_your_vehicle') end - hintIsShowed = true - elseif onDuty and zone.Spawner ~= spawner then - hintToDisplay = _U('wrong_point') - hintIsShowed = true else - if not isInPublicMarker then - hintToDisplay = "no hint to display" - hintIsShowed = false - end + hintToDisplay = _U('in_vehicle') end - end - - if isInMarker and not hasAlreadyEnteredMarker then - hasAlreadyEnteredMarker = true - end - - if not isInMarker and hasAlreadyEnteredMarker then - hasAlreadyEnteredMarker = false - TriggerEvent('esx_jobs:hasExitedMarker', zone) + hintIsShowed = true + elseif onDuty and currentZone.Spawner ~= spawner then + hintToDisplay = _U('wrong_point') + hintIsShowed = true + else + hintToDisplay = nil + hintIsShowed = false end end + + if isInMarker and not hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = true + end + + if not isInMarker and hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = false + TriggerEvent('esx_jobs:hasExitedMarker', currentZone) + end + end + + for k,v in pairs(Config.PublicZones) do + local distance = GetDistanceBetweenCoords(playerCoords, v.Pos.x, v.Pos.y, v.Pos.z, true) + + if v.Marker ~= -1 and distance < Config.DrawDistance then + DrawMarker(v.Marker, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, nil, nil, false) + letSleep = false + end + + if distance < v.Size.x / 2 then + letSleep, isInPublicMarker = false, true + ESX.ShowHelpNotification(v.Hint) + + if IsControlJustReleased(0, 38) then + ESX.Game.Teleport(playerPed, v.Teleport) + end + end + end + + if letSleep then + Citizen.Wait(500) end end end) Citizen.CreateThread(function() -- Slaughterer - RemoveIpl("CS1_02_cf_offmission") - RequestIpl("CS1_02_cf_onmission1") - RequestIpl("CS1_02_cf_onmission2") - RequestIpl("CS1_02_cf_onmission3") - RequestIpl("CS1_02_cf_onmission4") + RemoveIpl('CS1_02_cf_offmission') + RequestIpl('CS1_02_cf_onmission1') + RequestIpl('CS1_02_cf_onmission2') + RequestIpl('CS1_02_cf_onmission3') + RequestIpl('CS1_02_cf_onmission4') -- Tailor - RequestIpl("id2_14_during_door") - RequestIpl("id2_14_during1") + RequestIpl('id2_14_during_door') + RequestIpl('id2_14_during1') end) diff --git a/locales/en.lua b/locales/en.lua index 2e1c948d..98cc6e61 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -8,7 +8,7 @@ Locales['en'] = { ['bank_deposit_taken'] = 'a security deposit of ~r~$%s~s~ was taken from you.', ['foot_work'] = 'you have to be on foot to be able to work.', ['next_point'] = 'go to the next step after completing this one.', - ['not_your_vehicle'] = 'this is not your vehicle or you must be a driver.', + ['not_your_vehicle'] = 'you are not the driver of this vehicle.', ['in_vehicle'] = 'you must sit in a vehicle.', ['wrong_point'] = 'you are not at the right point of delivery.', ['max_limit'] = 'you cannot carry more ~y~%s~s~', diff --git a/server/main.lua b/server/main.lua index b383a65b..6463a136 100644 --- a/server/main.lua +++ b/server/main.lua @@ -21,13 +21,13 @@ local function Work(source, item) end local requiredItemQtty = 0 - if item[1].requires ~= "nothing" then + if item[1].requires ~= 'nothing' then requiredItemQtty = xPlayer.getInventoryItem(item[1].requires).count end if item[i].name ~= _U('delivery') and itemQtty >= item[i].max then xPlayer.showNotification(_U('max_limit', item[i].name)) - elseif item[i].requires ~= "nothing" and requiredItemQtty <= 0 then + elseif item[i].requires ~= 'nothing' and requiredItemQtty <= 0 then xPlayer.showNotification(_U('not_enough', item[1].requires_name)) else if item[i].name ~= _U('delivery') then @@ -46,7 +46,7 @@ local function Work(source, item) end end - if item[1].requires ~= "nothing" then + if item[1].requires ~= 'nothing' then local itemToRemoveQtty = xPlayer.getInventoryItem(item[1].requires).count if itemToRemoveQtty > 0 then xPlayer.removeInventoryItem(item[1].requires, item[1].remove) @@ -78,7 +78,7 @@ RegisterServerEvent('esx_jobs:caution') AddEventHandler('esx_jobs:caution', function(cautionType, cautionAmount, spawnPoint, vehicle) local xPlayer = ESX.GetPlayerFromId(source) - if cautionType == "take" then + if cautionType == 'take' then TriggerEvent('esx_addonaccount:getAccount', 'caution', xPlayer.identifier, function(account) xPlayer.removeAccountMoney('bank', cautionAmount) account.addMoney(cautionAmount) @@ -86,7 +86,7 @@ AddEventHandler('esx_jobs:caution', function(cautionType, cautionAmount, spawnPo xPlayer.showNotification(_U('bank_deposit_taken', ESX.Math.GroupDigits(cautionAmount))) TriggerClientEvent('esx_jobs:spawnJobVehicle', source, spawnPoint, vehicle) - elseif cautionType == "give_back" then + elseif cautionType == 'give_back' then if cautionAmount > 1 then print(('esx_jobs: %s is using cheat engine!'):format(xPlayer.identifier)) From f8f97578dbe7806437757cddc7a2df0d50f54a23 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sat, 7 Dec 2019 12:09:26 +0100 Subject: [PATCH 2320/3224] Added Czech translation (#22) * Added czech lang * Added czech lang --- __resource.lua | 2 ++ locales/cs.lua | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 locales/cs.lua diff --git a/__resource.lua b/__resource.lua index 89940347..448d485f 100644 --- a/__resource.lua +++ b/__resource.lua @@ -13,6 +13,7 @@ server_scripts { 'locales/fi.lua', 'locales/fr.lua', 'locales/sv.lua', + 'locales/cs.lua', 'config.lua', 'server/main.lua' } @@ -25,6 +26,7 @@ client_scripts { 'locales/fi.lua', 'locales/fr.lua', 'locales/sv.lua', + 'locales/cs.lua', 'config.lua', 'client/main.lua' } diff --git a/locales/cs.lua b/locales/cs.lua new file mode 100644 index 00000000..112e246c --- /dev/null +++ b/locales/cs.lua @@ -0,0 +1,28 @@ +Locales['cs'] = { + ['properties'] = 'nemovitosti', + ['clients'] = 'zákazníci', + ['client'] = 'zákazník', + ['realtor'] = 'Realitní makléř', + ['amount_withdraw'] = 'výše výběru', + ['invalid_amount'] = 'neplatná částka', + ['press_to_access'] = 'stiskni ~INPUT_CONTEXT~ pro přístup do menz', + ['amount'] = 'částka', + ['no_play_near'] = 'žádní hráči poblíž', + ['realtors'] = 'Realitní makléři', + ['boss_action'] = 'akce šéfa', + ['client_poor'] = 'tví klienti si tohle nemůžou dovolit', + + -- Property menu + ['property_name'] = 'nemovitost', + ['property_actions'] = 'akce', + ['property_actionbuttons'] = '{{Assign [Sell]|sell}} {{Assign [Rent]|rent}} {{GPS|gps}}', + + -- Customer menu + ['customer_client'] = 'klienti', + ['customer_property'] = 'nemovitost', + ['customer_agreement'] = 'smlouvy', + ['customer_actions'] = 'akce', + ['customer_contractbuttons'] = '{{Zrušit smlouvu|revoke}} {{GPS|gps}}', + ['customer_rent'] = 'pronajato', + ['customer_sell'] = 'prodáno', +} From 752c0d5e65881c1e9708651bb1ee60e7b4bc68e1 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sat, 7 Dec 2019 12:10:01 +0100 Subject: [PATCH 2321/3224] Add support for new ESX weight system (#365) * Add support for new ESX weight system * Update main.lua * Fix --- server/main.lua | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/server/main.lua b/server/main.lua index fb356401..e2b01235 100644 --- a/server/main.lua +++ b/server/main.lua @@ -28,32 +28,32 @@ AddEventHandler('esx_policejob:confiscatePlayerItem', function(target, itemType, if targetItem.count > 0 and targetItem.count <= amount then -- can the player carry the said amount of x item? - if sourceItem.limit ~= -1 and (sourceItem.count + amount) > sourceItem.limit then - TriggerClientEvent('esx:showNotification', _source, _U('quantity_invalid')) - else + if sourceXPlayer.canCarryItem(itemName, sourceItem.count) then targetXPlayer.removeInventoryItem(itemName, amount) sourceXPlayer.addInventoryItem (itemName, amount) - TriggerClientEvent('esx:showNotification', _source, _U('you_confiscated', amount, sourceItem.label, targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('got_confiscated', amount, sourceItem.label, sourceXPlayer.name)) + sourceXPlayer.showNotification(_U('you_confiscated', amount, sourceItem.label, targetXPlayer.name)) + targetXPlayer.showNotification(_U('got_confiscated', amount, sourceItem.label, sourceXPlayer.name)) + else + sourceXPlayer.showNotification(_U('quantity_invalid')) end else - TriggerClientEvent('esx:showNotification', _source, _U('quantity_invalid')) + sourceXPlayer.showNotification(_U('quantity_invalid')) end elseif itemType == 'item_account' then targetXPlayer.removeAccountMoney(itemName, amount) sourceXPlayer.addAccountMoney (itemName, amount) - TriggerClientEvent('esx:showNotification', _source, _U('you_confiscated_account', amount, itemName, targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('got_confiscated_account', amount, itemName, sourceXPlayer.name)) + sourceXPlayer.showNotification(_U('you_confiscated_account', amount, itemName, targetXPlayer.name)) + targetXPlayer.showNotification(_U('got_confiscated_account', amount, itemName, sourceXPlayer.name)) elseif itemType == 'item_weapon' then if amount == nil then amount = 0 end targetXPlayer.removeWeapon(itemName, amount) sourceXPlayer.addWeapon (itemName, amount) - TriggerClientEvent('esx:showNotification', _source, _U('you_confiscated_weapon', ESX.GetWeaponLabel(itemName), targetXPlayer.name, amount)) - TriggerClientEvent('esx:showNotification', target, _U('got_confiscated_weapon', ESX.GetWeaponLabel(itemName), amount, sourceXPlayer.name)) + sourceXPlayer.showNotification(_U('you_confiscated_weapon', ESX.GetWeaponLabel(itemName), targetXPlayer.name, amount)) + targetXPlayer.showNotification(_U('got_confiscated_weapon', ESX.GetWeaponLabel(itemName), amount, sourceXPlayer.name)) end end) @@ -105,7 +105,6 @@ RegisterServerEvent('esx_policejob:getStockItem') AddEventHandler('esx_policejob:getStockItem', function(itemName, count) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) - local sourceItem = xPlayer.getInventoryItem(itemName) TriggerEvent('esx_addoninventory:getSharedInventory', 'society_police', function(inventory) local inventoryItem = inventory.getItem(itemName) @@ -114,15 +113,15 @@ AddEventHandler('esx_policejob:getStockItem', function(itemName, count) if count > 0 and inventoryItem.count >= count then -- can the player carry the said amount of x item? - if sourceItem.limit ~= -1 and (sourceItem.count + count) > sourceItem.limit then - TriggerClientEvent('esx:showNotification', _source, _U('quantity_invalid')) - else + if xPlayer.canCarryItem(itemName, count) then inventory.removeItem(itemName, count) xPlayer.addInventoryItem(itemName, count) - TriggerClientEvent('esx:showNotification', _source, _U('have_withdrawn', count, inventoryItem.label)) + xPlayer.showNotification(_U('have_withdrawn', count, inventoryItem.label)) + else + xPlayer.showNotification(_U('quantity_invalid')) end else - TriggerClientEvent('esx:showNotification', _source, _U('quantity_invalid')) + xPlayer.showNotification(_U('quantity_invalid')) end end) end) @@ -139,9 +138,9 @@ AddEventHandler('esx_policejob:putStockItems', function(itemName, count) if sourceItem.count >= count and count > 0 then xPlayer.removeInventoryItem(itemName, count) inventory.addItem(itemName, count) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('have_deposited', count, inventoryItem.label)) + xPlayer.showNotification(_U('have_deposited', count, inventoryItem.label)) else - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('quantity_invalid')) + xPlayer.showNotification(_U('quantity_invalid')) end end) end) @@ -558,4 +557,4 @@ end) RegisterServerEvent('esx_policejob:message') AddEventHandler('esx_policejob:message', function(target, msg) TriggerClientEvent('esx:showNotification', target, msg) -end) \ No newline at end of file +end) From 5e8b248e0a51ece35de2d43440e998651ff9c167 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 7 Dec 2019 12:44:36 +0100 Subject: [PATCH 2322/3224] Completed server-sided code, and fixed serious caution flaws --- README.md | 2 +- __resource.lua | 25 +++- client/main.lua | 49 ++++--- config.lua | 2 + {client/jobs => jobs}/fisherman.lua | 4 +- {client/jobs => jobs}/fueler.lua | 8 +- {client/jobs => jobs}/lumberjack.lua | 8 +- {client/jobs => jobs}/miner.lua | 14 +- {client/jobs => jobs}/reporter.lua | 0 {client/jobs => jobs}/slaughterer.lua | 8 +- {client/jobs => jobs}/tailor.lua | 8 +- locales/br.lua | 1 + locales/en.lua | 1 + locales/fi.lua | 1 + locales/fr.lua | 1 + locales/sv.lua | 1 + server/main.lua | 180 +++++++++++++++----------- 17 files changed, 181 insertions(+), 132 deletions(-) rename {client/jobs => jobs}/fisherman.lua (98%) rename {client/jobs => jobs}/fueler.lua (98%) rename {client/jobs => jobs}/lumberjack.lua (97%) rename {client/jobs => jobs}/miner.lua (97%) rename {client/jobs => jobs}/reporter.lua (100%) rename {client/jobs => jobs}/slaughterer.lua (97%) rename {client/jobs => jobs}/tailor.lua (98%) diff --git a/README.md b/README.md index 893f0492..9b58d298 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ start esx_jobs ### License esx_jobs - jobs -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2019 Jérémie N'gadi 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. diff --git a/__resource.lua b/__resource.lua index 5abaf658..2cf3ecb0 100644 --- a/__resource.lua +++ b/__resource.lua @@ -12,6 +12,15 @@ server_scripts { 'locales/fr.lua', 'locales/sv.lua', 'config.lua', + + 'jobs/fisherman.lua', + 'jobs/fueler.lua', + 'jobs/lumberjack.lua', + 'jobs/miner.lua', + 'jobs/reporter.lua', + 'jobs/slaughterer.lua', + 'jobs/tailor.lua', + 'server/main.lua' } @@ -23,13 +32,15 @@ client_scripts { 'locales/fr.lua', 'locales/sv.lua', 'config.lua', - 'client/jobs/fisherman.lua', - 'client/jobs/fueler.lua', - 'client/jobs/lumberjack.lua', - 'client/jobs/miner.lua', - 'client/jobs/reporter.lua', - 'client/jobs/slaughterer.lua', - 'client/jobs/tailor.lua', + + 'jobs/fisherman.lua', + 'jobs/fueler.lua', + 'jobs/lumberjack.lua', + 'jobs/miner.lua', + 'jobs/reporter.lua', + 'jobs/slaughterer.lua', + 'jobs/tailor.lua', + 'client/main.lua' } diff --git a/client/main.lua b/client/main.lua index 1db333c1..492c0a81 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,5 +1,5 @@ -local menuIsShowed, hintIsShowed, hintToDisplay, hasAlreadyEnteredMarker, isInMarker, onDuty, vehicleObjInCaseofDrop, vehicleInCaseofDrop, vehicleMaxHealth -local PlayerData, Blips, JobBlips, myPlate, spawner = {}, {}, {}, {}, 0 +local menuIsShowed, hintIsShowed, hintToDisplay, hasAlreadyEnteredMarker, isInMarker, vehicleObjInCaseofDrop, vehicleInCaseofDrop, vehicleMaxHealth +local PlayerData, Blips, JobBlips, myPlate, onDuty, spawner = {}, {}, {}, {}, false, 0 ESX = nil @@ -55,7 +55,7 @@ function OpenMenu() end) end -AddEventHandler('esx_jobs:action', function(job, zone) +AddEventHandler('esx_jobs:action', function(job, zone, zoneIndex) menuIsShowed = true if zone.Type == 'cloakroom' then OpenMenu() @@ -65,7 +65,7 @@ AddEventHandler('esx_jobs:action', function(job, zone) local playerPed = PlayerPedId() if IsPedOnFoot(playerPed) then - TriggerServerEvent('esx_jobs:startWork', zone.Item) + TriggerServerEvent('esx_jobs:startWork', zoneIndex) else ESX.ShowNotification(_U('foot_work')) end @@ -150,7 +150,7 @@ AddEventHandler('esx_jobs:action', function(job, zone) hintToDisplay = nil hintIsShowed = false - TriggerServerEvent('esx_jobs:startWork', zone.Item) + TriggerServerEvent('esx_jobs:startWork', zoneIndex) end --nextStep(zone.GPS) @@ -195,28 +195,25 @@ function deleteBlips() end function refreshBlips() - local zones = {} - local blipInfo = {} - if PlayerData.job then - for jobKey,jobValues in pairs(Config.Jobs) do + local jobObject = Config.Jobs[PlayerData.job.name] - if jobKey == PlayerData.job.name then - for zoneKey,zoneValues in pairs(jobValues.Zones) do + if jobObject then + for k,v in pairs(jobObject.Zones) do + if v.Blip then + local blip = AddBlipForCoord(v.Pos.x, v.Pos.y, v.Pos.z) - if zoneValues.Blip then - local blip = AddBlipForCoord(zoneValues.Pos.x, zoneValues.Pos.y, zoneValues.Pos.z) - SetBlipSprite (blip, jobValues.BlipInfos.Sprite) - SetBlipScale (blip, 1.2) - SetBlipCategory(blip, 3) - SetBlipColour (blip, jobValues.BlipInfos.Color) - SetBlipAsShortRange(blip, true) + SetBlipSprite (blip, jobObject.BlipInfos.Sprite) + SetBlipScale (blip, 1.2) + SetBlipCategory(blip, 3) + SetBlipColour (blip, jobObject.BlipInfos.Color) + SetBlipAsShortRange(blip, true) - BeginTextCommandSetBlipName('STRING') - AddTextComponentSubstringPlayerName(zoneValues.Name) - EndTextCommandSetBlipName(blip) - table.insert(JobBlips, blip) - end + BeginTextCommandSetBlipName('STRING') + AddTextComponentSubstringPlayerName(v.Name) + EndTextCommandSetBlipName(blip) + + table.insert(JobBlips, blip) end end end @@ -273,7 +270,7 @@ end) Citizen.CreateThread(function() while true do Citizen.Wait(0) - local zones, currentZone, isInMarker = {} + local zones, currentZone, currentZoneIndex, isInMarker = {} local letSleep, playerPed = true, PlayerPedId() local playerCoords = GetEntityCoords(playerPed) @@ -293,14 +290,14 @@ Citizen.CreateThread(function() end if distance < v.Size.x then - letSleep, isInMarker, currentZone = false, true, v + letSleep, isInMarker, currentZone, currentZoneIndex = false, true, v, k break end end if IsControlJustReleased(0, 38) and not menuIsShowed and isInMarker then if onDuty or currentZone.Type == 'cloakroom' or PlayerData.job.name == 'reporter' then - TriggerEvent('esx_jobs:action', PlayerData.job.name, currentZone) + TriggerEvent('esx_jobs:action', PlayerData.job.name, currentZone, currentZoneIndex) end end diff --git a/config.lua b/config.lua index 334f1357..676570e8 100644 --- a/config.lua +++ b/config.lua @@ -3,6 +3,8 @@ Config.DrawDistance = 100.0 Config.Locale = 'fr' Config.Jobs = {} +Config.MaxCaution = 10000 -- the max caution allowed + Config.PublicZones = { EnterBuilding = { diff --git a/client/jobs/fisherman.lua b/jobs/fisherman.lua similarity index 98% rename from client/jobs/fisherman.lua rename to jobs/fisherman.lua index 207bc146..f86e332d 100644 --- a/client/jobs/fisherman.lua +++ b/jobs/fisherman.lua @@ -51,7 +51,7 @@ Config.Jobs.fisherman = { { name = _U('fm_fish'), db_name= 'fish', - time = 2000, + time = 2, max = 100, add = 1, remove = 1, @@ -160,7 +160,7 @@ Config.Jobs.fisherman = { Item = { { name = _U('delivery'), - time = 500, + time = 0.5, remove = 1, max = 100, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 11, diff --git a/client/jobs/fueler.lua b/jobs/fueler.lua similarity index 98% rename from client/jobs/fueler.lua rename to jobs/fueler.lua index f34922c5..8b6edeb6 100644 --- a/client/jobs/fueler.lua +++ b/jobs/fueler.lua @@ -42,7 +42,7 @@ Config.Jobs.fueler = { { name = _U('f_fuel'), db_name = 'petrol', - time = 5000, + time = 5, max = 24, add = 1, remove = 1, @@ -67,7 +67,7 @@ Config.Jobs.fueler = { { name = _U('f_fuel_refine'), db_name = 'petrol_raffin', - time = 5000, + time = 5, max = 24, add = 1, remove = 2, @@ -92,7 +92,7 @@ Config.Jobs.fueler = { { name = _U('f_gas'), db_name = 'essence', - time = 5000, + time = 5, max = 24, add = 2, remove = 1, @@ -158,7 +158,7 @@ Config.Jobs.fueler = { Item = { { name = _U('delivery'), - time = 500, + time = 0.5, remove = 1, max = 100, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 61, diff --git a/client/jobs/lumberjack.lua b/jobs/lumberjack.lua similarity index 97% rename from client/jobs/lumberjack.lua rename to jobs/lumberjack.lua index e6892c27..5eca3b24 100644 --- a/client/jobs/lumberjack.lua +++ b/jobs/lumberjack.lua @@ -41,7 +41,7 @@ Config.Jobs.lumberjack = { { name = _U('lj_wood'), db_name = 'wood', - time = 3000, + time = 3, max = 20, add = 1, remove = 1, @@ -65,7 +65,7 @@ Config.Jobs.lumberjack = { { name = _U('lj_cutwood'), db_name = 'cutted_wood', - time = 5000, + time = 5, max = 20, add = 1, remove = 1, @@ -89,7 +89,7 @@ Config.Jobs.lumberjack = { { name = _U('lj_planks'), db_name = 'packaged_plank', - time = 4000, + time = 4, max = 100, add = 5, remove = 1, @@ -152,7 +152,7 @@ Config.Jobs.lumberjack = { Item = { { name = _U('delivery'), - time = 500, + time = 0.5, remove = 1, max = 100, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 13, diff --git a/client/jobs/miner.lua b/jobs/miner.lua similarity index 97% rename from client/jobs/miner.lua rename to jobs/miner.lua index a26041fe..edbffb6d 100644 --- a/client/jobs/miner.lua +++ b/jobs/miner.lua @@ -42,7 +42,7 @@ Config.Jobs.miner = { { name = _U('m_rock'), db_name = 'stone', - time = 3000, + time = 3, max = 7, add = 1, remove = 1, @@ -67,7 +67,7 @@ Config.Jobs.miner = { { name = _U('m_washrock'), db_name = 'washed_stone', - time = 5000, + time = 5, max = 7, add = 1, remove = 1, @@ -92,7 +92,7 @@ Config.Jobs.miner = { { name = _U('m_copper'), db_name = 'copper', - time = 4000, + time = 4, max = 56, add = 8, remove = 1, @@ -179,7 +179,7 @@ Config.Jobs.miner = { Item = { { name = _U('delivery'), - time = 500, + time = 0.5, remove = 1, max = 56, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 5, @@ -205,7 +205,7 @@ Config.Jobs.miner = { Item = { { name = _U('delivery'), - time = 500, + time = 0.5, remove = 1, max = 42, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 9, @@ -231,7 +231,7 @@ Config.Jobs.miner = { Item = { { name = _U('delivery'), - time = 500, + time = 0.5, remove = 1, max = 21, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 25, @@ -257,7 +257,7 @@ Config.Jobs.miner = { Item = { { name = _U('delivery'), - time = 500, + time = 0.5, remove = 1, max = 50, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 250, diff --git a/client/jobs/reporter.lua b/jobs/reporter.lua similarity index 100% rename from client/jobs/reporter.lua rename to jobs/reporter.lua diff --git a/client/jobs/slaughterer.lua b/jobs/slaughterer.lua similarity index 97% rename from client/jobs/slaughterer.lua rename to jobs/slaughterer.lua index 1f7c26f2..d07077c6 100644 --- a/client/jobs/slaughterer.lua +++ b/jobs/slaughterer.lua @@ -40,7 +40,7 @@ Config.Jobs.slaughterer = { { name = _U('s_alive_chicken'), db_name = 'alive_chicken', - time = 3000, + time = 3, max = 20, add = 1, remove = 1, @@ -64,7 +64,7 @@ Config.Jobs.slaughterer = { { name = _U('s_slaughtered_chicken'), db_name = 'slaughtered_chicken', - time = 5000, + time = 5, max = 20, add = 1, remove = 1, @@ -88,7 +88,7 @@ Config.Jobs.slaughterer = { { name = _U('s_packagechicken'), db_name = 'packaged_chicken', - time = 4000, + time = 4, max = 100, add = 5, remove = 1, @@ -151,7 +151,7 @@ Config.Jobs.slaughterer = { Item = { { name = _U('delivery'), - time = 500, + time = 0.5, remove = 1, max = 100, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 23, diff --git a/client/jobs/tailor.lua b/jobs/tailor.lua similarity index 98% rename from client/jobs/tailor.lua rename to jobs/tailor.lua index 2d805c7e..bac08078 100644 --- a/client/jobs/tailor.lua +++ b/jobs/tailor.lua @@ -42,7 +42,7 @@ Config.Jobs.tailor = { { name = _U('dd_wool'), db_name = 'wool', - time = 3000, + time = 3, max = 40, add = 1, remove = 1, @@ -67,7 +67,7 @@ Config.Jobs.tailor = { { name = _U('dd_fabric'), db_name = 'fabric', - time = 5000, + time = 5, max = 80, add = 2, remove = 1, @@ -92,7 +92,7 @@ Config.Jobs.tailor = { { name = _U('dd_clothing'), db_name = 'clothe', - time = 4000, + time = 4, max = 40, add = 1, remove = 2, @@ -158,7 +158,7 @@ Config.Jobs.tailor = { Item = { { name = _U('delivery'), - time = 500, + time = 0.5, remove = 1, max = 100, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 40, diff --git a/locales/br.lua b/locales/br.lua index feff893a..013c4d1d 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -6,6 +6,7 @@ Locales['br'] = { ['job_wear'] = 'colocar uniforme', ['bank_deposit_returned'] = 'um depósito de segurança de ~g~$%s~s~ foi devolvido a você.', ['bank_deposit_taken'] = 'um depósito de segurança de ~g~$%s~s~ foi tirado de você.', + ['caution_afford'] = 'you cannot afford the caution of ~g~$%s~s~', ['foot_work'] = 'você deve estar a pé para poder trabalhar.', ['next_point'] = 'vá para o próximo passo depois de completar este.', ['not_your_vehicle'] = 'este não é o seu veículo ou você deve ser um motorista.', diff --git a/locales/en.lua b/locales/en.lua index 98cc6e61..5d04ac4b 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -6,6 +6,7 @@ Locales['en'] = { ['job_wear'] = 'workers clothes', ['bank_deposit_returned'] = 'a security deposit of ~g~$%s~s~ was returned to you.', ['bank_deposit_taken'] = 'a security deposit of ~r~$%s~s~ was taken from you.', + ['caution_afford'] = 'you cannot afford the caution of ~g~$%s~s~', ['foot_work'] = 'you have to be on foot to be able to work.', ['next_point'] = 'go to the next step after completing this one.', ['not_your_vehicle'] = 'you are not the driver of this vehicle.', diff --git a/locales/fi.lua b/locales/fi.lua index 2d84df38..51236475 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -6,6 +6,7 @@ Locales['fi'] = { ['job_wear'] = 'työvaatteet', ['bank_deposit_returned'] = 'vakuuden summa ~g~€%s~s~ palautettiin sinulle.', ['bank_deposit_taken'] = 'vakuuden summa ~r~€%s~s~ otettiin sinulta.', + ['caution_afford'] = 'you cannot afford the caution of ~g~$%s~s~', ['foot_work'] = 'sinun täytyy olla jalan, jotta voit työskennellä', ['next_point'] = 'mene seuraavaan pisteeseen kun olet valmis täällä', ['not_your_vehicle'] = 'tämä ei ole sinun ajoneuvo tai et ole sen kuski', diff --git a/locales/fr.lua b/locales/fr.lua index 55ebe0ed..7ec5fd24 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -6,6 +6,7 @@ Locales['fr'] = { ['job_wear'] = 'tenue de travail', ['bank_deposit_returned'] = 'une caution de ~g~$%s~s~ vous a été rendue.', ['bank_deposit_taken'] = 'une caution de ~g~$%s~s~ vous a été prélevée.', + ['caution_afford'] = 'you cannot afford the caution of ~g~$%s~s~', ['foot_work'] = 'vous devez être à pied pour pouvoir travailler.', ['next_point'] = 'rendez-vous à la prochaine étape après avoir complété celle-ci.', ['not_your_vehicle'] = 'ce n\'est pas votre véhicule ou vous devez être conducteur.', diff --git a/locales/sv.lua b/locales/sv.lua index 2d0c451f..49a99e88 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -6,6 +6,7 @@ Locales['sv'] = { ['job_wear'] = 'arbetskläder', ['bank_deposit_returned'] = 'en deposition på ~g~%s SEK~s~ har återvänts till dig.', ['bank_deposit_taken'] = 'en deposition på ~r~%s SEK~s~ togs från dig.', + ['caution_afford'] = 'you cannot afford the caution of ~g~$%s~s~', ['foot_work'] = 'du måste vara till fots för att kunna arbeta.', ['next_point'] = 'gå till nästa steg efter att du har avslutat här.', ['not_your_vehicle'] = 'det här är inte ditt fordon eller så måste du vara föraren.', diff --git a/server/main.lua b/server/main.lua index 6463a136..2541f01c 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,105 +1,139 @@ -local PlayersWorking = {} +local playersWorking = {} + ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) -local function Work(source, item) +Citizen.CreateThread(function() + while true do + Citizen.Wait(1000) + local timeNow = os.clock() - SetTimeout(item[1].time, function() + for playerId,data in pairs(playersWorking) do + Citizen.Wait(10) + local xPlayer = ESX.GetPlayerFromId(playerId) - if PlayersWorking[source] == true then + -- is player still online? + if xPlayer then + local distance = #(xPlayer.getCoords(true) - data.zoneCoords) - local xPlayer = ESX.GetPlayerFromId(source) - if xPlayer == nil then - return - end + -- player still within zone limits? + if distance <= data.zoneMaxDistance then + -- calculate the elapsed time + local timeElapsed = timeNow - data.time - for i=1, #item, 1 do - local itemQtty = 0 - if item[i].name ~= _U('delivery') then - itemQtty = xPlayer.getInventoryItem(item[i].db_name).count - end + if timeElapsed > data.jobItem[1].time then + data.time = os.clock() - local requiredItemQtty = 0 - if item[1].requires ~= 'nothing' then - requiredItemQtty = xPlayer.getInventoryItem(item[1].requires).count - end + for k,v in ipairs(data.jobItem) do + local itemQtty, requiredItemQtty = 0, 0 - if item[i].name ~= _U('delivery') and itemQtty >= item[i].max then - xPlayer.showNotification(_U('max_limit', item[i].name)) - elseif item[i].requires ~= 'nothing' and requiredItemQtty <= 0 then - xPlayer.showNotification(_U('not_enough', item[1].requires_name)) - else - if item[i].name ~= _U('delivery') then - -- Chances to drop the item - if item[i].drop == 100 then - xPlayer.addInventoryItem(item[i].db_name, item[i].add) - else - local chanceToDrop = math.random(100) - if chanceToDrop <= item[i].drop then - xPlayer.addInventoryItem(item[i].db_name, item[i].add) + if v.name ~= _U('delivery') then + itemQtty = xPlayer.getInventoryItem(v.db_name).count + end + + if data.jobItem[1].requires ~= 'nothing' then + requiredItemQtty = xPlayer.getInventoryItem(data.jobItem[1].requires).count + end + + if v.name ~= _U('delivery') and itemQtty >= v.max then + xPlayer.showNotification(_U('max_limit', v.name)) + playersWorking[playerId] = nil + elseif v.requires ~= 'nothing' and requiredItemQtty <= 0 then + xPlayer.showNotification(_U('not_enough', data.jobItem[1].requires_name)) + playersWorking[playerId] = nil + else + if v.name ~= _U('delivery') then + -- chances to drop the item + if v.drop == 100 then + xPlayer.addInventoryItem(v.db_name, v.add) + else + local chanceToDrop = math.random(100) + if chanceToDrop <= v.drop then + xPlayer.addInventoryItem(v.db_name, v.add) + end + end + else + xPlayer.addMoney(v.price) + end + end + end + + if data.jobItem[1].requires ~= 'nothing' then + local itemToRemoveQtty = xPlayer.getInventoryItem(data.jobItem[1].requires).count + if itemToRemoveQtty > 0 then + xPlayer.removeInventoryItem(data.jobItem[1].requires, data.jobItem[1].remove) end end - else - xPlayer.addMoney(item[i].price) end + else + playersWorking[playerId] = nil end + else + playersWorking[playerId] = nil end - - if item[1].requires ~= 'nothing' then - local itemToRemoveQtty = xPlayer.getInventoryItem(item[1].requires).count - if itemToRemoveQtty > 0 then - xPlayer.removeInventoryItem(item[1].requires, item[1].remove) - end - end - - Work(source, item) - end - end) -end + end +end) RegisterServerEvent('esx_jobs:startWork') -AddEventHandler('esx_jobs:startWork', function(item) - if not PlayersWorking[source] then - PlayersWorking[source] = true - Work(source, item) - else - print(('esx_jobs: %s attempted to exploit the marker!'):format(GetPlayerIdentifiers(source)[1])) +AddEventHandler('esx_jobs:startWork', function(zoneIndex) + if not playersWorking[source] then + local xPlayer = ESX.GetPlayerFromId(source) + + if xPlayer then + local jobObject = Config.Jobs[xPlayer.job.name] + + if jobObject then + local jobZone = jobObject.Zones[zoneIndex] + + if jobZone and jobZone.Item then + playersWorking[source] = { + jobItem = jobZone.Item, + zoneCoords = vector3(jobZone.Pos.x, jobZone.Pos.y, jobZone.Pos.z), + zoneMaxDistance = jobZone.Size.x, + time = os.clock() + } + end + end + end end end) RegisterServerEvent('esx_jobs:stopWork') AddEventHandler('esx_jobs:stopWork', function() - PlayersWorking[source] = false + if playersWorking[source] then + playersWorking[source] = nil + end end) -RegisterServerEvent('esx_jobs:caution') +RegisterNetEvent('esx_jobs:caution') AddEventHandler('esx_jobs:caution', function(cautionType, cautionAmount, spawnPoint, vehicle) local xPlayer = ESX.GetPlayerFromId(source) if cautionType == 'take' then - TriggerEvent('esx_addonaccount:getAccount', 'caution', xPlayer.identifier, function(account) - xPlayer.removeAccountMoney('bank', cautionAmount) - account.addMoney(cautionAmount) - end) - - xPlayer.showNotification(_U('bank_deposit_taken', ESX.Math.GroupDigits(cautionAmount))) - TriggerClientEvent('esx_jobs:spawnJobVehicle', source, spawnPoint, vehicle) - elseif cautionType == 'give_back' then - - if cautionAmount > 1 then - print(('esx_jobs: %s is using cheat engine!'):format(xPlayer.identifier)) - return + if cautionAmount <= Config.MaxCaution and cautionAmount > 0 then + TriggerEvent('esx_addonaccount:getAccount', 'caution', xPlayer.identifier, function(account) + if xPlayer.getAccount('bank').money >= cautionAmount then + xPlayer.removeAccountMoney('bank', cautionAmount) + account.addMoney(cautionAmount) + xPlayer.showNotification(_U('bank_deposit_taken', ESX.Math.GroupDigits(cautionAmount))) + TriggerClientEvent('esx_jobs:spawnJobVehicle', xPlayer.source, spawnPoint, vehicle) + else + xPlayer.showNotification(_U('caution_afford', ESX.Math.GroupDigits(cautionAmount))) + end + end) + end + elseif cautionType == 'give_back' then + if cautionAmount <= 1 and cautionAmount > 0 then + TriggerEvent('esx_addonaccount:getAccount', 'caution', xPlayer.identifier, function(account) + local caution = account.money + local toGive = ESX.Math.Round(caution * cautionAmount) + + xPlayer.addAccountMoney('bank', toGive) + account.removeMoney(toGive) + TriggerClientEvent('esx:showNotification', source, _U('bank_deposit_returned', ESX.Math.GroupDigits(toGive))) + end) end - - TriggerEvent('esx_addonaccount:getAccount', 'caution', xPlayer.identifier, function(account) - local caution = account.money - local toGive = ESX.Math.Round(caution * cautionAmount) - - xPlayer.addAccountMoney('bank', toGive) - account.removeMoney(toGive) - xPlayer.showNotification(_U('bank_deposit_returned', ESX.Math.GroupDigits(toGive))) - end) end end) From 0439cab26b34f1bbb514108f7c68df380f126a02 Mon Sep 17 00:00:00 2001 From: lemonpea <59174721+lemonpea@users.noreply.github.com> Date: Mon, 23 Dec 2019 17:03:28 +0100 Subject: [PATCH 2323/3224] Add function to replace all elements. This would be nice to have, it would be easier to manage a menu if it's already opened. Here is an example where I would use it. https://gyazo.com/a5b648502bc15c0c629ce3b86d1759cd --- client/functions.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/functions.lua b/client/functions.lua index 95b89359..d3b68d36 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -197,6 +197,10 @@ ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change, menu.setElement = function(i, key, val) menu.data.elements[i][key] = val end + + menu.setElements = function(newElements) + menu.data.elements = newElements + end menu.setTitle = function(val) menu.data.title = val From 28bcb5ca71db1f1597aa0f0cfd536e982b8791a2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 27 Dec 2019 13:00:54 +0100 Subject: [PATCH 2324/3224] Removed commands: /loadipl /unloadipl /playanim /playemote /spawnped /spawnobject --- client/main.lua | 77 --------------------------------------------- locales/br.lua | 7 ----- locales/cs.lua | 7 ----- locales/de.lua | 7 ----- locales/en.lua | 7 ----- locales/fi.lua | 7 ----- locales/fr.lua | 7 ----- locales/pl.lua | 7 ----- locales/sv.lua | 7 ----- server/commands.lua | 73 ++++++++++-------------------------------- 10 files changed, 17 insertions(+), 189 deletions(-) diff --git a/client/main.lua b/client/main.lua index 9c8019c3..5c8be801 100644 --- a/client/main.lua +++ b/client/main.lua @@ -266,47 +266,6 @@ AddEventHandler('esx:setJob', function(job) end end) -RegisterNetEvent('esx:loadIPL') -AddEventHandler('esx:loadIPL', function(name) - Citizen.CreateThread(function() - RequestIpl(name) - end) -end) - -RegisterNetEvent('esx:unloadIPL') -AddEventHandler('esx:unloadIPL', function(name) - Citizen.CreateThread(function() - RemoveIpl(name) - end) -end) - -RegisterNetEvent('esx:playAnim') -AddEventHandler('esx:playAnim', function(dict, anim) - Citizen.CreateThread(function() - local playerPed = PlayerPedId() - RequestAnimDict(dict) - - while not HasAnimDictLoaded(dict) do - Citizen.Wait(1) - end - - TaskPlayAnim(playerPed, dict, anim, 1.0, -1.0, 20000, 0, 1, true, true, true) - end) -end) - -RegisterNetEvent('esx:playEmote') -AddEventHandler('esx:playEmote', function(emote) - Citizen.CreateThread(function() - - local playerPed = PlayerPedId() - - TaskStartScenarioInPlace(playerPed, emote, 0, false); - Citizen.Wait(20000) - ClearPedTasks(playerPed) - - end) -end) - RegisterNetEvent('esx:spawnVehicle') AddEventHandler('esx:spawnVehicle', function(model) local playerPed = PlayerPedId() @@ -317,23 +276,6 @@ AddEventHandler('esx:spawnVehicle', function(model) end) end) -RegisterNetEvent('esx:spawnObject') -AddEventHandler('esx:spawnObject', function(model) - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - local forward = GetEntityForwardVector(playerPed) - local x, y, z = table.unpack(coords + forward * 1.0) - - ESX.Game.SpawnObject(model, { - x = x, - y = y, - z = z - }, function(obj) - SetEntityHeading(obj, GetEntityHeading(playerPed)) - PlaceObjectOnGroundProperly(obj) - end) -end) - RegisterNetEvent('esx:pickup') AddEventHandler('esx:pickup', function(id, label, player) local ped = GetPlayerPed(GetPlayerFromServerId(player)) @@ -374,25 +316,6 @@ AddEventHandler('esx:pickupWeapon', function(weaponPickup, weaponName, ammo) CreateAmbientPickup(weaponHash, pickupCoords, 0, ammo, 1, false, true) end) -RegisterNetEvent('esx:spawnPed') -AddEventHandler('esx:spawnPed', function(model) - model = (tonumber(model) ~= nil and tonumber(model) or GetHashKey(model)) - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - local forward = GetEntityForwardVector(playerPed) - local x, y, z = table.unpack(coords + forward * 1.0) - - Citizen.CreateThread(function() - RequestModel(model) - - while not HasModelLoaded(model) do - Citizen.Wait(1) - end - - CreatePed(5, model, x, y, z, 0.0, true, false) - end) -end) - RegisterNetEvent('esx:deleteVehicle') AddEventHandler('esx:deleteVehicle', function() local playerPed = PlayerPedId() diff --git a/locales/br.lua b/locales/br.lua index 6dc07cba..e2c5b503 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -53,16 +53,9 @@ Locales['br'] = { ['id_param'] = 'o ID do jogador', ['setjob_param2'] = 'o trabalho que voce deseja atribuir', ['setjob_param3'] = 'o nivel de emprego', - ['load_ipl'] = 'carregar IPL', - ['unload_ipl'] = 'descarregar o IPL', - ['play_anim'] = 'Iniciar animacao', - ['play_emote'] = 'Iniciar emote', ['spawn_car'] = 'spawn um carro', ['spawn_car_param'] = 'nome do carro', ['delete_vehicle'] = 'excluir Veiculo', - ['spawn_object'] = 'spawn objeto', - ['spawn_ped'] = 'spawn ped', - ['spawn_ped_param'] = 'exemplo a_m_m_hillbilly_01', ['givemoney'] = 'dar dinheiro', ['setmoney'] = 'set money for a player', ['money_type'] = 'valid money types: cash, bank, black', diff --git a/locales/cs.lua b/locales/cs.lua index 92e3c5f4..c1dc7c82 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -53,16 +53,9 @@ Locales['cs'] = { ['id_param'] = 'iD hráče', ['setjob_param2'] = 'název přiřazované práce', ['setjob_param3'] = 'úroveň práce', - ['load_ipl'] = 'načíst IPL', - ['unload_ipl'] = 'odnačíst IPL', - ['play_anim'] = 'přehrát animaci', - ['play_emote'] = 'přehrát emoci', ['spawn_car'] = 'spawn auto', ['spawn_car_param'] = 'název auta', ['delete_vehicle'] = 'odstranit vozidlo', - ['spawn_object'] = 'spawn objekt', - ['spawn_ped'] = 'spawn peda', - ['spawn_ped_param'] = 'příklad a_m_m_hillbilly_01', ['givemoney'] = 'dát peníze', ['setmoney'] = 'nastavit peníze hráči', ['money_type'] = 'platné typy peněz: cash, bank, black', diff --git a/locales/de.lua b/locales/de.lua index 91cf4c82..3ba684dd 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -53,16 +53,9 @@ Locales['de'] = { ['id_param'] = 'the ID of the player', ['setjob_param2'] = 'the job you wish to assign', ['setjob_param3'] = 'the job level', - ['load_ipl'] = 'load IPL', - ['unload_ipl'] = 'unload IPL', - ['play_anim'] = 'play animation', - ['play_emote'] = 'play emote', ['spawn_car'] = 'spawn a car', ['spawn_car_param'] = 'name of car', ['delete_vehicle'] = 'deletes Vehicle', - ['spawn_object'] = 'spawn object', - ['spawn_ped'] = 'spawn ped', - ['spawn_ped_param'] = 'example a_m_m_hillbilly_01', ['givemoney'] = 'give money', ['setmoney'] = 'set money for a player', ['money_type'] = 'valid money types: cash, bank, black', diff --git a/locales/en.lua b/locales/en.lua index ecb89bff..d10db002 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -53,16 +53,9 @@ Locales['en'] = { ['id_param'] = 'the ID of the player', ['setjob_param2'] = 'the job you wish to assign', ['setjob_param3'] = 'the job level', - ['load_ipl'] = 'load IPL', - ['unload_ipl'] = 'unload IPL', - ['play_anim'] = 'play animation', - ['play_emote'] = 'play emote', ['spawn_car'] = 'spawn a car', ['spawn_car_param'] = 'name of car', ['delete_vehicle'] = 'deletes Vehicle', - ['spawn_object'] = 'spawn object', - ['spawn_ped'] = 'spawn ped', - ['spawn_ped_param'] = 'example a_m_m_hillbilly_01', ['givemoney'] = 'give money', ['setmoney'] = 'set money for a player', ['money_type'] = 'valid money types: cash, bank, black', diff --git a/locales/fi.lua b/locales/fi.lua index 5cbca385..0898fde3 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -53,16 +53,9 @@ Locales['fi'] = { ['id_param'] = 'käyttäjän ID', ['setjob_param2'] = 'työ jonka haluat määrittää', ['setjob_param3'] = 'työn taso', - ['load_ipl'] = 'lataa IPL', - ['unload_ipl'] = 'poista IPL', - ['play_anim'] = 'toista animaatio', - ['play_emote'] = 'toista ele', ['spawn_car'] = 'spawnaa ajoneuvo', ['spawn_car_param'] = 'ajoneuvon nimi', ['delete_vehicle'] = 'poistaa ajoneuvon', - ['spawn_object'] = 'spawnaa objekti', - ['spawn_ped'] = 'spawnaa pedi', - ['spawn_ped_param'] = 'esimerkki a_m_m_hillbilly_01', ['givemoney'] = 'anna rahaa', ['setmoney'] = 'aseta pelaajan rahat', ['money_type'] = 'hyväksytyt rahatyypit: cash, bank, black', diff --git a/locales/fr.lua b/locales/fr.lua index b3f77b7c..09266cfd 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -53,16 +53,9 @@ Locales['fr'] = { ['id_param'] = 'identification du joueur', ['setjob_param2'] = 'le travail que vous souhaitez assigner', ['setjob_param3'] = 'le niveau d\'emploi', - ['load_ipl'] = 'charger IPL', - ['unload_ipl'] = 'décharger IPL', - ['play_anim'] = 'jouer animation', - ['play_emote'] = 'jouer emote', ['spawn_car'] = 'spawn un véhicule', ['spawn_car_param'] = 'nom de la voiture', ['delete_vehicle'] = 'supprimer le véhicule', - ['spawn_object'] = 'engendre un objet', - ['spawn_ped'] = 'spawn ped', - ['spawn_ped_param'] = 'example a_m_m_hillbilly_01', ['givemoney'] = 'donner de l\'argent', ['setmoney'] = 'définir l\'argent pour un joueur', ['money_type'] = 'types de monnaies valides: cash, bank, black', diff --git a/locales/pl.lua b/locales/pl.lua index 09e61c5a..a67dc75a 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -53,16 +53,9 @@ Locales['pl'] = { ['id_param'] = 'ID użytkownika', ['setjob_param2'] = 'praca, którą chcesz przydzielić', ['setjob_param3'] = 'poziom pracy', - ['load_ipl'] = 'załaduj IPL', - ['unload_ipl'] = 'usuń IPL', - ['play_anim'] = 'uruchom animację', - ['play_emote'] = 'uruchom emocje', ['spawn_car'] = 'sprowadź pojazd', ['spawn_car_param'] = 'nazwa samochodu', ['delete_vehicle'] = 'usuń pojazd', - ['spawn_object'] = 'pojaw obiekt', - ['spawn_ped'] = 'pojaw peda', - ['spawn_ped_param'] = 'np. a_m_m_hillbilly_01', ['givemoney'] = 'daj pieniądze', ['setmoney'] = 'ustaw pieniądze dla gracza', ['money_type'] = 'aktualne typy pieniędzy: cash, bank, black', diff --git a/locales/sv.lua b/locales/sv.lua index d15ce060..d0ab8171 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -53,16 +53,9 @@ Locales['sv'] = { ['id_param'] = 'spelarens ID', ['setjob_param2'] = 'det jobb du vill tilldela', ['setjob_param3'] = 'job level', - ['load_ipl'] = 'load IPL', - ['unload_ipl'] = 'unload IPL', - ['play_anim'] = 'spela animering', - ['play_emote'] = 'spela emote', ['spawn_car'] = 'spawna ett fordon', ['spawn_car_param'] = 'namn på fordon', ['delete_vehicle'] = 'ta bort fordon', - ['spawn_object'] = 'spawna föremål', - ['spawn_ped'] = 'spawna NPC', - ['spawn_ped_param'] = 'exempelvis a_m_m_hillbilly_01', ['givemoney'] = 'ge pengar', ['setmoney'] = 'bestäm mängd pengar till en valfri person', ['money_type'] = 'giltiga typer: cash, bank, black', diff --git a/server/commands.lua b/server/commands.lua index 20044962..097fef9a 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -26,7 +26,6 @@ TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, else TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'That job does not exist.' } }) end - else TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) end @@ -37,30 +36,6 @@ end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('setjob'), params = {{name = 'id', help = _U('id_param')}, {name = 'job', help = _U('setjob_param2')}, {name = 'grade_id', help = _U('setjob_param3')}}}) -TriggerEvent('es:addGroupCommand', 'loadipl', 'admin', function(source, args, user) - TriggerClientEvent('esx:loadIPL', -1, args[1]) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('load_ipl')}) - -TriggerEvent('es:addGroupCommand', 'unloadipl', 'admin', function(source, args, user) - TriggerClientEvent('esx:unloadIPL', -1, args[1]) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('unload_ipl')}) - -TriggerEvent('es:addGroupCommand', 'playanim', 'admin', function(source, args, user) - TriggerClientEvent('esx:playAnim', -1, args[1], args[3]) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('play_anim')}) - -TriggerEvent('es:addGroupCommand', 'playemote', 'admin', function(source, args, user) - TriggerClientEvent('esx:playEmote', -1, args[1]) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('play_emote')}) - TriggerEvent('es:addGroupCommand', 'car', 'admin', function(source, args, user) TriggerClientEvent('esx:spawnVehicle', source, args[1]) end, function(source, args, user) @@ -79,18 +54,6 @@ end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('delete_vehicle')}) -TriggerEvent('es:addGroupCommand', 'spawnped', 'admin', function(source, args, user) - TriggerClientEvent('esx:spawnPed', source, args[1]) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('spawn_ped'), params = {{name = 'name', help = _U('spawn_ped_param')}}}) - -TriggerEvent('es:addGroupCommand', 'spawnobject', 'admin', function(source, args, user) - TriggerClientEvent('esx:spawnObject', source, args[1]) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('spawn_object'), params = {{name = 'name'}}}) - TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, user) local _source = source local target = tonumber(args[1]) @@ -99,7 +62,7 @@ TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, u local xPlayer = ESX.GetPlayerFromId(target) - if target and money_type and money_amount and xPlayer ~= nil then + if target and money_type and money_amount and xPlayer then if money_type == 'cash' then xPlayer.setMoney(money_amount) elseif money_type == 'bank' then @@ -130,8 +93,8 @@ TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, local account = args[2] local amount = tonumber(args[3]) - if amount ~= nil then - if xPlayer.getAccount(account) ~= nil then + if amount then + if xPlayer.getAccount(account) then xPlayer.addAccountMoney(account, amount) else TriggerClientEvent('esx:showNotification', _source, _U('invalid_account')) @@ -149,8 +112,8 @@ TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, u local item = args[2] local count = (args[3] == nil and 1 or tonumber(args[3])) - if count ~= nil then - if xPlayer.getInventoryItem(item) ~= nil then + if count then + if xPlayer.getInventoryItem(item) then xPlayer.addInventoryItem(item, count) else TriggerClientEvent('esx:showNotification', _source, _U('invalid_item')) @@ -216,15 +179,14 @@ TriggerEvent('es:addGroupCommand', 'clearinventory', 'admin', function(source, a xPlayer = ESX.GetPlayerFromId(source) end - if not xPlayer then - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) - return - end - - for i=1, #xPlayer.inventory, 1 do - if xPlayer.inventory[i].count > 0 then - xPlayer.setInventoryItem(xPlayer.inventory[i].name, 0) + if xPlayer then + for i=1, #xPlayer.inventory, 1 do + if xPlayer.inventory[i].count > 0 then + xPlayer.setInventoryItem(xPlayer.inventory[i].name, 0) + end end + else + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) @@ -239,13 +201,12 @@ TriggerEvent('es:addGroupCommand', 'clearloadout', 'admin', function(source, arg xPlayer = ESX.GetPlayerFromId(source) end - if not xPlayer then + if xPlayer then + for i=#xPlayer.loadout, 1, -1 do + xPlayer.removeWeapon(xPlayer.loadout[i].name) + end + else TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) - return - end - - for i=#xPlayer.loadout, 1, -1 do - xPlayer.removeWeapon(xPlayer.loadout[i].name) end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) From f0130e8f384950165b76a3e5135a5912dcd39b3b Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 27 Dec 2019 13:39:31 +0100 Subject: [PATCH 2325/3224] player.lua: test nil values --- server/classes/player.lua | 105 +++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 42 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 8e67fe7f..350a20e3 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -263,16 +263,19 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end local account = self.getAccount(acc) - local prevMoney = account.money - local newMoney = ESX.Math.Round(money) - account.money = newMoney - - if acc == 'bank' then - self.set('bank', newMoney) + if account then + local prevMoney = account.money + local newMoney = ESX.Math.Round(money) + + account.money = newMoney + + if acc == 'bank' then + self.set('bank', newMoney) + end + + TriggerClientEvent('esx:setAccountMoney', self.source, account) end - - TriggerClientEvent('esx:setAccountMoney', self.source, account) end self.addAccountMoney = function(acc, money) @@ -282,15 +285,17 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end local account = self.getAccount(acc) - local newMoney = account.money + ESX.Math.Round(money) - account.money = newMoney - - if acc == 'bank' then - self.set('bank', newMoney) + if account then + local newMoney = account.money + ESX.Math.Round(money) + account.money = newMoney + + if acc == 'bank' then + self.set('bank', newMoney) + end + + TriggerClientEvent('esx:setAccountMoney', self.source, account) end - - TriggerClientEvent('esx:setAccountMoney', self.source, account) end self.removeAccountMoney = function(acc, money) @@ -300,15 +305,17 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end local account = self.getAccount(acc) - local newMoney = account.money - ESX.Math.Round(money) - account.money = newMoney - - if acc == 'bank' then - self.set('bank', newMoney) + if account then + local newMoney = account.money - ESX.Math.Round(money) + account.money = newMoney + + if acc == 'bank' then + self.set('bank', newMoney) + end + + TriggerClientEvent('esx:setAccountMoney', self.source, account) end - - TriggerClientEvent('esx:setAccountMoney', self.source, account) end self.getInventoryItem = function(name) @@ -317,37 +324,51 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l return v end end + + return end self.addInventoryItem = function(name, count) - local item = self.getInventoryItem(name) - local newCount = item.count + count - item.count = newCount + local item = self.getInventoryItem(name) - TriggerEvent('esx:onAddInventoryItem', self.source, item, count) - TriggerClientEvent('esx:addInventoryItem', self.source, item, count) + if item then + local newCount = item.count + count + item.count = newCount + + TriggerEvent('esx:onAddInventoryItem', self.source, item, count) + TriggerClientEvent('esx:addInventoryItem', self.source, item, count) + end end self.removeInventoryItem = function(name, count) - local item = self.getInventoryItem(name) - local newCount = item.count - count - item.count = newCount + local item = self.getInventoryItem(name) - TriggerEvent('esx:onRemoveInventoryItem', self.source, item, count) - TriggerClientEvent('esx:removeInventoryItem', self.source, item, count) + if item then + local newCount = item.count - count + + if newCount >= 0 then + item.count = newCount + + TriggerEvent('esx:onRemoveInventoryItem', self.source, item, count) + TriggerClientEvent('esx:removeInventoryItem', self.source, item, count) + end + end end self.setInventoryItem = function(name, count) - local item = self.getInventoryItem(name) - local oldCount = item.count - item.count = count + local item = self.getInventoryItem(name) - if oldCount > item.count then - TriggerEvent('esx:onRemoveInventoryItem', self.source, item, oldCount - item.count) - TriggerClientEvent('esx:removeInventoryItem', self.source, item, oldCount - item.count) - else - TriggerEvent('esx:onAddInventoryItem', self.source, item, item.count - oldCount) - TriggerClientEvent('esx:addInventoryItem', self.source, item, item.count - oldCount) + if item and count >= 0 then + local oldCount = item.count + item.count = count + + if oldCount > item.count then + TriggerEvent('esx:onRemoveInventoryItem', self.source, item, oldCount - item.count) + TriggerClientEvent('esx:removeInventoryItem', self.source, item, oldCount - item.count) + else + TriggerEvent('esx:onAddInventoryItem', self.source, item, item.count - oldCount) + TriggerClientEvent('esx:addInventoryItem', self.source, item, item.count - oldCount) + end end end @@ -522,7 +543,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end end - return nil + return end self.showNotification = function(msg) From f9afa6f01790aec37d7a21521ac141263d30dcf7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 27 Dec 2019 13:45:53 +0100 Subject: [PATCH 2326/3224] player.lua: implement canSwapItem() and triggerEvent() --- server/classes/player.lua | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/server/classes/player.lua b/server/classes/player.lua index 350a20e3..617c04af 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -13,6 +13,10 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.source = self.player.get('source') self.identifier = self.player.get('identifier') + self.triggerEvent = function(eventName, ...) + TriggerClientEvent(eventName, self.source, ...) + end + self.setMoney = function(money) money = ESX.Math.Round(money) @@ -389,6 +393,20 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l return newWeight <= self.maxWeight end + self.canSwapItem = function(firstItem, firstItemCount, testItem, testItemCount) + local firstItemObject = self.getInventoryItem(firstItem) + local testItemObject = self.getInventoryItem(testItem) + + if firstItemObject.count >= firstItemCount then + local weightWithoutFirstItem = ESX.Math.Round(self.getWeight() - (firstItemObject.weight * firstItemCount)) + local weightWithTestItem = ESX.Math.Round(weightWithoutFirstItem + (testItemObject.weight * testItemCount)) + + return weightWithTestItem <= self.maxWeight + end + + return false + end + self.setMaxWeight = function(newWeight) self.maxWeight = newWeight TriggerClientEvent('esx:setMaxWeight', self.source, self.maxWeight) From aad435842bb86e525fc094b8144846321b3c4b15 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 27 Dec 2019 13:47:18 +0100 Subject: [PATCH 2327/3224] Update player.lua --- server/classes/player.lua | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 617c04af..002d2850 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -271,13 +271,13 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if account then local prevMoney = account.money local newMoney = ESX.Math.Round(money) - + account.money = newMoney - + if acc == 'bank' then self.set('bank', newMoney) end - + TriggerClientEvent('esx:setAccountMoney', self.source, account) end end @@ -293,11 +293,11 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if account then local newMoney = account.money + ESX.Math.Round(money) account.money = newMoney - + if acc == 'bank' then self.set('bank', newMoney) end - + TriggerClientEvent('esx:setAccountMoney', self.source, account) end end @@ -313,11 +313,11 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if account then local newMoney = account.money - ESX.Math.Round(money) account.money = newMoney - + if acc == 'bank' then self.set('bank', newMoney) end - + TriggerClientEvent('esx:setAccountMoney', self.source, account) end end @@ -338,7 +338,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if item then local newCount = item.count + count item.count = newCount - + TriggerEvent('esx:onAddInventoryItem', self.source, item, count) TriggerClientEvent('esx:addInventoryItem', self.source, item, count) end @@ -352,7 +352,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if newCount >= 0 then item.count = newCount - + TriggerEvent('esx:onRemoveInventoryItem', self.source, item, count) TriggerClientEvent('esx:removeInventoryItem', self.source, item, count) end @@ -365,7 +365,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if item and count >= 0 then local oldCount = item.count item.count = count - + if oldCount > item.count then TriggerEvent('esx:onRemoveInventoryItem', self.source, item, oldCount - item.count) TriggerClientEvent('esx:removeInventoryItem', self.source, item, oldCount - item.count) @@ -514,7 +514,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l break end end - + TriggerClientEvent('esx:removeWeaponComponent', self.source, weaponName, weaponComponent) end end @@ -537,7 +537,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l return true end end - + return false else return false From 2d80e556311c6026ef4a6910b404b13fd7414e08 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 27 Dec 2019 13:49:40 +0100 Subject: [PATCH 2328/3224] rename _source variable to playerId --- server/classes/player.lua | 6 +++--- server/commands.lua | 20 ++++++++++---------- server/common.lua | 6 +++--- server/main.lua | 28 ++++++++++++++-------------- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 002d2850..d74b6429 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -456,10 +456,10 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l label = weaponLabel, components = {} }) - end - TriggerClientEvent('esx:addWeapon', self.source, weaponName, ammo) - TriggerClientEvent('esx:addInventoryItem', self.source, {label = weaponLabel}, 1) + TriggerClientEvent('esx:addWeapon', self.source, weaponName, ammo) + TriggerClientEvent('esx:addInventoryItem', self.source, {label = weaponLabel}, 1) + end end self.addWeaponComponent = function(weaponName, weaponComponent) diff --git a/server/commands.lua b/server/commands.lua index 097fef9a..b240f84d 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -55,7 +55,7 @@ end, function(source, args, user) end, {help = _U('delete_vehicle')}) TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, user) - local _source = source + local playerId = source local target = tonumber(args[1]) local money_type = args[2] local money_amount = tonumber(args[3]) @@ -70,17 +70,17 @@ TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, u elseif money_type == 'black' then xPlayer.setAccountMoney('black_money', money_amount) else - TriggerClientEvent('chatMessage', _source, 'SYSTEM', {255, 0, 0}, '^2' .. money_type .. ' ^0 is not a valid money type!') + TriggerClientEvent('chatMessage', playerId, 'SYSTEM', {255, 0, 0}, '^2' .. money_type .. ' ^0 is not a valid money type!') return end else - TriggerClientEvent('chatMessage', _source, 'SYSTEM', {255, 0, 0}, 'Invalid arguments.') + TriggerClientEvent('chatMessage', playerId, 'SYSTEM', {255, 0, 0}, 'Invalid arguments.') return end print('es_extended: ' .. GetPlayerName(source) .. ' just set $' .. money_amount .. ' (' .. money_type .. ') to ' .. xPlayer.name) - if xPlayer.source ~= _source then + if xPlayer.source ~= playerId then TriggerClientEvent('esx:showNotification', xPlayer.source, _U('money_set', money_amount, money_type)) end end, function(source, args, user) @@ -88,7 +88,7 @@ end, function(source, args, user) end, {help = _U('setmoney'), params = {{name = 'id', help = _U('id_param')}, {name = 'money type', help = _U('money_type')}, {name = 'amount', help = _U('money_amount')}}}) TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, args, user) - local _source = source + local playerId = source local xPlayer = ESX.GetPlayerFromId(args[1]) local account = args[2] local amount = tonumber(args[3]) @@ -97,17 +97,17 @@ TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, if xPlayer.getAccount(account) then xPlayer.addAccountMoney(account, amount) else - TriggerClientEvent('esx:showNotification', _source, _U('invalid_account')) + TriggerClientEvent('esx:showNotification', playerId, _U('invalid_account')) end else - TriggerClientEvent('esx:showNotification', _source, _U('amount_invalid')) + TriggerClientEvent('esx:showNotification', playerId, _U('amount_invalid')) end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('giveaccountmoney'), params = {{name = 'id', help = _U('id_param')}, {name = 'account', help = _U('account')}, {name = 'amount', help = _U('money_amount')}}}) TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, user) - local _source = source + local playerId = source local xPlayer = ESX.GetPlayerFromId(args[1]) local item = args[2] local count = (args[3] == nil and 1 or tonumber(args[3])) @@ -116,10 +116,10 @@ TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, u if xPlayer.getInventoryItem(item) then xPlayer.addInventoryItem(item, count) else - TriggerClientEvent('esx:showNotification', _source, _U('invalid_item')) + TriggerClientEvent('esx:showNotification', playerId, _U('invalid_item')) end else - TriggerClientEvent('esx:showNotification', _source, _U('invalid_amount')) + TriggerClientEvent('esx:showNotification', playerId, _U('invalid_amount')) end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) diff --git a/server/common.lua b/server/common.lua index ed937f54..a72e024e 100644 --- a/server/common.lua +++ b/server/common.lua @@ -83,9 +83,9 @@ end) RegisterServerEvent('esx:triggerServerCallback') AddEventHandler('esx:triggerServerCallback', function(name, requestId, ...) - local _source = source + local playerId = source - ESX.TriggerServerCallback(name, requestID, _source, function(...) - TriggerClientEvent('esx:serverCallback', _source, requestId, ...) + ESX.TriggerServerCallback(name, requestID, playerId, function(...) + TriggerClientEvent('esx:serverCallback', playerId, requestId, ...) end, ...) end) diff --git a/server/main.lua b/server/main.lua index 689e8b35..4a224094 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,5 +1,5 @@ AddEventHandler('es:playerLoaded', function(source, _player) - local _source = source + local playerId = source local tasks = {} local userData = { @@ -7,11 +7,11 @@ AddEventHandler('es:playerLoaded', function(source, _player) inventory = {}, job = {}, loadout = {}, - playerName = GetPlayerName(_source), + playerName = GetPlayerName(playerId), lastPosition = nil } - TriggerEvent('es:getPlayerFromId', _source, function(player) + TriggerEvent('es:getPlayerFromId', playerId, function(player) -- Update user name in DB table.insert(tasks, function(cb) MySQL.Async.execute('UPDATE users SET name = @name WHERE identifier = @identifier', { @@ -208,11 +208,11 @@ AddEventHandler('es:playerLoaded', function(source, _player) xPlayer.createAccounts(missingAccounts) end - ESX.Players[_source] = xPlayer + ESX.Players[playerId] = xPlayer - TriggerEvent('esx:playerLoaded', _source, xPlayer) + TriggerEvent('esx:playerLoaded', playerId, xPlayer) - TriggerClientEvent('esx:playerLoaded', _source, { + TriggerClientEvent('esx:playerLoaded', playerId, { identifier = xPlayer.identifier, accounts = xPlayer.getAccounts(), inventory = xPlayer.getInventory(), @@ -224,7 +224,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) }) xPlayer.displayMoney(xPlayer.getMoney()) - TriggerClientEvent('esx:createMissingPickups', _source, ESX.Pickups) + TriggerClientEvent('esx:createMissingPickups', playerId, ESX.Pickups) end) end) @@ -232,15 +232,15 @@ AddEventHandler('es:playerLoaded', function(source, _player) end) AddEventHandler('playerDropped', function(reason) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) + local playerId = source + local xPlayer = ESX.GetPlayerFromId(playerId) if xPlayer then - TriggerEvent('esx:playerDropped', _source, reason) + TriggerEvent('esx:playerDropped', playerId, reason) ESX.SavePlayer(xPlayer, function() - ESX.Players[_source] = nil - ESX.LastPlayerData[_source] = nil + ESX.Players[playerId] = nil + ESX.LastPlayerData[playerId] = nil end) end end) @@ -419,9 +419,9 @@ end) RegisterServerEvent('esx:onPickup') AddEventHandler('esx:onPickup', function(id) - local _source = source + local playerId = source local pickup = ESX.Pickups[id] - local xPlayer = ESX.GetPlayerFromId(_source) + local xPlayer = ESX.GetPlayerFromId(playerId) if pickup.type == 'item_standard' then if xPlayer.canCarryItem(pickup.name, pickup.count) then From 756a13f3bb682aab36f32bc9782d6cfefdf664f2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 27 Dec 2019 14:09:07 +0100 Subject: [PATCH 2329/3224] Add vehicle test for /car command, and use IsModelInCdimage() native --- client/main.lua | 18 ++++++++++++------ client/modules/streaming.lua | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/client/main.lua b/client/main.lua index 5c8be801..8e7d3a4a 100644 --- a/client/main.lua +++ b/client/main.lua @@ -267,13 +267,19 @@ AddEventHandler('esx:setJob', function(job) end) RegisterNetEvent('esx:spawnVehicle') -AddEventHandler('esx:spawnVehicle', function(model) - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) +AddEventHandler('esx:spawnVehicle', function(vehicle) + local model = (type(vehicle) == 'number' and vehicle or GetHashKey(vehicle)) - ESX.Game.SpawnVehicle(model, coords, 90.0, function(vehicle) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - end) + if IsModelInCdimage(model) then + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) + + ESX.Game.SpawnVehicle(model, coords, 90.0, function(vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + end) + else + TriggerEvent('chat:addMessage', { args = { '^1SYSTEM', 'Invalid vehicle model.' } }) + end end) RegisterNetEvent('esx:pickup') diff --git a/client/modules/streaming.lua b/client/modules/streaming.lua index 143d0c0c..69fffe72 100644 --- a/client/modules/streaming.lua +++ b/client/modules/streaming.lua @@ -1,7 +1,7 @@ function ESX.Streaming.RequestModel(modelHash, cb) modelHash = (type(modelHash) == 'number' and modelHash or GetHashKey(modelHash)) - if not HasModelLoaded(modelHash) then + if not HasModelLoaded(modelHash) and IsModelInCdimage(modelHash) then RequestModel(modelHash) while not HasModelLoaded(modelHash) do From 418767514876674161fd7088bad2c1ba58fe8ea4 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 27 Dec 2019 14:49:29 +0100 Subject: [PATCH 2330/3224] /dv command changes (see desc) - Added optional /dv argument for deleting vehicles in proximity - Use RequestControlOfEntity native to properly delete entities --- client/main.lua | 40 +++++++++++++++++++++++++++++++++------- server/commands.lua | 12 ++++++++---- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/client/main.lua b/client/main.lua index 8e7d3a4a..cc23ba5f 100644 --- a/client/main.lua +++ b/client/main.lua @@ -323,16 +323,42 @@ AddEventHandler('esx:pickupWeapon', function(weaponPickup, weaponName, ammo) end) RegisterNetEvent('esx:deleteVehicle') -AddEventHandler('esx:deleteVehicle', function() +AddEventHandler('esx:deleteVehicle', function(radius) local playerPed = PlayerPedId() - local vehicle = ESX.Game.GetVehicleInDirection() - if IsPedInAnyVehicle(playerPed, true) then - vehicle = GetVehiclePedIsIn(playerPed, false) - end + if radius and tonumber(radius) then + radius = tonumber(radius) + 0.01 + local vehicles = ESX.Game.GetVehiclesInArea(GetEntityCoords(playerPed), radius) - if DoesEntityExist(vehicle) then - ESX.Game.DeleteVehicle(vehicle) + for k,entity in ipairs(vehicles) do + local attempt = 0 + + while not NetworkHasControlOfEntity(entity) and attempt < 100 and DoesEntityExist(entity) do + Citizen.Wait(100) + NetworkRequestControlOfEntity(entity) + attempt = attempt + 1 + end + + if DoesEntityExist(entity) and NetworkHasControlOfEntity(entity) then + ESX.Game.DeleteVehicle(entity) + end + end + else + local vehicle, attempt = ESX.Game.GetVehicleInDirection(), 0 + + if IsPedInAnyVehicle(playerPed, true) then + vehicle = GetVehiclePedIsIn(playerPed, false) + end + + while not NetworkHasControlOfEntity(vehicle) and attempt < 100 and DoesEntityExist(vehicle) do + Citizen.Wait(100) + NetworkRequestControlOfEntity(vehicle) + attempt = attempt + 1 + end + + if DoesEntityExist(vehicle) and NetworkHasControlOfEntity(vehicle) then + ESX.Game.DeleteVehicle(vehicle) + end end end) diff --git a/server/commands.lua b/server/commands.lua index b240f84d..32e8447f 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -43,16 +43,20 @@ end, function(source, args, user) end, {help = _U('spawn_car'), params = {{name = 'car', help = _U('spawn_car_param')}}}) TriggerEvent('es:addGroupCommand', 'cardel', 'admin', function(source, args, user) - TriggerClientEvent('esx:deleteVehicle', source) + TriggerClientEvent('esx:deleteVehicle', source, args[1]) end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('delete_vehicle')}) +end, {help = _U('delete_vehicle'), params = { + {name = 'radius', help = 'Optional, delete every vehicle within the specified radius'} +}}) TriggerEvent('es:addGroupCommand', 'dv', 'admin', function(source, args, user) - TriggerClientEvent('esx:deleteVehicle', source) + TriggerClientEvent('esx:deleteVehicle', source, args[1]) end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('delete_vehicle')}) +end, {help = _U('delete_vehicle'), params = { + {name = 'radius', help = 'Optional, delete every vehicle within the specified radius'} +}}) TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, user) local playerId = source From 8eb1acd0825015940a4e4591c74944f2df42311e Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 2 Jan 2020 14:31:46 +0100 Subject: [PATCH 2331/3224] Fixed round function not properly working in some locales, closes #258 --- common/modules/math.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/modules/math.lua b/common/modules/math.lua index 6b4a4a5d..99a87631 100644 --- a/common/modules/math.lua +++ b/common/modules/math.lua @@ -1,7 +1,8 @@ ESX.Math = {} ESX.Math.Round = function(value, numDecimalPlaces) - return tonumber(string.format("%." .. (numDecimalPlaces or 0) .. "f", value)) + local mult = 10^(numDecimalPlaces or 0) + return math.floor(value * mult + 0.5) / mult end -- credit http://richard.warburton.it From 2539e6fa9d454f559c52e9a719b319ccf7f32ac2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 3 Jan 2020 12:49:07 +0100 Subject: [PATCH 2332/3224] Added missing exception handlers to commands, removed /setmoney command closes #206 --- locales/br.lua | 5 --- locales/cs.lua | 5 --- locales/de.lua | 5 --- locales/en.lua | 5 --- locales/fi.lua | 5 --- locales/fr.lua | 5 --- locales/pl.lua | 5 --- locales/sv.lua | 5 --- server/commands.lua | 92 ++++++++++++++++++++------------------------- 9 files changed, 40 insertions(+), 92 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index e2c5b503..9f6c9c96 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -56,11 +56,6 @@ Locales['br'] = { ['spawn_car'] = 'spawn um carro', ['spawn_car_param'] = 'nome do carro', ['delete_vehicle'] = 'excluir Veiculo', - ['givemoney'] = 'dar dinheiro', - ['setmoney'] = 'set money for a player', - ['money_type'] = 'valid money types: cash, bank, black', - ['money_set'] = 'someone ~y~highly ranked~s~ just set ~g~$%s~s~ (%s) for you!', - ['money_amount'] = 'quantia de dinheiro', ['invalid_account'] = 'conta invalida', ['account'] = 'conta', ['giveaccountmoney'] = 'dar dinheiro da conta', diff --git a/locales/cs.lua b/locales/cs.lua index c1dc7c82..f0bd3966 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -56,11 +56,6 @@ Locales['cs'] = { ['spawn_car'] = 'spawn auto', ['spawn_car_param'] = 'název auta', ['delete_vehicle'] = 'odstranit vozidlo', - ['givemoney'] = 'dát peníze', - ['setmoney'] = 'nastavit peníze hráči', - ['money_type'] = 'platné typy peněz: cash, bank, black', - ['money_set'] = 'někdo s ~y~vysokou úrovní~s~ vám právě nastavil ~g~$%s~s~ (%s)!', - ['money_amount'] = 'množství peněz', ['invalid_account'] = 'neplatný účet', ['account'] = 'účet', ['giveaccountmoney'] = 'dát peníze na účet', diff --git a/locales/de.lua b/locales/de.lua index 3ba684dd..e0be6b73 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -56,11 +56,6 @@ Locales['de'] = { ['spawn_car'] = 'spawn a car', ['spawn_car_param'] = 'name of car', ['delete_vehicle'] = 'deletes Vehicle', - ['givemoney'] = 'give money', - ['setmoney'] = 'set money for a player', - ['money_type'] = 'valid money types: cash, bank, black', - ['money_set'] = 'someone ~y~highly ranked~s~ just set ~g~$%s~s~ (%s) for you!', - ['money_amount'] = 'amount of money', ['invalid_account'] = 'invalid account', ['account'] = 'account', ['giveaccountmoney'] = 'give account money', diff --git a/locales/en.lua b/locales/en.lua index d10db002..0001af22 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -56,11 +56,6 @@ Locales['en'] = { ['spawn_car'] = 'spawn a car', ['spawn_car_param'] = 'name of car', ['delete_vehicle'] = 'deletes Vehicle', - ['givemoney'] = 'give money', - ['setmoney'] = 'set money for a player', - ['money_type'] = 'valid money types: cash, bank, black', - ['money_set'] = 'someone ~y~highly ranked~s~ just set ~g~$%s~s~ (%s) for you!', - ['money_amount'] = 'amount of money', ['invalid_account'] = 'invalid account', ['account'] = 'account', ['giveaccountmoney'] = 'give account money', diff --git a/locales/fi.lua b/locales/fi.lua index 0898fde3..2105d3e2 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -56,11 +56,6 @@ Locales['fi'] = { ['spawn_car'] = 'spawnaa ajoneuvo', ['spawn_car_param'] = 'ajoneuvon nimi', ['delete_vehicle'] = 'poistaa ajoneuvon', - ['givemoney'] = 'anna rahaa', - ['setmoney'] = 'aseta pelaajan rahat', - ['money_type'] = 'hyväksytyt rahatyypit: cash, bank, black', - ['money_set'] = 'joku ~y~korkeesti rankattu~s~ asetti ~g~$%s~s~ (%s) sinulle!', - ['money_amount'] = 'rahan määrä', ['invalid_account'] = 'virheellinen tunnus', ['account'] = 'tunnus', ['giveaccountmoney'] = 'anna tilille rahaa', diff --git a/locales/fr.lua b/locales/fr.lua index 09266cfd..5dd22293 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -56,11 +56,6 @@ Locales['fr'] = { ['spawn_car'] = 'spawn un véhicule', ['spawn_car_param'] = 'nom de la voiture', ['delete_vehicle'] = 'supprimer le véhicule', - ['givemoney'] = 'donner de l\'argent', - ['setmoney'] = 'définir l\'argent pour un joueur', - ['money_type'] = 'types de monnaies valides: cash, bank, black', - ['money_set'] = 'quelqu\'un de ~y~haut placé~s~ vous a attribué ~g~$%s~s~ (%s) !', - ['money_amount'] = 'somme d\'argent', ['invalid_account'] = 'compte invalide', ['account'] = 'compte', ['giveaccountmoney'] = 'donner de l\'argent au compte', diff --git a/locales/pl.lua b/locales/pl.lua index a67dc75a..a8f22d78 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -56,11 +56,6 @@ Locales['pl'] = { ['spawn_car'] = 'sprowadź pojazd', ['spawn_car_param'] = 'nazwa samochodu', ['delete_vehicle'] = 'usuń pojazd', - ['givemoney'] = 'daj pieniądze', - ['setmoney'] = 'ustaw pieniądze dla gracza', - ['money_type'] = 'aktualne typy pieniędzy: cash, bank, black', - ['money_set'] = 'ktoś ~y~wysoko postawiony~s~ podarował Ci pieniądze i masz teraz ~g~%s$~s~ (%s)!', - ['money_amount'] = 'kwota pieniędzy', ['invalid_account'] = 'błędne konto', ['account'] = 'konto', ['giveaccountmoney'] = 'daj pieniądze na konto', diff --git a/locales/sv.lua b/locales/sv.lua index d0ab8171..6db1b5b7 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -56,11 +56,6 @@ Locales['sv'] = { ['spawn_car'] = 'spawna ett fordon', ['spawn_car_param'] = 'namn på fordon', ['delete_vehicle'] = 'ta bort fordon', - ['givemoney'] = 'ge pengar', - ['setmoney'] = 'bestäm mängd pengar till en valfri person', - ['money_type'] = 'giltiga typer: cash, bank, black', - ['money_set'] = 'någon ~y~högt uppsatt~s~ satte ~g~%s SEK~s~ (%s) för dig!', - ['money_amount'] = 'summa pengar', ['invalid_account'] = 'ogiltigt konto', ['account'] = 'konto', ['giveaccountmoney'] = 'ge spelarkonto pengar', diff --git a/server/commands.lua b/server/commands.lua index 32e8447f..81e485cb 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -58,82 +58,70 @@ end, {help = _U('delete_vehicle'), params = { {name = 'radius', help = 'Optional, delete every vehicle within the specified radius'} }}) -TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, user) - local playerId = source - local target = tonumber(args[1]) - local money_type = args[2] - local money_amount = tonumber(args[3]) - - local xPlayer = ESX.GetPlayerFromId(target) - - if target and money_type and money_amount and xPlayer then - if money_type == 'cash' then - xPlayer.setMoney(money_amount) - elseif money_type == 'bank' then - xPlayer.setAccountMoney('bank', money_amount) - elseif money_type == 'black' then - xPlayer.setAccountMoney('black_money', money_amount) - else - TriggerClientEvent('chatMessage', playerId, 'SYSTEM', {255, 0, 0}, '^2' .. money_type .. ' ^0 is not a valid money type!') - return - end - else - TriggerClientEvent('chatMessage', playerId, 'SYSTEM', {255, 0, 0}, 'Invalid arguments.') - return - end - - print('es_extended: ' .. GetPlayerName(source) .. ' just set $' .. money_amount .. ' (' .. money_type .. ') to ' .. xPlayer.name) - - if xPlayer.source ~= playerId then - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('money_set', money_amount, money_type)) - end -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('setmoney'), params = {{name = 'id', help = _U('id_param')}, {name = 'money type', help = _U('money_type')}, {name = 'amount', help = _U('money_amount')}}}) - TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, args, user) - local playerId = source local xPlayer = ESX.GetPlayerFromId(args[1]) - local account = args[2] - local amount = tonumber(args[3]) - if amount then - if xPlayer.getAccount(account) then - xPlayer.addAccountMoney(account, amount) + if xPlayer then + local account = args[2] + local amount = tonumber(args[3]) + + if amount then + if xPlayer.getAccount(account) then + xPlayer.addAccountMoney(account, amount) + else + TriggerClientEvent('esx:showNotification', source, _U('invalid_account')) + end else - TriggerClientEvent('esx:showNotification', playerId, _U('invalid_account')) + TriggerClientEvent('esx:showNotification', source, _U('amount_invalid')) end else - TriggerClientEvent('esx:showNotification', playerId, _U('amount_invalid')) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('giveaccountmoney'), params = {{name = 'id', help = _U('id_param')}, {name = 'account', help = _U('account')}, {name = 'amount', help = _U('money_amount')}}}) TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, user) - local playerId = source local xPlayer = ESX.GetPlayerFromId(args[1]) - local item = args[2] - local count = (args[3] == nil and 1 or tonumber(args[3])) - if count then - if xPlayer.getInventoryItem(item) then - xPlayer.addInventoryItem(item, count) + if xPlayer then + local item = args[2] + local count = tonumber(args[3]) + + if count then + if xPlayer.getInventoryItem(item) then + xPlayer.addInventoryItem(item, count) + else + TriggerClientEvent('esx:showNotification', source, _U('invalid_item')) + end else - TriggerClientEvent('esx:showNotification', playerId, _U('invalid_item')) + TriggerClientEvent('esx:showNotification', source, _U('invalid_amount')) end else - TriggerClientEvent('esx:showNotification', playerId, _U('invalid_amount')) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('giveitem'), params = {{name = 'id', help = _U('id_param')}, {name = 'item', help = _U('item')}, {name = 'amount', help = _U('amount')}}}) TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, user) - local xPlayer = ESX.GetPlayerFromId(args[1]) - local weaponName = string.upper(args[2]) + local xPlayer = ESX.GetPlayerFromId(args[1]) - xPlayer.addWeapon(weaponName, tonumber(args[3])) + if xPlayer then + local weaponName = args[2] or 'unknown' + + if ESX.GetWeapon(weaponName) then + if xPlayer.hasWeapon(weaponName) then + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player already has that weapon.' } }) + else + xPlayer.addWeapon(weaponName, tonumber(args[3])) + end + else + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid weapon.' } }) + end + else + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) + end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('giveweapon'), params = {{name = 'id', help = _U('id_param')}, {name = 'weapon', help = _U('weapon')}, {name = 'ammo', help = _U('amountammo')}}}) From ffa05600a4bdfb286485d753e2ee814bbdd75961 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 3 Jan 2020 13:05:16 +0100 Subject: [PATCH 2333/3224] Updated readme --- README.md | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 1b15eacc..fd1543f1 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,22 @@ # es_extended -es_extended is a roleplay framework for FiveM. It is developed on top of EssentialMode (aka ES), thus commonly named ESX - the **Es**sentialMode E**x**tended framework for FiveM. +es_extended is a roleplay framework for FiveM. It is developed on top of EssentialMode (aka ES), where the project ESX is originating from - the **Es**sentialMode E**x**tended framework for FiveM. ## Links & Read more - [ESX Documentation](https://esx-org.github.io/) -- [ESX Discord Community](https://discord.gg/MsWzPqE) -- [FiveM Forum Thread](https://forum.fivem.net/t/release-esx-base/39881) +- [ESX Development Discord](https://discord.gg/MsWzPqE) - [FiveM Native Reference](https://runtime.fivem.net/doc/reference.html) -### Screenshot preview (todo) - -![screenshot](http://i.imgur.com/aPFdJl3.jpg) - ## Features -- Accounts (comes with bank / black money), you can add more accounts -- Advanced inventory system (press `F2` ingame) -- Job system -- Loadouts and position synced in database -- The best framework out there for RP servers -- i18n (locale) system -- Plenty of plugins available +- Weight based inventory system +- Weapons support, including support for attachments +- Supports different money accounts (defaulted with bank & black money) +- Many official resources available in our GitHub +- Job system, with grades and clothes support +- Supports multiple languages, most strings are localized +- Easy to use API ## Requirements @@ -87,7 +82,7 @@ start esx_menu_dialog es_extended - EssentialMode Extended framework for FiveM -Copyright (C) 2015-2019 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. From 2140f8628c345efb437a494e7bd88f792aad0c3c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 3 Jan 2020 13:55:23 +0100 Subject: [PATCH 2334/3224] Added log level to print uses, and change formatting --- server/classes/player.lua | 93 +++++++++++++++------------------------ server/common.lua | 10 +++-- server/functions.lua | 9 ++-- server/main.lua | 4 +- 4 files changed, 49 insertions(+), 67 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index d74b6429..fe1cf5e0 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -22,8 +22,6 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if money >= 0 then self.player.setMoney(money) - else - print(('es_extended: %s attempted exploiting! (reason: player tried setting -1 cash balance)'):format(self.identifier)) end end @@ -36,8 +34,6 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if money >= 0 then self.player.setBankBalance(money) - else - print(('es_extended: %s attempted exploiting! (reason: player tried setting -1 bank balance)'):format(self.identifier)) end end @@ -69,38 +65,30 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if money >= 0 then self.player.addMoney(money) - else - print(('es_extended: %s attempted exploiting! (reason: player tried adding -1 cash balance)'):format(self.identifier)) end end self.removeMoney = function(money) money = ESX.Math.Round(money) - if money >= 0 then + if money > 0 then self.player.removeMoney(money) - else - print(('es_extended: %s attempted exploiting! (reason: player tried removing -1 cash balance)'):format(self.identifier)) end end self.addBank = function(money) money = ESX.Math.Round(money) - if money >= 0 then + if money > 0 then self.player.addBank(money) - else - print(('es_extended: %s attempted exploiting! (reason: player tried adding -1 bank balance)'):format(self.identifier)) end end self.removeBank = function(money) money = ESX.Math.Round(money) - if money >= 0 then + if money > 0 then self.player.removeBank(money) - else - print(('es_extended: %s attempted exploiting! (reason: player tried removing -1 bank balance)'):format(self.identifier)) end end @@ -261,64 +249,55 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.setAccountMoney = function(acc, money) - if money < 0 then - print(('es_extended: %s attempted exploiting! (reason: player tried setting -1 account balance)'):format(self.identifier)) - return - end + if money >= 0 then + local account = self.getAccount(acc) - local account = self.getAccount(acc) + if account then + local prevMoney = account.money + local newMoney = ESX.Math.Round(money) - if account then - local prevMoney = account.money - local newMoney = ESX.Math.Round(money) + account.money = newMoney - account.money = newMoney + if acc == 'bank' then + self.set('bank', newMoney) + end - if acc == 'bank' then - self.set('bank', newMoney) + TriggerClientEvent('esx:setAccountMoney', self.source, account) end - - TriggerClientEvent('esx:setAccountMoney', self.source, account) end end self.addAccountMoney = function(acc, money) - if money < 0 then - print(('es_extended: %s attempted exploiting! (reason: player tried adding -1 account balance)'):format(self.identifier)) - return - end + if money > 0 then + local account = self.getAccount(acc) - local account = self.getAccount(acc) - - if account then - local newMoney = account.money + ESX.Math.Round(money) - account.money = newMoney - - if acc == 'bank' then - self.set('bank', newMoney) + if account then + local newMoney = account.money + ESX.Math.Round(money) + account.money = newMoney + + if acc == 'bank' then + self.set('bank', newMoney) + end + + TriggerClientEvent('esx:setAccountMoney', self.source, account) end - - TriggerClientEvent('esx:setAccountMoney', self.source, account) end end self.removeAccountMoney = function(acc, money) - if money < 0 then - print(('es_extended: %s attempted exploiting! (reason: player tried removing -1 account balance)'):format(self.identifier)) - return - end + if money > 0 then + local account = self.getAccount(acc) - local account = self.getAccount(acc) - - if account then - local newMoney = account.money - ESX.Math.Round(money) - account.money = newMoney - - if acc == 'bank' then - self.set('bank', newMoney) + if account then + local newMoney = account.money - ESX.Math.Round(money) + account.money = newMoney + + if acc == 'bank' then + self.set('bank', newMoney) + end + + TriggerClientEvent('esx:setAccountMoney', self.source, account) end - - TriggerClientEvent('esx:setAccountMoney', self.source, account) end end @@ -442,7 +421,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l TriggerEvent('esx:setJob', self.source, self.job, lastJob) TriggerClientEvent('esx:setJob', self.source, self.job) else - print(('es_extended: ignoring setJob for %s due to job not found!'):format(self.source)) + print(('[es_extended] [^3WARNING^7] Ignoring invalid .setJob() usage for "%s"'):format(self.identifier)) end end diff --git a/server/common.lua b/server/common.lua index a72e024e..b3c76c71 100644 --- a/server/common.lua +++ b/server/common.lua @@ -43,16 +43,18 @@ MySQL.ready(function() if ESX.Jobs[result2[i].job_name] then ESX.Jobs[result2[i].job_name].grades[tostring(result2[i].grade)] = result2[i] else - print(('es_extended: invalid job "%s" from table job_grades ignored!'):format(result2[i].job_name)) + print(('[es_extended] [^3WARNING^7] Invalid job "%s" from table job_grades ignored'):format(result2[i].job_name)) end end for k,v in pairs(ESX.Jobs) do if next(v.grades) == nil then ESX.Jobs[v.name] = nil - print(('es_extended: ignoring job "%s" due to missing job grades!'):format(v.name)) + print(('[es_extended] [^3WARNING^7] Ignoring job "%s" due to missing job grades'):format(v.name)) end end + + print('[es_extended] [^2INFO^7] ESX developed by ESX-Org has been initialized') end) AddEventHandler('esx:playerLoaded', function(source) @@ -78,7 +80,9 @@ end) RegisterServerEvent('esx:clientLog') AddEventHandler('esx:clientLog', function(msg) - RconPrint(msg .. "\n") + if Config.EnableDebug then + print(('[es_extended] [^2TRACE^7] %s'):format(msg)) + end end) RegisterServerEvent('esx:triggerServerCallback') diff --git a/server/functions.lua b/server/functions.lua index 07fa9501..7c883aa5 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -1,6 +1,6 @@ ESX.Trace = function(str) if Config.EnableDebug then - print('ESX> ' .. str) + print(('[es_extended] [^2TRACE^7] %s'):format(str)) end end @@ -32,7 +32,7 @@ ESX.TriggerServerCallback = function(name, requestId, source, cb, ...) if ESX.ServerCallbacks[name] ~= nil then ESX.ServerCallbacks[name](source, cb, ...) else - print('es_extended: TriggerServerCallback => [' .. name .. '] does not exist') + print(('[es_extended] [^3WARNING^7] Server callback "%s" does not exist. Make sure that the server sided file really is loading, an error in that file might cause it to not load.'):format(name)) end end @@ -88,7 +88,7 @@ ESX.SavePlayer = function(xPlayer, cb) end) Async.parallel(asyncTasks, function(results) - RconPrint('[SAVED] ' .. xPlayer.name .. "^7\n") + print(('[es_extended] [^2INFO^7] Saved %s'):format(xPlayer.getName())) if cb ~= nil then cb() @@ -108,8 +108,7 @@ ESX.SavePlayers = function(cb) end Async.parallelLimit(asyncTasks, 8, function(results) - RconPrint('[SAVED] All players' .. "\n") - + print(('[es_extended] [^2INFO^7] Saved %s player(s)'):format(#xPlayers)) if cb ~= nil then cb() end diff --git a/server/main.lua b/server/main.lua index 4a224094..c1bf5861 100644 --- a/server/main.lua +++ b/server/main.lua @@ -66,7 +66,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) canRemove = item.canRemove }) else - print(('es_extended: invalid item "%s" ignored!'):format(v.item)) + print(('[es_extended] [^3WARNING^7] Ignoring invalid item "%s" for "%s"'):format(v.item, player.getIdentifier())) end end @@ -147,7 +147,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) userData.job.skin_female = json.decode(gradeObject.skin_female) end else - print(('es_extended: %s had an unknown job [job: %s, grade: %s], setting as unemployed!'):format(player.getIdentifier(), job, grade)) + print(('[es_extended] [^3WARNING^7] Ignoring invalid job for %s [job: %s, grade: %s]'):format(player.getIdentifier(), job, grade)) local job, grade = 'unemployed', '0' local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] From bf9c14ed57b2e1094a1cbfbd2b105997dfc43a45 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 3 Jan 2020 17:56:44 +0100 Subject: [PATCH 2335/3224] Added /giveweaponcomponent command, easier to understand parms table --- server/commands.lua | 68 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 6 deletions(-) diff --git a/server/commands.lua b/server/commands.lua index 81e485cb..3c525759 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -14,7 +14,11 @@ TriggerEvent('es:addGroupCommand', 'tp', 'admin', function(source, args, user) end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = 'Teleport to coordinates', params = {{name = 'x', help = 'X coords'}, {name = 'y', help = 'Y coords'}, {name = 'z', help = 'Z coords'}}}) +end, {help = 'Teleport to coordinates', params = { + {name = 'x', help = 'X coords'}, + {name = 'y', help = 'Y coords'}, + {name = 'z', help = 'Z coords'} +}}) TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, user) if tonumber(args[1]) and args[2] and tonumber(args[3]) then @@ -34,7 +38,11 @@ TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('setjob'), params = {{name = 'id', help = _U('id_param')}, {name = 'job', help = _U('setjob_param2')}, {name = 'grade_id', help = _U('setjob_param3')}}}) +end, {help = _U('setjob'), params = { + {name = 'playerId', help = _U('id_param')}, + {name = 'job', help = _U('setjob_param2')}, + {name = 'grade_id', help = _U('setjob_param3')} +}}) TriggerEvent('es:addGroupCommand', 'car', 'admin', function(source, args, user) TriggerClientEvent('esx:spawnVehicle', source, args[1]) @@ -64,7 +72,7 @@ TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, if xPlayer then local account = args[2] local amount = tonumber(args[3]) - + if amount then if xPlayer.getAccount(account) then xPlayer.addAccountMoney(account, amount) @@ -79,7 +87,11 @@ TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('giveaccountmoney'), params = {{name = 'id', help = _U('id_param')}, {name = 'account', help = _U('account')}, {name = 'amount', help = _U('money_amount')}}}) +end, {help = _U('giveaccountmoney'), params = { + {name = 'playerId', help = _U('id_param')}, + {name = 'account', help = _U('account')}, + {name = 'amount', help = _U('money_amount')} +}}) TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, user) local xPlayer = ESX.GetPlayerFromId(args[1]) @@ -102,7 +114,11 @@ TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, u end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('giveitem'), params = {{name = 'id', help = _U('id_param')}, {name = 'item', help = _U('item')}, {name = 'amount', help = _U('amount')}}}) +end, {help = _U('giveitem'), params = { + {name = 'playerId', help = _U('id_param')}, + {name = 'item', help = _U('item')}, + {name = 'amount', help = _U('amount')} +}}) TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, user) local xPlayer = ESX.GetPlayerFromId(args[1]) @@ -124,7 +140,47 @@ TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('giveweapon'), params = {{name = 'id', help = _U('id_param')}, {name = 'weapon', help = _U('weapon')}, {name = 'ammo', help = _U('amountammo')}}}) +end, {help = _U('giveweapon'), params = { + {name = 'playerId', help = _U('id_param')}, + {name = 'weapon', help = _U('weapon')}, + {name = 'ammo', help = _U('amountammo')} +}}) + +TriggerEvent('es:addGroupCommand', 'giveweaponcomponent', 'admin', function(source, args, user) + local xPlayer = ESX.GetPlayerFromId(args[1]) + + if xPlayer then + local weapon = args[2] or 'unknown' + + if ESX.GetWeapon(weapon) then + if xPlayer.hasWeapon(weapon) then + local component = ESX.GetWeaponComponent(weapon, args[3] or 'unknown') + + if component then + if xPlayer.hasWeaponComponent(weapon, args[3]) then + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player already has that weapon component.' } }) + else + xPlayer.addWeaponComponent(weapon, args[3]) + end + else + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid weapon component.' } }) + end + else + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player does not have that weapon.' } }) + end + else + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid weapon.' } }) + end + else + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) + end +end, function(source, args, user) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) +end, {help = 'Give weapon component', params = { + {name = 'playerId', help = _U('id_param')}, + {name = 'weapon', help = _U('weapon')}, + {name = 'component', help = 'weapon component'} +}}) TriggerEvent('es:addGroupCommand', 'disc', 'admin', function(source, args, user) DropPlayer(source, 'You have been disconnected') From 9b33a3e6ca09db51199b2440982e9103eab6f35a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 3 Jan 2020 19:10:25 +0100 Subject: [PATCH 2336/3224] Fix math round function again Co-Authored-By: hugocabral --- common/modules/math.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/common/modules/math.lua b/common/modules/math.lua index 99a87631..947ccd78 100644 --- a/common/modules/math.lua +++ b/common/modules/math.lua @@ -1,8 +1,12 @@ ESX.Math = {} ESX.Math.Round = function(value, numDecimalPlaces) - local mult = 10^(numDecimalPlaces or 0) - return math.floor(value * mult + 0.5) / mult + if numDecimalPlaces then + local power = 10^numDecimalPlaces + return math.floor((value * power) + 0.5) / (power) + else + return math.floor(value + 0.5) + end end -- credit http://richard.warburton.it From 2f751524578980e0966c9f6b68be4d094de484f7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 3 Jan 2020 19:20:26 +0100 Subject: [PATCH 2337/3224] Changed how pickups work, see desc. Fixed #338, fixed #420 - Pickups now require you to press E once nearby to pick up - Fixed pickup objects sometimes not showing up #420 - Added animation to picking up and throwing items - Added message when inventory cannot accept picking up item --- client/functions.lua | 13 ++++++--- client/main.lua | 63 ++++++++++++++++++++++++++------------------ locales/br.lua | 6 +++-- locales/cs.lua | 6 +++-- locales/de.lua | 6 +++-- locales/en.lua | 6 +++-- locales/fi.lua | 6 +++-- locales/fr.lua | 6 +++-- locales/pl.lua | 7 ++--- locales/sv.lua | 6 +++-- server/main.lua | 32 ++++++++++++---------- 11 files changed, 98 insertions(+), 59 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 95b89359..5a56dd4d 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1199,19 +1199,26 @@ ESX.ShowInventory = function() end elseif data1.current.action == 'remove' then if IsPedOnFoot(playerPed) then + local dict, anim = 'weapons@first_person@aim_rng@generic@projectile@sticky_bomb@', 'plant_floor' + ESX.Streaming.RequestAnimDict(dict) + if type == 'item_weapon' then - TriggerServerEvent('esx:removeInventoryItem', type, item) menu1.close() - else -- type: item_standard + TaskPlayAnim(playerPed, dict, anim, 8.0, 1.0, 1000, 16, 0.0, false, false, false) + Citizen.Wait(1000) + TriggerServerEvent('esx:removeInventoryItem', type, item) + else ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_remove', { title = _U('amount') }, function(data2, menu2) local quantity = tonumber(data2.value) if quantity then - TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) menu2.close() menu1.close() + TaskPlayAnim(playerPed, dict, anim, 8.0, 1.0, 1000, 16, 0.0, false, false, false) + Citizen.Wait(1000) + TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) else ESX.ShowNotification(_U('amount_invalid')) end diff --git a/client/main.lua b/client/main.lua index cc23ba5f..7275114c 100644 --- a/client/main.lua +++ b/client/main.lua @@ -51,13 +51,14 @@ AddEventHandler('esx:createMissingPickups', function(missingPickups) ESX.Game.SpawnLocalObject('prop_money_bag_01', v.coords, function(obj) SetEntityAsMissionEntity(obj, true, false) PlaceObjectOnGroundProperly(obj) + FreezeEntityPosition(obj, true) pickups[pickupId] = { id = pickupId, obj = obj, label = v.label, inRange = false, - coords = v.coords + coords = vector3(v.coords.x, v.coords.y, v.coords.z) } end) end @@ -273,7 +274,7 @@ AddEventHandler('esx:spawnVehicle', function(vehicle) if IsModelInCdimage(model) then local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) - + ESX.Game.SpawnVehicle(model, coords, 90.0, function(vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) end) @@ -287,22 +288,19 @@ AddEventHandler('esx:pickup', function(id, label, player) local ped = GetPlayerPed(GetPlayerFromServerId(player)) local coords = GetEntityCoords(ped) local forward = GetEntityForwardVector(ped) - local x, y, z = table.unpack(coords + forward * -2.0) + coords = (coords + forward * 2.0) - ESX.Game.SpawnLocalObject('prop_money_bag_01', { - x = x, - y = y, - z = z - 2.0, - }, function(obj) + ESX.Game.SpawnLocalObject('prop_money_bag_01', coords, function(obj) SetEntityAsMissionEntity(obj, true, false) PlaceObjectOnGroundProperly(obj) + FreezeEntityPosition(obj, true) pickups[id] = { id = id, obj = obj, label = label, inRange = false, - coords = {x = x, y = y, z = z} + coords = coords } end) end) @@ -462,32 +460,47 @@ end Citizen.CreateThread(function() while true do Citizen.Wait(0) - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - - -- if there's no nearby pickups we can wait a bit to save performance - if next(pickups) == nil then - Citizen.Wait(500) - end + local playerCoords, letSleep = GetEntityCoords(playerPed), true + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() for k,v in pairs(pickups) do - local distance = GetDistanceBetweenCoords(coords, v.coords.x, v.coords.y, v.coords.z, true) - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + local distance = #(playerCoords - v.coords) + + if distance < 5 then + local label = v.label + letSleep = false + + if distance < 1 then + if IsControlJustReleased(0, 38) then + if IsPedOnFoot(playerPed) and (closestDistance == -1 or closestDistance > 3) and not v.inRange then + v.inRange = true + + local dict, anim = 'weapons@first_person@aim_rng@generic@projectile@sticky_bomb@', 'plant_floor' + ESX.Streaming.RequestAnimDict(dict) + TaskPlayAnim(playerPed, dict, anim, 8.0, 1.0, 1000, 16, 0.0, false, false, false) + Citizen.Wait(1000) + + TriggerServerEvent('esx:onPickup', v.id) + PlaySoundFrontend(-1, 'PICK_UP', 'HUD_FRONTEND_DEFAULT_SOUNDSET', false) + end + end + + label = ('%s~n~%s'):format(label, _U('threw_pickup_prompt')) + end - if distance <= 5.0 then ESX.Game.Utils.DrawText3D({ x = v.coords.x, y = v.coords.y, z = v.coords.z + 0.25 - }, v.label) + }, label, 1.2, 1) + elseif v.inRange then + v.inRange = false end + end - if (closestDistance == -1 or closestDistance > 3) and distance <= 1.0 and not v.inRange and IsPedOnFoot(playerPed) then - TriggerServerEvent('esx:onPickup', v.id) - PlaySoundFrontend(-1, 'PICK_UP', 'HUD_FRONTEND_DEFAULT_SOUNDSET', false) - v.inRange = true - end + if letSleep then + Citizen.Wait(500) end end end) diff --git a/locales/br.lua b/locales/br.lua index 9f6c9c96..b84c6424 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -33,10 +33,12 @@ Locales['br'] = { ['imp_invalid_quantity'] = 'acao impossivel, quantidade invalida', ['imp_invalid_amount'] = 'acao impossivel, valor invalido', ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', - ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', + ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', + ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', + ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related ['received_salary'] = 'voce recebeu seu salario: ~g~$%s~s~ ', ['received_help'] = 'voce recebeu seu cheque de bem-estar: ~g~$%s~s~ ', diff --git a/locales/cs.lua b/locales/cs.lua index f0bd3966..6a61bc90 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -33,10 +33,12 @@ Locales['cs'] = { ['imp_invalid_quantity'] = 'akce není možná, neplatný počet', ['imp_invalid_amount'] = 'akce není možná, neplatné množství', ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', - ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', + ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', + ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', + ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related ['received_salary'] = 'obdrželi jste výplatu: ~g~$%s~s~', ['received_help'] = 'obdrželi jste sociální dávku: ~g~$%s~s~', diff --git a/locales/de.lua b/locales/de.lua index e0be6b73..98d5f843 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -33,10 +33,12 @@ Locales['de'] = { ['imp_invalid_quantity'] = 'aktion nicht möglich, ungültige Anzahl', ['imp_invalid_amount'] = 'aktion nicht möglich, ungültiger Betrag', ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', - ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', + ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', + ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', + ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related ['received_salary'] = 'du hast dein Gehalt erhalten: ~g~$%s~s~', ['received_help'] = 'du hast deine Sozialhilfe erhalten: ~g~$%s~s~', diff --git a/locales/en.lua b/locales/en.lua index 0001af22..c5300254 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -33,10 +33,12 @@ Locales['en'] = { ['imp_invalid_quantity'] = 'action impossible, invalid quantity', ['imp_invalid_amount'] = 'action impossible, invalid amount', ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', - ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', + ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', + ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', + ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related ['received_salary'] = 'you received your salary: ~g~$%s~s~', ['received_help'] = 'you recieved your welfare check: ~g~$%s~s~', diff --git a/locales/fi.lua b/locales/fi.lua index 2105d3e2..626d853d 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -33,10 +33,12 @@ Locales['fi'] = { ['imp_invalid_quantity'] = 'toiminto mahdoton, virheellinen määrä', ['imp_invalid_amount'] = 'toiminto mahdoton, virhellinen summa', ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', - ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', + ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', + ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', + ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related ['received_salary'] = 'sinä vastaanotit palkkaa: ~g~$%s~s~', ['received_help'] = 'sinä vastaanotit valtion tukea: ~g~$%s~s~', diff --git a/locales/fr.lua b/locales/fr.lua index 5dd22293..07de2fc6 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -33,10 +33,12 @@ Locales['fr'] = { ['imp_invalid_quantity'] = 'action impossible, ~r~quantité invalide', ['imp_invalid_amount'] = 'action impossible, ~r~montant invalide', ['threw_standard'] = 'vous avez jeté ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'vous avez jeté ~r~$%s~s~ ~b~cash~s~', - ['threw_account'] = 'vous avez jeté ~r~$%s~s~ ~b~%s~s~', + ['threw_money'] = 'vous avez jeté ~g~$%s~s~ ~b~cash~s~', + ['threw_account'] = 'vous avez jeté ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~', ['threw_weapon_ammo'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles', + ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', + ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related ['received_salary'] = 'vous avez reçu votre salaire: ~g~$%s~s~', ['received_help'] = 'vous avez reçu une aide de l\'état: ~g~$%s~s~', diff --git a/locales/pl.lua b/locales/pl.lua index a8f22d78..c46546e5 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -33,11 +33,12 @@ Locales['pl'] = { ['imp_invalid_quantity'] = 'akcja jest niemożliwa, nieprawidłowa ilość', ['imp_invalid_amount'] = 'akcja jest niemożliwa, nieprawidłowa kwota', ['threw_standard'] = 'wyrzuciłeś/aś ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'wyrzuciłeś/aś ~r~$%s~s~ ~b~gotówki~s~', - ['threw_account'] = 'wyrzuciłeś/aś ~r~$%s~s~ ~b~%s~s~', + ['threw_money'] = 'wyrzuciłeś/aś ~g~$%s~s~ ~b~gotówki~s~', + ['threw_account'] = 'wyrzuciłeś/aś ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'wyrzuciłeś/aś ~b~%s~s~', ['threw_weapon_ammo'] = 'wyrzuciłeś/aś ~b~%s~s~ z ~o~%sx~s~ nabojami', - + ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', + ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related ['received_salary'] = 'otrzymałeś wynagrodzenie: ~g~%s$~s~', ['received_help'] = 'otrzymałem zapomogę: ~g~$%s~s~', diff --git a/locales/sv.lua b/locales/sv.lua index 6db1b5b7..39b15a72 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -33,10 +33,12 @@ Locales['sv'] = { ['imp_invalid_quantity'] = 'åtgärd omöjlig, ogiltig mängd', ['imp_invalid_amount'] = 'åtgärd omöjlig, ogiltig belopp', ['threw_standard'] = 'du kastade ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'du kastade ~r~$%s~s~ ~b~kontanter~s~', - ['threw_account'] = 'du kastade ~r~$%s~s~ ~b~%s~s~', + ['threw_money'] = 'du kastade ~g~%s SEK~s~ ~b~kontanter~s~', + ['threw_account'] = 'du kastade ~g~%s SEK~s~ ~b~%s~s~', ['threw_weapon'] = 'du kastade ~b~%s~s~', ['threw_weapon_ammo'] = 'du kastade ~b~%s~s~ med ~o~%sx~s~ skott', + ['threw_cannot_pickup'] = 'du kan inte plocka upp det på grund av att det kommer ej få plats i ditt förråd!', + ['threw_pickup_prompt'] = 'tryck ~y~E~s~ för att plocka upp', -- Salary related ['received_salary'] = 'du har mottagit din lön på ~g~%s SEK~s~', ['received_help'] = 'du har mottagit bidrag på ~g~%s SEK~s~', diff --git a/server/main.lua b/server/main.lua index c1bf5861..ad1c254a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -419,24 +419,28 @@ end) RegisterServerEvent('esx:onPickup') AddEventHandler('esx:onPickup', function(id) - local playerId = source - local pickup = ESX.Pickups[id] - local xPlayer = ESX.GetPlayerFromId(playerId) + local pickup, xPlayer, success = ESX.Pickups[id], ESX.GetPlayerFromId(source) - if pickup.type == 'item_standard' then - if xPlayer.canCarryItem(pickup.name, pickup.count) then - xPlayer.addInventoryItem(pickup.name, pickup.count) + if pickup then + if pickup.type == 'item_standard' then + if xPlayer.canCarryItem(pickup.name, pickup.count) then + xPlayer.addInventoryItem(pickup.name, pickup.count) + success = true + else + xPlayer.showNotification(_U('threw_cannot_pickup')) + end + elseif pickup.type == 'item_money' then + success = true + xPlayer.addMoney(pickup.count) + elseif pickup.type == 'item_account' then + success = true + xPlayer.addAccountMoney(pickup.name, pickup.count) + end + + if success then ESX.Pickups[id] = nil TriggerClientEvent('esx:removePickup', -1, id) end - elseif pickup.type == 'item_money' then - ESX.Pickups[id] = nil - TriggerClientEvent('esx:removePickup', -1, id) - xPlayer.addMoney(pickup.count) - elseif pickup.type == 'item_account' then - ESX.Pickups[id] = nil - TriggerClientEvent('esx:removePickup', -1, id) - xPlayer.addAccountMoney(pickup.name, pickup.count) end end) From fdabf80657ce24623d5e18cf27c6cfcca0a33921 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 4 Jan 2020 01:33:12 +0100 Subject: [PATCH 2338/3224] Implemented ESX weapon drops with components support, closes #421 --- client/main.lua | 112 ++++++++++++++++++++++++++----------------- locales/br.lua | 1 + locales/cs.lua | 1 + locales/de.lua | 1 + locales/en.lua | 1 + locales/fi.lua | 1 + locales/fr.lua | 1 + locales/pl.lua | 1 + locales/sv.lua | 1 + server/functions.lua | 10 ++-- server/main.lua | 18 +++++-- 11 files changed, 97 insertions(+), 51 deletions(-) diff --git a/client/main.lua b/client/main.lua index 7275114c..261702cb 100644 --- a/client/main.lua +++ b/client/main.lua @@ -45,25 +45,6 @@ AddEventHandler('esx:setMaxWeight', function(newMaxWeight) ESX.PlayerData.maxWeight = newMaxWeight end) -RegisterNetEvent('esx:createMissingPickups') -AddEventHandler('esx:createMissingPickups', function(missingPickups) - for pickupId,v in pairs(missingPickups) do - ESX.Game.SpawnLocalObject('prop_money_bag_01', v.coords, function(obj) - SetEntityAsMissionEntity(obj, true, false) - PlaceObjectOnGroundProperly(obj) - FreezeEntityPosition(obj, true) - - pickups[pickupId] = { - id = pickupId, - obj = obj, - label = v.label, - inRange = false, - coords = vector3(v.coords.x, v.coords.y, v.coords.z) - } - end) - end -end) - AddEventHandler('playerSpawned', function() while not ESX.PlayerLoaded do Citizen.Wait(1) @@ -283,26 +264,78 @@ AddEventHandler('esx:spawnVehicle', function(vehicle) end end) -RegisterNetEvent('esx:pickup') -AddEventHandler('esx:pickup', function(id, label, player) - local ped = GetPlayerPed(GetPlayerFromServerId(player)) - local coords = GetEntityCoords(ped) - local forward = GetEntityForwardVector(ped) - coords = (coords + forward * 2.0) +RegisterNetEvent('esx:createPickup') +AddEventHandler('esx:createPickup', function(pickupId, label, playerId, type, name, components) + local playerPed = GetPlayerPed(GetPlayerFromServerId(playerId)) + local entityCoords, forward, pickupObject = GetEntityCoords(playerPed), GetEntityForwardVector(playerPed) + local objectCoords = (entityCoords + forward * 1.0) - ESX.Game.SpawnLocalObject('prop_money_bag_01', coords, function(obj) - SetEntityAsMissionEntity(obj, true, false) - PlaceObjectOnGroundProperly(obj) - FreezeEntityPosition(obj, true) + if type == 'item_weapon' then + ESX.Streaming.RequestWeaponAsset(GetHashKey(name)) + pickupObject = CreateWeaponObject(GetHashKey(name), 50, objectCoords, true, 1.0, 0) - pickups[id] = { - id = id, - obj = obj, - label = label, + for k,v in ipairs(components) do + local component = ESX.GetWeaponComponent(name, v) + GiveWeaponComponentToWeaponObject(pickupObject, component.hash) + end + else + ESX.Game.SpawnLocalObject('prop_money_bag_01', objectCoords, function(obj) + pickupObject = obj + end) + + while not pickupObject do + Citizen.Wait(10) + end + end + + SetEntityAsMissionEntity(pickupObject, true, false) + PlaceObjectOnGroundProperly(pickupObject) + FreezeEntityPosition(pickupObject, true) + + pickups[pickupId] = { + id = pickupId, + obj = pickupObject, + label = label, + inRange = false, + coords = objectCoords + } +end) + +RegisterNetEvent('esx:createMissingPickups') +AddEventHandler('esx:createMissingPickups', function(missingPickups) + for pickupId,pickup in pairs(missingPickups) do + local pickupObject = nil + + if pickup.type == 'item_weapon' then + ESX.Streaming.RequestWeaponAsset(GetHashKey(pickup.name)) + pickupObject = CreateWeaponObject(GetHashKey(pickup.name), 50, pickup.coords.x, pickup.coords.y, pickup.coords.z, true, 1.0, 0) + + for k,componentName in ipairs(pickup.components) do + local component = ESX.GetWeaponComponent(pickup.name, componentName) + GiveWeaponComponentToWeaponObject(pickupObject, component.hash) + end + else + ESX.Game.SpawnLocalObject('prop_money_bag_01', pickup.coords, function(obj) + pickupObject = obj + end) + + while not pickupObject do + Citizen.Wait(10) + end + end + + SetEntityAsMissionEntity(pickupObject, true, false) + PlaceObjectOnGroundProperly(pickupObject) + FreezeEntityPosition(pickupObject, true) + + pickups[pickupId] = { + id = pickupId, + obj = pickupObject, + label = pickup.label, inRange = false, - coords = coords + coords = vector3(pickup.coords.x, pickup.coords.y, pickup.coords.z) } - end) + end end) RegisterNetEvent('esx:removePickup') @@ -311,15 +344,6 @@ AddEventHandler('esx:removePickup', function(id) pickups[id] = nil end) -RegisterNetEvent('esx:pickupWeapon') -AddEventHandler('esx:pickupWeapon', function(weaponPickup, weaponName, ammo) - local playerPed = PlayerPedId() - local pickupCoords = GetOffsetFromEntityInWorldCoords(playerPed, 2.0, 0.0, 0.5) - local weaponHash = GetHashKey(weaponPickup) - - CreateAmbientPickup(weaponHash, pickupCoords, 0, ammo, 1, false, true) -end) - RegisterNetEvent('esx:deleteVehicle') AddEventHandler('esx:deleteVehicle', function(radius) local playerPed = PlayerPedId() diff --git a/locales/br.lua b/locales/br.lua index b84c6424..98d58441 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -37,6 +37,7 @@ Locales['br'] = { ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related diff --git a/locales/cs.lua b/locales/cs.lua index 6a61bc90..38521079 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -37,6 +37,7 @@ Locales['cs'] = { ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related diff --git a/locales/de.lua b/locales/de.lua index 98d5f843..5df299f5 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -37,6 +37,7 @@ Locales['de'] = { ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related diff --git a/locales/en.lua b/locales/en.lua index c5300254..d3c2b4b4 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -37,6 +37,7 @@ Locales['en'] = { ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related diff --git a/locales/fi.lua b/locales/fi.lua index 626d853d..b20da9c0 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -37,6 +37,7 @@ Locales['fi'] = { ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related diff --git a/locales/fr.lua b/locales/fr.lua index 07de2fc6..2e134fe4 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -37,6 +37,7 @@ Locales['fr'] = { ['threw_account'] = 'vous avez jeté ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~', ['threw_weapon_ammo'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles', + ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related diff --git a/locales/pl.lua b/locales/pl.lua index c46546e5..40e7b373 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -37,6 +37,7 @@ Locales['pl'] = { ['threw_account'] = 'wyrzuciłeś/aś ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'wyrzuciłeś/aś ~b~%s~s~', ['threw_weapon_ammo'] = 'wyrzuciłeś/aś ~b~%s~s~ z ~o~%sx~s~ nabojami', + ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related diff --git a/locales/sv.lua b/locales/sv.lua index 39b15a72..98605566 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -37,6 +37,7 @@ Locales['sv'] = { ['threw_account'] = 'du kastade ~g~%s SEK~s~ ~b~%s~s~', ['threw_weapon'] = 'du kastade ~b~%s~s~', ['threw_weapon_ammo'] = 'du kastade ~b~%s~s~ med ~o~%sx~s~ skott', + ['threw_weapon_already'] = 'du har redan ett sådant vapen på dig', ['threw_cannot_pickup'] = 'du kan inte plocka upp det på grund av att det kommer ej få plats i ditt förråd!', ['threw_pickup_prompt'] = 'tryck ~y~E~s~ för att plocka upp', -- Salary related diff --git a/server/functions.lua b/server/functions.lua index 7c883aa5..545e6002 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -160,7 +160,7 @@ ESX.GetItemLabel = function(item) end end -ESX.CreatePickup = function(type, name, count, label, playerId) +ESX.CreatePickup = function(type, name, count, label, playerId, components) local pickupId = (ESX.PickupId == 65635 and 0 or ESX.PickupId + 1) local xPlayer = ESX.GetPlayerFromId(playerId) @@ -169,10 +169,14 @@ ESX.CreatePickup = function(type, name, count, label, playerId) name = name, count = count, label = label, - coords = xPlayer.getCoords() + coords = xPlayer.getCoords(), } - TriggerClientEvent('esx:pickup', -1, pickupId, label, playerId) + if type == 'item_weapon' then + ESX.Pickups[pickupId].components = components + end + + TriggerClientEvent('esx:createPickup', -1, pickupId, label, playerId, type, name, components) ESX.PickupId = pickupId end diff --git a/server/main.lua b/server/main.lua index ad1c254a..853bff44 100644 --- a/server/main.lua +++ b/server/main.lua @@ -390,15 +390,14 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) elseif type == 'item_weapon' then if xPlayer.hasWeapon(itemName) then local weaponNum, weapon = xPlayer.getWeapon(itemName) - local weaponPickup = 'PICKUP_' .. string.upper(itemName) xPlayer.removeWeapon(itemName) + local pickupLabel = ('~y~%s~s~ [~g~%s~s~ ammo]'):format(weapon.label, weapon.ammo) + ESX.CreatePickup('item_weapon', itemName, weapon.ammo, pickupLabel, playerId, weapon.components) + if weapon.ammo > 0 then - TriggerClientEvent('esx:pickupWeapon', playerId, weaponPickup, itemName, weapon.ammo) xPlayer.showNotification(_U('threw_weapon_ammo', weapon.label, weapon.ammo)) else - -- workaround for CreateAmbientPickup() giving 30 rounds of ammo when you drop the weapon with 0 ammo - TriggerClientEvent('esx:pickupWeapon', playerId, weaponPickup, itemName, 1) xPlayer.showNotification(_U('threw_weapon', weapon.label)) end end @@ -435,6 +434,17 @@ AddEventHandler('esx:onPickup', function(id) elseif pickup.type == 'item_account' then success = true xPlayer.addAccountMoney(pickup.name, pickup.count) + elseif pickup.type == 'item_weapon' then + if xPlayer.hasWeapon(pickup.name) then + xPlayer.showNotification(_U('threw_weapon_already')) + else + success = true + xPlayer.addWeapon(pickup.name, pickup.count) + + for k,v in ipairs(pickup.components) do + xPlayer.addWeaponComponent(pickup.name, v) + end + end end if success then From b30e72bdcc54e1ed76ee39c63c7a7d52b391036d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 4 Jan 2020 10:55:10 +0100 Subject: [PATCH 2339/3224] Fixed /givecommandcomponent command, closes #422 --- server/commands.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/commands.lua b/server/commands.lua index 3c525759..fc672392 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -153,6 +153,8 @@ TriggerEvent('es:addGroupCommand', 'giveweaponcomponent', 'admin', function(sour local weapon = args[2] or 'unknown' if ESX.GetWeapon(weapon) then + weapon = string.upper(weapon) + if xPlayer.hasWeapon(weapon) then local component = ESX.GetWeaponComponent(weapon, args[3] or 'unknown') From 4fd106e321ce5bc80b296d3365330dbae6fec84a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 4 Jan 2020 11:03:55 +0100 Subject: [PATCH 2340/3224] Fixed cone not spawning --- client/main.lua | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/client/main.lua b/client/main.lua index fabe8c79..688f7daa 100644 --- a/client/main.lua +++ b/client/main.lua @@ -747,15 +747,10 @@ function OpenPoliceActionsMenu() {label = _U('cash'), model = 'hei_prop_cash_crate_half_full'} }}, function(data2, menu2) local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - local forward = GetEntityForwardVector(playerPed) - local x, y, z = table.unpack(coords + forward * 1.0) + local coords, forward = GetEntityCoords(playerPed), GetEntityForwardVector(playerPed) + local objectCoords = (coords + forward * 1.0) - if data2.current.model == 'prop_roadcone02a' then - z = z - 2.0 - end - - ESX.Game.SpawnObject(data2.current.model, {x = x, y = y, z = z}, function(obj) + ESX.Game.SpawnObject(data2.current.model, objectCoords, function(obj) SetEntityHeading(obj, GetEntityHeading(playerPed)) PlaceObjectOnGroundProperly(obj) end) From 55f4881031ac1c944b81f16c389db91363b483fb Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 4 Jan 2020 11:04:06 +0100 Subject: [PATCH 2341/3224] Fixed Swedish typo --- locales/sv.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/sv.lua b/locales/sv.lua index 963e91e6..55dd9b3f 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -145,7 +145,7 @@ Locales['sv'] = { ['inventory'] = 'förråd', ['police_stock'] = 'polisförråd', -- Misc - ['remove_prop'] = 'tryck ~INPUT_CONTEXT~ för att ta bort obejektet', + ['remove_prop'] = 'tryck ~INPUT_CONTEXT~ för att ta bort objektet', ['map_blip'] = 'polisstation', ['unrestrained_timer'] = 'dina handklovar har försvunnit', -- Notifications From a64773124f28fa66effcaa7b6e5ecdac58b59301 Mon Sep 17 00:00:00 2001 From: JaeHyeok Kim Date: Sat, 4 Jan 2020 19:05:16 +0900 Subject: [PATCH 2342/3224] Added Korean support. (#354) * Added Korean localization of the SQL file * Added ko.lua * Fixed ko.lua, Updated resource.lua --- __resource.lua | 2 + locales/ko.lua | 154 ++++++++++++++++++++++++++++++ localization/ko_esx_policejob.sql | 90 +++++++++++++++++ 3 files changed, 246 insertions(+) create mode 100644 locales/ko.lua create mode 100644 localization/ko_esx_policejob.sql diff --git a/__resource.lua b/__resource.lua index dca1b4b1..c6eb4e6e 100644 --- a/__resource.lua +++ b/__resource.lua @@ -15,6 +15,7 @@ server_scripts { 'locales/fi.lua', 'locales/es.lua', 'locales/sv.lua', + 'locales/ko.lua', 'config.lua', 'server/main.lua' } @@ -29,6 +30,7 @@ client_scripts { 'locales/fi.lua', 'locales/es.lua', 'locales/sv.lua', + 'locales/ko.lua', 'config.lua', 'client/main.lua' } diff --git a/locales/ko.lua b/locales/ko.lua new file mode 100644 index 00000000..2a523c0c --- /dev/null +++ b/locales/ko.lua @@ -0,0 +1,154 @@ +Locales['ko'] = { + -- Cloakroom + ['cloakroom'] = '라커룸', + ['citizen_wear'] = '민간인 복장', + ['police_wear'] = '경찰 복장', + ['gilet_wear'] = '오렌지 반사 재킷', + ['bullet_wear'] = '방탄 조끼', + ['no_outfit'] = '당신에게 맞는 유니폼이 없습니다!', + ['open_cloackroom'] = '~y~옷~s~을 변경하려면 ~INPUT_CONTEXT~를 누르십시오.', + -- Armory + ['remove_object'] = '오브젝트를 빼다', + ['deposit_object'] = '오브젝트를 두다', + ['get_weapon'] = '병기고에서 무기를 빼다', + ['put_weapon'] = '병기고에 무기를 넣다', + ['buy_weapons'] = '무기 구매', + ['armory'] = '병기고', + ['open_armory'] = '~INPUT_CONTEXT~를 눌러 ~y~병기고~s~에 접근하십시오.', + ['armory_owned'] = '소유', + ['armory_free'] = '자유', + ['armory_item'] = '$%s', + ['armory_weapontitle'] = '병기고 - 무기 구매', + ['armory_componenttitle'] = '병기고 - 무기 부착물', + ['armory_bought'] = '당신은 ~r~$%s~s~에 ~y~%s~s~를 구매했습니다', + ['armory_money'] = '당신은 이 무기를 살 수 없습니다', + ['armory_hascomponent'] = '이 부착물이 장착되어 있습니다!', + ['get_weapon_menu'] = '병기고 - 무기 빼다', + ['put_weapon_menu'] = '병기고 - 무기 넣다', + -- Vehicles + ['vehicle_menu'] = '차량', + ['vehicle_blocked'] = '모든 스폰 지점이 차단되었습니다!', + ['garage_prompt'] = '~INPUT_CONTEXT~를 눌러 ~y~차량 동작~s~에 액세스하십시오.', + ['garage_title'] = '차량 행동', + ['garage_stored'] = '저장됨', + ['garage_notstored'] = '차고가 아님', + ['garage_storing'] = '차량을 제거하려고 합니다. 주변에 아무도 없는지 확인하십시오.', + ['garage_has_stored'] = '차량이 차고에 보관되었습니다', + ['garage_has_notstored'] = '차고에 차량이 없습니다', + ['garage_notavailable'] = '차량이 차고에 저장되어 있지 않습니다', + ['garage_blocked'] = '차고 출구가 막혔습니다!', + ['garage_empty'] = '차고에 차량이 없습니다.', + ['garage_released'] = '차량이 출시되었습니다', + ['garage_store_nearby'] = '주변에 차량이 없습니다.', + ['garage_storeditem'] = '차고 열기', + ['garage_storeitem'] = '차량 정리', + ['garage_buyitem'] = '차량 상점', + ['helicopter_prompt'] = '~y~헬리콥터 동작~s~에 액세스하려면 ~INPUT_CONTEXT~를 누릅니다.', + ['helicopter_notauthorized'] = '헬리콥터를 구매할 수 없습니다.', + ['shop_item'] = '$%s', + ['vehicleshop_title'] = '차량 판매점', + ['vehicleshop_confirm'] = '이 차량을 사고 싶습니까?', + ['vehicleshop_bought'] = '당신은 ~r~$%s~s~에 ~y~%s~s~를 구매했습니다', + ['vehicleshop_money'] = '이 차량을 살 수 없습니다', + ['vehicleshop_awaiting_model'] = '차량이 현재 ~g~다운로드 및 로딩중입니다~s~. 잠시만 기다려주십시오', + ['confirm_no'] = '아니요', + ['confirm_yes'] = '예', + -- Service + ['service_max'] = '서비스에 진입 할 수 없습니다. 최대 임원 : %s/%s', + ['service_not'] = '당신은 서비스를 입력하지 않았습니다! 먼저 변경해야합니다.', + ['service_anonunce'] = '서비스 정보', + ['service_in'] = '당신은 서비스에 들어갔다, 환영합니다!', + ['service_in_announce'] = '~y~%s~s~가 서비스에 들어 왔습니다!', + ['service_out'] = '당신은 서비스를 떠났습니다.', + ['service_out_announce'] = '~y~%s~s~가 서비스를 떠났습니다.', + -- Action Menu + ['citizen_interaction'] = '시민 상호 작용', + ['vehicle_interaction'] = '차량 상호 작용', + ['object_spawner'] = '오브젝트 Spawner', + + ['id_card'] = '신분증', + ['search'] = '수색', + ['handcuff'] = '수갑을 채우다 / 수갑을 풀어주다', + ['drag'] = '호위', + ['put_in_vehicle'] = '차량에 넣다', + ['out_the_vehicle'] = '차량을 끌다', + ['fine'] = '벌금', + ['unpaid_bills'] = '미지급 벌금 관리', + ['license_check'] = '라이선스 관리', + ['license_revoke'] = '라이선스 취소', + ['license_revoked'] = '~b~%s~s~는 ~y~취소~s~입니다!', + ['licence_you_revoked'] = '~y~%s~s~에 속하는 ~b~%s~s~를 취소했습니다.', + ['no_players_nearby'] = '근처에 플레이어가 없습니다!', + ['being_searched'] = '~b~경찰~s~이 당신을 ~y~수색~s~', + -- Vehicle interaction + ['vehicle_info'] = '차량 정보', + ['pick_lock'] = '차량 락픽', + ['vehicle_unlocked'] = '차량 ~g~잠금 해제~s~', + ['no_vehicles_nearby'] = '근처에 차량이 없습니다', + ['impound'] = '차량을 견인하다', + ['impound_prompt'] = '~y~견인~s~을 취소하려면 ~INPUT_CONTEXT~를 누릅니다', + ['impound_canceled'] = '당신은 견인을 취소했습니다', + ['impound_canceled_moved'] = '차량이 움직였기 때문에 견인이 취소되었습니다', + ['impound_successful'] = '당신은 차량을 견인했습니다', + ['search_database'] = '차량 정보', + ['search_database_title'] = '차량 정보 - 등록번호로 검색', + ['search_database_error_invalid'] = '~y~유효한~s~ 등록 번호가 ~r~아닙니다.~s~', + ['search_database_error_not_found'] = '그 ~y~등록 번호~s~는 차량에 등록되지 ~r~않았습니다!~s~', + ['search_database_found'] = '이 차량은 ~b~%s~s~에 ~y~등록되었습니다~s~', + -- Traffic interaction + ['traffic_interaction'] = '교통 상호 작용', + ['cone'] = '원뿔', + ['barrier'] = '장벽', + ['spikestrips'] = '스파이크 스트립', + ['box'] = '상자', + ['cash'] = '현금 상자', + -- ID Card Menu + ['name'] = '이름: %s', + ['job'] = '직업: %s', + ['sex'] = '성별: %s', + ['dob'] = '생일: %s', + ['height'] = '키: %s', + ['id'] = 'ID: %s', + ['bac'] = '혈중 알코올 농도: %s', + ['unknown'] = '알 수 없는', + ['male'] = '남자', + ['female'] = '여자', + -- Body Search Menu + ['guns_label'] = '--- 총 ---', + ['inventory_label'] = '--- 인벤토리 ---', + ['license_label'] = ' --- 라이선스 ---', + ['confiscate'] = '%s 을 압수', + ['confiscate_weapon'] = '%s 와 %s 총알을 압수', + ['confiscate_inv'] = '%sx %s 을 압수', + ['confiscate_dirty'] = '더러운 돈을 압수: $%s', + ['you_confiscated'] = '당신은 ~y~%sx~s~ ~b~%s~s~을 ~b~%s~s~에게서 압수했습니다', + ['got_confiscated'] = '~y~%sx~s~ ~b~%s~s~이(가) ~y~%s~s~에 압수되었습니다', + ['you_confiscated_account'] = '당신은 ~g~$%s~s~ (%s) 를 ~b~%s~s~ 에게서 압수했습니다.', + ['got_confiscated_account'] = '~g~$%s~s~ (%s) 이(가) ~y~%s~s~에 압수되었습니다', + ['you_confiscated_weapon'] = '당신은 ~b~%s~s~을 ~b~%s~s~에게서 압수하고 ~o~%s~s~ 총알도 압수했습니다.', + ['got_confiscated_weapon'] = '당신의 ~b~%s~s~와 ~o~%s~s~ 총알이 ~y~%s~s~에 의해 압수되었습니다.', + ['traffic_offense'] = '교통 위반', + ['minor_offense'] = '경범죄', + ['average_offense'] = '일반 범죄', + ['major_offense'] = '심각한 범죄', + ['fine_total'] = '벌금: %s', + -- Vehicle Info Menu + ['plate'] = '번호판: %s', + ['owner_unknown'] = '소유자: 알 수 없는', + ['owner'] = '소유자: %s', + -- Boss Menu + ['open_bossmenu'] = '~INPUT_CONTEXT~를 눌러 메뉴를 엽니다.', + ['quantity_invalid'] = '유효하지 않은 수량', + ['have_withdrawn'] = '당신은 ~y~%sx~s~ ~b~%s~s~ 뺐다 ', + ['have_deposited'] = '당신은 ~y~%sx~s~ ~b~%s~s~ 넣었다', + ['quantity'] = '수량', + ['inventory'] = '인벤토리', + ['police_stock'] = '경찰 자리', + -- Misc + ['remove_prop'] = '~INPUT_CONTEXT~를 눌러 오브젝트를 삭제하십시오.', + ['map_blip'] = '경찰서', + ['unrestrained_timer'] = '당신의 수갑이 천천히 풀리는 것을 느낍니다.', + -- Notifications + ['alert_police'] = '경찰 경보', + ['phone_police'] = '경찰', +} diff --git a/localization/ko_esx_policejob.sql b/localization/ko_esx_policejob.sql new file mode 100644 index 00000000..c3041914 --- /dev/null +++ b/localization/ko_esx_policejob.sql @@ -0,0 +1,90 @@ +USE `essentialmode`; + +INSERT INTO `addon_account` (name, label, shared) VALUES + ('society_police', '경찰', 1) +; + +INSERT INTO `datastore` (name, label, shared) VALUES + ('society_police', '경찰', 1) +; + +INSERT INTO `addon_inventory` (name, label, shared) VALUES + ('society_police', '경찰', 1) +; + +INSERT INTO `jobs` (name, label) VALUES + ('police', '경찰') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('police',0,'recruit','순경',20,'{}','{}'), + ('police',1,'officer','경장',40,'{}','{}'), + ('police',2,'sergeant','경사',60,'{}','{}'), + ('police',3,'lieutenant','경위',85,'{}','{}'), + ('police',4,'boss','경찰국장',100,'{}','{}') +; + +CREATE TABLE `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`) +); + +INSERT INTO `fine_types` (label, amount, category) VALUES + ('경적 남용', 30, 0), + ('연속으로 라인을 넘음', 40, 0), + ('역주행', 250, 0), + ('불법 U턴', 250, 0), + ('불법적인 오프로드 운전', 170, 0), + ('공무원 명령 미준수', 30, 0), + ('불법적으로 차량 정지', 150, 0), + ('불법 주차', 70, 0), + ('오른쪽으로 양보하지 않음', 70, 0), + ('등록되지 않은 차량', 90, 0), + ('정지선 지키지 않음', 105, 0), + ('빨간불에서 멈추지 않음', 130, 0), + ('위험한 추월', 100, 0), + ('불법 차량 운전', 100, 0), + ('무면허 운전', 1500, 0), + ('뺑소니', 800, 0), + ('5 km 이상 과속', 90, 0), + ('5-15 km 과속', 120, 0), + ('15-30 km 과속', 180, 0), + ('30 km 이상 과속', 300, 0), + ('교통방해', 110, 1), + ('공공질서 문제', 90, 1), + ('무질서한 행동', 90, 1), + ('공무집행 방해', 130, 1), + ('민간인에 대한 모욕', 75, 1), + ('공무원에 대한 모욕', 110, 1), + ('민간인에 대한 언어폭력', 90, 1), + ('공무원에 대한 언어폭력', 150, 1), + ('허위 정보 제공', 250, 1), + ('부패 시도', 1500, 1), + ('도시에서 무기 사용', 120, 2), + ('도시에서 위험한 무기 사용', 300, 2), + ('총기 면허 없음', 600, 2), + ('불법 무기 소지', 700, 2), + ('절도 도구 소지', 300, 2), + ('차량 절도', 1800, 2), + ('마약 판매/분배', 1500, 2), + ('마약 제조', 1500, 2), + ('마약 소지 ', 650, 2), + ('민간인 납치', 1500, 2), + ('공무원 납치', 2000, 2), + ('강도', 650, 2), + ('상점의 무장 강도', 650, 2), + ('은행의 무장 강도', 1500, 2), + ('민간인에 대한 폭행', 2000, 3), + ('공무원에 대한 폭행', 2500, 3), + ('민간인 살인 시도', 3000, 3), + ('공무원 살인 시도', 5000, 3), + ('민간인 살인', 10000, 3), + ('공무원 살인', 30000, 3), + ('우발적 살인', 1800, 3), + ('사기', 2000, 2); +; From 9c6b828dba69f205d141cd94ba9a18adf8e926b4 Mon Sep 17 00:00:00 2001 From: Viktor <35453587+LifeGoal@users.noreply.github.com> Date: Sat, 4 Jan 2020 11:06:25 +0100 Subject: [PATCH 2343/3224] Swedish locale update (#340) * sv.lua completion * Update sv.lua --- locales/sv.lua | 54 +++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/locales/sv.lua b/locales/sv.lua index 55dd9b3f..bbba9d4e 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -26,33 +26,33 @@ Locales['sv'] = { ['get_weapon_menu'] = 'vapenförråd - Ta ut vapen', ['put_weapon_menu'] = 'vapenförråd - Spara vapen', -- Vehicles - ['vehicle_menu'] = 'vehicle', - ['vehicle_blocked'] = 'all available spawn points are currently blocked!', - ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.', - ['garage_title'] = 'vehicle Actions', - ['garage_stored'] = 'stored', - ['garage_notstored'] = 'not in garage', - ['garage_storing'] = 'we\'re attempting to remove the vehicle, make sure no players are around it.', - ['garage_has_stored'] = 'the vehicle has been stored in your garage', - ['garage_has_notstored'] = 'no nearby owned vehicles were found', - ['garage_notavailable'] = 'your vehicle is not stored in the garage.', - ['garage_blocked'] = 'there\'s no available spawn points!', - ['garage_empty'] = 'you dont have any vehicles in your garage.', - ['garage_released'] = 'your vehicle has been released from the garage.', - ['garage_store_nearby'] = 'there is no nearby vehicles.', - ['garage_storeditem'] = 'open garage', - ['garage_storeitem'] = 'store vehicle in garage', - ['garage_buyitem'] = 'vehicle shop', - ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', - ['helicopter_notauthorized'] = 'you\'re not authorized to buy helicopters.', - ['shop_item'] = '$%s', - ['vehicleshop_title'] = 'vehicle Shop', - ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', - ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~', - ['vehicleshop_money'] = 'you cannot afford that vehicle', - ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', - ['confirm_no'] = 'no', - ['confirm_yes'] = 'yes', + ['vehicle_menu'] = 'fordon', + ['vehicle_blocked'] = 'det finns ingen tillgänglig plats att ställa ut fordonet på!', + ['garage_prompt'] = 'tryck ~INPUT_CONTEXT~ för att komma åt ~y~garaget~s~.', + ['garage_title'] = 'garage', + ['garage_stored'] = 'inställt', + ['garage_notstored'] = 'uttaget', + ['garage_storing'] = 'vi håller på att ställa in ditt fordon, se till att ingen är i närheten.', + ['garage_has_stored'] = 'fordonet har ställts in i garaget', + ['garage_has_notstored'] = 'inget ägt fordon finns i närheten', + ['garage_notavailable'] = 'ditt fordon är inte inställt i ditt garage.', + ['garage_blocked'] = 'det finns ingen tillgänglig plats att ställa ut fordonet på!', + ['garage_empty'] = 'du har inga fordon i ditt garage.', + ['garage_released'] = 'ditt fordon har tagits ut från garaget.', + ['garage_store_nearby'] = 'det finns inget fordon i närheten.', + ['garage_storeditem'] = 'öppna garage', + ['garage_storeitem'] = 'ställ in fordon', + ['garage_buyitem'] = 'fordonshandel', + ['helicopter_prompt'] = 'klicka på ~INPUT_CONTEXT~ för att komma åt ~y~garaget~s~.', + ['helicopter_notauthorized'] = 'du har inte behörighet till att köpa en helikopter.', + ['shop_item'] = '%s SEK', + ['vehicleshop_title'] = 'fordonshandel', + ['vehicleshop_confirm'] = 'vill du köpa detta fordon?', + ['vehicleshop_bought'] = 'du köpte ~y~%s~s~ för ~r~$%s~s~', + ['vehicleshop_money'] = 'du har inte råd med detta fordon', + ['vehicleshop_awaiting_model'] = 'fordonet ~g~LADDAS NED OCH LADDAS IN~s~ var god vänta', + ['confirm_no'] = 'nej', + ['confirm_yes'] = 'ja', -- Service ['service_max'] = 'du kan inte gå tjänst, poliser i tjänst: %s/%s', ['service_not'] = 'du är inte i tjänst! Byt om för att gå in i tjänst.', From 176adafc08c037f892c28e9ae44263893b223844 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 4 Jan 2020 11:15:47 +0100 Subject: [PATCH 2344/3224] Added missing requirements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: EDWernars Co-Authored-By: Petr 'celestian' Čech Co-Authored-By: kandasoranyan --- README.md | 18 ++++++++++++++---- __resource.lua | 3 ++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c8757c21..ec62e9de 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,16 @@ # esx_policejob +This resource for ESX adds police armories, vehicle garages and ability for cops to search, handcuff people and much more. + ### Requirements * Auto mode - * [esx_billing](https://github.com/FXServer-ESX/fxserver-esx_billing) + * [esx_billing](https://github.com/ESX-Org/esx_billing) + * [esx_vehicleshop](https://github.com/ESX-Org/esx_vehicleshop) * Player management (boss actions and armory with buyable weapons) - * [esx_society](https://github.com/FXServer-ESX/fxserver-esx_society) - * [esx_datastore](https://github.com/FXServer-ESX/fxserver-esx_datastore) + * [esx_addoninventory](https://github.com/ESX-Org/esx_addoninventory) + * [esx_datastore](https://github.com/ESX-Org/esx_datastore) + * [esx_society](https://github.com/ESX-Org/esx_society) * ESX Identity Support * [esx_identity](https://github.com/ESX-Org/esx_identity) @@ -14,6 +18,9 @@ * ESX License Support * [esx_license](https://github.com/ESX-Org/esx_license) +* ESX Service Support + * [esx_service](https://github.com/ESX-Org/esx_service) + ## Download & Installation ### Using [fvm](https://github.com/qlaffont/fvm-installer) @@ -39,15 +46,18 @@ git clone https://github.com/ESX-Org/esx_policejob [esx]/esx_policejob ``` start esx_policejob ``` + - * If you want player management you have to set `Config.EnablePlayerManagement` to `true` in `config.lua` * If you want armory management you have to set `Config.EnableArmoryManagement` to `true` in `config.lua` * If you want license management you have to set `Config.EnableLicenses` to `true` in `config.lua` + * If you want service management you have to set `Config.MaxInService` to a higher value than `-1` in `config.lua` + # Legal ### License esx_policejob - police script for ESX -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. diff --git a/__resource.lua b/__resource.lua index dca1b4b1..76c7da85 100644 --- a/__resource.lua +++ b/__resource.lua @@ -35,5 +35,6 @@ client_scripts { dependencies { 'es_extended', - 'esx_billing' + 'esx_billing', + 'esx_vehicleshop' } \ No newline at end of file From dcc113ae062fb0b7496ef30d73a07266b5b171c5 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sat, 4 Jan 2020 11:17:55 +0100 Subject: [PATCH 2345/3224] Removed keys table (#172) * Removed keys table * Changed key values to numbers --- client/job.lua | 14 +++++++------- client/main.lua | 26 +++++++------------------- 2 files changed, 14 insertions(+), 26 deletions(-) diff --git a/client/job.lua b/client/job.lua index a13ec181..1021b88c 100644 --- a/client/job.lua +++ b/client/job.lua @@ -361,7 +361,7 @@ Citizen.CreateThread(function() if CurrentAction then ESX.ShowHelpNotification(CurrentActionMsg) - if IsControlJustReleased(0, Keys['E']) then + if IsControlJustReleased(0, 38) then if CurrentAction == 'AmbulanceActions' then OpenAmbulanceActionsMenu() @@ -380,7 +380,7 @@ Citizen.CreateThread(function() end elseif ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'ambulance' and not isDead then - if IsControlJustReleased(0, Keys['F6']) then + if IsControlJustReleased(0, 167) then OpenMobileAmbulanceActionsMenu() end else @@ -832,12 +832,12 @@ function WaitForVehicleToLoad(modelHash) while not HasModelLoaded(modelHash) do Citizen.Wait(0) - DisableControlAction(0, Keys['TOP'], true) - DisableControlAction(0, Keys['DOWN'], true) - DisableControlAction(0, Keys['LEFT'], true) - DisableControlAction(0, Keys['RIGHT'], true) + DisableControlAction(0, 27, true) + DisableControlAction(0, 173, true) + DisableControlAction(0, 174, true) + DisableControlAction(0, 175, true) DisableControlAction(0, 176, true) -- ENTER key - DisableControlAction(0, Keys['BACKSPACE'], true) + DisableControlAction(0, 177, true) drawLoadingText(_U('vehicleshop_awaiting_model'), 255, 255, 255, 255) end diff --git a/client/main.lua b/client/main.lua index deb877e3..f0375890 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,15 +1,3 @@ -Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - local firstSpawn, PlayerLoaded = true, false isDead = false @@ -85,9 +73,9 @@ Citizen.CreateThread(function() if isDead then DisableAllControlActions(0) - EnableControlAction(0, Keys['G'], true) - EnableControlAction(0, Keys['T'], true) - EnableControlAction(0, Keys['E'], true) + EnableControlAction(0, 47, true) + EnableControlAction(0, 245, true) + EnableControlAction(0, 38, true) else Citizen.Wait(500) end @@ -163,7 +151,7 @@ function StartDistressSignal() AddTextComponentSubstringPlayerName(_U('distress_send')) EndTextCommandDisplayText(0.175, 0.805) - if IsControlPressed(0, Keys['G']) then + if IsControlPressed(0, 47) then SendDistressSignal() Citizen.CreateThread(function() @@ -270,21 +258,21 @@ function StartDeathTimer() if not Config.EarlyRespawnFine then text = text .. _U('respawn_bleedout_prompt') - if IsControlPressed(0, Keys['E']) and timeHeld > 60 then + if IsControlPressed(0, 38) and timeHeld > 60 then RemoveItemsAfterRPDeath() break end elseif Config.EarlyRespawnFine and canPayFine then text = text .. _U('respawn_bleedout_fine', ESX.Math.GroupDigits(Config.EarlyRespawnFineAmount)) - if IsControlPressed(0, Keys['E']) and timeHeld > 60 then + if IsControlPressed(0, 38) and timeHeld > 60 then TriggerServerEvent('esx_ambulancejob:payFine') RemoveItemsAfterRPDeath() break end end - if IsControlPressed(0, Keys['E']) then + if IsControlPressed(0, 38) then timeHeld = timeHeld + 1 else timeHeld = 0 From 9247654252e0c7eac736763eb5d65e0859435818 Mon Sep 17 00:00:00 2001 From: Viktor <35453587+LifeGoal@users.noreply.github.com> Date: Sat, 4 Jan 2020 11:18:15 +0100 Subject: [PATCH 2346/3224] sv.lua completion (#151) * sv.lua completion * Update sv.lua --- locales/sv.lua | 60 +++++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/locales/sv.lua b/locales/sv.lua index 501e602c..64abd2cf 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -4,37 +4,37 @@ Locales['sv'] = { ['ems_clothes_civil'] = 'civilkläder', ['ems_clothes_ems'] = 'ambulanskläder', -- Vehicles - ['ambulance'] = 'ambulance', - ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', - ['helicopter_buy'] = 'helicopter shop', - ['helicopter_garage'] = 'open garage', - ['helicopter_store'] = 'store helicopter in garage', - ['helicopter_garage_title'] = 'helicopter Garage', - ['helicopter_title'] = 'helicopter Actions', - ['helicopter_notauthorized'] = 'you\'re not authorized to buy helicopters.', - ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.', - ['garage_title'] = 'vehicle Actions', - ['garage_stored'] = 'stored', - ['garage_notstored'] = 'not in garage', - ['garage_storing'] = 'we\'re attempting to remove the vehicle, make sure no players are around it.', - ['garage_has_stored'] = 'the vehicle has been stored in your garage', - ['garage_has_notstored'] = 'no nearby owned vehicles were found', - ['garage_notavailable'] = 'your vehicle is not stored in the garage.', - ['garage_blocked'] = 'there\'s no available spawn points!', - ['garage_empty'] = 'you dont have any vehicles in your garage.', - ['garage_released'] = 'your vehicle has been released from the garage.', - ['garage_store_nearby'] = 'there is no nearby vehicles.', - ['garage_storeditem'] = 'open garage', - ['garage_storeitem'] = 'store vehicle in garage', - ['garage_buyitem'] = 'vehicle shop', + ['ambulance'] = 'ambulans', + ['helicopter_prompt'] = 'klicka på ~INPUT_CONTEXT~ för att komma åt ~y~garaget~s~.', + ['helicopter_buy'] = 'fordonshandel', + ['helicopter_garage'] = 'öppna garage', + ['helicopter_store'] = 'ställ in helikopter', + ['helicopter_garage_title'] = 'garage', + ['helicopter_title'] = 'garage', + ['helicopter_notauthorized'] = 'du har inte behörighet till att köpa en helikopter.', + ['garage_prompt'] = 'tryck ~INPUT_CONTEXT~ för att komma åt ~y~garaget~s~.', + ['garage_title'] = 'garage', + ['garage_stored'] = 'inställt', + ['garage_notstored'] = 'uttaget', + ['garage_storing'] = 'vi håller på att ställa in ditt fordon, se till att ingen är i närheten.', + ['garage_has_stored'] = 'fordonet har ställts in i garaget', + ['garage_has_notstored'] = 'inget ägt fordon finns i närheten', + ['garage_notavailable'] = 'ditt fordon är inte inställt i ditt garage.', + ['garage_blocked'] = 'det finns ingen tillgänglig plats att ställa ut fordonet på!', + ['garage_empty'] = 'du har inga fordon i ditt garage.', + ['garage_released'] = 'ditt fordon har tagits ut från garaget.', + ['garage_store_nearby'] = 'det finns inget fordon i närheten.', + ['garage_storeditem'] = 'öppna garage', + ['garage_storeitem'] = 'ställ in fordon', + ['garage_buyitem'] = 'fordonshandel', ['shop_item'] = '%s SEK', - ['vehicleshop_title'] = 'vehicle Shop', - ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', - ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~', - ['vehicleshop_money'] = 'you cannot afford that vehicle', - ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', - ['confirm_no'] = 'no', - ['confirm_yes'] = 'yes', + ['vehicleshop_title'] = 'fordonshandel', + ['vehicleshop_confirm'] = 'vill du köpa detta fordon?', + ['vehicleshop_bought'] = 'du köpte ~y~%s~s~ för ~r~$%s~s~', + ['vehicleshop_money'] = 'du har inte råd med detta fordon', + ['vehicleshop_awaiting_model'] = 'fordonet ~g~LADDAS NED OCH LADDAS IN~s~ var god vänta', + ['confirm_no'] = 'nej', + ['confirm_yes'] = 'ja', -- Action Menu ['revive_inprogress'] = 'en återupplivning har börjats', ['revive_complete'] = 'du har återupplivat ~y~%s~s~, bra jobbat!', From 94ba42812a16ebfba7f510599ee1b5b659ece090 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 4 Jan 2020 11:35:42 +0100 Subject: [PATCH 2347/3224] Removed useless prints, minor repo updates --- README.md | 7 ++++++- __resource.lua | 1 + server/main.lua | 44 ++++++++++++++++---------------------------- 3 files changed, 23 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index f2c3b451..5476caee 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ # esx_ambulancejob +ESX Ambulance Job is an plugin for ESX with features: + +- Adds death screen, with early respawn timer and bleed out timer +- Vehicle garages, revive menu and more for on duty EMS + ## Requirements * Auto mode @@ -39,7 +44,7 @@ start esx_ambulancejob ### License esx_ambulancejob - ambulance script for fivem -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. diff --git a/__resource.lua b/__resource.lua index 5c55606b..f5f45d38 100644 --- a/__resource.lua +++ b/__resource.lua @@ -36,5 +36,6 @@ client_scripts { dependencies { 'es_extended', + 'esx_skin', 'esx_vehicleshop' } \ No newline at end of file diff --git a/server/main.lua b/server/main.lua index 2003be0d..1f037c9e 100644 --- a/server/main.lua +++ b/server/main.lua @@ -10,8 +10,6 @@ AddEventHandler('esx_ambulancejob:revive', function(target) if xPlayer.job.name == 'ambulance' then xPlayer.addMoney(Config.ReviveReward) TriggerClientEvent('esx_ambulancejob:revive', target) - else - print(('esx_ambulancejob: %s attempted to revive!'):format(xPlayer.identifier)) end end) @@ -21,8 +19,6 @@ AddEventHandler('esx_ambulancejob:heal', function(target, type) if xPlayer.job.name == 'ambulance' then TriggerClientEvent('esx_ambulancejob:heal', target, type) - else - print(('esx_ambulancejob: %s attempted to heal!'):format(xPlayer.identifier)) end end) @@ -32,8 +28,6 @@ AddEventHandler('esx_ambulancejob:putInVehicle', function(target) if xPlayer.job.name == 'ambulance' then TriggerClientEvent('esx_ambulancejob:putInVehicle', target) - else - print(('esx_ambulancejob: %s attempted to put in vehicle!'):format(xPlayer.identifier)) end end) @@ -117,7 +111,6 @@ ESX.RegisterServerCallback('esx_ambulancejob:buyJobVehicle', function(source, cb -- vehicle model not found if price == 0 then - print(('esx_ambulancejob: %s attempted to exploit the shop! (invalid vehicle model)'):format(xPlayer.identifier)) cb(false) else if xPlayer.getMoney() >= price then @@ -165,14 +158,12 @@ ESX.RegisterServerCallback('esx_ambulancejob:storeNearbyVehicle', function(sourc ['@job'] = xPlayer.job.name }, function (rowsChanged) if rowsChanged == 0 then - print(('esx_ambulancejob: %s has exploited the garage!'):format(xPlayer.identifier)) cb(false) else cb(true, foundNum) end end) end - end) function getPriceFromHash(hashKey, jobGrade, type) @@ -199,9 +190,7 @@ end RegisterServerEvent('esx_ambulancejob:removeItem') AddEventHandler('esx_ambulancejob:removeItem', function(item) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) - + local xPlayer = ESX.GetPlayerFromId(source) xPlayer.removeInventoryItem(item, 1) if item == 'bandage' then @@ -216,10 +205,10 @@ AddEventHandler('esx_ambulancejob:giveItem', function(itemName, amount) local xPlayer = ESX.GetPlayerFromId(source) if xPlayer.job.name ~= 'ambulance' then - print(('esx_ambulancejob: %s attempted to spawn in an item!'):format(xPlayer.identifier)) + print(('[esx_ambulancejob] [^2INFO^7] "%s" attempted to spawn in an item!'):format(xPlayer.identifier)) return elseif (itemName ~= 'medikit' and itemName ~= 'bandage') then - print(('esx_ambulancejob: %s attempted to spawn in an item!'):format(xPlayer.identifier)) + print(('[esx_ambulancejob] [^2INFO^7] "%s" attempted to spawn in an item!'):format(xPlayer.identifier)) return end @@ -231,17 +220,19 @@ AddEventHandler('esx_ambulancejob:giveItem', function(itemName, amount) end) TriggerEvent('es:addGroupCommand', 'revive', 'admin', function(source, args, user) - if args[1] ~= nil then - if GetPlayerName(tonumber(args[1])) ~= nil then - print(('esx_ambulancejob: %s used admin revive'):format(GetPlayerIdentifiers(source)[1])) - TriggerClientEvent('esx_ambulancejob:revive', tonumber(args[1])) + if args[1] then + local playerId = tonumber(args[1]) + if playerId and ESX.Players[playerId] then + TriggerClientEvent('esx_ambulancejob:revive', playerId) + else + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) end else TriggerClientEvent('esx_ambulancejob:revive', source) end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, { help = _U('revive_help'), params = {{ name = 'id' }} }) +end, { help = _U('revive_help'), params = {{ name = 'playerId' }} }) ESX.RegisterUsableItem('medikit', function(source) if not playersHealing[source] then @@ -276,7 +267,7 @@ ESX.RegisterServerCallback('esx_ambulancejob:getDeathStatus', function(source, c ['@identifier'] = identifier }, function(isDead) if isDead then - print(('esx_ambulancejob: %s attempted combat logging!'):format(identifier)) + print(('[esx_ambulancejob] [^2INFO^7] "%s" attempted combat logging'):format(identifier)) end cb(isDead) @@ -287,13 +278,10 @@ RegisterServerEvent('esx_ambulancejob:setDeathStatus') AddEventHandler('esx_ambulancejob:setDeathStatus', function(isDead) local identifier = GetPlayerIdentifiers(source)[1] - if type(isDead) ~= 'boolean' then - print(('esx_ambulancejob: %s attempted to parse something else than a boolean to setDeathStatus!'):format(identifier)) - return + if type(isDead) == 'boolean' then + MySQL.Sync.execute('UPDATE users SET is_dead = @isDead WHERE identifier = @identifier', { + ['@identifier'] = identifier, + ['@isDead'] = isDead + }) end - - MySQL.Sync.execute('UPDATE users SET is_dead = @isDead WHERE identifier = @identifier', { - ['@identifier'] = identifier, - ['@isDead'] = isDead - }) end) From c7dbd9361fae3262a672b6ffa7b1605842c3efc0 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 4 Jan 2020 11:45:00 +0100 Subject: [PATCH 2348/3224] Fixed player revive notification showing Steam name, and check if online --- client/job.lua | 75 ++++++++++++++++++++++--------------------------- locales/br.lua | 1 + locales/cs.lua | 1 + locales/en.lua | 1 + locales/es.lua | 1 + locales/fi.lua | 7 +++-- locales/fr.lua | 7 +++-- locales/pl.lua | 1 + locales/sv.lua | 1 + server/main.lua | 29 +++++++++++-------- 10 files changed, 65 insertions(+), 59 deletions(-) diff --git a/client/job.lua b/client/job.lua index 1021b88c..2434ca4f 100644 --- a/client/job.lua +++ b/client/job.lua @@ -62,48 +62,7 @@ function OpenMobileAmbulanceActionsMenu() else if data.current.value == 'revive' then - - isBusy = true - - ESX.TriggerServerCallback('esx_ambulancejob:getItemAmount', function(quantity) - if quantity > 0 then - local closestPlayerPed = GetPlayerPed(closestPlayer) - - if IsPedDeadOrDying(closestPlayerPed, 1) then - local playerPed = PlayerPedId() - - ESX.ShowNotification(_U('revive_inprogress')) - - local lib, anim = 'mini@cpr@char_a@cpr_str', 'cpr_pumpchest' - - for i=1, 15, 1 do - Citizen.Wait(900) - - ESX.Streaming.RequestAnimDict(lib, function() - TaskPlayAnim(PlayerPedId(), lib, anim, 8.0, -8.0, -1, 0, 0, false, false, false) - end) - end - - TriggerServerEvent('esx_ambulancejob:removeItem', 'medikit') - TriggerServerEvent('esx_ambulancejob:revive', GetPlayerServerId(closestPlayer)) - - -- Show revive award? - if Config.ReviveReward > 0 then - ESX.ShowNotification(_U('revive_complete_award', GetPlayerName(closestPlayer), Config.ReviveReward)) - else - ESX.ShowNotification(_U('revive_complete', GetPlayerName(closestPlayer))) - end - else - ESX.ShowNotification(_U('player_not_unconscious')) - end - else - ESX.ShowNotification(_U('not_enough_medikit')) - end - - isBusy = false - - end, 'medikit') - + revivePlayer(closestPlayer) elseif data.current.value == 'small' then ESX.TriggerServerCallback('esx_ambulancejob:getItemAmount', function(quantity) @@ -174,6 +133,38 @@ function OpenMobileAmbulanceActionsMenu() end) end +function revivePlayer(closestPlayer) + isBusy = true + + ESX.TriggerServerCallback('esx_ambulancejob:getItemAmount', function(quantity) + if quantity > 0 then + local closestPlayerPed = GetPlayerPed(closestPlayer) + + if IsPedDeadOrDying(closestPlayerPed, 1) then + local playerPed = PlayerPedId() + local lib, anim = 'mini@cpr@char_a@cpr_str', 'cpr_pumpchest' + ESX.ShowNotification(_U('revive_inprogress')) + + for i=1, 15 do + Citizen.Wait(900) + + ESX.Streaming.RequestAnimDict(lib, function() + TaskPlayAnim(playerPed, lib, anim, 8.0, -8.0, -1, 0, 0, false, false, false) + end) + end + + TriggerServerEvent('esx_ambulancejob:removeItem', 'medikit') + TriggerServerEvent('esx_ambulancejob:revive', GetPlayerServerId(closestPlayer)) + else + ESX.ShowNotification(_U('player_not_unconscious')) + end + else + ESX.ShowNotification(_U('not_enough_medikit')) + end + isBusy = false + end, 'medikit') +end + function FastTravel(coords, heading) local playerPed = PlayerPedId() diff --git a/locales/br.lua b/locales/br.lua index 1cd0b382..6d9551c2 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -39,6 +39,7 @@ Locales['br'] = { ['revive_inprogress'] = 'Reanimação em andamento', ['revive_complete'] = 'você ressuscitou ~y~%s~s~', ['revive_complete_award'] = 'você ressuscitou ~y~%s~s~, ~g~$%s~s~', + ['revive_fail_offline'] = 'that player is no longer online', ['heal_inprogress'] = 'you are healing!', ['heal_complete'] = 'you have healed ~y~%s~s~', ['no_players'] = 'Nenhum jogador nas proximidades', diff --git a/locales/cs.lua b/locales/cs.lua index aa2f664f..807ad4e2 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -39,6 +39,7 @@ Locales['cs'] = { ['revive_inprogress'] = 'probíhá oživení!', ['revive_complete'] = 'oživili jste ~y~%s~s~', ['revive_complete_award'] = 'oživili jste ~y~%s~s~ a dostali jste ~g~$%s~s~!', + ['revive_fail_offline'] = 'that player is no longer online', ['heal_inprogress'] = 'uzdravujete!', ['heal_complete'] = 'uzdravili jste ~y~%s~s~', ['no_players'] = 'v okolí není žádný hráč!', diff --git a/locales/en.lua b/locales/en.lua index 36848986..ab37f814 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -39,6 +39,7 @@ Locales['en'] = { ['revive_inprogress'] = 'a revive is in progress!', ['revive_complete'] = 'you have revived ~y~%s~s~', ['revive_complete_award'] = 'you have revived ~y~%s~s~ and earned ~g~$%s~s~!', + ['revive_fail_offline'] = 'that player is no longer online', ['heal_inprogress'] = 'you are healing!', ['heal_complete'] = 'you have healed ~y~%s~s~', ['no_players'] = 'no players nearby', diff --git a/locales/es.lua b/locales/es.lua index a197d2ac..caad1d52 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -39,6 +39,7 @@ Locales['es'] = { ['revive_inprogress'] = 'reanimación en curso', ['revive_complete'] = 'has sido reanimado ~y~%s~s~', ['revive_complete_award'] = 'has sido reanimado ~y~%s~s~, ~g~$%s~s~', + ['revive_fail_offline'] = 'that player is no longer online', ['heal_inprogress'] = 'you are healing!', ['heal_complete'] = 'you have healed ~y~%s~s~', ['no_players'] = 'ningún jugador cerca', diff --git a/locales/fi.lua b/locales/fi.lua index 2068b318..ecc1b36e 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -1,8 +1,8 @@ Locales['fi'] = { -- Cloakroom - ['cloakroom'] = 'Vaatelokero', - ['ems_clothes_civil'] = 'Siviilikamppeet', - ['ems_clothes_ems'] = 'Työkamppeet', + ['cloakroom'] = 'vaatelokero', + ['ems_clothes_civil'] = 'siviilikamppeet', + ['ems_clothes_ems'] = 'työkamppeet', -- Vehicles ['ambulance'] = 'ambulance', ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', @@ -39,6 +39,7 @@ Locales['fi'] = { ['revive_inprogress'] = 'elvytys on menossa!', ['revive_complete'] = 'sinä elvytit henkilön ~y~%s~s~', ['revive_complete_award'] = 'sinä elvytit henkilön ~y~%s~s~ ja tienasit ~g~$%s~s~!', + ['revive_fail_offline'] = 'that player is no longer online', ['heal_inprogress'] = 'sinä olet parantamassa!', ['heal_complete'] = 'sinä paransit henkilön ~y~%s~s~', ['no_players'] = 'ei pelaajia lähettyvillä', diff --git a/locales/fr.lua b/locales/fr.lua index 94f62665..24fb1a4c 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,8 +1,8 @@ Locales['fr'] = { -- Cloakroom - ['cloakroom'] = 'Vestiaire', - ['ems_clothes_civil'] = 'Tenue Civil', - ['ems_clothes_ems'] = 'Tenue Ambulancier', + ['cloakroom'] = 'vestiaire', + ['ems_clothes_civil'] = 'tenue Civil', + ['ems_clothes_ems'] = 'tenue Ambulancier', -- Vehicles ['ambulance'] = 'ambulance', ['helicopter_prompt'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder aux ~y~Actions de l\'hélicoptère~s~.', @@ -39,6 +39,7 @@ Locales['fr'] = { ['revive_inprogress'] = 'réanimation en cours', ['revive_complete'] = 'vous avez réanimé ~y~%s~s~', ['revive_complete_award'] = 'vous avez réanimé ~y~%s~s~, ~g~$%s~s~', + ['revive_fail_offline'] = 'that player is no longer online', ['heal_inprogress'] = 'vous soignez...', ['heal_complete'] = 'vous avez soigné ~y~%s~s~', ['no_players'] = 'aucun joueur à proximité', diff --git a/locales/pl.lua b/locales/pl.lua index ebf75ce1..7308e156 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -39,6 +39,7 @@ Locales['pl'] = { ['revive_inprogress'] = 'trwa wskrzeszenie', ['revive_complete'] = 'zostałeś wskrzeszony ~y~%s~s~', ['revive_complete_award'] = 'zostałeś wskrzeszony ~y~%s~s~ i zarobiono ~g~$%s~s~!', + ['revive_fail_offline'] = 'that player is no longer online', ['heal_inprogress'] = 'leczysz!', ['heal_complete'] = 'zostałeś uleczony ~y~%s~s~', ['no_players'] = 'brak graczy w pobliżu', diff --git a/locales/sv.lua b/locales/sv.lua index 64abd2cf..c52d1f33 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -39,6 +39,7 @@ Locales['sv'] = { ['revive_inprogress'] = 'en återupplivning har börjats', ['revive_complete'] = 'du har återupplivat ~y~%s~s~, bra jobbat!', ['revive_complete_award'] = 'du har återupplivat ~y~%s~s~ och tjärnat ~g~%s SEK~s~ för dina tjänster, bra jobbat!', + ['revive_fail_offline'] = 'den spelaren har lämnat servern', ['heal_inprogress'] = 'du behandlar patienten!', ['heal_complete'] = 'du har behandlat ~y~%s~s~', ['no_players'] = 'det finns inga spelare i närheten!', diff --git a/server/main.lua b/server/main.lua index 1f037c9e..6da561e6 100644 --- a/server/main.lua +++ b/server/main.lua @@ -3,17 +3,24 @@ local playersHealing = {} TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) -RegisterServerEvent('esx_ambulancejob:revive') -AddEventHandler('esx_ambulancejob:revive', function(target) +RegisterNetEvent('esx_ambulancejob:revive') +AddEventHandler('esx_ambulancejob:revive', function(playerId) local xPlayer = ESX.GetPlayerFromId(source) - if xPlayer.job.name == 'ambulance' then - xPlayer.addMoney(Config.ReviveReward) - TriggerClientEvent('esx_ambulancejob:revive', target) + if xPlayer and xPlayer.job.name == 'ambulance' then + local xTarget = ESX.GetPlayerFromId(playerId) + + if xTarget then + xPlayer.showNotification(_U('revive_complete_award', xTarget.name, Config.ReviveReward)) + xPlayer.addMoney(Config.ReviveReward) + xTarget.triggerEvent('esx_ambulancejob:revive') + else + xPlayer.showNotification(_U('revive_fail_offline')) + end end end) -RegisterServerEvent('esx_ambulancejob:heal') +RegisterNetEvent('esx_ambulancejob:heal') AddEventHandler('esx_ambulancejob:heal', function(target, type) local xPlayer = ESX.GetPlayerFromId(source) @@ -22,7 +29,7 @@ AddEventHandler('esx_ambulancejob:heal', function(target, type) end end) -RegisterServerEvent('esx_ambulancejob:putInVehicle') +RegisterNetEvent('esx_ambulancejob:putInVehicle') AddEventHandler('esx_ambulancejob:putInVehicle', function(target) local xPlayer = ESX.GetPlayerFromId(source) @@ -88,7 +95,7 @@ if Config.EarlyRespawnFine then cb(bankBalance >= Config.EarlyRespawnFineAmount) end) - RegisterServerEvent('esx_ambulancejob:payFine') + RegisterNetEvent('esx_ambulancejob:payFine') AddEventHandler('esx_ambulancejob:payFine', function() local xPlayer = ESX.GetPlayerFromId(source) local fineAmount = Config.EarlyRespawnFineAmount @@ -188,7 +195,7 @@ function getPriceFromHash(hashKey, jobGrade, type) return 0 end -RegisterServerEvent('esx_ambulancejob:removeItem') +RegisterNetEvent('esx_ambulancejob:removeItem') AddEventHandler('esx_ambulancejob:removeItem', function(item) local xPlayer = ESX.GetPlayerFromId(source) xPlayer.removeInventoryItem(item, 1) @@ -200,7 +207,7 @@ AddEventHandler('esx_ambulancejob:removeItem', function(item) end end) -RegisterServerEvent('esx_ambulancejob:giveItem') +RegisterNetEvent('esx_ambulancejob:giveItem') AddEventHandler('esx_ambulancejob:giveItem', function(itemName, amount) local xPlayer = ESX.GetPlayerFromId(source) @@ -274,7 +281,7 @@ ESX.RegisterServerCallback('esx_ambulancejob:getDeathStatus', function(source, c end) end) -RegisterServerEvent('esx_ambulancejob:setDeathStatus') +RegisterNetEvent('esx_ambulancejob:setDeathStatus') AddEventHandler('esx_ambulancejob:setDeathStatus', function(isDead) local identifier = GetPlayerIdentifiers(source)[1] From 00b5a75d4f5e413516e4ae0084cc956a1e08ce78 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 4 Jan 2020 12:56:46 +0100 Subject: [PATCH 2349/3224] Minor server sided code improvement, fixed #14 --- README.md | 3 ++- server/main.lua | 36 +++++++++++++++++------------------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index c1fd14aa..ae32faa2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # esx_joblisting + Simple job listing script, you can specify what jobs you want to be whitelisted in db. ## Download & Installation @@ -30,7 +31,7 @@ start esx_joblisting ### License esx_joblisting - job listing script -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. diff --git a/server/main.lua b/server/main.lua index 3802ae40..b7a2d509 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,37 +1,35 @@ ESX = nil +local availableJobs = {} + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) -ESX.RegisterServerCallback('esx_joblisting:getJobsList', function(source, cb) +MySQL.ready(function() MySQL.Async.fetchAll('SELECT * FROM jobs WHERE whitelisted = @whitelisted', { ['@whitelisted'] = false }, function(result) - local data = {} - for i=1, #result, 1 do - table.insert(data, { - job = result[i].name, + table.insert(availableJobs, { + job = result[i].name, label = result[i].label }) end - - cb(data) end) end) +ESX.RegisterServerCallback('esx_joblisting:getJobsList', function(source, cb) + cb(availableJobs) +end) + RegisterServerEvent('esx_joblisting:setJob') AddEventHandler('esx_joblisting:setJob', function(job) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) + local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.fetchAll('SELECT whitelisted FROM jobs WHERE name = @name', { - ['@name'] = job, - }, function(result) - if not result[1].whitelisted then - xPlayer.setJob(job, 0) - else - print(('esx_joblisting: %s attempted to set a whitelisted job! (lua injector)'):format(xPlayer.identifier)) + if xPlayer then + for k,v in ipairs(availableJobs) do + if v.job == job then + xPlayer.setJob(job, 0) + break + end end - - end) - + end end) From bc4f9507178d80226bc781edbe1c2f3bd2cfca2e Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 4 Jan 2020 13:05:17 +0100 Subject: [PATCH 2350/3224] Minor repo changes --- README.md | 12 ++++++++++++ __resource.lua | 2 +- client/main.lua | 16 ++-------------- config.lua | 5 +++-- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index fc5e3235..162d2aef 100644 --- a/README.md +++ b/README.md @@ -26,3 +26,15 @@ start esx_voice ## Credits [aabbfive](https://github.com/aabbfive/voicecontroller) - Original author + +# Legal +### License +esx_voice + +Copyright (C) 2015-2020 Jérémie N'gadi + +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 http://www.gnu.org/licenses/. diff --git a/__resource.lua b/__resource.lua index d314d63b..bbf4a86a 100644 --- a/__resource.lua +++ b/__resource.lua @@ -9,7 +9,7 @@ client_scripts { 'locales/br.lua', 'locales/en.lua', 'locales/fi.lua', - 'locales/fr.lua', + 'locales/fr.lua', 'locales/pl.lua', 'locales/sv.lua', 'config.lua', diff --git a/client/main.lua b/client/main.lua index 9f03719d..7b461c26 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,15 +1,3 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - local voice = {default = 5.0, shout = 12.0, whisper = 1.0, current = 0, level = nil} function drawLevel(r, g, b, a) @@ -20,7 +8,7 @@ function drawLevel(r, g, b, a) SetTextDropShadow() SetTextOutline() - BeginTextCommandDisplayText("STRING") + BeginTextCommandDisplayText('STRING') AddTextComponentSubstringPlayerName(_U('voice', voice.level)) EndTextCommandDisplayText(0.175, 0.92) end @@ -39,7 +27,7 @@ Citizen.CreateThread(function() while true do Citizen.Wait(1) - if IsControlJustPressed(1, Keys['H']) and IsControlPressed(1, Keys['LEFTSHIFT']) then + if IsControlJustPressed(1, 74) and IsControlPressed(1, 21) then voice.current = (voice.current + 1) % 3 if voice.current == 0 then NetworkSetTalkerProximity(voice.default) diff --git a/config.lua b/config.lua index ad83260a..1875b978 100644 --- a/config.lua +++ b/config.lua @@ -1,2 +1,3 @@ -Config = {} -Config.Locale = 'en' \ No newline at end of file +Config = {} + +Config.Locale = 'fr' From 2634d0356e4406c8505f4f1345ddbefece8b4f2f Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sat, 4 Jan 2020 13:06:51 +0100 Subject: [PATCH 2351/3224] Removed keys table --- client/main.lua | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/client/main.lua b/client/main.lua index 896659a4..600255d2 100644 --- a/client/main.lua +++ b/client/main.lua @@ -3,18 +3,6 @@ local store = "" local blipRobbery = nil ESX = nil -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - Citizen.CreateThread(function() while ESX == nil do TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) @@ -119,7 +107,7 @@ Citizen.CreateThread(function() if distance < 0.5 then ESX.ShowHelpNotification(_U('press_to_rob', v.nameOfStore)) - if IsControlJustReleased(0, Keys['E']) then + if IsControlJustReleased(0, 38) then if IsPedArmed(PlayerPedId(), 4) then TriggerServerEvent('esx_holdup:robberyStarted', k) else From 9348b5176c54b625abb0664517776ad588bfcf23 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 4 Jan 2020 13:35:47 +0100 Subject: [PATCH 2352/3224] Initial repo cleanup --- __resource.lua | 14 +-- client.lua | 132 +++++++++-------------------- config.lua | 225 ++++++++++++++++++++++++------------------------- lists/seat.lua | 4 +- server.lua | 39 +++------ 5 files changed, 173 insertions(+), 241 deletions(-) diff --git a/__resource.lua b/__resource.lua index 6eb66c8a..df1af275 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,15 +1,17 @@ resource_manifest_version '05cfa83c-a124-4cfa-a768-c24a5811d8f9' +description 'ESX Sit' + version '1.0.3' +server_scripts { + 'config.lua', + 'lists/seat.lua', + 'server.lua' +} + client_scripts { 'config.lua', 'lists/seat.lua', 'client.lua' } - -server_scripts { - 'config.lua', - 'lists/seat.lua', - 'server.lua' -} \ No newline at end of file diff --git a/client.lua b/client.lua index 9836935e..0f22bd9a 100644 --- a/client.lua +++ b/client.lua @@ -1,23 +1,5 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - ESX = nil - -local sitting = false -local lastPos = nil -local currentSitObj = nil -local currentScenario = nil - -local debugProps = {} +local debugProps, sitting, lastPos, currentSitCoords, currentScenario = {} Citizen.CreateThread(function() while ESX == nil do @@ -26,139 +8,107 @@ Citizen.CreateThread(function() end end) -function DrawText3D(x,y,z, text, r,v,b) - local onScreen,_x,_y = World3dToScreen2d(x,y,z) - local px,py,pz = table.unpack(GetGameplayCamCoords()) - local dist = GetDistanceBetweenCoords(px,py,pz, x,y,z, 1) - - local scale = (1/dist)*2 - local fov = (1/GetGameplayCamFov())*100 - local scale = scale*fov - - if onScreen then - SetTextScale(0.0*scale, 1.1*scale) - SetTextFont(0) - SetTextProportional(1) - SetTextColour(r, v, b, 255) - SetTextDropshadow(0, 0, 0, 0, 255) - SetTextEdge(2, 0, 0, 0, 150) - SetTextDropShadow() - SetTextOutline() - SetTextEntry("STRING") - SetTextCentre(1) - AddTextComponentString(text) - DrawText(_x,_y) - end -end +if Config.Debug then + Citizen.CreateThread(function() + while true do + Citizen.Wait(0) -Citizen.CreateThread(function() - while true do - Citizen.Wait(0) - - if #debugProps > 0 then for i=1, #debugProps, 1 do local coords = GetEntityCoords(debugProps[i]) local hash = GetEntityModel(debugProps[i]) local id = coords.x .. coords.y .. coords.z - local model = "unknown" - + local model = 'unknown' + for i=1, #Config.Interactables, 1 do local seat = Config.Interactables[i] + if hash == GetHashKey(seat) then model = seat break end end - local txt = "ID: " .. id .. "\nHASH: " .. hash .. '\nMODEL: ' .. - DrawText3D(coords.x, coords.y, coords.z + 2.0, txt, 0, 255, 255) + local text = ('ID: %s~n~HASH: %s~n~MODEL: %s'):format(id, hash, model) + + ESX.Game.Utils.DrawText3D({ + x = coords.x, + y = coords.y, + z = coords.z + 2.0 + }, text) + end + + if #debugProps == 0 then + Citizen.Wait(500) end end + end) +end - local playerPed = GetPlayerPed(-1) +Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + local playerPed = PlayerPedId() if sitting and not IsPedUsingScenario(playerPed, currentScenario) then wakeup() end - if (GetLastInputMethod(2) and IsControlJustPressed(1, 38) and IsControlPressed(1, 21)) and not IsPedInAnyVehicle(playerPed, true) then - + if IsControlJustPressed(1, 38) and IsControlPressed(1, 21) and IsInputDisabled(0) and IsPedOnFoot(playerPed) then if sitting then wakeup() else - local object, distance = ESX.Game.GetClosestObject(Config.Interactables) - if Config.debug then + if Config.Debug then table.insert(debugProps, object) end if distance < 1.5 then - local hash = GetEntityModel(object) - local data = nil - local modelName = nil - local found = false for k,v in pairs(Config.Sitable) do if GetHashKey(k) == hash then - data = v - modelName = k - found = true + sit(object, k, v) break end end - - if found == true then - sit(object, modelName, data) - end - end - end - end - end end) function wakeup() - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() ClearPedTasks(playerPed) + sitting = false + SetEntityCoords(playerPed, lastPos) FreezeEntityPosition(playerPed, false) - FreezeEntityPosition(currentSitObj, false) - TriggerServerEvent('esx_interact:leavePlace', currentSitObj) - currentSitObj = nil - currentScenario = nil + + TriggerServerEvent('esx_sit:leavePlace', currentSitCoords) + currentSitCoords, currentScenario = nil, nil end function sit(object, modelName, data) - local pos = GetEntityCoords(object) - local id = pos.x .. pos.y .. pos.z - - ESX.TriggerServerCallback('esx_interact:getPlace', function(occupied) + local objectCoords = pos.x .. pos.y .. pos.z + ESX.TriggerServerCallback('esx_sit:getPlace', function(occupied) if occupied then - ESX.ShowNotification("Cette place est prise...") + ESX.ShowNotification('Cette place est prise...') else - local playerPed = GetPlayerPed(-1) - lastPos = GetEntityCoords(playerPed) - currentSitObj = id + local playerPed = PlayerPedId() + lastPos, currentSitCoords = GetEntityCoords(playerPed), objectCoords - TriggerServerEvent('esx_interact:takePlace', id) + TriggerServerEvent('esx_sit:takePlace', objectCoords) FreezeEntityPosition(object, true) currentScenario = data.scenario - TaskStartScenarioAtPosition(playerPed, currentScenario, pos.x, pos.y, pos.z - data.verticalOffset, GetEntityHeading(object)+180.0, 0, true, true) - + TaskStartScenarioAtPosition(playerPed, currentScenario, pos.x, pos.y, pos.z - data.verticalOffset, GetEntityHeading(object) + 180.0, 0, true, true) sitting = true - end - end) - end diff --git a/config.lua b/config.lua index 916c810d..221427b9 100644 --- a/config.lua +++ b/config.lua @@ -1,117 +1,116 @@ -Config = {} +Config = {} Config.MaxDistance = 1.5 - -Config.debug = false +Config.Debug = false Config.Interactables = { - "prop_bench_01a", - "prop_bench_01b", - "prop_bench_01c", - "prop_bench_02", - "prop_bench_03", - "prop_bench_04", - "prop_bench_05", - "prop_bench_06", - "prop_bench_05", - "prop_bench_08", - "prop_bench_09", - "prop_bench_10", - "prop_bench_11", - "prop_fib_3b_bench", - "prop_ld_bench01", - "prop_wait_bench_01", - "hei_prop_heist_off_chair", - "hei_prop_hei_skid_chair", - "prop_chair_01a", - "prop_chair_01b", - "prop_chair_02", - "prop_chair_03", - "prop_chair_04a", - "prop_chair_04b", - "prop_chair_05", - "prop_chair_06", - "prop_chair_05", - "prop_chair_08", - "prop_chair_09", - "prop_chair_10", - "prop_chateau_chair_01", - "prop_clown_chair", - "prop_cs_office_chair", - "prop_direct_chair_01", - "prop_direct_chair_02", - "prop_gc_chair02", - "prop_off_chair_01", - "prop_off_chair_03", - "prop_off_chair_04", - "prop_off_chair_04b", - "prop_off_chair_04_s", - "prop_off_chair_05", - "prop_old_deck_chair", - "prop_old_wood_chair", - "prop_rock_chair_01", - "prop_skid_chair_01", - "prop_skid_chair_02", - "prop_skid_chair_03", - "prop_sol_chair", - "prop_wheelchair_01", - "prop_wheelchair_01_s", - "p_armchair_01_s", - "p_clb_officechair_s", - "p_dinechair_01_s", - "p_ilev_p_easychair_s", - "p_soloffchair_s", - "p_yacht_chair_01_s", - "v_club_officechair", - "v_corp_bk_chair3", - "v_corp_cd_chair", - "v_corp_offchair", - "v_ilev_chair02_ped", - "v_ilev_hd_chair", - "v_ilev_p_easychair", - "v_ret_gc_chair03", - "prop_ld_farm_chair01", - "prop_table_04_chr", - "prop_table_05_chr", - "prop_table_06_chr", - "v_ilev_leath_chr", - "prop_table_01_chr_a", - "prop_table_01_chr_b", - "prop_table_02_chr", - "prop_table_03b_chr", - "prop_table_03_chr", - "prop_torture_ch_01", - "v_ilev_fh_dineeamesa", - "v_ilev_fh_kitchenstool", - "v_ilev_tort_stool", - "v_ilev_fh_kitchenstool", - "v_ilev_fh_kitchenstool", - "v_ilev_fh_kitchenstool", - "v_ilev_fh_kitchenstool", - "hei_prop_yah_seat_01", - "hei_prop_yah_seat_02", - "hei_prop_yah_seat_03", - "prop_waiting_seat_01", - "prop_yacht_seat_01", - "prop_yacht_seat_02", - "prop_yacht_seat_03", - "prop_hobo_seat_01", - "prop_rub_couch01", - "miss_rub_couch_01", - "prop_ld_farm_couch01", - "prop_ld_farm_couch02", - "prop_rub_couch02", - "prop_rub_couch03", - "prop_rub_couch04", - "p_lev_sofa_s", - "p_res_sofa_l_s", - "p_v_med_p_sofa_s", - "p_yacht_sofa_01_s", - "v_ilev_m_sofa", - "v_res_tre_sofa_s", - "v_tre_sofa_mess_a_s", - "v_tre_sofa_mess_b_s", - "v_tre_sofa_mess_c_s", - "prop_roller_car_01", - "prop_roller_car_02", -} \ No newline at end of file + 'prop_bench_01a', + 'prop_bench_01b', + 'prop_bench_01c', + 'prop_bench_02', + 'prop_bench_03', + 'prop_bench_04', + 'prop_bench_05', + 'prop_bench_06', + 'prop_bench_05', + 'prop_bench_08', + 'prop_bench_09', + 'prop_bench_10', + 'prop_bench_11', + 'prop_fib_3b_bench', + 'prop_ld_bench01', + 'prop_wait_bench_01', + 'hei_prop_heist_off_chair', + 'hei_prop_hei_skid_chair', + 'prop_chair_01a', + 'prop_chair_01b', + 'prop_chair_02', + 'prop_chair_03', + 'prop_chair_04a', + 'prop_chair_04b', + 'prop_chair_05', + 'prop_chair_06', + 'prop_chair_05', + 'prop_chair_08', + 'prop_chair_09', + 'prop_chair_10', + 'prop_chateau_chair_01', + 'prop_clown_chair', + 'prop_cs_office_chair', + 'prop_direct_chair_01', + 'prop_direct_chair_02', + 'prop_gc_chair02', + 'prop_off_chair_01', + 'prop_off_chair_03', + 'prop_off_chair_04', + 'prop_off_chair_04b', + 'prop_off_chair_04_s', + 'prop_off_chair_05', + 'prop_old_deck_chair', + 'prop_old_wood_chair', + 'prop_rock_chair_01', + 'prop_skid_chair_01', + 'prop_skid_chair_02', + 'prop_skid_chair_03', + 'prop_sol_chair', + 'prop_wheelchair_01', + 'prop_wheelchair_01_s', + 'p_armchair_01_s', + 'p_clb_officechair_s', + 'p_dinechair_01_s', + 'p_ilev_p_easychair_s', + 'p_soloffchair_s', + 'p_yacht_chair_01_s', + 'v_club_officechair', + 'v_corp_bk_chair3', + 'v_corp_cd_chair', + 'v_corp_offchair', + 'v_ilev_chair02_ped', + 'v_ilev_hd_chair', + 'v_ilev_p_easychair', + 'v_ret_gc_chair03', + 'prop_ld_farm_chair01', + 'prop_table_04_chr', + 'prop_table_05_chr', + 'prop_table_06_chr', + 'v_ilev_leath_chr', + 'prop_table_01_chr_a', + 'prop_table_01_chr_b', + 'prop_table_02_chr', + 'prop_table_03b_chr', + 'prop_table_03_chr', + 'prop_torture_ch_01', + 'v_ilev_fh_dineeamesa', + 'v_ilev_fh_kitchenstool', + 'v_ilev_tort_stool', + 'v_ilev_fh_kitchenstool', + 'v_ilev_fh_kitchenstool', + 'v_ilev_fh_kitchenstool', + 'v_ilev_fh_kitchenstool', + 'hei_prop_yah_seat_01', + 'hei_prop_yah_seat_02', + 'hei_prop_yah_seat_03', + 'prop_waiting_seat_01', + 'prop_yacht_seat_01', + 'prop_yacht_seat_02', + 'prop_yacht_seat_03', + 'prop_hobo_seat_01', + 'prop_rub_couch01', + 'miss_rub_couch_01', + 'prop_ld_farm_couch01', + 'prop_ld_farm_couch02', + 'prop_rub_couch02', + 'prop_rub_couch03', + 'prop_rub_couch04', + 'p_lev_sofa_s', + 'p_res_sofa_l_s', + 'p_v_med_p_sofa_s', + 'p_yacht_sofa_01_s', + 'v_ilev_m_sofa', + 'v_res_tre_sofa_s', + 'v_tre_sofa_mess_a_s', + 'v_tre_sofa_mess_b_s', + 'v_tre_sofa_mess_c_s', + 'prop_roller_car_01', + 'prop_roller_car_02', +} diff --git a/lists/seat.lua b/lists/seat.lua index 137fabc4..0592e9a5 100644 --- a/lists/seat.lua +++ b/lists/seat.lua @@ -1,5 +1,5 @@ Config.Sitable = { - --Only verticalOffset works right now! + --Only verticalOffset works right now! --all scenarios: pastebin.com/6mrYTdQv -- BENCH @@ -124,4 +124,4 @@ Config.Sitable = { -- MISC prop_roller_car_01 = { scenario = 'PROP_HUMAN_SEAT_BENCH', verticalOffset = -0.5, forwardOffset = 0.0, leftOffset = 0.0}, prop_roller_car_02 = { scenario = 'PROP_HUMAN_SEAT_BENCH', verticalOffset = -0.5, forwardOffset = 0.0, leftOffset = 0.0} -} \ No newline at end of file +} diff --git a/server.lua b/server.lua index f78ea11a..0d29c1d7 100644 --- a/server.lua +++ b/server.lua @@ -1,37 +1,18 @@ ESX = nil - -local SeatsTaken = {} +local seatsTaken = {} TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) --- SEATS -RegisterServerEvent('esx_interact:takePlace') -AddEventHandler('esx_interact:takePlace', function(object) - table.insert(SeatsTaken, object) +RegisterNetEvent('esx_sit:takePlace') +AddEventHandler('esx_sit:takePlace', function(objectCoords) + seatsTaken[objectCoords] = true end) -RegisterServerEvent('esx_interact:leavePlace') -AddEventHandler('esx_interact:leavePlace', function(object) - - local _SeatsTaken = {} - - for i=1, #SeatsTaken, 1 do - if object ~= SeatsTaken[i] then - table.insert(_SeatsTaken, SeatsTaken[i]) - end - end - - SeatsTaken = _SeatsTaken - +RegisterNetEvent('esx_sit:leavePlace') +AddEventHandler('esx_sit:leavePlace', function(objectCoords) + seatsTaken[objectCoords] = nil end) -ESX.RegisterServerCallback('esx_interact:getPlace', function(source, cb, id) - local found = false - - for i=1, #SeatsTaken, 1 do - if SeatsTaken[i] == id then - found = true - end - end - cb(found) -end) \ No newline at end of file +ESX.RegisterServerCallback('esx_sit:getPlace', function(source, cb, objectCoords) + cb(seatsTaken[objectCoords]) +end) From 653e60ae2ef03e233398e904da237a973e89ebde Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 4 Jan 2020 13:43:07 +0100 Subject: [PATCH 2353/3224] Manual pr #24, fixes sit not working Co-Authored-By: duckhunter392 --- client.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client.lua b/client.lua index 0f22bd9a..56264fcc 100644 --- a/client.lua +++ b/client.lua @@ -106,7 +106,7 @@ function sit(object, modelName, data) FreezeEntityPosition(object, true) currentScenario = data.scenario - + Citizen.Wait(1000) TaskStartScenarioAtPosition(playerPed, currentScenario, pos.x, pos.y, pos.z - data.verticalOffset, GetEntityHeading(object) + 180.0, 0, true, true) sitting = true end From 906ac324da157208f33fe27db340233279612e4b Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 4 Jan 2020 13:48:54 +0100 Subject: [PATCH 2354/3224] Minor changes --- client.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client.lua b/client.lua index 56264fcc..e918ea1a 100644 --- a/client.lua +++ b/client.lua @@ -28,13 +28,13 @@ if Config.Debug then end end - local text = ('ID: %s~n~HASH: %s~n~MODEL: %s'):format(id, hash, model) + local text = ('ID: %s~n~Hash: %s~n~Model: %s'):format(id, hash, model) ESX.Game.Utils.DrawText3D({ x = coords.x, y = coords.y, z = coords.z + 2.0 - }, text) + }, text, 0.5) end if #debugProps == 0 then @@ -53,7 +53,7 @@ Citizen.CreateThread(function() wakeup() end - if IsControlJustPressed(1, 38) and IsControlPressed(1, 21) and IsInputDisabled(0) and IsPedOnFoot(playerPed) then + if IsControlJustPressed(0, 38) and IsControlPressed(0, 21) and IsInputDisabled(0) and IsPedOnFoot(playerPed) then if sitting then wakeup() else From d2f52e2fce30142b26bbf98278dcbd3e9406428e Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 4 Jan 2020 13:50:08 +0100 Subject: [PATCH 2355/3224] Manual merge PR #10 #12 Co-Authored-By: Tracid --- config.lua | 1 + lists/seat.lua | 1 + 2 files changed, 2 insertions(+) diff --git a/config.lua b/config.lua index 221427b9..4f4957be 100644 --- a/config.lua +++ b/config.lua @@ -34,6 +34,7 @@ Config.Interactables = { 'prop_chair_08', 'prop_chair_09', 'prop_chair_10', + 'v_club_stagechair', 'prop_chateau_chair_01', 'prop_clown_chair', 'prop_cs_office_chair', diff --git a/lists/seat.lua b/lists/seat.lua index 0592e9a5..c5cb8c6c 100644 --- a/lists/seat.lua +++ b/lists/seat.lua @@ -21,6 +21,7 @@ Config.Sitable = { prop_wait_bench_01 = { scenario = 'PROP_HUMAN_SEAT_BENCH', verticalOffset = -0.5, forwardOffset = 0.0, leftOffset = 0.0}, -- CHAIR + v_club_stagechair = { scenario = 'PROP_HUMAN_SEAT_BENCH', verticalOffset = -0.5, forwardOffset = 0.0, leftOffset = 0.0}, hei_prop_heist_off_chair = { scenario = 'PROP_HUMAN_SEAT_BENCH', verticalOffset = -0.5, forwardOffset = 0.0, leftOffset = 0.0}, hei_prop_hei_skid_chair = { scenario = 'PROP_HUMAN_SEAT_BENCH', verticalOffset = -0.5, forwardOffset = 0.0, leftOffset = 0.0}, prop_chair_01a = { scenario = 'PROP_HUMAN_SEAT_BENCH', verticalOffset = -0.5, forwardOffset = 0.0, leftOffset = 0.0}, From bc56c7607b09204175aba644269c44425b992c1c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 4 Jan 2020 13:51:17 +0100 Subject: [PATCH 2356/3224] Fixed possible error --- server.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server.lua b/server.lua index 0d29c1d7..6ae31e82 100644 --- a/server.lua +++ b/server.lua @@ -10,7 +10,9 @@ end) RegisterNetEvent('esx_sit:leavePlace') AddEventHandler('esx_sit:leavePlace', function(objectCoords) - seatsTaken[objectCoords] = nil + if seatsTaken[objectCoords] then + seatsTaken[objectCoords] = nil + end end) ESX.RegisterServerCallback('esx_sit:getPlace', function(source, cb, objectCoords) From 23ced867d165ef00830627fb021971aad51b826b Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 4 Jan 2020 13:56:13 +0100 Subject: [PATCH 2357/3224] Update README.md --- README.md | 58 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 90125428..1ec6a9da 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,49 @@ -# fxserver-esx_sit +# esx_sit -### Warning: This resource is not actively maintained. The ESX Teams has higher priorties than this particular add-on, if you have a suggestion open a PR. The likelihood of the ESX Team making feature based updates to esx_sit are unlikely. Thanks for understanding! +This script allow you to sit in almost every object where you should be able to, the default keybind is SHIFT + E to toggle sitting. -This script allow you to sit almost everywhere. -If the player has many props around him, the game camera might become crazy. +## Download & Installation -SHIFT + E to sit, gamepad protected so player can't interact with gamepads. +### Using [fvm](https://github.com/qlaffont/fvm-installer) -[INSTALLATION] - -1) CD in your resources/[esx] folder -2) Clone the repository ``` -git clone https://github.com/FXServer-ESX/fxserver-esx_sit esx_sit +fvm install --save --folder=esx esx-org/esx_sit ``` -3) Add this in your server.cfg : -``` -start esx_sit -``` -[CREDITS] -- Original code by CmJustice https://github.com/CmJustice +### Using Git + +``` +cd resources +git clone https://github.com/ESX-Org/esx_sit [esx]/esx_sit +``` + +### Manually + +- Download https://github.com/ESX-Org/esx_sit/releases/latest +- Put it in the `resource/[esx]` directory + +### Installation + +- Add this to your server.cfg: + +``` +start esx_policejob +``` + +## Credits + +- [CmJustice](https://github.com/CmJustice) - Original author + +## Legal + +### License + +esx_sit + +Copyright (C) 2015-2020 Jérémie N'gadi + +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 http://www.gnu.org/licenses/. \ No newline at end of file From f51d8cb281aa158b3bc544efc036b62d453c38c3 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sat, 4 Jan 2020 15:16:16 +0100 Subject: [PATCH 2358/3224] Updated SQL to weight --- esx_basicneeds.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esx_basicneeds.sql b/esx_basicneeds.sql index 02d24aa6..d7c94296 100644 --- a/esx_basicneeds.sql +++ b/esx_basicneeds.sql @@ -1,6 +1,6 @@ USE `essentialmode`; -INSERT INTO `items` (`name`, `label`, `limit`) VALUES +INSERT INTO `items` (`name`, `label`, `weight`) VALUES ('bread', 'Pain', 10), ('water', 'Eau', 5) -; \ No newline at end of file +; From aa3c9213105fd6adcd0a869add8a6e663f2f294f Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sat, 4 Jan 2020 18:49:39 +0100 Subject: [PATCH 2359/3224] Minor cleanup (#28) * Minor cleanup * I forgot these * NEW ESX Support --- client/main.lua | 18 ++---------------- server/main.lua | 8 ++++---- 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/client/main.lua b/client/main.lua index b557b415..395ee2f2 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,19 +1,5 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - -- internal variables -local hasAlreadyEnteredMarker = false -local isInATMMarker = false -local menuIsShowed = false +local hasAlreadyEnteredMarker, isInATMMarker, menuIsShowed = false, false, false ESX = nil Citizen.CreateThread(function() @@ -110,7 +96,7 @@ Citizen.CreateThread(function() ESX.ShowHelpNotification(_U('press_e_atm')) - if IsControlJustReleased(0, Keys['E']) and IsPedOnFoot(PlayerPedId()) then + if IsControlJustReleased(0, 38) and IsPedOnFoot(PlayerPedId()) then menuIsShowed = true ESX.TriggerServerCallback('esx:getPlayerData', function(data) SendNUIMessage({ diff --git a/server/main.lua b/server/main.lua index 1fa90643..c1700a8f 100644 --- a/server/main.lua +++ b/server/main.lua @@ -11,11 +11,11 @@ AddEventHandler('esx_atm:deposit', function(amount) amount = ESX.Math.Round(amount) if amount == nil or amount <= 0 or amount > xPlayer.getMoney() then - TriggerClientEvent('esx:showNotification', _source, _U('invalid_amount')) + xPlayer.showNotification(_U('invalid_amount')) else xPlayer.removeMoney(amount) xPlayer.addAccountMoney('bank', amount) - TriggerClientEvent('esx:showNotification', _source, _U('deposit_money', amount)) + xPlayer.showNotification(_U('deposit_money', amount)) end end) @@ -30,10 +30,10 @@ AddEventHandler('esx_atm:withdraw', function(amount) amount = ESX.Math.Round(amount) if amount == nil or amount <= 0 or amount > accountMoney then - TriggerClientEvent('esx:showNotification', _source, _U('invalid_amount')) + xPlayer.showNotification(_U('invalid_amount')) else xPlayer.removeAccountMoney('bank', amount) xPlayer.addMoney(amount) - TriggerClientEvent('esx:showNotification', _source, _U('withdraw_money', amount)) + xPlayer.showNotification(_U('withdraw_money', amount)) end end) From 9e349217a48137dd545e3856e4621a6ab0772b23 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 4 Jan 2020 19:08:06 +0100 Subject: [PATCH 2360/3224] Fixed scenario not having time to start --- client.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client.lua b/client.lua index e918ea1a..4bd224bb 100644 --- a/client.lua +++ b/client.lua @@ -106,8 +106,8 @@ function sit(object, modelName, data) FreezeEntityPosition(object, true) currentScenario = data.scenario - Citizen.Wait(1000) TaskStartScenarioAtPosition(playerPed, currentScenario, pos.x, pos.y, pos.z - data.verticalOffset, GetEntityHeading(object) + 180.0, 0, true, true) + Citizen.Wait(1000) sitting = true end end) From 86ea93816adb4dbf0d888bf14c47b112274998f9 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sat, 4 Jan 2020 19:10:00 +0100 Subject: [PATCH 2361/3224] Removed keys table --- client/main.lua | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/client/main.lua b/client/main.lua index 39e5cc83..73d7c8e9 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,15 +1,3 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - local Player = nil local CruisedSpeed = 0 local CruisedSpeedKm = 0 @@ -27,7 +15,7 @@ end) Citizen.CreateThread(function () while true do Wait(0) - if IsControlJustPressed(1, Keys['Y']) and IsDriver() then + if IsControlJustPressed(1, 246) and IsDriver() then Player = GetPlayerPed(-1) TriggerCruiseControl() end @@ -57,7 +45,7 @@ function TriggerCruiseControl () SetVehicleForwardSpeed(GetVehicle(), CruisedSpeed) end - if IsControlJustPressed(1, Keys['Y']) then + if IsControlJustPressed(1, 246) then CruisedSpeed = GetVehiculeSpeed() CruisedSpeedKm = TransformToKm(CruisedSpeed) end From 6f91b8ac743b897f5c6d66d26d495e91216b0582 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sat, 4 Jan 2020 19:28:38 +0100 Subject: [PATCH 2362/3224] minor cleanup --- client/main.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/client/main.lua b/client/main.lua index 73d7c8e9..ecad619b 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,7 +1,5 @@ local Player = nil -local CruisedSpeed = 0 -local CruisedSpeedKm = 0 -local VehicleVectorY = 0 +local CruisedSpeed, CruisedSpeedKm, VehicleVectorY = 0, 0, 0 ESX = nil From b796a76ec31dd22c503da62c2adea1241c5ce3aa Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sat, 4 Jan 2020 19:49:37 +0100 Subject: [PATCH 2363/3224] Removed keys table --- client/main.lua | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/client/main.lua b/client/main.lua index 8f62976b..2b16b421 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,15 +1,3 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - ESX = nil local CurrentAction = nil local CurrentActionMsg = nil @@ -292,7 +280,7 @@ Citizen.CreateThread(function() if CurrentAction then ESX.ShowHelpNotification(CurrentActionMsg) - if IsControlJustReleased(0, Keys['E']) then + if IsControlJustReleased(0, 38) then if CurrentAction == 'dmvschool_menu' then OpenDMVSchoolMenu() end @@ -412,4 +400,4 @@ Citizen.CreateThread(function() Citizen.Wait(500) end end -end) \ No newline at end of file +end) From e83801cf42aebbdf1c00bcc8ef4ce7fc0e8333c6 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 4 Jan 2020 23:54:39 +0100 Subject: [PATCH 2364/3224] Death module: fixed killer sometimes not getting found, changed native. Fixes #417 --- client/modules/death.lua | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/client/modules/death.lua b/client/modules/death.lua index 650f1e6a..a2aeb76b 100644 --- a/client/modules/death.lua +++ b/client/modules/death.lua @@ -3,7 +3,6 @@ Citizen.CreateThread(function() while true do Citizen.Wait(0) - local player = PlayerId() if NetworkIsPlayerActive(player) then @@ -12,13 +11,13 @@ Citizen.CreateThread(function() if IsPedFatallyInjured(playerPed) and not isDead then isDead = true - local killer, killerWeapon = NetworkGetEntityKillerOfPlayer(player) - local killerServerId = NetworkGetPlayerIndexFromPed(killer) - - if killer ~= playerPed and killerServerId ~= nil and NetworkIsPlayerActive(killerServerId) then - PlayerKilledByPlayer(GetPlayerServerId(killerServerId), killerServerId, killerWeapon) + local killerEntity, deathCause = GetPedSourceOfDeath(playerPed), GetPedCauseOfDeath(playerPed) + local killerClientId = NetworkGetPlayerIndexFromPed(killerEntity) + + if killerEntity ~= playerPed and killerClientId and NetworkIsPlayerActive(killerClientId) then + PlayerKilledByPlayer(GetPlayerServerId(killerClientId), killerClientId, deathCause) else - PlayerKilled() + PlayerKilled(deathCause) end elseif not IsPedFatallyInjured(playerPed) then @@ -28,18 +27,18 @@ Citizen.CreateThread(function() end end) -function PlayerKilledByPlayer(killerServerId, killerClientId, killerWeapon) +function PlayerKilledByPlayer(killerServerId, killerClientId, deathCause) local victimCoords = GetEntityCoords(PlayerPedId()) local killerCoords = GetEntityCoords(GetPlayerPed(killerClientId)) - local distance = GetDistanceBetweenCoords(victimCoords, killerCoords, true) + local distance = #(victimCoords - killerCoords) local data = { - victimCoords = { x = ESX.Math.Round(victimCoords.x, 1), y = ESX.Math.Round(victimCoords.y, 1), z = ESX.Math.Round(victimCoords.z, 1) }, - killerCoords = { x = ESX.Math.Round(killerCoords.x, 1), y = ESX.Math.Round(killerCoords.y, 1), z = ESX.Math.Round(killerCoords.z, 1) }, + victimCoords = {x = ESX.Math.Round(victimCoords.x, 1), y = ESX.Math.Round(victimCoords.y, 1), z = ESX.Math.Round(victimCoords.z, 1)}, + killerCoords = {x = ESX.Math.Round(killerCoords.x, 1), y = ESX.Math.Round(killerCoords.y, 1), z = ESX.Math.Round(killerCoords.z, 1)}, killedByPlayer = true, - deathCause = killerWeapon, - distance = ESX.Math.Round(distance, 1), + deathCause = deathCause, + distance = ESX.Math.Round(distance, 1), killerServerId = killerServerId, killerClientId = killerClientId @@ -49,15 +48,15 @@ function PlayerKilledByPlayer(killerServerId, killerClientId, killerWeapon) TriggerServerEvent('esx:onPlayerDeath', data) end -function PlayerKilled() +function PlayerKilled(deathCause) local playerPed = PlayerPedId() - local victimCoords = GetEntityCoords(PlayerPedId()) + local victimCoords = GetEntityCoords(playerPed) local data = { - victimCoords = { x = ESX.Math.Round(victimCoords.x, 1), y = ESX.Math.Round(victimCoords.y, 1), z = ESX.Math.Round(victimCoords.z, 1) }, + victimCoords = {x = ESX.Math.Round(victimCoords.x, 1), y = ESX.Math.Round(victimCoords.y, 1), z = ESX.Math.Round(victimCoords.z, 1)}, killedByPlayer = false, - deathCause = GetPedCauseOfDeath(playerPed) + deathCause = deathCause } TriggerEvent('esx:onPlayerDeath', data) From feaf8424205bfd9b14de786e15e9fb411f738fc7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 5 Jan 2020 15:49:00 +0100 Subject: [PATCH 2365/3224] Show player name and not steam name, fixes #354 --- client/functions.lua | 127 +++++++++++++++++++------------------------ server/main.lua | 44 +++++++++++---- 2 files changed, 89 insertions(+), 82 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 5a56dd4d..c42f6621 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -990,7 +990,7 @@ ESX.Game.Utils.DrawText3D = function(coords, text, size, font) if not size then size = 1 end if not font then font = 0 end - + local scale = (size / distance) * 2 local fov = (1 / GetGameplayCamFov()) * 100 scale = scale * fov @@ -1113,87 +1113,72 @@ ESX.ShowInventory = function() align = 'bottom-right', elements = elements, }, function(data1, menu1) - local item = data1.current.value - local type = data1.current.type + local item, type = data1.current.value, data1.current.type if data1.current.action == 'give' then - local playersInArea = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) - local foundPlayers, elements = false, {} + local playersNearby = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) - for k,v in ipairs(playersInArea) do - if v ~= PlayerId() then - foundPlayers = true + if #playersNearby > 0 then + local players, elements = {}, {} - table.insert(elements, { - label = GetPlayerName(v), - player = v - }) + for k,player in ipairs(playersNearby) do + players[GetPlayerServerId(player)] = true end - end - if foundPlayers then - foundPlayers = false - - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'give_item_to', { - title = _U('give_to'), - align = 'bottom-right', - elements = elements - }, function(data2, menu2) - local playersInArea, nearbyPlayer = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) - - for k,v in ipairs(playersInArea) do - if v ~= PlayerId() then - - if v == data2.current.player then - foundPlayers = true - nearbyPlayer = v - break - end - end + ESX.TriggerServerCallback('esx:getPlayerNames', function(returnedPlayers) + for playerId,playerName in pairs(returnedPlayers) do + table.insert(elements, { + label = playerName, + playerId = playerId + }) end - - if foundPlayers then - if type == 'item_weapon' then - local closestPed = GetPlayerPed(nearbyPlayer) - local sourceAmmo = GetAmmoInPedWeapon(playerPed, GetHashKey(item)) - - if IsPedOnFoot(closestPed) then - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(nearbyPlayer), type, item, sourceAmmo) - menu2.close() - menu1.close() + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'give_item_to', { + title = _U('give_to'), + align = 'bottom-right', + elements = elements + }, function(data2, menu2) + local selectedPlayer, selectedPlayerId = GetPlayerFromServerId(data2.current.playerId), data2.current.playerId + playersNearby = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) + playersNearby = ESX.Table.Set(playersNearby) + + if playersNearby[selectedPlayer] then + local selectedPlayerPed = GetPlayerPed(selectedPlayer) + + if IsPedOnFoot(selectedPlayerPed) then + if type == 'item_weapon' then + TriggerServerEvent('esx:giveInventoryItem', selectedPlayerId, type, item, nil) + menu2.close() + menu1.close() + else + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', { + title = _U('amount') + }, function(data3, menu3) + local quantity = tonumber(data3.value) + + if quantity then + TriggerServerEvent('esx:giveInventoryItem', selectedPlayerId, type, item, quantity) + menu3.close() + menu2.close() + menu1.close() + else + ESX.ShowNotification(_U('amount_invalid')) + end + end, function(data3, menu3) + menu3.close() + end) + end else ESX.ShowNotification(_U('in_vehicle')) end else - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', { - title = _U('amount') - }, function(data3, menu3) - local quantity = tonumber(data3.value) - local closestPed = GetPlayerPed(nearbyPlayer) - - if IsPedOnFoot(closestPed) then - if quantity then - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(nearbyPlayer), type, item, quantity) - menu3.close() - menu2.close() - menu1.close() - else - ESX.ShowNotification(_U('amount_invalid')) - end - else - ESX.ShowNotification(_U('in_vehicle')) - end - end, function(data3, menu3) - menu3.close() - end) + ESX.ShowNotification(_U('players_nearby')) + menu2.close() end - else - ESX.ShowNotification(_U('players_nearby')) + end, function(data2, menu2) menu2.close() - end - end, function(data2, menu2) - menu2.close() - end) -- give end + end) + end, players) else ESX.ShowNotification(_U('players_nearby')) end @@ -1212,7 +1197,7 @@ ESX.ShowInventory = function() title = _U('amount') }, function(data2, menu2) local quantity = tonumber(data2.value) - + if quantity then menu2.close() menu1.close() @@ -1244,7 +1229,7 @@ ESX.ShowInventory = function() title = _U('amountammo') }, function(data2, menu2) local quantity = tonumber(data2.value) - + if quantity then if pedAmmo >= quantity and quantity > 0 then TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), 'item_ammo', item, quantity) diff --git a/server/main.lua b/server/main.lua index 853bff44..fc384765 100644 --- a/server/main.lua +++ b/server/main.lua @@ -301,21 +301,27 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo sourceXPlayer.showNotification(_U('imp_invalid_amount')) end elseif type == 'item_weapon' then - if not targetXPlayer.hasWeapon(itemName) then - sourceXPlayer.removeWeapon(itemName) - targetXPlayer.addWeapon(itemName, itemCount) + if sourceXPlayer.hasWeapon(itemName) then local weaponLabel = ESX.GetWeaponLabel(itemName) - if itemCount > 0 then - sourceXPlayer.showNotification(_U('gave_weapon_withammo', weaponLabel, itemCount, targetXPlayer.name)) - targetXPlayer.showNotification(_U('received_weapon_withammo', weaponLabel, itemCount, sourceXPlayer.name)) + if not targetXPlayer.hasWeapon(itemName) then + local _,weapon = xPlayer.getWeapon(itemName) + itemCount = weapon.ammo + + sourceXPlayer.removeWeapon(itemName) + targetXPlayer.addWeapon(itemName, itemCount) + + if itemCount > 0 then + sourceXPlayer.showNotification(_U('gave_weapon_withammo', weaponLabel, itemCount, targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_weapon_withammo', weaponLabel, itemCount, sourceXPlayer.name)) + else + sourceXPlayer.showNotification(_U('gave_weapon', weaponLabel, targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_weapon', weaponLabel, sourceXPlayer.name)) + end else - sourceXPlayer.showNotification(_U('gave_weapon', weaponLabel, targetXPlayer.name)) - targetXPlayer.showNotification(_U('received_weapon', weaponLabel, sourceXPlayer.name)) + sourceXPlayer.showNotification(_U('gave_weapon_hasalready', targetXPlayer.name, weaponLabel)) + targetXPlayer.showNotification(_U('received_weapon_hasalready', sourceXPlayer.name, weaponLabel)) end - else - sourceXPlayer.showNotification(_U('gave_weapon_hasalready', targetXPlayer.name, weaponLabel)) - targetXPlayer.showNotification(_U('received_weapon_hasalready', sourceXPlayer.name, weaponLabel)) end elseif type == 'item_ammo' then if sourceXPlayer.hasWeapon(itemName) then @@ -482,6 +488,22 @@ ESX.RegisterServerCallback('esx:getOtherPlayerData', function(source, cb, target }) end) +ESX.RegisterServerCallback('esx:getPlayerNames', function(source, cb, players) + players[source] = nil + + for playerId,v in pairs(players) do + local xPlayer = ESX.GetPlayerFromId(playerId) + + if xPlayer then + players[playerId] = xPlayer.getName() + else + players[playerId] = nil + end + end + + cb(players) +end) + TriggerEvent("es:addGroup", "jobmaster", "user", function(group) end) ESX.StartDBSync() From dce7fd3945c2983f1db2b57326f4078a0b458761 Mon Sep 17 00:00:00 2001 From: CreativeOutcast - BenZoN <3528000+benzon@users.noreply.github.com> Date: Sun, 5 Jan 2020 15:57:54 +0100 Subject: [PATCH 2366/3224] Added missing SetPedHeadOverlay (#32) Added facial blemishes to ApplySkin --- client/main.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/client/main.lua b/client/main.lua index d76f4861..b9e741dc 100644 --- a/client/main.lua +++ b/client/main.lua @@ -258,6 +258,7 @@ function ApplySkin(skin, clothes) SetPedHairColor (playerPed, Character['hair_color_1'], Character['hair_color_2']) -- Hair Color SetPedHeadOverlay (playerPed, 3, Character['age_1'], (Character['age_2'] / 10) + 0.0) -- Age + opacity + SetPedHeadOverlay (playerPed, 0, Character['blemishes_1'], (Character['blemishes_2'] / 10) + 0.0) -- Blemishes + opacity SetPedHeadOverlay (playerPed, 1, Character['beard_1'], (Character['beard_2'] / 10) + 0.0) -- Beard + opacity SetPedEyeColor (playerPed, Character['eye_color'], 0, 1) -- Eyes color SetPedHeadOverlay (playerPed, 2, Character['eyebrows_1'], (Character['eyebrows_2'] / 10) + 0.0) -- Eyebrows + opacity From faacd1f5b95f9809fbc3c02a0111c6901cf9bab3 Mon Sep 17 00:00:00 2001 From: BackrndSource Date: Sun, 5 Jan 2020 15:58:37 +0100 Subject: [PATCH 2367/3224] Add Spanish Translation (#31) * Spanish Traduction (locales/es.lua) * Update to add locale/es.lua --- __resource.lua | 1 + locales/es.lua | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 locales/es.lua diff --git a/__resource.lua b/__resource.lua index c11c3fec..52714ec0 100644 --- a/__resource.lua +++ b/__resource.lua @@ -9,6 +9,7 @@ client_scripts { 'locales/br.lua', 'locales/de.lua', 'locales/en.lua', + 'locales/es.lua', 'locales/fi.lua', 'locales/fr.lua', 'locales/pl.lua', diff --git a/locales/es.lua b/locales/es.lua new file mode 100644 index 00000000..8d3cba00 --- /dev/null +++ b/locales/es.lua @@ -0,0 +1,76 @@ +Locales['es'] = { + ['sex'] = 'sexo', + ['face'] = 'cara', + ['skin'] = 'piel', + ['wrinkles'] = 'arrugas', + ['wrinkle_thickness'] = 'grosor arrugas', + ['beard_type'] = 'tipo de barba', +  ['beard_size'] = 'tamaño barba', +  ['beard_color_1'] = 'color de barba 1', +  ['beard_color_2'] = 'color de barba 2', +  ['hair_1'] = 'cabello 1', +  ['hair_2'] = 'cabello 2', +  ['hair_color_1'] = 'color de cabello 1', +  ['hair_color_2'] = 'color de cabello 2', +  ['eye_color'] = 'color de ojos', +  ['eyebrow_type'] = 'tipo de ceja', +  ['eyebrow_size'] = 'tamaño ceja', +  ['eyebrow_color_1'] = 'color de ceja 1', +  ['eyebrow_color_2'] = 'color de ceja 2', +  ['makeup_type'] = 'tipo de maquillaje', +  ['makeup_thickness'] = 'espesor maquillaje', +  ['makeup_color_1'] = 'color maquillaje 1', +  ['makeup_color_2'] = 'color maquillaje 2', +  ['lipstick_type'] = 'tipo de barra de labios', +  ['lipstick_thickness'] = 'grosor barra de labios', +  ['lipstick_color_1'] = 'color barra de labios 1', +  ['lipstick_color_2'] = 'color barra de labios 2', +  ['ear_accessories'] = 'accesorios oreja', +  ['ear_accessories_color'] = 'color accesorios oreja', +  ['tshirt_1'] = 'camiseta 1', +  ['tshirt_2'] = 'camiseta 2', +  ['torso_1'] = 'torso 1', +  ['torso_2'] = 'torso 2', +  ['decals_1'] = 'tatuajes 1', +  ['decals_2'] = 'tatuajes 2', + ['arms'] = 'brazos', + ['arms_2'] = 'brazos 2', +  ['pants_1'] = 'pantalones 1', +  ['pants_2'] = 'pantalones 2', +  ['shoes_1'] = 'zapatos 1', +  ['shoes_2'] = 'zapatos 2', +  ['mask_1'] = 'máscara 1', +  ['mask_2'] = 'máscara 2', +  ['bproof_1'] = 'chaleco antibalas 1', +  ['bproof_2'] = 'chaleco antibalas 2', +  ['chain_1'] = 'cadena 1', +  ['chain_2'] = 'cadena 2', +  ['helmet_1'] = 'casco 1', +  ['helmet_2'] = 'casco 2', +  ['watches_1'] = 'relojes 1', +  ['watches_2'] = 'relojes 2', +  ['bracelets_1'] = 'pulseras 1', +  ['bracelets_2'] = 'pulseras 2', +  ['glasses_1'] = 'gafas 1', +  ['glasses_2'] = 'gafas 2', + ['bag'] = 'bolsa', + ['bag_color'] = 'color de la bolsa', + ['blemishes'] = 'manchas', + ['blemishes_size']= 'opacidad de las manchas', + ['ageing'] = 'envejecimiento', + ['ageing_1'] = 'nivel de envejecimiento', + ['blush'] = 'rubor', + ['blush_1'] = 'opacidad del rubor', + ['blush_color'] = 'color del rubor', + ['complexion'] = 'complexión', + ['complexion_1'] = 'nivel de complexión', + ['sun'] = 'bronceado', + ['sun_1'] = 'nivel de bronceado', + ['freckles'] = 'pecas', + ['freckles_1'] = 'opacidad de las pecas', + ['chest_hair'] = 'pecholobo', + ['chest_hair_1'] = 'espesor del pecholobo', + ['chest_color'] = 'color del pecholobo', + ['bodyb'] = 'manchas corporales', + ['bodyb_size'] = 'opacidad manchas corporales' +} From 01a6cc466fd1ad815350f4ed27900186a1bfecc5 Mon Sep 17 00:00:00 2001 From: maiconkkl Date: Sun, 5 Jan 2020 15:51:05 -0300 Subject: [PATCH 2368/3224] Improved Portuguese locale (#174) * Correcting and improving translation * Update br.lua * Update br.lua * Update br.lua --- locales/br.lua | 146 ++++++++++++++++++++++++------------------------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index 6d9551c2..3a96cd65 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,93 +1,93 @@ Locales['br'] = { -- Cloakroom - ['cloakroom'] = 'Vestiário', - ['ems_clothes_civil'] = 'Roupa Normal', - ['ems_clothes_ems'] = 'Entrar como Socorrista', + ['cloakroom'] = 'guarda roupa', + ['ems_clothes_civil'] = 'roupa normal', + ['ems_clothes_ems'] = 'entrar como socorrista', -- Vehicles - ['ambulance'] = 'ambulance', - ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', - ['helicopter_buy'] = 'helicopter shop', - ['helicopter_garage'] = 'open garage', - ['helicopter_store'] = 'store helicopter in garage', - ['helicopter_garage_title'] = 'helicopter Garage', - ['helicopter_title'] = 'helicopter Actions', - ['helicopter_notauthorized'] = 'you\'re not authorized to buy helicopters.', - ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.', - ['garage_title'] = 'vehicle Actions', - ['garage_stored'] = 'stored', - ['garage_notstored'] = 'not in garage', - ['garage_storing'] = 'we\'re attempting to remove the vehicle, make sure no players are around it.', - ['garage_has_stored'] = 'the vehicle has been stored in your garage', - ['garage_has_notstored'] = 'no nearby owned vehicles were found', - ['garage_notavailable'] = 'your vehicle is not stored in the garage.', - ['garage_blocked'] = 'there\'s no available spawn points!', - ['garage_empty'] = 'you dont have any vehicles in your garage.', - ['garage_released'] = 'your vehicle has been released from the garage.', - ['garage_store_nearby'] = 'there is no nearby vehicles.', - ['garage_storeditem'] = 'open garage', - ['garage_storeitem'] = 'store vehicle in garage', - ['garage_buyitem'] = 'vehicle shop', + ['ambulance'] = 'ambulancia', + ['helicopter_prompt'] = 'pressione ~INPUT_CONTEXT~ para acessar a ~y~Helicopter Actions~s~.', + ['helicopter_buy'] = 'loja de helicóptero', + ['helicopter_garage'] = 'garagem aberta', + ['helicopter_store'] = 'helicóptero da loja entregue na garagem', + ['helicopter_garage_title'] = 'garagem de helicóptero', + ['helicopter_title'] = 'ações do helicóptero', + ['helicopter_notauthorized'] = 'você não está autorizado a comprar helicópteros.', + ['garage_prompt'] = 'pressione ~INPUT_CONTEXT~ para entra no ~y~Vehicle Actions~s~.', + ['garage_title'] = 'ações do veiculo', + ['garage_stored'] = 'guardado', + ['garage_notstored'] = 'não foi guardado', + ['garage_storing'] = 'estamos tentando guardar o veículo, verifique se não há cidadões ao seu redor.', + ['garage_has_stored'] = 'o veículo foi guardado na sua garagem', + ['garage_has_notstored'] = 'nem um dos seus veiculos foi encontrado proximo', + ['garage_notavailable'] = 'o seu veículo não está guardado na garagem.', + ['garage_blocked'] = 'não há pontos de spawn disponíveis!', + ['garage_empty'] = 'você não tem veículos na sua garagem.', + ['garage_released'] = 'seu veículo foi liberado da garagem.', + ['garage_store_nearby'] = 'não há veículos próximos.', + ['garage_storeditem'] = 'abrir garagem', + ['garage_storeitem'] = 'veículo da loja na garagem', + ['garage_buyitem'] = 'loja de veículos', ['shop_item'] = '$%s', - ['vehicleshop_title'] = 'vehicle Shop', - ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', - ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~', - ['vehicleshop_money'] = 'you cannot afford that vehicle', - ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', - ['confirm_no'] = 'no', - ['confirm_yes'] = 'yes', + ['vehicleshop_title'] = 'loja de veículos', + ['vehicleshop_confirm'] = 'você quer comprar este veículo?', + ['vehicleshop_bought'] = 'você comprou ~y~%s~s~ para ~r~$%s~s~', + ['vehicleshop_money'] = 'você não pode pagar esse veículo', + ['vehicleshop_awaiting_model'] = 'o veículo está atualmente ~g~DOWNLOADING & LOADING~s~, por favor aguarde', + ['confirm_no'] = 'não', + ['confirm_yes'] = 'sim', -- Action Menu - ['revive_inprogress'] = 'Reanimação em andamento', + ['revive_inprogress'] = 'reanimação em andamento', ['revive_complete'] = 'você ressuscitou ~y~%s~s~', ['revive_complete_award'] = 'você ressuscitou ~y~%s~s~, ~g~$%s~s~', - ['revive_fail_offline'] = 'that player is no longer online', - ['heal_inprogress'] = 'you are healing!', - ['heal_complete'] = 'you have healed ~y~%s~s~', - ['no_players'] = 'Nenhum jogador nas proximidades', - ['no_vehicles'] = 'Sem veículos nas proximidades', - ['player_not_unconscious'] = 'Não está inconsciente', - ['player_not_conscious'] = 'that player is not conscious!', + ['revive_fail_offline'] = 'esse cidadão não está mais na cidade', + ['heal_inprogress'] = 'você está curando!', + ['heal_complete'] = 'você curou ~y~%s~s~', + ['no_players'] = 'nenhum cidadão nas proximidades', + ['no_vehicles'] = 'sem veículos nas proximidades', + ['player_not_unconscious'] = 'não está inconsciente', + ['player_not_conscious'] = 'esse cidadão não está consciente!', -- Boss Menu - ['boss_actions'] = 'Menu Administração', + ['boss_actions'] = 'menu administração', -- Misc ['invalid_amount'] = '~r~Quantidade inválida', - ['actions_prompt'] = 'press ~INPUT_CONTEXT~ access the ~y~Ambulance Actions~s~.', - ['deposit_amount'] = 'Quantidade inválida para deposito', - ['money_withdraw'] = 'Quantidade a ser retirada', - ['fast_travel'] = 'Aperte ~INPUT_CONTEXT~ para mover-se rapidamente.', - ['open_pharmacy'] = 'Aperte ~INPUT_CONTEXT~ para abrir a farmácia.', - ['pharmacy_menu_title'] = 'Farmácia', + ['actions_prompt'] = 'aperte ~INPUT_CONTEXT~ para entra ~y~Ambulance Actions~s~.', + ['deposit_amount'] = 'quantidade inválida para deposito', + ['money_withdraw'] = 'quantidade a ser retirada', + ['fast_travel'] = 'aperte ~INPUT_CONTEXT~ para mover-se rapidamente.', + ['open_pharmacy'] = 'aperte ~INPUT_CONTEXT~ para abrir a farmácia.', + ['pharmacy_menu_title'] = 'farmácia', ['pharmacy_take'] = 'tomar %s', - ['medikit'] = 'Seringa', - ['bandage'] = 'Vendagem', - ['max_item'] = 'você já carrega o suficiente sobre você.', + ['medikit'] = 'seringa', + ['bandage'] = 'vendagem', + ['max_item'] = 'você não pode carregar mais', -- F6 Menu - ['ems_menu'] = 'Interação com cidadão', - ['ems_menu_title'] = 'Ambulância - Interação com cidadão', - ['ems_menu_revive'] = 'Reanimar', - ['ems_menu_putincar'] = 'Colocar no veiculo', - ['ems_menu_small'] = 'Curar pequenas feridas', - ['ems_menu_big'] = 'Tratando lesões graves', + ['ems_menu'] = 'interação com cidadão', + ['ems_menu_title'] = 'ambulância - Interação com cidadão', + ['ems_menu_revive'] = 'reanimar', + ['ems_menu_putincar'] = 'colocar no veiculo', + ['ems_menu_small'] = 'curar pequenas feridas', + ['ems_menu_big'] = 'tratando lesões graves', -- Phone - ['alert_ambulance'] = 'Alerta Socorro', + ['alert_ambulance'] = 'alerta socorrista', -- Death - ['respawn_available_in'] = 'respawn available in ~b~%s minutes %s seconds~s~', - ['respawn_bleedout_in'] = 'you will bleed out in ~b~%s minutes %s seconds~s~\n', - ['respawn_bleedout_prompt'] = 'hold [~b~E~s~] to respawn', - ['respawn_bleedout_fine'] = 'hold [~b~E~s~] to respawn for ~g~$%s~s~', - ['respawn_bleedout_fine_msg'] = 'you paid ~r~$%s~s~ to respawn.', - ['distress_send'] = 'press [~b~G~s~] to send distress signal', - ['distress_sent'] = 'distress signal has been sent to available units!', - ['distress_message'] = 'medical attention required: unconscious citizen!', - ['combatlog_message'] = 'you have been force-respawned because you\'ve previously left the server when dead.', + ['respawn_available_in'] = 'você irar reviver em ~b~%s minutos %s segundos~s~', + ['respawn_bleedout_in'] = 'você vai sangrar ~b~%s minutos %s segundos~s~\n', + ['respawn_bleedout_prompt'] = 'aguarde [~b~E~s~] para reviver', + ['respawn_bleedout_fine'] = 'aguarde [~b~E~s~] para reviver por ~g~$%s~s~', + ['respawn_bleedout_fine_msg'] = 'você precisa pagar ~r~$%s~s~ para reviver', + ['distress_send'] = 'pressione [~b~G~s~] enviar sinal de socorro', + ['distress_sent'] = 'sinal de socorro foi enviado para as unidades disponíveis!', + ['distress_message'] = 'atenção médica necessária: cidadão inconsciente!', + ['combatlog_message'] = 'você foi revivido porque deixou o servidor anteriormente quando estava morto.', -- Revive - ['revive_help'] = 'reviver um jogador', + ['revive_help'] = 'reviver um cidadão', -- Item ['used_medikit'] = 'você usou 1x Seringa', ['used_bandage'] = 'você usou 1x Vendagem', - ['not_enough_medikit'] = 'Você não tem ~b~Seringa~s~.', - ['not_enough_bandage'] = 'Você não tem ~b~Vendagem~s~.', - ['healed'] = 'Você foi tratado.', + ['not_enough_medikit'] = 'você não tem ~b~Seringa~s~.', + ['not_enough_bandage'] = 'você não tem ~b~Vendagem~s~.', + ['healed'] = 'você foi tratado.', -- Blips - ['blip_hospital'] = 'Hôspital', - ['blip_dead'] = 'unconscious player', + ['blip_hospital'] = 'hospital', + ['blip_dead'] = 'cidadão inconsciente', } From 40e4a009f1de1f0ddb3328e64a6a8c6327a5358a Mon Sep 17 00:00:00 2001 From: maiconkkl Date: Sun, 5 Jan 2020 23:09:13 -0300 Subject: [PATCH 2369/3224] Correcting and improving translation --- locales/br.lua | 44 ++-- localization/br_esx_vehicleshop.sql | 333 ++++++++++++++++++++++++++++ 2 files changed, 355 insertions(+), 22 deletions(-) create mode 100644 localization/br_esx_vehicleshop.sql diff --git a/locales/br.lua b/locales/br.lua index 9001a2e2..c70a5d4d 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,22 +1,22 @@ Locales['br'] = { -- global menus - ['not_enough_in_society'] = 'there\'s not enough of ~r~that item~s~ in the society!', - ['player_cannot_hold'] = 'you do ~r~not~s~ have enough ~y~free space~s~ in your inventory!', - ['vehicle_belongs'] = 'an vehicle with plate ~y~%s~s~ now belongs to ~b~you~s~', + ['not_enough_in_society'] = 'não há o suficiente desse ~r~that item~s~ na sociedade!', + ['player_cannot_hold'] = 'você não tem espaço suficiente em seu inventário!', + ['vehicle_belongs'] = 'um veículo com placa ~y~%s~s~ agora pertence a ~b~you~s~', ['broke_company'] = 'você não tem dinheiro suficiente na conta da empresa', - ['license_missing'] = 'you don\'t have a driver\'s license!', - ['purchase_type'] = 'type of purchase', - ['society_type'] = 'society', - ['staff_type'] = 'personal usage', + ['license_missing'] = 'você não tem carteira de motorista!', + ['purchase_type'] = 'tipo de compra', + ['society_type'] = 'sociedade', + ['staff_type'] = 'uso pessoal', ['buy_vehicle_shop'] = 'comprar %s por $%s?', ['buy_vehicle'] = 'comprar veículo', ['car_dealer'] = 'Concessionária de carros', - ['shop_awaiting_model'] = 'the vehicle is currently loading, please wait', + ['shop_awaiting_model'] = 'o veículo está carregando no momento, aguarde', ['create_bill'] = 'criar recibo', ['dealer_boss'] = 'Concessionária de carros - Chefe', ['delivered'] = 'veículo ~g~entregue~s~ para o revendedor', ['depop_vehicle'] = 'volte ao veiculo', - ['return_provider'] = 'return vehicle to provider', + ['return_provider'] = 'devolver veículo ao fornecedor', ['get_rented_vehicles'] = 'veículos para alugar', ['invalid_amount'] = 'Montante inválido', ['invoice_amount'] = 'valor da fatura', @@ -29,12 +29,12 @@ Locales['br'] = { ['paid_rental'] = 'Você tem ~g~pago~s~ para o seu aluguel de veiculos: ~g~$%s~s~', ['pop_vehicle'] = 'sai do veiculo', ['rent_vehicle'] = 'Concessionária - Veículos para alugar', - ['return_provider_menu'] = 'car Dealer - Return vehicle to provider', + ['return_provider_menu'] = 'revendedor de carros - Devolver veículo ao fornecedor', ['rental_amount'] = 'montante do aluguel', ['sell_menu'] = 'Pressione ~INPUT_CONTEXT~ para vender ', ['set_vehicle_owner_rent'] = 'Atribuir veículo [Alugar]', ['set_vehicle_owner_sell'] = 'Veículos para [Venda]', - ['set_vehicle_owner_sell_society'] = 'assign Vehicle [Sale] [Society]', + ['set_vehicle_owner_sell_society'] = 'atribuir veículo [Sale] [Society]', ['shop_menu'] = 'pressione ~INPUT_CONTEXT~ para acessar o menu', ['generic_shopitem'] = '$%s', ['vehicle_dealer'] = 'Veículo - Concessionária', @@ -42,8 +42,8 @@ Locales['br'] = { ['vehicle_purchased'] = 'você comprou um veículo', ['vehicle_set_owned'] = 'Veículo ~y~%s~s~ foi atribuído a ~b~%s~s~', ['vehicle_set_rented'] = 'Veículo ~y~%s~s~ foi alugado para ~b~%s~s~', - ['vehicle_sold_for'] = 'the ~b~%s~s~ has been ~y~sold~s~ for ~g~$%s~s~', - ['vehicle_sold_to'] = 'Veículo ~y~%s~s~ vendido to ~b~%s~s~', + ['vehicle_sold_for'] = 'o ~b~%s~s~ foi vendido com sucesso para ~g~$%s~s~', + ['vehicle_sold_to'] = 'Veículo ~y~%s~s~ vendido para ~b~%s~s~', ['deposit_stock'] = 'Colocar no estoque', ['take_stock'] = 'Retirar do estoque', ['dealership_stock'] = 'estoque da concessionária', @@ -52,15 +52,15 @@ Locales['br'] = { ['inventory'] = 'Inventário', ['dealership'] = 'Concessionária', ['dealer_customers'] = 'clientes revendedores', - ['have_withdrawn'] = 'you have withdrawn ~y~x%s~s~ ~b~%s~s~', - ['have_deposited'] = 'you have deposited ~y~x%s~s~ ~b~%s~s~', - ['boss_actions'] = 'boss actions', + ['have_withdrawn'] = 'você retirou ~y~x%s~s~ ~b~%s~s~', + ['have_deposited'] = 'você depositou ~y~x%s~s~ ~b~%s~s~', + ['boss_actions'] = 'ações do chefe', -- sold vehicles - ['boss_sold'] = 'list of sold vehicles', - ['customer_client'] = 'customer name', - ['customer_model'] = 'car model', - ['customer_plate'] = 'car plate', - ['customer_soldby'] = 'sold by', - ['customer_date'] = 'date', + ['boss_sold'] = 'lista de veículos vendidos', + ['customer_client'] = 'nome do cliente', + ['customer_model'] = 'modelo de carro', + ['customer_plate'] = 'placa do carro', + ['customer_soldby'] = 'vendido por', + ['customer_date'] = 'data', } diff --git a/localization/br_esx_vehicleshop.sql b/localization/br_esx_vehicleshop.sql new file mode 100644 index 00000000..5a6db334 --- /dev/null +++ b/localization/br_esx_vehicleshop.sql @@ -0,0 +1,333 @@ +USE `essentialmode`; + +INSERT INTO `addon_account` (name, label, shared) VALUES + ('society_cardealer','Vendedor de carros',1) +; + +INSERT INTO `addon_inventory` (name, label, shared) VALUES + ('society_cardealer','Vendedor de carros',1) +; + +INSERT INTO `jobs` (name, label) VALUES + ('cardealer','Vendedor de carros') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('cardealer',0,'recrutar','Recrutar',10,'{}','{}'), + ('cardealer',1,'novato','Novato',25,'{}','{}'), + ('cardealer',2,'experiente','Experiente',40,'{}','{}'), + ('cardealer',3,'chefe','Chefe',0,'{}','{}') +; + +CREATE TABLE `cardealer_vehicles` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `vehicle` varchar(255) NOT NULL, + `price` int(11) NOT NULL, + + PRIMARY KEY (`id`) +); + +CREATE TABLE `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`) +); + +CREATE TABLE `owned_vehicles` ( + `owner` varchar(22) NOT NULL, + `plate` varchar(12) NOT NULL, + `vehicle` longtext, + `type` VARCHAR(20) NOT NULL DEFAULT 'car', + `job` VARCHAR(20) NULL DEFAULT NULL, + `stored` TINYINT(1) NOT NULL DEFAULT '0', + + PRIMARY KEY (`plate`) +); + +CREATE TABLE `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(22) NOT NULL, + + PRIMARY KEY (`plate`) +); + +CREATE TABLE `vehicle_categories` ( + `name` varchar(60) NOT NULL, + `label` varchar(60) NOT NULL, + + PRIMARY KEY (`name`) +); + +INSERT INTO `vehicle_categories` (name, label) VALUES + ('compacts','Compactos'), + ('coupes','Cupês'), + ('sedans','Sedans'), + ('sports','Esportes'), + ('sportsclassics','Clássicos Esportivos'), + ('super','Super'), + ('muscle','Músculo'), + ('offroad','Fora da estrada'), + ('suvs','SUVs'), + ('vans','Vans'), + ('motorcycles','Motos') +; + +CREATE TABLE `vehicles` ( + `name` varchar(60) NOT NULL, + `model` varchar(60) NOT NULL, + `price` int(11) NOT NULL, + `category` varchar(60) DEFAULT NULL, + + PRIMARY KEY (`model`) +); + +INSERT INTO `vehicles` (name, model, price, category) VALUES + ('Blade','blade',15000,'muscle'), + ('Buccaneer','buccaneer',18000,'muscle'), + ('Buccaneer Rider','buccaneer2',24000,'muscle'), + ('Chino','chino',15000,'muscle'), + ('Chino Luxe','chino2',19000,'muscle'), + ('Coquette BlackFin','coquette3',55000,'muscle'), + ('Dominator','dominator',35000,'muscle'), + ('Dukes','dukes',28000,'muscle'), + ('Gauntlet','gauntlet',30000,'muscle'), + ('Hotknife','hotknife',125000,'muscle'), + ('Faction','faction',20000,'muscle'), + ('Faction Rider','faction2',30000,'muscle'), + ('Faction XL','faction3',40000,'muscle'), + ('Nightshade','nightshade',65000,'muscle'), + ('Phoenix','phoenix',12500,'muscle'), + ('Picador','picador',18000,'muscle'), + ('Sabre Turbo','sabregt',20000,'muscle'), + ('Sabre GT','sabregt2',25000,'muscle'), + ('Slam Van','slamvan3',11500,'muscle'), + ('Tampa','tampa',16000,'muscle'), + ('Virgo','virgo',14000,'muscle'), + ('Vigero','vigero',12500,'muscle'), + ('Voodoo','voodoo',7200,'muscle'), + ('Blista','blista',8000,'compacts'), + ('Brioso R/A','brioso',18000,'compacts'), + ('Issi','issi2',10000,'compacts'), + ('Panto','panto',10000,'compacts'), + ('Prairie','prairie',12000,'compacts'), + ('Bison','bison',45000,'vans'), + ('Bobcat XL','bobcatxl',32000,'vans'), + ('Burrito','burrito3',19000,'vans'), + ('Burrito','gburrito2',29000,'vans'), + ('Camper','camper',42000,'vans'), + ('Gang Burrito','gburrito',45000,'vans'), + ('Journey','journey',6500,'vans'), + ('Minivan','minivan',13000,'vans'), + ('Moonbeam','moonbeam',18000,'vans'), + ('Moonbeam Rider','moonbeam2',35000,'vans'), + ('Paradise','paradise',19000,'vans'), + ('Rumpo','rumpo',15000,'vans'), + ('Rumpo Trail','rumpo3',19500,'vans'), + ('Surfer','surfer',12000,'vans'), + ('Youga','youga',10800,'vans'), + ('Youga Luxuary','youga2',14500,'vans'), + ('Asea','asea',5500,'sedans'), + ('Cognoscenti','cognoscenti',55000,'sedans'), + ('Emperor','emperor',8500,'sedans'), + ('Fugitive','fugitive',12000,'sedans'), + ('Glendale','glendale',6500,'sedans'), + ('Intruder','intruder',7500,'sedans'), + ('Premier','premier',8000,'sedans'), + ('Primo Custom','primo2',14000,'sedans'), + ('Regina','regina',5000,'sedans'), + ('Schafter','schafter2',25000,'sedans'), + ('Stretch','stretch',90000,'sedans'), + ('Super Diamond','superd',130000,'sedans'), + ('Tailgater','tailgater',30000,'sedans'), + ('Warrener','warrener',4000,'sedans'), + ('Washington','washington',9000,'sedans'), + ('Baller','baller2',40000,'suvs'), + ('Baller Sport','baller3',60000,'suvs'), + ('Cavalcade','cavalcade2',55000,'suvs'), + ('Contender','contender',70000,'suvs'), + ('Dubsta','dubsta',45000,'suvs'), + ('Dubsta Luxuary','dubsta2',60000,'suvs'), + ('Fhantom','fq2',17000,'suvs'), + ('Grabger','granger',50000,'suvs'), + ('Gresley','gresley',47500,'suvs'), + ('Huntley S','huntley',40000,'suvs'), + ('Landstalker','landstalker',35000,'suvs'), + ('Mesa','mesa',16000,'suvs'), + ('Mesa Trail','mesa3',40000,'suvs'), + ('Patriot','patriot',55000,'suvs'), + ('Radius','radi',29000,'suvs'), + ('Rocoto','rocoto',45000,'suvs'), + ('Seminole','seminole',25000,'suvs'), + ('XLS','xls',32000,'suvs'), + ('Btype','btype',62000,'sportsclassics'), + ('Btype Luxe','btype3',85000,'sportsclassics'), + ('Btype Hotroad','btype2',155000,'sportsclassics'), + ('Casco','casco',30000,'sportsclassics'), + ('Coquette Classic','coquette2',40000,'sportsclassics'), + ('Manana','manana',12800,'sportsclassics'), + ('Monroe','monroe',55000,'sportsclassics'), + ('Pigalle','pigalle',20000,'sportsclassics'), + ('Stinger','stinger',80000,'sportsclassics'), + ('Stinger GT','stingergt',75000,'sportsclassics'), + ('Stirling GT','feltzer3',65000,'sportsclassics'), + ('Z-Type','ztype',220000,'sportsclassics'), + ('Bifta','bifta',12000,'offroad'), + ('Bf Injection','bfinjection',16000,'offroad'), + ('Blazer','blazer',6500,'offroad'), + ('Blazer Sport','blazer4',8500,'offroad'), + ('Brawler','brawler',45000,'offroad'), + ('Bubsta 6x6','dubsta3',120000,'offroad'), + ('Dune Buggy','dune',8000,'offroad'), + ('Guardian','guardian',45000,'offroad'), + ('Rebel','rebel2',35000,'offroad'), + ('Sandking','sandking',55000,'offroad'), + ('The Liberator','monster',210000,'offroad'), + ('Trophy Truck','trophytruck',60000,'offroad'), + ('Trophy Truck Limited','trophytruck2',80000,'offroad'), + ('Cognoscenti Cabrio','cogcabrio',55000,'coupes'), + ('Exemplar','exemplar',32000,'coupes'), + ('F620','f620',40000,'coupes'), + ('Felon','felon',42000,'coupes'), + ('Felon GT','felon2',55000,'coupes'), + ('Jackal','jackal',38000,'coupes'), + ('Oracle XS','oracle2',35000,'coupes'), + ('Sentinel','sentinel',32000,'coupes'), + ('Sentinel XS','sentinel2',40000,'coupes'), + ('Windsor','windsor',95000,'coupes'), + ('Windsor Drop','windsor2',125000,'coupes'), + ('Zion','zion',36000,'coupes'), + ('Zion Cabrio','zion2',45000,'coupes'), + ('9F','ninef',65000,'sports'), + ('9F Cabrio','ninef2',80000,'sports'), + ('Alpha','alpha',60000,'sports'), + ('Banshee','banshee',70000,'sports'), + ('Bestia GTS','bestiagts',55000,'sports'), + ('Buffalo','buffalo',12000,'sports'), + ('Buffalo S','buffalo2',20000,'sports'), + ('Carbonizzare','carbonizzare',75000,'sports'), + ('Comet','comet2',65000,'sports'), + ('Coquette','coquette',65000,'sports'), + ('Drift Tampa','tampa2',80000,'sports'), + ('Elegy','elegy2',38500,'sports'), + ('Feltzer','feltzer2',55000,'sports'), + ('Furore GT','furoregt',45000,'sports'), + ('Fusilade','fusilade',40000,'sports'), + ('Jester','jester',65000,'sports'), + ('Jester(Racecar)','jester2',135000,'sports'), + ('Khamelion','khamelion',38000,'sports'), + ('Kuruma','kuruma',30000,'sports'), + ('Lynx','lynx',40000,'sports'), + ('Mamba','mamba',70000,'sports'), + ('Massacro','massacro',65000,'sports'), + ('Massacro(Racecar)','massacro2',130000,'sports'), + ('Omnis','omnis',35000,'sports'), + ('Penumbra','penumbra',28000,'sports'), + ('Rapid GT','rapidgt',35000,'sports'), + ('Rapid GT Convertible','rapidgt2',45000,'sports'), + ('Schafter V12','schafter3',50000,'sports'), + ('Seven 70','seven70',39500,'sports'), + ('Sultan','sultan',15000,'sports'), + ('Surano','surano',50000,'sports'), + ('Tropos','tropos',40000,'sports'), + ('Verlierer','verlierer2',70000,'sports'), + ('Adder','adder',900000,'super'), + ('Banshee 900R','banshee2',255000,'super'), + ('Bullet','bullet',90000,'super'), + ('Cheetah','cheetah',375000,'super'), + ('Entity XF','entityxf',425000,'super'), + ('ETR1','sheava',220000,'super'), + ('FMJ','fmj',185000,'super'), + ('Infernus','infernus',180000,'super'), + ('Osiris','osiris',160000,'super'), + ('Pfister','pfister811',85000,'super'), + ('RE-7B','le7b',325000,'super'), + ('Reaper','reaper',150000,'super'), + ('Sultan RS','sultanrs',65000,'super'), + ('T20','t20',300000,'super'), + ('Turismo R','turismor',350000,'super'), + ('Tyrus','tyrus',600000,'super'), + ('Vacca','vacca',120000,'super'), + ('Voltic','voltic',90000,'super'), + ('X80 Proto','prototipo',2500000,'super'), + ('Zentorno','zentorno',1500000,'super'), + ('Akuma','AKUMA',7500,'motorcycles'), + ('Avarus','avarus',18000,'motorcycles'), + ('Bagger','bagger',13500,'motorcycles'), + ('Bati 801','bati',12000,'motorcycles'), + ('Bati 801RR','bati2',19000,'motorcycles'), + ('BF400','bf400',6500,'motorcycles'), + ('BMX (velo)','bmx',160,'motorcycles'), + ('Carbon RS','carbonrs',18000,'motorcycles'), + ('Chimera','chimera',38000,'motorcycles'), + ('Cliffhanger','cliffhanger',9500,'motorcycles'), + ('Cruiser (velo)','cruiser',510,'motorcycles'), + ('Daemon','daemon',11500,'motorcycles'), + ('Daemon High','daemon2',13500,'motorcycles'), + ('Defiler','defiler',9800,'motorcycles'), + ('Double T','double',28000,'motorcycles'), + ('Enduro','enduro',5500,'motorcycles'), + ('Esskey','esskey',4200,'motorcycles'), + ('Faggio','faggio',1900,'motorcycles'), + ('Vespa','faggio2',2800,'motorcycles'), + ('Fixter (velo)','fixter',225,'motorcycles'), + ('Gargoyle','gargoyle',16500,'motorcycles'), + ('Hakuchou','hakuchou',31000,'motorcycles'), + ('Hakuchou Sport','hakuchou2',55000,'motorcycles'), + ('Hexer','hexer',12000,'motorcycles'), + ('Innovation','innovation',23500,'motorcycles'), + ('Manchez','manchez',5300,'motorcycles'), + ('Nemesis','nemesis',5800,'motorcycles'), + ('Nightblade','nightblade',35000,'motorcycles'), + ('PCJ-600','pcj',6200,'motorcycles'), + ('Ruffian','ruffian',6800,'motorcycles'), + ('Sanchez','sanchez',5300,'motorcycles'), + ('Sanchez Sport','sanchez2',5300,'motorcycles'), + ('Sanctus','sanctus',25000,'motorcycles'), + ('Scorcher (velo)','scorcher',280,'motorcycles'), + ('Sovereign','sovereign',22000,'motorcycles'), + ('Shotaro Concept','shotaro',320000,'motorcycles'), + ('Thrust','thrust',24000,'motorcycles'), + ('Tri bike (velo)','tribike3',520,'motorcycles'), + ('Vader','vader',7200,'motorcycles'), + ('Vortex','vortex',9800,'motorcycles'), + ('Woflsbane','wolfsbane',9000,'motorcycles'), + ('Zombie','zombiea',9500,'motorcycles'), + ('Zombie Luxuary','zombieb',12000,'motorcycles'), + ('blazer5', 'blazer5', 1755600, 'offroad'), + ('Ruiner 2', 'ruiner2', 5745600, 'muscle'), + ('Voltic 2', 'voltic2', 3830400, 'super'), + ('Ardent', 'ardent', 1150000, 'sportsclassics'), + ('Oppressor', 'oppressor', 3524500, 'super'), + ('Visione', 'visione', 2250000, 'super'), + ('Retinue', 'retinue', 615000, 'sportsclassics'), + ('Cyclone', 'cyclone', 1890000, 'super'), + ('Rapid GT3', 'rapidgt3', 885000, 'sportsclassics'), + ('raiden', 'raiden', 1375000, 'sports'), + ('Yosemite', 'yosemite', 485000, 'muscle'), + ('Deluxo', 'deluxo', 4721500, 'sportsclassics'), + ('Pariah', 'pariah', 1420000, 'sports'), + ('Stromberg', 'stromberg', 3185350, 'sports'), + ('SC 1', 'sc1', 1603000, 'super'), + ('riata', 'riata', 380000, 'offroad'), + ('Hermes', 'hermes', 535000, 'muscle'), + ('Savestra', 'savestra', 990000, 'sportsclassics'), + ('Streiter', 'streiter', 500000, 'sports'), + ('Kamacho', 'kamacho', 345000, 'offroad'), + ('GT 500', 'gt500', 785000, 'sportsclassics'), + ('Z190', 'z190', 900000, 'sportsclassics'), + ('Viseris', 'viseris', 875000, 'sportsclassics'), + ('Autarch', 'autarch', 1955000, 'super'), + ('Comet 5', 'comet5', 1145000, 'sports'), + ('Neon', 'neon', 1500000, 'sports'), + ('Revolter', 'revolter', 1610000, 'sports'), + ('Sentinel3', 'sentinel3', 650000, 'sports'), + ('Hustler', 'hustler', 625000, 'muscle') +; From 79762b6b44b054d30a733f24d007b4f650559550 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Mon, 6 Jan 2020 15:51:35 +0100 Subject: [PATCH 2370/3224] Updated SQL --- esx_basicneeds.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esx_basicneeds.sql b/esx_basicneeds.sql index d7c94296..2bf6df1f 100644 --- a/esx_basicneeds.sql +++ b/esx_basicneeds.sql @@ -1,6 +1,6 @@ USE `essentialmode`; INSERT INTO `items` (`name`, `label`, `weight`) VALUES - ('bread', 'Pain', 10), - ('water', 'Eau', 5) + ('bread', 'Pain', 1), + ('water', 'Eau', 1) ; From 208a362a5c68cc98787a1ae5abe771d7945165db Mon Sep 17 00:00:00 2001 From: rex2630 Date: Mon, 6 Jan 2020 15:52:04 +0100 Subject: [PATCH 2371/3224] SQL weight --- localization/de_esx_basicneeds.sql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/localization/de_esx_basicneeds.sql b/localization/de_esx_basicneeds.sql index 0e097e34..6dcf8319 100644 --- a/localization/de_esx_basicneeds.sql +++ b/localization/de_esx_basicneeds.sql @@ -1,6 +1,6 @@ USE `essentialmode`; -INSERT INTO `items` (`name`, `label`, `limit`) VALUES - ('bread', 'Brot', 10), - ('water', 'Wasser', 5) -; \ No newline at end of file +INSERT INTO `items` (`name`, `label`, `weight`) VALUES + ('bread', 'Brot', 1), + ('water', 'Wasser', 1) +; From 68e2fc52bf8f7a2f0a370b914ca35fe30b241837 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Mon, 6 Jan 2020 15:52:24 +0100 Subject: [PATCH 2372/3224] SQL weight --- localization/fi_esx_basicneeds.sql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/localization/fi_esx_basicneeds.sql b/localization/fi_esx_basicneeds.sql index 222cd54b..96a7a19d 100644 --- a/localization/fi_esx_basicneeds.sql +++ b/localization/fi_esx_basicneeds.sql @@ -1,6 +1,6 @@ USE `essentialmode`; -INSERT INTO `items` (`name`, `label`, `limit`) VALUES - ('bread', 'Leipä', 10), - ('water', 'Vesi', 5) -; \ No newline at end of file +INSERT INTO `items` (`name`, `label`, `weight`) VALUES + ('bread', 'Leipä', 1), + ('water', 'Vesi', 1) +; From bde5d69c1a303e2a1ff5eca9533bb374b7ce7283 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Mon, 6 Jan 2020 15:52:45 +0100 Subject: [PATCH 2373/3224] SQL weight --- localization/pl_esx_basicneeds.sql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/localization/pl_esx_basicneeds.sql b/localization/pl_esx_basicneeds.sql index dab8eeb7..3510f9cd 100644 --- a/localization/pl_esx_basicneeds.sql +++ b/localization/pl_esx_basicneeds.sql @@ -1,6 +1,6 @@ USE `essentialmode`; -INSERT INTO `items` (`name`, `label`, `limit`) VALUES - ('bread', 'Chleb', 10), - ('water', 'Woda', 5) -; \ No newline at end of file +INSERT INTO `items` (`name`, `label`, `weight`) VALUES + ('bread', 'Chleb', 1), + ('water', 'Woda', 1) +; From 37474d5d755b32cab395f6c3de876bc7c1f8bfd5 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Mon, 6 Jan 2020 15:53:05 +0100 Subject: [PATCH 2374/3224] SQL weight --- localization/sv_esx_basicneeds.sql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/localization/sv_esx_basicneeds.sql b/localization/sv_esx_basicneeds.sql index a22ab46b..be91ddc8 100644 --- a/localization/sv_esx_basicneeds.sql +++ b/localization/sv_esx_basicneeds.sql @@ -1,6 +1,6 @@ USE `essentialmode`; -INSERT INTO `items` (`name`, `label`, `limit`) VALUES - ('bread', 'Bröd', 10), - ('water', 'Vatten', 5) -; \ No newline at end of file +INSERT INTO `items` (`name`, `label`, `weight`) VALUES + ('bread', 'Bröd', 1), + ('water', 'Vatten', 1) +; From 04d3a6162fef4666c4079a524a8fa60d8361825b Mon Sep 17 00:00:00 2001 From: rex2630 Date: Mon, 6 Jan 2020 15:56:35 +0100 Subject: [PATCH 2375/3224] Updated to newest ESX --- server/main.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/main.lua b/server/main.lua index 4d4b4425..bddea2ca 100644 --- a/server/main.lua +++ b/server/main.lua @@ -9,7 +9,7 @@ ESX.RegisterUsableItem('bread', function(source) TriggerClientEvent('esx_status:add', source, 'hunger', 200000) TriggerClientEvent('esx_basicneeds:onEat', source) - TriggerClientEvent('esx:showNotification', source, _U('used_bread')) + xPlayer.showNotification(_U('used_bread')) end) ESX.RegisterUsableItem('water', function(source) @@ -19,7 +19,7 @@ ESX.RegisterUsableItem('water', function(source) TriggerClientEvent('esx_status:add', source, 'thirst', 200000) TriggerClientEvent('esx_basicneeds:onDrink', source) - TriggerClientEvent('esx:showNotification', source, _U('used_water')) + xPlayer.showNotification(_U('used_water')) end) TriggerEvent('es:addGroupCommand', 'heal', 'admin', function(source, args, user) @@ -46,4 +46,4 @@ TriggerEvent('es:addGroupCommand', 'heal', 'admin', function(source, args, user) end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = 'Heal a player, or yourself - restores thirst, hunger and health.', params = {{name = 'playerId', help = '(optional) player id'}}}) \ No newline at end of file +end, {help = 'Heal a player, or yourself - restores thirst, hunger and health.', params = {{name = 'playerId', help = '(optional) player id'}}}) From cc5b9c1538eac25ffda0f2c21946e25eec4bff69 Mon Sep 17 00:00:00 2001 From: Tinky <48660658+Tinky124@users.noreply.github.com> Date: Mon, 6 Jan 2020 16:04:53 +0100 Subject: [PATCH 2376/3224] Removed local keys --- client/main.lua | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/client/main.lua b/client/main.lua index 151bbfb7..9b6fe351 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,15 +1,3 @@ -local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, - ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, - ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, - ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, - ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, - ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, - ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 -} - ESX = nil local isDead = false @@ -55,7 +43,7 @@ end Citizen.CreateThread(function() while true do Citizen.Wait(0) - if IsControlJustReleased(0, Keys['F7']) and not isDead and not ESX.UI.Menu.IsOpen('default', GetCurrentResourceName(), 'billing') then + if IsControlJustReleased(0, 168) and not isDead and not ESX.UI.Menu.IsOpen('default', GetCurrentResourceName(), 'billing') then ShowBillsMenu() end end From dc1ba4f1ed5f9738a6f80201b83fbe81fc06eca4 Mon Sep 17 00:00:00 2001 From: maiconkkl Date: Mon, 6 Jan 2020 22:10:59 -0300 Subject: [PATCH 2377/3224] Correcting and improving translation --- locales/br.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index 9f93e8ea..bee997ed 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -4,7 +4,7 @@ Locales['br'] = { ['received_invoice'] = 'você ~r~recebeu~s~ uma fatura', ['paid_invoice'] = 'você ~g~pagou~s~ uma fatura de ~r~$%s~s~', ['received_payment'] = 'você ~g~recebeu~s~ um pagamento de ~r~$%s~s~', - ['player_not_online'] = 'o jogador não está logado', - ['no_money'] = 'you do not have enough money to pay this bill', - ['target_no_money'] = 'the player ~r~does not~s~ have enough money to pay the bill!', + ['player_not_online'] = 'o jogador não está na cidade', + ['no_money'] = 'você não tem dinheiro suficiente para pagar esta fatura', + ['target_no_money'] = 'o cidadão ~r~não tem~s~ dinheiro suficiente para pagar a conta!', } From 7b1ff095f149342722b2e946a7a2781919c8f422 Mon Sep 17 00:00:00 2001 From: pikaxo Date: Tue, 7 Jan 2020 23:01:23 +0000 Subject: [PATCH 2378/3224] rectify README.md fix README.md where it says ``` start esx_policejob ``` went to ``` start esx_sit ``` --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1ec6a9da..74c5d7a7 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ git clone https://github.com/ESX-Org/esx_sit [esx]/esx_sit - Add this to your server.cfg: ``` -start esx_policejob +start esx_sit ``` ## Credits @@ -46,4 +46,4 @@ This program Is free software: you can redistribute it And/Or modify it under th 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 http://www.gnu.org/licenses/. \ No newline at end of file +You should have received a copy Of the GNU General Public License along with this program. If Not, see http://www.gnu.org/licenses/. From aa9ffd386638d4ba0a8e9fce5385baa0c07f3295 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 12 Jan 2020 19:17:05 +0100 Subject: [PATCH 2379/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (95%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 95% rename from __resource.lua rename to fxmanifest.lua index 953bf74a..a4be3e72 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ES Extended' From 91eb2f85051f32ae35757aabb60431340b848a7d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 12 Jan 2020 19:18:41 +0100 Subject: [PATCH 2380/3224] Removed jobmaster group --- server/commands.lua | 2 +- server/main.lua | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/server/commands.lua b/server/commands.lua index fc672392..cbee7f24 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -20,7 +20,7 @@ end, {help = 'Teleport to coordinates', params = { {name = 'z', help = 'Z coords'} }}) -TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, user) +TriggerEvent('es:addGroupCommand', 'setjob', 'admin', function(source, args, user) if tonumber(args[1]) and args[2] and tonumber(args[3]) then local xPlayer = ESX.GetPlayerFromId(args[1]) diff --git a/server/main.lua b/server/main.lua index fc384765..f849c758 100644 --- a/server/main.lua +++ b/server/main.lua @@ -504,7 +504,5 @@ ESX.RegisterServerCallback('esx:getPlayerNames', function(source, cb, players) cb(players) end) -TriggerEvent("es:addGroup", "jobmaster", "user", function(group) end) - ESX.StartDBSync() ESX.StartPayCheck() From 9be103db3173db7499618d98a6b1dee91ffdd45c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 12 Jan 2020 21:04:04 +0100 Subject: [PATCH 2381/3224] ESX.Game.Teleport() support heading, minor cleanup --- client/functions.lua | 352 ++++++++++++------------------------------- 1 file changed, 93 insertions(+), 259 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index c42f6621..c5e2021d 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -280,14 +280,20 @@ ESX.Game.GetPedMugshot = function(ped) end ESX.Game.Teleport = function(entity, coords, cb) - RequestCollisionAtCoord(coords.x, coords.y, coords.z) - - while not HasCollisionLoadedAroundEntity(entity) do + if DoesEntityExist(entity) then RequestCollisionAtCoord(coords.x, coords.y, coords.z) - Citizen.Wait(0) - end - SetEntityCoords(entity, coords.x, coords.y, coords.z) + while not HasCollisionLoadedAroundEntity(entity) do + RequestCollisionAtCoord(coords.x, coords.y, coords.z) + Citizen.Wait(0) + end + + SetEntityCoords(entity, coords.x, coords.y, coords.z, false, false, false, false) + + if coords.heading then + SetEntityHeading(entity, coords.heading) + end + end if cb then cb() @@ -625,7 +631,7 @@ ESX.Game.GetClosestPed = function(coords, ignoreList) end ESX.Game.GetVehicleProperties = function(vehicle) - local color1, color2 = GetVehicleColours(vehicle) + local colorPrimary, colorSecondary = GetVehicleColours(vehicle) local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) local extras = {} @@ -647,8 +653,8 @@ ESX.Game.GetVehicleProperties = function(vehicle) fuelLevel = ESX.Math.Round(GetVehicleFuelLevel(vehicle), 1), dirtLevel = ESX.Math.Round(GetVehicleDirtLevel(vehicle), 1), - color1 = color1, - color2 = color2, + color1 = colorPrimary, + color2 = colorSecondary, pearlescentColor = pearlescentColor, wheelColor = wheelColor, @@ -721,264 +727,92 @@ ESX.Game.GetVehicleProperties = function(vehicle) end ESX.Game.SetVehicleProperties = function(vehicle, props) - SetVehicleModKit(vehicle, 0) - - if props.plate then - SetVehicleNumberPlateText(vehicle, props.plate) - end - - if props.plateIndex then - SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex) - end - - if props.bodyHealth then - SetVehicleBodyHealth(vehicle, props.bodyHealth + 0.0) - end - - if props.engineHealth then - SetVehicleEngineHealth(vehicle, props.engineHealth + 0.0) - end - - if props.fuelLevel then - SetVehicleFuelLevel(vehicle, props.fuelLevel + 0.0) - end - - if props.dirtLevel then - SetVehicleDirtLevel(vehicle, props.dirtLevel + 0.0) - end - - if props.color1 then - local color1, color2 = GetVehicleColours(vehicle) - SetVehicleColours(vehicle, props.color1, color2) - end - - if props.color2 then - local color1, color2 = GetVehicleColours(vehicle) - SetVehicleColours(vehicle, color1, props.color2) - end - - if props.pearlescentColor then + if DoesEntityExist(vehicle) then + local colorPrimary, colorSecondary = GetVehicleColours(vehicle) local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) - SetVehicleExtraColours(vehicle, props.pearlescentColor, wheelColor) - end + SetVehicleModKit(vehicle, 0) - if props.wheelColor then - local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) - SetVehicleExtraColours(vehicle, pearlescentColor, props.wheelColor) - end + if props.plate then SetVehicleNumberPlateText(vehicle, props.plate) end + if props.plateIndex then SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex) end + if props.bodyHealth then SetVehicleBodyHealth(vehicle, props.bodyHealth + 0.0) end + if props.engineHealth then SetVehicleEngineHealth(vehicle, props.engineHealth + 0.0) end + if props.fuelLevel then SetVehicleFuelLevel(vehicle, props.fuelLevel + 0.0) end + if props.dirtLevel then SetVehicleDirtLevel(vehicle, props.dirtLevel + 0.0) end + if props.color1 then SetVehicleColours(vehicle, props.color1, colorSecondary) end + if props.color2 then SetVehicleColours(vehicle, colorPrimary, props.color2) end + if props.pearlescentColor then SetVehicleExtraColours(vehicle, props.pearlescentColor, wheelColor) end + if props.wheelColor then SetVehicleExtraColours(vehicle, pearlescentColor, props.wheelColor) end + if props.wheels then SetVehicleWheelType(vehicle, props.wheels) end + if props.windowTint then SetVehicleWindowTint(vehicle, props.windowTint) end - if props.wheels then - SetVehicleWheelType(vehicle, props.wheels) - end + if props.neonEnabled then + SetVehicleNeonLightEnabled(vehicle, 0, props.neonEnabled[1]) + SetVehicleNeonLightEnabled(vehicle, 1, props.neonEnabled[2]) + SetVehicleNeonLightEnabled(vehicle, 2, props.neonEnabled[3]) + SetVehicleNeonLightEnabled(vehicle, 3, props.neonEnabled[4]) + end - if props.windowTint then - SetVehicleWindowTint(vehicle, props.windowTint) - end - - if props.neonEnabled then - SetVehicleNeonLightEnabled(vehicle, 0, props.neonEnabled[1]) - SetVehicleNeonLightEnabled(vehicle, 1, props.neonEnabled[2]) - SetVehicleNeonLightEnabled(vehicle, 2, props.neonEnabled[3]) - SetVehicleNeonLightEnabled(vehicle, 3, props.neonEnabled[4]) - end - - if props.extras then - for id,enabled in pairs(props.extras) do - if enabled then - SetVehicleExtra(vehicle, tonumber(id), 0) - else - SetVehicleExtra(vehicle, tonumber(id), 1) + if props.extras then + for id,enabled in pairs(props.extras) do + if enabled then + SetVehicleExtra(vehicle, tonumber(id), 0) + else + SetVehicleExtra(vehicle, tonumber(id), 1) + end end end - end - if props.neonColor then - SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) - end + if props.neonColor then SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) end + if props.modSmokeEnabled then ToggleVehicleMod(vehicle, 20, true) end + if props.tyreSmokeColor then SetVehicleTyreSmokeColor(vehicle, props.tyreSmokeColor[1], props.tyreSmokeColor[2], props.tyreSmokeColor[3]) end + if props.modSpoilers then SetVehicleMod(vehicle, 0, props.modSpoilers, false) end + if props.modFrontBumper then SetVehicleMod(vehicle, 1, props.modFrontBumper, false) end + if props.modRearBumper then SetVehicleMod(vehicle, 2, props.modRearBumper, false) end + if props.modSideSkirt then SetVehicleMod(vehicle, 3, props.modSideSkirt, false) end + if props.modExhaust then SetVehicleMod(vehicle, 4, props.modExhaust, false) end + if props.modFrame then SetVehicleMod(vehicle, 5, props.modFrame, false) end + if props.modGrille then SetVehicleMod(vehicle, 6, props.modGrille, false) end + if props.modHood then SetVehicleMod(vehicle, 7, props.modHood, false) end + if props.modFender then SetVehicleMod(vehicle, 8, props.modFender, false) end + if props.modRightFender then SetVehicleMod(vehicle, 9, props.modRightFender, false) end + if props.modRoof then SetVehicleMod(vehicle, 10, props.modRoof, false) end + if props.modEngine then SetVehicleMod(vehicle, 11, props.modEngine, false) end + if props.modBrakes then SetVehicleMod(vehicle, 12, props.modBrakes, false) end + if props.modTransmission then SetVehicleMod(vehicle, 13, props.modTransmission, false) end + if props.modHorns then SetVehicleMod(vehicle, 14, props.modHorns, false) end + if props.modSuspension then SetVehicleMod(vehicle, 15, props.modSuspension, false) end + if props.modArmor then SetVehicleMod(vehicle, 16, props.modArmor, false) end + if props.modTurbo then ToggleVehicleMod(vehicle, 18, props.modTurbo) end + if props.modXenon then ToggleVehicleMod(vehicle, 22, props.modXenon) end + if props.modFrontWheels then SetVehicleMod(vehicle, 23, props.modFrontWheels, false) end + if props.modBackWheels then SetVehicleMod(vehicle, 24, props.modBackWheels, false) end + if props.modPlateHolder then SetVehicleMod(vehicle, 25, props.modPlateHolder, false) end + if props.modVanityPlate then SetVehicleMod(vehicle, 26, props.modVanityPlate, false) end + if props.modTrimA then SetVehicleMod(vehicle, 27, props.modTrimA, false) end + if props.modOrnaments then SetVehicleMod(vehicle, 28, props.modOrnaments, false) end + if props.modDashboard then SetVehicleMod(vehicle, 29, props.modDashboard, false) end + if props.modDial then SetVehicleMod(vehicle, 30, props.modDial, false) end + if props.modDoorSpeaker then SetVehicleMod(vehicle, 31, props.modDoorSpeaker, false) end + if props.modSeats then SetVehicleMod(vehicle, 32, props.modSeats, false) end + if props.modSteeringWheel then SetVehicleMod(vehicle, 33, props.modSteeringWheel, false) end + if props.modShifterLeavers then SetVehicleMod(vehicle, 34, props.modShifterLeavers, false) end + if props.modAPlate then SetVehicleMod(vehicle, 35, props.modAPlate, false) end + if props.modSpeakers then SetVehicleMod(vehicle, 36, props.modSpeakers, false) end + if props.modTrunk then SetVehicleMod(vehicle, 37, props.modTrunk, false) end + if props.modHydrolic then SetVehicleMod(vehicle, 38, props.modHydrolic, false) end + if props.modEngineBlock then SetVehicleMod(vehicle, 39, props.modEngineBlock, false) end + if props.modAirFilter then SetVehicleMod(vehicle, 40, props.modAirFilter, false) end + if props.modStruts then SetVehicleMod(vehicle, 41, props.modStruts, false) end + if props.modArchCover then SetVehicleMod(vehicle, 42, props.modArchCover, false) end + if props.modAerials then SetVehicleMod(vehicle, 43, props.modAerials, false) end + if props.modTrimB then SetVehicleMod(vehicle, 44, props.modTrimB, false) end + if props.modTank then SetVehicleMod(vehicle, 45, props.modTank, false) end + if props.modWindows then SetVehicleMod(vehicle, 46, props.modWindows, false) end - if props.modSmokeEnabled then - ToggleVehicleMod(vehicle, 20, true) - end - - if props.tyreSmokeColor then - SetVehicleTyreSmokeColor(vehicle, props.tyreSmokeColor[1], props.tyreSmokeColor[2], props.tyreSmokeColor[3]) - end - - if props.modSpoilers then - SetVehicleMod(vehicle, 0, props.modSpoilers, false) - end - - if props.modFrontBumper then - SetVehicleMod(vehicle, 1, props.modFrontBumper, false) - end - - if props.modRearBumper then - SetVehicleMod(vehicle, 2, props.modRearBumper, false) - end - - if props.modSideSkirt then - SetVehicleMod(vehicle, 3, props.modSideSkirt, false) - end - - if props.modExhaust then - SetVehicleMod(vehicle, 4, props.modExhaust, false) - end - - if props.modFrame then - SetVehicleMod(vehicle, 5, props.modFrame, false) - end - - if props.modGrille then - SetVehicleMod(vehicle, 6, props.modGrille, false) - end - - if props.modHood then - SetVehicleMod(vehicle, 7, props.modHood, false) - end - - if props.modFender then - SetVehicleMod(vehicle, 8, props.modFender, false) - end - - if props.modRightFender then - SetVehicleMod(vehicle, 9, props.modRightFender, false) - end - - if props.modRoof then - SetVehicleMod(vehicle, 10, props.modRoof, false) - end - - if props.modEngine then - SetVehicleMod(vehicle, 11, props.modEngine, false) - end - - if props.modBrakes then - SetVehicleMod(vehicle, 12, props.modBrakes, false) - end - - if props.modTransmission then - SetVehicleMod(vehicle, 13, props.modTransmission, false) - end - - if props.modHorns then - SetVehicleMod(vehicle, 14, props.modHorns, false) - end - - if props.modSuspension then - SetVehicleMod(vehicle, 15, props.modSuspension, false) - end - - if props.modArmor then - SetVehicleMod(vehicle, 16, props.modArmor, false) - end - - if props.modTurbo then - ToggleVehicleMod(vehicle, 18, props.modTurbo) - end - - if props.modXenon then - ToggleVehicleMod(vehicle, 22, props.modXenon) - end - - if props.modFrontWheels then - SetVehicleMod(vehicle, 23, props.modFrontWheels, false) - end - - if props.modBackWheels then - SetVehicleMod(vehicle, 24, props.modBackWheels, false) - end - - if props.modPlateHolder then - SetVehicleMod(vehicle, 25, props.modPlateHolder, false) - end - - if props.modVanityPlate then - SetVehicleMod(vehicle, 26, props.modVanityPlate, false) - end - - if props.modTrimA then - SetVehicleMod(vehicle, 27, props.modTrimA, false) - end - - if props.modOrnaments then - SetVehicleMod(vehicle, 28, props.modOrnaments, false) - end - - if props.modDashboard then - SetVehicleMod(vehicle, 29, props.modDashboard, false) - end - - if props.modDial then - SetVehicleMod(vehicle, 30, props.modDial, false) - end - - if props.modDoorSpeaker then - SetVehicleMod(vehicle, 31, props.modDoorSpeaker, false) - end - - if props.modSeats then - SetVehicleMod(vehicle, 32, props.modSeats, false) - end - - if props.modSteeringWheel then - SetVehicleMod(vehicle, 33, props.modSteeringWheel, false) - end - - if props.modShifterLeavers then - SetVehicleMod(vehicle, 34, props.modShifterLeavers, false) - end - - if props.modAPlate then - SetVehicleMod(vehicle, 35, props.modAPlate, false) - end - - if props.modSpeakers then - SetVehicleMod(vehicle, 36, props.modSpeakers, false) - end - - if props.modTrunk then - SetVehicleMod(vehicle, 37, props.modTrunk, false) - end - - if props.modHydrolic then - SetVehicleMod(vehicle, 38, props.modHydrolic, false) - end - - if props.modEngineBlock then - SetVehicleMod(vehicle, 39, props.modEngineBlock, false) - end - - if props.modAirFilter then - SetVehicleMod(vehicle, 40, props.modAirFilter, false) - end - - if props.modStruts then - SetVehicleMod(vehicle, 41, props.modStruts, false) - end - - if props.modArchCover then - SetVehicleMod(vehicle, 42, props.modArchCover, false) - end - - if props.modAerials then - SetVehicleMod(vehicle, 43, props.modAerials, false) - end - - if props.modTrimB then - SetVehicleMod(vehicle, 44, props.modTrimB, false) - end - - if props.modTank then - SetVehicleMod(vehicle, 45, props.modTank, false) - end - - if props.modWindows then - SetVehicleMod(vehicle, 46, props.modWindows, false) - end - - if props.modLivery then - SetVehicleMod(vehicle, 48, props.modLivery, false) - SetVehicleLivery(vehicle, props.modLivery) + if props.modLivery then + SetVehicleMod(vehicle, 48, props.modLivery, false) + SetVehicleLivery(vehicle, props.modLivery) + end end end From ccdd4494c5137556192529b0500fa0183b25a9f2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 12 Jan 2020 21:55:18 +0100 Subject: [PATCH 2382/3224] Reset color after client print, use async callback for retrieving jobs --- server/common.lua | 57 +++++++++++++++++++++----------------------- server/functions.lua | 4 ++-- server/paycheck.lua | 3 --- 3 files changed, 29 insertions(+), 35 deletions(-) diff --git a/server/common.lua b/server/common.lua index b3c76c71..e2496d75 100644 --- a/server/common.lua +++ b/server/common.lua @@ -30,39 +30,36 @@ MySQL.ready(function() end end) - local result = MySQL.Sync.fetchAll('SELECT * FROM jobs', {}) - - for i=1, #result do - ESX.Jobs[result[i].name] = result[i] - ESX.Jobs[result[i].name].grades = {} - end - - local result2 = MySQL.Sync.fetchAll('SELECT * FROM job_grades', {}) - - for i=1, #result2 do - if ESX.Jobs[result2[i].job_name] then - ESX.Jobs[result2[i].job_name].grades[tostring(result2[i].grade)] = result2[i] - else - print(('[es_extended] [^3WARNING^7] Invalid job "%s" from table job_grades ignored'):format(result2[i].job_name)) + MySQL.Async.fetchAll('SELECT * FROM jobs', {}, function(jobs) + for k,v in ipairs(jobs) do + ESX.Jobs[v.name] = v + ESX.Jobs[v.name].grades = {} end - end - for k,v in pairs(ESX.Jobs) do - if next(v.grades) == nil then - ESX.Jobs[v.name] = nil - print(('[es_extended] [^3WARNING^7] Ignoring job "%s" due to missing job grades'):format(v.name)) - end - end + MySQL.Async.fetchAll('SELECT * FROM job_grades', {}, function(jobGrades) + for k,v in ipairs(jobGrades) do + if ESX.Jobs[v.job_name] then + ESX.Jobs[v.job_name].grades[tostring(v.grade)] = v + else + print(('[es_extended] [^3WARNING^7] Ignoring job grades for "%s" due to missing job'):format(v.job_name)) + end + end + + for k2,v2 in pairs(ESX.Jobs) do + if ESX.Table.SizeOf(v2.grades) == 0 then + ESX.Jobs[v2.name] = nil + print(('[es_extended] [^3WARNING^7] Ignoring job "%s" due to no job grades found'):format(v2.name)) + end + end + end) + end) print('[es_extended] [^2INFO^7] ESX developed by ESX-Org has been initialized') end) -AddEventHandler('esx:playerLoaded', function(source) - local xPlayer = ESX.GetPlayerFromId(source) - local accounts = {} - local items = {} - local xPlayerAccounts = xPlayer.getAccounts() - local xPlayerItems = xPlayer.getInventory() +AddEventHandler('esx:playerLoaded', function(playerId) + local xPlayer, accounts, items = ESX.GetPlayerFromId(playerId), {}, {} + local xPlayerAccounts, xPlayerItems = xPlayer.getAccounts(), xPlayer.getInventory() for i=1, #xPlayerAccounts, 1 do accounts[xPlayerAccounts[i].name] = xPlayerAccounts[i].money @@ -72,16 +69,16 @@ AddEventHandler('esx:playerLoaded', function(source) items[xPlayerItems[i].name] = xPlayerItems[i].count end - ESX.LastPlayerData[source] = { + ESX.LastPlayerData[playerId] = { accounts = accounts, - items = items + items = items } end) RegisterServerEvent('esx:clientLog') AddEventHandler('esx:clientLog', function(msg) if Config.EnableDebug then - print(('[es_extended] [^2TRACE^7] %s'):format(msg)) + print(('[es_extended] [^2TRACE^7] %s^7'):format(msg)) end end) diff --git a/server/functions.lua b/server/functions.lua index 545e6002..5bd0008f 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -1,6 +1,6 @@ -ESX.Trace = function(str) +ESX.Trace = function(msg) if Config.EnableDebug then - print(('[es_extended] [^2TRACE^7] %s'):format(str)) + print(('[es_extended] [^2TRACE^7] %s^7'):format(msg)) end end diff --git a/server/paycheck.lua b/server/paycheck.lua index 8df7bf95..293898f9 100644 --- a/server/paycheck.lua +++ b/server/paycheck.lua @@ -1,5 +1,4 @@ ESX.StartPayCheck = function() - function payCheck() local xPlayers = ESX.GetPlayers() @@ -39,9 +38,7 @@ ESX.StartPayCheck = function() end SetTimeout(Config.PaycheckInterval, payCheck) - end SetTimeout(Config.PaycheckInterval, payCheck) - end From 5566abca4f5c9e070f25f4b6369f210cb778e47f Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 12 Jan 2020 22:04:59 +0100 Subject: [PATCH 2383/3224] Removed updating loadout from client - usally spawned weapons --- client/main.lua | 1 - server/main.lua | 4 ---- 2 files changed, 5 deletions(-) diff --git a/client/main.lua b/client/main.lua index 261702cb..22292f4e 100644 --- a/client/main.lua +++ b/client/main.lua @@ -449,7 +449,6 @@ Citizen.CreateThread(function() if loadoutChanged and isLoadoutLoaded then ESX.PlayerData.loadout = loadout - TriggerServerEvent('esx:updateLoadout', loadout) end end end) diff --git a/server/main.lua b/server/main.lua index f849c758..b6e1806d 100644 --- a/server/main.lua +++ b/server/main.lua @@ -245,11 +245,7 @@ AddEventHandler('playerDropped', function(reason) end end) -RegisterServerEvent('esx:updateLoadout') -AddEventHandler('esx:updateLoadout', function(loadout) local xPlayer = ESX.GetPlayerFromId(source) - xPlayer.loadout = loadout -end) RegisterServerEvent('esx:updateLastPosition') AddEventHandler('esx:updateLastPosition', function(position) From f89e05175626f47275b4301e6561295414210711 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 12 Jan 2020 22:13:30 +0100 Subject: [PATCH 2384/3224] BREAKING COMMIT - Player loading improvements (read description!) This commit implements a new way of saving and getting player coords. Player coords are synced with its assigned xPlayer, the syncing interval is defined in the configuration file. Also coords wont sync if the player is too close to their previous location. Existing servers must change their database to account for the new length of the position varchar, at 53 chars max. There's also a column default value specified in the sql file. New xPlayer functions: - .getCoords() - .setCoords() (x,y,z,heading (optional) table - .updateCoords() The last one is used for syncing coords from client (interval). The second one will teleport the player. First one is a renamed .getLastPosition() --- client/main.lua | 89 ++++----- config.lua | 3 +- es_extended.sql | 2 +- server/classes/player.lua | 82 ++++---- server/functions.lua | 7 +- server/main.lua | 405 +++++++++++++++++++------------------- 6 files changed, 277 insertions(+), 311 deletions(-) diff --git a/client/main.lua b/client/main.lua index 22292f4e..48285d2b 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,6 +1,4 @@ - -local isLoadoutLoaded, isPaused, isPlayerSpawned, isDead = false, false, false, false -local lastLoadout, pickups = {}, {} +local isLoadoutLoaded, isPaused, isDead, isFirstSpawn, pickups = false, false, false, true, {} RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) @@ -47,33 +45,26 @@ end) AddEventHandler('playerSpawned', function() while not ESX.PlayerLoaded do - Citizen.Wait(1) + Citizen.Wait(10) end - local playerPed = PlayerPedId() + TriggerEvent('esx:restoreLoadout') - -- Restore position - if ESX.PlayerData.lastPosition then - SetEntityCoords(playerPed, ESX.PlayerData.lastPosition.x, ESX.PlayerData.lastPosition.y, ESX.PlayerData.lastPosition.z) + if isFirstSpawn then + ESX.Game.Teleport(PlayerPedId(), ESX.PlayerData.coords) + isFirstSpawn = false end - TriggerEvent('esx:restoreLoadout') -- restore loadout - - isLoadoutLoaded, isPlayerSpawned, isDead = true, true, false + isLoadoutLoaded, isDead = true, false if Config.EnablePvP then - SetCanAttackFriendly(playerPed, true, false) + SetCanAttackFriendly(PlayerPedId(), true, false) NetworkSetFriendlyFireOption(true) end end) -AddEventHandler('esx:onPlayerDeath', function() - isDead = true -end) - -AddEventHandler('skinchanger:loadDefaultModel', function() - isLoadoutLoaded = false -end) +AddEventHandler('esx:onPlayerDeath', function() isDead = true end) +AddEventHandler('skinchanger:loadDefaultModel', function() isLoadoutLoaded = false end) AddEventHandler('skinchanger:modelLoaded', function() while not ESX.PlayerLoaded do @@ -175,7 +166,6 @@ AddEventHandler('esx:addWeapon', function(weaponName, ammo) local weaponHash = GetHashKey(weaponName) GiveWeaponToPed(playerPed, weaponHash, ammo, false, false) - --AddAmmoToPed(playerPed, weaponHash, ammo) possibly not needed end) RegisterNetEvent('esx:addWeaponComponent') @@ -211,7 +201,6 @@ AddEventHandler('esx:removeWeapon', function(weaponName, ammo) end end) - RegisterNetEvent('esx:removeWeaponComponent') AddEventHandler('esx:removeWeaponComponent', function(weaponName, weaponComponent) local playerPed = PlayerPedId() @@ -221,21 +210,16 @@ AddEventHandler('esx:removeWeaponComponent', function(weaponName, weaponComponen RemoveWeaponComponentFromPed(playerPed, weaponHash, componentHash) end) --- Commands RegisterNetEvent('esx:teleport') -AddEventHandler('esx:teleport', function(pos) - pos.x = pos.x + 0.0 - pos.y = pos.y + 0.0 - pos.z = pos.z + 0.0 +AddEventHandler('esx:teleport', function(coords) + local playerPed = PlayerPedId() - RequestCollisionAtCoord(pos.x, pos.y, pos.z) + -- ensure decmial number + coords.x = coords.x + 0.0 + coords.y = coords.y + 0.0 + coords.z = coords.z + 0.0 - while not HasCollisionLoadedAroundEntity(PlayerPedId()) do - RequestCollisionAtCoord(pos.x, pos.y, pos.z) - Citizen.Wait(1) - end - - SetEntityCoords(PlayerPedId(), pos.x, pos.y, pos.z) + ESX.Game.Teleport(playerPed, coords) end) RegisterNetEvent('esx:setJob') @@ -384,7 +368,7 @@ AddEventHandler('esx:deleteVehicle', function(radius) end end) --- Pause menu disable HUD display +-- Pause menu disables HUD display if Config.EnableHud then Citizen.CreateThread(function() while true do @@ -405,12 +389,11 @@ end -- Save loadout Citizen.CreateThread(function() + local lastLoadout = {} + while true do Citizen.Wait(5000) - - local playerPed = PlayerPedId() - local loadout = {} - local loadoutChanged = false + local playerPed, loadout, loadoutChanged = PlayerPedId(), {}, false for k,v in ipairs(Config.Weapons) do local weaponName = v.name @@ -469,8 +452,8 @@ if Config.DisableWantedLevel then Citizen.CreateThread(function() while true do Citizen.Wait(0) - local playerId = PlayerId() + if GetPlayerWantedLevel(playerId) ~= 0 then SetPlayerWantedLevel(playerId, 0, false) SetPlayerWantedLevelNow(playerId, false) @@ -528,22 +511,26 @@ Citizen.CreateThread(function() end end) --- Last position +-- Update current player coords Citizen.CreateThread(function() - while true do + local previousCoords = vector3(0, 0, 0) + + -- wait for player to restore coords + while not isLoadoutLoaded do Citizen.Wait(1000) + end + + while true do + Citizen.Wait(Config.CoordsSyncInterval) local playerPed = PlayerPedId() + local playerCoords = GetEntityCoords(playerPed) + local distance = #(playerCoords - previousCoords) - if ESX.PlayerLoaded and isPlayerSpawned then - local coords = GetEntityCoords(playerPed) - - if not IsEntityDead(playerPed) then - ESX.PlayerData.lastPosition = {x = coords.x, y = coords.y, z = coords.z} - end - end - - if IsEntityDead(playerPed) and isPlayerSpawned then - isPlayerSpawned = false + if distance > 10 then + previousCoords = playerCoords + local playerHeading = ESX.Math.Round(GetEntityHeading(playerPed), 1) + local formattedCoords = {x = ESX.Math.Round(playerCoords.x, 1), y = ESX.Math.Round(playerCoords.y, 1), z = ESX.Math.Round(playerCoords.z, 1), heading = playerHeading} + TriggerServerEvent('esx:updateCoords', formattedCoords) end end end) diff --git a/config.lua b/config.lua index a332cf44..5dfee80f 100644 --- a/config.lua +++ b/config.lua @@ -10,6 +10,7 @@ Config.EnableHud = true -- enable the default hud? Display current jo Config.EnablePvP = true -- enable pvp? Config.MaxWeight = 24 -- the max inventory weight without backpack -Config.PaycheckInterval = 7 * 60000 +Config.PaycheckInterval = 7 * 60000 -- how often to recieve pay checks in milliseconds +Config.CoordsSyncInterval = 2 * 60000 -- how often to sync coords with server in milliseconds Config.EnableDebug = false diff --git a/es_extended.sql b/es_extended.sql index 52534684..4cab101a 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -6,7 +6,7 @@ ALTER TABLE `users` ADD COLUMN `job` VARCHAR(50) NULL DEFAULT 'unemployed' AFTER `skin`, ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, - ADD COLUMN `position` VARCHAR(36) NULL AFTER `loadout` + ADD COLUMN `position` VARCHAR(53) NULL DEFAULT '{"x":-269.4,"y":-955.3,"z":31.2,"heading":205.8}' AFTER `loadout` ; CREATE TABLE `items` ( diff --git a/server/classes/player.lua b/server/classes/player.lua index fe1cf5e0..851bb397 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -1,4 +1,4 @@ -function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, lastPosition) +function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, coords) local self = {} self.player = player @@ -7,8 +7,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.job = job self.loadout = loadout self.name = name - self.lastPosition = lastPosition self.maxWeight = Config.MaxWeight + self.coords = coords self.source = self.player.get('source') self.identifier = self.player.get('identifier') @@ -41,23 +41,25 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l return self.player.get('bank') end - self.getCoords = function(vectorType) - local coords = self.player.get('coords') - coords = {x = ESX.Math.Round(coords.x, 1), y = ESX.Math.Round(coords.y, 1), z = ESX.Math.Round(coords.z, 1)} + self.setCoords = function(coords) + self.updateCoords(coords) + self.triggerEvent('esx:teleport', coords) + end - if vectorType then - return vector3(coords.x, coords.y, coords.z) + self.updateCoords = function(coords) + self.coords = {x = ESX.Math.Round(coords.x, 1), y = ESX.Math.Round(coords.y, 1), z = ESX.Math.Round(coords.z, 1), heading = ESX.Math.Round(coords.heading, 1)} + end + + self.getCoords = function(vector) + if vector then + return vector3(self.coords.x, self.coords.y, self.coords.z) else - return coords + return self.coords end end - self.setCoords = function(x, y, z) - self.player.coords = {x = x, y = y, z = z} - end - self.kick = function(reason) - self.player.kick(reason) + DropPlayer(self.source, reason) end self.addMoney = function(money) @@ -194,20 +196,6 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.name = newName end - self.getLastPosition = function() - if self.lastPosition and self.lastPosition.x and self.lastPosition.y and self.lastPosition.z then - self.lastPosition.x = ESX.Math.Round(self.lastPosition.x, 1) - self.lastPosition.y = ESX.Math.Round(self.lastPosition.y, 1) - self.lastPosition.z = ESX.Math.Round(self.lastPosition.z, 1) - end - - return self.lastPosition - end - - self.setLastPosition = function(position) - self.lastPosition = position - end - self.getMissingAccounts = function(cb) MySQL.Async.fetchAll('SELECT name FROM user_accounts WHERE identifier = @identifier', { ['@identifier'] = self.getIdentifier() @@ -262,7 +250,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.set('bank', newMoney) end - TriggerClientEvent('esx:setAccountMoney', self.source, account) + self.triggerEvent('esx:setAccountMoney', account) end end end @@ -279,7 +267,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.set('bank', newMoney) end - TriggerClientEvent('esx:setAccountMoney', self.source, account) + self.triggerEvent('esx:setAccountMoney', account) end end end @@ -296,7 +284,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.set('bank', newMoney) end - TriggerClientEvent('esx:setAccountMoney', self.source, account) + self.triggerEvent('esx:setAccountMoney', account) end end end @@ -319,7 +307,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l item.count = newCount TriggerEvent('esx:onAddInventoryItem', self.source, item, count) - TriggerClientEvent('esx:addInventoryItem', self.source, item, count) + self.triggerEvent('esx:addInventoryItem', item, count) end end @@ -333,7 +321,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l item.count = newCount TriggerEvent('esx:onRemoveInventoryItem', self.source, item, count) - TriggerClientEvent('esx:removeInventoryItem', self.source, item, count) + self.triggerEvent('esx:removeInventoryItem', item, count) end end end @@ -347,10 +335,10 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if oldCount > item.count then TriggerEvent('esx:onRemoveInventoryItem', self.source, item, oldCount - item.count) - TriggerClientEvent('esx:removeInventoryItem', self.source, item, oldCount - item.count) + self.triggerEvent('esx:removeInventoryItem', item, oldCount - item.count) else TriggerEvent('esx:onAddInventoryItem', self.source, item, item.count - oldCount) - TriggerClientEvent('esx:addInventoryItem', self.source, item, item.count - oldCount) + self.triggerEvent('esx:addInventoryItem', item, item.count - oldCount) end end end @@ -388,7 +376,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.setMaxWeight = function(newWeight) self.maxWeight = newWeight - TriggerClientEvent('esx:setMaxWeight', self.source, self.maxWeight) + self.triggerEvent('esx:setMaxWeight', self.maxWeight) end self.setJob = function(job, grade) @@ -419,7 +407,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end TriggerEvent('esx:setJob', self.source, self.job, lastJob) - TriggerClientEvent('esx:setJob', self.source, self.job) + self.triggerEvent('esx:setJob', self.job) else print(('[es_extended] [^3WARNING^7] Ignoring invalid .setJob() usage for "%s"'):format(self.identifier)) end @@ -436,8 +424,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l components = {} }) - TriggerClientEvent('esx:addWeapon', self.source, weaponName, ammo) - TriggerClientEvent('esx:addInventoryItem', self.source, {label = weaponLabel}, 1) + self.triggerEvent('esx:addWeapon', weaponName, ammo) + self.triggerEvent('esx:addInventoryItem', {label = weaponLabel}, 1) end end @@ -447,7 +435,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if weapon then if not self.hasWeaponComponent(weaponName, weaponComponent) then table.insert(self.loadout[loadoutNum].components, weaponComponent) - TriggerClientEvent('esx:addWeaponComponent', self.source, weaponName, weaponComponent) + self.triggerEvent('esx:addWeaponComponent', weaponName, weaponComponent) end end end @@ -457,7 +445,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if weapon then weapon.ammo = weapon.ammo + ammoCount - TriggerClientEvent('esx:setWeaponAmmo', self.source, weaponName, weapon.ammo) + self.triggerEvent('esx:setWeaponAmmo', weaponName, weapon.ammo) end end @@ -469,7 +457,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l weaponLabel = v.label for k2,v2 in ipairs(v.components) do - TriggerClientEvent('esx:removeWeaponComponent', self.source, weaponName, v2) + self.triggerEvent('esx:removeWeaponComponent', weaponName, v2) end table.remove(self.loadout, k) @@ -478,8 +466,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end if weaponLabel then - TriggerClientEvent('esx:removeWeapon', self.source, weaponName, ammo) - TriggerClientEvent('esx:removeInventoryItem', self.source, {label = weaponLabel}, 1) + self.triggerEvent('esx:removeWeapon', weaponName, ammo) + self.triggerEvent('esx:removeInventoryItem', {label = weaponLabel}, 1) end end @@ -494,7 +482,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end end - TriggerClientEvent('esx:removeWeaponComponent', self.source, weaponName, weaponComponent) + self.triggerEvent('esx:removeWeaponComponent', weaponName, weaponComponent) end end @@ -503,7 +491,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if weapon then weapon.ammo = weapon.ammo - ammoCount - TriggerClientEvent('esx:setWeaponAmmo', self.source, weaponName, weapon.ammo) + self.triggerEvent('esx:setWeaponAmmo', weaponName, weapon.ammo) end end @@ -544,11 +532,11 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.showNotification = function(msg) - TriggerClientEvent('esx:showNotification', self.source, msg) + self.triggerEvent('esx:showNotification', msg) end self.showHelpNotification = function(msg) - TriggerClientEvent('esx:showHelpNotification', self.source, msg) + self.triggerEvent('esx:showHelpNotification', msg) end return self diff --git a/server/functions.lua b/server/functions.lua index 5bd0008f..2a20eeea 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -38,7 +38,6 @@ end ESX.SavePlayer = function(xPlayer, cb) local asyncTasks = {} - xPlayer.setLastPosition(xPlayer.getCoords()) -- User accounts for k,v in ipairs(xPlayer.accounts) do @@ -80,7 +79,7 @@ ESX.SavePlayer = function(xPlayer, cb) ['@job'] = xPlayer.job.name, ['@job_grade'] = xPlayer.job.grade, ['@loadout'] = json.encode(xPlayer.getLoadout()), - ['@position'] = json.encode(xPlayer.getLastPosition()), + ['@position'] = json.encode(xPlayer.getCoords()), ['@identifier'] = xPlayer.identifier }, function(rowsChanged) cb() @@ -88,7 +87,7 @@ ESX.SavePlayer = function(xPlayer, cb) end) Async.parallel(asyncTasks, function(results) - print(('[es_extended] [^2INFO^7] Saved %s'):format(xPlayer.getName())) + print(('[es_extended] [^2INFO^7] Saved player "%s^7"'):format(xPlayer.getName())) if cb ~= nil then cb() @@ -190,4 +189,4 @@ ESX.DoesJobExist = function(job, grade) end return false -end \ No newline at end of file +end diff --git a/server/main.lua b/server/main.lua index b6e1806d..49fb94fe 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,233 +1,225 @@ -AddEventHandler('es:playerLoaded', function(source, _player) - local playerId = source - local tasks = {} +AddEventHandler('es:playerLoaded', function(playerId, player) + local tasks = {} local userData = { - accounts = {}, - inventory = {}, - job = {}, - loadout = {}, - playerName = GetPlayerName(playerId), - lastPosition = nil + accounts = {}, + inventory = {}, + job = {}, + loadout = {}, + playerName = GetPlayerName(playerId), + coords = nil } - TriggerEvent('es:getPlayerFromId', playerId, function(player) - -- Update user name in DB - table.insert(tasks, function(cb) - MySQL.Async.execute('UPDATE users SET name = @name WHERE identifier = @identifier', { - ['@identifier'] = player.getIdentifier(), - ['@name'] = userData.playerName - }, function(rowsChanged) - cb() - end) + -- Update user name in DB + table.insert(tasks, function(cb) + MySQL.Async.execute('UPDATE users SET name = @name WHERE identifier = @identifier', { + ['@identifier'] = player.getIdentifier(), + ['@name'] = userData.playerName + }, function(rowsChanged) + cb() end) + end) - -- Get accounts - table.insert(tasks, function(cb) - MySQL.Async.fetchAll('SELECT name, money FROM user_accounts WHERE identifier = @identifier', { - ['@identifier'] = player.getIdentifier() - }, function(accounts) - local validAccounts = ESX.Table.Set(Config.Accounts) - for k,v in ipairs(accounts) do - if validAccounts[v.name] then - table.insert(userData.accounts, { - name = v.name, - money = v.money, - label = Config.AccountLabels[v.name] - }) - end + -- Get accounts + table.insert(tasks, function(cb) + MySQL.Async.fetchAll('SELECT name, money FROM user_accounts WHERE identifier = @identifier', { + ['@identifier'] = player.getIdentifier() + }, function(accounts) + local validAccounts = ESX.Table.Set(Config.Accounts) + for k,v in ipairs(accounts) do + if validAccounts[v.name] then + table.insert(userData.accounts, { + name = v.name, + money = v.money, + label = Config.AccountLabels[v.name] + }) end + end - cb() - end) + cb() end) + end) - -- Get inventory - table.insert(tasks, function(cb) + -- Get inventory + table.insert(tasks, function(cb) + MySQL.Async.fetchAll('SELECT item, count FROM user_inventory WHERE identifier = @identifier', { + ['@identifier'] = player.getIdentifier() + }, function(inventory) + local tasks2, foundItems = {}, {} - MySQL.Async.fetchAll('SELECT item, count FROM user_inventory WHERE identifier = @identifier', { - ['@identifier'] = player.getIdentifier() - }, function(inventory) - local tasks2, foundItems = {}, {} + for k,v in ipairs(inventory) do + local item = ESX.Items[v.item] - for k,v in ipairs(inventory) do - local item = ESX.Items[v.item] + if item then + foundItems[v.item] = true - if item then - foundItems[v.item] = true - - table.insert(userData.inventory, { - name = v.item, - count = v.count, - label = item.label, - weight = item.weight, - usable = ESX.UsableItemsCallbacks[v.item] ~= nil, - rare = item.rare, - canRemove = item.canRemove - }) - else - print(('[es_extended] [^3WARNING^7] Ignoring invalid item "%s" for "%s"'):format(v.item, player.getIdentifier())) - end + table.insert(userData.inventory, { + name = v.item, + count = v.count, + label = item.label, + weight = item.weight, + usable = ESX.UsableItemsCallbacks[v.item] ~= nil, + rare = item.rare, + canRemove = item.canRemove + }) + else + print(('[es_extended] [^3WARNING^7] Ignoring invalid item "%s" for "%s"'):format(v.item, player.getIdentifier())) end + end - for itemName,item in pairs(ESX.Items) do - if not foundItems[itemName] then - table.insert(userData.inventory, { - name = itemName, - count = 0, - label = item.label, - weight = item.weight, - usable = ESX.UsableItemsCallbacks[itemName] ~= nil, - rare = item.rare, - canRemove = item.canRemove - }) + for name,item in pairs(ESX.Items) do + if not foundItems[name] then + table.insert(userData.inventory, { + name = name, + count = 0, + label = item.label, + weight = item.weight, + usable = ESX.UsableItemsCallbacks[name] ~= nil, + rare = item.rare, + canRemove = item.canRemove + }) - local scope = function(item, identifier) - table.insert(tasks2, function(cb2) - MySQL.Async.execute('INSERT INTO user_inventory (identifier, item, count) VALUES (@identifier, @item, @count)', { - ['@identifier'] = identifier, - ['@item'] = item, - ['@count'] = 0 - }, function(rowsChanged) - cb2() - end) + local scope = function(item, identifier) + table.insert(tasks2, function(cb2) + MySQL.Async.execute('INSERT INTO user_inventory (identifier, item, count) VALUES (@identifier, @item, @count)', { + ['@identifier'] = identifier, + ['@item'] = item, + ['@count'] = 0 + }, function(rowsChanged) + cb2() end) - end + end) + end - scope(itemName, player.getIdentifier()) + scope(name, player.getIdentifier()) + end + end + + Async.parallelLimit(tasks2, 5, function(results) end) + + table.sort(userData.inventory, function(a,b) + return a.label < b.label + end) + + cb() + end) + + end) + + -- Get job and loadout + table.insert(tasks, function(cb) + + local tasks2 = {} + + -- Get job name, grade and coords + table.insert(tasks2, function(cb2) + + MySQL.Async.fetchAll('SELECT job, job_grade, loadout, position FROM users WHERE identifier = @identifier', { + ['@identifier'] = player.getIdentifier() + }, function(result) + local job, grade = result[1].job, tostring(result[1].job_grade) + + if ESX.DoesJobExist(job, grade) then + local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] + + userData.job = {} + + 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 + else + print(('[es_extended] [^3WARNING^7] Ignoring invalid job for %s [job: %s, grade: %s]'):format(player.getIdentifier(), job, grade)) + + local job, grade = 'unemployed', '0' + local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] + + userData.job = {} + + 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 = {} + end + + if result[1].loadout then + userData.loadout = json.decode(result[1].loadout) + + -- Compatibility with old loadouts prior to components update + for k,v in ipairs(userData.loadout) do + if v.components == nil then + v.components = {} + end end end - Async.parallelLimit(tasks2, 5, function(results) end) - - table.sort(userData.inventory, function(a,b) - return a.label < b.label - end) - - cb() + userData.coords = json.decode(result[1].position) + cb2() end) end) - -- Get job and loadout - table.insert(tasks, function(cb) + Async.series(tasks2, cb) - local tasks2 = {} + end) - -- Get job name, grade and last position - table.insert(tasks2, function(cb2) + -- Run Tasks + Async.parallel(tasks, function(results) + local xPlayer = CreateExtendedPlayer(player, userData.accounts, userData.inventory, userData.job, userData.loadout, userData.playerName, userData.coords) - MySQL.Async.fetchAll('SELECT job, job_grade, loadout, position FROM users WHERE identifier = @identifier', { - ['@identifier'] = player.getIdentifier() - }, function(result) - local job, grade = result[1].job, tostring(result[1].job_grade) - - if ESX.DoesJobExist(job, grade) then - local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] - - userData.job = {} - - 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 ~= nil then - userData.job.skin_male = json.decode(gradeObject.skin_male) - end - - if gradeObject.skin_female ~= nil then - userData.job.skin_female = json.decode(gradeObject.skin_female) - end - else - print(('[es_extended] [^3WARNING^7] Ignoring invalid job for %s [job: %s, grade: %s]'):format(player.getIdentifier(), job, grade)) - - local job, grade = 'unemployed', '0' - local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] - - userData.job = {} - - 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 = {} - end - - if result[1].loadout ~= nil then - userData.loadout = json.decode(result[1].loadout) - - -- Compatibility with old loadouts prior to components update - for k,v in ipairs(userData.loadout) do - if v.components == nil then - v.components = {} - end - end - end - - if result[1].position ~= nil then - userData.lastPosition = json.decode(result[1].position) - end - - cb2() - end) - - end) - - Async.series(tasks2, cb) - - end) - - -- Run Tasks - Async.parallel(tasks, function(results) - local xPlayer = CreateExtendedPlayer(player, userData.accounts, userData.inventory, userData.job, userData.loadout, userData.playerName, userData.lastPosition) - - xPlayer.getMissingAccounts(function(missingAccounts) - if #missingAccounts > 0 then - for i=1, #missingAccounts, 1 do - table.insert(xPlayer.accounts, { - name = missingAccounts[i], - money = 0, - label = Config.AccountLabels[missingAccounts[i]] - }) - end - - xPlayer.createAccounts(missingAccounts) + xPlayer.getMissingAccounts(function(missingAccounts) + if #missingAccounts > 0 then + for i=1, #missingAccounts, 1 do + table.insert(xPlayer.accounts, { + name = missingAccounts[i], + money = 0, + label = Config.AccountLabels[missingAccounts[i]] + }) end - ESX.Players[playerId] = xPlayer + xPlayer.createAccounts(missingAccounts) + end - TriggerEvent('esx:playerLoaded', playerId, xPlayer) + ESX.Players[playerId] = xPlayer - TriggerClientEvent('esx:playerLoaded', playerId, { - identifier = xPlayer.identifier, - accounts = xPlayer.getAccounts(), - inventory = xPlayer.getInventory(), - job = xPlayer.getJob(), - loadout = xPlayer.getLoadout(), - lastPosition = xPlayer.getLastPosition(), - money = xPlayer.getMoney(), - maxWeight = xPlayer.maxWeight - }) + TriggerEvent('esx:playerLoaded', playerId, xPlayer) - xPlayer.displayMoney(xPlayer.getMoney()) - TriggerClientEvent('esx:createMissingPickups', playerId, ESX.Pickups) - end) + xPlayer.triggerEvent('esx:playerLoaded', { + identifier = xPlayer.identifier, + accounts = xPlayer.getAccounts(), + coords = xPlayer.getCoords(), + inventory = xPlayer.getInventory(), + job = xPlayer.getJob(), + loadout = xPlayer.getLoadout(), + money = xPlayer.getMoney(), + maxWeight = xPlayer.maxWeight + }) + + xPlayer.displayMoney(xPlayer.getMoney()) + xPlayer.triggerEvent('esx:createMissingPickups', ESX.Pickups) end) - end) end) @@ -245,15 +237,16 @@ AddEventHandler('playerDropped', function(reason) end end) +RegisterNetEvent('esx:updateCoords') +AddEventHandler('esx:updateCoords', function(coords) local xPlayer = ESX.GetPlayerFromId(source) -RegisterServerEvent('esx:updateLastPosition') -AddEventHandler('esx:updateLastPosition', function(position) - local xPlayer = ESX.GetPlayerFromId(source) - xPlayer.setLastPosition(position) + if xPlayer then + xPlayer.updateCoords(coords) + end end) -RegisterServerEvent('esx:giveInventoryItem') +RegisterNetEvent('esx:giveInventoryItem') AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCount) local playerId = source local sourceXPlayer = ESX.GetPlayerFromId(playerId) @@ -306,7 +299,7 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo sourceXPlayer.removeWeapon(itemName) targetXPlayer.addWeapon(itemName, itemCount) - + if itemCount > 0 then sourceXPlayer.showNotification(_U('gave_weapon_withammo', weaponLabel, itemCount, targetXPlayer.name)) targetXPlayer.showNotification(_U('received_weapon_withammo', weaponLabel, itemCount, sourceXPlayer.name)) @@ -339,7 +332,7 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo end end) -RegisterServerEvent('esx:removeInventoryItem') +RegisterNetEvent('esx:removeInventoryItem') AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) local playerId = source local xPlayer = ESX.GetPlayerFromId(source) @@ -406,7 +399,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) end end) -RegisterServerEvent('esx:useItem') +RegisterNetEvent('esx:useItem') AddEventHandler('esx:useItem', function(itemName) local xPlayer = ESX.GetPlayerFromId(source) local count = xPlayer.getInventoryItem(itemName).count @@ -418,7 +411,7 @@ AddEventHandler('esx:useItem', function(itemName) end end) -RegisterServerEvent('esx:onPickup') +RegisterNetEvent('esx:onPickup') AddEventHandler('esx:onPickup', function(id) local pickup, xPlayer, success = ESX.Pickups[id], ESX.GetPlayerFromId(source) @@ -465,7 +458,6 @@ ESX.RegisterServerCallback('esx:getPlayerData', function(source, cb) inventory = xPlayer.getInventory(), job = xPlayer.getJob(), loadout = xPlayer.getLoadout(), - lastPosition = xPlayer.getLastPosition(), money = xPlayer.getMoney() }) end) @@ -479,7 +471,6 @@ ESX.RegisterServerCallback('esx:getOtherPlayerData', function(source, cb, target inventory = xPlayer.getInventory(), job = xPlayer.getJob(), loadout = xPlayer.getLoadout(), - lastPosition = xPlayer.getLastPosition(), money = xPlayer.getMoney() }) end) From 210b98975a4bb52d244e3d44ffa9d59d1df4684c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 12 Jan 2020 22:15:47 +0100 Subject: [PATCH 2385/3224] Removed old lastPosition code --- client/main.lua | 7 ------- 1 file changed, 7 deletions(-) diff --git a/client/main.lua b/client/main.lua index f0375890..517b6483 100644 --- a/client/main.lua +++ b/client/main.lua @@ -308,10 +308,7 @@ function RemoveItemsAfterRPDeath() z = Config.RespawnPoint.coords.z } - ESX.SetPlayerData('lastPosition', formattedCoords) ESX.SetPlayerData('loadout', {}) - - TriggerServerEvent('esx:updateLastPosition', formattedCoords) RespawnPed(PlayerPedId(), formattedCoords, Config.RespawnPoint.heading) StopScreenEffect('DeathFailOut') @@ -365,10 +362,6 @@ AddEventHandler('esx_ambulancejob:revive', function() z = ESX.Math.Round(coords.z, 1) } - ESX.SetPlayerData('lastPosition', formattedCoords) - - TriggerServerEvent('esx:updateLastPosition', formattedCoords) - RespawnPed(playerPed, formattedCoords, 0.0) StopScreenEffect('DeathFailOut') From b3a36747a3ba2a546af365bf4870f0637327b6b6 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 10:27:07 +0100 Subject: [PATCH 2386/3224] Removed saving Steam name in database, closes #246 --- es_extended.sql | 1 - server/main.lua | 10 ---------- 2 files changed, 11 deletions(-) diff --git a/es_extended.sql b/es_extended.sql index 4cab101a..399847e9 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -1,7 +1,6 @@ USE `essentialmode`; ALTER TABLE `users` - ADD COLUMN `name` VARCHAR(50) NULL DEFAULT '' AFTER `money`, ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, ADD COLUMN `job` VARCHAR(50) NULL DEFAULT 'unemployed' AFTER `skin`, ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, diff --git a/server/main.lua b/server/main.lua index 49fb94fe..643797f0 100644 --- a/server/main.lua +++ b/server/main.lua @@ -10,16 +10,6 @@ AddEventHandler('es:playerLoaded', function(playerId, player) coords = nil } - -- Update user name in DB - table.insert(tasks, function(cb) - MySQL.Async.execute('UPDATE users SET name = @name WHERE identifier = @identifier', { - ['@identifier'] = player.getIdentifier(), - ['@name'] = userData.playerName - }, function(rowsChanged) - cb() - end) - end) - -- Get accounts table.insert(tasks, function(cb) MySQL.Async.fetchAll('SELECT name, money FROM user_accounts WHERE identifier = @identifier', { From 7fc962a83cd478fc5bbb7f4499fc0066f374d059 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 10:47:02 +0100 Subject: [PATCH 2387/3224] Removed mysql database usage --- README.md | 2 +- __resource.lua | 1 - client/main.lua | 18 +++++------ config.lua | 3 +- locales/fi.lua | 2 +- locales/fr.lua | 2 +- server/main.lua | 82 +++++++++++++++++++++++-------------------------- 7 files changed, 50 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index 492ed3be..bf364c90 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ git clone https://github.com/ESX-Org/esx_rpchat [esx]/esx_rpchat ### License esx_rpchat - RP chat for ESX -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. diff --git a/__resource.lua b/__resource.lua index 58c0093b..0685eab3 100644 --- a/__resource.lua +++ b/__resource.lua @@ -5,7 +5,6 @@ description 'ESX RP Chat' version '1.3.1' server_scripts { - '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', 'locales/sv.lua', 'locales/en.lua', diff --git a/client/main.lua b/client/main.lua index c94a255b..5beb7495 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,22 +1,20 @@ RegisterNetEvent('esx_rpchat:sendProximityMessage') AddEventHandler('esx_rpchat:sendProximityMessage', function(playerId, title, message, color) - local source = PlayerId() + local player = PlayerId() local target = GetPlayerFromServerId(playerId) - local sourcePed, targetPed = PlayerPedId(), GetPlayerPed(target) - local sourceCoords, targetCoords = GetEntityCoords(sourcePed), GetEntityCoords(targetPed) + local playerPed, targetPed = PlayerPedId(), GetPlayerPed(target) + local playerCoords, targetCoords = GetEntityCoords(playerPed), GetEntityCoords(targetPed) - if target == source then - TriggerEvent('chat:addMessage', { args = { title, message }, color = color }) - elseif GetDistanceBetweenCoords(sourceCoords, targetCoords, true) < 20 then - TriggerEvent('chat:addMessage', { args = { title, message }, color = color }) + if target == player or #(playerCoords - targetCoords) < 20 then + TriggerEvent('chat:addMessage', {args = {title, message}, color = color}) end end) Citizen.CreateThread(function() - TriggerEvent('chat:addSuggestion', '/twt', _U('twt_help'), { { name = _U('generic_argument_name'), help = _U('generic_argument_help') } } ) - TriggerEvent('chat:addSuggestion', '/me', _U('me_help'), { { name = _U('generic_argument_name'), help = _U('generic_argument_help') } } ) - TriggerEvent('chat:addSuggestion', '/do', _U('do_help'), { { name = _U('generic_argument_name'), help = _U('generic_argument_help') } } ) + TriggerEvent('chat:addSuggestion', '/twt', _U('twt_help'), {{name = _U('generic_argument_name'), help = _U('generic_argument_help')}}) + TriggerEvent('chat:addSuggestion', '/me', _U('me_help'), {{name = _U('generic_argument_name'), help = _U('generic_argument_help')}}) + TriggerEvent('chat:addSuggestion', '/do', _U('do_help'), {{name = _U('generic_argument_name'), help = _U('generic_argument_help')}}) end) AddEventHandler('onResourceStop', function(resource) diff --git a/config.lua b/config.lua index 15e7a099..b8f2f98d 100644 --- a/config.lua +++ b/config.lua @@ -1,5 +1,4 @@ -Config = {} -Config.Locale = 'en' +Config = {} Config.EnableESXIdentity = false -- only turn this on if you are using esx_identity and want to use RP names Config.OnlyFirstname = false \ No newline at end of file diff --git a/locales/fi.lua b/locales/fi.lua index e85ad38b..8416d4e2 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -4,7 +4,7 @@ Locales['fi'] = { ['twt_prefix'] = '^0[^4Twitter^0] (^5@%s^0)', ['me_help'] = 'teet jotain', ['me_prefix'] = 'me | %s', - ['do_help'] = 'roolipeliä tiedot', --TODO: check translation + ['do_help'] = 'roolipeliä tiedot', ['do_prefix'] = 'do | %s', ['generic_argument_name'] = 'viesti', ['generic_argument_help'] = 'viestin sisältö', diff --git a/locales/fr.lua b/locales/fr.lua index 22ae4f93..7ae7dd6f 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -4,7 +4,7 @@ Locales['fr'] = { ['twt_prefix'] = '^0[^4Twitter^0] (^5@%s^0)', ['me_help'] = 'action personnelle', ['me_prefix'] = 'me | %s', - ['do_help'] = 'RP information', --TODO: check translation + ['do_help'] = 'RP information', ['do_prefix'] = 'faire | %s', ['generic_argument_name'] = 'message', ['generic_argument_help'] = 'le message', diff --git a/server/main.lua b/server/main.lua index 7b3ca55c..4ec542a3 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,71 +1,65 @@ AddEventHandler('es:invalidCommandHandler', function(source, command_args, user) CancelEvent() - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', _U('unknown_command', command_args[1]) } }) + TriggerClientEvent('chat:addMessage', source, {args = {'^1SYSTEM', _U('unknown_command', command_args[1])}}) end) -AddEventHandler('chatMessage', function(source, name, message) +AddEventHandler('chatMessage', function(playerId, playerName, message) if string.sub(message, 1, string.len('/')) ~= '/' then CancelEvent() - if Config.EnableESXIdentity then name = GetCharacterName(source) end - TriggerClientEvent('chat:addMessage', -1, { args = { _U('ooc_prefix', name), message }, color = { 128, 128, 128 } }) + local xPlayer = ESX.GetPlayerFromId(playerId) + if xPlayer then playerName = xPlayer.getName() end + TriggerClientEvent('chat:addMessage', -1, {args = {_U('ooc_prefix', playerName), message}, color = {128, 128, 128}}) end end) -RegisterCommand('twt', function(source, args, rawCommand) - if source == 0 then - print('esx_rpchat: you can\'t use this command from rcon!') - return +RegisterCommand('twt', function(playerId, args, rawCommand) + if playerId == 0 then + print('esx_rpchat: you can\'t use this command from console!') + else + args = table.concat(args, ' ') + local playerName = GetRealPlayerName(playerId) + + TriggerClientEvent('chat:addMessage', -1, {args = {_U('twt_prefix', playerName), args}, color = {0, 153, 204}}) end - - args = table.concat(args, ' ') - local name = GetPlayerName(source) - if Config.EnableESXIdentity then name = GetCharacterName(source) end - - TriggerClientEvent('chat:addMessage', -1, { args = { _U('twt_prefix', name), args }, color = { 0, 153, 204 } }) - --print(('%s: %s'):format(name, args)) end, false) -RegisterCommand('me', function(source, args, rawCommand) +RegisterCommand('me', function(playerId, args, rawCommand) if source == 0 then - print('esx_rpchat: you can\'t use this command from rcon!') - return + print('esx_rpchat: you can\'t use this command from console!') + else + args = table.concat(args, ' ') + local playerName = GetRealPlayerName(playerId) + + TriggerClientEvent('esx_rpchat:sendProximityMessage', -1, source, _U('me_prefix', playerName), args, {255, 0, 0}) end - - args = table.concat(args, ' ') - local name = GetPlayerName(source) - if Config.EnableESXIdentity then name = GetCharacterName(source) end - - TriggerClientEvent('esx_rpchat:sendProximityMessage', -1, source, _U('me_prefix', name), args, { 255, 0, 0 }) - --print(('%s: %s'):format(name, args)) end, false) -RegisterCommand('do', function(source, args, rawCommand) +RegisterCommand('do', function(playerId, args, rawCommand) if source == 0 then - print('esx_rpchat: you can\'t use this command from rcon!') - return + print('esx_rpchat: you can\'t use this command from console!') + else + args = table.concat(args, ' ') + local playerName = GetRealPlayerName(playerId) + + TriggerClientEvent('esx_rpchat:sendProximityMessage', -1, source, _U('do_prefix', playerName), args, {0, 0, 255}) end - - args = table.concat(args, ' ') - local name = GetPlayerName(source) - if Config.EnableESXIdentity then name = GetCharacterName(source) end - - TriggerClientEvent('esx_rpchat:sendProximityMessage', -1, source, _U('do_prefix', name), args, { 0, 0, 255 }) - --print(('%s: %s'):format(name, args)) end, false) -function GetCharacterName(source) - local result = MySQL.Sync.fetchAll('SELECT firstname, lastname FROM users WHERE identifier = @identifier', { - ['@identifier'] = GetPlayerIdentifiers(source)[1] - }) +function GetRealPlayerName(playerId) + local xPlayer = ESX.GetPlayerFromId(playerId) - if result[1] and result[1].firstname and result[1].lastname then - if Config.OnlyFirstname then - return result[1].firstname + if xPlayer then + if Config.EnableESXIdentity then + if Config.OnlyFirstname then + return xPlayer.get('firstName') + else + return xPlayer.getName() + end else - return ('%s %s'):format(result[1].firstname, result[1].lastname) + return xPlayer.getName() end else - return GetPlayerName(source) + return GetPlayerName(playerId) end end From b587a25c924769038ac40b116c92e0c54cb105f4 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 10:47:18 +0100 Subject: [PATCH 2388/3224] Update config.lua --- config.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config.lua b/config.lua index b8f2f98d..0ef102ec 100644 --- a/config.lua +++ b/config.lua @@ -1,4 +1,5 @@ Config = {} +Config.Locale = 'fr' +Config.OnlyFirstname = false Config.EnableESXIdentity = false -- only turn this on if you are using esx_identity and want to use RP names -Config.OnlyFirstname = false \ No newline at end of file From 47a36bb9c7e9605fa4797d0b6d1dad7fbee04706 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 10:58:08 +0100 Subject: [PATCH 2389/3224] Added missing ESX usage --- config.lua | 4 ++-- server/main.lua | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/config.lua b/config.lua index 0ef102ec..610145b8 100644 --- a/config.lua +++ b/config.lua @@ -1,5 +1,5 @@ Config = {} -Config.Locale = 'fr' +Config.Locale = 'sv' Config.OnlyFirstname = false -Config.EnableESXIdentity = false -- only turn this on if you are using esx_identity and want to use RP names +Config.EnableESXIdentity = true -- only turn this on if you are using esx_identity and want to use RP names diff --git a/server/main.lua b/server/main.lua index 4ec542a3..3442f910 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,3 +1,7 @@ +ESX = nil + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + AddEventHandler('es:invalidCommandHandler', function(source, command_args, user) CancelEvent() TriggerClientEvent('chat:addMessage', source, {args = {'^1SYSTEM', _U('unknown_command', command_args[1])}}) From 10665aff53ea592e8d6165eefd34b3953bc99aeb Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 11:03:16 +0100 Subject: [PATCH 2390/3224] Update xPlayer name --- README.md | 2 +- client/main.lua | 5 ++- server/main.lua | 96 ++++++++++++++++++++++++++++++------------------- 3 files changed, 65 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 0f8f41f5..c2edec3f 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ start esx_identity ### License esx_identity - rp characters -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. diff --git a/client/main.lua b/client/main.lua index f95ab368..9b1f08f0 100644 --- a/client/main.lua +++ b/client/main.lua @@ -97,6 +97,8 @@ end) Citizen.CreateThread(function() while true do + Citizen.Wait(0) + if guiEnabled then DisableControlAction(0, 1, true) -- LookLeftRight DisableControlAction(0, 2, true) -- LookUpDown @@ -117,8 +119,9 @@ Citizen.CreateThread(function() DisableControlAction(0, 143, true) -- disable melee DisableControlAction(0, 75, true) -- disable exit vehicle DisableControlAction(27, 75, true) -- disable exit vehicle + else + Citizen.Wait(500) end - Citizen.Wait(10) end end) diff --git a/server/main.lua b/server/main.lua index 7fc76471..d3112b89 100644 --- a/server/main.lua +++ b/server/main.lua @@ -36,6 +36,7 @@ end function getCharacters(source, callback) local identifier = GetPlayerIdentifiers(source)[1] + MySQL.Async.fetchAll('SELECT * FROM `characters` WHERE `identifier` = @identifier', { ['@identifier'] = identifier }, function(result) @@ -159,9 +160,11 @@ function setIdentity(identifier, data, callback) }) end -function updateIdentity(identifier, data, callback) +function updateIdentity(playerId, data, callback) + local xPlayer = ESX.GetPlayerFromId(playerId) + MySQL.Async.execute('UPDATE `users` SET `firstname` = @firstname, `lastname` = @lastname, `dateofbirth` = @dateofbirth, `sex` = @sex, `height` = @height WHERE identifier = @identifier', { - ['@identifier'] = identifier, + ['@identifier'] = xPlayer.identifier, ['@firstname'] = data.firstname, ['@lastname'] = data.lastname, ['@dateofbirth'] = data.dateofbirth, @@ -169,6 +172,9 @@ function updateIdentity(identifier, data, callback) ['@height'] = data.height }, function(rowsChanged) if callback then + xPlayer.set('firstName', data.firstname) + xPlayer.set('lastName', data.lastname) + xPlayer.setName(('%s %s'):format(data.firstname, data.lastname)) callback(true) end end) @@ -194,53 +200,69 @@ AddEventHandler('esx_identity:setIdentity', function(data, myIdentifiers) setIdentity(myIdentifiers.steamid, data, function(callback) if callback then TriggerClientEvent('esx_identity:identityCheck', myIdentifiers.playerid, true) + + local xPlayer = ESX.GetPlayerFromId(myIdentifiers.playerid) + xPlayer.set('firstName', data.firstname) + xPlayer.set('lastName', data.lastname) + xPlayer.setName(('%s %s'):format(data.firstname, data.lastname)) else - TriggerClientEvent('chat:addMessage', source, { args = { '^[IDENTITY]', 'Failed to set character, try again later or contact the server admin!' } }) + TriggerClientEvent('chat:addMessage', myIdentifiers.playerid, { args = { '^1[IDENTITY]', 'Failed to set character, try again later or contact the server admin!' } }) end end) end) -AddEventHandler('es:playerLoaded', function(source) +AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) local myID = { - steamid = GetPlayerIdentifiers(source)[1], - playerid = source + steamid = xPlayer.identifier, + playerid = playerId } - TriggerClientEvent('esx_identity:saveID', source, myID) - getIdentity(source, function(data) + TriggerClientEvent('esx_identity:saveID', playerId, myID) + + getIdentity(playerId, function(data) if data.firstname == '' then - TriggerClientEvent('esx_identity:identityCheck', source, false) - TriggerClientEvent('esx_identity:showRegisterIdentity', source) + TriggerClientEvent('esx_identity:identityCheck', playerId, false) + TriggerClientEvent('esx_identity:showRegisterIdentity', playerId) else - TriggerClientEvent('esx_identity:identityCheck', source, true) + TriggerClientEvent('esx_identity:identityCheck', playerId, true) + + xPlayer.set('firstName', data.firstname) + xPlayer.set('lastName', data.lastname) + xPlayer.setName(('%s %s'):format(data.firstname, data.lastname)) end end) end) +-- Set all the client side variables for connected users one new time AddEventHandler('onResourceStart', function(resource) if resource == GetCurrentResourceName() then Citizen.Wait(3000) + local xPlayers = ESX.GetPlayers() - -- Set all the client side variables for connected users one new time - local xPlayers, xPlayer = ESX.GetPlayers() for i=1, #xPlayers, 1 do - xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) - local myID = { - steamid = xPlayer.identifier, - playerid = xPlayer.source - } + if xPlayer then + local myID = { + steamid = xPlayer.identifier, + playerid = xPlayer.source + } + + TriggerClientEvent('esx_identity:saveID', xPlayer.source, myID) + + getIdentity(xPlayer.source, function(data) + if data.firstname == '' then + TriggerClientEvent('esx_identity:identityCheck', xPlayer.source, false) + TriggerClientEvent('esx_identity:showRegisterIdentity', xPlayer.source) + else + TriggerClientEvent('esx_identity:identityCheck', xPlayer.source, true) - TriggerClientEvent('esx_identity:saveID', xPlayer.source, myID) - - getIdentity(xPlayer.source, function(data) - if data.firstname == '' then - TriggerClientEvent('esx_identity:identityCheck', xPlayer.source, false) - TriggerClientEvent('esx_identity:showRegisterIdentity', xPlayer.source) - else - TriggerClientEvent('esx_identity:identityCheck', xPlayer.source, true) - end - end) + xPlayer.set('firstName', data.firstname) + xPlayer.set('lastName', data.lastname) + xPlayer.setName(('%s %s'):format(data.firstname, data.lastname)) + end + end) + end end end end) @@ -248,9 +270,9 @@ end) TriggerEvent('es:addCommand', 'register', function(source, args, user) getCharacters(source, function(data) if data.firstname3 ~= '' then - TriggerClientEvent('chat:addMessage', source, { args = { '^[IDENTITY]', 'You can only have 3 registered characters. Use the ^3/chardel^0 command in order to delete existing characters.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'You can only have 3 registered characters. Use the ^3/chardel^0 command in order to delete existing characters.' } }) else - TriggerClientEvent('esx_identity:showRegisterIdentity', source, {}) + TriggerClientEvent('esx_identity:showRegisterIdentity', source) end end) end, {help = "Register a new character"}) @@ -280,7 +302,7 @@ TriggerEvent('es:addGroupCommand', 'charlist', 'user', function(source, args, us end end else - TriggerClientEvent('chat:addMessage', source, { args = { '^[IDENTITY]', 'You have no registered characters. Use the ^3/register^0 command to register a character.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'You have no registered characters. Use the ^3/register^0 command to register a character.' } }) end end) end, function(source, args, user) @@ -291,7 +313,7 @@ TriggerEvent('es:addGroupCommand', 'charselect', 'user', function(source, args, local charNumber = tonumber(args[1]) if charNumber == nil or charNumber > 3 or charNumber < 1 then - TriggerClientEvent('chat:addMessage', source, { args = { '^[IDENTITY]', 'That\'s an invalid character!' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'That\'s an invalid character!' } }) return end @@ -307,7 +329,8 @@ TriggerEvent('es:addGroupCommand', 'charselect', 'user', function(source, args, } if data.firstname ~= '' then - updateIdentity(GetPlayerIdentifiers(source)[1], data, function(callback) + updateIdentity(source, data, function(callback) + if callback then TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'Updated your active character to ^2' .. data.firstname .. ' ' .. data.lastname } }) else @@ -329,7 +352,7 @@ TriggerEvent('es:addGroupCommand', 'charselect', 'user', function(source, args, } if data.firstname ~= '' then - updateIdentity(GetPlayerIdentifiers(source)[1], data, function(callback) + updateIdentity(source, data, function(callback) if callback then TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'Updated your active character to ^2' .. data.firstname .. ' ' .. data.lastname } }) @@ -352,7 +375,8 @@ TriggerEvent('es:addGroupCommand', 'charselect', 'user', function(source, args, } if data.firstname ~= '' then - updateIdentity(GetPlayerIdentifiers(source)[1], data, function(callback) + updateIdentity(source, data, function(callback) + if callback then TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'Updated your active character to ^2' .. data.firstname .. ' ' .. data.lastname } }) else @@ -375,7 +399,7 @@ TriggerEvent('es:addGroupCommand', 'chardel', 'user', function(source, args, use local charNumber = tonumber(args[1]) if charNumber == nil or charNumber > 3 or charNumber < 1 then - TriggerClientEvent('chat:addMessage', source, { args = { '^[IDENTITY]', 'That\'s an invalid character!' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'That\'s an invalid character!' } }) return end From 5f4a78330b509af2b94cac058ff2a2d0057b80ac Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 11:08:08 +0100 Subject: [PATCH 2391/3224] Set missing info and added new event handler --- server/main.lua | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/server/main.lua b/server/main.lua index d3112b89..27c243c2 100644 --- a/server/main.lua +++ b/server/main.lua @@ -172,9 +172,7 @@ function updateIdentity(playerId, data, callback) ['@height'] = data.height }, function(rowsChanged) if callback then - xPlayer.set('firstName', data.firstname) - xPlayer.set('lastName', data.lastname) - xPlayer.setName(('%s %s'):format(data.firstname, data.lastname)) + TriggerEvent('esx_identity:characterUpdated', playerId, data) callback(true) end end) @@ -200,11 +198,7 @@ AddEventHandler('esx_identity:setIdentity', function(data, myIdentifiers) setIdentity(myIdentifiers.steamid, data, function(callback) if callback then TriggerClientEvent('esx_identity:identityCheck', myIdentifiers.playerid, true) - - local xPlayer = ESX.GetPlayerFromId(myIdentifiers.playerid) - xPlayer.set('firstName', data.firstname) - xPlayer.set('lastName', data.lastname) - xPlayer.setName(('%s %s'):format(data.firstname, data.lastname)) + TriggerEvent('esx_identity:characterUpdated', myIdentifiers.playerid, data) else TriggerClientEvent('chat:addMessage', myIdentifiers.playerid, { args = { '^1[IDENTITY]', 'Failed to set character, try again later or contact the server admin!' } }) end @@ -225,14 +219,24 @@ AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) TriggerClientEvent('esx_identity:showRegisterIdentity', playerId) else TriggerClientEvent('esx_identity:identityCheck', playerId, true) - - xPlayer.set('firstName', data.firstname) - xPlayer.set('lastName', data.lastname) - xPlayer.setName(('%s %s'):format(data.firstname, data.lastname)) + TriggerEvent('esx_identity:characterUpdated', playerId, data) end end) end) +AddEventHandler('esx_identity:characterUpdated', function(playerId, data) + local xPlayer = ESX.GetPlayerFromId(playerId) + + if xPlayer then + xPlayer.setName(('%s %s'):format(data.firstname, data.lastname)) + xPlayer.set('firstName', data.firstname) + xPlayer.set('lastName', data.lastname) + xPlayer.set('dateofbirth', data.dateofbirth) + xPlayer.set('sex', data.sex) + xPlayer.set('height', data.height) + end +end) + -- Set all the client side variables for connected users one new time AddEventHandler('onResourceStart', function(resource) if resource == GetCurrentResourceName() then @@ -256,10 +260,7 @@ AddEventHandler('onResourceStart', function(resource) TriggerClientEvent('esx_identity:showRegisterIdentity', xPlayer.source) else TriggerClientEvent('esx_identity:identityCheck', xPlayer.source, true) - - xPlayer.set('firstName', data.firstname) - xPlayer.set('lastName', data.lastname) - xPlayer.setName(('%s %s'):format(data.firstname, data.lastname)) + TriggerEvent('esx_identity:characterUpdated', xPlayer.source, data) end end) end From 1d83a1f2f46c2ea324c0b4196310dcfac68435c1 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 11:54:19 +0100 Subject: [PATCH 2392/3224] Updated native names, added optional values (read desc) Added flash and saveToBreif booleans to ESX.ShowNotification() and ESX.ShowHelpNotification() Added two optional booleans thisFrame, beep to ShowHelpNotification() and last new optional argument duration --- client/functions.lua | 39 +++++++++++++++++++++------------------ server/classes/player.lua | 8 ++++---- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index c5e2021d..854b0b40 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -44,25 +44,28 @@ ESX.SetPlayerData = function(key, val) ESX.PlayerData[key] = val end -ESX.ShowNotification = function(msg) +ESX.ShowNotification = function(msg, flash, saveToBrief) AddTextEntry('esxNotification', msg) - SetNotificationTextEntry('esxNotification') - DrawNotification(false, true) + BeginTextCommandThefeedPost('esxNotification') + EndTextCommandThefeedPostTicker(flash or false, saveToBrief or true) end -ESX.ShowAdvancedNotification = function(title, subject, msg, icon, iconType) +ESX.ShowAdvancedNotification = function(sender, subject, msg, textureDict, iconType, flash, saveToBrief) AddTextEntry('esxAdvancedNotification', msg) - SetNotificationTextEntry('esxAdvancedNotification') - SetNotificationMessage(icon, icon, false, iconType, title, subject) - DrawNotification(false, false) + BeginTextCommandThefeedPost('esxAdvancedNotification') + EndTextCommandThefeedPostMessagetext(textureDict, textureDict, false, iconType, sender, subject) + EndTextCommandThefeedPostTicker(flash, saveToBrief) end -ESX.ShowHelpNotification = function(msg) - --if not IsHelpMessageBeingDisplayed() then - AddTextEntry('esxHelpNotification', msg) +ESX.ShowHelpNotification = function(msg, thisFrame, beep, duration) + AddTextEntry('esxHelpNotification', msg) + + if thisFrame then + DisplayHelpTextThisFrame('esxHelpNotification', true) + else BeginTextCommandDisplayHelp('esxHelpNotification') - EndTextCommandDisplayHelp(0, false, true, -1) - --end + EndTextCommandDisplayHelp(0, false, beep or true, duration or -1) + end end ESX.TriggerServerCallback = function(name, cb, ...) @@ -1104,18 +1107,18 @@ AddEventHandler('esx:serverCallback', function(requestId, ...) end) RegisterNetEvent('esx:showNotification') -AddEventHandler('esx:showNotification', function(msg) - ESX.ShowNotification(msg) +AddEventHandler('esx:showNotification', function(msg, flash, saveToBrief) + ESX.ShowNotification(msg, flash, saveToBrief) end) RegisterNetEvent('esx:showAdvancedNotification') -AddEventHandler('esx:showAdvancedNotification', function(title, subject, msg, icon, iconType) - ESX.ShowAdvancedNotification(title, subject, msg, icon, iconType) +AddEventHandler('esx:showAdvancedNotification', function(sender, subject, msg, textureDict, iconType, flash, saveToBrief) + ESX.ShowAdvancedNotification(sender, subject, msg, textureDict, iconType, flash, saveToBrief) end) RegisterNetEvent('esx:showHelpNotification') -AddEventHandler('esx:showHelpNotification', function(msg) - ESX.ShowHelpNotification(msg) +AddEventHandler('esx:showHelpNotification', function(msg, thisFrame, beep, duration) + ESX.ShowHelpNotification(msg, thisFrame, beep, duration) end) -- SetTimeout diff --git a/server/classes/player.lua b/server/classes/player.lua index 851bb397..6909b5c8 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -531,12 +531,12 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c return end - self.showNotification = function(msg) - self.triggerEvent('esx:showNotification', msg) + self.showNotification = function(msg, flash, saveToBrief) + self.triggerEvent('esx:showNotification', msg, flash, saveToBrief) end - self.showHelpNotification = function(msg) - self.triggerEvent('esx:showHelpNotification', msg) + self.showHelpNotification = function(msg, thisFrame, beep, duration) + self.triggerEvent('esx:showHelpNotification', msg, thisFrame, beep, duration) end return self From c345d40374194ef7c2becca7e27bd183fac28239 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 12:11:37 +0100 Subject: [PATCH 2393/3224] Disable DisplayHelpTextThisFrame saveToBreif, fixed code --- client/functions.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 854b0b40..ec5e3b29 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -45,9 +45,10 @@ ESX.SetPlayerData = function(key, val) end ESX.ShowNotification = function(msg, flash, saveToBrief) + if saveToBrief == nil then saveToBrief = true end AddTextEntry('esxNotification', msg) BeginTextCommandThefeedPost('esxNotification') - EndTextCommandThefeedPostTicker(flash or false, saveToBrief or true) + EndTextCommandThefeedPostTicker(flash or false, saveToBrief) end ESX.ShowAdvancedNotification = function(sender, subject, msg, textureDict, iconType, flash, saveToBrief) @@ -61,10 +62,11 @@ ESX.ShowHelpNotification = function(msg, thisFrame, beep, duration) AddTextEntry('esxHelpNotification', msg) if thisFrame then - DisplayHelpTextThisFrame('esxHelpNotification', true) + DisplayHelpTextThisFrame('esxHelpNotification', false) else + if beep == nil then beep = true end BeginTextCommandDisplayHelp('esxHelpNotification') - EndTextCommandDisplayHelp(0, false, beep or true, duration or -1) + EndTextCommandDisplayHelp(0, false, beep, duration or -1) end end From 60fd7e317ba6aa363f152429e4f918a9e2b7b8d9 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 12:18:39 +0100 Subject: [PATCH 2394/3224] Added optional notification background color arugment Co-Authored-By: WolfShy1 --- client/functions.lua | 14 ++++++++------ server/classes/player.lua | 4 ++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index ec5e3b29..c14e9643 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -44,16 +44,18 @@ ESX.SetPlayerData = function(key, val) ESX.PlayerData[key] = val end -ESX.ShowNotification = function(msg, flash, saveToBrief) +ESX.ShowNotification = function(msg, flash, saveToBrief, hudColorIndex) if saveToBrief == nil then saveToBrief = true end AddTextEntry('esxNotification', msg) BeginTextCommandThefeedPost('esxNotification') + if hudColorIndex then ThefeedNextPostBackgroundColor(hudColorIndex) end EndTextCommandThefeedPostTicker(flash or false, saveToBrief) end -ESX.ShowAdvancedNotification = function(sender, subject, msg, textureDict, iconType, flash, saveToBrief) +ESX.ShowAdvancedNotification = function(sender, subject, msg, textureDict, iconType, flash, saveToBrief, hudColorIndex) AddTextEntry('esxAdvancedNotification', msg) BeginTextCommandThefeedPost('esxAdvancedNotification') + if hudColorIndex then ThefeedNextPostBackgroundColor(hudColorIndex) end EndTextCommandThefeedPostMessagetext(textureDict, textureDict, false, iconType, sender, subject) EndTextCommandThefeedPostTicker(flash, saveToBrief) end @@ -1109,13 +1111,13 @@ AddEventHandler('esx:serverCallback', function(requestId, ...) end) RegisterNetEvent('esx:showNotification') -AddEventHandler('esx:showNotification', function(msg, flash, saveToBrief) - ESX.ShowNotification(msg, flash, saveToBrief) +AddEventHandler('esx:showNotification', function(msg, flash, saveToBrief, hudColorIndex) + ESX.ShowNotification(msg, flash, saveToBrief, hudColorIndex) end) RegisterNetEvent('esx:showAdvancedNotification') -AddEventHandler('esx:showAdvancedNotification', function(sender, subject, msg, textureDict, iconType, flash, saveToBrief) - ESX.ShowAdvancedNotification(sender, subject, msg, textureDict, iconType, flash, saveToBrief) +AddEventHandler('esx:showAdvancedNotification', function(sender, subject, msg, textureDict, iconType, flash, saveToBrief, hudColorIndex) + ESX.ShowAdvancedNotification(sender, subject, msg, textureDict, iconType, flash, saveToBrief, hudColorIndex) end) RegisterNetEvent('esx:showHelpNotification') diff --git a/server/classes/player.lua b/server/classes/player.lua index 6909b5c8..f612d74c 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -531,8 +531,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c return end - self.showNotification = function(msg, flash, saveToBrief) - self.triggerEvent('esx:showNotification', msg, flash, saveToBrief) + self.showNotification = function(msg, flash, saveToBrief, hudColorIndex) + self.triggerEvent('esx:showNotification', msg, flash, saveToBrief, hudColorIndex) end self.showHelpNotification = function(msg, thisFrame, beep, duration) From 0d4377042d9ed2ba974305e99493a0e4fdefd420 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 12:33:55 +0100 Subject: [PATCH 2395/3224] Update functions.lua --- client/functions.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/functions.lua b/client/functions.lua index c14e9643..884254a4 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -53,11 +53,12 @@ ESX.ShowNotification = function(msg, flash, saveToBrief, hudColorIndex) end ESX.ShowAdvancedNotification = function(sender, subject, msg, textureDict, iconType, flash, saveToBrief, hudColorIndex) + if saveToBrief == nil then saveToBrief = true end AddTextEntry('esxAdvancedNotification', msg) BeginTextCommandThefeedPost('esxAdvancedNotification') if hudColorIndex then ThefeedNextPostBackgroundColor(hudColorIndex) end EndTextCommandThefeedPostMessagetext(textureDict, textureDict, false, iconType, sender, subject) - EndTextCommandThefeedPostTicker(flash, saveToBrief) + EndTextCommandThefeedPostTicker(flash or false, saveToBrief) end ESX.ShowHelpNotification = function(msg, thisFrame, beep, duration) From 0fbd5d03a21d9290472738c2895ea7f6713e45aa Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 14:10:57 +0100 Subject: [PATCH 2396/3224] Minor changes, fixed giving weapon? --- client/functions.lua | 43 ++++++++++++++++++++++--------------------- server/main.lua | 2 +- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 884254a4..10dd84d5 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -278,13 +278,17 @@ ESX.UI.ShowInventoryItemNotification = function(add, item, count) end ESX.Game.GetPedMugshot = function(ped) - local mugshot = RegisterPedheadshot(ped) + if DoesEntityExist(ped) then + local mugshot = RegisterPedheadshot(ped) - while not IsPedheadshotReady(mugshot) do - Citizen.Wait(0) + while not IsPedheadshotReady(mugshot) do + Citizen.Wait(0) + end + + return mugshot, GetPedheadshotTxdString(mugshot) + else + return end - - return mugshot, GetPedheadshotTxdString(mugshot) end ESX.Game.Teleport = function(entity, coords, cb) @@ -512,15 +516,14 @@ ESX.Game.GetClosestPlayer = function(coords) end ESX.Game.GetPlayersInArea = function(coords, area) - local players = ESX.Game.GetPlayers() - local playersInArea = {} + local players, playersInArea = ESX.Game.GetPlayers(), {} + coords = vector3(coords.x, coords.y, coords.z) for i=1, #players, 1 do - local target = GetPlayerPed(players[i]) + local target = GetPlayerPed(players[i]) local targetCoords = GetEntityCoords(target) - local distance = GetDistanceBetweenCoords(targetCoords, coords.x, coords.y, coords.z, true) - if distance <= area then + if #(coords - targetCoords) <= area then table.insert(playersInArea, players[i]) end end @@ -539,23 +542,22 @@ ESX.Game.GetVehicles = function() end ESX.Game.GetClosestVehicle = function(coords) - local vehicles = ESX.Game.GetVehicles() - local closestDistance = -1 - local closestVehicle = -1 - local coords = coords + local vehicles = ESX.Game.GetVehicles() + local closestDistance, closestVehicle, coords = -1, -1, coords - if coords == nil then + if coords then + coords = vector3(coords.x, coords.y, coords.z) + else local playerPed = PlayerPedId() - coords = GetEntityCoords(playerPed) + coords = GetEntityCoords(playerPed) end for i=1, #vehicles, 1 do local vehicleCoords = GetEntityCoords(vehicles[i]) - local distance = GetDistanceBetweenCoords(vehicleCoords, coords.x, coords.y, coords.z, true) + local distance = #(coords - vehicleCoords) if closestDistance == -1 or closestDistance > distance then - closestVehicle = vehicles[i] - closestDistance = distance + closestVehicle, closestDistance = vehicles[i], distance end end @@ -677,9 +679,8 @@ ESX.Game.GetVehicleProperties = function(vehicle) IsVehicleNeonLightEnabled(vehicle, 3) }, - extras = extras, - neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), + extras = extras, tyreSmokeColor = table.pack(GetVehicleTyreSmokeColor(vehicle)), modSpoilers = GetVehicleMod(vehicle, 0), diff --git a/server/main.lua b/server/main.lua index 643797f0..251dcd6a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -284,7 +284,7 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo local weaponLabel = ESX.GetWeaponLabel(itemName) if not targetXPlayer.hasWeapon(itemName) then - local _,weapon = xPlayer.getWeapon(itemName) + local weaponNum, weapon = xPlayer.getWeapon(itemName) itemCount = weapon.ammo sourceXPlayer.removeWeapon(itemName) From 1e146c32116f3307d06aaaa9c36a43fe76e1a427 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 14:13:15 +0100 Subject: [PATCH 2397/3224] Added entity check for GetVehicleProperties() --- client/functions.lua | 182 ++++++++++++++++++++++--------------------- 1 file changed, 93 insertions(+), 89 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 10dd84d5..edc0ff5f 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -641,98 +641,102 @@ ESX.Game.GetClosestPed = function(coords, ignoreList) end ESX.Game.GetVehicleProperties = function(vehicle) - local colorPrimary, colorSecondary = GetVehicleColours(vehicle) - local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) - local extras = {} + if DoesEntityExist(vehicle) then + local colorPrimary, colorSecondary = GetVehicleColours(vehicle) + local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) + local extras = {} - for id=0, 12 do - if DoesExtraExist(vehicle, id) then - local state = IsVehicleExtraTurnedOn(vehicle, id) == 1 - extras[tostring(id)] = state + for id=0, 12 do + if DoesExtraExist(vehicle, id) then + local state = IsVehicleExtraTurnedOn(vehicle, id) == 1 + extras[tostring(id)] = state + end end + + return { + model = GetEntityModel(vehicle), + + plate = ESX.Math.Trim(GetVehicleNumberPlateText(vehicle)), + plateIndex = GetVehicleNumberPlateTextIndex(vehicle), + + bodyHealth = ESX.Math.Round(GetVehicleBodyHealth(vehicle), 1), + engineHealth = ESX.Math.Round(GetVehicleEngineHealth(vehicle), 1), + + fuelLevel = ESX.Math.Round(GetVehicleFuelLevel(vehicle), 1), + dirtLevel = ESX.Math.Round(GetVehicleDirtLevel(vehicle), 1), + color1 = colorPrimary, + color2 = colorSecondary, + + pearlescentColor = pearlescentColor, + wheelColor = wheelColor, + + wheels = GetVehicleWheelType(vehicle), + windowTint = GetVehicleWindowTint(vehicle), + + neonEnabled = { + IsVehicleNeonLightEnabled(vehicle, 0), + IsVehicleNeonLightEnabled(vehicle, 1), + IsVehicleNeonLightEnabled(vehicle, 2), + IsVehicleNeonLightEnabled(vehicle, 3) + }, + + neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), + extras = extras, + tyreSmokeColor = table.pack(GetVehicleTyreSmokeColor(vehicle)), + + modSpoilers = GetVehicleMod(vehicle, 0), + modFrontBumper = GetVehicleMod(vehicle, 1), + modRearBumper = GetVehicleMod(vehicle, 2), + modSideSkirt = GetVehicleMod(vehicle, 3), + modExhaust = GetVehicleMod(vehicle, 4), + modFrame = GetVehicleMod(vehicle, 5), + modGrille = GetVehicleMod(vehicle, 6), + modHood = GetVehicleMod(vehicle, 7), + modFender = GetVehicleMod(vehicle, 8), + modRightFender = GetVehicleMod(vehicle, 9), + modRoof = GetVehicleMod(vehicle, 10), + + modEngine = GetVehicleMod(vehicle, 11), + modBrakes = GetVehicleMod(vehicle, 12), + modTransmission = GetVehicleMod(vehicle, 13), + modHorns = GetVehicleMod(vehicle, 14), + modSuspension = GetVehicleMod(vehicle, 15), + modArmor = GetVehicleMod(vehicle, 16), + + modTurbo = IsToggleModOn(vehicle, 18), + modSmokeEnabled = IsToggleModOn(vehicle, 20), + modXenon = IsToggleModOn(vehicle, 22), + + modFrontWheels = GetVehicleMod(vehicle, 23), + modBackWheels = GetVehicleMod(vehicle, 24), + + modPlateHolder = GetVehicleMod(vehicle, 25), + modVanityPlate = GetVehicleMod(vehicle, 26), + modTrimA = GetVehicleMod(vehicle, 27), + modOrnaments = GetVehicleMod(vehicle, 28), + modDashboard = GetVehicleMod(vehicle, 29), + modDial = GetVehicleMod(vehicle, 30), + modDoorSpeaker = GetVehicleMod(vehicle, 31), + modSeats = GetVehicleMod(vehicle, 32), + modSteeringWheel = GetVehicleMod(vehicle, 33), + modShifterLeavers = GetVehicleMod(vehicle, 34), + modAPlate = GetVehicleMod(vehicle, 35), + modSpeakers = GetVehicleMod(vehicle, 36), + modTrunk = GetVehicleMod(vehicle, 37), + modHydrolic = GetVehicleMod(vehicle, 38), + modEngineBlock = GetVehicleMod(vehicle, 39), + modAirFilter = GetVehicleMod(vehicle, 40), + modStruts = GetVehicleMod(vehicle, 41), + modArchCover = GetVehicleMod(vehicle, 42), + modAerials = GetVehicleMod(vehicle, 43), + modTrimB = GetVehicleMod(vehicle, 44), + modTank = GetVehicleMod(vehicle, 45), + modWindows = GetVehicleMod(vehicle, 46), + modLivery = GetVehicleLivery(vehicle) + } + else + return end - - return { - model = GetEntityModel(vehicle), - - plate = ESX.Math.Trim(GetVehicleNumberPlateText(vehicle)), - plateIndex = GetVehicleNumberPlateTextIndex(vehicle), - - bodyHealth = ESX.Math.Round(GetVehicleBodyHealth(vehicle), 1), - engineHealth = ESX.Math.Round(GetVehicleEngineHealth(vehicle), 1), - - fuelLevel = ESX.Math.Round(GetVehicleFuelLevel(vehicle), 1), - dirtLevel = ESX.Math.Round(GetVehicleDirtLevel(vehicle), 1), - color1 = colorPrimary, - color2 = colorSecondary, - - pearlescentColor = pearlescentColor, - wheelColor = wheelColor, - - wheels = GetVehicleWheelType(vehicle), - windowTint = GetVehicleWindowTint(vehicle), - - neonEnabled = { - IsVehicleNeonLightEnabled(vehicle, 0), - IsVehicleNeonLightEnabled(vehicle, 1), - IsVehicleNeonLightEnabled(vehicle, 2), - IsVehicleNeonLightEnabled(vehicle, 3) - }, - - neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), - extras = extras, - tyreSmokeColor = table.pack(GetVehicleTyreSmokeColor(vehicle)), - - modSpoilers = GetVehicleMod(vehicle, 0), - modFrontBumper = GetVehicleMod(vehicle, 1), - modRearBumper = GetVehicleMod(vehicle, 2), - modSideSkirt = GetVehicleMod(vehicle, 3), - modExhaust = GetVehicleMod(vehicle, 4), - modFrame = GetVehicleMod(vehicle, 5), - modGrille = GetVehicleMod(vehicle, 6), - modHood = GetVehicleMod(vehicle, 7), - modFender = GetVehicleMod(vehicle, 8), - modRightFender = GetVehicleMod(vehicle, 9), - modRoof = GetVehicleMod(vehicle, 10), - - modEngine = GetVehicleMod(vehicle, 11), - modBrakes = GetVehicleMod(vehicle, 12), - modTransmission = GetVehicleMod(vehicle, 13), - modHorns = GetVehicleMod(vehicle, 14), - modSuspension = GetVehicleMod(vehicle, 15), - modArmor = GetVehicleMod(vehicle, 16), - - modTurbo = IsToggleModOn(vehicle, 18), - modSmokeEnabled = IsToggleModOn(vehicle, 20), - modXenon = IsToggleModOn(vehicle, 22), - - modFrontWheels = GetVehicleMod(vehicle, 23), - modBackWheels = GetVehicleMod(vehicle, 24), - - modPlateHolder = GetVehicleMod(vehicle, 25), - modVanityPlate = GetVehicleMod(vehicle, 26), - modTrimA = GetVehicleMod(vehicle, 27), - modOrnaments = GetVehicleMod(vehicle, 28), - modDashboard = GetVehicleMod(vehicle, 29), - modDial = GetVehicleMod(vehicle, 30), - modDoorSpeaker = GetVehicleMod(vehicle, 31), - modSeats = GetVehicleMod(vehicle, 32), - modSteeringWheel = GetVehicleMod(vehicle, 33), - modShifterLeavers = GetVehicleMod(vehicle, 34), - modAPlate = GetVehicleMod(vehicle, 35), - modSpeakers = GetVehicleMod(vehicle, 36), - modTrunk = GetVehicleMod(vehicle, 37), - modHydrolic = GetVehicleMod(vehicle, 38), - modEngineBlock = GetVehicleMod(vehicle, 39), - modAirFilter = GetVehicleMod(vehicle, 40), - modStruts = GetVehicleMod(vehicle, 41), - modArchCover = GetVehicleMod(vehicle, 42), - modAerials = GetVehicleMod(vehicle, 43), - modTrimB = GetVehicleMod(vehicle, 44), - modTank = GetVehicleMod(vehicle, 45), - modWindows = GetVehicleMod(vehicle, 46), - modLivery = GetVehicleLivery(vehicle) - } end ESX.Game.SetVehicleProperties = function(vehicle, props) From 06eb61fa2ae206a21baa8426b8a2f560ab7e7f37 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 15:04:15 +0100 Subject: [PATCH 2398/3224] Fixed random vehicle colors --- client/functions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/functions.lua b/client/functions.lua index edc0ff5f..8f020a8a 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -752,7 +752,7 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) if props.fuelLevel then SetVehicleFuelLevel(vehicle, props.fuelLevel + 0.0) end if props.dirtLevel then SetVehicleDirtLevel(vehicle, props.dirtLevel + 0.0) end if props.color1 then SetVehicleColours(vehicle, props.color1, colorSecondary) end - if props.color2 then SetVehicleColours(vehicle, colorPrimary, props.color2) end + if props.color2 then SetVehicleColours(vehicle, props.color1 or colorPrimary, props.color2) end if props.pearlescentColor then SetVehicleExtraColours(vehicle, props.pearlescentColor, wheelColor) end if props.wheelColor then SetVehicleExtraColours(vehicle, pearlescentColor, props.wheelColor) end if props.wheels then SetVehicleWheelType(vehicle, props.wheels) end From 32f8a2d45d9c6f052dd18f3194c23afa0c963691 Mon Sep 17 00:00:00 2001 From: maiconkkl Date: Wed, 15 Jan 2020 16:41:55 -0300 Subject: [PATCH 2399/3224] Create SqlTranslate (#175) --- localization/br_esx_ambulancejob.sql | 33 ++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 localization/br_esx_ambulancejob.sql diff --git a/localization/br_esx_ambulancejob.sql b/localization/br_esx_ambulancejob.sql new file mode 100644 index 00000000..98357560 --- /dev/null +++ b/localization/br_esx_ambulancejob.sql @@ -0,0 +1,33 @@ +USE `essentialmode`; + +INSERT INTO `addon_account` (name, label, shared) VALUES + ('society_ambulance', 'EMS', 1) +; + +INSERT INTO `addon_inventory` (name, label, shared) VALUES + ('society_ambulance', 'EMS', 1) +; + +INSERT INTO `datastore` (name, label, shared) VALUES + ('society_ambulance', 'EMS', 1) +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('ambulance',0,'ambulância','Jr. EMT',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}'), + ('ambulance',1,'medico','EMT',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}'), + ('ambulance',2,'medico chefe','Sr. EMT',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}'), + ('ambulance',3,'boss','EMT Supervisor',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}') +; + +INSERT INTO `jobs` (name, label) VALUES + ('ambulance','EMS') +; + +INSERT INTO `items` (name, label, weight) VALUES + ('bandage','curativo', 2), + ('medikit','kit medico', 2) +; + +ALTER TABLE `users` + ADD `is_dead` TINYINT(1) NULL DEFAULT '0' +; From d94522fbbe50c0db4a35809bb6393d10b0011f25 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 20:43:40 +0100 Subject: [PATCH 2400/3224] Fixed #177 --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 6da561e6..b9b7afc0 100644 --- a/server/main.lua +++ b/server/main.lua @@ -229,7 +229,7 @@ end) TriggerEvent('es:addGroupCommand', 'revive', 'admin', function(source, args, user) if args[1] then local playerId = tonumber(args[1]) - if playerId and ESX.Players[playerId] then + if playerId and ESX.GetPlayerFromId(playerId) then TriggerClientEvent('esx_ambulancejob:revive', playerId) else TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) From d76f9352816546cc7557b1925bfc7e552f0151e8 Mon Sep 17 00:00:00 2001 From: maiconkkl Date: Wed, 15 Jan 2020 16:45:50 -0300 Subject: [PATCH 2401/3224] Added Portuguese translation (#13) * Correcting and improving translation * Correcting and improving translation * Update br.lua --- __resource.lua | 1 + locales/br.lua | 9 +++++++++ 2 files changed, 10 insertions(+) create mode 100644 locales/br.lua diff --git a/__resource.lua b/__resource.lua index 35ea7766..75959689 100644 --- a/__resource.lua +++ b/__resource.lua @@ -8,6 +8,7 @@ server_scripts { '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', 'config.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'locales/sv.lua', diff --git a/locales/br.lua b/locales/br.lua new file mode 100644 index 00000000..0f442a3c --- /dev/null +++ b/locales/br.lua @@ -0,0 +1,9 @@ +Locales['br'] = { + ['whitelist_check'] = 'certificando-se de que você está na lista de permitidos(whitelist) neste servidor. . .', + ['not_whitelisted'] = 'você não está na lista de permitidos(whitelist) neste servidor', + ['steamid_error'] = 'seu ID do Steam não foi encontrado, o Steam está aberto?', + ['whitelist_empty'] = 'a lista de permitidos(whitelist) ainda não foi carregada ou ninguém foi incluído!', + ['help_whitelist_add'] = 'adicionar alguém à lista de permitidos(whitelist) no servidor', + ['help_whitelist_load'] = 'recarregar a lista de permitidos(whitelist)', +} + From 5d924d4b8ad7ebcda433267f7ad5953ce2f91199 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 21:48:13 +0100 Subject: [PATCH 2402/3224] Use canSwapItem() test --- README.md | 2 +- server/main.lua | 34 ++++++++++++++++++---------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index bb1588a3..0dd5146c 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ start esx_drugs ### License esx_drugs - drugs job -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. diff --git a/server/main.lua b/server/main.lua index 7edbbf2a..26c13db0 100644 --- a/server/main.lua +++ b/server/main.lua @@ -76,28 +76,30 @@ AddEventHandler('esx_drugs:processCannabis', function() local xPlayer = ESX.GetPlayerFromId(_source) local xCannabis = xPlayer.getInventoryItem('cannabis') - if not xPlayer.canCarryItem('marijuana', 1) then - xPlayer.showNotification(_U('weed_processingfull')) - elseif xCannabis.count < 3 then - xPlayer.showNotification(_U('weed_processingenough')) + if xCannabis.count > 3 then + if xPlayer.canSwapItem('cannabis', 3, 'marijuana', 1) then + xPlayer.removeInventoryItem('cannabis', 3) + xPlayer.addInventoryItem('marijuana', 1) + + xPlayer.showNotification(_U('weed_processed')) + else + xPlayer.showNotification(_U('weed_processingfull')) + playersProcessingCannabis[_source] = nil + end else - xPlayer.removeInventoryItem('cannabis', 3) - xPlayer.addInventoryItem('marijuana', 1) - - xPlayer.showNotification(_U('weed_processed')) + xPlayer.showNotification(_U('weed_processingenough')) + playersProcessingCannabis[_source] = nil end - - playersProcessingCannabis[_source] = nil end) else print(('esx_drugs: %s attempted to exploit weed processing!'):format(GetPlayerIdentifiers(source)[1])) end end) -function CancelProcessing(playerID) - if playersProcessingCannabis[playerID] then - ESX.ClearTimeout(playersProcessingCannabis[playerID]) - playersProcessingCannabis[playerID] = nil +function CancelProcessing(playerId) + if playersProcessingCannabis[playerId] then + ESX.ClearTimeout(playersProcessingCannabis[playerId]) + playersProcessingCannabis[playerId] = nil end end @@ -106,8 +108,8 @@ AddEventHandler('esx_drugs:cancelProcessing', function() CancelProcessing(source) end) -AddEventHandler('esx:playerDropped', function(playerID, reason) - CancelProcessing(playerID) +AddEventHandler('esx:playerDropped', function(playerId, reason) + CancelProcessing(playerId) end) RegisterServerEvent('esx:onPlayerDeath') From 7120de4ab5df55e4ccf11647366248da581ea457 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 21:49:17 +0100 Subject: [PATCH 2403/3224] Update esx_drugs.sql --- esx_drugs.sql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/esx_drugs.sql b/esx_drugs.sql index 6981b9e8..aa88673d 100644 --- a/esx_drugs.sql +++ b/esx_drugs.sql @@ -1,10 +1,10 @@ USE `essentialmode`; -INSERT INTO `items` (`name`, `label`, `limit`, `rare`, `can_remove`) VALUES - ('cannabis', 'Cannabis', 40, 0, 1), - ('marijuana', 'Marijuana', 14, 0, 1) +INSERT INTO `items` (`name`, `label`, `weight`, `rare`, `can_remove`) VALUES + ('cannabis', 'Cannabis', 3, 0, 1), + ('marijuana', 'Marijuana', 2, 0, 1) ; INSERT INTO `licenses` (`type`, `label`) VALUES ('weed_processing', 'Weed Processing License') -; \ No newline at end of file +; From 3c5a76eaff446dfe0c4eaed90daa9d1320a69b1d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 21:50:48 +0100 Subject: [PATCH 2404/3224] Update main.lua --- server/main.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/main.lua b/server/main.lua index 26c13db0..49b9d9b6 100644 --- a/server/main.lua +++ b/server/main.lua @@ -38,7 +38,7 @@ ESX.RegisterServerCallback('esx_drugs:buyLicense', function(source, cb, licenseN if license then if xPlayer.getMoney() >= license.price then xPlayer.removeMoney(license.price) - + TriggerEvent('esx_license:addLicense', source, licenseName, function() cb(true) end) @@ -80,16 +80,16 @@ AddEventHandler('esx_drugs:processCannabis', function() if xPlayer.canSwapItem('cannabis', 3, 'marijuana', 1) then xPlayer.removeInventoryItem('cannabis', 3) xPlayer.addInventoryItem('marijuana', 1) - + xPlayer.showNotification(_U('weed_processed')) else xPlayer.showNotification(_U('weed_processingfull')) - playersProcessingCannabis[_source] = nil end else xPlayer.showNotification(_U('weed_processingenough')) - playersProcessingCannabis[_source] = nil end + + playersProcessingCannabis[_source] = nil end) else print(('esx_drugs: %s attempted to exploit weed processing!'):format(GetPlayerIdentifiers(source)[1])) From 99c43b62c0f800da33f05c922b3109b28c168214 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 16 Jan 2020 12:26:31 +0100 Subject: [PATCH 2405/3224] Fixed Teleport function with vector3 types --- client/functions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/functions.lua b/client/functions.lua index 8f020a8a..cb14c356 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -302,7 +302,7 @@ ESX.Game.Teleport = function(entity, coords, cb) SetEntityCoords(entity, coords.x, coords.y, coords.z, false, false, false, false) - if coords.heading then + if type(coords) == 'table' and coords.heading then SetEntityHeading(entity, coords.heading) end end From 35f31af91e0032493cd35b91187bbe1f69c9fc72 Mon Sep 17 00:00:00 2001 From: Michael Douglas Date: Fri, 17 Jan 2020 12:48:14 -0300 Subject: [PATCH 2406/3224] Improved Portuguese locale (#59) * Correcting and improving translation * Update br.lua --- locales/br.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index 170df88a..36d1414f 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,11 +1,11 @@ Locales ['br'] = { - ['buy_license'] = 'buy weapon license?', + ['buy_license'] = 'comprar licença de porte de arma?', ['yes'] = '%s', - ['no'] = 'no', - ['weapon_bought'] = 'purchased for %s EUR', + ['no'] = 'não', + ['weapon_bought'] = 'comprado por %s R$', ['not_enough_black'] = 'você não tem dinheiro sujo suficiente', ['not_enough'] = 'você não tem dinheiro suficiente', - ['already_owned'] = 'you already own this weapon!', + ['already_owned'] = 'você já possui esta arma!', ['shop_menu_title'] = 'comprar', ['shop_menu_prompt'] = 'pressione ~INPUT_CONTEXT~ para comprar armas.', ['shop_menu_item'] = 'R$%s', From f646acc89fe2d83d7e3afb5b7766304921336361 Mon Sep 17 00:00:00 2001 From: Michael Douglas Date: Fri, 17 Jan 2020 12:51:02 -0300 Subject: [PATCH 2407/3224] Added Portuguese locale (#84) * Correcting and improving translation * Update br.lua * Update __resource.lua --- __resource.lua | 2 ++ locales/br.lua | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 locales/br.lua diff --git a/__resource.lua b/__resource.lua index a0ea656d..c83faa79 100644 --- a/__resource.lua +++ b/__resource.lua @@ -7,6 +7,7 @@ version '1.0.4' server_scripts { '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fi.lua', 'locales/fr.lua', @@ -19,6 +20,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fi.lua', 'locales/fr.lua', diff --git a/locales/br.lua b/locales/br.lua new file mode 100644 index 00000000..70d5606a --- /dev/null +++ b/locales/br.lua @@ -0,0 +1,38 @@ +Locales['br'] = { + ['actions'] = 'ações', + ['boss_menu'] = 'menu chefe', + ['money_generic'] = '$%s', + ['deposit_amount'] = 'valor do depósito', + ['deposit_society_money'] = 'depositar dinheiro da sociedade', + ['do_you_want_to_recruit'] = 'você quer recrutar %s?', + ['employee'] = 'empregado', + ['employee_list'] = 'lista de empregados', + ['employee_management'] = 'gestão de funcionários', + ['fire'] = 'fogo', + ['grade'] = 'grau(escolaridade)', + ['have_deposited'] = 'você depositou ~r~$%s~s~', + ['have_withdrawn'] = 'você retirou ~g~$%s~s~', + ['invalid_amount'] = 'montante inválido', + ['invalid_amount_max'] = 'esse salário não é permitido', + ['no'] = 'não', + ['promote'] = 'promover', + ['promote_employee'] = 'promover %s', + ['recruit'] = 'recrutar', + ['recruiting'] = 'recrutamento', + ['salary_amount'] = 'valor do salário', + ['salary_management'] = 'gestão salarial', + ['wash_money'] = 'lavar dinheiro', + ['wash_money_amount'] = 'quantidade a lavar', + ['withdraw_amount'] = 'retirar montante', + ['withdraw_society_money'] = 'retirar dinheiro da sociedade', + ['yes'] = 'sim', + ['you_have'] = 'você tem ~g~$%s~s~ esperando lavagem de dinheiro (24h).', + ['you_have_laundered'] = 'você lavou ~g~$%s~s~ do seu dinheiro ', + ['you_have_hired'] = 'você recrutou %s', + ['you_have_been_hired'] = 'você foi contratado por %s', + ['you_have_fired'] = 'você demitiu %s', + ['you_have_been_fired'] = 'você foi demitido de %s', + ['you_have_promoted'] = 'você promoveu %s a %s', + ['you_have_been_promoted'] = 'você foi promovido ~b~promoted~s~!', +} + From aed8c8afe1493f959a1b5628b8d41a450dcbc89a Mon Sep 17 00:00:00 2001 From: Michael Douglas Date: Fri, 17 Jan 2020 15:53:19 -0300 Subject: [PATCH 2408/3224] Correcting and improving Portuguese locale (#42) * Correcting and improving translation * Update br.lua --- locales/br.lua | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index 3aa61263..7dcaa93c 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -13,7 +13,7 @@ Locales['br'] = { ['hair_color_1'] = 'cor do cabelo 1', ['hair_color_2'] = 'cor do cabelo 2', ['eyebrow_type'] = 'tipo de sobrancelha', - ['eye_color'] = 'eye color', + ['eye_color'] = 'cor dos olhos', ['eyebrow_size'] = 'tamanho da sobrancelha', ['eyebrow_color_1'] = 'cor da sobrancelha 1', ['eyebrow_color_2'] = 'cor da sobrancelha 2', @@ -47,30 +47,30 @@ Locales['br'] = { ['chain_2'] = 'acessórios pescoço 2', ['helmet_1'] = 'capacete 1', ['helmet_2'] = 'capacete 2', - ['watches_1'] = 'watches 1', - ['watches_2'] = 'watches 2', + ['watches_1'] = 'relógios 1', + ['watches_2'] = 'relógios 2', ['bracelets_1'] = 'bracelets 1', ['bracelets_2'] = 'bracelets 2', ['glasses_1'] = 'óculos 1', ['glasses_2'] = 'óculos 2', ['bag'] = 'mochilas', ['bag_color'] = 'cor das mochilas', - ['blemishes'] = 'blemishes', - ['blemishes_size']= 'blemishes thickness', - ['ageing'] = 'ageing', - ['ageing_1'] = 'ageing thickness', + ['blemishes'] = 'manchas', + ['blemishes_size']= 'espessura das manchas', + ['ageing'] = 'envelhecimento', + ['ageing_1'] = 'espessura do envelhecimento', ['blush'] = 'blush', - ['blush_1'] = 'blush thickness', - ['blush_color'] = 'blush color', - ['complexion'] = 'complexion', - ['complexion_1'] = 'complexion thickness', - ['sun'] = 'sun', - ['sun_1'] = 'sun thickness', - ['freckles'] = 'freckles', - ['freckles_1'] = 'freckles thickness', - ['chest_hair'] = 'chest hair', - ['chest_hair_1'] = 'chest hair thickness', - ['chest_color'] = 'chest hair color', - ['bodyb'] = 'body blemishes', - ['bodyb_size'] = 'body blemishes thickness' + ['blush_1'] = 'espessura do blush', + ['blush_color'] = 'cor do blush', + ['complexion'] = 'pele', + ['complexion_1'] = 'pele espessura', + ['sun'] = 'bronzeado', + ['sun_1'] = 'quantidade do bronzeamento', + ['freckles'] = 'sardas', + ['freckles_1'] = 'sardas quantidade', + ['chest_hair'] = 'cabelo no peito', + ['chest_hair_1'] = 'quantidade de cabelo no peito', + ['chest_color'] = 'cor do cabelo no peito', + ['bodyb'] = 'manchas no corpo', + ['bodyb_size'] = 'espessura de manchas do corpo' } From 308889ac32ef478171687bc1f1f03b35db6062e5 Mon Sep 17 00:00:00 2001 From: Michael Douglas Date: Sat, 18 Jan 2020 11:01:00 -0300 Subject: [PATCH 2409/3224] Correcting and improving Portuguese locale (#45) * Correcting and improving translation * Update br.lua --- locales/br.lua | 72 ++++++++++++++++----------------- localization/br_esx_taxijob.sql | 25 ++++++++++++ 2 files changed, 61 insertions(+), 36 deletions(-) create mode 100644 localization/br_esx_taxijob.sql diff --git a/locales/br.lua b/locales/br.lua index 2ba4f59c..68e39f43 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,49 +1,49 @@ Locales['br'] = { -- cloakroom - ['cloakroom_menu'] = 'cloakroom', - ['cloakroom_prompt'] = 'press ~INPUT_CONTEXT~ to open the ~y~cloakroom~s~.', - ['wear_citizen'] = 'citizen wear', - ['wear_work'] = 'taxi wear', + ['cloakroom_menu'] = 'guarda-roupa', + ['cloakroom_prompt'] = 'pressione ~INPUT_CONTEXT~ para abrir o ~y~cloakroom~s~.', + ['wear_citizen'] = 'roupa de cidadão', + ['wear_work'] = 'roupa de taxista', -- garage - ['spawner_prompt'] = 'press ~INPUT_CONTEXT~ to open the ~y~garage~s~.', - ['store_veh'] = 'Pressione ~INPUT_CONTEXT~ para guardar o veículo', + ['spawner_prompt'] = 'pressione ~INPUT_CONTEXT~ para abrir a ~y~garage~s~.', + ['store_veh'] = 'pressione ~INPUT_CONTEXT~ para guardar o veículo', ['spawn_veh'] = 'pegar veículo', - ['spawnpoint_blocked'] = 'there is a vehicle blocking the spawnpoint!', - ['only_taxi'] = 'Você só pode guardar taxis.', + ['spawnpoint_blocked'] = 'existe um veículo bloqueando o ponto de spawn!', + ['only_taxi'] = 'você só pode guardar taxis.', - ['taking_service'] = 'Pegando serviço: Taxi/Uber', - ['full_service'] = 'Serviço completo: ', - ['amount_invalid'] = 'Valor inválido', - ['press_to_open'] = 'Pressione ~INPUT_CONTEXT~ para acessar o menu', - ['billing'] = 'Faturamento', - ['billing_sent'] = 'the bill has been registered!', - ['invoice_amount'] = 'Valor da fatura', - ['no_players_near'] = 'Nenhum jogador nas proximidades', - ['start_job'] = 'start / stop driving NPC jobs', - ['drive_search_pass'] = 'Dirigindo em busca de ~y~passageiros', - ['customer_found'] = 'Você ~g~encontrou~s~ um passageiro, dirija até o destino', - ['client_unconcious'] = 'Seu passageiro está ~r~insconsciente~s~. Procure por outro.', - ['arrive_dest'] = 'Você ~g~chegou~s~ ao seu destino', + ['taking_service'] = 'pegando serviço: Taxi/Uber', + ['full_service'] = 'serviço completo: ', + ['amount_invalid'] = 'valor inválido', + ['press_to_open'] = 'pressione ~INPUT_CONTEXT~ para acessar o menu', + ['billing'] = 'faturamento', + ['billing_sent'] = 'a fatura foi enviada!', + ['invoice_amount'] = 'valor da fatura', + ['no_players_near'] = 'nenhum jogador nas proximidades', + ['start_job'] = 'iniciar / parar missão', + ['drive_search_pass'] = 'dirigindo em busca de ~y~passageiros', + ['customer_found'] = 'você ~g~encontrou~s~ um passageiro, dirija até o destino', + ['client_unconcious'] = 'seu passageiro está ~r~insconsciente~s~. Procure por outro.', + ['arrive_dest'] = 'você ~g~chegou~s~ ao seu destino', ['take_me_to_near'] = '~s~Leve me para~y~ %s~s~, perto~y~ %s', ['take_me_to'] = '~s~Leve me para~y~ %s', - ['close_to_client'] = 'Você está perto do passageiro, aproximisse dele', - ['return_to_veh'] = 'Volte para o seu veículo para continuar a missão', - ['must_in_taxi'] = 'Você deve estar em um táxi para começar a missão', - ['must_in_vehicle'] = 'Você deve estar em um veículo para começar a missão', - ['have_earned'] = 'Você ganhou ~g~$%s~s~', - ['comp_earned'] = '- Sua empresa ganhou ~g~$%s~s~\n- Você ganhou ~g~$%s~s~', - ['deposit_stock'] = 'deposit Stock', - ['take_stock'] = 'take Stock', - ['boss_actions'] = 'boss Actions', - ['mission_complete'] = 'mission Completed', - ['quantity'] = 'quantity', - ['quantity_invalid'] = 'that is an invalid quantity!', - ['inventory'] = 'inventory', - ['taxi_client'] = 'taxi Client', + ['close_to_client'] = 'você está perto do passageiro, aproximisse dele', + ['return_to_veh'] = 'volte para o seu veículo para continuar a missão', + ['must_in_taxi'] = 'você deve estar em um táxi para começar a missão', + ['must_in_vehicle'] = 'você deve estar em um veículo para começar a missão', + ['have_earned'] = 'você ganhou ~g~$%s~s~', + ['comp_earned'] = '- sua empresa ganhou ~g~$%s~s~\n- Você ganhou ~g~$%s~s~', + ['deposit_stock'] = 'depositar estoque', + ['take_stock'] = 'retirar estoque', + ['boss_actions'] = 'ações de chefe', + ['mission_complete'] = 'missão completa', + ['quantity'] = 'quantidade', + ['quantity_invalid'] = 'é uma quantidade inválida!', + ['inventory'] = 'inventário', + ['taxi_client'] = 'cliente do taxi', ['have_withdrawn'] = 'você retirou ~y~x%s~s~ ~b~%s~s~', ['have_deposited'] = 'você depositou ~y~x%s~s~ ~b~%s~s~', ['player_cannot_hold'] = 'você não tem espaço suficiente em seu inventário!', ['blip_taxi'] = 'taxi', ['phone_taxi'] = 'taxi', -} \ No newline at end of file +} diff --git a/localization/br_esx_taxijob.sql b/localization/br_esx_taxijob.sql new file mode 100644 index 00000000..608db9c4 --- /dev/null +++ b/localization/br_esx_taxijob.sql @@ -0,0 +1,25 @@ +USE `essentialmode`; + +INSERT INTO `addon_account` (name, label, shared) VALUES + ('society_taxi', 'Taxi', 1) +; + +INSERT INTO `datastore` (name, label, shared) VALUES + ('society_taxi', 'Taxi', 1) +; + +INSERT INTO `addon_inventory` (name, label, shared) VALUES + ('society_taxi', 'Taxi', 1) +; + +INSERT INTO `jobs` (name, label) VALUES + ('taxi', 'Taxi') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('taxi',0,'recrue','Recrutar',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}'), + ('taxi',1,'novice','Taxista',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}'), + ('taxi',2,'experimente','Taxista Experiente',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}'), + ('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}'), + ('taxi',4,'boss','Taxista Chefe',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}') +; From eb407d980c806972652a7e87e4987f36b3662fe1 Mon Sep 17 00:00:00 2001 From: Julien80 Date: Sat, 18 Jan 2020 20:53:18 +0100 Subject: [PATCH 2410/3224] Fix give weapon on esx:giveInventoryItem --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 251dcd6a..78086ea5 100644 --- a/server/main.lua +++ b/server/main.lua @@ -284,7 +284,7 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo local weaponLabel = ESX.GetWeaponLabel(itemName) if not targetXPlayer.hasWeapon(itemName) then - local weaponNum, weapon = xPlayer.getWeapon(itemName) + local weaponNum, weapon = sourceXPlayer.getWeapon(itemName) itemCount = weapon.ammo sourceXPlayer.removeWeapon(itemName) From 535a03de98b259129497c35cc8e8ed7e6377b8f9 Mon Sep 17 00:00:00 2001 From: Willem Dekker <16556575+Willem-Dekker@users.noreply.github.com> Date: Sun, 19 Jan 2020 15:58:37 +0100 Subject: [PATCH 2411/3224] Added Dutch translation (#80) * added dutch translations EN->NL * Update nl.lua updated indenting Co-authored-by: Samuel --- __resource.lua | 2 ++ locales/nl.lua | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 locales/nl.lua diff --git a/__resource.lua b/__resource.lua index c83faa79..96ac4d28 100644 --- a/__resource.lua +++ b/__resource.lua @@ -13,6 +13,7 @@ server_scripts { 'locales/fr.lua', 'locales/sv.lua', 'locales/pl.lua', + 'locales/nl.lua', 'locales/cs.lua', 'config.lua', 'server/main.lua' @@ -26,6 +27,7 @@ client_scripts { 'locales/fr.lua', 'locales/sv.lua', 'locales/pl.lua', + 'locales/nl.lua', 'locales/cs.lua', 'config.lua', 'client/main.lua' diff --git a/locales/nl.lua b/locales/nl.lua new file mode 100644 index 00000000..c5aa6011 --- /dev/null +++ b/locales/nl.lua @@ -0,0 +1,38 @@ +Locales['nl'] = { + ['actions'] = 'acties', + ['boss_menu'] = 'baas menu', + ['money_generic'] = '€%s', + ['deposit_amount'] = 'stort hoeveelheid', + ['deposit_society_money'] = 'stort maatschappij geld', + ['do_you_want_to_recruit'] = 'Wil je %s aannemen?', + ['employee'] = 'werknemer', + ['employee_list'] = 'werknemer lijst', + ['employee_management'] = 'werknemer beheer', + ['fire'] = 'ontslaan', + ['grade'] = 'schaal', + ['have_deposited'] = 'je hebt gestort ~r~$%s~s~', + ['have_withdrawn'] = 'je hebt opgenomen ~g~$%s~s~', + ['invalid_amount'] = 'ongeldige hoeveelheid', + ['invalid_amount_max'] = 'dit salaris is niet toegestaan', + ['no'] = 'nee', + ['promote'] = 'promoveer', + ['promote_employee'] = 'promoveer %s', + ['recruit'] = 'werv', + ['recruiting'] = 'werven', + ['salary_amount'] = 'salaris hoeveelheid', + ['salary_management'] = 'salaris beheer', + ['wash_money'] = 'witwas geld', + ['wash_money_amount'] = 'hoeveelheid om wit te wassen', + ['withdraw_amount'] = 'opneem hoeveelheid', + ['withdraw_society_money'] = 'neem maatschappelijk geld op', + ['yes'] = 'ja', + ['you_have'] = 'je hebt ~g~€%s~s~ staan in ~y~geld witwassen~s~ (24h).', + ['you_have_laundered'] = 'je hebt je geld: ~g~€%s~s~ ~r~witgewassen~s~ ', + ['you_have_hired'] = 'je bent gevraagt %s', + ['you_have_been_hired'] = 'je bent aangenomen door %s', + ['you_have_fired'] = 'je bent ontslagen %s', + ['you_have_been_fired'] = 'je bent ondslagen van %s', + ['you_have_promoted'] = 'je hebt gepromoveerd %s naar %s', + ['you_have_been_promoted'] = 'je bent ~b~gepromoveerd~s~!', +} + From 7b0a4c25093ccd1c31ef3818159596c2096c15dd Mon Sep 17 00:00:00 2001 From: BackrndSource Date: Sun, 19 Jan 2020 16:04:49 +0100 Subject: [PATCH 2412/3224] Spanish Translation (#21) * Create es.lua * Update __resource.lua --- __resource.lua | 2 ++ locales/es.lua | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 locales/es.lua diff --git a/__resource.lua b/__resource.lua index ea830cab..72fc260d 100644 --- a/__resource.lua +++ b/__resource.lua @@ -8,6 +8,7 @@ client_scripts { '@es_extended/locale.lua', 'locales/de.lua', 'locales/en.lua', + 'locales/es.lua', 'locales/fi.lua', 'locales/fr.lua', 'locales/sv.lua', @@ -20,6 +21,7 @@ server_scripts { '@es_extended/locale.lua', 'locales/de.lua', 'locales/en.lua', + 'locales/es.lua', 'locales/fi.lua', 'locales/fr.lua', 'locales/sv.lua', diff --git a/locales/es.lua b/locales/es.lua new file mode 100644 index 00000000..a742876a --- /dev/null +++ b/locales/es.lua @@ -0,0 +1,16 @@ +Locales['es'] = { + ['shop_robbery'] = 'atraco a tienda', + ['press_to_rob'] = 'pulsa ~INPUT_CONTEXT~ para ~o~robar~s~ ~b~%s~s~', + ['robbery_timer'] = 'atraco: ~r~%s~s~ segundos restantes', + ['recently_robbed'] = 'esta tienda fue robada recientemente. Espera ~y~%s~s~ antes de poder robarla de nuevo', + ['rob_in_prog'] = '~r~Robo en proceso en ~b~%s~s~', + ['started_to_rob'] = 'has empezado a robar en ~y~%s~s~', + ['alarm_triggered'] = 'la alarma ha sido activada!', + ['robbery_complete'] = '~r~El robo salió bien~s~, has ~o~robado~s~ ~g~%s€~s~', + ['robbery_complete_at'] = '~r~Robo finalizado en ~y~%s~s~', + ['robbery_cancelled'] = 'el ~o~robo~s~ ha sido cancelado!', + ['robbery_cancelled_at'] = '~r~El robo en ~b~%s~s~ ha sido cancelado!', + ['min_police'] = 'se necesitan ~b~%s policias~s~ activos para poder robar.', + ['robbery_already'] = '~r~Ya hay un robo en progreso.', + ['no_threat'] = 'sin pistola el encargado de la tienda no te tiene miedo...', +} From c5376b64c6e311cb4ed160afe76831b157a9ff42 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 16:05:49 +0100 Subject: [PATCH 2413/3224] Minor cleanup (#32) * Update for newest ESX * Minor cleanup * Update readme * Link fix in readme * I forgot this * And this * Minor cleanup 2 --- README.md | 8 +++---- client/main.lua | 57 ++++--------------------------------------------- server/main.lua | 5 ++--- 3 files changed, 10 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index 01104f79..8b6bdf76 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ -# fxserver-esx_garage -FXServer ESX Garage +# esx_garage +ESX Garage [REQUIREMENTS] -- instance => https://github.com/FXServer-ESX/fxserver-instance +- instance => https://github.com/ESX-Org/instance [INSTALLATION] 1) CD in your resources/[esx] folder 2) Clone the repository ``` -git clone https://github.com/FXServer-ESX/fxserver-esx_garage esx_garage +git clone https://github.com/ESX-Org/esx_garage esx_garage ``` 3) Import esx_garage.sql in your database 4) Add this in your server.cfg : diff --git a/client/main.lua b/client/main.lua index a109a772..4f0cd4b0 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,8 +1,5 @@ -ESX = nil -local LastGarage = nil -local LastPart = nil -local LastParking = nil -local thisGarage = nil +ESX = nil +local LastGarage, LastPart, LastParking, thisGarage = nil, nil, nil, nil Citizen.CreateThread(function() while ESX == nil do @@ -21,9 +18,7 @@ AddEventHandler('instance:onCreate', function(instance) end) AddEventHandler('esx_garage:hasEnteredMarker', function(name, part, parking) - if part == 'ExteriorEntryPoint' then - local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) local garage = Config.Garages[name] @@ -36,7 +31,6 @@ AddEventHandler('esx_garage:hasEnteredMarker', function(name, part, parking) end if IsPedInAnyVehicle(playerPed, false) then - local vehicle = GetVehiclePedIsIn(playerPed, false) local maxHealth = GetEntityMaxHealth(vehicle) local health = GetEntityHealth(vehicle) @@ -45,7 +39,6 @@ AddEventHandler('esx_garage:hasEnteredMarker', function(name, part, parking) if healthPercent < Config.MinimumHealthPercent then ESX.ShowNotification(_U('veh_health')) else - if GetPedInVehicleSeat(vehicle, -1) == playerPed then local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) @@ -73,7 +66,6 @@ AddEventHandler('esx_garage:hasEnteredMarker', function(name, part, parking) for j=1, #vehicles, 1 do if i == vehicles[j].zone then - local spawn = function(j) local vehicle = GetClosestVehicle(garage.Parkings[i].Pos.x, garage.Parkings[i].Pos.y, garage.Parkings[i].Pos.z, 2.0, 0, 71) @@ -89,22 +81,15 @@ AddEventHandler('esx_garage:hasEnteredMarker', function(name, part, parking) }, garage.Parkings[i].Heading, function(vehicle) ESX.Game.SetVehicleProperties(vehicle, vehicles[j].vehicle) end) - end spawn(j) - end - end end - end, name) - end) - else - ESX.Game.Teleport(playerPed, { x = garage.InteriorSpawnPoint.Pos.x, y = garage.InteriorSpawnPoint.Pos.y, @@ -119,7 +104,6 @@ AddEventHandler('esx_garage:hasEnteredMarker', function(name, part, parking) for j=1, #vehicles, 1 do if i == vehicles[j].zone then - local spawn = function(j) local vehicle = GetClosestVehicle(garage.Parkings[i].Pos.x, garage.Parkings[i].Pos.garage.Parkings[i].Pos.y, garage.Parkings[i].Pos.z, 2.0, 0, 71) @@ -139,22 +123,14 @@ AddEventHandler('esx_garage:hasEnteredMarker', function(name, part, parking) end spawn(j) - end - end end - end, name) - end) - end - end - else - ESX.Game.Teleport(playerPed, { x = garage.InteriorSpawnPoint.Pos.x, y = garage.InteriorSpawnPoint.Pos.y, @@ -169,7 +145,6 @@ AddEventHandler('esx_garage:hasEnteredMarker', function(name, part, parking) for j=1, #vehicles, 1 do if i == vehicles[j].zone then - local spawn = function(j) local vehicle = GetClosestVehicle(garage.Parkings[i].Pos.x, garage.Parkings[i].Pos.y, garage.Parkings[i].Pos.z, 2.0, 0, 71) @@ -185,26 +160,18 @@ AddEventHandler('esx_garage:hasEnteredMarker', function(name, part, parking) }, garage.Parkings[i].Heading, function(vehicle) ESX.Game.SetVehicleProperties(vehicle, vehicles[j].vehicle) end) - end spawn(j) - end - end end - end, name) - end) - end - end if part == 'InteriorExitPoint' then - local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) local garage = thisGarage @@ -231,10 +198,8 @@ AddEventHandler('esx_garage:hasEnteredMarker', function(name, part, parking) ESX.Game.SetVehicleProperties(vehicle, vehicleProps) ESX.Game.SetVehicleEngineOn(vehicle, (not GetIsVehicleEngineRunning(vehicle)), false, true) end) - end) - else ESX.Game.Teleport(playerPed,{ @@ -244,7 +209,6 @@ AddEventHandler('esx_garage:hasEnteredMarker', function(name, part, parking) }, function() TriggerEvent('instance:close') end) - end for i=1, #garage.Parkings, 1 do @@ -264,7 +228,6 @@ AddEventHandler('esx_garage:hasEnteredMarker', function(name, part, parking) end thisGarage = nil - end if part == 'Parking' then @@ -283,11 +246,8 @@ AddEventHandler('esx_garage:hasEnteredMarker', function(name, part, parking) if Config.EnableOwnedVehicles then TriggerServerEvent('esx_garage:updateOwnedVehicle', vehicleProps) end - end - end - end) AddEventHandler('esx_property:hasExitedMarker', function(name, part, parking) @@ -301,9 +261,7 @@ AddEventHandler('esx_property:hasExitedMarker', function(name, part, parking) if IsPedInAnyVehicle(playerPed, false) and not IsAnyVehicleNearPoint(parkingPos.x, parkingPos.y, parkingPos.z, 1.0) then TriggerServerEvent('esx_garage:setParking', name, parking, false) end - end - end) -- Create Blips @@ -375,9 +333,7 @@ end) -- Enter / Exit marker events Citizen.CreateThread(function() - while true do - Citizen.Wait(1) local playerPed = PlayerPedId() @@ -403,7 +359,6 @@ Citizen.CreateThread(function() end for i=1, #v.Parkings, 1 do - local parking = v.Parkings[i] if (not v.disabled and GetDistanceBetweenCoords(coords, parking.Pos.x, parking.Pos.y, parking.Pos.z, true) < Config.ParkingMarkerSize.x) then @@ -412,10 +367,8 @@ Citizen.CreateThread(function() currentPart = 'Parking' currentParking = i end - end end - end if isInMarker and not HasAlreadyEnteredMarker or (isInMarker and (LastGarage ~= currentGarage or LastPart ~= currentPart or LastParking ~= currentParking) ) then @@ -433,11 +386,9 @@ Citizen.CreateThread(function() end if not isInMarker and HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = false - + TriggerEvent('esx_property:hasExitedMarker', LastGarage, LastPart, LastParking) end - end -end) \ No newline at end of file +end) diff --git a/server/main.lua b/server/main.lua index 97453643..5b02e5f2 100644 --- a/server/main.lua +++ b/server/main.lua @@ -15,7 +15,7 @@ AddEventHandler('esx_garage:setParking', function(garage, zone, vehicleProps) ['@garage'] = garage; ['@zone'] = zone }, function(rowsChanged) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('veh_released')) + xPlayer.showNotification(_U('veh_released')) end) else MySQL.Async.execute('INSERT INTO `user_parkings` (`identifier`, `garage`, `zone`, `vehicle`) VALUES (@identifier, @garage, @zone, @vehicle)', @@ -25,7 +25,7 @@ AddEventHandler('esx_garage:setParking', function(garage, zone, vehicleProps) ['@zone'] = zone, ['vehicle'] = json.encode(vehicleProps) }, function(rowsChanged) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('veh_stored')) + xPlayer.showNotification(_U('veh_stored')) end) end end) @@ -58,5 +58,4 @@ ESX.RegisterServerCallback('esx_vehicleshop:getVehiclesInGarage', function(sourc cb(vehicles) end) - end) From 9ccfd3fd412d080db2de315ec9cb0d3efefbd00c Mon Sep 17 00:00:00 2001 From: BackrndSource Date: Sun, 19 Jan 2020 16:06:14 +0100 Subject: [PATCH 2414/3224] Added Spanish translation (#25) * Create es.lua * Update __resource.lua --- __resource.lua | 2 ++ locales/es.lua | 5 +++++ 2 files changed, 7 insertions(+) create mode 100644 locales/es.lua diff --git a/__resource.lua b/__resource.lua index a48059d9..bbb62299 100644 --- a/__resource.lua +++ b/__resource.lua @@ -9,6 +9,7 @@ server_scripts { 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', + 'locales/es.lua', 'locales/fr.lua', 'locales/sv.lua', 'locales/pl.lua', @@ -22,6 +23,7 @@ client_scripts { 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', + 'locales/es.lua', 'locales/fr.lua', 'locales/sv.lua', 'locales/pl.lua', diff --git a/locales/es.lua b/locales/es.lua new file mode 100644 index 00000000..37ac19f4 --- /dev/null +++ b/locales/es.lua @@ -0,0 +1,5 @@ +Locales['es'] = { + ['veh_released'] = 'has sacado tu vehículo', + ['veh_stored'] = 'has guardado tu vehículo', + ['veh_health'] = 'debes de reparar tu vehículo antes de guardarlo', +} From 804bf06ce5b3eeccf4c21ba8b0cc1e9e9d878fee Mon Sep 17 00:00:00 2001 From: Willem Dekker <16556575+Willem-Dekker@users.noreply.github.com> Date: Sun, 19 Jan 2020 16:08:36 +0100 Subject: [PATCH 2415/3224] Added Dutch translations (#52) * translated EN -> NL * added the locale to the config * Update nl.lua Updated indenting to 2 spaces instead of 4 --- __resource.lua | 2 ++ locales/nl.lua | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 locales/nl.lua diff --git a/__resource.lua b/__resource.lua index 0739b5a9..b2829826 100644 --- a/__resource.lua +++ b/__resource.lua @@ -12,6 +12,7 @@ client_scripts { 'locales/br.lua', 'locales/sv.lua', 'locales/pl.lua', + 'locales/nl.lua', 'config.lua', 'client/main.lua' } @@ -24,6 +25,7 @@ server_scripts { 'locales/br.lua', 'locales/sv.lua', 'locales/pl.lua', + 'locales/nl.lua', 'config.lua', 'server/main.lua' } diff --git a/locales/nl.lua b/locales/nl.lua new file mode 100644 index 00000000..6ff38d7a --- /dev/null +++ b/locales/nl.lua @@ -0,0 +1,85 @@ +Locales['nl'] = { + ['mechanic'] = 'monteur', + ['drive_to_indicated'] = '~y~Rij~s~ naar de aangegeven locatie', + ['mission_canceled'] = 'opdracht ~r~Geannuleerd~s~', + ['vehicle_list'] = 'voertuigenlijst', + ['work_wear'] = 'werk kleding', + ['civ_wear'] = 'burger kleding', + ['deposit_stock'] = 'vooraad wegleggen', + ['withdraw_stock'] = 'vooraad opbergen', + ['boss_actions'] = 'baas acties', + ['service_vehicle'] = 'service voertuig', + ['flat_bed'] = 'oprijwagen', + ['tow_truck'] = 'sleep wagen', + ['service_full'] = 'dienst voledig: ', + ['open_actions'] = 'Druk op ~INPUT_CONTEXT~ om in het menu te komen.', + ['harvest'] = 'oogsten', + ['harvest_menu'] = 'druk op ~INPUT_CONTEXT~ om in het oogst menu te komen.', + ['not_experienced_enough'] = 'je hebt ~r~niet genoeg ervaring~s~ om dit te doen.', + ['gas_can'] = 'jerrycan', + ['repair_tools'] = 'reparatie gereedschap', + ['body_work_tools'] = 'plaatwerk gereedschap', + ['blowtorch'] = 'gasbrannder', + ['repair_kit'] = 'reparatie set', + ['body_kit'] = 'plaatwerk set', + ['craft'] = 'maaken', + ['craft_menu'] = 'druk op ~INPUT_CONTEXT~ om in het maak menu te komen.', + ['billing'] = 'facturen', + ['hijack'] = 'openbreken', + ['repair'] = 'repareer', + ['clean'] = 'maak schoon', + ['imp_veh'] = 'inbeslag nemen', + ['place_objects'] = 'plaats objecten', + ['invoice_amount'] = 'factuur bedrag', + ['amount_invalid'] = 'ongeldig aantal', + ['no_players_nearby'] = 'er is geen speler in de buurt', + ['no_vehicle_nearby'] = 'er is geen voertuig in de buurt', + ['inside_vehicle'] = 'je kan dit niet doen in een voertuig!', + ['vehicle_unlocked'] = 'het voortuig is ~g~opengebroken', + ['vehicle_repaired'] = 'het voortuig is ~g~gerepareerd', + ['vehicle_cleaned'] = 'het voortuig is ~g~schoongemaakt', + ['vehicle_impounded'] = 'het voortuig is ~r~in beslag genomen', + ['must_seat_driver'] = 'je moet in de bestuurders stoel zitten', + ['must_near'] = 'je moet ~r~dicht bij een voertuig zijn~s~ om hem in beslag te nemen.', + ['vehicle_success_attached'] = 'voertuig succesvol ~b~vastgemaakt~s~', + ['please_drop_off'] = 'graag voertuig naar de garage brengen', + ['cant_attach_own_tt'] = '~r~je kan niet~s~ je eigen wagen vast maken', + ['no_veh_att'] = 'er zijn geen ~r~voertuigen~s~ om vast te maken', + ['not_right_veh'] = 'dit is niet het juiste voertuig', + ['veh_det_succ'] = 'voertuig succesvol ~b~losgekoppeld~s~!', + ['imp_flatbed'] = '~r~Actie onmogelijk!~s~ je moet een ~b~oprijwagen~s~ nodig om deze te laden', + ['objects'] = 'objecten', + ['roadcone'] = 'pion', + ['toolbox'] = 'gereedschaps kist', + ['mechanic_stock'] = 'monteurs opslag', + ['quantity'] = 'hoeveelheid', + ['invalid_quantity'] = 'ongeldige hoeveelheid', + ['inventory'] = 'inventaris', + ['veh_unlocked'] = '~g~Voertuig opgengemaakt', + ['hijack_failed'] = '~r~Openbreken mislukt', + ['body_repaired'] = '~g~Plaatwerk gerepareerd', + ['veh_repaired'] = '~g~Voertuig gerepareerd', + ['veh_stored'] = 'Druk op ~INPUT_CONTEXT~ om voertuig op te slaan.', + ['press_remove_obj'] = 'Druk op ~INPUT_CONTEXT~ om object weg te halen', + ['please_tow'] = 'graag voertuig ~y~afslepen~s~', + ['wait_five'] = 'je moet 5 minuten ~r~wachten~s~', + ['must_in_flatbed'] = 'je bent een oprijwagen nodig voor deze klant', + ['mechanic_customer'] = 'klant van garage', + ['you_do_not_room'] = '~r~Je hebt geen ruimte', + ['recovery_gas_can'] = '~b~Jerrycan~s~ Ophalen...', + ['recovery_repair_tools'] = '~b~Reparatie gereedschap~s~ Ophalen...', + ['recovery_body_tools'] = '~b~Plaatwerk gereedschap~s~ Ophalen...', + ['not_enough_gas_can'] = 'je hebt ~r~niet genoeg~s~ jerrycans.', + ['assembling_blowtorch'] = 'In elkaar aan het zetten ~b~gasbrannder~s~...', + ['not_enough_repair_tools'] = 'je hebt ~r~niet genoeg~s~ reparatie gereedschap.', + ['assembling_repair_kit'] = 'In elkaar aan het zetten ~b~reparatie set~s~...', + ['not_enough_body_tools'] = 'je hebt ~r~niet genoeg~s~ plaatwerk gereedschap.', + ['assembling_body_kit'] = 'In elkaar aan het zetten ~b~plaatwerk set~s~...', + ['your_comp_earned'] = 'de garage heeft ~g~verdient~s~ ~g~€', + ['you_used_blowtorch'] = 'je gebruikte een ~b~gasbrannder', + ['you_used_repair_kit'] = 'je gebruikte een ~b~reparatie set', + ['you_used_body_kit'] = 'je gebruikte een ~b~plaatwerk set', + ['have_withdrawn'] = 'je hebt opgenomen ~y~x%s~s~ ~b~%s~s~', + ['have_deposited'] = 'je hebt gestort ~y~x%s~s~ ~b~%s~s~', + ['player_cannot_hold'] = 'je hebt ~r~niet~s~ genoeg ~y~vrije ruimte~s~ in je inventaris!', +} From 1f235378ef1991d6915a76889466a81c1819d3d3 Mon Sep 17 00:00:00 2001 From: NebelRebell <40825041+NebelRebell@users.noreply.github.com> Date: Sun, 19 Jan 2020 16:09:11 +0100 Subject: [PATCH 2416/3224] Update (#45) dependencies { 'es_extended', 'esx_society', 'esx_billing' } --- __resource.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/__resource.lua b/__resource.lua index b2829826..06605d69 100644 --- a/__resource.lua +++ b/__resource.lua @@ -29,3 +29,9 @@ server_scripts { 'config.lua', 'server/main.lua' } + +dependencies { + 'es_extended', + 'esx_society', + 'esx_billing' +} From 31d476397b557c1ef558733fac13118e2b5af728 Mon Sep 17 00:00:00 2001 From: kaju Date: Sun, 19 Jan 2020 18:10:36 +0300 Subject: [PATCH 2417/3224] Added Turkish translation (#20) * Create tr.lua * Update __resource.lua * Create tr_esx_realestateagentjob.sql Co-authored-by: Samuel --- __resource.lua | 2 ++ locales/tr.lua | 27 ++++++++++++++++++++++ localization/tr_esx_realestateagentjob.sql | 16 +++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 locales/tr.lua create mode 100644 localization/tr_esx_realestateagentjob.sql diff --git a/__resource.lua b/__resource.lua index 448d485f..a4c1ad1e 100644 --- a/__resource.lua +++ b/__resource.lua @@ -13,6 +13,7 @@ server_scripts { 'locales/fi.lua', 'locales/fr.lua', 'locales/sv.lua', + 'locales/tr.lua', 'locales/cs.lua', 'config.lua', 'server/main.lua' @@ -26,6 +27,7 @@ client_scripts { 'locales/fi.lua', 'locales/fr.lua', 'locales/sv.lua', + 'locales/tr.lua', 'locales/cs.lua', 'config.lua', 'client/main.lua' diff --git a/locales/tr.lua b/locales/tr.lua new file mode 100644 index 00000000..7eccb556 --- /dev/null +++ b/locales/tr.lua @@ -0,0 +1,27 @@ +Locales['tr'] = { + ['properties'] = 'Mülkler', + ['clients'] = 'Müşteriler', + ['realtor'] = 'Emlak Bürosu', + ['amount_withdraw'] = 'Çekilecek miktar', + ['invalid_amount'] = 'Geçersiz miktar', + ['press_to_access'] = 'Menüye erişmek için ~INPUT_CONTEXT~ tuşuna basın.', + ['amount'] = 'Miktar', + ['no_play_near'] = 'Yakında kimse yok, + ['realtors'] = 'Emlak Bürosu çalışanları', + ['boss_action'] = 'Patron eylemleri', + ['client_poor'] = 'Müşterinin bunu ödeyecek kadar parası yok.', + + -- Property menu + ['property_name'] = 'Mülk', + ['property_actions'] = 'Eylemler', + ['property_actionbuttons'] = '{{İşlem [Sat]|sell}} {{İşlem [Kirala]|rent}} {{GPS|gps}}', + + -- Customer menu + ['customer_client'] = 'Müşteri', + ['customer_property'] = 'Mülk', + ['customer_agreement'] = 'Sözleşme', + ['customer_actions'] = 'Eylemler', + ['customer_contractbuttons'] = '{{Sözleşmeyi iptal et|revoke}} {{GPS|gps}}', + ['customer_rent'] = 'Kiralandı', + ['customer_sell'] = 'Satıldı', +} diff --git a/localization/tr_esx_realestateagentjob.sql b/localization/tr_esx_realestateagentjob.sql new file mode 100644 index 00000000..e99df386 --- /dev/null +++ b/localization/tr_esx_realestateagentjob.sql @@ -0,0 +1,16 @@ +USE `essentialmode`; + +INSERT INTO `addon_account` (name, label, shared) VALUES + ('society_realestateagent','Emlak Bürosu',1) +; + +INSERT INTO `jobs` (name, label) VALUES + ('realestateagent','Emlak Bürosu') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('realestateagent',0,'location','Eleman',10,'{}','{}'), + ('realestateagent',1,'vendeur','Sekreter',25,'{}','{}'), + ('realestateagent',2,'gestion','Asistan',40,'{}','{}'), + ('realestateagent',3,'boss','Patron',0,'{}','{}') +; From 02841bb362b339b69a77d0b7589bd1f98e0f0760 Mon Sep 17 00:00:00 2001 From: LeCyreaxYT <38440842+LeCyreaxYT@users.noreply.github.com> Date: Sun, 19 Jan 2020 16:12:21 +0100 Subject: [PATCH 2418/3224] Added German translation (#78) * Create de.lua * Update __resource.lua --- __resource.lua | 2 + locales/de.lua | 269 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 271 insertions(+) create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index eb9932df..696eed11 100644 --- a/__resource.lua +++ b/__resource.lua @@ -11,6 +11,7 @@ server_scripts { 'locales/fr.lua', 'locales/pl.lua', 'locales/br.lua', + 'locales/de.lua', 'config.lua', 'server/main.lua' } @@ -21,6 +22,7 @@ client_scripts { 'locales/fr.lua', 'locales/pl.lua', 'locales/br.lua', + 'locales/de.lua', 'config.lua', 'client/main.lua' } diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..d2fac421 --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,269 @@ +Locales['de'] = { + ['by_default'] = 'Standard', + ['installed'] = 'installed', + ['already_own'] = 'Sie besitzen bereits: %s', + ['not_enough_money'] = 'du kannst dir diese mod nicht leisten', + ['purchased'] = 'Du hast diese Mod gekauft!', + ['press_custom'] = 'Drücke ~INPUT_PICKUP~ um dein Fahrzeug auf zu Tunen', + ['level'] = 'level %s', + ['neon'] = 'Neon', + ['blip_name'] = 'Tuning', +-- Paint Colors + -- Black + ['black'] = 'black', + ['graphite'] = 'graphite', + ['black_metallic'] = 'black Metallic', + ['caststeel'] = 'cast Steel', + ['black_anth'] = 'black Anthracite', + ['matteblack'] = 'matte Black', + ['darknight'] = 'dark Night', + ['deepblack'] = 'deep Black', + ['oil'] = 'oil', + ['carbon'] = 'carbon', + -- White + ['white'] = 'white', + ['vanilla'] = 'vanilla', + ['creme'] = 'creme', + ['polarwhite'] = 'polar White', + ['beige'] = 'beige', + ['mattewhite'] = 'matte White', + ['snow'] = 'snow', + ['cotton'] = 'cotton', + ['alabaster'] = 'alabaster', + ['purewhite'] = 'pure White', + -- Grey + ['grey'] = 'grey', + ['silver'] = 'silver', + ['metallicgrey'] = 'metallic Grey', + ['laminatedsteel'] = 'laminated Steel', + ['darkgray'] = 'dark Grey', + ['rockygray'] = 'rocky Grey', + ['graynight'] = 'gray Night', + ['aluminum'] = 'aluminum', + ['graymat'] = 'matte Grey', + ['lightgrey'] = 'light Grey', + ['asphaltgray'] = 'asphalt Grey', + ['grayconcrete'] = 'concrete Grey', + ['darksilver'] = 'dark Silver', + ['magnesite'] = 'magnesite', + ['nickel'] = 'nickel', + ['zinc'] = 'zinc', + ['dolomite'] = 'dolomite', + ['bluesilver'] = 'blue Silver', + ['titanium'] = 'titanium', + ['steelblue'] = 'steel Blue', + ['champagne'] = 'champagne', + ['grayhunter'] = 'grey Hunter', + -- Red + ['red'] = 'red', + ['torino_red'] = 'torino Red', + ['poppy'] = 'poppy', + ['copper_red'] = 'copper Red', + ['cardinal'] = 'cardinal Red', + ['brick'] = 'brick Red', + ['garnet'] = 'Garnet', + ['cabernet'] = 'cabernet Red', + ['candy'] = 'candy Red', + ['matte_red'] = 'matte Red', + ['dark_red'] = 'dark Red', + ['red_pulp'] = 'red Pulp', + ['bril_red'] = 'brilliant Red', + ['pale_red'] = 'pale Red', + ['wine_red'] = 'wine Red', + ['volcano'] = 'Volcano', + -- Pink + ['pink'] = 'pink', + ['electricpink'] = 'electric Pink', + ['brightpink'] = 'bright Pink', + ['salmon'] = 'salmon', + ['sugarplum'] = 'sugar Plum', + -- Blue + ['blue'] = 'blue', + ['topaz'] = 'topaz', + ['light_blue'] = 'light Blue', + ['galaxy_blue'] = 'galaxy Blue', + ['dark_blue'] = 'dark Blue', + ['azure'] = 'azure', + ['navy_blue'] = 'navy Blue', + ['lapis'] = 'lapis Lazuli', + ['blue_diamond'] = 'blue Diamond', + ['surfer'] = 'surfer', + ['pastel_blue'] = 'pastel Blue', + ['celeste_blue'] = 'celeste Blue', + ['rally_blue'] = 'rally Blue', + ['blue_paradise'] = 'blue Paradise', + ['blue_night'] = 'blue Night', + ['cyan_blue'] = 'cyan Blue', + ['cobalt'] = 'cobalt', + ['electric_blue'] = 'electric Blue', + ['horizon_blue'] = 'horizon Blue', + ['metallic_blue'] = 'metallic Blue', + ['aquamarine'] = 'aquamarine', + ['blue_agathe'] = 'blue Agathe', + ['zirconium'] = 'zirconium', + ['spinel'] = 'spinel', + ['tourmaline'] = 'tourmaline', + ['paradise'] = 'paradise', + ['bubble_gum'] = 'bubble Gum', + ['midnight_blue'] = 'midnight Blue', + ['forbidden_blue'] = 'forbidden Blue', + ['glacier_blue'] = 'glacier Blue', + -- Yellow + ['yellow'] = 'yellow', + ['wheat'] = 'wheat', + ['raceyellow'] = 'race Yellow', + ['paleyellow'] = 'pale Yellow', + ['lightyellow'] = 'light Yellow', + -- Green + ['green'] = 'green', + ['met_dark_green'] = 'metallic Dark Green', + ['rally_green'] = 'Rally Green', + ['pine_green'] = 'pine Green', + ['olive_green'] = 'olive Green', + ['light_green'] = 'Light Green', + ['lime_green'] = 'lime green', + ['forest_green'] = 'forest Green', + ['lawn_green'] = 'lawn Green', + ['imperial_green'] = 'imperial Green', + ['green_bottle'] = 'breen Bottle', + ['citrus_green'] = 'citrus Green', + ['green_anis'] = 'green Anis', + ['khaki'] = 'Khaki', + ['army_green'] = 'army Green', + ['dark_green'] = 'dark Green', + ['hunter_green'] = 'hunter Green', + ['matte_foilage_green'] = 'matte Foilage Green', + -- Orange + ['orange'] = 'orange', + ['tangerine'] = 'Tangerine', + ['matteorange'] = 'Matte Orange', + ['lightorange'] = 'Light Orange', + ['peach'] = 'Peach', + ['pumpkin'] = 'Pumpkin', + ['orangelambo'] = 'Orange Lambo', + -- Brown + ['brown'] = 'brown', + ['copper'] = 'Copper', + ['lightbrown'] = 'Light Brown', + ['darkbrown'] = 'Dark Brown', + ['bronze'] = 'Bronze', + ['brownmetallic'] = 'Brown Metallic', + ['espresso'] = 'Espresso', + ['chocolate'] = 'Chocolate', + ['terracotta'] = 'Terracotta', + ['marble'] = 'Marble', + ['sand'] = 'Sand', + ['sepia'] = 'Sepia', + ['bison'] = 'Bison', + ['palm'] = 'Palm', + ['caramel'] = 'Caramel', + ['rust'] = 'Rust', + ['chestnut'] = 'Chestnut', + ['hazelnut'] = 'Hazelnut', + ['shell'] = 'Shell', + ['mahogany'] = 'Mahogany', + ['cauldron'] = 'Cauldron', + ['blond'] = 'Blond', + ['gravel'] = 'Gravel', + ['darkearth'] = 'Dark Earth', + ['desert'] = 'Desert', + -- Purple + ['purple'] = 'purple', + ['indigo'] = 'Indigo', + ['deeppurple'] = 'Deep Purple', + ['darkviolet'] = 'Dark Violet', + ['amethyst'] = 'Amethyst', + ['mysticalviolet'] = 'Mystic Violet', + ['purplemetallic'] = 'Purple Metallic', + ['matteviolet'] = 'Matte Violet', + ['mattedeeppurple'] = 'Matte Deep Purple', + -- Chrome + ['chrome'] = 'chrome', + ['brushedchrome'] = 'brushed Chrome', + ['blackchrome'] = 'black Chrome', + ['brushedaluminum'] = 'brushed Aluminum', + -- Metal + ['gold'] = 'gold', + ['puregold'] = 'pure Gold', + ['brushedgold'] = 'brushed Gold', + ['lightgold'] = 'light Gold', +-- License Plates + ['blue_on_white_1'] = 'blau auf weiß 1', + ['yellow_on_black'] = 'gelb auf schwarz', + ['yellow_blue'] = 'gelb auf blau', + ['blue_on_white_2'] = 'blau auf weiß 2', + ['blue_on_white_3'] = 'blau auf weiß 3', +-- Upgrades + ['upgrades'] = 'Upgrades', + ['engine'] = 'Motor', + ['brakes'] = 'bremsen', + ['transmission'] = 'Getriebe', + ['suspension'] = 'Suspension', + ['armor'] = 'Panzerung', + ['turbo'] = 'Turbo', + ['no_turbo'] = 'kein Turbo', +-- Cosmetics + ['cosmetics'] = 'Zubehör', + -- Body Parts + ['bodyparts'] = 'Karroserie Teile', + ['leftfender'] = 'linker Kotflügel', + ['rightfender'] = 'rechter Kotflügel', + ['spoilers'] = 'Spoiler', + ['sideskirt'] = 'Seitenschweller', + ['cage'] = 'Käfig', + ['hood'] = 'Motorhaube', + ['grille'] = 'Gitter', + ['rearbumper'] = 'hintere Stoßstange', + ['frontbumper'] = 'Frontstoßstange', + ['exhaust'] = 'Auspuff', + ['roof'] = 'Dach', + -- Paint + ['respray'] = 'Lackierung', + ['primary'] = 'Primär', + ['secondary'] = 'Sekundär', + ['pearlescent'] = 'Perlglanz', + -- Misc + ['headlights'] = 'Scheinwerfer', + ['licenseplates'] = 'Nummernschild', + ['windowtint'] = 'Fenstertönung', + ['horns'] = 'Hörner', + -- Neon + ['neons'] = 'neons', + -- Wheels + ['wheels'] = 'Räder', + ['tiresmoke'] = 'Reifenrauch', + ['wheel_type'] = 'Rad-Typ', + ['wheel_color'] = 'Radfarbe', + ['sport'] = 'Sport', + ['muscle'] = 'Muskel', + ['lowrider'] = 'Lowrider', + ['suv'] = 'SUV', + ['allterrain'] = 'alles Gelände', + ['tuning'] = 'tuning', + ['motorcycle'] = 'Motorrad', + ['highend'] = 'High End', + + ['modplateholder'] = 'Platte - Zurück', + ['modvanityplate'] = 'Platte - Vorne', + ['interior'] = 'interior', + ['trim'] = 'trim', + ['dashboard'] = 'dashboard', + ['speedometer'] = 'Tachometer', + ['door_speakers'] = 'Türlautsprecher', + ['seats'] = 'Sitze', + ['steering_wheel'] = 'Lenkrad', + ['gear_lever'] = 'Schalthebel', + ['quarter_deck'] = 'Achterdeck', + ['speakers'] = 'Lautsprecher', + ['trunk'] = 'Kofferraum', + ['hydraulic'] = 'hydraulisch', + ['engine_block'] = 'Motorblock', + ['air_filter'] = 'air filter', + ['struts'] = 'Streben', + ['arch_cover'] = 'Bogenabdeckung', + ['aerials'] = 'Antennen', + ['wings'] = 'Flügel', + ['fuel_tank'] = 'Treibstofftank', + ['windows'] = 'Fenster', + ['stickers'] = 'Designs', +} From b73f9502279c04ea7840ab6da4757acf50c69915 Mon Sep 17 00:00:00 2001 From: criminalist Date: Sun, 19 Jan 2020 22:18:03 +0700 Subject: [PATCH 2419/3224] Added Russian translation (#23) * RU local * Add RU local * add RU local --- __resource.lua | 4 +++- locales/ru.lua | 19 +++++++++++++++++++ localization/ru_esx_accessories.sql | 8 ++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 locales/ru.lua create mode 100644 localization/ru_esx_accessories.sql diff --git a/__resource.lua b/__resource.lua index d2f35714..e5b31921 100644 --- a/__resource.lua +++ b/__resource.lua @@ -7,6 +7,7 @@ version '1.1.0' server_scripts { '@es_extended/locale.lua', 'locales/en.lua', + 'locales/ru.lua', 'locales/fi.lua', 'locales/fr.lua', 'locales/sv.lua', @@ -19,6 +20,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', 'locales/en.lua', + 'locales/ru.lua', 'locales/fi.lua', 'locales/fr.lua', 'locales/sv.lua', @@ -32,4 +34,4 @@ dependencies { 'es_extended', 'esx_skin', 'esx_datastore' -} \ No newline at end of file +} diff --git a/locales/ru.lua b/locales/ru.lua new file mode 100644 index 00000000..125bd36c --- /dev/null +++ b/locales/ru.lua @@ -0,0 +1,19 @@ +Locales ['ru'] = { + ['valid_purchase'] = 'Подтверждаете покупку', + ['yes'] = 'Да ($%s)', + ['no'] = 'Нет', + ['helmet'] = 'Шлем / Шапка', + ['glasses'] = 'Очки', + ['mask'] = 'Маска', + ['ears'] = 'Аксессуары для ушей', + ['shop'] = 'Магазин %s', + ['set_unset'] = 'Положить / Снять', + ['not_enough_money'] = 'У вас не достаточно денег', + ['press_access'] = 'Нажмите ~INPUT_CONTEXT~ для доступа к меню', + ['accessories_blip'] = 'Аксессуары', + ['no_ears'] = 'У вас нет аксессуаров для ушей', + ['no_glasses'] = 'У вас нет очков', + ['no_helmet'] = 'У вас нет шлема', + ['no_mask'] = 'У вас нет маски', + ['you_paid'] = 'Вы заплатили ~g~$%s~s~', +} diff --git a/localization/ru_esx_accessories.sql b/localization/ru_esx_accessories.sql new file mode 100644 index 00000000..cd2139f5 --- /dev/null +++ b/localization/ru_esx_accessories.sql @@ -0,0 +1,8 @@ +USE `essentialmode`; + +INSERT INTO `datastore` (name, label, shared) VALUES + ('user_ears', 'Аксессуары для ушей', 0), + ('user_glasses', 'Очки', 0), + ('user_helmet', 'Шлем', 0), + ('user_mask', 'Маски', 0) +; From d733fe5428f113fe67056172ccbbfc1ccf5a79eb Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 19 Jan 2020 16:30:30 +0100 Subject: [PATCH 2420/3224] Minor code cleanup, use latest esx_identity code --- README.md | 3 +- client/main.lua | 83 +++++------------------ locales/br.lua | 1 - locales/de.lua | 1 - locales/en.lua | 3 +- locales/es.lua | 1 - locales/fi.lua | 1 - locales/fr.lua | 1 - locales/ko.lua | 1 - locales/pl.lua | 3 +- locales/sv.lua | 1 - server/main.lua | 175 +++++++++++++++++++----------------------------- 12 files changed, 88 insertions(+), 186 deletions(-) diff --git a/README.md b/README.md index ec62e9de..ee0709f4 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ git clone https://github.com/ESX-Org/esx_policejob [esx]/esx_policejob ## Installation - Import `esx_policejob.sql` in your database -- Add this in your server.cfg : +- Add this to your server.cfg: ``` start esx_policejob @@ -52,7 +52,6 @@ start esx_policejob * If you want license management you have to set `Config.EnableLicenses` to `true` in `config.lua` * If you want service management you have to set `Config.MaxInService` to a higher value than `-1` in `config.lua` - # Legal ### License esx_policejob - police script for ESX diff --git a/client/main.lua b/client/main.lua index 688f7daa..315b175f 100644 --- a/client/main.lua +++ b/client/main.lua @@ -610,7 +610,7 @@ function OpenPoliceActionsMenu() if data.current.value == 'citizen_interaction' then local elements = { {label = _U('id_card'), value = 'identity_card'}, - {label = _U('search'), value = 'body_search'}, + {label = _U('search'), value = 'search'}, {label = _U('handcuff'), value = 'handcuff'}, {label = _U('drag'), value = 'drag'}, {label = _U('put_in_vehicle'), value = 'put_in_vehicle'}, @@ -634,8 +634,7 @@ function OpenPoliceActionsMenu() if action == 'identity_card' then OpenIdentityCardMenu(closestPlayer) - elseif action == 'body_search' then - TriggerServerEvent('esx_policejob:message', GetPlayerServerId(closestPlayer), _U('being_searched')) + elseif action == 'search' then OpenBodySearchMenu(closestPlayer) elseif action == 'handcuff' then TriggerServerEvent('esx_policejob:handcuff', GetPlayerServerId(closestPlayer)) @@ -765,58 +764,15 @@ end function OpenIdentityCardMenu(player) ESX.TriggerServerCallback('esx_policejob:getOtherPlayerData', function(data) - local elements = {} - local nameLabel = _U('name', data.name) - local jobLabel, sexLabel, dobLabel, heightLabel, idLabel - - if data.job.grade_label and data.job.grade_label ~= '' then - jobLabel = _U('job', data.job.label .. ' - ' .. data.job.grade_label) - else - jobLabel = _U('job', data.job.label) - end - - if Config.EnableESXIdentity then - nameLabel = _U('name', data.firstname .. ' ' .. data.lastname) - - if data.sex then - if string.lower(data.sex) == 'm' then - sexLabel = _U('sex', _U('male')) - else - sexLabel = _U('sex', _U('female')) - end - else - sexLabel = _U('sex', _U('unknown')) - end - - if data.dob then - dobLabel = _U('dob', data.dob) - else - dobLabel = _U('dob', _U('unknown')) - end - - if data.height then - heightLabel = _U('height', data.height) - else - heightLabel = _U('height', _U('unknown')) - end - - if data.name then - idLabel = _U('id', data.name) - else - idLabel = _U('id', _U('unknown')) - end - end - local elements = { - {label = nameLabel}, - {label = jobLabel} + {label = _U('name', data.name)}, + {label = _U('job', ('%s - %s'):format(data.job.label, data.job.grade_label))} } if Config.EnableESXIdentity then - table.insert(elements, {label = sexLabel}) - table.insert(elements, {label = dobLabel}) - table.insert(elements, {label = heightLabel}) - table.insert(elements, {label = idLabel}) + table.insert(elements, {label = _U('sex', _U(data.sex))}) + table.insert(elements, {label = _U('dob', data.dob)}) + table.insert(elements, {label = _U('height', data.height)}) end if data.drunk then @@ -949,8 +905,7 @@ function OpenFineCategoryMenu(player, category) end function LookupVehicle() - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'lookup_vehicle', - { + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'lookup_vehicle', { title = _U('search_database_title'), }, function(data, menu) local length = string.len(data.value) @@ -972,32 +927,26 @@ function LookupVehicle() end function ShowPlayerLicense(player) - local elements, targetName = {} + local elements = {} - ESX.TriggerServerCallback('esx_policejob:getOtherPlayerData', function(data) - if data.licenses then - for i=1, #data.licenses, 1 do - if data.licenses[i].label and data.licenses[i].type then + ESX.TriggerServerCallback('esx_policejob:getOtherPlayerData', function(playerData) + if playerData.licenses then + for i=1, #playerData.licenses, 1 do + if playerData.licenses[i].label and playerData.licenses[i].type then table.insert(elements, { - label = data.licenses[i].label, - type = data.licenses[i].type + label = playerData.licenses[i].label, + type = playerData.licenses[i].type }) end end end - if Config.EnableESXIdentity then - targetName = data.firstname .. ' ' .. data.lastname - else - targetName = data.name - end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'manage_license', { title = _U('license_revoke'), align = 'top-left', elements = elements, }, function(data, menu) - ESX.ShowNotification(_U('licence_you_revoked', data.current.label, targetName)) + ESX.ShowNotification(_U('licence_you_revoked', data.current.label, playerData.name)) TriggerServerEvent('esx_policejob:message', GetPlayerServerId(player), _U('license_revoked', data.current.label)) TriggerServerEvent('esx_license:removeLicense', GetPlayerServerId(player), data.current.type) diff --git a/locales/br.lua b/locales/br.lua index 9f040eab..13ad287c 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -108,7 +108,6 @@ Locales['br'] = { ['sex'] = 'sex: %s', ['dob'] = 'DOB: %s', ['height'] = 'height: %s', - ['id'] = 'ID: %s', ['bac'] = 'BAC: %s', ['unknown'] = 'unknown', ['male'] = 'male', diff --git a/locales/de.lua b/locales/de.lua index 2f5a9b07..eb6ee554 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -108,7 +108,6 @@ Locales['de'] = { ['sex'] = 'sex: %s', ['dob'] = 'DOB: %s', ['height'] = 'height: %s', - ['id'] = 'ID: %s', ['bac'] = 'BAC: %s', ['unknown'] = 'unknown', ['male'] = 'male', diff --git a/locales/en.lua b/locales/en.lua index 69a6b496..323f4e7d 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -108,7 +108,6 @@ Locales['en'] = { ['sex'] = 'sex: %s', ['dob'] = 'DOB: %s', ['height'] = 'height: %s', - ['id'] = 'ID: %s', ['bac'] = 'BAC: %s', ['unknown'] = 'unknown', ['male'] = 'male', @@ -117,7 +116,7 @@ Locales['en'] = { ['guns_label'] = '--- Guns ---', ['inventory_label'] = '--- Inventory ---', ['license_label'] = ' --- Licenses ---', - ['confiscate'] = 'confiscate %s', + ['confiscate'] = 'sieze illegal items', ['confiscate_weapon'] = 'confiscate %s with %s bullets', ['confiscate_inv'] = 'confiscate %sx %s', ['confiscate_dirty'] = 'confiscate dirty money: $%s', diff --git a/locales/es.lua b/locales/es.lua index 202b444e..c9c05cc5 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -108,7 +108,6 @@ Locales['es'] = { ['sex'] = 'sex: %s', ['dob'] = 'DOB: %s', ['height'] = 'height: %s', - ['id'] = 'ID: %s', ['bac'] = 'BAC: %s', ['unknown'] = 'unknown', ['male'] = 'male', diff --git a/locales/fi.lua b/locales/fi.lua index 89fce3ff..93c8af21 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -108,7 +108,6 @@ Locales['fi'] = { ['sex'] = 'sukupuoli: %s', ['dob'] = 'syntymäaika: %s', ['height'] = 'pituus: %s', - ['id'] = 'ID: %s', ['bac'] = 'alkometri: %s', ['unknown'] = 'tuntematon', ['male'] = 'mies', diff --git a/locales/fr.lua b/locales/fr.lua index 2165e130..8f3071cc 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -108,7 +108,6 @@ Locales['fr'] = { ['sex'] = 'sexe: %s', ['dob'] = 'DOB: %s', ['height'] = 'taille: %s', - ['id'] = 'ID: %s', ['bac'] = 'BAC: %s', ['unknown'] = 'inconnu', ['male'] = 'homme', diff --git a/locales/ko.lua b/locales/ko.lua index 2a523c0c..cf7fe418 100644 --- a/locales/ko.lua +++ b/locales/ko.lua @@ -108,7 +108,6 @@ Locales['ko'] = { ['sex'] = '성별: %s', ['dob'] = '생일: %s', ['height'] = '키: %s', - ['id'] = 'ID: %s', ['bac'] = '혈중 알코올 농도: %s', ['unknown'] = '알 수 없는', ['male'] = '남자', diff --git a/locales/pl.lua b/locales/pl.lua index 3ce1d255..210092ca 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -108,8 +108,7 @@ Locales['pl'] = { ['sex'] = 'płeć: %s', ['dob'] = 'data urodzenia: %s', ['height'] = 'wzrost: %s', - ['id'] = 'iD: %s', - ['bac'] = 'bAC: %s', + ['bac'] = 'BAC: %s', ['unknown'] = 'nieznany', ['male'] = 'mężczyzna', ['female'] = 'kobieta', diff --git a/locales/sv.lua b/locales/sv.lua index bbba9d4e..a79aef07 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -108,7 +108,6 @@ Locales['sv'] = { ['sex'] = 'kön: %s', ['dob'] = 'födelsedatum: %s', ['height'] = 'längd: %s', - ['id'] = 'ID: %s', ['bac'] = 'alkohol i blodet: %s', ['unknown'] = 'okänt', ['male'] = 'man', diff --git a/server/main.lua b/server/main.lua index e2b01235..06097983 100644 --- a/server/main.lua +++ b/server/main.lua @@ -9,7 +9,7 @@ end TriggerEvent('esx_phone:registerNumber', 'police', _U('alert_police'), true, true) TriggerEvent('esx_society:registerSociety', 'police', 'Police', 'society_police', 'society_police', 'society_police', {type = 'public'}) -RegisterServerEvent('esx_policejob:confiscatePlayerItem') +RegisterNetEvent('esx_policejob:confiscatePlayerItem') AddEventHandler('esx_policejob:confiscatePlayerItem', function(target, itemType, itemName, amount) local _source = source local sourceXPlayer = ESX.GetPlayerFromId(_source) @@ -57,7 +57,7 @@ AddEventHandler('esx_policejob:confiscatePlayerItem', function(target, itemType, end end) -RegisterServerEvent('esx_policejob:handcuff') +RegisterNetEvent('esx_policejob:handcuff') AddEventHandler('esx_policejob:handcuff', function(target) local xPlayer = ESX.GetPlayerFromId(source) @@ -68,7 +68,7 @@ AddEventHandler('esx_policejob:handcuff', function(target) end end) -RegisterServerEvent('esx_policejob:drag') +RegisterNetEvent('esx_policejob:drag') AddEventHandler('esx_policejob:drag', function(target) local xPlayer = ESX.GetPlayerFromId(source) @@ -79,7 +79,7 @@ AddEventHandler('esx_policejob:drag', function(target) end end) -RegisterServerEvent('esx_policejob:putInVehicle') +RegisterNetEvent('esx_policejob:putInVehicle') AddEventHandler('esx_policejob:putInVehicle', function(target) local xPlayer = ESX.GetPlayerFromId(source) @@ -90,7 +90,7 @@ AddEventHandler('esx_policejob:putInVehicle', function(target) end end) -RegisterServerEvent('esx_policejob:OutVehicle') +RegisterNetEvent('esx_policejob:OutVehicle') AddEventHandler('esx_policejob:OutVehicle', function(target) local xPlayer = ESX.GetPlayerFromId(source) @@ -101,7 +101,7 @@ AddEventHandler('esx_policejob:OutVehicle', function(target) end end) -RegisterServerEvent('esx_policejob:getStockItem') +RegisterNetEvent('esx_policejob:getStockItem') AddEventHandler('esx_policejob:getStockItem', function(itemName, count) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) @@ -126,7 +126,7 @@ AddEventHandler('esx_policejob:getStockItem', function(itemName, count) end) end) -RegisterServerEvent('esx_policejob:putStockItems') +RegisterNetEvent('esx_policejob:putStockItems') AddEventHandler('esx_policejob:putStockItems', function(itemName, count) local xPlayer = ESX.GetPlayerFromId(source) local sourceItem = xPlayer.getInventoryItem(itemName) @@ -145,68 +145,44 @@ AddEventHandler('esx_policejob:putStockItems', function(itemName, count) end) end) -ESX.RegisterServerCallback('esx_policejob:getOtherPlayerData', function(source, cb, target) - if Config.EnableESXIdentity then - local xPlayer = ESX.GetPlayerFromId(target) - local result = MySQL.Sync.fetchAll('SELECT firstname, lastname, sex, dateofbirth, height FROM users WHERE identifier = @identifier', { - ['@identifier'] = xPlayer.identifier - }) +ESX.RegisterServerCallback('esx_policejob:getOtherPlayerData', function(source, cb, target, notify) + local xPlayer = ESX.GetPlayerFromId(target) - local firstname = result[1].firstname - local lastname = result[1].lastname - local sex = result[1].sex - local dob = result[1].dateofbirth - local height = result[1].height + if notify then + xPlayer.showNotification(_U('being_searched')) + end + if xPlayer then local data = { - name = GetPlayerName(target), - job = xPlayer.job, - inventory = xPlayer.inventory, - accounts = xPlayer.accounts, - weapons = xPlayer.loadout, - firstname = firstname, - lastname = lastname, - sex = sex, - dob = dob, - height = height + name = xPlayer.getName(), + job = xPlayer.job.label, + grade = xPlayer.job.grade_label, + inventory = xPlayer.getInventory(), + accounts = xPlayer.getAccounts(), + weapons = xPlayer.getLoadout() } - TriggerEvent('esx_status:getStatus', target, 'drunk', function(status) - if status ~= nil then - data.drunk = math.floor(status.percent) - end - end) + if Config.EnableESXIdentity then + data.dob = xPlayer.get('dateofbirth') + data.height = xPlayer.get('height') - if Config.EnableLicenses then - TriggerEvent('esx_license:getLicenses', target, function(licenses) - data.licenses = licenses - cb(data) - end) - else - cb(data) + if xPlayer.get('sex') == 'm' then data.sex = 'male' else data.sex = 'female' end end - else - local xPlayer = ESX.GetPlayerFromId(target) - - local data = { - name = GetPlayerName(target), - job = xPlayer.job, - inventory = xPlayer.inventory, - accounts = xPlayer.accounts, - weapons = xPlayer.loadout - } TriggerEvent('esx_status:getStatus', target, 'drunk', function(status) if status then - data.drunk = math.floor(status.percent) + data.drunk = ESX.Math.Round(status.percent) + end + + if Config.EnableLicenses then + TriggerEvent('esx_license:getLicenses', target, function(licenses) + data.licenses = licenses + cb(data) + end) + else + cb(data) end end) - - TriggerEvent('esx_license:getLicenses', target, function(licenses) - data.licenses = licenses - end) - - cb(data) end end) @@ -219,28 +195,35 @@ ESX.RegisterServerCallback('esx_policejob:getFineList', function(source, cb, cat 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 - } + local retrivedInfo = {plate = plate} if result[1] then - MySQL.Async.fetchAll('SELECT name, firstname, lastname FROM users WHERE identifier = @identifier', { - ['@identifier'] = result[1].owner - }, function(result2) - - if Config.EnableESXIdentity then - retrivedInfo.owner = result2[1].firstname .. ' ' .. result2[1].lastname - else - retrivedInfo.owner = result2[1].name - end + local xPlayer = ESX.GetPlayerFromIdentifier(result[1].owner) + -- is the owner online? + if xPlayer then + retrivedInfo.owner = xPlayer.getName() cb(retrivedInfo) - end) + else + MySQL.Async.fetchAll('SELECT name, firstname, lastname FROM users WHERE identifier = @identifier', { + ['@identifier'] = result[1].owner + }, function(result2) + if result2[1] then + if Config.EnableESXIdentity then + retrivedInfo.owner = ('%s %s'):format(result2[1].firstname, result2[1].lastname) + else + retrivedInfo.owner = result2[1].name + end + + cb(retrivedInfo) + else + cb(retrivedInfo) + end + end) + end else cb(retrivedInfo) end @@ -251,14 +234,13 @@ ESX.RegisterServerCallback('esx_policejob:getVehicleFromPlate', function(source, MySQL.Async.fetchAll('SELECT owner FROM owned_vehicles WHERE plate = @plate', { ['@plate'] = plate }, function(result) - if result[1] ~= nil then - + if result[1] then MySQL.Async.fetchAll('SELECT name, firstname, lastname FROM users WHERE identifier = @identifier', { ['@identifier'] = result[1].owner }, function(result2) if Config.EnableESXIdentity then - cb(result2[1].firstname .. ' ' .. result2[1].lastname, true) + cb(('%s %s'):format(result2[1].firstname, result2[1].lastname), true) else cb(result2[1].name, true) end @@ -290,12 +272,7 @@ ESX.RegisterServerCallback('esx_policejob:addArmoryWeapon', function(source, cb, end TriggerEvent('esx_datastore:getSharedDataStore', 'society_police', function(store) - local weapons = store.get('weapons') - - if weapons == nil then - weapons = {} - end - + local weapons = store.get('weapons') or {} local foundWeapon = false for i=1, #weapons, 1 do @@ -323,12 +300,7 @@ ESX.RegisterServerCallback('esx_policejob:removeArmoryWeapon', function(source, xPlayer.addWeapon(weaponName, 500) TriggerEvent('esx_datastore:getSharedDataStore', 'society_police', function(store) - - local weapons = store.get('weapons') - - if weapons == nil then - weapons = {} - end + local weapons = store.get('weapons') or {} local foundWeapon = false @@ -342,7 +314,7 @@ ESX.RegisterServerCallback('esx_policejob:removeArmoryWeapon', function(source, if not foundWeapon then table.insert(weapons, { - name = weaponName, + name = weaponName, count = 0 }) end @@ -382,7 +354,6 @@ ESX.RegisterServerCallback('esx_policejob:buyWeapon', function(source, cb, weapo elseif type == 2 then local price = selectedWeapon.components[componentNum] local weaponNum, weapon = ESX.GetWeapon(weaponName) - local component = weapon.components[componentNum] if component then @@ -402,7 +373,6 @@ ESX.RegisterServerCallback('esx_policejob:buyWeapon', function(source, cb, weapo end end) - ESX.RegisterServerCallback('esx_policejob:buyJobVehicle', function(source, cb, vehicleProps, type) local xPlayer = ESX.GetPlayerFromId(source) local price = getPriceFromHash(vehicleProps.model, xPlayer.job.grade_name, type) @@ -464,7 +434,6 @@ ESX.RegisterServerCallback('esx_policejob:storeNearbyVehicle', function(source, end end) end - end) function getPriceFromHash(hashKey, jobGrade, type) @@ -506,37 +475,36 @@ ESX.RegisterServerCallback('esx_policejob:getPlayerInventory', function(source, local xPlayer = ESX.GetPlayerFromId(source) local items = xPlayer.inventory - cb( { items = items } ) + cb({items = items}) end) AddEventHandler('playerDropped', function() -- Save the source in case we lose it (which happens a lot) - local _source = source + local playerId = source -- Did the player ever join? - if _source ~= nil then - local xPlayer = ESX.GetPlayerFromId(_source) + if playerId then + local xPlayer = ESX.GetPlayerFromId(playerId) -- Is it worth telling all clients to refresh? - if xPlayer ~= nil and xPlayer.job ~= nil and xPlayer.job.name == 'police' then + if xPlayer and xPlayer.job.name == 'police' then Citizen.Wait(5000) TriggerClientEvent('esx_policejob:updateBlip', -1) end end end) -RegisterServerEvent('esx_policejob:spawned') +RegisterNetEvent('esx_policejob:spawned') AddEventHandler('esx_policejob:spawned', function() - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) + local xPlayer = ESX.GetPlayerFromId(playerId) - if xPlayer ~= nil and xPlayer.job ~= nil and xPlayer.job.name == 'police' then + if xPlayer and xPlayer.job.name == 'police' then Citizen.Wait(5000) TriggerClientEvent('esx_policejob:updateBlip', -1) end end) -RegisterServerEvent('esx_policejob:forceBlip') +RegisterNetEvent('esx_policejob:forceBlip') AddEventHandler('esx_policejob:forceBlip', function() TriggerClientEvent('esx_policejob:updateBlip', -1) end) @@ -553,8 +521,3 @@ AddEventHandler('onResourceStop', function(resource) TriggerEvent('esx_phone:removeNumber', 'police') end end) - -RegisterServerEvent('esx_policejob:message') -AddEventHandler('esx_policejob:message', function(target, msg) - TriggerClientEvent('esx:showNotification', target, msg) -end) From 7cf30361542d95b059d23ffdeae734c8bce09378 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 19 Jan 2020 16:38:59 +0100 Subject: [PATCH 2421/3224] Minor adjustments --- client/job.lua | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/client/job.lua b/client/job.lua index 2434ca4f..013e9e5e 100644 --- a/client/job.lua +++ b/client/job.lua @@ -149,7 +149,7 @@ function revivePlayer(closestPlayer) Citizen.Wait(900) ESX.Streaming.RequestAnimDict(lib, function() - TaskPlayAnim(playerPed, lib, anim, 8.0, -8.0, -1, 0, 0, false, false, false) + TaskPlayAnim(playerPed, lib, anim, 8.0, -8.0, -1, 0, 0.0, false, false, false) end) end @@ -724,16 +724,13 @@ function OpenShopMenu(elements, restoreCoords, shopCoords) align = 'top-left', elements = elements }, function(data, menu) - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop_confirm', { title = _U('vehicleshop_confirm', data.current.name, data.current.price), align = 'top-left', elements = { - { label = _U('confirm_no'), value = 'no' }, - { label = _U('confirm_yes'), value = 'yes' } - } - }, function(data2, menu2) - + {label = _U('confirm_no'), value = 'no'}, + {label = _U('confirm_yes'), value = 'yes'} + }}, function(data2, menu2) if data2.current.value == 'yes' then local newPlate = exports['esx_vehicleshop']:GeneratePlate() local vehicle = GetVehiclePedIsIn(playerPed, false) From ecb553f23cccc7f4520c8ab70c2a90a307d9c186 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 19 Jan 2020 16:44:22 +0100 Subject: [PATCH 2422/3224] Minor adjustments --- client/job.lua | 21 +++++--------- config.lua | 79 +++++++++++++++++++++++--------------------------- 2 files changed, 44 insertions(+), 56 deletions(-) diff --git a/client/job.lua b/client/job.lua index 013e9e5e..c3ee0617 100644 --- a/client/job.lua +++ b/client/job.lua @@ -32,7 +32,6 @@ function OpenAmbulanceActionsMenu() end function OpenMobileAmbulanceActionsMenu() - ESX.UI.Menu.CloseAll() ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'mobile_ambulance_actions', { @@ -40,8 +39,7 @@ function OpenMobileAmbulanceActionsMenu() align = 'top-left', elements = { {label = _U('ems_menu'), value = 'citizen_interaction'} - } - }, function(data, menu) + }}, function(data, menu) if data.current.value == 'citizen_interaction' then ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'citizen_interaction', { title = _U('ems_menu_title'), @@ -51,8 +49,7 @@ function OpenMobileAmbulanceActionsMenu() {label = _U('ems_menu_small'), value = 'small'}, {label = _U('ems_menu_big'), value = 'big'}, {label = _U('ems_menu_putincar'), value = 'put_in_vehicle'} - } - }, function(data, menu) + }}, function(data, menu) if isBusy then return end local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() @@ -60,11 +57,9 @@ function OpenMobileAmbulanceActionsMenu() if closestPlayer == -1 or closestDistance > 1.0 then ESX.ShowNotification(_U('no_players')) else - if data.current.value == 'revive' then revivePlayer(closestPlayer) elseif data.current.value == 'small' then - ESX.TriggerServerCallback('esx_ambulancejob:getItemAmount', function(quantity) if quantity > 0 then local closestPlayerPed = GetPlayerPed(closestPlayer) @@ -195,7 +190,7 @@ Citizen.CreateThread(function() -- Ambulance Actions for k,v in ipairs(hospital.AmbulanceActions) do - local distance = GetDistanceBetweenCoords(playerCoords, v, true) + local distance = #(playerCoords - v) if distance < Config.DrawDistance then DrawMarker(Config.Marker.type, v, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Config.Marker.x, Config.Marker.y, Config.Marker.z, Config.Marker.r, Config.Marker.g, Config.Marker.b, Config.Marker.a, false, false, 2, Config.Marker.rotate, nil, nil, false) @@ -209,7 +204,7 @@ Citizen.CreateThread(function() -- Pharmacies for k,v in ipairs(hospital.Pharmacies) do - local distance = GetDistanceBetweenCoords(playerCoords, v, true) + local distance = #(playerCoords - v) if distance < Config.DrawDistance then DrawMarker(Config.Marker.type, v, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Config.Marker.x, Config.Marker.y, Config.Marker.z, Config.Marker.r, Config.Marker.g, Config.Marker.b, Config.Marker.a, false, false, 2, Config.Marker.rotate, nil, nil, false) @@ -223,7 +218,7 @@ Citizen.CreateThread(function() -- Vehicle Spawners for k,v in ipairs(hospital.Vehicles) do - local distance = GetDistanceBetweenCoords(playerCoords, v.Spawner, true) + local distance = #(playerCoords - v.Spawner) if distance < Config.DrawDistance then DrawMarker(v.Marker.type, v.Spawner, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Marker.x, v.Marker.y, v.Marker.z, v.Marker.r, v.Marker.g, v.Marker.b, v.Marker.a, false, false, 2, v.Marker.rotate, nil, nil, false) @@ -237,7 +232,7 @@ Citizen.CreateThread(function() -- Helicopter Spawners for k,v in ipairs(hospital.Helicopters) do - local distance = GetDistanceBetweenCoords(playerCoords, v.Spawner, true) + local distance = #(playerCoords - v.Spawner) if distance < Config.DrawDistance then DrawMarker(v.Marker.type, v.Spawner, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Marker.x, v.Marker.y, v.Marker.z, v.Marker.r, v.Marker.g, v.Marker.b, v.Marker.a, false, false, 2, v.Marker.rotate, nil, nil, false) @@ -251,7 +246,7 @@ Citizen.CreateThread(function() -- Fast Travels for k,v in ipairs(hospital.FastTravels) do - local distance = GetDistanceBetweenCoords(playerCoords, v.From, true) + local distance = #(playerCoords - v.From) if distance < Config.DrawDistance then DrawMarker(v.Marker.type, v.From, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Marker.x, v.Marker.y, v.Marker.z, v.Marker.r, v.Marker.g, v.Marker.b, v.Marker.a, false, false, 2, v.Marker.rotate, nil, nil, false) @@ -266,7 +261,7 @@ Citizen.CreateThread(function() -- Fast Travels (Prompt) for k,v in ipairs(hospital.FastTravelsPrompt) do - local distance = GetDistanceBetweenCoords(playerCoords, v.From, true) + local distance = #(playerCoords - v.From) if distance < Config.DrawDistance then DrawMarker(v.Marker.type, v.From, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Marker.x, v.Marker.y, v.Marker.z, v.Marker.r, v.Marker.g, v.Marker.b, v.Marker.a, false, false, 2, v.Marker.rotate, nil, nil, false) diff --git a/config.lua b/config.lua index 8a37c47c..20e848f9 100644 --- a/config.lua +++ b/config.lua @@ -2,7 +2,7 @@ Config = {} Config.DrawDistance = 100.0 -Config.Marker = { type = 1, x = 1.5, y = 1.5, z = 0.5, r = 102, g = 0, b = 102, a = 100, rotate = false } +Config.Marker = {type = 1, x = 1.5, y = 1.5, z = 0.5, r = 102, g = 0, b = 102, a = 100, rotate = false} Config.ReviveReward = 700 -- revive reward, set to 0 if you don't want it enabled Config.AntiCombatLog = true -- enable anti-combat logging? @@ -10,11 +10,8 @@ Config.LoadIpl = true -- disable if you're using fivem-ipl or Config.Locale = 'fr' -local second = 1000 -local minute = 60 * second - -Config.EarlyRespawnTimer = 2 * minute -- Time til respawn is available -Config.BleedoutTimer = 10 * minute -- Time til the player bleeds out +Config.EarlyRespawnTimer = 60000 * 1 -- time til respawn is available +Config.BleedoutTimer = 60000 * 10 -- time til the player bleeds out Config.EnablePlayerManagement = false @@ -26,7 +23,7 @@ Config.RemoveItemsAfterRPDeath = true Config.EarlyRespawnFine = false Config.EarlyRespawnFineAmount = 5000 -Config.RespawnPoint = { coords = vector3(341.0, -1397.3, 32.5), heading = 48.5 } +Config.RespawnPoint = {coords = vector3(341.0, -1397.3, 32.5), heading = 48.5} Config.Hospitals = { @@ -51,11 +48,11 @@ Config.Hospitals = { { Spawner = vector3(307.7, -1433.4, 30.0), InsideShop = vector3(446.7, -1355.6, 43.5), - Marker = { type = 36, x = 1.0, y = 1.0, z = 1.0, r = 100, g = 50, b = 200, a = 100, rotate = true }, + Marker = {type = 36, x = 1.0, y = 1.0, z = 1.0, r = 100, g = 50, b = 200, a = 100, rotate = true}, SpawnPoints = { - { coords = vector3(297.2, -1429.5, 29.8), heading = 227.6, radius = 4.0 }, - { coords = vector3(294.0, -1433.1, 29.8), heading = 227.6, radius = 4.0 }, - { coords = vector3(309.4, -1442.5, 29.8), heading = 227.6, radius = 6.0 } + {coords = vector3(297.2, -1429.5, 29.8), heading = 227.6, radius = 4.0}, + {coords = vector3(294.0, -1433.1, 29.8), heading = 227.6, radius = 4.0}, + {coords = vector3(309.4, -1442.5, 29.8), heading = 227.6, radius = 6.0} } } }, @@ -64,10 +61,10 @@ Config.Hospitals = { { Spawner = vector3(317.5, -1449.5, 46.5), InsideShop = vector3(305.6, -1419.7, 41.5), - Marker = { type = 34, x = 1.5, y = 1.5, z = 1.5, r = 100, g = 150, b = 150, a = 100, rotate = true }, + Marker = {type = 34, x = 1.5, y = 1.5, z = 1.5, r = 100, g = 150, b = 150, a = 100, rotate = true}, SpawnPoints = { - { coords = vector3(313.5, -1465.1, 46.5), heading = 142.7, radius = 10.0 }, - { coords = vector3(299.5, -1453.2, 46.5), heading = 142.7, radius = 10.0 } + {coords = vector3(313.5, -1465.1, 46.5), heading = 142.7, radius = 10.0}, + {coords = vector3(299.5, -1453.2, 46.5), heading = 142.7, radius = 10.0} } } }, @@ -75,53 +72,53 @@ Config.Hospitals = { FastTravels = { { From = vector3(294.7, -1448.1, 29.0), - To = { coords = vector3(272.8, -1358.8, 23.5), heading = 0.0 }, - Marker = { type = 1, x = 2.0, y = 2.0, z = 0.5, r = 102, g = 0, b = 102, a = 100, rotate = false } + To = {coords = vector3(272.8, -1358.8, 23.5), heading = 0.0}, + Marker = {type = 1, x = 2.0, y = 2.0, z = 0.5, r = 102, g = 0, b = 102, a = 100, rotate = false} }, { From = vector3(275.3, -1361, 23.5), - To = { coords = vector3(295.8, -1446.5, 28.9), heading = 0.0 }, - Marker = { type = 1, x = 2.0, y = 2.0, z = 0.5, r = 102, g = 0, b = 102, a = 100, rotate = false } + To = {coords = vector3(295.8, -1446.5, 28.9), heading = 0.0}, + Marker = {type = 1, x = 2.0, y = 2.0, z = 0.5, r = 102, g = 0, b = 102, a = 100, rotate = false} }, { From = vector3(247.3, -1371.5, 23.5), - To = { coords = vector3(333.1, -1434.9, 45.5), heading = 138.6 }, - Marker = { type = 1, x = 1.5, y = 1.5, z = 0.5, r = 102, g = 0, b = 102, a = 100, rotate = false } + To = {coords = vector3(333.1, -1434.9, 45.5), heading = 138.6}, + Marker = {type = 1, x = 1.5, y = 1.5, z = 0.5, r = 102, g = 0, b = 102, a = 100, rotate = false} }, { From = vector3(335.5, -1432.0, 45.50), - To = { coords = vector3(249.1, -1369.6, 23.5), heading = 0.0 }, - Marker = { type = 1, x = 2.0, y = 2.0, z = 0.5, r = 102, g = 0, b = 102, a = 100, rotate = false } + To = {coords = vector3(249.1, -1369.6, 23.5), heading = 0.0}, + Marker = {type = 1, x = 2.0, y = 2.0, z = 0.5, r = 102, g = 0, b = 102, a = 100, rotate = false} }, { From = vector3(234.5, -1373.7, 20.9), - To = { coords = vector3(320.9, -1478.6, 28.8), heading = 0.0 }, - Marker = { type = 1, x = 1.5, y = 1.5, z = 1.0, r = 102, g = 0, b = 102, a = 100, rotate = false } + To = {coords = vector3(320.9, -1478.6, 28.8), heading = 0.0}, + Marker = {type = 1, x = 1.5, y = 1.5, z = 1.0, r = 102, g = 0, b = 102, a = 100, rotate = false} }, { From = vector3(317.9, -1476.1, 28.9), - To = { coords = vector3(238.6, -1368.4, 23.5), heading = 0.0 }, - Marker = { type = 1, x = 1.5, y = 1.5, z = 1.0, r = 102, g = 0, b = 102, a = 100, rotate = false } + To = {coords = vector3(238.6, -1368.4, 23.5), heading = 0.0}, + Marker = {type = 1, x = 1.5, y = 1.5, z = 1.0, r = 102, g = 0, b = 102, a = 100, rotate = false} } }, FastTravelsPrompt = { { From = vector3(237.4, -1373.8, 26.0), - To = { coords = vector3(251.9, -1363.3, 38.5), heading = 0.0 }, - Marker = { type = 1, x = 1.5, y = 1.5, z = 0.5, r = 102, g = 0, b = 102, a = 100, rotate = false }, + To = {coords = vector3(251.9, -1363.3, 38.5), heading = 0.0}, + Marker = {type = 1, x = 1.5, y = 1.5, z = 0.5, r = 102, g = 0, b = 102, a = 100, rotate = false}, Prompt = _U('fast_travel') }, { From = vector3(256.5, -1357.7, 36.0), - To = { coords = vector3(235.4, -1372.8, 26.3), heading = 0.0 }, - Marker = { type = 1, x = 1.5, y = 1.5, z = 0.5, r = 102, g = 0, b = 102, a = 100, rotate = false }, + To = {coords = vector3(235.4, -1372.8, 26.3), heading = 0.0}, + Marker = {type = 1, x = 1.5, y = 1.5, z = 0.5, r = 102, g = 0, b = 102, a = 100, rotate = false}, Prompt = _U('fast_travel') } } @@ -130,41 +127,37 @@ Config.Hospitals = { } Config.AuthorizedVehicles = { - ambulance = { - { model = 'ambulance', label = 'Ambulance Van', price = 5000} + {model = 'ambulance', label = 'Ambulance Van', price = 5000} }, doctor = { - { model = 'ambulance', label = 'Ambulance Van', price = 4500} + {model = 'ambulance', label = 'Ambulance Van', price = 4500} }, chief_doctor = { - { model = 'ambulance', label = 'Ambulance Van', price = 3000} + {model = 'ambulance', label = 'Ambulance Van', price = 3000} }, boss = { - { model = 'ambulance', label = 'Ambulance Van', price = 2000} + {model = 'ambulance', label = 'Ambulance Van', price = 2000} } - } Config.AuthorizedHelicopters = { - ambulance = {}, doctor = { - { model = 'buzzard2', label = 'Nagasaki Buzzard', price = 150000 } + {model = 'buzzard2', label = 'Nagasaki Buzzard', price = 150000} }, chief_doctor = { - { model = 'buzzard2', label = 'Nagasaki Buzzard', price = 150000 }, - { model = 'seasparrow', label = 'Sea Sparrow', price = 300000 } + {model = 'buzzard2', label = 'Nagasaki Buzzard', price = 150000}, + {model = 'seasparrow', label = 'Sea Sparrow', price = 300000} }, boss = { - { model = 'buzzard2', label = 'Nagasaki Buzzard', price = 10000 }, - { model = 'seasparrow', label = 'Sea Sparrow', price = 250000 } + {model = 'buzzard2', label = 'Nagasaki Buzzard', price = 10000}, + {model = 'seasparrow', label = 'Sea Sparrow', price = 250000} } - } From 950ea7e626bb80ec8419db6d4e4e0b58698858d2 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 16:45:08 +0100 Subject: [PATCH 2423/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename __resource.lua => fxmanifest.lua (90%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 90% rename from __resource.lua rename to fxmanifest.lua index ec94a2c4..85852ca4 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Police Job' @@ -39,4 +41,4 @@ dependencies { 'es_extended', 'esx_billing', 'esx_vehicleshop' -} \ No newline at end of file +} From 6b056fe421b1ccffef13b15f850a2ceb822a97ec Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 16:47:27 +0100 Subject: [PATCH 2424/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename __resource.lua => fxmanifest.lua (90%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 90% rename from __resource.lua rename to fxmanifest.lua index f5f45d38..7acca84c 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Ambulance Job' @@ -38,4 +40,4 @@ dependencies { 'es_extended', 'esx_skin', 'esx_vehicleshop' -} \ No newline at end of file +} From e35d754e62a1c12e867a282b439dbd02f07716eb Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 16:49:27 +0100 Subject: [PATCH 2425/3224] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a1740479..5271675b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# fxserver-esx_optionalneeds -FXServer ESX Optional Needs +# esx_optionalneeds +ESX Optional Needs [REQUIREMENTS] - esx_status https://github.com/ESX-Org/esx_status From 245f6ddda2aa29929bf6bf0c78dd917e7210e575 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 16:49:57 +0100 Subject: [PATCH 2426/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (79%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 79% rename from __resource.lua rename to fxmanifest.lua index b85dfa97..b658cece 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Optional Needs' From 29714df92a36ea79a4e3e19db6349adf4a212b47 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 16:51:07 +0100 Subject: [PATCH 2427/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (89%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 89% rename from __resource.lua rename to fxmanifest.lua index e5b31921..bf837fae 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Accessories' From 1532d50fa82962941e72ad456a7c516dbee1c1db Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 16:52:17 +0100 Subject: [PATCH 2428/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/__resource.lua b/__resource.lua index 7a772331..83665169 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Clothes Shop' @@ -36,4 +38,4 @@ client_scripts { dependencies { 'es_extended', 'esx_skin' -} \ No newline at end of file +} From 126a30b75d7001d07adb209d6bba27fc7c580aa5 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 16:52:29 +0100 Subject: [PATCH 2429/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename __resource.lua => fxmanifest.lua (100%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 100% rename from __resource.lua rename to fxmanifest.lua From fb16b7970ac787a373ebcad8930957fa70b62498 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 16:53:30 +0100 Subject: [PATCH 2430/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (87%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 87% rename from __resource.lua rename to fxmanifest.lua index 696eed11..ebdbf7df 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX LS Customs' From 5cbc84f766c86fe801e4cc7fbeba65f17b869ab4 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 16:54:56 +0100 Subject: [PATCH 2431/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (90%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 90% rename from __resource.lua rename to fxmanifest.lua index a4c1ad1e..4465e17a 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Real Estate Job' From cfcc2cc3d7529d000b0a4b4bad47f8dcab08deec Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 16:56:22 +0100 Subject: [PATCH 2432/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (89%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 89% rename from __resource.lua rename to fxmanifest.lua index 06605d69..8267d7a1 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Mechanic Job' From bf5e11bd9922ea6ab954e3ac238478d2c2b01f1d Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 16:57:02 +0100 Subject: [PATCH 2433/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (88%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 88% rename from __resource.lua rename to fxmanifest.lua index bbb62299..f26eec32 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Garage' From 39c7768f7aac5abfaf1727365c7c3781b556201d Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 16:57:45 +0100 Subject: [PATCH 2434/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (80%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 80% rename from __resource.lua rename to fxmanifest.lua index e41f5e03..621dabd1 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Voice Controller' From 5e24910a43ebdcb3520cb5ec03be131d03550b61 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 16:59:02 +0100 Subject: [PATCH 2435/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (83%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 83% rename from __resource.lua rename to fxmanifest.lua index 72fc260d..4ce6f7f6 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Holdup' From c64b2b078f0d438bcf595281cddd973f6d93412c Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:00:24 +0100 Subject: [PATCH 2436/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (90%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 90% rename from __resource.lua rename to fxmanifest.lua index 96ac4d28..640e4723 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Society' From fe0d3b617463c1950aa0d9aae3d36c55c591da41 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:01:04 +0100 Subject: [PATCH 2437/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename __resource.lua => fxmanifest.lua (84%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 84% rename from __resource.lua rename to fxmanifest.lua index 90167455..ff5ac70c 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Taxi Job' @@ -30,4 +32,4 @@ server_scripts { 'server/main.lua' } -dependency 'es_extended' \ No newline at end of file +dependency 'es_extended' From bfa26bf5f9de1613abaf0ed29bdc3e6d0ff0ab51 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:01:50 +0100 Subject: [PATCH 2438/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (80%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 80% rename from __resource.lua rename to fxmanifest.lua index 52714ec0..33537561 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'Skin Changer' From 98294c1ade977042f97aa99f2906e2e4d3e110f8 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:02:37 +0100 Subject: [PATCH 2439/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (90%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 90% rename from __resource.lua rename to fxmanifest.lua index 0b512cd0..ecee11cf 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Weapon Shop' From ee42aca4d8e3a65880f583136fcaf6c0094f8e28 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:03:28 +0100 Subject: [PATCH 2440/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (87%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 87% rename from __resource.lua rename to fxmanifest.lua index 101f3a7a..88bae9ed 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Drugs' From 5e6cd29ca84aaa954f8b5b304dd3b1a0a23a1e3a Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:04:01 +0100 Subject: [PATCH 2441/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename __resource.lua => fxmanifest.lua (85%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 85% rename from __resource.lua rename to fxmanifest.lua index 3222d8a6..638263f9 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Vehicle Shop' @@ -32,4 +34,4 @@ client_scripts { dependency 'es_extended' -export 'GeneratePlate' \ No newline at end of file +export 'GeneratePlate' From 39e31b40b0a285e662369d5978b0874b14376952 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:04:54 +0100 Subject: [PATCH 2442/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (80%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 80% rename from __resource.lua rename to fxmanifest.lua index 75959689..f3754627 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Whitelist' From 322ecdcb8565450cf886692a3f2cdd997f511010 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:05:28 +0100 Subject: [PATCH 2443/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename __resource.lua => fxmanifest.lua (77%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 77% rename from __resource.lua rename to fxmanifest.lua index 07f5c207..fdf64c89 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Identity' @@ -23,4 +25,4 @@ files { 'html/style.css' } -dependency 'es_extended' \ No newline at end of file +dependency 'es_extended' From 0cd967e4068ecb812326386dcda1cb014d6359ac Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:06:01 +0100 Subject: [PATCH 2444/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (82%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 82% rename from __resource.lua rename to fxmanifest.lua index 0685eab3..692acb9e 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX RP Chat' From 964a9ff1336885bcb53b08e22c72c6a87dba2b9a Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:06:38 +0100 Subject: [PATCH 2445/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename __resource.lua => fxmanifest.lua (86%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 86% rename from __resource.lua rename to fxmanifest.lua index 7ed7647b..c0669a48 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Billing' @@ -33,4 +35,4 @@ client_scripts { 'client/main.lua' } -dependency 'es_extended' \ No newline at end of file +dependency 'es_extended' From b6ed954020bfb739e437b064d58d7555fbb97a74 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:07:17 +0100 Subject: [PATCH 2446/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (73%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 73% rename from __resource.lua rename to fxmanifest.lua index df1af275..c91a36d5 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '05cfa83c-a124-4cfa-a768-c24a5811d8f9' +fx_version 'adamant' + +game 'gta5' description 'ESX Sit' From e282df14d8c63cd915967c954b1915eb60102b7f Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:07:42 +0100 Subject: [PATCH 2447/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename __resource.lua => fxmanifest.lua (53%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 53% rename from __resource.lua rename to fxmanifest.lua index 6adcb056..e7dda640 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Animations' @@ -9,4 +11,4 @@ client_scripts { 'client/main.lua' } -dependency 'es_extended' \ No newline at end of file +dependency 'es_extended' From 2ba4cafcafa7be33cba8b66373d11d5c9c37efef Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:08:25 +0100 Subject: [PATCH 2448/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename __resource.lua => fxmanifest.lua (92%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 92% rename from __resource.lua rename to fxmanifest.lua index 2cf3ecb0..b4f6e1cc 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Jobs' @@ -49,4 +51,4 @@ dependencies { 'esx_addonaccount', 'skinchanger', 'esx_skin' -} \ No newline at end of file +} From e3ce8299aa17c8695e067b8c0ab0d8c2b8d8e346 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:09:08 +0100 Subject: [PATCH 2449/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (89%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 89% rename from __resource.lua rename to fxmanifest.lua index 7f6be01c..dc2a4794 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Basic Needs' From 6bac44756a95fb0484c0a64c18dec75d7bb592c7 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:12:20 +0100 Subject: [PATCH 2450/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 ++++ 1 file changed, 4 insertions(+) rename __resource.lua => fxmanifest.lua (88%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 88% rename from __resource.lua rename to fxmanifest.lua index 74633228..d1049f6b 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,3 +1,7 @@ +fx_version 'adamant' + +game 'gta5' + description 'CruiseControl System for ESX' version '1.0.0' From 6f8587b391886359b22a2bc41bc78869d3940703 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 19 Jan 2020 17:14:33 +0100 Subject: [PATCH 2451/3224] Implemented dead player blips, closes #46 (read desc) - Fixed vehicles in vehicle shop not unloading - Use busy spinner instead of drawing when loading vehicles --- client/job.lua | 78 ++++++++++++++++++++++++++++++++----------------- client/main.lua | 30 ++++++------------- locales/br.lua | 1 - locales/cs.lua | 1 - locales/en.lua | 1 - locales/es.lua | 1 - locales/fi.lua | 1 - locales/fr.lua | 1 - locales/pl.lua | 1 - locales/sv.lua | 1 - server/main.lua | 50 ++++++++++++++++++++++++++----- 11 files changed, 102 insertions(+), 64 deletions(-) diff --git a/client/job.lua b/client/job.lua index c3ee0617..c0c3c06c 100644 --- a/client/job.lua +++ b/client/job.lua @@ -1,6 +1,6 @@ local CurrentAction, CurrentActionMsg, CurrentActionData = nil, '', {} local HasAlreadyEnteredMarker, LastHospital, LastPart, LastPartNum -local isBusy = false +local isBusy, deadPlayers, deadPlayerBlips, isOnDuty = false, {}, {}, false local spawnedVehicles, isInShopMenu = {}, false function OpenAmbulanceActionsMenu() @@ -407,11 +407,16 @@ function OpenCloakroomMenu() elements = { {label = _U('ems_clothes_civil'), value = 'citizen_wear'}, {label = _U('ems_clothes_ems'), value = 'ambulance_wear'}, - } - }, function(data, menu) + }}, function(data, menu) if data.current.value == 'citizen_wear' then ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) TriggerEvent('skinchanger:loadSkin', skin) + isOnDuty = false + + for playerId,v in pairs(deadPlayerBlips) do + RemoveBlip(v) + deadPlayerBlips[playerId] = nil + end end) elseif data.current.value == 'ambulance_wear' then ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) @@ -420,6 +425,8 @@ function OpenCloakroomMenu() else TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_female) end + + isOnDuty = true end) end @@ -768,12 +775,13 @@ function OpenShopMenu(elements, restoreCoords, shopCoords) ESX.Game.Teleport(playerPed, restoreCoords) end, function(data, menu) DeleteSpawnedVehicles() - WaitForVehicleToLoad(data.current.model) + ESX.Game.SpawnLocalVehicle(data.current.model, shopCoords, 0.0, function(vehicle) table.insert(spawnedVehicles, vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) FreezeEntityPosition(vehicle, true) + SetModelAsNoLongerNeeded(data.current.model) end) end) @@ -782,6 +790,7 @@ function OpenShopMenu(elements, restoreCoords, shopCoords) table.insert(spawnedVehicles, vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) FreezeEntityPosition(vehicle, true) + SetModelAsNoLongerNeeded(elements[1].model) end) end @@ -812,35 +821,19 @@ function WaitForVehicleToLoad(modelHash) if not HasModelLoaded(modelHash) then RequestModel(modelHash) + BeginTextCommandBusyspinnerOn('STRING') + AddTextComponentSubstringPlayerName(_U('vehicleshop_awaiting_model')) + EndTextCommandBusyspinnerOn(4) + while not HasModelLoaded(modelHash) do Citizen.Wait(0) - - DisableControlAction(0, 27, true) - DisableControlAction(0, 173, true) - DisableControlAction(0, 174, true) - DisableControlAction(0, 175, true) - DisableControlAction(0, 176, true) -- ENTER key - DisableControlAction(0, 177, true) - - drawLoadingText(_U('vehicleshop_awaiting_model'), 255, 255, 255, 255) + DisableAllControlActions(0) end + + BusyspinnerOff() end end -function drawLoadingText(text, red, green, blue, alpha) - SetTextFont(4) - SetTextScale(0.0, 0.5) - SetTextColour(red, green, blue, alpha) - SetTextDropshadow(0, 0, 0, 0, 255) - SetTextDropShadow() - SetTextOutline() - SetTextCentre(true) - - BeginTextCommandDisplayText("STRING") - AddTextComponentSubstringPlayerName(text) - EndTextCommandDisplayText(0.5, 0.5) -end - function OpenPharmacyMenu() ESX.UI.Menu.CloseAll() @@ -898,3 +891,34 @@ AddEventHandler('esx_ambulancejob:heal', function(healType, quiet) ESX.ShowNotification(_U('healed')) end end) + +RegisterNetEvent('esx_ambulancejob:setDeadPlayers') +AddEventHandler('esx_ambulancejob:setDeadPlayers', function(_deadPlayers) + deadPlayers = _deadPlayers + + if isOnDuty then + for playerId,v in pairs(deadPlayerBlips) do + RemoveBlip(v) + deadPlayerBlips[playerId] = nil + end + + for playerId,status in pairs(deadPlayers) do + if status == 'distress' then + local player = GetPlayerFromServerId(playerId) + local playerPed = GetPlayerPed(player) + local blip = AddBlipForEntity(playerPed) + + SetBlipSprite(blip, 303) + SetBlipColour(blip, 1) + SetBlipFlashes(blip, true) + SetBlipCategory(blip, 7) + + BeginTextCommandSetBlipName('STRING') + AddTextComponentSubstringPlayerName(_U('blip_dead')) + EndTextCommandSetBlipName(blip) + + deadPlayerBlips[playerId] = blip + end + end + end +end) diff --git a/client/main.lua b/client/main.lua index 517b6483..55f7689c 100644 --- a/client/main.lua +++ b/client/main.lua @@ -109,7 +109,7 @@ AddEventHandler('esx_ambulancejob:useItem', function(itemName) Citizen.Wait(0) DisableAllControlActions(0) end - + TriggerEvent('esx_ambulancejob:heal', 'big', true) ESX.ShowNotification(_U('used_medikit')) end) @@ -151,16 +151,8 @@ function StartDistressSignal() AddTextComponentSubstringPlayerName(_U('distress_send')) EndTextCommandDisplayText(0.175, 0.805) - if IsControlPressed(0, 47) then + if IsControlJustReleased(0, 47) then SendDistressSignal() - - Citizen.CreateThread(function() - Citizen.Wait(1000 * 60 * 5) - if isDead then - StartDistressSignal() - end - end) - break end end @@ -172,11 +164,7 @@ function SendDistressSignal() local coords = GetEntityCoords(playerPed) ESX.ShowNotification(_U('distress_sent')) - TriggerServerEvent('esx_phone:send', 'ambulance', _U('distress_message'), false, { - x = coords.x, - y = coords.y, - z = coords.z - }) + TriggerServerEvent('esx_ambulancejob:onPlayerDistress') end function DrawGenericTextThisFrame() @@ -195,9 +183,9 @@ function secondsToClock(seconds) if seconds <= 0 then return 0, 0 else - local hours = string.format("%02.f", math.floor(seconds / 3600)) - local mins = string.format("%02.f", math.floor(seconds / 60 - (hours * 60))) - local secs = string.format("%02.f", math.floor(seconds - hours * 3600 - mins * 60)) + local hours = string.format('%02.f', math.floor(seconds / 3600)) + local mins = string.format('%02.f', math.floor(seconds / 60 - (hours * 60))) + local secs = string.format('%02.f', math.floor(seconds - hours * 3600 - mins * 60)) return mins, secs end @@ -245,7 +233,7 @@ function StartDeathTimer() DrawGenericTextThisFrame() - SetTextEntry("STRING") + SetTextEntry('STRING') AddTextComponentString(text) DrawText(0.5, 0.8) end @@ -280,11 +268,11 @@ function StartDeathTimer() DrawGenericTextThisFrame() - SetTextEntry("STRING") + SetTextEntry('STRING') AddTextComponentString(text) DrawText(0.5, 0.8) end - + if bleedoutTimer < 1 and isDead then RemoveItemsAfterRPDeath() end diff --git a/locales/br.lua b/locales/br.lua index 3a96cd65..da8db727 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -77,7 +77,6 @@ Locales['br'] = { ['respawn_bleedout_fine_msg'] = 'você precisa pagar ~r~$%s~s~ para reviver', ['distress_send'] = 'pressione [~b~G~s~] enviar sinal de socorro', ['distress_sent'] = 'sinal de socorro foi enviado para as unidades disponíveis!', - ['distress_message'] = 'atenção médica necessária: cidadão inconsciente!', ['combatlog_message'] = 'você foi revivido porque deixou o servidor anteriormente quando estava morto.', -- Revive ['revive_help'] = 'reviver um cidadão', diff --git a/locales/cs.lua b/locales/cs.lua index 807ad4e2..f3a01344 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -77,7 +77,6 @@ Locales['cs'] = { ['respawn_bleedout_fine_msg'] = 'zaplatili jste ~r~$%s~s~ za respawn.', ['distress_send'] = 'stiskněte [~b~G~s~] pro vyslání tísňového signálu', ['distress_sent'] = 'tísňový signál byl vyslán dostupným jednotkám!', - ['distress_message'] = 'nutná lékařská péče: občan v bezvědomí!', ['combatlog_message'] = 'byli jste násilně oživeni, protože jste předtím opustili server, když jste byli mrtví.', -- Revive ['revive_help'] = 'oživit hráče', diff --git a/locales/en.lua b/locales/en.lua index ab37f814..eee39e22 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -77,7 +77,6 @@ Locales['en'] = { ['respawn_bleedout_fine_msg'] = 'you paid ~r~$%s~s~ to respawn.', ['distress_send'] = 'press [~b~G~s~] to send distress signal', ['distress_sent'] = 'distress signal has been sent to available units!', - ['distress_message'] = 'medical attention required: unconscious citizen!', ['combatlog_message'] = 'you have been force-respawned because you\'ve previously left the server when dead.', -- Revive ['revive_help'] = 'revive a player', diff --git a/locales/es.lua b/locales/es.lua index caad1d52..a9cec2aa 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -77,7 +77,6 @@ Locales['es'] = { ['respawn_bleedout_fine_msg'] = 'you paid ~r~$%s~s~ to respawn.', ['distress_send'] = 'press [~b~G~s~] to send distress signal', ['distress_sent'] = 'distress signal has been sent to available units!', - ['distress_message'] = 'medical attention required: unconscious citizen!', ['combatlog_message'] = 'you have been force-respawned because you\'ve previously left the server when dead.', -- Revive ['revive_help'] = 'reviver un jugador', diff --git a/locales/fi.lua b/locales/fi.lua index ecc1b36e..3ca1f5c6 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -77,7 +77,6 @@ Locales['fi'] = { ['respawn_bleedout_fine_msg'] = 'you paid ~r~$%s~s~ to respawn.', ['distress_send'] = 'press [~b~G~s~] to send distress signal', ['distress_sent'] = 'distress signal has been sent to available units!', - ['distress_message'] = 'medical attention required: unconscious citizen!', ['combatlog_message'] = 'you have been force-respawned because you\'ve previously left the server when dead.', -- Revive ['revive_help'] = 'elvytä pelaaja', diff --git a/locales/fr.lua b/locales/fr.lua index 24fb1a4c..e86658c7 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -77,7 +77,6 @@ Locales['fr'] = { ['respawn_bleedout_fine_msg'] = 'vous avez payé ~r~$%s~s~ pour être réanimer.', ['distress_send'] = 'appuyez sur [~b~G~s~] pour envoyer un signal de détresse', ['distress_sent'] = 'un signal a été envoyé à toutes les unités disponibles!', - ['distress_message'] = 'interventtion requise: citoyen inconscient!', ['combatlog_message'] = 'vous avez été réanimé de force car vous avez quitté le serveur.', -- Revive ['revive_help'] = 'relancer un joueur', diff --git a/locales/pl.lua b/locales/pl.lua index 7308e156..9d70f91e 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -77,7 +77,6 @@ Locales['pl'] = { ['respawn_bleedout_fine_msg'] = 'you paid ~r~$%s~s~ to respawn.', ['distress_send'] = 'press [~b~G~s~] to send distress signal', ['distress_sent'] = 'distress signal has been sent to available units!', - ['distress_message'] = 'medical attention required: unconscious citizen!', ['combatlog_message'] = 'you have been force-respawned because you\'ve previously left the server when dead.', -- Revive ['revive_help'] = 'ożyw gracza', diff --git a/locales/sv.lua b/locales/sv.lua index c52d1f33..773a0ebc 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -77,7 +77,6 @@ Locales['sv'] = { ['respawn_bleedout_fine_msg'] = 'du betalade ~r~%s SEK~s~ för att respawna.', ['distress_send'] = 'tryck ~b~[G]~s~ för att skicka nödsignal', ['distress_sent'] = 'nödsignal har skickats till samtliga enheter!', - ['distress_message'] = 'läkarvård krävs: medvetslös medborgare!', ['combatlog_message'] = 'du har force-respawnats på grund av att du lämnat servern medans du var död', -- Revive ['revive_help'] = 'återuppliva en spelare', diff --git a/server/main.lua b/server/main.lua index b9b7afc0..08eff022 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,8 +1,12 @@ ESX = nil -local playersHealing = {} +local playersHealing, deadPlayers = {}, {} TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) +TriggerEvent('esx_phone:registerNumber', 'ambulance', _U('alert_ambulance'), true, true) + +TriggerEvent('esx_society:registerSociety', 'ambulance', 'Ambulance', 'society_ambulance', 'society_ambulance', 'society_ambulance', {type = 'public'}) + RegisterNetEvent('esx_ambulancejob:revive') AddEventHandler('esx_ambulancejob:revive', function(playerId) local xPlayer = ESX.GetPlayerFromId(source) @@ -11,15 +15,49 @@ AddEventHandler('esx_ambulancejob:revive', function(playerId) local xTarget = ESX.GetPlayerFromId(playerId) if xTarget then - xPlayer.showNotification(_U('revive_complete_award', xTarget.name, Config.ReviveReward)) - xPlayer.addMoney(Config.ReviveReward) - xTarget.triggerEvent('esx_ambulancejob:revive') + if deadPlayers[playerId] then + xPlayer.showNotification(_U('revive_complete_award', xTarget.name, Config.ReviveReward)) + xPlayer.addMoney(Config.ReviveReward) + xTarget.triggerEvent('esx_ambulancejob:revive') + deadPlayers[playerId] = nil + else + xPlayer.showNotification(_U('player_not_unconscious')) + end else xPlayer.showNotification(_U('revive_fail_offline')) end end end) +RegisterNetEvent('esx:onPlayerDeath') +AddEventHandler('esx:onPlayerDeath', function(data) + deadPlayers[source] = 'dead' + TriggerClientEvent('esx_ambulancejob:setDeadPlayers', -1, deadPlayers) +end) + +RegisterNetEvent('esx_ambulancejob:onPlayerDistress') +AddEventHandler('esx_ambulancejob:onPlayerDistress', function() + if deadPlayers[source] then + deadPlayers[source] = 'distress' + TriggerClientEvent('esx_ambulancejob:setDeadPlayers', -1, deadPlayers) + end +end) + +RegisterNetEvent('esx_ambulancejob:onPlayerSpawn') +AddEventHandler('esx_ambulancejob:onPlayerSpawn', function() + if deadPlayers[source] then + deadPlayers[source] = nil + TriggerClientEvent('esx_ambulancejob:setDeadPlayers', -1, deadPlayers) + end +end) + +AddEventHandler('esx:playerDropped', function(playerId, reason) + if deadPlayers[playerId] then + deadPlayers[playerId] = nil + TriggerClientEvent('esx_ambulancejob:setDeadPlayers', -1, deadPlayers) + end +end) + RegisterNetEvent('esx_ambulancejob:heal') AddEventHandler('esx_ambulancejob:heal', function(target, type) local xPlayer = ESX.GetPlayerFromId(source) @@ -38,10 +76,6 @@ AddEventHandler('esx_ambulancejob:putInVehicle', function(target) end end) -TriggerEvent('esx_phone:registerNumber', 'ambulance', _U('alert_ambulance'), true, true) - -TriggerEvent('esx_society:registerSociety', 'ambulance', 'Ambulance', 'society_ambulance', 'society_ambulance', 'society_ambulance', {type = 'public'}) - ESX.RegisterServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) From 7b3f5edc4cde79cba02f6f582e95adcca475a8c5 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:17:35 +0100 Subject: [PATCH 2452/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (86%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 86% rename from __resource.lua rename to fxmanifest.lua index b5859d1f..6b03126e 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'Instance' From 516e1b0b41b57ba0b53de3e0a0dfcc3c262c7bb4 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:19:23 +0100 Subject: [PATCH 2453/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename __resource.lua => fxmanifest.lua (77%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 77% rename from __resource.lua rename to fxmanifest.lua index f5d3f588..047862ad 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Menu List' @@ -23,4 +25,4 @@ files { 'html/fonts/bankgothic.ttf' } -dependency 'es_extended' \ No newline at end of file +dependency 'es_extended' From 0b35d90e3e655256b4f140c36e2853da68ad3a19 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:19:57 +0100 Subject: [PATCH 2454/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (63%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 63% rename from __resource.lua rename to fxmanifest.lua index ca139253..b2389969 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Boilerplate' From 80be9a988ffd6a7131993a03514363e25e2755ef Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:20:27 +0100 Subject: [PATCH 2455/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename __resource.lua => fxmanifest.lua (74%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 74% rename from __resource.lua rename to fxmanifest.lua index 8d41f890..0f112e25 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Menu Dialog' @@ -20,4 +22,4 @@ files { 'html/fonts/bankgothic.ttf' } -dependency 'es_extended' \ No newline at end of file +dependency 'es_extended' From ffb733cfc703ffac426f95bb0d873654e8474ab3 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:21:15 +0100 Subject: [PATCH 2456/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename __resource.lua => fxmanifest.lua (91%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 91% rename from __resource.lua rename to fxmanifest.lua index 2f2390ac..8e318256 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Phone' @@ -55,4 +57,4 @@ files { 'html/img/icons/location.png' } -dependency 'es_extended' \ No newline at end of file +dependency 'es_extended' From b7a4ba0a987c44755e2cd0ab83f881a720e6b076 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:21:45 +0100 Subject: [PATCH 2457/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename __resource.lua => fxmanifest.lua (64%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 64% rename from __resource.lua rename to fxmanifest.lua index b403a312..534538e1 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Addon Account' @@ -10,4 +12,4 @@ server_scripts { 'server/main.lua' } -dependency 'es_extended' \ No newline at end of file +dependency 'es_extended' From c48849494dba2585036322d8b0a9455d5c44a2fb Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:22:16 +0100 Subject: [PATCH 2458/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename __resource.lua => fxmanifest.lua (84%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 84% rename from __resource.lua rename to fxmanifest.lua index b03b19df..733c50e0 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Banker job' @@ -30,4 +32,4 @@ client_scripts { 'client/main.lua' } -dependency 'es_extended' \ No newline at end of file +dependency 'es_extended' From c459aaaf3df283c0cbb7f30d49a5910bd567884f Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:23:34 +0100 Subject: [PATCH 2459/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename __resource.lua => fxmanifest.lua (58%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 58% rename from __resource.lua rename to fxmanifest.lua index 49fd7b07..babecdef 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Service' @@ -12,4 +14,4 @@ client_scripts { 'client/main.lua' } -dependency 'es_extended' \ No newline at end of file +dependency 'es_extended' From 4f3b02d92d3a0a543718410909cd7cfffe29a12c Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:24:11 +0100 Subject: [PATCH 2460/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (68%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 68% rename from __resource.lua rename to fxmanifest.lua index 438d4cb2..7f8b4beb 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX License' From 0af2a133bdd4a8d24c470b20d5a9be0eaf64d974 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:24:40 +0100 Subject: [PATCH 2461/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename __resource.lua => fxmanifest.lua (85%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 85% rename from __resource.lua rename to fxmanifest.lua index 91e2d952..03bc591a 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Boat' @@ -25,4 +27,4 @@ client_scripts { dependencies { 'es_extended', 'esx_vehicleshop' -} \ No newline at end of file +} From 996a0f9e3b8d9664a11c4069c88cf36104389cd6 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:25:02 +0100 Subject: [PATCH 2462/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename __resource.lua => fxmanifest.lua (64%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 64% rename from __resource.lua rename to fxmanifest.lua index 8362acc0..6680ece9 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Addon Inventory' @@ -10,4 +12,4 @@ server_scripts { 'server/main.lua' } -dependency 'es_extended' \ No newline at end of file +dependency 'es_extended' From fa268545cfb6576db9d3d0b6d2594b90edad54d5 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:25:44 +0100 Subject: [PATCH 2463/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (70%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 70% rename from __resource.lua rename to fxmanifest.lua index f9f6fe26..1b75cbf1 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Data Store' From 3bc0919760dbe9b06a6c85648af19a5eced34f21 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:26:24 +0100 Subject: [PATCH 2464/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (88%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 88% rename from __resource.lua rename to fxmanifest.lua index 3637c8ee..0c6cc685 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Barber Shop' From bb13bd9092e56d3261ee00fd5a9b1acd33867dc4 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:27:54 +0100 Subject: [PATCH 2465/3224] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 476ac2fc..b678dc87 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -# fxserver-esx_status -FXServer ESX Status +# esx_status +ESX Status [INSTALLATION] 1) CD in your resources/[esx] folder 2) Clone the repository ``` -git clone https://github.com/FXServer-ESX/fxserver-esx_status esx_status +git clone https://github.com/ESX-Org/esx_status esx_status ``` 3) Import esx_status.sql in your database 4) Add this in your server.cfg : From e98ad1f1a57d076cf588ed2cd66262fad28503e8 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:28:35 +0100 Subject: [PATCH 2466/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename __resource.lua => fxmanifest.lua (82%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 82% rename from __resource.lua rename to fxmanifest.lua index 57b90da0..fa08f8d4 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Status' @@ -22,4 +24,4 @@ files { 'html/ui.html', 'html/css/app.css', 'html/scripts/app.js' -} \ No newline at end of file +} From a02b54f196b0a84950404f38418f3aa3df400917 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:29:17 +0100 Subject: [PATCH 2467/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (84%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 84% rename from __resource.lua rename to fxmanifest.lua index da307f67..75a968b5 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Menu Default' From 8c2a00c4c473598ca2472275ceff796e89b111af Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:38:02 +0100 Subject: [PATCH 2468/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (89%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 89% rename from __resource.lua rename to fxmanifest.lua index a45df0e0..e51331a6 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Skin' From ca79838b7701b6e25b88a8efafcc45439373c596 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:40:22 +0100 Subject: [PATCH 2469/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (91%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 91% rename from __resource.lua rename to fxmanifest.lua index a5b84ec4..53d33fb4 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Property' From 0214e834783f14830ac9dcc79559ff4eebc69e9f Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:41:15 +0100 Subject: [PATCH 2470/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (89%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 89% rename from __resource.lua rename to fxmanifest.lua index bf1ee68e..3bb6d04d 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Shops' From 100d097b333d740eab02520d6b2a82bfc72d142e Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:41:44 +0100 Subject: [PATCH 2471/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (90%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 90% rename from __resource.lua rename to fxmanifest.lua index 631e975c..c1068048 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Job Listing' From 18e0fe37504835f67d007c43066b207a9112df57 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:42:15 +0100 Subject: [PATCH 2472/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename __resource.lua => fxmanifest.lua (88%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 88% rename from __resource.lua rename to fxmanifest.lua index 3f6c7f0e..83e9eaa1 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX Atm' @@ -42,4 +44,4 @@ files { 'html/scripts/app.js' } -dependency 'es_extended' \ No newline at end of file +dependency 'es_extended' From 168cb1710f40eba0f9437540bac6cd68225520e6 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:47:42 +0100 Subject: [PATCH 2473/3224] Locale fix --- client/main.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/client/main.lua b/client/main.lua index 2b16b421..8ddc344b 100644 --- a/client/main.lua +++ b/client/main.lua @@ -6,11 +6,10 @@ local Licenses = {} local CurrentTest = nil local CurrentTestType = nil local CurrentVehicle = nil -local CurrentCheckPoint = 0 +local CurrentCheckPoint, DriveErrors = 0, 0 local LastCheckPoint = -1 local CurrentBlip = nil local CurrentZoneType = nil -local DriveErrors = 0 local IsAboveSpeedLimit = false local LastVehicleHealth = nil @@ -129,7 +128,7 @@ function OpenDMVSchoolMenu() if not ownedLicenses['drive_truck'] then table.insert(elements, { - label = (('%s: %s'):format(_U('drive_truck'), _U('school_item', ESX.Math.GroupDigits(Config.Prices['drive_truck'])))), + label = (('%s: %s'):format(_U('road_test_truck'), _U('school_item', ESX.Math.GroupDigits(Config.Prices['drive_truck'])))), value = 'drive_test', type = 'drive_truck' }) From de844c9222871325e944f74584a47c09cd03bb8c Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:50:55 +0100 Subject: [PATCH 2474/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (91%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 91% rename from __resource.lua rename to fxmanifest.lua index eed009cd..fe8e4b3c 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ESX DMV School' From 6db3f2ef7df0c0a56d13c75af01d81c25896fb52 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:52:07 +0100 Subject: [PATCH 2475/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua | 6 ------ fxmanifest.lua | 8 ++++++++ 2 files changed, 8 insertions(+), 6 deletions(-) delete mode 100644 __resource.lua create mode 100644 fxmanifest.lua diff --git a/__resource.lua b/__resource.lua deleted file mode 100644 index 647efcea..00000000 --- a/__resource.lua +++ /dev/null @@ -1,6 +0,0 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' - -description 'Async' - -server_script 'async.lua' -client_script 'async.lua' \ No newline at end of file diff --git a/fxmanifest.lua b/fxmanifest.lua new file mode 100644 index 00000000..9a1b24ff --- /dev/null +++ b/fxmanifest.lua @@ -0,0 +1,8 @@ +fx_version 'adamant' + +game 'gta5' + +description 'Async' + +server_script 'async.lua' +client_script 'async.lua' From 9803279a3992bb2db9d20e7704705691a92f2600 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sun, 19 Jan 2020 17:53:08 +0100 Subject: [PATCH 2476/3224] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (52%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 52% rename from __resource.lua rename to fxmanifest.lua index 65f46367..1797c90e 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'cron' From 133825dbea8145a30aae9a21a93a85ea83cb5d55 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 19 Jan 2020 17:57:28 +0100 Subject: [PATCH 2477/3224] Use new key register --- client/main.lua | 15 ++++++--------- locales/br.lua | 5 +++++ locales/cs.lua | 6 ++++++ locales/de.lua | 5 +++++ locales/en.lua | 7 ++++++- locales/fi.lua | 5 +++++ locales/fr.lua | 5 +++++ locales/pl.lua | 7 ++++++- locales/sv.lua | 5 +++++ 9 files changed, 49 insertions(+), 11 deletions(-) diff --git a/client/main.lua b/client/main.lua index 48285d2b..18d0ad43 100644 --- a/client/main.lua +++ b/client/main.lua @@ -436,16 +436,13 @@ Citizen.CreateThread(function() end end) --- Menu interactions -Citizen.CreateThread(function() - while true do - Citizen.Wait(0) - - if IsControlJustReleased(0, 289) and IsInputDisabled(0) and not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then - ESX.ShowInventory() - end +RegisterCommand('showinventory', function() + if not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then + ESX.ShowInventory() end -end) +end, false) + +RegisterKeyMapping('showinventory', _U('keymap_showinventory'), 'keyboard', 'F2') -- Disable wanted level if Config.DisableWantedLevel then diff --git a/locales/br.lua b/locales/br.lua index 98d58441..e67cdc54 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -40,6 +40,10 @@ Locales['br'] = { ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', + + -- Key mapping + ['keymap_showinventory'] = 'show Inventory', + -- Salary related ['received_salary'] = 'voce recebeu seu salario: ~g~$%s~s~ ', ['received_help'] = 'voce recebeu seu cheque de bem-estar: ~g~$%s~s~ ', @@ -73,6 +77,7 @@ Locales['br'] = { ['command_clearinventory'] = 'clear all items from inventory', ['command_clearloadout'] = 'remove all weapons from loadout', ['command_playerid_param'] = 'specify playerId or leave blank for yourself', + -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', diff --git a/locales/cs.lua b/locales/cs.lua index 38521079..7c537b59 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -40,6 +40,11 @@ Locales['cs'] = { ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', + + -- Key mapping + ['keymap_showinventory'] = 'show Inventory', + + -- Salary related ['received_salary'] = 'obdrželi jste výplatu: ~g~$%s~s~', ['received_help'] = 'obdrželi jste sociální dávku: ~g~$%s~s~', @@ -73,6 +78,7 @@ Locales['cs'] = { ['command_clearinventory'] = 'clear all items from inventory', ['command_clearloadout'] = 'remove all weapons from loadout', ['command_playerid_param'] = 'specify playerId or leave blank for yourself', + -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', diff --git a/locales/de.lua b/locales/de.lua index 5df299f5..4a9a5f7f 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -40,6 +40,10 @@ Locales['de'] = { ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', + + -- Key mapping + ['keymap_showinventory'] = 'show Inventory', + -- Salary related ['received_salary'] = 'du hast dein Gehalt erhalten: ~g~$%s~s~', ['received_help'] = 'du hast deine Sozialhilfe erhalten: ~g~$%s~s~', @@ -73,6 +77,7 @@ Locales['de'] = { ['command_clearinventory'] = 'clear all items from inventory', ['command_clearloadout'] = 'remove all weapons from loadout', ['command_playerid_param'] = 'specify playerId or leave blank for yourself', + -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', diff --git a/locales/en.lua b/locales/en.lua index d3c2b4b4..a41b982d 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -40,12 +40,16 @@ Locales['en'] = { ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', + + -- Key mapping + ['keymap_showinventory'] = 'show Inventory', + -- Salary related ['received_salary'] = 'you received your salary: ~g~$%s~s~', ['received_help'] = 'you recieved your welfare check: ~g~$%s~s~', ['company_nomoney'] = 'the company you\'re employeed at is too poor to pay out your salary', ['received_paycheck'] = 'received paycheck', - ['bank'] = 'bank', + ['bank'] = 'maze Bank', ['black_money'] = 'dirty Money', ['act_imp'] = 'action impossible', @@ -73,6 +77,7 @@ Locales['en'] = { ['command_clearinventory'] = 'clear all items from inventory', ['command_clearloadout'] = 'remove all weapons from loadout', ['command_playerid_param'] = 'specify playerId or leave blank for yourself', + -- Locale settings ['locale_digit_grouping_symbol'] = ',', ['locale_currency'] = '$%s', diff --git a/locales/fi.lua b/locales/fi.lua index b20da9c0..a3a32e6c 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -40,6 +40,10 @@ Locales['fi'] = { ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', + + -- Key mapping + ['keymap_showinventory'] = 'show Inventory', + -- Salary related ['received_salary'] = 'sinä vastaanotit palkkaa: ~g~$%s~s~', ['received_help'] = 'sinä vastaanotit valtion tukea: ~g~$%s~s~', @@ -73,6 +77,7 @@ Locales['fi'] = { ['command_clearinventory'] = 'clear all items from inventory', ['command_clearloadout'] = 'remove all weapons from loadout', ['command_playerid_param'] = 'specify playerId or leave blank for yourself', + -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', diff --git a/locales/fr.lua b/locales/fr.lua index 2e134fe4..6a984c9b 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -40,6 +40,10 @@ Locales['fr'] = { ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', + + -- Key mapping + ['keymap_showinventory'] = 'show Inventory', + -- Salary related ['received_salary'] = 'vous avez reçu votre salaire: ~g~$%s~s~', ['received_help'] = 'vous avez reçu une aide de l\'état: ~g~$%s~s~', @@ -73,6 +77,7 @@ Locales['fr'] = { ['command_clearinventory'] = 'effacer tout les items de l\'inventaire', ['command_clearloadout'] = 'retirer toutes les armes de l\'équipement', ['command_playerid_param'] = 'spécifiez un playerid ou laissez vide pour vous-même', + -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', diff --git a/locales/pl.lua b/locales/pl.lua index 40e7b373..37408c76 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -40,6 +40,11 @@ Locales['pl'] = { ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', + + -- Key mapping + ['keymap_showinventory'] = 'show Inventory', + + -- Salary related ['received_salary'] = 'otrzymałeś wynagrodzenie: ~g~%s$~s~', ['received_help'] = 'otrzymałem zapomogę: ~g~$%s~s~', @@ -72,7 +77,7 @@ Locales['pl'] = { ['command_clearinventory'] = 'usuń wszystkie przedmioty z ekwipunku', ['command_clearloadout'] = 'usuń wszystkie bronie z wyposażenia', ['command_playerid_param'] = 'id gracza lub zostaw puste dla siebie', - + -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', diff --git a/locales/sv.lua b/locales/sv.lua index 98605566..47bc4bde 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -40,6 +40,10 @@ Locales['sv'] = { ['threw_weapon_already'] = 'du har redan ett sådant vapen på dig', ['threw_cannot_pickup'] = 'du kan inte plocka upp det på grund av att det kommer ej få plats i ditt förråd!', ['threw_pickup_prompt'] = 'tryck ~y~E~s~ för att plocka upp', + + -- Key mapping + ['keymap_showinventory'] = 'öppna inventory', + -- Salary related ['received_salary'] = 'du har mottagit din lön på ~g~%s SEK~s~', ['received_help'] = 'du har mottagit bidrag på ~g~%s SEK~s~', @@ -73,6 +77,7 @@ Locales['sv'] = { ['command_clearinventory'] = 'clear all items from inventory', ['command_clearloadout'] = 'remove all weapons from loadout', ['command_playerid_param'] = 'specify playerId or leave blank for yourself', + -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '%s SEK', From a1097012538f79b06eac08408e04336e01b480d2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 19 Jan 2020 22:54:45 +0100 Subject: [PATCH 2478/3224] removed xPlayer .addBank() and .removeBank() Phasing out ES code, and those functions were misleading --- server/classes/player.lua | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index f612d74c..9871426e 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -78,22 +78,6 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c end end - self.addBank = function(money) - money = ESX.Math.Round(money) - - if money > 0 then - self.player.addBank(money) - end - end - - self.removeBank = function(money) - money = ESX.Math.Round(money) - - if money > 0 then - self.player.removeBank(money) - end - end - self.displayMoney = function(money) self.player.displayMoney(money) end From cced6c955e1934cfc5ac3bb275ff73261ca8b47a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 19 Jan 2020 22:59:26 +0100 Subject: [PATCH 2479/3224] Removed xPlayer .setBankBalance(), .getBank(), .setSessionVar(), .getSessionVar(), .getPermissions(), .setPermissions() --- server/classes/player.lua | 44 +++++++-------------------------------- 1 file changed, 8 insertions(+), 36 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 9871426e..391b0e96 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -1,14 +1,14 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, coords) local self = {} - self.player = player - self.accounts = accounts - self.inventory = inventory - self.job = job - self.loadout = loadout - self.name = name - self.maxWeight = Config.MaxWeight - self.coords = coords + self.player = player + self.accounts = accounts + self.inventory = inventory + self.job = job + self.loadout = loadout + self.name = name + self.maxWeight = Config.MaxWeight + self.coords = coords self.source = self.player.get('source') self.identifier = self.player.get('identifier') @@ -29,18 +29,6 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c return self.player.get('money') end - self.setBankBalance = function(money) - money = ESX.Math.Round(money) - - if money >= 0 then - self.player.setBankBalance(money) - end - end - - self.getBank = function() - return self.player.get('bank') - end - self.setCoords = function(coords) self.updateCoords(coords) self.triggerEvent('esx:teleport', coords) @@ -86,22 +74,6 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c self.player.displayBank(money) end - self.setSessionVar = function(key, value) - self.player.setSessionVar(key, value) - end - - self.getSessionVar = function(k) - return self.player.getSessionVar(k) - end - - self.getPermissions = function() - return self.player.getPermissions() - end - - self.setPermissions = function(p) - self.player.setPermissions(p) - end - self.getIdentifier = function() return self.player.getIdentifier() end From 4cc96465120a3318555369676df3d1f7cf3a45ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Eskildsen?= Date: Mon, 20 Jan 2020 06:33:17 +0100 Subject: [PATCH 2480/3224] Added Cash support to /giveaccountmoney Just to have a easy way to give cash to a person i have added a check to see if account == cash, just to avoide having more commands. --- server/commands.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/commands.lua b/server/commands.lua index cbee7f24..b2f7b34d 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -74,7 +74,9 @@ TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, local amount = tonumber(args[3]) if amount then - if xPlayer.getAccount(account) then + if account == 'cash' then + xPlayer.addMoney(amount) + else if xPlayer.getAccount(account) then xPlayer.addAccountMoney(account, amount) else TriggerClientEvent('esx:showNotification', source, _U('invalid_account')) From 392184ee2776d64af2dd9bc55d57c8e40491dcbd Mon Sep 17 00:00:00 2001 From: Michael Douglas Date: Mon, 20 Jan 2020 07:40:20 -0300 Subject: [PATCH 2481/3224] Improved Portuguese translation (#433) * Correcting and improving translation * remove incorrectly added capital letters * Update br.lua * fixin translates Co-authored-by: Samuel --- locales/br.lua | 118 +++++++++++++++++++++++++------------------------ 1 file changed, 60 insertions(+), 58 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index e67cdc54..af7e0f9a 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,59 +1,60 @@ Locales['br'] = { -- Inventory - ['cash'] = 'efectivo', - ['inventory'] = 'inventario %s / %s', + ['cash'] = 'dinheiro', + ['inventory'] = 'inventário %s / %s', ['use'] = 'usar', ['give'] = 'dar', ['remove'] = 'remover', ['return'] = 'voltar', - ['give_to'] = 'give to', + ['give_to'] = 'dar para', ['amount'] = 'quantidade', - ['giveammo'] = 'Dar muniçao', - ['amountammo'] = 'quantidade de muniçao', - ['noammo'] = 'voce nao tem todas essas muniçoes!', + ['giveammo'] = 'dar munição', + ['amountammo'] = 'quantidade de munição', + ['noammo'] = 'voce não tem todas essas munições!', ['gave_item'] = 'voce deu ~y~%sx~s~ ~b~%s~s~ para ~y~%s~s~', ['received_item'] = 'voce recebeu ~y~%sx~s~ ~b~%s~s~ de ~b~%s~s~', - ['gave_weapon'] = 'you gave ~b~%s~s~ to ~y~%s~s~', - ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', - ['gave_weapon_withammo'] = 'you gave ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~', - ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', - ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', - ['received_weapon'] = 'you received ~b~%s~s~ from ~b~%s~s~', - ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', - ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', - ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', - ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['gave_weapon'] = 'você deu ~b~%s~s~ para ~y~%s~s~', + ['gave_weapon_ammo'] = 'você deu ~o~%sx~s~ balas para ~b~%s~s~ de ~y~%s~s~', + ['gave_weapon_withammo'] = 'você deu ~b~%s~s~ com ~o~%sx~s~ balas para ~y~%s~s~', + ['gave_weapon_hasalready'] = '~y~%s~s~ já tem um(a) ~y~%s~s~', + ['gave_weapon_noweapon'] = 'não tem essa arma ~y~%s~s~', + ['received_weapon'] = 'você recebeu ~b~%s~s~ de ~b~%s~s~', + ['received_weapon_ammo'] = 'você recebeu ~o~%sx~s~ balas para a sua(o seu) ~b~%s~s~ de ~b~%s~s~', + ['received_weapon_withammo'] = 'você recebeu ~b~%s~s~ com ~o~%sx~s~ balas de ~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~ tentou lhe dar uma ~y~%s~s~, mas você já tem um(a)', + ['received_weapon_noweapon'] = '~b~%s~s~ tentou lhe dar munição para ~y~%s~s~, mas você não tem um(a)', ['gave_money'] = 'voce deu ~g~$%s~s~ para ~y~%s~s~', ['received_money'] = 'voce recebeu ~g~$%s~s~ de ~b~%s~s~', ['gave_account_money'] = 'voce deu ~g~$%s~s~ (%s) para ~y~%s~s~', ['received_account_money'] = 'voce recebeu ~g~$%s~s~ (%s) de ~b~%s~s~', - ['amount_invalid'] = 'quantidade invalida', - ['players_nearby'] = 'nenhum jogador por perto', - ['ex_inv_lim'] = 'acao nao e possivel, excedendo o limite de estoque para ~y~%s~s~', - ['imp_invalid_quantity'] = 'acao impossivel, quantidade invalida', - ['imp_invalid_amount'] = 'acao impossivel, valor invalido', - ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', - ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', - ['threw_weapon'] = 'you threw ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', - ['threw_weapon_already'] = 'you already carry the same weapon', - ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', - ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', + + ['amount_invalid'] = 'quantidade inválida', + ['players_nearby'] = 'nenhum cidadão por perto', + ['ex_inv_lim'] = 'ação não e possivel, excedendo o limite de estoque para ~y~%s~s~', + ['imp_invalid_quantity'] = 'ação impossível, quantidade inválida', + ['imp_invalid_amount'] = 'ação impossível, valor invalido', + ['threw_standard'] = 'você jogou ~y~%sx~s~ ~b~%s~s~', + ['threw_money'] = 'você jogou ~g~$%s~s~ ~b~cash~s~', + ['threw_account'] = 'você jogou ~g~$%s~s~ ~b~%s~s~', + ['threw_weapon'] = 'você jogou ~b~%s~s~', + ['threw_weapon_ammo'] = 'você jogou ~b~%s~s~ com ~o~%sx~s~ balas', + ['threw_weapon_already'] = 'você já esta com essa arma', + ['threw_cannot_pickup'] = 'você não pode pegar porque seu inventário está cheio!', + ['threw_pickup_prompt'] = 'pressione ~y~E~s~ para pegar', -- Key mapping ['keymap_showinventory'] = 'show Inventory', -- Salary related - ['received_salary'] = 'voce recebeu seu salario: ~g~$%s~s~ ', + ['received_salary'] = 'voce recebeu seu salário: ~g~$%s~s~ ', ['received_help'] = 'voce recebeu seu cheque de bem-estar: ~g~$%s~s~ ', - ['company_nomoney'] = 'a empresa em que voce esta empregado esta muito pobre para pagar seu salario', + ['company_nomoney'] = 'a empresa em que voce esta empregado esta muito pobre para pagar seu salário', ['received_paycheck'] = 'recebeu dinheiro', ['bank'] = 'banco', ['black_money'] = 'dinheiro sujo', - ['act_imp'] = 'acao impossivel', - ['in_vehicle'] = 'voce nao pode dar nada para alguem no veiculo', + ['act_imp'] = 'ação impossível', + ['in_vehicle'] = 'voce não pode dar nada para alguem no veículo', -- Commands ['setjob'] = 'atribuir um trabalho a um usuario', @@ -62,8 +63,8 @@ Locales['br'] = { ['setjob_param3'] = 'o nivel de emprego', ['spawn_car'] = 'spawn um carro', ['spawn_car_param'] = 'nome do carro', - ['delete_vehicle'] = 'excluir Veiculo', - ['invalid_account'] = 'conta invalida', + ['delete_vehicle'] = 'excluir veículo', + ['invalid_account'] = 'conta inválida', ['account'] = 'conta', ['giveaccountmoney'] = 'dar dinheiro da conta', ['invalid_item'] = 'item invalido', @@ -71,12 +72,13 @@ Locales['br'] = { ['giveitem'] = 'dar item', ['weapon'] = 'arma', ['giveweapon'] = 'dar arma', - ['disconnect'] = 'disconnect from the server', - ['chat_clear'] = 'clear the chat', - ['chat_clear_all'] = 'clear the chat for everyone', - ['command_clearinventory'] = 'clear all items from inventory', - ['command_clearloadout'] = 'remove all weapons from loadout', - ['command_playerid_param'] = 'specify playerId or leave blank for yourself', + + ['disconnect'] = 'desconectar do servidor', + ['chat_clear'] = 'limpar o chat', + ['chat_clear_all'] = 'limpar o chat para todos', + ['command_clearinventory'] = 'remover todos os itens do inventário', + ['command_clearloadout'] = 'remova todas as armas do carregamento', + ['command_playerid_param'] = 'especifique playerId ou deixe em branco para si mesmo', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', @@ -95,16 +97,16 @@ Locales['br'] = { ['weapon_pistol50'] = 'pistola .50', ['weapon_microsmg'] = 'micro smg', ['weapon_smg'] = 'smg', - ['weapon_assaultsmg'] = 'assault smg', - ['weapon_assaultrifle'] = 'assault rifle', - ['weapon_carbinerifle'] = 'carbine rifle', - ['weapon_advancedrifle'] = 'advanced rifle', + ['weapon_assaultsmg'] = 'smg de assalto', + ['weapon_assaultrifle'] = 'rifle de assalto', + ['weapon_carbinerifle'] = 'carabina rifle', + ['weapon_advancedrifle'] = 'rifle avançado', ['weapon_mg'] = 'mg', - ['weapon_combatmg'] = 'combat mg', + ['weapon_combatmg'] = 'combate mg', ['weapon_pumpshotgun'] = 'espingarda', - ['weapon_sawnoffshotgun'] = 'sawed off shotgun', - ['weapon_assaultshotgun'] = 'assault shotgun', - ['weapon_bullpupshotgun'] = 'bullpup shotgun', + ['weapon_sawnoffshotgun'] = 'espingarda serrada', + ['weapon_assaultshotgun'] = 'espingarda de assalto', + ['weapon_bullpupshotgun'] = 'espingarda de bullpup', ['weapon_stungun'] = 'arma de choque', ['weapon_sniperrifle'] = 'sniper rifle', ['weapon_heavysniper'] = 'heavy sniper', @@ -144,7 +146,7 @@ Locales['br'] = { ['weapon_knuckle'] = 'soco ingles', ['weapon_hatchet'] = 'machado', ['weapon_railgun'] = 'railgun', - ['weapon_machete'] = 'facao', + ['weapon_machete'] = 'facão', ['weapon_machinepistol'] = 'machine pistol', ['weapon_switchblade'] = 'canivete', ['weapon_revolver'] = 'heavy revolver', @@ -160,18 +162,18 @@ Locales['br'] = { ['weapon_flashlight'] = 'laterna', ['gadget_nightvision'] = 'visao noturna', ['gadget_parachute'] = 'paraquedas', - ['weapon_flare'] = 'Flare', + ['weapon_flare'] = 'flare', ['weapon_doubleaction'] = 'double-Action Revolver', -- Weapon Components - ['component_clip_default'] = 'default Grip', - ['component_clip_extended'] = 'extended Grip', + ['component_clip_default'] = 'aderência padrão', + ['component_clip_extended'] = 'aderência prolongada', ['component_clip_drum'] = 'drum Magazine', ['component_clip_box'] = 'box Magazine', - ['component_flashlight'] = 'flashlight', - ['component_scope'] = 'scope', - ['component_scope_advanced'] = 'advanced Scope', - ['component_suppressor'] = 'suppressor', + ['component_flashlight'] = 'lanterna', + ['component_scope'] = 'mira', + ['component_scope_advanced'] = 'mira avançada', + ['component_suppressor'] = 'supressor', ['component_grip'] = 'grip', - ['component_luxary_finish'] = 'luxary Weapon Finish', + ['component_luxary_finish'] = 'acabamento de arma de luxo', } From 17b19893c95f4255d9762b765928a6e5e15a474d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 20 Jan 2020 13:21:13 +0100 Subject: [PATCH 2482/3224] Fixed benzon typo --- server/commands.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/commands.lua b/server/commands.lua index b2f7b34d..b57a23bf 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -76,7 +76,7 @@ TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, if amount then if account == 'cash' then xPlayer.addMoney(amount) - else if xPlayer.getAccount(account) then + elseif xPlayer.getAccount(account) then xPlayer.addAccountMoney(account, amount) else TriggerClientEvent('esx:showNotification', source, _U('invalid_account')) From cd1ce6a84954c58e443f5224841d5f280799a180 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 20 Jan 2020 14:33:24 +0100 Subject: [PATCH 2483/3224] Don't parse item object to client, added weapon component notifications (more see desc) - Removed xPlayer .displayBank() - Fixed issues with giving weapon using commands - Modified ESX.UI.ShowInventoryItemNotification() to take string instead of table - Minor adjustments and variable renames - Fixed lower case weapons not droppable - Removed /disconnect command becasue fivem implemented their own --- client/main.lua | 22 +++++--- html/js/app.js | 12 +++-- server/classes/player.lua | 108 +++++++++++++++++++++----------------- server/commands.lua | 26 ++++----- server/main.lua | 2 + 5 files changed, 93 insertions(+), 77 deletions(-) diff --git a/client/main.lua b/client/main.lua index 18d0ad43..489d4ae8 100644 --- a/client/main.lua +++ b/client/main.lua @@ -124,15 +124,18 @@ AddEventHandler('es:activateMoney', function(money) end) RegisterNetEvent('esx:addInventoryItem') -AddEventHandler('esx:addInventoryItem', function(item, count) +AddEventHandler('esx:addInventoryItem', function(item, count, showNotification) for k,v in ipairs(ESX.PlayerData.inventory) do - if v.name == item.name then - ESX.PlayerData.inventory[k] = item + if v.name == item then + ESX.UI.ShowInventoryItemNotification(true, v.label, count - v.count) + ESX.PlayerData.inventory[k].count = count break end end - ESX.UI.ShowInventoryItemNotification(true, item, count) + if showNotification then + ESX.UI.ShowInventoryItemNotification(true, item, count) + end if ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then ESX.ShowInventory() @@ -140,15 +143,18 @@ AddEventHandler('esx:addInventoryItem', function(item, count) end) RegisterNetEvent('esx:removeInventoryItem') -AddEventHandler('esx:removeInventoryItem', function(item, count) +AddEventHandler('esx:removeInventoryItem', function(item, count, showNotification) for k,v in ipairs(ESX.PlayerData.inventory) do - if v.name == item.name then - ESX.PlayerData.inventory[k] = item + if v.name == item then + ESX.UI.ShowInventoryItemNotification(false, v.label, v.count - count) + ESX.PlayerData.inventory[k].count = count break end end - ESX.UI.ShowInventoryItemNotification(false, item, count) + if showNotification then + ESX.UI.ShowInventoryItemNotification(false, item, count) + end if ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then ESX.ShowInventory() diff --git a/html/js/app.js b/html/js/app.js index 95308dc6..7705334c 100644 --- a/html/js/app.js +++ b/html/js/app.js @@ -22,7 +22,6 @@ }; ESX.updateHUDElement = function (name, data) { - for (let i = 0; i < ESX.HUDElements.length; i++) { if (ESX.HUDElements[i].name == name) { ESX.HUDElements[i].data = data; @@ -51,7 +50,7 @@ } }; - ESX.inventoryNotification = function (add, item, count) { + ESX.inventoryNotification = function (add, label, count) { let notif = ''; if (add) { @@ -60,10 +59,13 @@ notif += '-'; } - notif += count + ' ' + item.label; + if (count) { + notif += count + ' ' + label; + } else { + notif += ' ' + label; + } let elem = $('
    ' + notif + '
    '); - $('#inventory_notifications').append(elem); $(elem).delay(3000).fadeOut(1000, function () { @@ -105,4 +107,4 @@ }); }; -})(); \ No newline at end of file +})(); diff --git a/server/classes/player.lua b/server/classes/player.lua index 391b0e96..3b931af8 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -70,10 +70,6 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c self.player.displayMoney(money) end - self.displayBank = function(money) - self.player.displayBank(money) - end - self.getIdentifier = function() return self.player.getIdentifier() end @@ -97,8 +93,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c self.getAccounts = function() local accounts = {} - for k,v in ipairs(Config.Accounts) do - if v == 'bank' then + for k,account in ipairs(Config.Accounts) do + if account == 'bank' then table.insert(accounts, { name = 'bank', money = self.get('bank'), @@ -106,8 +102,9 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c }) else for k2,v2 in ipairs(self.accounts) do - if v2.name == v then + if v2.name == account then table.insert(accounts, v2) + break end end end @@ -116,8 +113,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c return accounts end - self.getAccount = function(a) - if a == 'bank' then + self.getAccount = function(account) + if account == 'bank' then return { name = 'bank', money = self.get('bank'), @@ -126,7 +123,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c end for k,v in ipairs(self.accounts) do - if v.name == a then + if v.name == account then return v end end @@ -192,9 +189,9 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c end end - self.setAccountMoney = function(acc, money) + self.setAccountMoney = function(accountName, money) if money >= 0 then - local account = self.getAccount(acc) + local account = self.getAccount(accountName) if account then local prevMoney = account.money @@ -202,7 +199,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c account.money = newMoney - if acc == 'bank' then + if accountName == 'bank' then self.set('bank', newMoney) end @@ -211,15 +208,15 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c end end - self.addAccountMoney = function(acc, money) + self.addAccountMoney = function(accountName, money) if money > 0 then - local account = self.getAccount(acc) + local account = self.getAccount(accountName) if account then local newMoney = account.money + ESX.Math.Round(money) account.money = newMoney - if acc == 'bank' then + if accountName == 'bank' then self.set('bank', newMoney) end @@ -228,15 +225,15 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c end end - self.removeAccountMoney = function(acc, money) + self.removeAccountMoney = function(accountName, money) if money > 0 then - local account = self.getAccount(acc) + local account = self.getAccount(accountName) if account then local newMoney = account.money - ESX.Math.Round(money) account.money = newMoney - if acc == 'bank' then + if accountName == 'bank' then self.set('bank', newMoney) end @@ -259,11 +256,13 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c local item = self.getInventoryItem(name) if item then - local newCount = item.count + count - item.count = newCount + count = ESX.Math.Round(count) - TriggerEvent('esx:onAddInventoryItem', self.source, item, count) - self.triggerEvent('esx:addInventoryItem', item, count) + local newCount = item.count + count + item.count = newCount + + TriggerEvent('esx:onAddInventoryItem', self.source, item.name, item.count) + self.triggerEvent('esx:addInventoryItem', item.name, item.count) end end @@ -271,13 +270,14 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c local item = self.getInventoryItem(name) if item then + count = ESX.Math.Round(count) local newCount = item.count - count if newCount >= 0 then item.count = newCount - TriggerEvent('esx:onRemoveInventoryItem', self.source, item, count) - self.triggerEvent('esx:removeInventoryItem', item, count) + TriggerEvent('esx:onRemoveInventoryItem', self.source, item.name, item.count) + self.triggerEvent('esx:removeInventoryItem', item.name, item.count) end end end @@ -286,15 +286,12 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c local item = self.getInventoryItem(name) if item and count >= 0 then - local oldCount = item.count - item.count = count + count = ESX.Math.Round(count) - if oldCount > item.count then - TriggerEvent('esx:onRemoveInventoryItem', self.source, item, oldCount - item.count) - self.triggerEvent('esx:removeInventoryItem', item, oldCount - item.count) + if count > item.count then + self.addInventoryItem(item.name, count - item.count) else - TriggerEvent('esx:onAddInventoryItem', self.source, item, item.count - oldCount) - self.triggerEvent('esx:addInventoryItem', item, item.count - oldCount) + self.removeInventoryItem(item.name, item.count - count) end end end @@ -351,15 +348,16 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c self.job.grade_label = gradeObject.label self.job.grade_salary = gradeObject.salary - self.job.skin_male = {} - self.job.skin_female = {} - if gradeObject.skin_male then self.job.skin_male = json.decode(gradeObject.skin_male) + else + self.job.skin_male = {} end if gradeObject.skin_female then self.job.skin_female = json.decode(gradeObject.skin_female) + else + self.job.skin_female = {} end TriggerEvent('esx:setJob', self.source, self.job, lastJob) @@ -370,9 +368,9 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c end self.addWeapon = function(weaponName, ammo) - local weaponLabel = ESX.GetWeaponLabel(weaponName) - if not self.hasWeapon(weaponName) then + local weaponLabel = ESX.GetWeaponLabel(weaponName) + table.insert(self.loadout, { name = weaponName, ammo = ammo, @@ -381,7 +379,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c }) self.triggerEvent('esx:addWeapon', weaponName, ammo) - self.triggerEvent('esx:addInventoryItem', {label = weaponLabel}, 1) + self.triggerEvent('esx:addInventoryItem', weaponLabel, false, true) end end @@ -389,9 +387,14 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c local loadoutNum, weapon = self.getWeapon(weaponName) if weapon then - if not self.hasWeaponComponent(weaponName, weaponComponent) then - table.insert(self.loadout[loadoutNum].components, weaponComponent) - self.triggerEvent('esx:addWeaponComponent', weaponName, weaponComponent) + local component = ESX.GetWeaponComponent(weaponName, weaponComponent) + + if component then + if not self.hasWeaponComponent(weaponName, weaponComponent) then + table.insert(self.loadout[loadoutNum].components, weaponComponent) + self.triggerEvent('esx:addWeaponComponent', weaponName, weaponComponent) + self.triggerEvent('esx:addInventoryItem', component.label, false, true) + end end end end @@ -413,7 +416,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c weaponLabel = v.label for k2,v2 in ipairs(v.components) do - self.triggerEvent('esx:removeWeaponComponent', weaponName, v2) + self.removeWeaponComponent(weaponName, v2) end table.remove(self.loadout, k) @@ -423,7 +426,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c if weaponLabel then self.triggerEvent('esx:removeWeapon', weaponName, ammo) - self.triggerEvent('esx:removeInventoryItem', {label = weaponLabel}, 1) + self.triggerEvent('esx:removeInventoryItem', weaponLabel, false, true) end end @@ -431,14 +434,21 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c local loadoutNum, weapon = self.getWeapon(weaponName) if weapon then - for k,v in ipairs(self.loadout[loadoutNum].components) do - if v.name == weaponComponent then - table.remove(self.loadout[loadoutNum].components, k) - break + local component = ESX.GetWeaponComponent(weaponName, weaponComponent) + + if component then + if self.hasWeaponComponent(weaponName, weaponComponent) then + for k,v in ipairs(self.loadout[loadoutNum].components) do + if v.name == weaponComponent then + table.remove(self.loadout[loadoutNum].components, k) + break + end + end + + self.triggerEvent('esx:removeWeaponComponent', weaponName, weaponComponent) + self.triggerEvent('esx:removeInventoryItem', component.label, false, true) end end - - self.triggerEvent('esx:removeWeaponComponent', weaponName, weaponComponent) end end diff --git a/server/commands.lua b/server/commands.lua index b57a23bf..90c50375 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -129,6 +129,8 @@ TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, local weaponName = args[2] or 'unknown' if ESX.GetWeapon(weaponName) then + weaponName = string.upper(weaponName) + if xPlayer.hasWeapon(weaponName) then TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player already has that weapon.' } }) else @@ -152,19 +154,19 @@ TriggerEvent('es:addGroupCommand', 'giveweaponcomponent', 'admin', function(sour local xPlayer = ESX.GetPlayerFromId(args[1]) if xPlayer then - local weapon = args[2] or 'unknown' + local weaponName = args[2] or 'unknown' - if ESX.GetWeapon(weapon) then - weapon = string.upper(weapon) + if ESX.GetWeapon(weaponName) then + weaponName = string.upper(weaponName) - if xPlayer.hasWeapon(weapon) then - local component = ESX.GetWeaponComponent(weapon, args[3] or 'unknown') + if xPlayer.hasWeapon(weaponName) then + local component = ESX.GetWeaponComponent(weaponName, args[3] or 'unknown') if component then - if xPlayer.hasWeaponComponent(weapon, args[3]) then + if xPlayer.hasWeaponComponent(weaponName, args[3]) then TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player already has that weapon component.' } }) else - xPlayer.addWeaponComponent(weapon, args[3]) + xPlayer.addWeaponComponent(weaponName, args[3]) end else TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid weapon component.' } }) @@ -182,20 +184,14 @@ end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = 'Give weapon component', params = { {name = 'playerId', help = _U('id_param')}, - {name = 'weapon', help = _U('weapon')}, - {name = 'component', help = 'weapon component'} + {name = 'weaponName', help = _U('weapon')}, + {name = 'componentName', help = 'weapon component'} }}) TriggerEvent('es:addGroupCommand', 'disc', 'admin', function(source, args, user) DropPlayer(source, 'You have been disconnected') end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end) - -TriggerEvent('es:addGroupCommand', 'disconnect', 'admin', function(source, args, user) - DropPlayer(source, 'You have been disconnected') -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('disconnect')}) TriggerEvent('es:addGroupCommand', 'clear', 'user', function(source, args, user) diff --git a/server/main.lua b/server/main.lua index 78086ea5..16047c86 100644 --- a/server/main.lua +++ b/server/main.lua @@ -373,6 +373,8 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) end end elseif type == 'item_weapon' then + itemName = string.upper(itemName) + if xPlayer.hasWeapon(itemName) then local weaponNum, weapon = xPlayer.getWeapon(itemName) xPlayer.removeWeapon(itemName) From 74ab98d7d7649e27cf1db0f26023976bec38edfb Mon Sep 17 00:00:00 2001 From: Viktor <35453587+LifeGoal@users.noreply.github.com> Date: Mon, 20 Jan 2020 19:26:21 +0100 Subject: [PATCH 2484/3224] Fixed SQL problem --- es_extended.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/es_extended.sql b/es_extended.sql index 399847e9..253af3b9 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -1,7 +1,7 @@ USE `essentialmode`; ALTER TABLE `users` - ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, + ADD COLUMN `skin` LONGTEXT NULL, ADD COLUMN `job` VARCHAR(50) NULL DEFAULT 'unemployed' AFTER `skin`, ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, From 4150f8c9111582683487f1096db460a704a135d2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 22 Jan 2020 12:20:37 +0100 Subject: [PATCH 2485/3224] Cloakroom cleanup --- client/main.lua | 118 +++++-------- config.lua | 434 ++++++++++++++++++++++++++---------------------- server/main.lua | 2 +- 3 files changed, 280 insertions(+), 274 deletions(-) diff --git a/client/main.lua b/client/main.lua index 315b175f..ebb4e7a7 100644 --- a/client/main.lua +++ b/client/main.lua @@ -25,28 +25,24 @@ function cleanPlayer(playerPed) ResetPedMovementClipset(playerPed, 0) end -function setUniform(job, playerPed) +function setUniform(uniform, playerPed) TriggerEvent('skinchanger:getSkin', function(skin) - if skin.sex == 0 then - if Config.Uniforms[job].male then - TriggerEvent('skinchanger:loadClothes', skin, Config.Uniforms[job].male) - else - ESX.ShowNotification(_U('no_outfit')) - end + local uniformObject - if job == 'bullet_wear' then + if skin.sex == 0 then + uniformObject = Config.Uniforms[uniform].male + else + uniformObject = Config.Uniforms[uniform].female + end + + if uniformObject then + TriggerEvent('skinchanger:loadClothes', skin, uniformObject) + + if uniform == 'bullet_wear' then SetPedArmour(playerPed, 100) end else - if Config.Uniforms[job].female then - TriggerEvent('skinchanger:loadClothes', skin, Config.Uniforms[job].female) - else - ESX.ShowNotification(_U('no_outfit')) - end - - if job == 'bullet_wear' then - SetPedArmour(playerPed, 100) - end + ESX.ShowNotification(_U('no_outfit')) end end) end @@ -56,31 +52,20 @@ function OpenCloakroomMenu() local grade = PlayerData.job.grade_name local elements = { - { label = _U('citizen_wear'), value = 'citizen_wear' }, - { label = _U('bullet_wear'), value = 'bullet_wear' }, - { label = _U('gilet_wear'), value = 'gilet_wear' } + {label = _U('citizen_wear'), value = 'citizen_wear'}, + {label = _U('bullet_wear'), uniform = 'bullet_wear'}, + {label = _U('gilet_wear'), uniform = 'gilet_wear'}, + {label = _U('police_wear'), uniform = grade} } - if grade == 'recruit' then - table.insert(elements, {label = _U('police_wear'), value = 'recruit_wear'}) - elseif grade == 'officer' then - table.insert(elements, {label = _U('police_wear'), value = 'officer_wear'}) - elseif grade == 'sergeant' then - table.insert(elements, {label = _U('police_wear'), value = 'sergeant_wear'}) - elseif grade == 'intendent' then - table.insert(elements, {label = _U('police_wear'), value = 'intendent_wear'}) - elseif grade == 'lieutenant' then - table.insert(elements, {label = _U('police_wear'), value = 'lieutenant_wear'}) - elseif grade == 'chef' then - table.insert(elements, {label = _U('police_wear'), value = 'chef_wear'}) - elseif grade == 'boss' then - table.insert(elements, {label = _U('police_wear'), value = 'boss_wear'}) - end + if Config.EnableCustomPeds then + for k,v in ipairs(Config.CustomPeds.shared) do + table.insert(elements, {label = v.label, value = 'freemode_ped', maleModel = v.maleModel, femaleModel = v.femaleModel}) + end - if Config.EnableNonFreemodePeds then - table.insert(elements, {label = 'Sheriff wear', value = 'freemode_ped', maleModel = 's_m_y_sheriff_01', femaleModel = 's_f_y_sheriff_01'}) - table.insert(elements, {label = 'Police wear', value = 'freemode_ped', maleModel = 's_m_y_cop_01', femaleModel = 's_f_y_cop_01'}) - table.insert(elements, {label = 'Swat wear', value = 'freemode_ped', maleModel = 's_m_y_swat_01', femaleModel = 's_m_y_swat_01'}) + for k,v in ipairs(Config.CustomPeds[grade]) do + table.insert(elements, {label = v.label, value = 'freemode_ped', maleModel = v.maleModel, femaleModel = v.femaleModel}) + end end ESX.UI.Menu.CloseAll() @@ -111,7 +96,7 @@ function OpenCloakroomMenu() end) end - if Config.MaxInService ~= -1 then + if Config.EnableESXService then ESX.TriggerServerCallback('esx_service:isInService', function(isInService) if isInService then playerInService = false @@ -133,8 +118,8 @@ function OpenCloakroomMenu() end end - if Config.MaxInService ~= -1 and data.current.value ~= 'citizen_wear' then - local serviceOk = 'waiting' + if Config.EnableESXService and data.current.value ~= 'citizen_wear' then + local awaitService ESX.TriggerServerCallback('esx_service:isInService', function(isInService) if not isInService then @@ -143,7 +128,7 @@ function OpenCloakroomMenu() if not canTakeService then ESX.ShowNotification(_U('service_max', inServiceCount, maxInService)) else - serviceOk = true + awaitService = true playerInService = true local notification = { @@ -160,36 +145,24 @@ function OpenCloakroomMenu() end, 'police') else - serviceOk = true + awaitService = true end end, 'police') - while type(serviceOk) == 'string' do + while awaitService == nil do Citizen.Wait(5) end -- if we couldn't enter service don't let the player get changed - if not serviceOk then + if not awaitService then return end end - if - data.current.value == 'recruit_wear' or - data.current.value == 'officer_wear' or - data.current.value == 'sergeant_wear' or - data.current.value == 'intendent_wear' or - data.current.value == 'lieutenant_wear' or - data.current.value == 'chef_wear' or - data.current.value == 'boss_wear' or - data.current.value == 'bullet_wear' or - data.current.value == 'gilet_wear' - then - setUniform(data.current.value, playerPed) - end - - if data.current.value == 'freemode_ped' then - local modelHash = '' + if data.current.uniform then + setUniform(data.current.uniform, playerPed) + elseif data.current.value == 'freemode_ped' then + local modelHash ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) if skin.sex == 0 then @@ -201,6 +174,7 @@ function OpenCloakroomMenu() ESX.Streaming.RequestModel(modelHash, function() SetPlayerModel(PlayerId(), modelHash) SetModelAsNoLongerNeeded(modelHash) + SetPedDefaultComponentVariation(PlayerPedId()) TriggerEvent('esx:restoreLoadout') end) @@ -413,15 +387,15 @@ function StoreNearbyVehicle(playerCoords) IsBusy = true Citizen.CreateThread(function() - BeginTextCommandBusyString('STRING') + BeginTextCommandBusyspinnerOn('STRING') AddTextComponentSubstringPlayerName(_U('garage_storing')) - EndTextCommandBusyString(4) + EndTextCommandBusyspinnerOn(4) while IsBusy do Citizen.Wait(100) end - RemoveLoadingPrompt() + BusyspinnerOff() end) -- Workaround for vehicle not deleting when other players are near it. @@ -583,16 +557,16 @@ function WaitForVehicleToLoad(modelHash) if not HasModelLoaded(modelHash) then RequestModel(modelHash) - BeginTextCommandBusyString('STRING') + BeginTextCommandBusyspinnerOn('STRING') AddTextComponentSubstringPlayerName(_U('vehicleshop_awaiting_model')) - EndTextCommandBusyString(4) + EndTextCommandBusyspinnerOn(4) while not HasModelLoaded(modelHash) do Citizen.Wait(0) DisableAllControlActions(0) end - RemoveLoadingPrompt() + BusyspinnerOff() end end @@ -620,7 +594,7 @@ function OpenPoliceActionsMenu() } if Config.EnableLicenses then - table.insert(elements, { label = _U('license_check'), value = 'license' }) + table.insert(elements, {label = _U('license_check'), value = 'license'}) end ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'citizen_interaction', { @@ -1291,7 +1265,7 @@ end) AddEventHandler('esx_phone:cancelMessage', function(dispatchNumber) if PlayerData.job and PlayerData.job.name == 'police' and PlayerData.job.name == dispatchNumber then -- if esx_service is enabled - if Config.MaxInService ~= -1 and not playerInService then + if Config.EnableESXService and not playerInService then CancelEvent() end end @@ -1855,7 +1829,7 @@ AddEventHandler('esx_policejob:updateBlip', function() blipsCops = {} -- Enable blip? - if Config.MaxInService ~= -1 and not playerInService then + if Config.EnableESXService and not playerInService then return end @@ -1898,7 +1872,7 @@ AddEventHandler('onResourceStop', function(resource) TriggerEvent('esx_policejob:unrestrain') TriggerEvent('esx_phone:removeSpecialContact', 'police') - if Config.MaxInService ~= -1 then + if Config.EnableESXService then TriggerServerEvent('esx_service:disableService', 'police') end diff --git a/config.lua b/config.lua index d7712724..a47eaa62 100644 --- a/config.lua +++ b/config.lua @@ -2,21 +2,23 @@ Config = {} Config.DrawDistance = 100.0 Config.MarkerType = 1 -Config.MarkerSize = { x = 1.5, y = 1.5, z = 0.5 } -Config.MarkerColor = { r = 50, g = 50, b = 204 } +Config.MarkerSize = {x = 1.5, y = 1.5, z = 0.5} +Config.MarkerColor = {r = 50, g = 50, b = 204} Config.EnablePlayerManagement = false Config.EnableArmoryManagement = false Config.EnableESXIdentity = false -- enable if you're using esx_identity -Config.EnableNonFreemodePeds = false -- turn this on if you want custom peds Config.EnableLicenses = false -- enable if you're using esx_license Config.EnableHandcuffTimer = true -- enable handcuff timer? will unrestrain player after the time ends Config.HandcuffTimer = 10 * 60000 -- 10 mins -Config.EnableJobBlip = false -- enable blips for colleagues, requires esx_society +Config.EnableJobBlip = false -- enable blips for cops on duty, requires esx_society +Config.EnableCustomPeds = false -- enable custom peds in cloak room? See Config.CustomPeds below to customize peds + +Config.EnableESXService = false -- enable esx service? +Config.MaxInService = 5 -Config.MaxInService = -1 Config.Locale = 'fr' Config.PoliceStations = { @@ -44,10 +46,10 @@ Config.PoliceStations = { Spawner = vector3(454.6, -1017.4, 28.4), InsideShop = vector3(228.5, -993.5, -99.5), SpawnPoints = { - { coords = vector3(438.4, -1018.3, 27.7), heading = 90.0, radius = 6.0 }, - { coords = vector3(441.0, -1024.2, 28.3), heading = 90.0, radius = 6.0 }, - { coords = vector3(453.5, -1022.2, 28.0), heading = 90.0, radius = 6.0 }, - { coords = vector3(450.9, -1016.5, 28.1), heading = 90.0, radius = 6.0 } + {coords = vector3(438.4, -1018.3, 27.7), heading = 90.0, radius = 6.0}, + {coords = vector3(441.0, -1024.2, 28.3), heading = 90.0, radius = 6.0}, + {coords = vector3(453.5, -1022.2, 28.0), heading = 90.0, radius = 6.0}, + {coords = vector3(450.9, -1016.5, 28.1), heading = 90.0, radius = 6.0} } }, @@ -55,8 +57,8 @@ Config.PoliceStations = { Spawner = vector3(473.3, -1018.8, 28.0), InsideShop = vector3(228.5, -993.5, -99.0), SpawnPoints = { - { coords = vector3(475.9, -1021.6, 28.0), heading = 276.1, radius = 6.0 }, - { coords = vector3(484.1, -1023.1, 27.5), heading = 302.5, radius = 6.0 } + {coords = vector3(475.9, -1021.6, 28.0), heading = 276.1, radius = 6.0}, + {coords = vector3(484.1, -1023.1, 27.5), heading = 302.5, radius = 6.0} } } }, @@ -66,7 +68,7 @@ Config.PoliceStations = { Spawner = vector3(461.1, -981.5, 43.6), InsideShop = vector3(477.0, -1106.4, 43.0), SpawnPoints = { - { coords = vector3(449.5, -981.2, 43.6), heading = 92.6, radius = 10.0 } + {coords = vector3(449.5, -981.2, 43.6), heading = 92.6, radius = 10.0} } } }, @@ -81,70 +83,70 @@ Config.PoliceStations = { Config.AuthorizedWeapons = { recruit = { - { weapon = 'WEAPON_APPISTOL', components = { 0, 0, 1000, 4000, nil }, price = 10000 }, - { weapon = 'WEAPON_NIGHTSTICK', price = 0 }, - { weapon = 'WEAPON_STUNGUN', price = 1500 }, - { weapon = 'WEAPON_FLASHLIGHT', price = 80 } + {weapon = 'WEAPON_APPISTOL', components = {0, 0, 1000, 4000, nil}, price = 10000}, + {weapon = 'WEAPON_NIGHTSTICK', price = 0}, + {weapon = 'WEAPON_STUNGUN', price = 1500}, + {weapon = 'WEAPON_FLASHLIGHT', price = 80} }, officer = { - { weapon = 'WEAPON_APPISTOL', components = { 0, 0, 1000, 4000, nil }, price = 10000 }, - { weapon = 'WEAPON_ADVANCEDRIFLE', components = { 0, 6000, 1000, 4000, 8000, nil }, price = 50000 }, - { weapon = 'WEAPON_NIGHTSTICK', price = 0 }, - { weapon = 'WEAPON_STUNGUN', price = 500 }, - { weapon = 'WEAPON_FLASHLIGHT', price = 0 } + {weapon = 'WEAPON_APPISTOL', components = {0, 0, 1000, 4000, nil}, price = 10000}, + {weapon = 'WEAPON_ADVANCEDRIFLE', components = {0, 6000, 1000, 4000, 8000, nil}, price = 50000}, + {weapon = 'WEAPON_NIGHTSTICK', price = 0}, + {weapon = 'WEAPON_STUNGUN', price = 500}, + {weapon = 'WEAPON_FLASHLIGHT', price = 0} }, sergeant = { - { weapon = 'WEAPON_APPISTOL', components = { 0, 0, 1000, 4000, nil }, price = 10000 }, - { weapon = 'WEAPON_ADVANCEDRIFLE', components = { 0, 6000, 1000, 4000, 8000, nil }, price = 50000 }, - { weapon = 'WEAPON_PUMPSHOTGUN', components = { 2000, 6000, nil }, price = 70000 }, - { weapon = 'WEAPON_NIGHTSTICK', price = 0 }, - { weapon = 'WEAPON_STUNGUN', price = 500 }, - { weapon = 'WEAPON_FLASHLIGHT', price = 0 } + {weapon = 'WEAPON_APPISTOL', components = {0, 0, 1000, 4000, nil}, price = 10000}, + {weapon = 'WEAPON_ADVANCEDRIFLE', components = {0, 6000, 1000, 4000, 8000, nil}, price = 50000}, + {weapon = 'WEAPON_PUMPSHOTGUN', components = {2000, 6000, nil}, price = 70000}, + {weapon = 'WEAPON_NIGHTSTICK', price = 0}, + {weapon = 'WEAPON_STUNGUN', price = 500}, + {weapon = 'WEAPON_FLASHLIGHT', price = 0} }, intendent = { - { weapon = 'WEAPON_APPISTOL', components = { 0, 0, 1000, 4000, nil }, price = 10000 }, - { weapon = 'WEAPON_ADVANCEDRIFLE', components = { 0, 6000, 1000, 4000, 8000, nil }, price = 50000 }, - { weapon = 'WEAPON_PUMPSHOTGUN', components = { 2000, 6000, nil }, price = 70000 }, - { weapon = 'WEAPON_NIGHTSTICK', price = 0 }, - { weapon = 'WEAPON_STUNGUN', price = 500 }, - { weapon = 'WEAPON_FLASHLIGHT', price = 0 } + {weapon = 'WEAPON_APPISTOL', components = {0, 0, 1000, 4000, nil}, price = 10000}, + {weapon = 'WEAPON_ADVANCEDRIFLE', components = {0, 6000, 1000, 4000, 8000, nil}, price = 50000}, + {weapon = 'WEAPON_PUMPSHOTGUN', components = {2000, 6000, nil}, price = 70000}, + {weapon = 'WEAPON_NIGHTSTICK', price = 0}, + {weapon = 'WEAPON_STUNGUN', price = 500}, + {weapon = 'WEAPON_FLASHLIGHT', price = 0} }, lieutenant = { - { weapon = 'WEAPON_APPISTOL', components = { 0, 0, 1000, 4000, nil }, price = 10000 }, - { weapon = 'WEAPON_ADVANCEDRIFLE', components = { 0, 6000, 1000, 4000, 8000, nil }, price = 50000 }, - { weapon = 'WEAPON_PUMPSHOTGUN', components = { 2000, 6000, nil }, price = 70000 }, - { weapon = 'WEAPON_NIGHTSTICK', price = 0 }, - { weapon = 'WEAPON_STUNGUN', price = 500 }, - { weapon = 'WEAPON_FLASHLIGHT', price = 0 } + {weapon = 'WEAPON_APPISTOL', components = {0, 0, 1000, 4000, nil}, price = 10000}, + {weapon = 'WEAPON_ADVANCEDRIFLE', components = {0, 6000, 1000, 4000, 8000, nil}, price = 50000}, + {weapon = 'WEAPON_PUMPSHOTGUN', components = {2000, 6000, nil}, price = 70000}, + {weapon = 'WEAPON_NIGHTSTICK', price = 0}, + {weapon = 'WEAPON_STUNGUN', price = 500}, + {weapon = 'WEAPON_FLASHLIGHT', price = 0} }, chef = { - { weapon = 'WEAPON_APPISTOL', components = { 0, 0, 1000, 4000, nil }, price = 10000 }, - { weapon = 'WEAPON_ADVANCEDRIFLE', components = { 0, 6000, 1000, 4000, 8000, nil }, price = 50000 }, - { weapon = 'WEAPON_PUMPSHOTGUN', components = { 2000, 6000, nil }, price = 70000 }, - { weapon = 'WEAPON_NIGHTSTICK', price = 0 }, - { weapon = 'WEAPON_STUNGUN', price = 500 }, - { weapon = 'WEAPON_FLASHLIGHT', price = 0 } + {weapon = 'WEAPON_APPISTOL', components = {0, 0, 1000, 4000, nil}, price = 10000}, + {weapon = 'WEAPON_ADVANCEDRIFLE', components = {0, 6000, 1000, 4000, 8000, nil}, price = 50000}, + {weapon = 'WEAPON_PUMPSHOTGUN', components = {2000, 6000, nil}, price = 70000}, + {weapon = 'WEAPON_NIGHTSTICK', price = 0}, + {weapon = 'WEAPON_STUNGUN', price = 500}, + {weapon = 'WEAPON_FLASHLIGHT', price = 0} }, boss = { - { weapon = 'WEAPON_APPISTOL', components = { 0, 0, 1000, 4000, nil }, price = 10000 }, - { weapon = 'WEAPON_ADVANCEDRIFLE', components = { 0, 6000, 1000, 4000, 8000, nil }, price = 50000 }, - { weapon = 'WEAPON_PUMPSHOTGUN', components = { 2000, 6000, nil }, price = 70000 }, - { weapon = 'WEAPON_NIGHTSTICK', price = 0 }, - { weapon = 'WEAPON_STUNGUN', price = 500 }, - { weapon = 'WEAPON_FLASHLIGHT', price = 0 } + {weapon = 'WEAPON_APPISTOL', components = {0, 0, 1000, 4000, nil}, price = 10000}, + {weapon = 'WEAPON_ADVANCEDRIFLE', components = {0, 6000, 1000, 4000, 8000, nil}, price = 50000}, + {weapon = 'WEAPON_PUMPSHOTGUN', components = {2000, 6000, nil}, price = 70000}, + {weapon = 'WEAPON_NIGHTSTICK', price = 0}, + {weapon = 'WEAPON_STUNGUN', price = 500}, + {weapon = 'WEAPON_FLASHLIGHT', price = 0} } } Config.AuthorizedVehicles = { Shared = { - { model = 'police', label = 'Police Cruiser', price = 10000 }, - { model = 'pbus', label = 'Police Prison Bus', price = 5000 } + {model = 'police', label = 'Police Cruiser', price = 10000}, + {model = 'pbus', label = 'Police Prison Bus', price = 5000} }, recruit = { @@ -152,12 +154,12 @@ Config.AuthorizedVehicles = { }, officer = { - { model = 'police3', label = 'Police Interceptor', price = 20000 } + {model = 'police3', label = 'Police Interceptor', price = 20000} }, sergeant = { - { model = 'policet', label = 'Police Transporter', price = 18500 }, - { model = 'policeb', label = 'Police Bike', price = 30500 } + {model = 'policet', label = 'Police Transporter', price = 18500}, + {model = 'policeb', label = 'Police Bike', price = 30500} }, intendent = { @@ -165,8 +167,8 @@ Config.AuthorizedVehicles = { }, lieutenant = { - { model = 'riot', label = 'Police Riot', price = 70000 }, - { model = 'fbi2', label = 'FIB SUV', price = 60000 } + {model = 'riot', label = 'Police Riot', price = 70000}, + {model = 'fbi2', label = 'FIB SUV', price = 60000} }, chef = { @@ -188,204 +190,234 @@ Config.AuthorizedHelicopters = { intendent = {}, lieutenant = { - { model = 'polmav', label = 'Police Maverick', livery = 0, price = 200000 } + {model = 'polmav', label = 'Police Maverick', livery = 0, price = 200000} }, chef = { - { model = 'polmav', label = 'Police Maverick', livery = 0, price = 150000 } + {model = 'polmav', label = 'Police Maverick', livery = 0, price = 150000} }, boss = { - { model = 'polmav', label = 'Police Maverick', livery = 0, price = 100000 } + {model = 'polmav', label = 'Police Maverick', livery = 0, price = 100000} + } +} + + +Config.CustomPeds = { + shared = { + {label = 'Sheriff Ped', maleModel = 's_m_y_sheriff_01', femaleModel = 's_f_y_sheriff_01'}, + {label = 'Police Ped', maleModel = 's_m_y_cop_01', femaleModel = 's_f_y_cop_01'} + }, + + recruit = {}, + + officer = {}, + + sergeant = {}, + + intendent = {}, + + lieutenant = {}, + + chef = {}, + + boss = { + {label = 'SWAT Ped', maleModel = 's_m_y_swat_01', femaleModel = 's_m_y_swat_01'} } } -- CHECK SKINCHANGER CLIENT MAIN.LUA for matching elements - Config.Uniforms = { - recruit_wear = { + recruit = { male = { - ['tshirt_1'] = 59, ['tshirt_2'] = 1, - ['torso_1'] = 55, ['torso_2'] = 0, - ['decals_1'] = 0, ['decals_2'] = 0, - ['arms'] = 41, - ['pants_1'] = 25, ['pants_2'] = 0, - ['shoes_1'] = 25, ['shoes_2'] = 0, - ['helmet_1'] = 46, ['helmet_2'] = 0, - ['chain_1'] = 0, ['chain_2'] = 0, - ['ears_1'] = 2, ['ears_2'] = 0 + tshirt_1 = 59, tshirt_2 = 1, + torso_1 = 55, torso_2 = 0, + decals_1 = 0, decals_2 = 0, + arms = 41, + pants_1 = 25, pants_2 = 0, + shoes_1 = 25, shoes_2 = 0, + helmet_1 = 46, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 }, female = { - ['tshirt_1'] = 36, ['tshirt_2'] = 1, - ['torso_1'] = 48, ['torso_2'] = 0, - ['decals_1'] = 0, ['decals_2'] = 0, - ['arms'] = 44, - ['pants_1'] = 34, ['pants_2'] = 0, - ['shoes_1'] = 27, ['shoes_2'] = 0, - ['helmet_1'] = 45, ['helmet_2'] = 0, - ['chain_1'] = 0, ['chain_2'] = 0, - ['ears_1'] = 2, ['ears_2'] = 0 + tshirt_1 = 36, tshirt_2 = 1, + torso_1 = 48, torso_2 = 0, + decals_1 = 0, decals_2 = 0, + arms = 44, + pants_1 = 34, pants_2 = 0, + shoes_1 = 27, shoes_2 = 0, + helmet_1 = 45, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 } }, - officer_wear = { + + officer = { male = { - ['tshirt_1'] = 58, ['tshirt_2'] = 0, - ['torso_1'] = 55, ['torso_2'] = 0, - ['decals_1'] = 0, ['decals_2'] = 0, - ['arms'] = 41, - ['pants_1'] = 25, ['pants_2'] = 0, - ['shoes_1'] = 25, ['shoes_2'] = 0, - ['helmet_1'] = -1, ['helmet_2'] = 0, - ['chain_1'] = 0, ['chain_2'] = 0, - ['ears_1'] = 2, ['ears_2'] = 0 + tshirt_1 = 58, tshirt_2 = 0, + torso_1 = 55, torso_2 = 0, + decals_1 = 0, decals_2 = 0, + arms = 41, + pants_1 = 25, pants_2 = 0, + shoes_1 = 25, shoes_2 = 0, + helmet_1 = -1, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 }, female = { - ['tshirt_1'] = 35, ['tshirt_2'] = 0, - ['torso_1'] = 48, ['torso_2'] = 0, - ['decals_1'] = 0, ['decals_2'] = 0, - ['arms'] = 44, - ['pants_1'] = 34, ['pants_2'] = 0, - ['shoes_1'] = 27, ['shoes_2'] = 0, - ['helmet_1'] = -1, ['helmet_2'] = 0, - ['chain_1'] = 0, ['chain_2'] = 0, - ['ears_1'] = 2, ['ears_2'] = 0 + tshirt_1 = 35, tshirt_2 = 0, + torso_1 = 48, torso_2 = 0, + decals_1 = 0, decals_2 = 0, + arms = 44, + pants_1 = 34, pants_2 = 0, + shoes_1 = 27, shoes_2 = 0, + helmet_1 = -1, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 } }, - sergeant_wear = { + + sergeant = { male = { - ['tshirt_1'] = 58, ['tshirt_2'] = 0, - ['torso_1'] = 55, ['torso_2'] = 0, - ['decals_1'] = 8, ['decals_2'] = 1, - ['arms'] = 41, - ['pants_1'] = 25, ['pants_2'] = 0, - ['shoes_1'] = 25, ['shoes_2'] = 0, - ['helmet_1'] = -1, ['helmet_2'] = 0, - ['chain_1'] = 0, ['chain_2'] = 0, - ['ears_1'] = 2, ['ears_2'] = 0 + tshirt_1 = 58, tshirt_2 = 0, + torso_1 = 55, torso_2 = 0, + decals_1 = 8, decals_2 = 1, + arms = 41, + pants_1 = 25, pants_2 = 0, + shoes_1 = 25, shoes_2 = 0, + helmet_1 = -1, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 }, female = { - ['tshirt_1'] = 35, ['tshirt_2'] = 0, - ['torso_1'] = 48, ['torso_2'] = 0, - ['decals_1'] = 7, ['decals_2'] = 1, - ['arms'] = 44, - ['pants_1'] = 34, ['pants_2'] = 0, - ['shoes_1'] = 27, ['shoes_2'] = 0, - ['helmet_1'] = -1, ['helmet_2'] = 0, - ['chain_1'] = 0, ['chain_2'] = 0, - ['ears_1'] = 2, ['ears_2'] = 0 + tshirt_1 = 35, tshirt_2 = 0, + torso_1 = 48, torso_2 = 0, + decals_1 = 7, decals_2 = 1, + arms = 44, + pants_1 = 34, pants_2 = 0, + shoes_1 = 27, shoes_2 = 0, + helmet_1 = -1, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 } }, - intendent_wear = { + + intendent = { male = { - ['tshirt_1'] = 58, ['tshirt_2'] = 0, - ['torso_1'] = 55, ['torso_2'] = 0, - ['decals_1'] = 8, ['decals_2'] = 2, - ['arms'] = 41, - ['pants_1'] = 25, ['pants_2'] = 0, - ['shoes_1'] = 25, ['shoes_2'] = 0, - ['helmet_1'] = -1, ['helmet_2'] = 0, - ['chain_1'] = 0, ['chain_2'] = 0, - ['ears_1'] = 2, ['ears_2'] = 0 + tshirt_1 = 58, tshirt_2 = 0, + torso_1 = 55, torso_2 = 0, + decals_1 = 8, decals_2 = 2, + arms = 41, + pants_1 = 25, pants_2 = 0, + shoes_1 = 25, shoes_2 = 0, + helmet_1 = -1, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 }, female = { - ['tshirt_1'] = 35, ['tshirt_2'] = 0, - ['torso_1'] = 48, ['torso_2'] = 0, - ['decals_1'] = 7, ['decals_2'] = 2, - ['arms'] = 44, - ['pants_1'] = 34, ['pants_2'] = 0, - ['shoes_1'] = 27, ['shoes_2'] = 0, - ['helmet_1'] = -1, ['helmet_2'] = 0, - ['chain_1'] = 0, ['chain_2'] = 0, - ['ears_1'] = 2, ['ears_2'] = 0 + tshirt_1 = 35, tshirt_2 = 0, + torso_1 = 48, torso_2 = 0, + decals_1 = 7, decals_2 = 2, + arms = 44, + pants_1 = 34, pants_2 = 0, + shoes_1 = 27, shoes_2 = 0, + helmet_1 = -1, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 } }, - lieutenant_wear = { -- currently the same as intendent_wear + + lieutenant = {-- currently the same as intendent male = { - ['tshirt_1'] = 58, ['tshirt_2'] = 0, - ['torso_1'] = 55, ['torso_2'] = 0, - ['decals_1'] = 8, ['decals_2'] = 2, - ['arms'] = 41, - ['pants_1'] = 25, ['pants_2'] = 0, - ['shoes_1'] = 25, ['shoes_2'] = 0, - ['helmet_1'] = -1, ['helmet_2'] = 0, - ['chain_1'] = 0, ['chain_2'] = 0, - ['ears_1'] = 2, ['ears_2'] = 0 + tshirt_1 = 58, tshirt_2 = 0, + torso_1 = 55, torso_2 = 0, + decals_1 = 8, decals_2 = 2, + arms = 41, + pants_1 = 25, pants_2 = 0, + shoes_1 = 25, shoes_2 = 0, + helmet_1 = -1, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 }, female = { - ['tshirt_1'] = 35, ['tshirt_2'] = 0, - ['torso_1'] = 48, ['torso_2'] = 0, - ['decals_1'] = 7, ['decals_2'] = 2, - ['arms'] = 44, - ['pants_1'] = 34, ['pants_2'] = 0, - ['shoes_1'] = 27, ['shoes_2'] = 0, - ['helmet_1'] = -1, ['helmet_2'] = 0, - ['chain_1'] = 0, ['chain_2'] = 0, - ['ears_1'] = 2, ['ears_2'] = 0 + tshirt_1 = 35, tshirt_2 = 0, + torso_1 = 48, torso_2 = 0, + decals_1 = 7, decals_2 = 2, + arms = 44, + pants_1 = 34, pants_2 = 0, + shoes_1 = 27, shoes_2 = 0, + helmet_1 = -1, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 } }, - chef_wear = { + + chef = { male = { - ['tshirt_1'] = 58, ['tshirt_2'] = 0, - ['torso_1'] = 55, ['torso_2'] = 0, - ['decals_1'] = 8, ['decals_2'] = 3, - ['arms'] = 41, - ['pants_1'] = 25, ['pants_2'] = 0, - ['shoes_1'] = 25, ['shoes_2'] = 0, - ['helmet_1'] = -1, ['helmet_2'] = 0, - ['chain_1'] = 0, ['chain_2'] = 0, - ['ears_1'] = 2, ['ears_2'] = 0 + tshirt_1 = 58, tshirt_2 = 0, + torso_1 = 55, torso_2 = 0, + decals_1 = 8, decals_2 = 3, + arms = 41, + pants_1 = 25, pants_2 = 0, + shoes_1 = 25, shoes_2 = 0, + helmet_1 = -1, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 }, female = { - ['tshirt_1'] = 35, ['tshirt_2'] = 0, - ['torso_1'] = 48, ['torso_2'] = 0, - ['decals_1'] = 7, ['decals_2'] = 3, - ['arms'] = 44, - ['pants_1'] = 34, ['pants_2'] = 0, - ['shoes_1'] = 27, ['shoes_2'] = 0, - ['helmet_1'] = -1, ['helmet_2'] = 0, - ['chain_1'] = 0, ['chain_2'] = 0, - ['ears_1'] = 2, ['ears_2'] = 0 + tshirt_1 = 35, tshirt_2 = 0, + torso_1 = 48, torso_2 = 0, + decals_1 = 7, decals_2 = 3, + arms = 44, + pants_1 = 34, pants_2 = 0, + shoes_1 = 27, shoes_2 = 0, + helmet_1 = -1, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 } }, - boss_wear = { -- currently the same as chef_wear + + boss = {-- currently the same as chef male = { - ['tshirt_1'] = 58, ['tshirt_2'] = 0, - ['torso_1'] = 55, ['torso_2'] = 0, - ['decals_1'] = 8, ['decals_2'] = 3, - ['arms'] = 41, - ['pants_1'] = 25, ['pants_2'] = 0, - ['shoes_1'] = 25, ['shoes_2'] = 0, - ['helmet_1'] = -1, ['helmet_2'] = 0, - ['chain_1'] = 0, ['chain_2'] = 0, - ['ears_1'] = 2, ['ears_2'] = 0 + tshirt_1 = 58, tshirt_2 = 0, + torso_1 = 55, torso_2 = 0, + decals_1 = 8, decals_2 = 3, + arms = 41, + pants_1 = 25, pants_2 = 0, + shoes_1 = 25, shoes_2 = 0, + helmet_1 = -1, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 }, female = { - ['tshirt_1'] = 35, ['tshirt_2'] = 0, - ['torso_1'] = 48, ['torso_2'] = 0, - ['decals_1'] = 7, ['decals_2'] = 3, - ['arms'] = 44, - ['pants_1'] = 34, ['pants_2'] = 0, - ['shoes_1'] = 27, ['shoes_2'] = 0, - ['helmet_1'] = -1, ['helmet_2'] = 0, - ['chain_1'] = 0, ['chain_2'] = 0, - ['ears_1'] = 2, ['ears_2'] = 0 + tshirt_1 = 35, tshirt_2 = 0, + torso_1 = 48, torso_2 = 0, + decals_1 = 7, decals_2 = 3, + arms = 44, + pants_1 = 34, pants_2 = 0, + shoes_1 = 27, shoes_2 = 0, + helmet_1 = -1, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 } }, + bullet_wear = { male = { - ['bproof_1'] = 11, ['bproof_2'] = 1 + bproof_1 = 11, bproof_2 = 1 }, female = { - ['bproof_1'] = 13, ['bproof_2'] = 1 + bproof_1 = 13, bproof_2 = 1 } }, + gilet_wear = { male = { - ['tshirt_1'] = 59, ['tshirt_2'] = 1 + tshirt_1 = 59, tshirt_2 = 1 }, female = { - ['tshirt_1'] = 36, ['tshirt_2'] = 1 + tshirt_1 = 36, tshirt_2 = 1 } } - -} \ No newline at end of file +} diff --git a/server/main.lua b/server/main.lua index 06097983..c30f3fc1 100644 --- a/server/main.lua +++ b/server/main.lua @@ -2,7 +2,7 @@ ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) -if Config.MaxInService ~= -1 then +if Config.EnableESXService then TriggerEvent('esx_service:activateService', 'police', Config.MaxInService) end From eb31314f02f9f1f26126d3647fd26ce4bed4a098 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 22 Jan 2020 12:33:51 +0100 Subject: [PATCH 2486/3224] Minor code improvements, drag once, improved coords distance code --- client/main.lua | 196 ++++++++++++++++++++++-------------------------- 1 file changed, 89 insertions(+), 107 deletions(-) diff --git a/client/main.lua b/client/main.lua index ebb4e7a7..dc06a9c4 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1337,43 +1337,40 @@ AddEventHandler('esx_policejob:handcuff', function() isHandcuffed = not isHandcuffed local playerPed = PlayerPedId() - Citizen.CreateThread(function() - if isHandcuffed then + if isHandcuffed then + RequestAnimDict('mp_arresting') + while not HasAnimDictLoaded('mp_arresting') do + Citizen.Wait(100) + end - RequestAnimDict('mp_arresting') - while not HasAnimDictLoaded('mp_arresting') do - Citizen.Wait(100) - end + TaskPlayAnim(playerPed, 'mp_arresting', 'idle', 8.0, -8, -1, 49, 0, 0, 0, 0) - TaskPlayAnim(playerPed, 'mp_arresting', 'idle', 8.0, -8, -1, 49, 0, 0, 0, 0) + SetEnableHandcuffs(playerPed, true) + DisablePlayerFiring(playerPed, true) + SetCurrentPedWeapon(playerPed, GetHashKey('WEAPON_UNARMED'), true) -- unarm player + SetPedCanPlayGestureAnims(playerPed, false) + FreezeEntityPosition(playerPed, true) + DisplayRadar(false) - SetEnableHandcuffs(playerPed, true) - DisablePlayerFiring(playerPed, true) - SetCurrentPedWeapon(playerPed, GetHashKey('WEAPON_UNARMED'), true) -- unarm player - SetPedCanPlayGestureAnims(playerPed, false) - FreezeEntityPosition(playerPed, true) - DisplayRadar(false) - - if Config.EnableHandcuffTimer then - if handcuffTimer.active then - ESX.ClearTimeout(handcuffTimer.task) - end - - StartHandcuffTimer() - end - else - if Config.EnableHandcuffTimer and handcuffTimer.active then + if Config.EnableHandcuffTimer then + if handcuffTimer.active then ESX.ClearTimeout(handcuffTimer.task) end - ClearPedSecondaryTask(playerPed) - SetEnableHandcuffs(playerPed, false) - DisablePlayerFiring(playerPed, false) - SetPedCanPlayGestureAnims(playerPed, true) - FreezeEntityPosition(playerPed, false) - DisplayRadar(true) + StartHandcuffTimer() end - end) + else + if Config.EnableHandcuffTimer and handcuffTimer.active then + ESX.ClearTimeout(handcuffTimer.task) + end + + ClearPedSecondaryTask(playerPed) + SetEnableHandcuffs(playerPed, false) + DisablePlayerFiring(playerPed, false) + SetPedCanPlayGestureAnims(playerPed, true) + FreezeEntityPosition(playerPed, false) + DisplayRadar(true) + end end) RegisterNetEvent('esx_policejob:unrestrain') @@ -1398,43 +1395,37 @@ end) RegisterNetEvent('esx_policejob:drag') AddEventHandler('esx_policejob:drag', function(copId) - if not isHandcuffed then - return + if isHandcuffed then + dragStatus.isDragged = not dragStatus.isDragged + dragStatus.CopId = copId end - - dragStatus.isDragged = not dragStatus.isDragged - dragStatus.CopId = copId end) Citizen.CreateThread(function() - local playerPed - local targetPed + local wasDragged while true do - Citizen.Wait(1) + Citizen.Wait(0) + local playerPed = PlayerPedId() - if isHandcuffed then - playerPed = PlayerPedId() + if isHandcuffed and dragStatus.isDragged then + local targetPed = GetPlayerPed(GetPlayerFromServerId(dragStatus.CopId)) - if dragStatus.isDragged then - targetPed = GetPlayerPed(GetPlayerFromServerId(dragStatus.CopId)) - - -- undrag if target is in an vehicle - if not IsPedSittingInAnyVehicle(targetPed) then + if DoesEntityExist(targetPed) and IsPedOnFoot(targetPed) and not IsPedDeadOrDying(targetPed, true) then + if not wasDragged then AttachEntityToEntity(playerPed, targetPed, 11816, 0.54, 0.54, 0.0, 0.0, 0.0, 0.0, false, false, false, false, 2, true) + wasDragged = true else - dragStatus.isDragged = false - DetachEntity(playerPed, true, false) + Citizen.Wait(1000) end - - if IsPedDeadOrDying(targetPed, true) then - dragStatus.isDragged = false - DetachEntity(playerPed, true, false) - end - else + wasDragged = false + dragStatus.isDragged = false DetachEntity(playerPed, true, false) end + elseif wasDragged then + wasDragged = false + DetachEntity(playerPed, true, false) else Citizen.Wait(500) end @@ -1443,29 +1434,27 @@ end) RegisterNetEvent('esx_policejob:putInVehicle') AddEventHandler('esx_policejob:putInVehicle', function() - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) + if isHandcuffed then + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) - if not isHandcuffed then - return - end + if IsAnyVehicleNearPoint(coords, 5.0) then + local vehicle = GetClosestVehicle(coords, 5.0, 0, 71) - if IsAnyVehicleNearPoint(coords, 5.0) then - local vehicle = GetClosestVehicle(coords, 5.0, 0, 71) + if DoesEntityExist(vehicle) then + local maxSeats, freeSeat = GetVehicleMaxNumberOfPassengers(vehicle) - if DoesEntityExist(vehicle) then - local maxSeats, freeSeat = GetVehicleMaxNumberOfPassengers(vehicle) - - for i=maxSeats - 1, 0, -1 do - if IsVehicleSeatFree(vehicle, i) then - freeSeat = i - break + for i=maxSeats - 1, 0, -1 do + if IsVehicleSeatFree(vehicle, i) then + freeSeat = i + break + end end - end - if freeSeat then - TaskWarpPedIntoVehicle(playerPed, vehicle, freeSeat) - dragStatus.isDragged = false + if freeSeat then + TaskWarpPedIntoVehicle(playerPed, vehicle, freeSeat) + dragStatus.isDragged = false + end end end end @@ -1475,12 +1464,10 @@ RegisterNetEvent('esx_policejob:OutVehicle') AddEventHandler('esx_policejob:OutVehicle', function() local playerPed = PlayerPedId() - if not IsPedSittingInAnyVehicle(playerPed) then - return + if IsPedSittingInAnyVehicle(playerPed) then + local vehicle = GetVehiclePedIsIn(playerPed, false) + TaskLeaveVehicle(playerPed, vehicle, 16) end - - local vehicle = GetVehiclePedIsIn(playerPed, false) - TaskLeaveVehicle(playerPed, vehicle, 16) end) -- Handcuff @@ -1546,7 +1533,6 @@ end) -- Create blips Citizen.CreateThread(function() - for k,v in pairs(Config.PoliceStations) do local blip = AddBlipForCoord(v.Blip.Coords) @@ -1557,89 +1543,86 @@ Citizen.CreateThread(function() SetBlipAsShortRange(blip, true) BeginTextCommandSetBlipName('STRING') - AddTextComponentString(_U('map_blip')) + AddTextComponentSubstringPlayerName(_U('map_blip')) EndTextCommandSetBlipName(blip) end - end) --- Display markers +-- Draw markers and more Citizen.CreateThread(function() while true do Citizen.Wait(0) if PlayerData.job and PlayerData.job.name == 'police' then - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) + local playerCoords = GetEntityCoords(playerPed) local isInMarker, hasExited, letSleep = false, false, true local currentStation, currentPart, currentPartNum for k,v in pairs(Config.PoliceStations) do - for i=1, #v.Cloakrooms, 1 do - local distance = GetDistanceBetweenCoords(coords, v.Cloakrooms[i], true) + local distance = #(playerCoords - v.Cloakrooms[i]) if distance < Config.DrawDistance then DrawMarker(20, v.Cloakrooms[i], 0.0, 0.0, 0.0, 0, 0.0, 0.0, 1.0, 1.0, 1.0, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, true, false, false, false) letSleep = false - end - if distance < Config.MarkerSize.x then - isInMarker, currentStation, currentPart, currentPartNum = true, k, 'Cloakroom', i + if distance < Config.MarkerSize.x then + isInMarker, currentStation, currentPart, currentPartNum = true, k, 'Cloakroom', i + end end end for i=1, #v.Armories, 1 do - local distance = GetDistanceBetweenCoords(coords, v.Armories[i], true) + local distance = #(playerCoords - v.Armories[i]) if distance < Config.DrawDistance then DrawMarker(21, v.Armories[i], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.5, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, true, false, false, false) letSleep = false - end - if distance < Config.MarkerSize.x then - isInMarker, currentStation, currentPart, currentPartNum = true, k, 'Armory', i + if distance < Config.MarkerSize.x then + isInMarker, currentStation, currentPart, currentPartNum = true, k, 'Armory', i + end end end for i=1, #v.Vehicles, 1 do - local distance = GetDistanceBetweenCoords(coords, v.Vehicles[i].Spawner, true) + local distance = #(playerCoords - v.Vehicles[i].Spawner) if distance < Config.DrawDistance then DrawMarker(36, v.Vehicles[i].Spawner, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, true, false, false, false) letSleep = false - end - if distance < Config.MarkerSize.x then - isInMarker, currentStation, currentPart, currentPartNum = true, k, 'Vehicles', i + if distance < Config.MarkerSize.x then + isInMarker, currentStation, currentPart, currentPartNum = true, k, 'Vehicles', i + end end end for i=1, #v.Helicopters, 1 do - local distance = GetDistanceBetweenCoords(coords, v.Helicopters[i].Spawner, true) + local distance = #(playerCoords - v.Helicopters[i].Spawner) if distance < Config.DrawDistance then DrawMarker(34, v.Helicopters[i].Spawner, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, true, false, false, false) letSleep = false - end - if distance < Config.MarkerSize.x then - isInMarker, currentStation, currentPart, currentPartNum = true, k, 'Helicopters', i + if distance < Config.MarkerSize.x then + isInMarker, currentStation, currentPart, currentPartNum = true, k, 'Helicopters', i + end end end if Config.EnablePlayerManagement and PlayerData.job.grade_name == 'boss' then for i=1, #v.BossActions, 1 do - local distance = GetDistanceBetweenCoords(coords, v.BossActions[i], true) + local distance = #(playerCoords - v.BossActions[i]) if distance < Config.DrawDistance then DrawMarker(22, v.BossActions[i], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, true, false, false, false) letSleep = false - end - if distance < Config.MarkerSize.x then - isInMarker, currentStation, currentPart, currentPartNum = true, k, 'BossActions', i + if distance < Config.MarkerSize.x then + isInMarker, currentStation, currentPart, currentPartNum = true, k, 'BossActions', i + end end end end @@ -1670,7 +1653,6 @@ Citizen.CreateThread(function() if letSleep then Citizen.Wait(500) end - else Citizen.Wait(500) end @@ -1691,17 +1673,17 @@ Citizen.CreateThread(function() Citizen.Wait(500) local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) + local playerCoords = GetEntityCoords(playerPed) local closestDistance = -1 local closestEntity = nil for i=1, #trackedEntities, 1 do - local object = GetClosestObjectOfType(coords, 3.0, GetHashKey(trackedEntities[i]), false, false, false) + local object = GetClosestObjectOfType(playerCoords, 3.0, GetHashKey(trackedEntities[i]), false, false, false) if DoesEntityExist(object) then local objCoords = GetEntityCoords(object) - local distance = GetDistanceBetweenCoords(coords, objCoords, true) + local distance = #(playerCoords - objCoords) if closestDistance == -1 or closestDistance > distance then closestDistance = distance From 7037671420b247852427a291b5ffa57ea2894593 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 22 Jan 2020 14:46:41 +0100 Subject: [PATCH 2487/3224] Fixed not on duty logic --- client/main.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/main.lua b/client/main.lua index dc06a9c4..d5ef5c40 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1719,7 +1719,7 @@ Citizen.CreateThread(function() if CurrentAction == 'menu_cloakroom' then OpenCloakroomMenu() elseif CurrentAction == 'menu_armory' then - if Config.MaxInService == -1 then + if not Config.EnableESXService then OpenArmoryMenu(CurrentActionData.station) elseif playerInService then OpenArmoryMenu(CurrentActionData.station) @@ -1727,7 +1727,7 @@ Citizen.CreateThread(function() ESX.ShowNotification(_U('service_not')) end elseif CurrentAction == 'menu_vehicle_spawner' then - if Config.MaxInService == -1 then + if not Config.EnableESXService then OpenVehicleSpawnerMenu('car', CurrentActionData.station, CurrentActionData.part, CurrentActionData.partNum) elseif playerInService then OpenVehicleSpawnerMenu('car', CurrentActionData.station, CurrentActionData.part, CurrentActionData.partNum) @@ -1735,7 +1735,7 @@ Citizen.CreateThread(function() ESX.ShowNotification(_U('service_not')) end elseif CurrentAction == 'Helicopters' then - if Config.MaxInService == -1 then + if not Config.EnableESXService then OpenVehicleSpawnerMenu('helicopter', CurrentActionData.station, CurrentActionData.part, CurrentActionData.partNum) elseif playerInService then OpenVehicleSpawnerMenu('helicopter', CurrentActionData.station, CurrentActionData.part, CurrentActionData.partNum) @@ -1762,7 +1762,7 @@ Citizen.CreateThread(function() end -- CurrentAction end if IsControlJustReleased(0, 167) and not isDead and PlayerData.job and PlayerData.job.name == 'police' and not ESX.UI.Menu.IsOpen('default', GetCurrentResourceName(), 'police_actions') then - if Config.MaxInService == -1 then + if not Config.EnableESXService then OpenPoliceActionsMenu() elseif playerInService then OpenPoliceActionsMenu() From ceef639a134919cc40d86eaa4235a2c6721c287a Mon Sep 17 00:00:00 2001 From: Dione Batista Date: Thu, 23 Jan 2020 11:57:12 -0300 Subject: [PATCH 2488/3224] Create br_esx_basicneeds.sql (#26) --- localization/br_esx_basicneeds.sql | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 localization/br_esx_basicneeds.sql diff --git a/localization/br_esx_basicneeds.sql b/localization/br_esx_basicneeds.sql new file mode 100644 index 00000000..f7b5b6ca --- /dev/null +++ b/localization/br_esx_basicneeds.sql @@ -0,0 +1,6 @@ +USE `essentialmode`; + +INSERT INTO `items` (`name`, `label`, `weight`) VALUES + ('bread', 'Pao', 1), + ('water', 'Agua', 1) +; From 3e52e7ece0fbc1b9c756371f26d0138bbe89bc7c Mon Sep 17 00:00:00 2001 From: rex2630 Date: Thu, 23 Jan 2020 16:51:34 +0100 Subject: [PATCH 2489/3224] Create cs_esx_accessories.sql --- localization/cs_esx_accessories.sql | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 localization/cs_esx_accessories.sql diff --git a/localization/cs_esx_accessories.sql b/localization/cs_esx_accessories.sql new file mode 100644 index 00000000..d3319986 --- /dev/null +++ b/localization/cs_esx_accessories.sql @@ -0,0 +1,8 @@ +USE `essentialmode`; + +INSERT INTO `datastore` (name, label, shared) VALUES + ('user_ears', 'Usi', 0), + ('user_glasses', 'Bryle', 0), + ('user_helmet', 'Helma', 0), + ('user_mask', 'Maska', 0) +; From e1eb0aea2c8ea020f7b67c6779cf80c0d586279d Mon Sep 17 00:00:00 2001 From: rex2630 Date: Thu, 23 Jan 2020 16:54:32 +0100 Subject: [PATCH 2490/3224] Create cs_esx_basicneeds.sql --- localization/cs_esx_basicneeds.sql | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 localization/cs_esx_basicneeds.sql diff --git a/localization/cs_esx_basicneeds.sql b/localization/cs_esx_basicneeds.sql new file mode 100644 index 00000000..cca74355 --- /dev/null +++ b/localization/cs_esx_basicneeds.sql @@ -0,0 +1,6 @@ +USE `essentialmode`; + +INSERT INTO `items` (`name`, `label`, `weight`) VALUES + ('bread', 'Chleba', 1), + ('water', 'Voda', 1) +; From 54bb4aa7b1257556942e2e588dcdc07860c45f82 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Thu, 23 Jan 2020 17:02:25 +0100 Subject: [PATCH 2491/3224] Added czech language (#11) * Create cs.lua * Update fxmanifest.lua --- fxmanifest.lua | 2 ++ locales/cs.lua | 9 +++++++++ 2 files changed, 11 insertions(+) create mode 100644 locales/cs.lua diff --git a/fxmanifest.lua b/fxmanifest.lua index 0c6cc685..474fbd9d 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -14,6 +14,7 @@ server_scripts { 'locales/fi.lua', 'locales/fr.lua', 'locales/es.lua', + 'locales/cs.lua', 'config.lua', 'server/main.lua' } @@ -26,6 +27,7 @@ client_scripts { 'locales/fi.lua', 'locales/fr.lua', 'locales/es.lua', + 'locales/cs.lua', 'config.lua', 'client/main.lua' } diff --git a/locales/cs.lua b/locales/cs.lua new file mode 100644 index 00000000..97c4aa84 --- /dev/null +++ b/locales/cs.lua @@ -0,0 +1,9 @@ +Locales['cs'] = { + ['valid_purchase'] = 'potvrdit nakup?', + ['yes'] = 'ano', + ['no'] = 'ne', + ['not_enough_money'] = 'nemas dostatek penez', + ['press_access'] = 'stiskni ~INPUT_CONTEXT~ pro pristup k ~y~Holici~s~.', + ['barber_blip'] = 'Holic', + ['you_paid'] = 'zaplatil jsi ~g~$%s~s~', +} From 9a80cd0dcd2c40c46c081e3a93a18fbad6354542 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 24 Jan 2020 11:19:56 +0100 Subject: [PATCH 2492/3224] Minor code improvements --- client/job.lua | 51 +++++++++++++++++++++---------------------------- client/main.lua | 2 +- 2 files changed, 23 insertions(+), 30 deletions(-) diff --git a/client/job.lua b/client/job.lua index c0c3c06c..a43f732f 100644 --- a/client/job.lua +++ b/client/job.lua @@ -187,7 +187,6 @@ Citizen.CreateThread(function() local currentHospital, currentPart, currentPartNum for hospitalNum,hospital in pairs(Config.Hospitals) do - -- Ambulance Actions for k,v in ipairs(hospital.AmbulanceActions) do local distance = #(playerCoords - v) @@ -195,10 +194,10 @@ Citizen.CreateThread(function() if distance < Config.DrawDistance then DrawMarker(Config.Marker.type, v, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Config.Marker.x, Config.Marker.y, Config.Marker.z, Config.Marker.r, Config.Marker.g, Config.Marker.b, Config.Marker.a, false, false, 2, Config.Marker.rotate, nil, nil, false) letSleep = false - end - if distance < Config.Marker.x then - isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'AmbulanceActions', k + if distance < Config.Marker.x then + isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'AmbulanceActions', k + end end end @@ -209,10 +208,10 @@ Citizen.CreateThread(function() if distance < Config.DrawDistance then DrawMarker(Config.Marker.type, v, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Config.Marker.x, Config.Marker.y, Config.Marker.z, Config.Marker.r, Config.Marker.g, Config.Marker.b, Config.Marker.a, false, false, 2, Config.Marker.rotate, nil, nil, false) letSleep = false - end - if distance < Config.Marker.x then - isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'Pharmacy', k + if distance < Config.Marker.x then + isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'Pharmacy', k + end end end @@ -223,10 +222,10 @@ Citizen.CreateThread(function() if distance < Config.DrawDistance then DrawMarker(v.Marker.type, v.Spawner, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Marker.x, v.Marker.y, v.Marker.z, v.Marker.r, v.Marker.g, v.Marker.b, v.Marker.a, false, false, 2, v.Marker.rotate, nil, nil, false) letSleep = false - end - if distance < v.Marker.x then - isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'Vehicles', k + if distance < v.Marker.x then + isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'Vehicles', k + end end end @@ -237,10 +236,10 @@ Citizen.CreateThread(function() if distance < Config.DrawDistance then DrawMarker(v.Marker.type, v.Spawner, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Marker.x, v.Marker.y, v.Marker.z, v.Marker.r, v.Marker.g, v.Marker.b, v.Marker.a, false, false, 2, v.Marker.rotate, nil, nil, false) letSleep = false - end - if distance < v.Marker.x then - isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'Helicopters', k + if distance < v.Marker.x then + isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'Helicopters', k + end end end @@ -251,11 +250,10 @@ Citizen.CreateThread(function() if distance < Config.DrawDistance then DrawMarker(v.Marker.type, v.From, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Marker.x, v.Marker.y, v.Marker.z, v.Marker.r, v.Marker.g, v.Marker.b, v.Marker.a, false, false, 2, v.Marker.rotate, nil, nil, false) letSleep = false - end - - if distance < v.Marker.x then - FastTravel(v.To.coords, v.To.heading) + if distance < v.Marker.x then + FastTravel(v.To.coords, v.To.heading) + end end end @@ -266,18 +264,16 @@ Citizen.CreateThread(function() if distance < Config.DrawDistance then DrawMarker(v.Marker.type, v.From, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Marker.x, v.Marker.y, v.Marker.z, v.Marker.r, v.Marker.g, v.Marker.b, v.Marker.a, false, false, 2, v.Marker.rotate, nil, nil, false) letSleep = false - end - if distance < v.Marker.x then - isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'FastTravelsPrompt', k + if distance < v.Marker.x then + isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'FastTravelsPrompt', k + end end end - end -- Logic for exiting & entering markers if isInMarker and not HasAlreadyEnteredMarker or (isInMarker and (LastHospital ~= currentHospital or LastPart ~= currentPart or LastPartNum ~= currentPartNum)) then - if (LastHospital ~= nil and LastPart ~= nil and LastPartNum ~= nil) and (LastHospital ~= currentHospital or LastPart ~= currentPart or LastPartNum ~= currentPartNum) @@ -289,7 +285,6 @@ Citizen.CreateThread(function() HasAlreadyEnteredMarker, LastHospital, LastPart, LastPartNum = true, currentHospital, currentPart, currentPartNum TriggerEvent('esx_ambulancejob:hasEnteredMarker', currentHospital, currentPart, currentPartNum) - end if not hasExited and not isInMarker and HasAlreadyEnteredMarker then @@ -348,7 +343,6 @@ Citizen.CreateThread(function() ESX.ShowHelpNotification(CurrentActionMsg) if IsControlJustReleased(0, 38) then - if CurrentAction == 'AmbulanceActions' then OpenAmbulanceActionsMenu() elseif CurrentAction == 'Pharmacy' then @@ -362,10 +356,9 @@ Citizen.CreateThread(function() end CurrentAction = nil - end - elseif ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'ambulance' and not isDead then + elseif ESX.PlayerData.job and ESX.PlayerData.job.name == 'ambulance' and not isDead then if IsControlJustReleased(0, 167) then OpenMobileAmbulanceActionsMenu() end @@ -907,16 +900,16 @@ AddEventHandler('esx_ambulancejob:setDeadPlayers', function(_deadPlayers) local player = GetPlayerFromServerId(playerId) local playerPed = GetPlayerPed(player) local blip = AddBlipForEntity(playerPed) - + SetBlipSprite(blip, 303) SetBlipColour(blip, 1) SetBlipFlashes(blip, true) SetBlipCategory(blip, 7) - + BeginTextCommandSetBlipName('STRING') AddTextComponentSubstringPlayerName(_U('blip_dead')) EndTextCommandSetBlipName(blip) - + deadPlayerBlips[playerId] = blip end end diff --git a/client/main.lua b/client/main.lua index 55f7689c..a73715e7 100644 --- a/client/main.lua +++ b/client/main.lua @@ -138,7 +138,7 @@ function StartDistressSignal() local timer = Config.BleedoutTimer while timer > 0 and isDead do - Citizen.Wait(2) + Citizen.Wait(0) timer = timer - 30 SetTextFont(4) From 24990717bc5b90c125943c9eb416dfc671530554 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 24 Jan 2020 11:25:25 +0100 Subject: [PATCH 2493/3224] Fixed #135 --- client/job.lua | 249 ++++++++++++++++++++++++++----------------------- 1 file changed, 133 insertions(+), 116 deletions(-) diff --git a/client/job.lua b/client/job.lua index a43f732f..f6c5eff5 100644 --- a/client/job.lua +++ b/client/job.lua @@ -182,67 +182,120 @@ end Citizen.CreateThread(function() while true do Citizen.Wait(0) - local playerCoords = GetEntityCoords(PlayerPedId()) - local letSleep, isInMarker, hasExited = true, false, false - local currentHospital, currentPart, currentPartNum + + if ESX.PlayerData.job and ESX.PlayerData.job.name == 'ambulance' then + local playerCoords = GetEntityCoords(PlayerPedId()) + local letSleep, isInMarker, hasExited = true, false, false + local currentHospital, currentPart, currentPartNum + + for hospitalNum,hospital in pairs(Config.Hospitals) do + -- Ambulance Actions + for k,v in ipairs(hospital.AmbulanceActions) do + local distance = #(playerCoords - v) + + if distance < Config.DrawDistance then + DrawMarker(Config.Marker.type, v, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Config.Marker.x, Config.Marker.y, Config.Marker.z, Config.Marker.r, Config.Marker.g, Config.Marker.b, Config.Marker.a, false, false, 2, Config.Marker.rotate, nil, nil, false) + letSleep = false + + if distance < Config.Marker.x then + isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'AmbulanceActions', k + end + end + end + + -- Pharmacies + for k,v in ipairs(hospital.Pharmacies) do + local distance = #(playerCoords - v) + + if distance < Config.DrawDistance then + DrawMarker(Config.Marker.type, v, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Config.Marker.x, Config.Marker.y, Config.Marker.z, Config.Marker.r, Config.Marker.g, Config.Marker.b, Config.Marker.a, false, false, 2, Config.Marker.rotate, nil, nil, false) + letSleep = false + + if distance < Config.Marker.x then + isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'Pharmacy', k + end + end + end + + -- Vehicle Spawners + for k,v in ipairs(hospital.Vehicles) do + local distance = #(playerCoords - v.Spawner) + + if distance < Config.DrawDistance then + DrawMarker(v.Marker.type, v.Spawner, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Marker.x, v.Marker.y, v.Marker.z, v.Marker.r, v.Marker.g, v.Marker.b, v.Marker.a, false, false, 2, v.Marker.rotate, nil, nil, false) + letSleep = false + + if distance < v.Marker.x then + isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'Vehicles', k + end + end + end + + -- Helicopter Spawners + for k,v in ipairs(hospital.Helicopters) do + local distance = #(playerCoords - v.Spawner) + + if distance < Config.DrawDistance then + DrawMarker(v.Marker.type, v.Spawner, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Marker.x, v.Marker.y, v.Marker.z, v.Marker.r, v.Marker.g, v.Marker.b, v.Marker.a, false, false, 2, v.Marker.rotate, nil, nil, false) + letSleep = false + + if distance < v.Marker.x then + isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'Helicopters', k + end + end + end + + -- Fast Travels (Prompt) + for k,v in ipairs(hospital.FastTravelsPrompt) do + local distance = #(playerCoords - v.From) + + if distance < Config.DrawDistance then + DrawMarker(v.Marker.type, v.From, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Marker.x, v.Marker.y, v.Marker.z, v.Marker.r, v.Marker.g, v.Marker.b, v.Marker.a, false, false, 2, v.Marker.rotate, nil, nil, false) + letSleep = false + + if distance < v.Marker.x then + isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'FastTravelsPrompt', k + end + end + end + end + + -- Logic for exiting & entering markers + if isInMarker and not HasAlreadyEnteredMarker or (isInMarker and (LastHospital ~= currentHospital or LastPart ~= currentPart or LastPartNum ~= currentPartNum)) then + if + (LastHospital ~= nil and LastPart ~= nil and LastPartNum ~= nil) and + (LastHospital ~= currentHospital or LastPart ~= currentPart or LastPartNum ~= currentPartNum) + then + TriggerEvent('esx_ambulancejob:hasExitedMarker', LastHospital, LastPart, LastPartNum) + hasExited = true + end + + HasAlreadyEnteredMarker, LastHospital, LastPart, LastPartNum = true, currentHospital, currentPart, currentPartNum + + TriggerEvent('esx_ambulancejob:hasEnteredMarker', currentHospital, currentPart, currentPartNum) + end + + if not hasExited and not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent('esx_ambulancejob:hasExitedMarker', LastHospital, LastPart, LastPartNum) + end + + if letSleep then + Citizen.Wait(500) + end + else + Citizen.Wait(500) + end + end +end) + +-- Fast travels +Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + local playerCoords, letSleep = GetEntityCoords(PlayerPedId()), true for hospitalNum,hospital in pairs(Config.Hospitals) do - -- Ambulance Actions - for k,v in ipairs(hospital.AmbulanceActions) do - local distance = #(playerCoords - v) - - if distance < Config.DrawDistance then - DrawMarker(Config.Marker.type, v, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Config.Marker.x, Config.Marker.y, Config.Marker.z, Config.Marker.r, Config.Marker.g, Config.Marker.b, Config.Marker.a, false, false, 2, Config.Marker.rotate, nil, nil, false) - letSleep = false - - if distance < Config.Marker.x then - isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'AmbulanceActions', k - end - end - end - - -- Pharmacies - for k,v in ipairs(hospital.Pharmacies) do - local distance = #(playerCoords - v) - - if distance < Config.DrawDistance then - DrawMarker(Config.Marker.type, v, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Config.Marker.x, Config.Marker.y, Config.Marker.z, Config.Marker.r, Config.Marker.g, Config.Marker.b, Config.Marker.a, false, false, 2, Config.Marker.rotate, nil, nil, false) - letSleep = false - - if distance < Config.Marker.x then - isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'Pharmacy', k - end - end - end - - -- Vehicle Spawners - for k,v in ipairs(hospital.Vehicles) do - local distance = #(playerCoords - v.Spawner) - - if distance < Config.DrawDistance then - DrawMarker(v.Marker.type, v.Spawner, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Marker.x, v.Marker.y, v.Marker.z, v.Marker.r, v.Marker.g, v.Marker.b, v.Marker.a, false, false, 2, v.Marker.rotate, nil, nil, false) - letSleep = false - - if distance < v.Marker.x then - isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'Vehicles', k - end - end - end - - -- Helicopter Spawners - for k,v in ipairs(hospital.Helicopters) do - local distance = #(playerCoords - v.Spawner) - - if distance < Config.DrawDistance then - DrawMarker(v.Marker.type, v.Spawner, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Marker.x, v.Marker.y, v.Marker.z, v.Marker.r, v.Marker.g, v.Marker.b, v.Marker.a, false, false, 2, v.Marker.rotate, nil, nil, false) - letSleep = false - - if distance < v.Marker.x then - isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'Helicopters', k - end - end - end - -- Fast Travels for k,v in ipairs(hospital.FastTravels) do local distance = #(playerCoords - v.From) @@ -256,40 +309,6 @@ Citizen.CreateThread(function() end end end - - -- Fast Travels (Prompt) - for k,v in ipairs(hospital.FastTravelsPrompt) do - local distance = #(playerCoords - v.From) - - if distance < Config.DrawDistance then - DrawMarker(v.Marker.type, v.From, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Marker.x, v.Marker.y, v.Marker.z, v.Marker.r, v.Marker.g, v.Marker.b, v.Marker.a, false, false, 2, v.Marker.rotate, nil, nil, false) - letSleep = false - - if distance < v.Marker.x then - isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'FastTravelsPrompt', k - end - end - end - end - - -- Logic for exiting & entering markers - if isInMarker and not HasAlreadyEnteredMarker or (isInMarker and (LastHospital ~= currentHospital or LastPart ~= currentPart or LastPartNum ~= currentPartNum)) then - if - (LastHospital ~= nil and LastPart ~= nil and LastPartNum ~= nil) and - (LastHospital ~= currentHospital or LastPart ~= currentPart or LastPartNum ~= currentPartNum) - then - TriggerEvent('esx_ambulancejob:hasExitedMarker', LastHospital, LastPart, LastPartNum) - hasExited = true - end - - HasAlreadyEnteredMarker, LastHospital, LastPart, LastPartNum = true, currentHospital, currentPart, currentPartNum - - TriggerEvent('esx_ambulancejob:hasEnteredMarker', currentHospital, currentPart, currentPartNum) - end - - if not hasExited and not isInMarker and HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = false - TriggerEvent('esx_ambulancejob:hasExitedMarker', LastHospital, LastPart, LastPartNum) end if letSleep then @@ -299,30 +318,28 @@ Citizen.CreateThread(function() end) AddEventHandler('esx_ambulancejob:hasEnteredMarker', function(hospital, part, partNum) - if ESX.PlayerData.job and ESX.PlayerData.job.name == 'ambulance' then - if part == 'AmbulanceActions' then - CurrentAction = part - CurrentActionMsg = _U('actions_prompt') - CurrentActionData = {} - elseif part == 'Pharmacy' then - CurrentAction = part - CurrentActionMsg = _U('open_pharmacy') - CurrentActionData = {} - elseif part == 'Vehicles' then - CurrentAction = part - CurrentActionMsg = _U('garage_prompt') - CurrentActionData = {hospital = hospital, partNum = partNum} - elseif part == 'Helicopters' then - CurrentAction = part - CurrentActionMsg = _U('helicopter_prompt') - CurrentActionData = {hospital = hospital, partNum = partNum} - elseif part == 'FastTravelsPrompt' then - local travelItem = Config.Hospitals[hospital][part][partNum] + if part == 'AmbulanceActions' then + CurrentAction = part + CurrentActionMsg = _U('actions_prompt') + CurrentActionData = {} + elseif part == 'Pharmacy' then + CurrentAction = part + CurrentActionMsg = _U('open_pharmacy') + CurrentActionData = {} + elseif part == 'Vehicles' then + CurrentAction = part + CurrentActionMsg = _U('garage_prompt') + CurrentActionData = {hospital = hospital, partNum = partNum} + elseif part == 'Helicopters' then + CurrentAction = part + CurrentActionMsg = _U('helicopter_prompt') + CurrentActionData = {hospital = hospital, partNum = partNum} + elseif part == 'FastTravelsPrompt' then + local travelItem = Config.Hospitals[hospital][part][partNum] - CurrentAction = part - CurrentActionMsg = travelItem.Prompt - CurrentActionData = {to = travelItem.To.coords, heading = travelItem.To.heading} - end + CurrentAction = part + CurrentActionMsg = travelItem.Prompt + CurrentActionData = {to = travelItem.To.coords, heading = travelItem.To.heading} end end) From ef171d2ded64ed4c8fc94762c20d46a6b1e72ebe Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 24 Jan 2020 11:33:53 +0100 Subject: [PATCH 2494/3224] Minor cleanup, removed unused code --- client/job.lua | 56 +++++++------------------------------------------ client/main.lua | 31 ++++++++++++--------------- 2 files changed, 21 insertions(+), 66 deletions(-) diff --git a/client/job.lua b/client/job.lua index f6c5eff5..c2d8b9f1 100644 --- a/client/job.lua +++ b/client/job.lua @@ -459,11 +459,9 @@ function OpenVehicleSpawnerMenu(hospital, partNum) align = 'top-left', elements = elements }, function(data, menu) - if data.current.action == 'buy_vehicle' then local shopCoords = Config.Hospitals[hospital].Vehicles[partNum].InsideShop local shopElements = {} - local authorizedVehicles = Config.AuthorizedVehicles[ESX.PlayerData.job.grade_name] if #authorizedVehicles > 0 then @@ -476,11 +474,9 @@ function OpenVehicleSpawnerMenu(hospital, partNum) type = 'car' }) end - else - return - end - OpenShopMenu(shopElements, playerCoords, shopCoords) + OpenShopMenu(shopElements, playerCoords, shopCoords) + end elseif data.current.action == 'garage' then local garage = {} @@ -529,20 +525,16 @@ function OpenVehicleSpawnerMenu(hospital, partNum) end, function(data2, menu2) menu2.close() end) - else ESX.ShowNotification(_U('garage_empty')) end end, 'car') - elseif data.current.action == 'store_garage' then StoreNearbyVehicle(playerCoords) end - end, function(data, menu) menu.close() end) - end function StoreNearbyVehicle(playerCoords) @@ -629,22 +621,18 @@ end function OpenHelicopterSpawnerMenu(hospital, partNum) local playerCoords = GetEntityCoords(PlayerPedId()) ESX.PlayerData = ESX.GetPlayerData() - local elements = { - {label = _U('helicopter_garage'), action = 'garage'}, - {label = _U('helicopter_store'), action = 'store_garage'}, - {label = _U('helicopter_buy'), action = 'buy_helicopter'} - } ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'helicopter_spawner', { title = _U('helicopter_title'), align = 'top-left', - elements = elements - }, function(data, menu) - + elements = { + {label = _U('helicopter_garage'), action = 'garage'}, + {label = _U('helicopter_store'), action = 'store_garage'}, + {label = _U('helicopter_buy'), action = 'buy_helicopter'} + }}, function(data, menu) if data.current.action == 'buy_helicopter' then local shopCoords = Config.Hospitals[hospital].Helicopters[partNum].InsideShop local shopElements = {} - local authorizedHelicopters = Config.AuthorizedHelicopters[ESX.PlayerData.job.grade_name] if #authorizedHelicopters > 0 then @@ -711,20 +699,16 @@ function OpenHelicopterSpawnerMenu(hospital, partNum) end, function(data2, menu2) menu2.close() end) - else ESX.ShowNotification(_U('garage_empty')) end end, 'helicopter') - elseif data.current.action == 'store_garage' then StoreNearbyVehicle(playerCoords) end - end, function(data, menu) menu.close() end) - end function OpenShopMenu(elements, restoreCoords, shopCoords) @@ -853,37 +837,13 @@ function OpenPharmacyMenu() elements = { {label = _U('pharmacy_take', _U('medikit')), item = 'medikit', type = 'slider', value = 1, min = 1, max = 100}, {label = _U('pharmacy_take', _U('bandage')), item = 'bandage', type = 'slider', value = 1, min = 1, max = 100} - } - }, function(data, menu) + }}, function(data, menu) TriggerServerEvent('esx_ambulancejob:giveItem', data.current.item, data.current.value) end, function(data, menu) menu.close() end) end -function WarpPedInClosestVehicle(ped) - local coords = GetEntityCoords(ped) - - local vehicle, distance = ESX.Game.GetClosestVehicle(coords) - - if distance ~= -1 and distance <= 5.0 then - local maxSeats, freeSeat = GetVehicleMaxNumberOfPassengers(vehicle) - - for i=maxSeats - 1, 0, -1 do - if IsVehicleSeatFree(vehicle, i) then - freeSeat = i - break - end - end - - if freeSeat then - TaskWarpPedIntoVehicle(ped, vehicle, freeSeat) - end - else - ESX.ShowNotification(_U('no_vehicles')) - end -end - RegisterNetEvent('esx_ambulancejob:heal') AddEventHandler('esx_ambulancejob:heal', function(healType, quiet) local playerPed = PlayerPedId() diff --git a/client/main.lua b/client/main.lua index a73715e7..30f62169 100644 --- a/client/main.lua +++ b/client/main.lua @@ -334,32 +334,27 @@ RegisterNetEvent('esx_ambulancejob:revive') AddEventHandler('esx_ambulancejob:revive', function() local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) - TriggerServerEvent('esx_ambulancejob:setDeathStatus', false) - Citizen.CreateThread(function() - DoScreenFadeOut(800) + DoScreenFadeOut(800) - while not IsScreenFadedOut() do - Citizen.Wait(50) - end + while not IsScreenFadedOut() do + Citizen.Wait(50) + end - local formattedCoords = { - x = ESX.Math.Round(coords.x, 1), - y = ESX.Math.Round(coords.y, 1), - z = ESX.Math.Round(coords.z, 1) - } + local formattedCoords = { + x = ESX.Math.Round(coords.x, 1), + y = ESX.Math.Round(coords.y, 1), + z = ESX.Math.Round(coords.z, 1) + } - RespawnPed(playerPed, formattedCoords, 0.0) + RespawnPed(playerPed, formattedCoords, 0.0) - StopScreenEffect('DeathFailOut') - DoScreenFadeIn(800) - end) + StopScreenEffect('DeathFailOut') + DoScreenFadeIn(800) end) -- Load unloaded IPLs if Config.LoadIpl then - Citizen.CreateThread(function() - RequestIpl('Coroner_Int_on') -- Morgue - end) + RequestIpl('Coroner_Int_on') -- Morgue end From d4776bf383120aa55ea7d950066bc549dfca43e1 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 24 Jan 2020 11:34:44 +0100 Subject: [PATCH 2495/3224] Removed unused locale --- locales/br.lua | 1 - locales/cs.lua | 1 - locales/en.lua | 1 - locales/es.lua | 1 - locales/fi.lua | 1 - locales/fr.lua | 1 - locales/pl.lua | 1 - locales/sv.lua | 1 - 8 files changed, 8 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index da8db727..4d88eed3 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -43,7 +43,6 @@ Locales['br'] = { ['heal_inprogress'] = 'você está curando!', ['heal_complete'] = 'você curou ~y~%s~s~', ['no_players'] = 'nenhum cidadão nas proximidades', - ['no_vehicles'] = 'sem veículos nas proximidades', ['player_not_unconscious'] = 'não está inconsciente', ['player_not_conscious'] = 'esse cidadão não está consciente!', -- Boss Menu diff --git a/locales/cs.lua b/locales/cs.lua index f3a01344..5e3690d7 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -43,7 +43,6 @@ Locales['cs'] = { ['heal_inprogress'] = 'uzdravujete!', ['heal_complete'] = 'uzdravili jste ~y~%s~s~', ['no_players'] = 'v okolí není žádný hráč!', - ['no_vehicles'] = 'v okolí není žádné vozidlo', ['player_not_unconscious'] = 'hráč není v bezvědomí!', ['player_not_conscious'] = 'hráč je v bezvědomí!', -- Boss Menu diff --git a/locales/en.lua b/locales/en.lua index eee39e22..14111578 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -43,7 +43,6 @@ Locales['en'] = { ['heal_inprogress'] = 'you are healing!', ['heal_complete'] = 'you have healed ~y~%s~s~', ['no_players'] = 'no players nearby', - ['no_vehicles'] = 'no vehicles nearby', ['player_not_unconscious'] = 'that player is not unconscious!', ['player_not_conscious'] = 'that player is not conscious!', -- Boss Menu diff --git a/locales/es.lua b/locales/es.lua index a9cec2aa..656a4d53 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -43,7 +43,6 @@ Locales['es'] = { ['heal_inprogress'] = 'you are healing!', ['heal_complete'] = 'you have healed ~y~%s~s~', ['no_players'] = 'ningún jugador cerca', - ['no_vehicles'] = 'ningún vehículo cerca', ['player_not_unconscious'] = 'n\'estás inconsciente', ['player_not_conscious'] = 'that player is not conscious!', -- Boss Menu diff --git a/locales/fi.lua b/locales/fi.lua index 3ca1f5c6..d98cf398 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -43,7 +43,6 @@ Locales['fi'] = { ['heal_inprogress'] = 'sinä olet parantamassa!', ['heal_complete'] = 'sinä paransit henkilön ~y~%s~s~', ['no_players'] = 'ei pelaajia lähettyvillä', - ['no_vehicles'] = 'ei ajoneuvoja lähettyvillä', ['player_not_unconscious'] = 'tämä pelaaja ei ole tajuton!', ['player_not_conscious'] = 'tämä pelaaja ei ole tajuissaan!', -- Boss Menu diff --git a/locales/fr.lua b/locales/fr.lua index e86658c7..51d558ff 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -43,7 +43,6 @@ Locales['fr'] = { ['heal_inprogress'] = 'vous soignez...', ['heal_complete'] = 'vous avez soigné ~y~%s~s~', ['no_players'] = 'aucun joueur à proximité', - ['no_vehicles'] = 'aucun véhicule à proximité', ['player_not_unconscious'] = 'n\'est pas inconscient', ['player_not_conscious'] = 'Cette personne est inconsciente!', -- Boss Menu diff --git a/locales/pl.lua b/locales/pl.lua index 9d70f91e..007c8383 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -43,7 +43,6 @@ Locales['pl'] = { ['heal_inprogress'] = 'leczysz!', ['heal_complete'] = 'zostałeś uleczony ~y~%s~s~', ['no_players'] = 'brak graczy w pobliżu', - ['no_vehicles'] = 'brak pojazdów w pobliżu', ['player_not_unconscious'] = 'ten gracz nie jest nieprzytomny!', ['player_not_conscious'] = 'ten gracz nie jest świadomy!', -- Boss Menu diff --git a/locales/sv.lua b/locales/sv.lua index 773a0ebc..c7f55b6e 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -43,7 +43,6 @@ Locales['sv'] = { ['heal_inprogress'] = 'du behandlar patienten!', ['heal_complete'] = 'du har behandlat ~y~%s~s~', ['no_players'] = 'det finns inga spelare i närheten!', - ['no_vehicles'] = 'det finns inget fordon i närheten!', ['player_not_unconscious'] = 'spelaren är inte medvetslös!', ['player_not_conscious'] = 'spelaren är inte vid medvetande!', -- Boss Menu From 073cfde650e7c4b2f24326add2a6d68910b835ae Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 24 Jan 2020 12:11:45 +0100 Subject: [PATCH 2496/3224] Merged helicopter and car garage, which removes dupe code and move to its own file --- client/job.lua | 388 +-------------------------------------------- client/vehicle.lua | 297 ++++++++++++++++++++++++++++++++++ config.lua | 58 +++---- fxmanifest.lua | 3 +- locales/br.lua | 8 +- locales/cs.lua | 8 +- locales/en.lua | 8 +- locales/es.lua | 8 +- locales/fi.lua | 8 +- locales/fr.lua | 8 +- locales/pl.lua | 8 +- locales/sv.lua | 10 +- server/main.lua | 20 +-- 13 files changed, 346 insertions(+), 486 deletions(-) create mode 100644 client/vehicle.lua diff --git a/client/job.lua b/client/job.lua index c2d8b9f1..2dbeaf01 100644 --- a/client/job.lua +++ b/client/job.lua @@ -1,7 +1,7 @@ local CurrentAction, CurrentActionMsg, CurrentActionData = nil, '', {} local HasAlreadyEnteredMarker, LastHospital, LastPart, LastPartNum local isBusy, deadPlayers, deadPlayerBlips, isOnDuty = false, {}, {}, false -local spawnedVehicles, isInShopMenu = {}, false +isInShopMenu = false function OpenAmbulanceActionsMenu() local elements = { @@ -365,9 +365,9 @@ Citizen.CreateThread(function() elseif CurrentAction == 'Pharmacy' then OpenPharmacyMenu() elseif CurrentAction == 'Vehicles' then - OpenVehicleSpawnerMenu(CurrentActionData.hospital, CurrentActionData.partNum) + OpenVehicleSpawnerMenu('car', CurrentActionData.hospital, CurrentAction, CurrentActionData.partNum) elseif CurrentAction == 'Helicopters' then - OpenHelicopterSpawnerMenu(CurrentActionData.hospital, CurrentActionData.partNum) + OpenVehicleSpawnerMenu('helicopter', CurrentActionData.hospital, CurrentAction, CurrentActionData.partNum) elseif CurrentAction == 'FastTravelsPrompt' then FastTravel(CurrentActionData.to, CurrentActionData.heading) end @@ -446,388 +446,6 @@ function OpenCloakroomMenu() end) end -function OpenVehicleSpawnerMenu(hospital, partNum) - local playerCoords = GetEntityCoords(PlayerPedId()) - local elements = { - {label = _U('garage_storeditem'), action = 'garage'}, - {label = _U('garage_storeitem'), action = 'store_garage'}, - {label = _U('garage_buyitem'), action = 'buy_vehicle'} - } - - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle', { - title = _U('garage_title'), - align = 'top-left', - elements = elements - }, function(data, menu) - if data.current.action == 'buy_vehicle' then - local shopCoords = Config.Hospitals[hospital].Vehicles[partNum].InsideShop - local shopElements = {} - local authorizedVehicles = Config.AuthorizedVehicles[ESX.PlayerData.job.grade_name] - - if #authorizedVehicles > 0 then - for k,vehicle in ipairs(authorizedVehicles) do - table.insert(shopElements, { - label = ('%s - %s'):format(vehicle.label, _U('shop_item', ESX.Math.GroupDigits(vehicle.price))), - name = vehicle.label, - model = vehicle.model, - price = vehicle.price, - type = 'car' - }) - end - - OpenShopMenu(shopElements, playerCoords, shopCoords) - end - elseif data.current.action == 'garage' then - local garage = {} - - ESX.TriggerServerCallback('esx_vehicleshop:retrieveJobVehicles', function(jobVehicles) - if #jobVehicles > 0 then - for k,v in ipairs(jobVehicles) do - local props = json.decode(v.vehicle) - local vehicleName = GetLabelText(GetDisplayNameFromVehicleModel(props.model)) - local label = ('%s - %s: '):format(vehicleName, props.plate) - - if v.stored then - label = label .. ('%s'):format(_U('garage_stored')) - else - label = label .. ('%s'):format(_U('garage_notstored')) - end - - table.insert(garage, { - label = label, - stored = v.stored, - model = props.model, - vehicleProps = props - }) - end - - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_garage', { - title = _U('garage_title'), - align = 'top-left', - elements = garage - }, function(data2, menu2) - if data2.current.stored then - local foundSpawn, spawnPoint = GetAvailableVehicleSpawnPoint(hospital, 'Vehicles', partNum) - - if foundSpawn then - menu2.close() - - ESX.Game.SpawnVehicle(data2.current.model, spawnPoint.coords, spawnPoint.heading, function(vehicle) - ESX.Game.SetVehicleProperties(vehicle, data2.current.vehicleProps) - - TriggerServerEvent('esx_vehicleshop:setJobVehicleState', data2.current.vehicleProps.plate, false) - ESX.ShowNotification(_U('garage_released')) - end) - end - else - ESX.ShowNotification(_U('garage_notavailable')) - end - end, function(data2, menu2) - menu2.close() - end) - else - ESX.ShowNotification(_U('garage_empty')) - end - end, 'car') - elseif data.current.action == 'store_garage' then - StoreNearbyVehicle(playerCoords) - end - end, function(data, menu) - menu.close() - end) -end - -function StoreNearbyVehicle(playerCoords) - local vehicles, vehiclePlates = ESX.Game.GetVehiclesInArea(playerCoords, 30.0), {} - - if #vehicles > 0 then - for k,v in ipairs(vehicles) do - - -- 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)) - }) - end - end - else - ESX.ShowNotification(_U('garage_store_nearby')) - return - end - - ESX.TriggerServerCallback('esx_ambulancejob:storeNearbyVehicle', function(storeSuccess, foundNum) - if storeSuccess then - local vehicleId = vehiclePlates[foundNum] - local attempts = 0 - ESX.Game.DeleteVehicle(vehicleId.vehicle) - isBusy = true - - Citizen.CreateThread(function() - while isBusy do - Citizen.Wait(0) - drawLoadingText(_U('garage_storing'), 255, 255, 255, 255) - end - end) - - -- Workaround for vehicle not deleting when other players are near it. - while DoesEntityExist(vehicleId.vehicle) do - Citizen.Wait(500) - attempts = attempts + 1 - - -- Give up - if attempts > 30 then - break - end - - 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) - break - end - end - end - end - - isBusy = false - ESX.ShowNotification(_U('garage_has_stored')) - else - ESX.ShowNotification(_U('garage_has_notstored')) - end - end, vehiclePlates) -end - -function GetAvailableVehicleSpawnPoint(hospital, part, partNum) - local spawnPoints = Config.Hospitals[hospital][part][partNum].SpawnPoints - local found, foundSpawnPoint = false, nil - - for i=1, #spawnPoints, 1 do - if ESX.Game.IsSpawnPointClear(spawnPoints[i].coords, spawnPoints[i].radius) then - found, foundSpawnPoint = true, spawnPoints[i] - break - end - end - - if found then - return true, foundSpawnPoint - else - ESX.ShowNotification(_U('garage_blocked')) - return false - end -end - -function OpenHelicopterSpawnerMenu(hospital, partNum) - local playerCoords = GetEntityCoords(PlayerPedId()) - ESX.PlayerData = ESX.GetPlayerData() - - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'helicopter_spawner', { - title = _U('helicopter_title'), - align = 'top-left', - elements = { - {label = _U('helicopter_garage'), action = 'garage'}, - {label = _U('helicopter_store'), action = 'store_garage'}, - {label = _U('helicopter_buy'), action = 'buy_helicopter'} - }}, function(data, menu) - if data.current.action == 'buy_helicopter' then - local shopCoords = Config.Hospitals[hospital].Helicopters[partNum].InsideShop - local shopElements = {} - local authorizedHelicopters = Config.AuthorizedHelicopters[ESX.PlayerData.job.grade_name] - - if #authorizedHelicopters > 0 then - for k,helicopter in ipairs(authorizedHelicopters) do - table.insert(shopElements, { - label = ('%s - %s'):format(helicopter.label, _U('shop_item', ESX.Math.GroupDigits(helicopter.price))), - name = helicopter.label, - model = helicopter.model, - price = helicopter.price, - type = 'helicopter' - }) - end - else - ESX.ShowNotification(_U('helicopter_notauthorized')) - return - end - - OpenShopMenu(shopElements, playerCoords, shopCoords) - elseif data.current.action == 'garage' then - local garage = {} - - ESX.TriggerServerCallback('esx_vehicleshop:retrieveJobVehicles', function(jobVehicles) - if #jobVehicles > 0 then - for k,v in ipairs(jobVehicles) do - local props = json.decode(v.vehicle) - local vehicleName = GetLabelText(GetDisplayNameFromVehicleModel(props.model)) - local label = ('%s - %s: '):format(vehicleName, props.plate) - - if v.stored then - label = label .. ('%s'):format(_U('garage_stored')) - else - label = label .. ('%s'):format(_U('garage_notstored')) - end - - table.insert(garage, { - label = label, - stored = v.stored, - model = props.model, - vehicleProps = props - }) - end - - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'helicopter_garage', { - title = _U('helicopter_garage_title'), - align = 'top-left', - elements = garage - }, function(data2, menu2) - if data2.current.stored then - local foundSpawn, spawnPoint = GetAvailableVehicleSpawnPoint(hospital, 'Helicopters', partNum) - - if foundSpawn then - menu2.close() - - ESX.Game.SpawnVehicle(data2.current.model, spawnPoint.coords, spawnPoint.heading, function(vehicle) - ESX.Game.SetVehicleProperties(vehicle, data2.current.vehicleProps) - - TriggerServerEvent('esx_vehicleshop:setJobVehicleState', data2.current.vehicleProps.plate, false) - ESX.ShowNotification(_U('garage_released')) - end) - end - else - ESX.ShowNotification(_U('garage_notavailable')) - end - end, function(data2, menu2) - menu2.close() - end) - else - ESX.ShowNotification(_U('garage_empty')) - end - end, 'helicopter') - elseif data.current.action == 'store_garage' then - StoreNearbyVehicle(playerCoords) - end - end, function(data, menu) - menu.close() - end) -end - -function OpenShopMenu(elements, restoreCoords, shopCoords) - local playerPed = PlayerPedId() - isInShopMenu = true - - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop', { - title = _U('vehicleshop_title'), - align = 'top-left', - elements = elements - }, function(data, menu) - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop_confirm', { - title = _U('vehicleshop_confirm', data.current.name, data.current.price), - align = 'top-left', - elements = { - {label = _U('confirm_no'), value = 'no'}, - {label = _U('confirm_yes'), value = 'yes'} - }}, function(data2, menu2) - if data2.current.value == 'yes' then - local newPlate = exports['esx_vehicleshop']:GeneratePlate() - local vehicle = GetVehiclePedIsIn(playerPed, false) - local props = ESX.Game.GetVehicleProperties(vehicle) - props.plate = newPlate - - ESX.TriggerServerCallback('esx_ambulancejob:buyJobVehicle', function (bought) - if bought then - ESX.ShowNotification(_U('vehicleshop_bought', data.current.name, ESX.Math.GroupDigits(data.current.price))) - - isInShopMenu = false - ESX.UI.Menu.CloseAll() - - DeleteSpawnedVehicles() - FreezeEntityPosition(playerPed, false) - SetEntityVisible(playerPed, true) - - ESX.Game.Teleport(playerPed, restoreCoords) - else - ESX.ShowNotification(_U('vehicleshop_money')) - menu2.close() - end - end, props, data.current.type) - else - menu2.close() - end - - end, function(data2, menu2) - menu2.close() - end) - - end, function(data, menu) - isInShopMenu = false - ESX.UI.Menu.CloseAll() - - DeleteSpawnedVehicles() - FreezeEntityPosition(playerPed, false) - SetEntityVisible(playerPed, true) - - ESX.Game.Teleport(playerPed, restoreCoords) - end, function(data, menu) - DeleteSpawnedVehicles() - WaitForVehicleToLoad(data.current.model) - - ESX.Game.SpawnLocalVehicle(data.current.model, shopCoords, 0.0, function(vehicle) - table.insert(spawnedVehicles, vehicle) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - FreezeEntityPosition(vehicle, true) - SetModelAsNoLongerNeeded(data.current.model) - end) - end) - - WaitForVehicleToLoad(elements[1].model) - ESX.Game.SpawnLocalVehicle(elements[1].model, shopCoords, 0.0, function(vehicle) - table.insert(spawnedVehicles, vehicle) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - FreezeEntityPosition(vehicle, true) - SetModelAsNoLongerNeeded(elements[1].model) - end) -end - -Citizen.CreateThread(function() - while true do - Citizen.Wait(0) - - if isInShopMenu then - DisableControlAction(0, 75, true) -- Disable exit vehicle - DisableControlAction(27, 75, true) -- Disable exit vehicle - else - Citizen.Wait(500) - end - end -end) - -function DeleteSpawnedVehicles() - while #spawnedVehicles > 0 do - local vehicle = spawnedVehicles[1] - ESX.Game.DeleteVehicle(vehicle) - table.remove(spawnedVehicles, 1) - end -end - -function WaitForVehicleToLoad(modelHash) - modelHash = (type(modelHash) == 'number' and modelHash or GetHashKey(modelHash)) - - if not HasModelLoaded(modelHash) then - RequestModel(modelHash) - - BeginTextCommandBusyspinnerOn('STRING') - AddTextComponentSubstringPlayerName(_U('vehicleshop_awaiting_model')) - EndTextCommandBusyspinnerOn(4) - - while not HasModelLoaded(modelHash) do - Citizen.Wait(0) - DisableAllControlActions(0) - end - - BusyspinnerOff() - end -end - function OpenPharmacyMenu() ESX.UI.Menu.CloseAll() diff --git a/client/vehicle.lua b/client/vehicle.lua new file mode 100644 index 00000000..39c5ce90 --- /dev/null +++ b/client/vehicle.lua @@ -0,0 +1,297 @@ +local spawnedVehicles = {} + +function OpenVehicleSpawnerMenu(type, hospital, part, partNum) + local playerCoords = GetEntityCoords(PlayerPedId()) + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle', { + title = _U('garage_title'), + align = 'top-left', + elements = { + {label = _U('garage_storeditem'), action = 'garage'}, + {label = _U('garage_storeitem'), action = 'store_garage'}, + {label = _U('garage_buyitem'), action = 'buy_vehicle'} + }}, function(data, menu) + if data.current.action == 'buy_vehicle' then + local shopElements = {} + local authorizedVehicles = Config.AuthorizedVehicles[type][ESX.PlayerData.job.grade_name] + local shopCoords = Config.Hospitals[hospital][part][partNum].InsideShop + + if #authorizedVehicles > 0 then + for k,vehicle in ipairs(authorizedVehicles) do + local vehicleLabel = GetLabelText(GetDisplayNameFromVehicleModel(vehicle.model)) + + table.insert(shopElements, { + label = ('%s - %s'):format(vehicleLabel, _U('shop_item', ESX.Math.GroupDigits(vehicle.price))), + name = vehicleLabel, + model = vehicle.model, + price = vehicle.price, + props = vehicle.props, + type = type + }) + end + + OpenShopMenu(shopElements, playerCoords, shopCoords) + end + elseif data.current.action == 'garage' then + local garage = {} + + ESX.TriggerServerCallback('esx_vehicleshop:retrieveJobVehicles', function(jobVehicles) + if #jobVehicles > 0 then + for k,v in ipairs(jobVehicles) do + local props = json.decode(v.vehicle) + local vehicleName = GetLabelText(GetDisplayNameFromVehicleModel(props.model)) + local label = ('%s - %s: '):format(vehicleName, props.plate) + + if v.stored then + label = label .. ('%s'):format(_U('garage_stored')) + else + label = label .. ('%s'):format(_U('garage_notstored')) + end + + table.insert(garage, { + label = label, + stored = v.stored, + model = props.model, + vehicleProps = props + }) + end + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_garage', { + title = _U('garage_title'), + align = 'top-left', + elements = garage + }, function(data2, menu2) + if data2.current.stored then + local foundSpawn, spawnPoint = GetAvailableVehicleSpawnPoint(hospital, part, partNum) + + if foundSpawn then + menu2.close() + + ESX.Game.SpawnVehicle(data2.current.model, spawnPoint.coords, spawnPoint.heading, function(vehicle) + ESX.Game.SetVehicleProperties(vehicle, data2.current.vehicleProps) + + TriggerServerEvent('esx_vehicleshop:setJobVehicleState', data2.current.vehicleProps.plate, false) + ESX.ShowNotification(_U('garage_released')) + end) + end + else + ESX.ShowNotification(_U('garage_notavailable')) + end + end, function(data2, menu2) + menu2.close() + end) + else + ESX.ShowNotification(_U('garage_empty')) + end + end, type) + elseif data.current.action == 'store_garage' then + StoreNearbyVehicle(playerCoords) + end + end, function(data, menu) + menu.close() + end) +end + +function StoreNearbyVehicle(playerCoords) + local vehicles, vehiclePlates = ESX.Game.GetVehiclesInArea(playerCoords, 30.0), {} + + if #vehicles > 0 then + for k,v in ipairs(vehicles) do + + -- 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)) + }) + end + end + else + ESX.ShowNotification(_U('garage_store_nearby')) + return + end + + ESX.TriggerServerCallback('esx_ambulancejob:storeNearbyVehicle', function(storeSuccess, foundNum) + if storeSuccess then + local vehicleId = vehiclePlates[foundNum] + local attempts = 0 + ESX.Game.DeleteVehicle(vehicleId.vehicle) + isBusy = true + + Citizen.CreateThread(function() + while isBusy do + Citizen.Wait(0) + drawLoadingText(_U('garage_storing'), 255, 255, 255, 255) + end + end) + + -- Workaround for vehicle not deleting when other players are near it. + while DoesEntityExist(vehicleId.vehicle) do + Citizen.Wait(500) + attempts = attempts + 1 + + -- Give up + if attempts > 30 then + break + end + + 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) + break + end + end + end + end + + isBusy = false + ESX.ShowNotification(_U('garage_has_stored')) + else + ESX.ShowNotification(_U('garage_has_notstored')) + end + end, vehiclePlates) +end + +function GetAvailableVehicleSpawnPoint(hospital, part, partNum) + local spawnPoints = Config.Hospitals[hospital][part][partNum].SpawnPoints + local found, foundSpawnPoint = false, nil + + for i=1, #spawnPoints, 1 do + if ESX.Game.IsSpawnPointClear(spawnPoints[i].coords, spawnPoints[i].radius) then + found, foundSpawnPoint = true, spawnPoints[i] + break + end + end + + if found then + return true, foundSpawnPoint + else + ESX.ShowNotification(_U('garage_blocked')) + return false + end +end + +function OpenShopMenu(elements, restoreCoords, shopCoords) + local playerPed = PlayerPedId() + isInShopMenu = true + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop', { + title = _U('vehicleshop_title'), + align = 'top-left', + elements = elements + }, function(data, menu) + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop_confirm', { + title = _U('vehicleshop_confirm', data.current.name, data.current.price), + align = 'top-left', + elements = { + {label = _U('confirm_no'), value = 'no'}, + {label = _U('confirm_yes'), value = 'yes'} + }}, function(data2, menu2) + if data2.current.value == 'yes' then + local newPlate = exports['esx_vehicleshop']:GeneratePlate() + local vehicle = GetVehiclePedIsIn(playerPed, false) + local props = ESX.Game.GetVehicleProperties(vehicle) + props.plate = newPlate + + ESX.TriggerServerCallback('esx_ambulancejob:buyJobVehicle', function(bought) + if bought then + ESX.ShowNotification(_U('vehicleshop_bought', data.current.name, ESX.Math.GroupDigits(data.current.price))) + + isInShopMenu = false + ESX.UI.Menu.CloseAll() + + DeleteSpawnedVehicles() + FreezeEntityPosition(playerPed, false) + SetEntityVisible(playerPed, true) + + ESX.Game.Teleport(playerPed, restoreCoords) + else + ESX.ShowNotification(_U('vehicleshop_money')) + menu2.close() + end + end, props, data.current.type) + else + menu2.close() + end + end, function(data2, menu2) + menu2.close() + end) + end, function(data, menu) + isInShopMenu = false + ESX.UI.Menu.CloseAll() + + DeleteSpawnedVehicles() + FreezeEntityPosition(playerPed, false) + SetEntityVisible(playerPed, true) + + ESX.Game.Teleport(playerPed, restoreCoords) + end, function(data, menu) + DeleteSpawnedVehicles() + WaitForVehicleToLoad(data.current.model) + + ESX.Game.SpawnLocalVehicle(data.current.model, shopCoords, 0.0, function(vehicle) + table.insert(spawnedVehicles, vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + FreezeEntityPosition(vehicle, true) + SetModelAsNoLongerNeeded(data.current.model) + + if data.current.props then + ESX.Game.SetVehicleProperties(vehicle, data.current.props) + end + end) + end) + + WaitForVehicleToLoad(elements[1].model) + ESX.Game.SpawnLocalVehicle(elements[1].model, shopCoords, 0.0, function(vehicle) + table.insert(spawnedVehicles, vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + FreezeEntityPosition(vehicle, true) + SetModelAsNoLongerNeeded(elements[1].model) + + if elements[1].props then + ESX.Game.SetVehicleProperties(vehicle, elements[1].props) + end + end) +end + +Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + + if isInShopMenu then + DisableControlAction(0, 75, true) -- Disable exit vehicle + DisableControlAction(27, 75, true) -- Disable exit vehicle + else + Citizen.Wait(500) + end + end +end) + +function DeleteSpawnedVehicles() + while #spawnedVehicles > 0 do + local vehicle = spawnedVehicles[1] + ESX.Game.DeleteVehicle(vehicle) + table.remove(spawnedVehicles, 1) + end +end + +function WaitForVehicleToLoad(modelHash) + modelHash = (type(modelHash) == 'number' and modelHash or GetHashKey(modelHash)) + + if not HasModelLoaded(modelHash) then + RequestModel(modelHash) + + BeginTextCommandBusyspinnerOn('STRING') + AddTextComponentSubstringPlayerName(_U('vehicleshop_awaiting_model')) + EndTextCommandBusyspinnerOn(4) + + while not HasModelLoaded(modelHash) do + Citizen.Wait(0) + DisableAllControlActions(0) + end + + BusyspinnerOff() + end +end diff --git a/config.lua b/config.lua index 20e848f9..7bb21f18 100644 --- a/config.lua +++ b/config.lua @@ -127,37 +127,39 @@ Config.Hospitals = { } Config.AuthorizedVehicles = { - ambulance = { - {model = 'ambulance', label = 'Ambulance Van', price = 5000} + car = { + ambulance = { + {model = 'ambulance', price = 5000} + }, + + doctor = { + {model = 'ambulance', price = 4500} + }, + + chief_doctor = { + {model = 'ambulance', price = 3000} + }, + + boss = { + {model = 'ambulance', price = 2000} + } }, - doctor = { - {model = 'ambulance', label = 'Ambulance Van', price = 4500} - }, + helicopter = { + ambulance = {}, - chief_doctor = { - {model = 'ambulance', label = 'Ambulance Van', price = 3000} - }, + doctor = { + {model = 'buzzard2', price = 150000} + }, - boss = { - {model = 'ambulance', label = 'Ambulance Van', price = 2000} - } -} - -Config.AuthorizedHelicopters = { - ambulance = {}, - - doctor = { - {model = 'buzzard2', label = 'Nagasaki Buzzard', price = 150000} - }, - - chief_doctor = { - {model = 'buzzard2', label = 'Nagasaki Buzzard', price = 150000}, - {model = 'seasparrow', label = 'Sea Sparrow', price = 300000} - }, - - boss = { - {model = 'buzzard2', label = 'Nagasaki Buzzard', price = 10000}, - {model = 'seasparrow', label = 'Sea Sparrow', price = 250000} + chief_doctor = { + {model = 'buzzard2', price = 150000}, + {model = 'seasparrow', price = 300000} + }, + + boss = { + {model = 'buzzard2', price = 10000}, + {model = 'seasparrow', price = 250000} + } } } diff --git a/fxmanifest.lua b/fxmanifest.lua index 7acca84c..ba925897 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -33,7 +33,8 @@ client_scripts { 'locales/cs.lua', 'config.lua', 'client/main.lua', - 'client/job.lua' + 'client/job.lua', + 'client/vehicle.lua', } dependencies { diff --git a/locales/br.lua b/locales/br.lua index 4d88eed3..9e3147d0 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -6,12 +6,6 @@ Locales['br'] = { -- Vehicles ['ambulance'] = 'ambulancia', ['helicopter_prompt'] = 'pressione ~INPUT_CONTEXT~ para acessar a ~y~Helicopter Actions~s~.', - ['helicopter_buy'] = 'loja de helicóptero', - ['helicopter_garage'] = 'garagem aberta', - ['helicopter_store'] = 'helicóptero da loja entregue na garagem', - ['helicopter_garage_title'] = 'garagem de helicóptero', - ['helicopter_title'] = 'ações do helicóptero', - ['helicopter_notauthorized'] = 'você não está autorizado a comprar helicópteros.', ['garage_prompt'] = 'pressione ~INPUT_CONTEXT~ para entra no ~y~Vehicle Actions~s~.', ['garage_title'] = 'ações do veiculo', ['garage_stored'] = 'guardado', @@ -30,7 +24,7 @@ Locales['br'] = { ['shop_item'] = '$%s', ['vehicleshop_title'] = 'loja de veículos', ['vehicleshop_confirm'] = 'você quer comprar este veículo?', - ['vehicleshop_bought'] = 'você comprou ~y~%s~s~ para ~r~$%s~s~', + ['vehicleshop_bought'] = 'você comprou ~y~%s~s~ para ~g~$%s~s~', ['vehicleshop_money'] = 'você não pode pagar esse veículo', ['vehicleshop_awaiting_model'] = 'o veículo está atualmente ~g~DOWNLOADING & LOADING~s~, por favor aguarde', ['confirm_no'] = 'não', diff --git a/locales/cs.lua b/locales/cs.lua index 5e3690d7..37d65c5a 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -6,12 +6,6 @@ Locales['cs'] = { -- Vehicles ['ambulance'] = 'ambulance', ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', - ['helicopter_buy'] = 'helicopter shop', - ['helicopter_garage'] = 'open garage', - ['helicopter_store'] = 'store helicopter in garage', - ['helicopter_garage_title'] = 'helicopter Garage', - ['helicopter_title'] = 'helicopter Actions', - ['helicopter_notauthorized'] = 'you\'re not authorized to buy helicopters.', ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.', ['garage_title'] = 'vehicle Actions', ['garage_stored'] = 'stored', @@ -30,7 +24,7 @@ Locales['cs'] = { ['shop_item'] = '$%s', ['vehicleshop_title'] = 'vehicle Shop', ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', - ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~', + ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~g~$%s~s~', ['vehicleshop_money'] = 'you cannot afford that vehicle', ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', ['confirm_no'] = 'no', diff --git a/locales/en.lua b/locales/en.lua index 14111578..5b5f6d24 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -6,12 +6,6 @@ Locales['en'] = { -- Vehicles ['ambulance'] = 'ambulance', ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', - ['helicopter_buy'] = 'helicopter shop', - ['helicopter_garage'] = 'open garage', - ['helicopter_store'] = 'store helicopter in garage', - ['helicopter_garage_title'] = 'helicopter Garage', - ['helicopter_title'] = 'helicopter Actions', - ['helicopter_notauthorized'] = 'you\'re not authorized to buy helicopters.', ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.', ['garage_title'] = 'vehicle Actions', ['garage_stored'] = 'stored', @@ -30,7 +24,7 @@ Locales['en'] = { ['shop_item'] = '$%s', ['vehicleshop_title'] = 'vehicle Shop', ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', - ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~', + ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~g~$%s~s~', ['vehicleshop_money'] = 'you cannot afford that vehicle', ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', ['confirm_no'] = 'no', diff --git a/locales/es.lua b/locales/es.lua index 656a4d53..e231db54 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -6,12 +6,6 @@ Locales['es'] = { -- Vehicles ['ambulance'] = 'ambulance', ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', - ['helicopter_buy'] = 'helicopter shop', - ['helicopter_garage'] = 'open garage', - ['helicopter_store'] = 'store helicopter in garage', - ['helicopter_garage_title'] = 'helicopter Garage', - ['helicopter_title'] = 'helicopter Actions', - ['helicopter_notauthorized'] = 'you\'re not authorized to buy helicopters.', ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.', ['garage_title'] = 'vehicle Actions', ['garage_stored'] = 'stored', @@ -30,7 +24,7 @@ Locales['es'] = { ['shop_item'] = '$%s', ['vehicleshop_title'] = 'vehicle Shop', ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', - ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~', + ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~g~$%s~s~', ['vehicleshop_money'] = 'you cannot afford that vehicle', ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', ['confirm_no'] = 'no', diff --git a/locales/fi.lua b/locales/fi.lua index d98cf398..9ef6caf8 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -6,12 +6,6 @@ Locales['fi'] = { -- Vehicles ['ambulance'] = 'ambulance', ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', - ['helicopter_buy'] = 'helicopter shop', - ['helicopter_garage'] = 'open garage', - ['helicopter_store'] = 'store helicopter in garage', - ['helicopter_garage_title'] = 'helicopter Garage', - ['helicopter_title'] = 'helicopter Actions', - ['helicopter_notauthorized'] = 'you\'re not authorized to buy helicopters.', ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.', ['garage_title'] = 'vehicle Actions', ['garage_stored'] = 'stored', @@ -30,7 +24,7 @@ Locales['fi'] = { ['shop_item'] = '$%s', ['vehicleshop_title'] = 'vehicle Shop', ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', - ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~', + ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~g~$%s~s~', ['vehicleshop_money'] = 'you cannot afford that vehicle', ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', ['confirm_no'] = 'no', diff --git a/locales/fr.lua b/locales/fr.lua index 51d558ff..fb750289 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -6,12 +6,6 @@ Locales['fr'] = { -- Vehicles ['ambulance'] = 'ambulance', ['helicopter_prompt'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder aux ~y~Actions de l\'hélicoptère~s~.', - ['helicopter_buy'] = 'magasin hélicoptère', - ['helicopter_garage'] = 'ouvrir le garage', - ['helicopter_store'] = 'garer l\'hélicoptère dans le garage', - ['helicopter_garage_title'] = 'garage hélicoptère', - ['helicopter_title'] = 'actions hélicoptère', - ['helicopter_notauthorized'] = 'vous n\'êtes pas autorisé à acheter un hélicoptère.', ['garage_prompt'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder aux ~y~Actions des véhciules~s~.', ['garage_title'] = 'actions véhicules', ['garage_stored'] = 'rangé', @@ -30,7 +24,7 @@ Locales['fr'] = { ['shop_item'] = '$%s', ['vehicleshop_title'] = 'magasin véhicule', ['vehicleshop_confirm'] = 'voulez-vous acheter ce véhicule?', - ['vehicleshop_bought'] = 'vous avez acheté ~y~%s~s~ pour ~r~$%s~s~', + ['vehicleshop_bought'] = 'vous avez acheté ~y~%s~s~ pour ~g~$%s~s~', ['vehicleshop_money'] = 'vous ne pouvez pas acheter ce véhicule', ['vehicleshop_awaiting_model'] = 'le véhicule est actuellement en ~g~PRÉPARATION~s~ veuillez patienter', ['confirm_no'] = 'non', diff --git a/locales/pl.lua b/locales/pl.lua index 007c8383..ebf082c1 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -6,12 +6,6 @@ Locales['pl'] = { -- Vehicles ['ambulance'] = 'ambulance', ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', - ['helicopter_buy'] = 'helicopter shop', - ['helicopter_garage'] = 'open garage', - ['helicopter_store'] = 'store helicopter in garage', - ['helicopter_garage_title'] = 'helicopter Garage', - ['helicopter_title'] = 'helicopter Actions', - ['helicopter_notauthorized'] = 'you\'re not authorized to buy helicopters.', ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.', ['garage_title'] = 'vehicle Actions', ['garage_stored'] = 'stored', @@ -30,7 +24,7 @@ Locales['pl'] = { ['shop_item'] = '$%s', ['vehicleshop_title'] = 'vehicle Shop', ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', - ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~', + ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~g~$%s~s~', ['vehicleshop_money'] = 'you cannot afford that vehicle', ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', ['confirm_no'] = 'no', diff --git a/locales/sv.lua b/locales/sv.lua index c7f55b6e..b0d736aa 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -5,13 +5,7 @@ Locales['sv'] = { ['ems_clothes_ems'] = 'ambulanskläder', -- Vehicles ['ambulance'] = 'ambulans', - ['helicopter_prompt'] = 'klicka på ~INPUT_CONTEXT~ för att komma åt ~y~garaget~s~.', - ['helicopter_buy'] = 'fordonshandel', - ['helicopter_garage'] = 'öppna garage', - ['helicopter_store'] = 'ställ in helikopter', - ['helicopter_garage_title'] = 'garage', - ['helicopter_title'] = 'garage', - ['helicopter_notauthorized'] = 'du har inte behörighet till att köpa en helikopter.', + ['helicopter_prompt'] = 'tryck ~INPUT_CONTEXT~ för att komma åt ~y~helikoptergaraget~s~.', ['garage_prompt'] = 'tryck ~INPUT_CONTEXT~ för att komma åt ~y~garaget~s~.', ['garage_title'] = 'garage', ['garage_stored'] = 'inställt', @@ -30,7 +24,7 @@ Locales['sv'] = { ['shop_item'] = '%s SEK', ['vehicleshop_title'] = 'fordonshandel', ['vehicleshop_confirm'] = 'vill du köpa detta fordon?', - ['vehicleshop_bought'] = 'du köpte ~y~%s~s~ för ~r~$%s~s~', + ['vehicleshop_bought'] = 'du köpte ~y~%s~s~ för ~g~%s SEK~s~', ['vehicleshop_money'] = 'du har inte råd med detta fordon', ['vehicleshop_awaiting_model'] = 'fordonet ~g~LADDAS NED OCH LADDAS IN~s~ var god vänta', ['confirm_no'] = 'nej', diff --git a/server/main.lua b/server/main.lua index 08eff022..4b24fb5e 100644 --- a/server/main.lua +++ b/server/main.lua @@ -207,22 +207,12 @@ ESX.RegisterServerCallback('esx_ambulancejob:storeNearbyVehicle', function(sourc end end) -function getPriceFromHash(hashKey, jobGrade, type) - if type == 'helicopter' then - local vehicles = Config.AuthorizedHelicopters[jobGrade] +function getPriceFromHash(vehicleHash, jobGrade, type) + local vehicles = Config.AuthorizedVehicles[type][jobGrade] - for k,v in ipairs(vehicles) do - if GetHashKey(v.model) == hashKey then - return v.price - end - end - elseif type == 'car' then - local vehicles = Config.AuthorizedVehicles[jobGrade] - - for k,v in ipairs(vehicles) do - if GetHashKey(v.model) == hashKey then - return v.price - end + for k,v in ipairs(vehicles) do + if GetHashKey(v.model) == vehicleHash then + return v.price end end From a606c2bdd27f047db2f7dc7da7dae08c419da7fb Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 24 Jan 2020 12:21:11 +0100 Subject: [PATCH 2497/3224] Fixed NUI limit with too many vehicles in garage --- client/vehicle.lua | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/client/vehicle.lua b/client/vehicle.lua index 39c5ce90..77e14355 100644 --- a/client/vehicle.lua +++ b/client/vehicle.lua @@ -37,6 +37,8 @@ function OpenVehicleSpawnerMenu(type, hospital, part, partNum) ESX.TriggerServerCallback('esx_vehicleshop:retrieveJobVehicles', function(jobVehicles) if #jobVehicles > 0 then + local allVehicleProps = {} + for k,v in ipairs(jobVehicles) do local props = json.decode(v.vehicle) local vehicleName = GetLabelText(GetDisplayNameFromVehicleModel(props.model)) @@ -52,8 +54,10 @@ function OpenVehicleSpawnerMenu(type, hospital, part, partNum) label = label, stored = v.stored, model = props.model, - vehicleProps = props + plate = props.plate }) + + allVehicleProps[props.plate] = props end ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_garage', { @@ -68,9 +72,10 @@ function OpenVehicleSpawnerMenu(type, hospital, part, partNum) menu2.close() ESX.Game.SpawnVehicle(data2.current.model, spawnPoint.coords, spawnPoint.heading, function(vehicle) - ESX.Game.SetVehicleProperties(vehicle, data2.current.vehicleProps) + local vehicleProps = allVehicleProps[data2.current.plate] + ESX.Game.SetVehicleProperties(vehicle, vehicleProps) - TriggerServerEvent('esx_vehicleshop:setJobVehicleState', data2.current.vehicleProps.plate, false) + TriggerServerEvent('esx_vehicleshop:setJobVehicleState', data2.current.plate, false) ESX.ShowNotification(_U('garage_released')) end) end From bfb15244d0a8b338e88861fd1afbae446c9585d9 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 24 Jan 2020 12:29:14 +0100 Subject: [PATCH 2498/3224] Added IsModelInCdimage() check to garage --- client/vehicle.lua | 103 +++++++++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 46 deletions(-) diff --git a/client/vehicle.lua b/client/vehicle.lua index 77e14355..a14a6b33 100644 --- a/client/vehicle.lua +++ b/client/vehicle.lua @@ -18,19 +18,23 @@ function OpenVehicleSpawnerMenu(type, hospital, part, partNum) if #authorizedVehicles > 0 then for k,vehicle in ipairs(authorizedVehicles) do - local vehicleLabel = GetLabelText(GetDisplayNameFromVehicleModel(vehicle.model)) + if IsModelInCdimage(vehicle.model) then + local vehicleLabel = GetLabelText(GetDisplayNameFromVehicleModel(vehicle.model)) - table.insert(shopElements, { - label = ('%s - %s'):format(vehicleLabel, _U('shop_item', ESX.Math.GroupDigits(vehicle.price))), - name = vehicleLabel, - model = vehicle.model, - price = vehicle.price, - props = vehicle.props, - type = type - }) + table.insert(shopElements, { + label = ('%s - %s'):format(vehicleLabel, _U('shop_item', ESX.Math.GroupDigits(vehicle.price))), + name = vehicleLabel, + model = vehicle.model, + price = vehicle.price, + props = vehicle.props, + type = type + }) + end end - OpenShopMenu(shopElements, playerCoords, shopCoords) + if #shopElements > 0 then + OpenShopMenu(shopElements, playerCoords, shopCoords) + end end elseif data.current.action == 'garage' then local garage = {} @@ -41,50 +45,57 @@ function OpenVehicleSpawnerMenu(type, hospital, part, partNum) for k,v in ipairs(jobVehicles) do local props = json.decode(v.vehicle) - local vehicleName = GetLabelText(GetDisplayNameFromVehicleModel(props.model)) - local label = ('%s - %s: '):format(vehicleName, props.plate) - if v.stored then - label = label .. ('%s'):format(_U('garage_stored')) - else - label = label .. ('%s'):format(_U('garage_notstored')) + if IsModelInCdimage(props.model) then + local vehicleName = GetLabelText(GetDisplayNameFromVehicleModel(props.model)) + local label = ('%s - %s: '):format(vehicleName, props.plate) + + if v.stored then + label = label .. ('%s'):format(_U('garage_stored')) + else + label = label .. ('%s'):format(_U('garage_notstored')) + end + + table.insert(garage, { + label = label, + stored = v.stored, + model = props.model, + plate = props.plate + }) + + allVehicleProps[props.plate] = props end - - table.insert(garage, { - label = label, - stored = v.stored, - model = props.model, - plate = props.plate - }) - - allVehicleProps[props.plate] = props end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_garage', { - title = _U('garage_title'), - align = 'top-left', - elements = garage - }, function(data2, menu2) - if data2.current.stored then - local foundSpawn, spawnPoint = GetAvailableVehicleSpawnPoint(hospital, part, partNum) + if #garage > 0 then + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_garage', { + title = _U('garage_title'), + align = 'top-left', + elements = garage + }, function(data2, menu2) + if data2.current.stored then + local foundSpawn, spawnPoint = GetAvailableVehicleSpawnPoint(hospital, part, partNum) - if foundSpawn then - menu2.close() + if foundSpawn then + menu2.close() - ESX.Game.SpawnVehicle(data2.current.model, spawnPoint.coords, spawnPoint.heading, function(vehicle) - local vehicleProps = allVehicleProps[data2.current.plate] - ESX.Game.SetVehicleProperties(vehicle, vehicleProps) + ESX.Game.SpawnVehicle(data2.current.model, spawnPoint.coords, spawnPoint.heading, function(vehicle) + local vehicleProps = allVehicleProps[data2.current.plate] + ESX.Game.SetVehicleProperties(vehicle, vehicleProps) - TriggerServerEvent('esx_vehicleshop:setJobVehicleState', data2.current.plate, false) - ESX.ShowNotification(_U('garage_released')) - end) + TriggerServerEvent('esx_vehicleshop:setJobVehicleState', data2.current.plate, false) + ESX.ShowNotification(_U('garage_released')) + end) + end + else + ESX.ShowNotification(_U('garage_notavailable')) end - else - ESX.ShowNotification(_U('garage_notavailable')) - end - end, function(data2, menu2) - menu2.close() - end) + end, function(data2, menu2) + menu2.close() + end) + else + ESX.ShowNotification(_U('garage_empty')) + end else ESX.ShowNotification(_U('garage_empty')) end From 355c04bebbffffc848ae7e9da76ca35d182f6196 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 24 Jan 2020 13:25:10 +0100 Subject: [PATCH 2499/3224] Move vehicle garage to seperate file, see desc for full change --- client/main.lua | 367 ++------------------------------------------- client/vehicle.lua | 322 +++++++++++++++++++++++++++++++++++++++ config.lua | 84 +++++------ fxmanifest.lua | 3 +- locales/br.lua | 4 +- locales/de.lua | 4 +- locales/en.lua | 4 +- locales/es.lua | 4 +- locales/fi.lua | 4 +- locales/fr.lua | 4 +- locales/ko.lua | 4 +- locales/pl.lua | 4 +- locales/sv.lua | 8 +- server/main.lua | 27 +--- 14 files changed, 398 insertions(+), 445 deletions(-) create mode 100644 client/vehicle.lua diff --git a/client/main.lua b/client/main.lua index d5ef5c40..e2d024f5 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,7 +1,6 @@ -local PlayerData, CurrentActionData, handcuffTimer, dragStatus, blipsCops, currentTask, spawnedVehicles = {}, {}, {}, {}, {}, {}, {} -local HasAlreadyEnteredMarker, isDead, isHandcuffed, hasAlreadyJoined, playerInService, isInShopMenu = false, false, false, false, false, false +local CurrentActionData, handcuffTimer, dragStatus, blipsCops, currentTask = {}, {}, {}, {}, {} local LastStation, LastPart, LastPartNum, LastEntity, CurrentAction, CurrentActionMsg -dragStatus.isDragged = false +dragStatus.isDragged, isInShopMenu = false, false ESX = nil Citizen.CreateThread(function() @@ -14,7 +13,7 @@ Citizen.CreateThread(function() Citizen.Wait(10) end - PlayerData = ESX.GetPlayerData() + ESX.PlayerData = ESX.GetPlayerData() end) function cleanPlayer(playerPed) @@ -49,7 +48,7 @@ end function OpenCloakroomMenu() local playerPed = PlayerPedId() - local grade = PlayerData.job.grade_name + local grade = ESX.PlayerData.job.grade_name local elements = { {label = _U('citizen_wear'), value = 'citizen_wear'}, @@ -230,346 +229,6 @@ function OpenArmoryMenu(station) end) end -function OpenVehicleSpawnerMenu(type, station, part, partNum) - local playerCoords = GetEntityCoords(PlayerPedId()) - PlayerData = ESX.GetPlayerData() - local elements = { - {label = _U('garage_storeditem'), action = 'garage'}, - {label = _U('garage_storeitem'), action = 'store_garage'}, - {label = _U('garage_buyitem'), action = 'buy_vehicle'} - } - - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle', { - title = _U('garage_title'), - align = 'top-left', - elements = elements - }, function(data, menu) - if data.current.action == 'buy_vehicle' then - local shopElements, shopCoords = {} - - if type == 'car' then - shopCoords = Config.PoliceStations[station].Vehicles[partNum].InsideShop - local authorizedVehicles = Config.AuthorizedVehicles[PlayerData.job.grade_name] - - if #Config.AuthorizedVehicles.Shared > 0 then - for k,vehicle in ipairs(Config.AuthorizedVehicles.Shared) do - table.insert(shopElements, { - label = ('%s - %s'):format(vehicle.label, _U('shop_item', ESX.Math.GroupDigits(vehicle.price))), - name = vehicle.label, - model = vehicle.model, - price = vehicle.price, - type = 'car' - }) - end - end - - if #authorizedVehicles > 0 then - for k,vehicle in ipairs(authorizedVehicles) do - table.insert(shopElements, { - label = ('%s - %s'):format(vehicle.label, _U('shop_item', ESX.Math.GroupDigits(vehicle.price))), - name = vehicle.label, - model = vehicle.model, - price = vehicle.price, - type = 'car' - }) - end - else - if #Config.AuthorizedVehicles.Shared == 0 then - return - end - end - elseif type == 'helicopter' then - shopCoords = Config.PoliceStations[station].Helicopters[partNum].InsideShop - local authorizedHelicopters = Config.AuthorizedHelicopters[PlayerData.job.grade_name] - - if #authorizedHelicopters > 0 then - for k,vehicle in ipairs(authorizedHelicopters) do - table.insert(shopElements, { - label = ('%s - %s'):format(vehicle.label, _U('shop_item', ESX.Math.GroupDigits(vehicle.price))), - name = vehicle.label, - model = vehicle.model, - price = vehicle.price, - livery = vehicle.livery or nil, - type = 'helicopter' - }) - end - else - ESX.ShowNotification(_U('helicopter_notauthorized')) - return - end - end - - OpenShopMenu(shopElements, playerCoords, shopCoords) - elseif data.current.action == 'garage' then - local garage = {} - - ESX.TriggerServerCallback('esx_vehicleshop:retrieveJobVehicles', function(jobVehicles) - if #jobVehicles > 0 then - for k,v in ipairs(jobVehicles) do - local props = json.decode(v.vehicle) - local vehicleName = GetLabelText(GetDisplayNameFromVehicleModel(props.model)) - local label = ('%s - %s: '):format(vehicleName, props.plate) - - if v.stored then - label = label .. ('%s'):format(_U('garage_stored')) - else - label = label .. ('%s'):format(_U('garage_notstored')) - end - - table.insert(garage, { - label = label, - stored = v.stored, - model = props.model, - vehicleProps = props - }) - end - - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_garage', { - title = _U('garage_title'), - align = 'top-left', - elements = garage - }, function(data2, menu2) - if data2.current.stored then - local foundSpawn, spawnPoint = GetAvailableVehicleSpawnPoint(station, part, partNum) - - if foundSpawn then - menu2.close() - - ESX.Game.SpawnVehicle(data2.current.model, spawnPoint.coords, spawnPoint.heading, function(vehicle) - ESX.Game.SetVehicleProperties(vehicle, data2.current.vehicleProps) - - TriggerServerEvent('esx_vehicleshop:setJobVehicleState', data2.current.vehicleProps.plate, false) - ESX.ShowNotification(_U('garage_released')) - end) - end - else - ESX.ShowNotification(_U('garage_notavailable')) - end - end, function(data2, menu2) - menu2.close() - end) - else - ESX.ShowNotification(_U('garage_empty')) - end - end, type) - elseif data.current.action == 'store_garage' then - StoreNearbyVehicle(playerCoords) - end - end, function(data, menu) - menu.close() - end) -end - -function StoreNearbyVehicle(playerCoords) - local vehicles, vehiclePlates = ESX.Game.GetVehiclesInArea(playerCoords, 30.0), {} - - if #vehicles > 0 then - for k,v in ipairs(vehicles) do - - -- 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)) - }) - end - end - else - ESX.ShowNotification(_U('garage_store_nearby')) - return - end - - ESX.TriggerServerCallback('esx_policejob:storeNearbyVehicle', function(storeSuccess, foundNum) - if storeSuccess then - local vehicleId = vehiclePlates[foundNum] - local attempts = 0 - ESX.Game.DeleteVehicle(vehicleId.vehicle) - IsBusy = true - - Citizen.CreateThread(function() - BeginTextCommandBusyspinnerOn('STRING') - AddTextComponentSubstringPlayerName(_U('garage_storing')) - EndTextCommandBusyspinnerOn(4) - - while IsBusy do - Citizen.Wait(100) - end - - BusyspinnerOff() - end) - - -- Workaround for vehicle not deleting when other players are near it. - while DoesEntityExist(vehicleId.vehicle) do - Citizen.Wait(500) - attempts = attempts + 1 - - -- Give up - if attempts > 30 then - break - end - - 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) - break - end - end - end - end - - IsBusy = false - ESX.ShowNotification(_U('garage_has_stored')) - else - ESX.ShowNotification(_U('garage_has_notstored')) - end - end, vehiclePlates) -end - -function GetAvailableVehicleSpawnPoint(station, part, partNum) - local spawnPoints = Config.PoliceStations[station][part][partNum].SpawnPoints - local found, foundSpawnPoint = false, nil - - for i=1, #spawnPoints, 1 do - if ESX.Game.IsSpawnPointClear(spawnPoints[i].coords, spawnPoints[i].radius) then - found, foundSpawnPoint = true, spawnPoints[i] - break - end - end - - if found then - return true, foundSpawnPoint - else - ESX.ShowNotification(_U('vehicle_blocked')) - return false - end -end - -function OpenShopMenu(elements, restoreCoords, shopCoords) - local playerPed = PlayerPedId() - isInShopMenu = true - - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop', { - title = _U('vehicleshop_title'), - align = 'top-left', - elements = elements - }, function(data, menu) - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop_confirm', { - title = _U('vehicleshop_confirm', data.current.name, data.current.price), - align = 'top-left', - elements = { - {label = _U('confirm_no'), value = 'no'}, - {label = _U('confirm_yes'), value = 'yes'} - }}, function(data2, menu2) - if data2.current.value == 'yes' then - local newPlate = exports['esx_vehicleshop']:GeneratePlate() - local vehicle = GetVehiclePedIsIn(playerPed, false) - local props = ESX.Game.GetVehicleProperties(vehicle) - props.plate = newPlate - - ESX.TriggerServerCallback('esx_policejob:buyJobVehicle', function (bought) - if bought then - ESX.ShowNotification(_U('vehicleshop_bought', data.current.name, ESX.Math.GroupDigits(data.current.price))) - - isInShopMenu = false - ESX.UI.Menu.CloseAll() - DeleteSpawnedVehicles() - FreezeEntityPosition(playerPed, false) - SetEntityVisible(playerPed, true) - - ESX.Game.Teleport(playerPed, restoreCoords) - else - ESX.ShowNotification(_U('vehicleshop_money')) - menu2.close() - end - end, props, data.current.type) - else - menu2.close() - end - end, function(data2, menu2) - menu2.close() - end) - end, function(data, menu) - isInShopMenu = false - ESX.UI.Menu.CloseAll() - - DeleteSpawnedVehicles() - FreezeEntityPosition(playerPed, false) - SetEntityVisible(playerPed, true) - - ESX.Game.Teleport(playerPed, restoreCoords) - end, function(data, menu) - DeleteSpawnedVehicles() - WaitForVehicleToLoad(data.current.model) - - ESX.Game.SpawnLocalVehicle(data.current.model, shopCoords, 0.0, function(vehicle) - table.insert(spawnedVehicles, vehicle) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - FreezeEntityPosition(vehicle, true) - SetModelAsNoLongerNeeded(data.current.model) - - if data.current.livery then - SetVehicleModKit(vehicle, 0) - SetVehicleLivery(vehicle, data.current.livery) - end - end) - end) - - WaitForVehicleToLoad(elements[1].model) - ESX.Game.SpawnLocalVehicle(elements[1].model, shopCoords, 0.0, function(vehicle) - table.insert(spawnedVehicles, vehicle) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - FreezeEntityPosition(vehicle, true) - SetModelAsNoLongerNeeded(elements[1].model) - - if elements[1].livery then - SetVehicleModKit(vehicle, 0) - SetVehicleLivery(vehicle, elements[1].livery) - end - end) -end - -Citizen.CreateThread(function() - while true do - Citizen.Wait(0) - - if isInShopMenu then - DisableControlAction(0, 75, true) -- Disable exit vehicle - DisableControlAction(27, 75, true) -- Disable exit vehicle - else - Citizen.Wait(500) - end - end -end) - -function DeleteSpawnedVehicles() - while #spawnedVehicles > 0 do - local vehicle = spawnedVehicles[1] - ESX.Game.DeleteVehicle(vehicle) - table.remove(spawnedVehicles, 1) - end -end - -function WaitForVehicleToLoad(modelHash) - modelHash = (type(modelHash) == 'number' and modelHash or GetHashKey(modelHash)) - - if not HasModelLoaded(modelHash) then - RequestModel(modelHash) - - BeginTextCommandBusyspinnerOn('STRING') - AddTextComponentSubstringPlayerName(_U('vehicleshop_awaiting_model')) - EndTextCommandBusyspinnerOn(4) - - while not HasModelLoaded(modelHash) do - Citizen.Wait(0) - DisableAllControlActions(0) - end - - BusyspinnerOff() - end -end - function OpenPoliceActionsMenu() ESX.UI.Menu.CloseAll() @@ -1041,7 +700,7 @@ function OpenBuyWeaponsMenu() local playerPed = PlayerPedId() PlayerData = ESX.GetPlayerData() - for k,v in ipairs(Config.AuthorizedWeapons[PlayerData.job.grade_name]) do + for k,v in ipairs(Config.AuthorizedWeapons[ESX.PlayerData.job.grade_name]) do local weaponNum, weapon = ESX.GetWeapon(v.weapon) local components, label = {} local hasWeapon = HasPedGotWeapon(playerPed, GetHashKey(v.weapon), false) @@ -1244,7 +903,7 @@ end RegisterNetEvent('esx:setJob') AddEventHandler('esx:setJob', function(job) - PlayerData.job = job + ESX.PlayerData.job = job Citizen.Wait(5000) TriggerServerEvent('esx_policejob:forceBlip') @@ -1263,7 +922,7 @@ end) -- don't show dispatches if the player isn't in service AddEventHandler('esx_phone:cancelMessage', function(dispatchNumber) - if PlayerData.job and PlayerData.job.name == 'police' and PlayerData.job.name == dispatchNumber then + if ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' and ESX.PlayerData.job.name == dispatchNumber then -- if esx_service is enabled if Config.EnableESXService and not playerInService then CancelEvent() @@ -1306,7 +965,7 @@ end) AddEventHandler('esx_policejob:hasEnteredEntityZone', function(entity) local playerPed = PlayerPedId() - if PlayerData.job and PlayerData.job.name == 'police' and IsPedOnFoot(playerPed) then + if ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' and IsPedOnFoot(playerPed) then CurrentAction = 'remove_entity' CurrentActionMsg = _U('remove_prop') CurrentActionData = {entity = entity} @@ -1553,7 +1212,7 @@ Citizen.CreateThread(function() while true do Citizen.Wait(0) - if PlayerData.job and PlayerData.job.name == 'police' then + if ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' then local playerPed = PlayerPedId() local playerCoords = GetEntityCoords(playerPed) local isInMarker, hasExited, letSleep = false, false, true @@ -1612,7 +1271,7 @@ Citizen.CreateThread(function() end end - if Config.EnablePlayerManagement and PlayerData.job.grade_name == 'boss' then + if Config.EnablePlayerManagement and ESX.PlayerData.job.grade_name == 'boss' then for i=1, #v.BossActions, 1 do local distance = #(playerCoords - v.BossActions[i]) @@ -1714,7 +1373,7 @@ Citizen.CreateThread(function() if CurrentAction then ESX.ShowHelpNotification(CurrentActionMsg) - if IsControlJustReleased(0, 38) and PlayerData.job and PlayerData.job.name == 'police' then + if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' then if CurrentAction == 'menu_cloakroom' then OpenCloakroomMenu() @@ -1761,7 +1420,7 @@ Citizen.CreateThread(function() end end -- CurrentAction end - if IsControlJustReleased(0, 167) and not isDead and PlayerData.job and PlayerData.job.name == 'police' and not ESX.UI.Menu.IsOpen('default', GetCurrentResourceName(), 'police_actions') then + if IsControlJustReleased(0, 167) and not isDead and ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' and not ESX.UI.Menu.IsOpen('default', GetCurrentResourceName(), 'police_actions') then if not Config.EnableESXService then OpenPoliceActionsMenu() elseif playerInService then @@ -1820,7 +1479,7 @@ AddEventHandler('esx_policejob:updateBlip', function() end -- Is the player a cop? In that case show all the blips for other cops - if PlayerData.job and PlayerData.job.name == 'police' then + if ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' then ESX.TriggerServerCallback('esx_society:getOnlinePlayers', function(players) for i=1, #players, 1 do if players[i].job.name == 'police' then diff --git a/client/vehicle.lua b/client/vehicle.lua new file mode 100644 index 00000000..a0af0aec --- /dev/null +++ b/client/vehicle.lua @@ -0,0 +1,322 @@ + +local spawnedVehicles = {} + +function OpenVehicleSpawnerMenu(type, station, part, partNum) + local playerCoords = GetEntityCoords(PlayerPedId()) + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle', { + title = _U('garage_title'), + align = 'top-left', + elements = { + {label = _U('garage_storeditem'), action = 'garage'}, + {label = _U('garage_storeitem'), action = 'store_garage'}, + {label = _U('garage_buyitem'), action = 'buy_vehicle'} + }}, function(data, menu) + if data.current.action == 'buy_vehicle' then + local shopElements = {} + local shopCoords = Config.PoliceStations[station][part][partNum].InsideShop + local authorizedVehicles = Config.AuthorizedVehicles[type][ESX.PlayerData.job.grade_name] + + if #authorizedVehicles > 0 then + for k,vehicle in ipairs(authorizedVehicles) do + if IsModelInCdimage(vehicle.model) then + local vehicleLabel = GetLabelText(GetDisplayNameFromVehicleModel(vehicle.model)) + + table.insert(shopElements, { + label = ('%s - %s'):format(vehicleLabel, _U('shop_item', ESX.Math.GroupDigits(vehicle.price))), + name = vehicleLabel, + model = vehicle.model, + price = vehicle.price, + props = vehicle.props, + type = type + }) + end + end + + if #shopElements > 0 then + OpenShopMenu(shopElements, playerCoords, shopCoords) + else + ESX.ShowNotification(_U('garage_notauthorized')) + end + else + ESX.ShowNotification(_U('garage_notauthorized')) + end + elseif data.current.action == 'garage' then + local garage = {} + + ESX.TriggerServerCallback('esx_vehicleshop:retrieveJobVehicles', function(jobVehicles) + if #jobVehicles > 0 then + local allVehicleProps = {} + + for k,v in ipairs(jobVehicles) do + local props = json.decode(v.vehicle) + + if IsModelInCdimage(props.model) then + local vehicleName = GetLabelText(GetDisplayNameFromVehicleModel(props.model)) + local label = ('%s - %s: '):format(vehicleName, props.plate) + + if v.stored then + label = label .. ('%s'):format(_U('garage_stored')) + else + label = label .. ('%s'):format(_U('garage_notstored')) + end + + table.insert(garage, { + label = label, + stored = v.stored, + model = props.model, + plate = props.plate + }) + + allVehicleProps[props.plate] = props + end + end + + if #garage > 0 then + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_garage', { + title = _U('garage_title'), + align = 'top-left', + elements = garage + }, function(data2, menu2) + if data2.current.stored then + local foundSpawn, spawnPoint = GetAvailableVehicleSpawnPoint(station, part, partNum) + + if foundSpawn then + menu2.close() + + ESX.Game.SpawnVehicle(data2.current.model, spawnPoint.coords, spawnPoint.heading, function(vehicle) + local vehicleProps = allVehicleProps[data2.current.plate] + ESX.Game.SetVehicleProperties(vehicle, vehicleProps) + + TriggerServerEvent('esx_vehicleshop:setJobVehicleState', data2.current.plate, false) + ESX.ShowNotification(_U('garage_released')) + end) + end + else + ESX.ShowNotification(_U('garage_notavailable')) + end + end, function(data2, menu2) + menu2.close() + end) + else + ESX.ShowNotification(_U('garage_empty')) + end + else + ESX.ShowNotification(_U('garage_empty')) + end + end, type) + elseif data.current.action == 'store_garage' then + StoreNearbyVehicle(playerCoords) + end + end, function(data, menu) + menu.close() + end) +end + +function StoreNearbyVehicle(playerCoords) + local vehicles, vehiclePlates = ESX.Game.GetVehiclesInArea(playerCoords, 30.0), {} + + if #vehicles > 0 then + for k,v in ipairs(vehicles) do + + -- 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)) + }) + end + end + else + ESX.ShowNotification(_U('garage_store_nearby')) + return + end + + ESX.TriggerServerCallback('esx_policejob:storeNearbyVehicle', function(storeSuccess, foundNum) + if storeSuccess then + local vehicleId = vehiclePlates[foundNum] + local attempts = 0 + ESX.Game.DeleteVehicle(vehicleId.vehicle) + IsBusy = true + + Citizen.CreateThread(function() + BeginTextCommandBusyspinnerOn('STRING') + AddTextComponentSubstringPlayerName(_U('garage_storing')) + EndTextCommandBusyspinnerOn(4) + + while IsBusy do + Citizen.Wait(100) + end + + BusyspinnerOff() + end) + + -- Workaround for vehicle not deleting when other players are near it. + while DoesEntityExist(vehicleId.vehicle) do + Citizen.Wait(500) + attempts = attempts + 1 + + -- Give up + if attempts > 30 then + break + end + + 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) + break + end + end + end + end + + IsBusy = false + ESX.ShowNotification(_U('garage_has_stored')) + else + ESX.ShowNotification(_U('garage_has_notstored')) + end + end, vehiclePlates) +end + +function GetAvailableVehicleSpawnPoint(station, part, partNum) + local spawnPoints = Config.PoliceStations[station][part][partNum].SpawnPoints + local found, foundSpawnPoint = false, nil + + for i=1, #spawnPoints, 1 do + if ESX.Game.IsSpawnPointClear(spawnPoints[i].coords, spawnPoints[i].radius) then + found, foundSpawnPoint = true, spawnPoints[i] + break + end + end + + if found then + return true, foundSpawnPoint + else + ESX.ShowNotification(_U('vehicle_blocked')) + return false + end +end + +function OpenShopMenu(elements, restoreCoords, shopCoords) + local playerPed = PlayerPedId() + isInShopMenu = true + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop', { + title = _U('vehicleshop_title'), + align = 'top-left', + elements = elements + }, function(data, menu) + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop_confirm', { + title = _U('vehicleshop_confirm', data.current.name, data.current.price), + align = 'top-left', + elements = { + {label = _U('confirm_no'), value = 'no'}, + {label = _U('confirm_yes'), value = 'yes'} + }}, function(data2, menu2) + if data2.current.value == 'yes' then + local newPlate = exports['esx_vehicleshop']:GeneratePlate() + local vehicle = GetVehiclePedIsIn(playerPed, false) + local props = ESX.Game.GetVehicleProperties(vehicle) + props.plate = newPlate + + ESX.TriggerServerCallback('esx_policejob:buyJobVehicle', function (bought) + if bought then + ESX.ShowNotification(_U('vehicleshop_bought', data.current.name, ESX.Math.GroupDigits(data.current.price))) + + isInShopMenu = false + ESX.UI.Menu.CloseAll() + DeleteSpawnedVehicles() + FreezeEntityPosition(playerPed, false) + SetEntityVisible(playerPed, true) + + ESX.Game.Teleport(playerPed, restoreCoords) + else + ESX.ShowNotification(_U('vehicleshop_money')) + menu2.close() + end + end, props, data.current.type) + else + menu2.close() + end + end, function(data2, menu2) + menu2.close() + end) + end, function(data, menu) + isInShopMenu = false + ESX.UI.Menu.CloseAll() + + DeleteSpawnedVehicles() + FreezeEntityPosition(playerPed, false) + SetEntityVisible(playerPed, true) + + ESX.Game.Teleport(playerPed, restoreCoords) + end, function(data, menu) + DeleteSpawnedVehicles() + WaitForVehicleToLoad(data.current.model) + + ESX.Game.SpawnLocalVehicle(data.current.model, shopCoords, 0.0, function(vehicle) + table.insert(spawnedVehicles, vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + FreezeEntityPosition(vehicle, true) + SetModelAsNoLongerNeeded(data.current.model) + + if data.current.props then + ESX.Game.SetVehicleProperties(vehicle, data.current.props) + end + end) + end) + + WaitForVehicleToLoad(elements[1].model) + ESX.Game.SpawnLocalVehicle(elements[1].model, shopCoords, 0.0, function(vehicle) + table.insert(spawnedVehicles, vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + FreezeEntityPosition(vehicle, true) + SetModelAsNoLongerNeeded(elements[1].model) + + if elements[1].props then + ESX.Game.SetVehicleProperties(vehicle, elements[1].props) + end + end) +end + +Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + + if isInShopMenu then + DisableControlAction(0, 75, true) -- Disable exit vehicle + DisableControlAction(27, 75, true) -- Disable exit vehicle + else + Citizen.Wait(500) + end + end +end) + +function DeleteSpawnedVehicles() + while #spawnedVehicles > 0 do + local vehicle = spawnedVehicles[1] + ESX.Game.DeleteVehicle(vehicle) + table.remove(spawnedVehicles, 1) + end +end + +function WaitForVehicleToLoad(modelHash) + modelHash = (type(modelHash) == 'number' and modelHash or GetHashKey(modelHash)) + + if not HasModelLoaded(modelHash) then + RequestModel(modelHash) + + BeginTextCommandBusyspinnerOn('STRING') + AddTextComponentSubstringPlayerName(_U('vehicleshop_awaiting_model')) + EndTextCommandBusyspinnerOn(4) + + while not HasModelLoaded(modelHash) do + Citizen.Wait(0) + DisableAllControlActions(0) + end + + BusyspinnerOff() + end +end diff --git a/config.lua b/config.lua index a47eaa62..f3de61a0 100644 --- a/config.lua +++ b/config.lua @@ -144,65 +144,53 @@ Config.AuthorizedWeapons = { } Config.AuthorizedVehicles = { - Shared = { - {model = 'police', label = 'Police Cruiser', price = 10000}, - {model = 'pbus', label = 'Police Prison Bus', price = 5000} + car = { + recruit = {}, + + officer = { + {model = 'police3', price = 20000} + }, + + sergeant = { + {model = 'policet', price = 18500}, + {model = 'policeb', price = 30500} + }, + + intendent = {}, + + lieutenant = { + {model = 'riot', price = 70000}, + {model = 'fbi2', price = 60000} + }, + + chef = {}, + + boss = {} }, - recruit = { + helicopter = { + recruit = {}, - }, + officer = {}, - officer = { - {model = 'police3', label = 'Police Interceptor', price = 20000} - }, + sergeant = {}, - sergeant = { - {model = 'policet', label = 'Police Transporter', price = 18500}, - {model = 'policeb', label = 'Police Bike', price = 30500} - }, + intendent = {}, - intendent = { + lieutenant = { + {model = 'polmav', props = {modLivery = 0}, price = 200000} + }, - }, - - lieutenant = { - {model = 'riot', label = 'Police Riot', price = 70000}, - {model = 'fbi2', label = 'FIB SUV', price = 60000} - }, - - chef = { - - }, - - boss = { + chef = { + {model = 'polmav', props = {modLivery = 0}, price = 150000} + }, + boss = { + {model = 'polmav', props = {modLivery = 0}, price = 100000} + } } } -Config.AuthorizedHelicopters = { - recruit = {}, - - officer = {}, - - sergeant = {}, - - intendent = {}, - - lieutenant = { - {model = 'polmav', label = 'Police Maverick', livery = 0, price = 200000} - }, - - chef = { - {model = 'polmav', label = 'Police Maverick', livery = 0, price = 150000} - }, - - boss = { - {model = 'polmav', label = 'Police Maverick', livery = 0, price = 100000} - } -} - - Config.CustomPeds = { shared = { {label = 'Sheriff Ped', maleModel = 's_m_y_sheriff_01', femaleModel = 's_f_y_sheriff_01'}, diff --git a/fxmanifest.lua b/fxmanifest.lua index 85852ca4..af5949ca 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -34,7 +34,8 @@ client_scripts { 'locales/sv.lua', 'locales/ko.lua', 'config.lua', - 'client/main.lua' + 'client/main.lua', + 'client/vehicle.lua' } dependencies { diff --git a/locales/br.lua b/locales/br.lua index 13ad287c..e47dda49 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -20,7 +20,7 @@ Locales['br'] = { ['armory_item'] = '$%s', ['armory_weapontitle'] = 'armory - Buy weapon', ['armory_componenttitle'] = 'armory - Weapon attatchments', - ['armory_bought'] = 'you bought an ~y~%s~s~ for ~r~$%s~s~', + ['armory_bought'] = 'you bought an ~y~%s~s~ for ~g~$%s~s~', ['armory_money'] = 'you cannot afford that weapon', ['armory_hascomponent'] = 'you have that attatchment equiped!', ['get_weapon_menu'] = 'armory - Withdraw Weapon', @@ -43,8 +43,8 @@ Locales['br'] = { ['garage_storeditem'] = 'open garage', ['garage_storeitem'] = 'store vehicle in garage', ['garage_buyitem'] = 'vehicle shop', + ['garage_notauthorized'] = 'you\'re not authorized to buy this kind of vehicles.', ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', - ['helicopter_notauthorized'] = 'you\'re not authorized to buy helicopters.', ['shop_item'] = '$%s', ['vehicleshop_title'] = 'vehicle Shop', ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', diff --git a/locales/de.lua b/locales/de.lua index eb6ee554..7492e226 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -20,7 +20,7 @@ Locales['de'] = { ['armory_item'] = '$%s', ['armory_weapontitle'] = 'armory - Buy weapon', ['armory_componenttitle'] = 'armory - Weapon attatchments', - ['armory_bought'] = 'you bought an ~y~%s~s~ for ~r~$%s~s~', + ['armory_bought'] = 'you bought an ~y~%s~s~ for ~g~$%s~s~', ['armory_money'] = 'you cannot afford that weapon', ['armory_hascomponent'] = 'you have that attatchment equiped!', ['get_weapon_menu'] = 'armory - Withdraw Weapon', @@ -43,8 +43,8 @@ Locales['de'] = { ['garage_storeditem'] = 'open garage', ['garage_storeitem'] = 'store vehicle in garage', ['garage_buyitem'] = 'vehicle shop', + ['garage_notauthorized'] = 'you\'re not authorized to buy this kind of vehicles.', ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', - ['helicopter_notauthorized'] = 'you\'re not authorized to buy helicopters.', ['shop_item'] = '$%s', ['vehicleshop_title'] = 'vehicle Shop', ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', diff --git a/locales/en.lua b/locales/en.lua index 323f4e7d..0a30a598 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -20,7 +20,7 @@ Locales['en'] = { ['armory_item'] = '$%s', ['armory_weapontitle'] = 'armory - Buy weapon', ['armory_componenttitle'] = 'armory - Weapon attatchments', - ['armory_bought'] = 'you bought an ~y~%s~s~ for ~r~$%s~s~', + ['armory_bought'] = 'you bought an ~y~%s~s~ for ~g~$%s~s~', ['armory_money'] = 'you cannot afford that weapon', ['armory_hascomponent'] = 'you have that attatchment equiped!', ['get_weapon_menu'] = 'armory - Withdraw Weapon', @@ -43,8 +43,8 @@ Locales['en'] = { ['garage_storeditem'] = 'open garage', ['garage_storeitem'] = 'store vehicle in garage', ['garage_buyitem'] = 'vehicle shop', + ['garage_notauthorized'] = 'you\'re not authorized to buy this kind of vehicles.', ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', - ['helicopter_notauthorized'] = 'you\'re not authorized to buy helicopters.', ['shop_item'] = '$%s', ['vehicleshop_title'] = 'vehicle Shop', ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', diff --git a/locales/es.lua b/locales/es.lua index c9c05cc5..354c89e6 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -20,7 +20,7 @@ Locales['es'] = { ['armory_item'] = '$%s', ['armory_weapontitle'] = 'armory - Buy weapon', ['armory_componenttitle'] = 'armory - Weapon attatchments', - ['armory_bought'] = 'you bought an ~y~%s~s~ for ~r~$%s~s~', + ['armory_bought'] = 'you bought an ~y~%s~s~ for ~g~$%s~s~', ['armory_money'] = 'you cannot afford that weapon', ['armory_hascomponent'] = 'you have that attatchment equiped!', ['get_weapon_menu'] = 'armory - Withdraw Weapon', @@ -43,8 +43,8 @@ Locales['es'] = { ['garage_storeditem'] = 'open garage', ['garage_storeitem'] = 'store vehicle in garage', ['garage_buyitem'] = 'vehicle shop', + ['garage_notauthorized'] = 'you\'re not authorized to buy this kind of vehicles.', ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', - ['helicopter_notauthorized'] = 'you\'re not authorized to buy helicopters.', ['shop_item'] = '$%s', ['vehicleshop_title'] = 'vehicle Shop', ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', diff --git a/locales/fi.lua b/locales/fi.lua index 93c8af21..b0f5d7d9 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -20,7 +20,7 @@ Locales['fi'] = { ['armory_item'] = '$%s', ['armory_weapontitle'] = 'armory - Buy weapon', ['armory_componenttitle'] = 'armory - Weapon attatchments', - ['armory_bought'] = 'you bought an ~y~%s~s~ for ~r~$%s~s~', + ['armory_bought'] = 'you bought an ~y~%s~s~ for ~g~$%s~s~', ['armory_money'] = 'you cannot afford that weapon', ['armory_hascomponent'] = 'you have that attatchment equiped!', ['get_weapon_menu'] = 'armory - Withdraw Weapon', @@ -43,8 +43,8 @@ Locales['fi'] = { ['garage_storeditem'] = 'open garage', ['garage_storeitem'] = 'store vehicle in garage', ['garage_buyitem'] = 'vehicle shop', + ['garage_notauthorized'] = 'you\'re not authorized to buy this kind of vehicles.', ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', - ['helicopter_notauthorized'] = 'you\'re not authorized to buy helicopters.', ['shop_item'] = '$%s', ['vehicleshop_title'] = 'vehicle Shop', ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', diff --git a/locales/fr.lua b/locales/fr.lua index 8f3071cc..d30a825b 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -20,7 +20,7 @@ Locales['fr'] = { ['armory_item'] = '$%s', ['armory_weapontitle'] = 'armurerie - Acheter une arme', ['armory_componenttitle'] = 'armurerie - Accessoires d\'armes', - ['armory_bought'] = 'vous achetez un ~y~%s~s~ pour ~r~$%s~s~', + ['armory_bought'] = 'vous achetez un ~y~%s~s~ pour ~g~$%s~s~', ['armory_money'] = 'vous ne pouvez pas acheter cette arme', ['armory_hascomponent'] = 'vous avez cet accessoire équipé!', ['get_weapon_menu'] = 'armurerie - Retirer arme', @@ -43,8 +43,8 @@ Locales['fr'] = { ['garage_storeditem'] = 'ouvrir le garage', ['garage_storeitem'] = 'ranger le véhicule', ['garage_buyitem'] = 'magasin véhicule', + ['garage_notauthorized'] = 'you\'re not authorized to buy this kind of vehicles.', ['helicopter_prompt'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder aux ~y~Actions de l\'hélicoptère~s~.', - ['helicopter_notauthorized'] = 'vous n\'êtes pas autorisé à acheter un hélicoptère.', ['shop_item'] = '$%s', ['vehicleshop_title'] = 'magasin véhicule', ['vehicleshop_confirm'] = 'voulez-vous acheter ce véhicule?', diff --git a/locales/ko.lua b/locales/ko.lua index cf7fe418..ea2c093c 100644 --- a/locales/ko.lua +++ b/locales/ko.lua @@ -20,7 +20,7 @@ Locales['ko'] = { ['armory_item'] = '$%s', ['armory_weapontitle'] = '병기고 - 무기 구매', ['armory_componenttitle'] = '병기고 - 무기 부착물', - ['armory_bought'] = '당신은 ~r~$%s~s~에 ~y~%s~s~를 구매했습니다', + ['armory_bought'] = '당신은 ~g~$%s~s~에 ~y~%s~s~를 구매했습니다', ['armory_money'] = '당신은 이 무기를 살 수 없습니다', ['armory_hascomponent'] = '이 부착물이 장착되어 있습니다!', ['get_weapon_menu'] = '병기고 - 무기 빼다', @@ -43,8 +43,8 @@ Locales['ko'] = { ['garage_storeditem'] = '차고 열기', ['garage_storeitem'] = '차량 정리', ['garage_buyitem'] = '차량 상점', + ['garage_notauthorized'] = 'you\'re not authorized to buy this kind of vehicles.', ['helicopter_prompt'] = '~y~헬리콥터 동작~s~에 액세스하려면 ~INPUT_CONTEXT~를 누릅니다.', - ['helicopter_notauthorized'] = '헬리콥터를 구매할 수 없습니다.', ['shop_item'] = '$%s', ['vehicleshop_title'] = '차량 판매점', ['vehicleshop_confirm'] = '이 차량을 사고 싶습니까?', diff --git a/locales/pl.lua b/locales/pl.lua index 210092ca..ab5e8678 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -20,7 +20,7 @@ Locales['pl'] = { ['armory_item'] = '$%s', ['armory_weapontitle'] = 'armory - Buy weapon', ['armory_componenttitle'] = 'armory - Weapon attatchments', - ['armory_bought'] = 'you bought an ~y~%s~s~ for ~r~$%s~s~', + ['armory_bought'] = 'you bought an ~y~%s~s~ for ~g~$%s~s~', ['armory_money'] = 'you cannot afford that weapon', ['armory_hascomponent'] = 'you have that attatchment equiped!', ['get_weapon_menu'] = 'armory - Withdraw Weapon', @@ -43,8 +43,8 @@ Locales['pl'] = { ['garage_storeditem'] = 'open garage', ['garage_storeitem'] = 'store vehicle in garage', ['garage_buyitem'] = 'vehicle shop', + ['garage_notauthorized'] = 'you\'re not authorized to buy this kind of vehicles.', ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', - ['helicopter_notauthorized'] = 'you\'re not authorized to buy helicopters.', ['shop_item'] = '$%s', ['vehicleshop_title'] = 'vehicle Shop', ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', diff --git a/locales/sv.lua b/locales/sv.lua index a79aef07..04f52ed0 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -43,12 +43,12 @@ Locales['sv'] = { ['garage_storeditem'] = 'öppna garage', ['garage_storeitem'] = 'ställ in fordon', ['garage_buyitem'] = 'fordonshandel', - ['helicopter_prompt'] = 'klicka på ~INPUT_CONTEXT~ för att komma åt ~y~garaget~s~.', - ['helicopter_notauthorized'] = 'du har inte behörighet till att köpa en helikopter.', + ['garage_notauthorized'] = 'du har inte tillgång till att köpa dessa fordon.', + ['helicopter_prompt'] = 'tryck ~INPUT_CONTEXT~ för att komma åt ~y~helikoptergaraget~s~.', ['shop_item'] = '%s SEK', ['vehicleshop_title'] = 'fordonshandel', ['vehicleshop_confirm'] = 'vill du köpa detta fordon?', - ['vehicleshop_bought'] = 'du köpte ~y~%s~s~ för ~r~$%s~s~', + ['vehicleshop_bought'] = 'du köpte ~y~%s~s~ för ~g~%s SEK~s~', ['vehicleshop_money'] = 'du har inte råd med detta fordon', ['vehicleshop_awaiting_model'] = 'fordonet ~g~LADDAS NED OCH LADDAS IN~s~ var god vänta', ['confirm_no'] = 'nej', @@ -76,7 +76,7 @@ Locales['sv'] = { ['unpaid_bills'] = 'se obetalda räkningar', ['license_check'] = 'se licenser', ['license_revoke'] = 'återkalla licenser', - ['license_revoked'] = 'Ditt ~b~%s~s~ har blivit ~y~återkallat~s~!', + ['license_revoked'] = 'ditt ~b~%s~s~ har blivit ~y~återkallat~s~!', ['licence_you_revoked'] = 'du återkallade ett ~b~%s~s~ som tillhörde ~y~%s~s~', ['no_players_nearby'] = 'det finns ingen i närheten', ['being_searched'] = 'du blir ~y~visiterad~s~ av ~b~Polisen~s~', diff --git a/server/main.lua b/server/main.lua index c30f3fc1..e328e551 100644 --- a/server/main.lua +++ b/server/main.lua @@ -436,29 +436,12 @@ ESX.RegisterServerCallback('esx_policejob:storeNearbyVehicle', function(source, end end) -function getPriceFromHash(hashKey, jobGrade, type) - if type == 'helicopter' then - local vehicles = Config.AuthorizedHelicopters[jobGrade] +function getPriceFromHash(vehicleHash, jobGrade, type) + local vehicles = Config.AuthorizedVehicles[type][jobGrade] - for k,v in ipairs(vehicles) do - if GetHashKey(v.model) == hashKey then - return v.price - end - end - elseif type == 'car' then - local vehicles = Config.AuthorizedVehicles[jobGrade] - local shared = Config.AuthorizedVehicles['Shared'] - - for k,v in ipairs(vehicles) do - if GetHashKey(v.model) == hashKey then - return v.price - end - end - - for k,v in ipairs(shared) do - if GetHashKey(v.model) == hashKey then - return v.price - end + for k,v in ipairs(vehicles) do + if GetHashKey(v.model) == vehicleHash then + return v.price end end From a5e8e7f6b8def681fd5b97d4970bb28398a33130 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 24 Jan 2020 13:25:25 +0100 Subject: [PATCH 2500/3224] Update main.lua --- client/main.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/client/main.lua b/client/main.lua index e2d024f5..94676317 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,4 +1,5 @@ local CurrentActionData, handcuffTimer, dragStatus, blipsCops, currentTask = {}, {}, {}, {}, {} +local HasAlreadyEnteredMarker, isDead, isHandcuffed, hasAlreadyJoined, playerInService = false, false, false, false, false local LastStation, LastPart, LastPartNum, LastEntity, CurrentAction, CurrentActionMsg dragStatus.isDragged, isInShopMenu = false, false ESX = nil From c37a2170d713e974792682716a4a378f7a846bec Mon Sep 17 00:00:00 2001 From: rex2630 Date: Fri, 24 Jan 2020 17:05:54 +0100 Subject: [PATCH 2501/3224] Added Czech locale (#384) * Update fxmanifest.lua * Create cs.lua --- fxmanifest.lua | 2 + locales/cs.lua | 153 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 locales/cs.lua diff --git a/fxmanifest.lua b/fxmanifest.lua index af5949ca..cddca542 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -18,6 +18,7 @@ server_scripts { 'locales/es.lua', 'locales/sv.lua', 'locales/ko.lua', + 'locales/cs.lua', 'config.lua', 'server/main.lua' } @@ -33,6 +34,7 @@ client_scripts { 'locales/es.lua', 'locales/sv.lua', 'locales/ko.lua', + 'locales/cs.lua', 'config.lua', 'client/main.lua', 'client/vehicle.lua' diff --git a/locales/cs.lua b/locales/cs.lua new file mode 100644 index 00000000..eff426e6 --- /dev/null +++ b/locales/cs.lua @@ -0,0 +1,153 @@ +Locales['cs'] = { + -- Cloakroom + ['cloakroom'] = 'satna', + ['citizen_wear'] = 'civilní oblek', + ['police_wear'] = 'policejní oblek', + ['gilet_wear'] = 'oranžová reflexní vesta', + ['bullet_wear'] = 'neprůstřelná vesta', + ['no_outfit'] = 'není zde žádná uniforma, která by ti sedla!', + ['open_cloackroom'] = 'stiskni ~INPUT_CONTEXT~ pro změnu ~y~oblečení~s~.', + -- Armory + ['remove_object'] = 'vzít objekt', + ['deposit_object'] = 'odevzdat objekt', + ['get_weapon'] = 'vzít zbraň ze zbrojnice', + ['put_weapon'] = 'uchovat zbraň ve zbrojnici', + ['buy_weapons'] = 'koupit zbraně', + ['armory'] = 'zbrojnice', + ['open_armory'] = 'stiskni ~INPUT_CONTEXT~ pro přístup do ~y~zbrojnice~s~.', + ['armory_owned'] = 'vlastněno', + ['armory_free'] = 'zdarma', + ['armory_item'] = '$%s', + ['armory_weapontitle'] = 'zbrojnice', + ['armory_componenttitle'] = 'zbrojnice - Příslušenství ke zbraním', + ['armory_bought'] = 'zakoupil jsi ~y~%s~s~ za ~r~$%s~s~', + ['armory_money'] = 'nemáš dostatek peněz na tuto zbraň', + ['armory_hascomponent'] = 'toto příslušenství máš již nainstalováno!', + ['get_weapon_menu'] = 'zbrojnice - Vzít zbraň', + ['put_weapon_menu'] = 'zbrojnice - Uchovat zbraň', + -- Vehicles + ['vehicle_menu'] = 'vozidlo', + ['vehicle_blocked'] = 'vsechny dostupne spawn pointy jsou blokovany!', + ['garage_prompt'] = 'stiskni ~INPUT_CONTEXT~ pro otevreni ~y~akce vozidel~s~.', + ['garage_title'] = 'akce vozidel', + ['garage_stored'] = 'uloženo', + ['garage_notstored'] = 'není v garáži', + ['garage_storing'] = 'pokousime se o odstraneni vozidla, ujisti se, ze kolem nej nejsou hraci.', + ['garage_has_stored'] = 'vozidlo bylo ulozeno do garaze', + ['garage_has_notstored'] = 'zadne nejblizsi vlastnene vozidlo nenalezeno', + ['garage_notavailable'] = 'tvoje vozidlo neni ulozeno v garazi.', + ['garage_blocked'] = 'nejsou zde zadne spawn pointy!', + ['garage_empty'] = 'zadne vozidlo nemas v garazi.', + ['garage_released'] = 'tvoje vozidlo bylo vyjmuto z garaze.', + ['garage_store_nearby'] = 'nejsou poblíž zádná vozidla.', + ['garage_storeditem'] = 'otevřít garáž', + ['garage_storeitem'] = 'uchovat vozidlo v garáži', + ['garage_buyitem'] = 'prodej vozidel', + ['garage_notauthorized'] = 'nemas opravneni ke koupi tohoto vozidla.', + ['helicopter_prompt'] = 'stiskni ~INPUT_CONTEXT~ pro pristup k ~y~akcim Helikopter~s~.', + ['shop_item'] = '$%s', + ['vehicleshop_title'] = 'prodejce vozidel', + ['vehicleshop_confirm'] = 'opravdu chces koupit toto vozidlo?', + ['vehicleshop_bought'] = 'koupil jsi ~y~%s~s~ za ~r~$%s~s~', + ['vehicleshop_money'] = 'toto vozidlo si nemuzete dovolit', + ['vehicleshop_awaiting_model'] = 'vozidlo se prave ~g~stahuje a nacita~s~ prosim pockej', + ['confirm_no'] = 'ne', + ['confirm_yes'] = 'ano', + -- Service + ['service_max'] = 'nemuzete vstoupit do sluzby, max dustojníci v provozu: %s/%s', + ['service_not'] = 'nezadali jste sluzbu! Nejprve se musíte zmenit.', + ['service_anonunce'] = 'informace o sluzbe', + ['service_in'] = 'vstoupil jsi do sluzby, vitej!', + ['service_in_announce'] = 'operator ~y~%s~s~ se pripojil do sluzby!', + ['service_out'] = 'opustil jsi sluzbu.', + ['service_out_announce'] = 'operator ~y~%s~s~ opustil jejich sluzbu.', + -- Action Menu + ['citizen_interaction'] = 'Interakce s občanem', + ['vehicle_interaction'] = 'Interakce vozidla', + ['object_spawner'] = 'Objekty', + + ['id_card'] = 'Občanský průkaz', + ['search'] = 'prohledat', + ['handcuff'] = 'poutat / odpoutat', + ['drag'] = 'prenést', + ['put_in_vehicle'] = 'vlozit do vozidla', + ['out_the_vehicle'] = 'vytahnout z vozidla', + ['fine'] = 'pokuta', + ['unpaid_bills'] = 'spravovat nezaplacené pokuty', + ['license_check'] = 'spravovat průkazy', + ['license_revoke'] = 'zneplatnit průkaz', + ['license_revoked'] = 'vase ~b~%s~s~ bylo ~y~zruseno~s~!', + ['licence_you_revoked'] = 'zrusil jsi ~b~%s~s~ ktery patril ~y~%s~s~', + ['no_players_nearby'] = 'zadny hrac pobliz!', + ['being_searched'] = 'prave jsi ~y~prohledavan~s~ ~b~policii~s~', + -- Vehicle interaction + ['vehicle_info'] = 'informace o vozidle', + ['pick_lock'] = 'vypáčit vozidlo', + ['vehicle_unlocked'] = 'vozidlo je ~g~Odemčeno~s~', + ['no_vehicles_nearby'] = 'there is no vehicles nearby', + ['impound'] = 'odtahnout vozidlo', + ['impound_prompt'] = 'zmackni ~INPUT_CONTEXT~ pro zruseni ~y~odtahnuti~s~', + ['impound_canceled'] = 'zrusil jsi odtah', + ['impound_canceled_moved'] = 'odtah byl zrusen,protoze se vozidlo pohlo!', + ['impound_successful'] = 'uspesne jsi odtahl vozidlo', + ['search_database'] = 'informace o vozidle', + ['search_database_title'] = 'informace o vozidle - pomocí registracnich cisel', + ['search_database_error_invalid'] = 'tohle ~r~neni~s~ ~y~spravne~s~ registracni cislo', + ['search_database_error_not_found'] = 'toto ~y~registracni cislo~s~ je ~r~nespravne~s~ pro toto vozidlo!', + ['search_database_found'] = 'vozidlo bylo ~y~registrovano~s~ k ~b~%s~s~', + -- Traffic interaction + ['traffic_interaction'] = 'interakce provozu', + ['cone'] = 'kuzel', + ['barrier'] = 'bariera', + ['spikestrips'] = 'ostnaty pas', + ['box'] = 'box', + ['cash'] = 'box penez', + -- ID Card Menu + ['name'] = 'jméno: %s', + ['job'] = 'práce: %s', + ['sex'] = 'pohlaví: %s', + ['dob'] = 'DOB: %s', + ['height'] = 'výška: %s', + ['bac'] = 'BAC: %s', + ['unknown'] = 'neznámé', + ['male'] = 'muž', + ['female'] = 'žena', + -- Body Search Menu + ['guns_label'] = '--- Zbraně ---', + ['inventory_label'] = '--- Inventář ---', + ['license_label'] = ' --- Průkazy ---', + ['confiscate'] = 'zabavit %s', + ['confiscate_weapon'] = 'zabavit %s s %s naboji', + ['confiscate_inv'] = 'zabavit %sx %s', + ['confiscate_dirty'] = 'zabavit spinave penize: $%s', + ['you_confiscated'] = 'zabavil jsi ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', + ['got_confiscated'] = '~y~%sx~s~ ~b~%s~s~ byly zabaveny od ~y~%s~s~', + ['you_confiscated_account'] = 'zabavil jsi ~g~$%s~s~ (%s) od ~b~%s~s~', + ['got_confiscated_account'] = '~g~$%s~s~ (%s) byly zabaveny ~y~%s~s~', + ['you_confiscated_weapon'] = 'zabavil jsi ~b~%s~s~ od ~b~%s~s~ s ~o~%s~s~ naboji ', + ['got_confiscated_weapon'] = 'tvoje ~b~%s~s~ s ~o~%s~s~ bylo zabaveno od ~y~%s~s~', + ['traffic_offense'] = 'dopravní přestupek', + ['minor_offense'] = 'malý přestupek', + ['average_offense'] = 'přestupek', + ['major_offense'] = 'trestný čin', + ['fine_total'] = 'pokuta: %s', + -- Vehicle Info Menu + ['plate'] = 'SPZ: %s', + ['owner_unknown'] = 'vlastník: Neznámý', + ['owner'] = 'vlastník: %s', + -- Boss Menu + ['open_bossmenu'] = 'stiskni ~INPUT_CONTEXT~ pro otevření menu', + ['quantity_invalid'] = 'neplatné množství', + ['have_withdrawn'] = 'vybral jsi ~y~%sx~s~ ~b~%s~s~', + ['have_deposited'] = 'vložil jsi ~y~%sx~s~ ~b~%s~s~', + ['quantity'] = 'množství', + ['inventory'] = 'inventář', + ['police_stock'] = 'policejní sklad', + -- Misc + ['remove_prop'] = 'stiskni ~INPUT_CONTEXT~ pro odstranění předmětu', + ['map_blip'] = 'policejní stanice', + ['unrestrained_timer'] = 'cítíš, že tvé pouta pomalu ztrácejí přilnavost a padají.', + -- Notifications + ['alert_police'] = 'policejní poplach', + ['phone_police'] = 'policie', +} From 7cd4e234e043ededde48806f169fd7a306beb411 Mon Sep 17 00:00:00 2001 From: Yagiz ALP Date: Tue, 28 Jan 2020 21:48:33 +0300 Subject: [PATCH 2502/3224] Added turkish language (#44) * Create tr.lua * Update tr.lua Added turkish locale * Update fxmanifest.lua * done hmm, yes, floor here is made out of floor. --- fxmanifest.lua | 1 + locales/tr.lua | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 locales/tr.lua diff --git a/fxmanifest.lua b/fxmanifest.lua index 33537561..c1fb2f47 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -16,6 +16,7 @@ client_scripts { 'locales/fr.lua', 'locales/pl.lua', 'locales/sv.lua', + 'locales/tr.lua', 'config.lua', 'client/main.lua' } diff --git a/locales/tr.lua b/locales/tr.lua new file mode 100644 index 00000000..54313745 --- /dev/null +++ b/locales/tr.lua @@ -0,0 +1,76 @@ +Locales['tr'] = { + ['sex'] = 'cinsiyet', + ['face'] = 'yüz', + ['skin'] = 'deri', + ['wrinkles'] = 'kırışıklıklar', + ['wrinkle_thickness'] = 'kırışıklık yoğunluğu', + ['beard_type'] = 'sakal tipi', + ['beard_size'] = 'sakal boyutu', + ['beard_color_1'] = 'sakal rengi 1', + ['beard_color_2'] = 'sakal rengi 2', + ['hair_1'] = 'saç 1', + ['hair_2'] = 'saç 2', + ['hair_color_1'] = 'saç rengi 1', + ['hair_color_2'] = 'saç rengi 2', + ['eye_color'] = 'göz rengi', + ['eyebrow_type'] = 'kaş tipi', + ['eyebrow_size'] = 'kaş boyutu', + ['eyebrow_color_1'] = 'kaş rengi 1', + ['eyebrow_color_2'] = 'Kaş Rengi 2', + ['makeup_type'] = 'makyaj tipi', + ['makeup_thickness'] = 'makyaj kalınlığı', + ['makeup_color_1'] = 'makyaj rengi 1', + ['makeup_color_2'] = 'makyaj rengi 2', + ['lipstick_type'] = 'ruj tipi', + ['lipstick_thickness'] = 'ruj kalınlığı', + ['lipstick_color_1'] = 'ruj rengi 1', + ['lipstick_color_2'] = 'ruj rengi 2', + ['ear_accessories'] = 'kulak aksessuarları', + ['ear_accessories_color'] = 'kulak aksessuar rengi', + ['tshirt_1'] = 'tişört 1', + ['tshirt_2'] = 'tişört 2', + ['torso_1'] = 'gövde 1', + ['torso_2'] = 'gövde 2', + ['decals_1'] = 'çıkartma 1', + ['decals_2'] = 'çıkartma 2', + ['arms'] = 'kollar', + ['arms_2'] = 'kollar 2' + ['pants_1'] = 'pantolonlar 1', + ['pants_2'] = 'pantolonlar 2', + ['shoes_1'] = 'ayakkabılar 1', + ['shoes_2'] = 'ayakkabılar 2', + ['mask_1'] = 'maske 1', + ['mask_2'] = 'maske 2', + ['bproof_1'] = 'zırh 1', + ['bproof_2'] = 'zırh 2', + ['chain_1'] = 'zincir 1', + ['chain_2'] = 'zincir 2', + ['helmet_1'] = 'kask 1', + ['helmet_2'] = 'kask 2', + ['watches_1'] = 'saat 1', + ['watches_2'] = 'saat 2', + ['bracelets_1'] = 'takı 1', + ['bracelets_2'] = 'takı 2', + ['glasses_1'] = 'gözlük 1', + ['glasses_2'] = 'gözlük 2', + ['bag'] = 'çanta', + ['bag_color'] = 'çanta rengi', + ['blemishes'] = 'leke', + ['blemishes_size']= 'leke kalınlığı', + ['ageing'] = 'yaşlanma', + ['ageing_1'] = 'yaşlanma kalınlığı', + ['blush'] = 'kızarıklık', + ['blush_1'] = 'kızarıklık kalınlığı', + ['blush_color'] = 'kızarıklık rengi', + ['complexion'] = 'ten', + ['complexion_1'] = 'ten Kalınlığı', + ['sun'] = 'yanık', + ['sun_1'] = 'yanık kalınlığı', + ['freckles'] = 'çiller', + ['freckles_1'] = 'çil kalınlığı', + ['chest_hair'] = 'gövde kılı', + ['chest_hair_1'] = 'gövde kılı kalınlığı', + ['chest_color'] = 'gövde kılı rengi', + ['bodyb'] = 'gövde lekesi', + ['bodyb_size'] = 'gövde lekesi kalınlığı' +} From 74aa8328b6f6d964752ed53f6ef212ebb2398a63 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 30 Jan 2020 11:33:40 +0100 Subject: [PATCH 2503/3224] Fixed syntax errors and more --- README.md | 4 ++- config.lua | 1 + locales/br.lua | 2 +- locales/de.lua | 2 +- locales/en.lua | 2 +- locales/es.lua | 94 +++++++++++++++++++++++++------------------------- locales/fi.lua | 2 +- locales/fr.lua | 2 +- locales/pl.lua | 2 +- locales/sv.lua | 2 +- locales/tr.lua | 4 +-- 11 files changed, 60 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index cdff521a..93583906 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # skinchanger +skinchanger is a resource that makes it easy to set and get player ped clothing. It supports the freemode peds `mp_m_freemode_01` and `mp_f_freemode_01`. + ## Download & Installation ### Using [fvm](https://github.com/qlaffont/fvm-installer) @@ -92,7 +94,7 @@ end) ### License skinchanger - make your own skin! -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. diff --git a/config.lua b/config.lua index 5290495d..a3d6aa84 100644 --- a/config.lua +++ b/config.lua @@ -1,2 +1,3 @@ Config = {} + Config.Locale = 'en' diff --git a/locales/br.lua b/locales/br.lua index 7dcaa93c..355e9664 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -72,5 +72,5 @@ Locales['br'] = { ['chest_hair_1'] = 'quantidade de cabelo no peito', ['chest_color'] = 'cor do cabelo no peito', ['bodyb'] = 'manchas no corpo', - ['bodyb_size'] = 'espessura de manchas do corpo' + ['bodyb_size'] = 'espessura de manchas do corpo', } diff --git a/locales/de.lua b/locales/de.lua index 73712d23..ccd88014 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -72,5 +72,5 @@ Locales['de'] = { ['chest_hair_1'] = 'chest hair thickness', ['chest_color'] = 'chest hair color', ['bodyb'] = 'body blemishes', - ['bodyb_size'] = 'body blemishes thickness' + ['bodyb_size'] = 'body blemishes thickness', } diff --git a/locales/en.lua b/locales/en.lua index d808137c..f58354ea 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -72,5 +72,5 @@ Locales['en'] = { ['chest_hair_1'] = 'chest hair thickness', ['chest_color'] = 'chest hair color', ['bodyb'] = 'body blemishes', - ['bodyb_size'] = 'body blemishes thickness' + ['bodyb_size'] = 'body blemishes thickness', } diff --git a/locales/es.lua b/locales/es.lua index 8d3cba00..983e731e 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -5,54 +5,54 @@ Locales['es'] = { ['wrinkles'] = 'arrugas', ['wrinkle_thickness'] = 'grosor arrugas', ['beard_type'] = 'tipo de barba', -  ['beard_size'] = 'tamaño barba', -  ['beard_color_1'] = 'color de barba 1', -  ['beard_color_2'] = 'color de barba 2', -  ['hair_1'] = 'cabello 1', -  ['hair_2'] = 'cabello 2', -  ['hair_color_1'] = 'color de cabello 1', -  ['hair_color_2'] = 'color de cabello 2', -  ['eye_color'] = 'color de ojos', -  ['eyebrow_type'] = 'tipo de ceja', -  ['eyebrow_size'] = 'tamaño ceja', -  ['eyebrow_color_1'] = 'color de ceja 1', -  ['eyebrow_color_2'] = 'color de ceja 2', -  ['makeup_type'] = 'tipo de maquillaje', -  ['makeup_thickness'] = 'espesor maquillaje', -  ['makeup_color_1'] = 'color maquillaje 1', -  ['makeup_color_2'] = 'color maquillaje 2', -  ['lipstick_type'] = 'tipo de barra de labios', -  ['lipstick_thickness'] = 'grosor barra de labios', -  ['lipstick_color_1'] = 'color barra de labios 1', -  ['lipstick_color_2'] = 'color barra de labios 2', -  ['ear_accessories'] = 'accesorios oreja', -  ['ear_accessories_color'] = 'color accesorios oreja', -  ['tshirt_1'] = 'camiseta 1', -  ['tshirt_2'] = 'camiseta 2', -  ['torso_1'] = 'torso 1', -  ['torso_2'] = 'torso 2', -  ['decals_1'] = 'tatuajes 1', -  ['decals_2'] = 'tatuajes 2', + ['beard_size'] = 'tamaño barba', + ['beard_color_1'] = 'color de barba 1', + ['beard_color_2'] = 'color de barba 2', + ['hair_1'] = 'cabello 1', + ['hair_2'] = 'cabello 2', + ['hair_color_1'] = 'color de cabello 1', + ['hair_color_2'] = 'color de cabello 2', + ['eye_color'] = 'color de ojos', + ['eyebrow_type'] = 'tipo de ceja', + ['eyebrow_size'] = 'tamaño ceja', + ['eyebrow_color_1'] = 'color de ceja 1', + ['eyebrow_color_2'] = 'color de ceja 2', + ['makeup_type'] = 'tipo de maquillaje', + ['makeup_thickness'] = 'espesor maquillaje', + ['makeup_color_1'] = 'color maquillaje 1', + ['makeup_color_2'] = 'color maquillaje 2', + ['lipstick_type'] = 'tipo de barra de labios', + ['lipstick_thickness'] = 'grosor barra de labios', + ['lipstick_color_1'] = 'color barra de labios 1', + ['lipstick_color_2'] = 'color barra de labios 2', + ['ear_accessories'] = 'accesorios oreja', + ['ear_accessories_color'] = 'color accesorios oreja', + ['tshirt_1'] = 'camiseta 1', + ['tshirt_2'] = 'camiseta 2', + ['torso_1'] = 'torso 1', + ['torso_2'] = 'torso 2', + ['decals_1'] = 'tatuajes 1', + ['decals_2'] = 'tatuajes 2', ['arms'] = 'brazos', ['arms_2'] = 'brazos 2', -  ['pants_1'] = 'pantalones 1', -  ['pants_2'] = 'pantalones 2', -  ['shoes_1'] = 'zapatos 1', -  ['shoes_2'] = 'zapatos 2', -  ['mask_1'] = 'máscara 1', -  ['mask_2'] = 'máscara 2', -  ['bproof_1'] = 'chaleco antibalas 1', -  ['bproof_2'] = 'chaleco antibalas 2', -  ['chain_1'] = 'cadena 1', -  ['chain_2'] = 'cadena 2', -  ['helmet_1'] = 'casco 1', -  ['helmet_2'] = 'casco 2', -  ['watches_1'] = 'relojes 1', -  ['watches_2'] = 'relojes 2', -  ['bracelets_1'] = 'pulseras 1', -  ['bracelets_2'] = 'pulseras 2', -  ['glasses_1'] = 'gafas 1', -  ['glasses_2'] = 'gafas 2', + ['pants_1'] = 'pantalones 1', + ['pants_2'] = 'pantalones 2', + ['shoes_1'] = 'zapatos 1', + ['shoes_2'] = 'zapatos 2', + ['mask_1'] = 'máscara 1', + ['mask_2'] = 'máscara 2', + ['bproof_1'] = 'chaleco antibalas 1', + ['bproof_2'] = 'chaleco antibalas 2', + ['chain_1'] = 'cadena 1', + ['chain_2'] = 'cadena 2', + ['helmet_1'] = 'casco 1', + ['helmet_2'] = 'casco 2', + ['watches_1'] = 'relojes 1', + ['watches_2'] = 'relojes 2', + ['bracelets_1'] = 'pulseras 1', + ['bracelets_2'] = 'pulseras 2', + ['glasses_1'] = 'gafas 1', + ['glasses_2'] = 'gafas 2', ['bag'] = 'bolsa', ['bag_color'] = 'color de la bolsa', ['blemishes'] = 'manchas', @@ -72,5 +72,5 @@ Locales['es'] = { ['chest_hair_1'] = 'espesor del pecholobo', ['chest_color'] = 'color del pecholobo', ['bodyb'] = 'manchas corporales', - ['bodyb_size'] = 'opacidad manchas corporales' + ['bodyb_size'] = 'opacidad manchas corporales', } diff --git a/locales/fi.lua b/locales/fi.lua index d1a0d6e4..ef2e937b 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -72,5 +72,5 @@ Locales['fi'] = { ['chest_hair_1'] = 'chest hair thickness', ['chest_color'] = 'chest hair color', ['bodyb'] = 'body blemishes', - ['bodyb_size'] = 'body blemishes thickness' + ['bodyb_size'] = 'body blemishes thickness', } diff --git a/locales/fr.lua b/locales/fr.lua index 6ecc2f8b..91238c38 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -72,5 +72,5 @@ Locales['fr'] = { ['chest_hair_1'] = 'opacité pillositée', ['chest_color'] = 'couleur pillositée', ['bodyb'] = 'imperfections du corps', - ['bodyb_size'] = 'opacité imperfections' + ['bodyb_size'] = 'opacité imperfections', } diff --git a/locales/pl.lua b/locales/pl.lua index 468b891e..bb6a8089 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -72,5 +72,5 @@ Locales['pl'] = { ['chest_hair_1'] = 'chest hair thickness', ['chest_color'] = 'chest hair color', ['bodyb'] = 'body blemishes', - ['bodyb_size'] = 'body blemishes thickness' + ['bodyb_size'] = 'body blemishes thickness', } diff --git a/locales/sv.lua b/locales/sv.lua index ff65a74e..9ca5aab3 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -72,5 +72,5 @@ Locales['sv'] = { ['chest_hair_1'] = 'chest hair thickness', ['chest_color'] = 'chest hair color', ['bodyb'] = 'body blemishes', - ['bodyb_size'] = 'body blemishes thickness' + ['bodyb_size'] = 'body blemishes thickness', } diff --git a/locales/tr.lua b/locales/tr.lua index 54313745..cec054f7 100644 --- a/locales/tr.lua +++ b/locales/tr.lua @@ -34,7 +34,7 @@ Locales['tr'] = { ['decals_1'] = 'çıkartma 1', ['decals_2'] = 'çıkartma 2', ['arms'] = 'kollar', - ['arms_2'] = 'kollar 2' + ['arms_2'] = 'kollar 2', ['pants_1'] = 'pantolonlar 1', ['pants_2'] = 'pantolonlar 2', ['shoes_1'] = 'ayakkabılar 1', @@ -72,5 +72,5 @@ Locales['tr'] = { ['chest_hair_1'] = 'gövde kılı kalınlığı', ['chest_color'] = 'gövde kılı rengi', ['bodyb'] = 'gövde lekesi', - ['bodyb_size'] = 'gövde lekesi kalınlığı' + ['bodyb_size'] = 'gövde lekesi kalınlığı', } From 7f75fe55b92fabea9c676c211d3db85dcbc5af56 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 30 Jan 2020 11:37:54 +0100 Subject: [PATCH 2504/3224] Revert unfinished code --- locales/en.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/en.lua b/locales/en.lua index 0a30a598..2a08acd5 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -116,7 +116,7 @@ Locales['en'] = { ['guns_label'] = '--- Guns ---', ['inventory_label'] = '--- Inventory ---', ['license_label'] = ' --- Licenses ---', - ['confiscate'] = 'sieze illegal items', + ['confiscate'] = 'confiscate %s', ['confiscate_weapon'] = 'confiscate %s with %s bullets', ['confiscate_inv'] = 'confiscate %sx %s', ['confiscate_dirty'] = 'confiscate dirty money: $%s', From d83ad88adec0003ae43c0216a3f23ce92679e876 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 30 Jan 2020 12:04:55 +0100 Subject: [PATCH 2505/3224] Fixed ranks, fixes #387 and closes #142 --- config.lua | 86 +------------------------------ esx_policejob.sql | 2 +- localization/de_esx_policejob.sql | 7 ++- localization/en_esx_policejob.sql | 1 - localization/fi_esx_policejob.sql | 1 - localization/ko_esx_policejob.sql | 1 - localization/sv_esx_policejob.sql | 7 ++- 7 files changed, 9 insertions(+), 96 deletions(-) diff --git a/config.lua b/config.lua index f3de61a0..7af9bb20 100644 --- a/config.lua +++ b/config.lua @@ -106,15 +106,6 @@ Config.AuthorizedWeapons = { {weapon = 'WEAPON_FLASHLIGHT', price = 0} }, - intendent = { - {weapon = 'WEAPON_APPISTOL', components = {0, 0, 1000, 4000, nil}, price = 10000}, - {weapon = 'WEAPON_ADVANCEDRIFLE', components = {0, 6000, 1000, 4000, 8000, nil}, price = 50000}, - {weapon = 'WEAPON_PUMPSHOTGUN', components = {2000, 6000, nil}, price = 70000}, - {weapon = 'WEAPON_NIGHTSTICK', price = 0}, - {weapon = 'WEAPON_STUNGUN', price = 500}, - {weapon = 'WEAPON_FLASHLIGHT', price = 0} - }, - lieutenant = { {weapon = 'WEAPON_APPISTOL', components = {0, 0, 1000, 4000, nil}, price = 10000}, {weapon = 'WEAPON_ADVANCEDRIFLE', components = {0, 6000, 1000, 4000, 8000, nil}, price = 50000}, @@ -124,15 +115,6 @@ Config.AuthorizedWeapons = { {weapon = 'WEAPON_FLASHLIGHT', price = 0} }, - chef = { - {weapon = 'WEAPON_APPISTOL', components = {0, 0, 1000, 4000, nil}, price = 10000}, - {weapon = 'WEAPON_ADVANCEDRIFLE', components = {0, 6000, 1000, 4000, 8000, nil}, price = 50000}, - {weapon = 'WEAPON_PUMPSHOTGUN', components = {2000, 6000, nil}, price = 70000}, - {weapon = 'WEAPON_NIGHTSTICK', price = 0}, - {weapon = 'WEAPON_STUNGUN', price = 500}, - {weapon = 'WEAPON_FLASHLIGHT', price = 0} - }, - boss = { {weapon = 'WEAPON_APPISTOL', components = {0, 0, 1000, 4000, nil}, price = 10000}, {weapon = 'WEAPON_ADVANCEDRIFLE', components = {0, 6000, 1000, 4000, 8000, nil}, price = 50000}, @@ -156,15 +138,11 @@ Config.AuthorizedVehicles = { {model = 'policeb', price = 30500} }, - intendent = {}, - lieutenant = { {model = 'riot', price = 70000}, {model = 'fbi2', price = 60000} }, - chef = {}, - boss = {} }, @@ -175,16 +153,10 @@ Config.AuthorizedVehicles = { sergeant = {}, - intendent = {}, - lieutenant = { {model = 'polmav', props = {modLivery = 0}, price = 200000} }, - chef = { - {model = 'polmav', props = {modLivery = 0}, price = 150000} - }, - boss = { {model = 'polmav', props = {modLivery = 0}, price = 100000} } @@ -203,12 +175,8 @@ Config.CustomPeds = { sergeant = {}, - intendent = {}, - lieutenant = {}, - chef = {}, - boss = { {label = 'SWAT Ped', maleModel = 's_m_y_swat_01', femaleModel = 's_m_y_swat_01'} } @@ -291,7 +259,7 @@ Config.Uniforms = { } }, - intendent = { + lieutenant = { male = { tshirt_1 = 58, tshirt_2 = 0, torso_1 = 55, torso_2 = 0, @@ -316,57 +284,7 @@ Config.Uniforms = { } }, - lieutenant = {-- currently the same as intendent - male = { - tshirt_1 = 58, tshirt_2 = 0, - torso_1 = 55, torso_2 = 0, - decals_1 = 8, decals_2 = 2, - arms = 41, - pants_1 = 25, pants_2 = 0, - shoes_1 = 25, shoes_2 = 0, - helmet_1 = -1, helmet_2 = 0, - chain_1 = 0, chain_2 = 0, - ears_1 = 2, ears_2 = 0 - }, - female = { - tshirt_1 = 35, tshirt_2 = 0, - torso_1 = 48, torso_2 = 0, - decals_1 = 7, decals_2 = 2, - arms = 44, - pants_1 = 34, pants_2 = 0, - shoes_1 = 27, shoes_2 = 0, - helmet_1 = -1, helmet_2 = 0, - chain_1 = 0, chain_2 = 0, - ears_1 = 2, ears_2 = 0 - } - }, - - chef = { - male = { - tshirt_1 = 58, tshirt_2 = 0, - torso_1 = 55, torso_2 = 0, - decals_1 = 8, decals_2 = 3, - arms = 41, - pants_1 = 25, pants_2 = 0, - shoes_1 = 25, shoes_2 = 0, - helmet_1 = -1, helmet_2 = 0, - chain_1 = 0, chain_2 = 0, - ears_1 = 2, ears_2 = 0 - }, - female = { - tshirt_1 = 35, tshirt_2 = 0, - torso_1 = 48, torso_2 = 0, - decals_1 = 7, decals_2 = 3, - arms = 44, - pants_1 = 34, pants_2 = 0, - shoes_1 = 27, shoes_2 = 0, - helmet_1 = -1, helmet_2 = 0, - chain_1 = 0, chain_2 = 0, - ears_1 = 2, ears_2 = 0 - } - }, - - boss = {-- currently the same as chef + boss = { male = { tshirt_1 = 58, tshirt_2 = 0, torso_1 = 55, torso_2 = 0, diff --git a/esx_policejob.sql b/esx_policejob.sql index ca16562e..a5a8afaa 100644 --- a/esx_policejob.sql +++ b/esx_policejob.sql @@ -13,7 +13,7 @@ INSERT INTO `addon_inventory` (name, label, shared) VALUES ; INSERT INTO `jobs` (name, label) VALUES - ('police','LSPD') + ('police', 'LSPD') ; INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES diff --git a/localization/de_esx_policejob.sql b/localization/de_esx_policejob.sql index dee8b026..0eea7a4d 100644 --- a/localization/de_esx_policejob.sql +++ b/localization/de_esx_policejob.sql @@ -19,13 +19,12 @@ INSERT INTO `jobs` (name, label) VALUES INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES ('police',0,'recruit','Rekrut',20,'{}','{}'), ('police',1,'officer','Officier',40,'{}','{}'), - ('police',2,'sergeant','Sergent',40,'{}','{}'), - ('police',3,'lieutenant','Lieutenant',65,'{}','{}'), - ('police',4,'boss','Commandant',80,'{}','{}') + ('police',2,'sergeant','Sergent',60,'{}','{}'), + ('police',3,'lieutenant','Lieutenant',85,'{}','{}'), + ('police',4,'boss','Commandant',100,'{}','{}') ; CREATE TABLE `fine_types` ( - `id` int(11) NOT NULL AUTO_INCREMENT, `label` varchar(255) DEFAULT NULL, `amount` int(11) DEFAULT NULL, diff --git a/localization/en_esx_policejob.sql b/localization/en_esx_policejob.sql index 479c7bd4..4e32909c 100644 --- a/localization/en_esx_policejob.sql +++ b/localization/en_esx_policejob.sql @@ -25,7 +25,6 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ; CREATE TABLE `fine_types` ( - `id` int(11) NOT NULL AUTO_INCREMENT, `label` varchar(255) DEFAULT NULL, `amount` int(11) DEFAULT NULL, diff --git a/localization/fi_esx_policejob.sql b/localization/fi_esx_policejob.sql index dd51d4cf..0765c9e8 100644 --- a/localization/fi_esx_policejob.sql +++ b/localization/fi_esx_policejob.sql @@ -25,7 +25,6 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ; CREATE TABLE `fine_types` ( - `id` int(11) NOT NULL AUTO_INCREMENT, `label` varchar(255) DEFAULT NULL, `amount` int(11) DEFAULT NULL, diff --git a/localization/ko_esx_policejob.sql b/localization/ko_esx_policejob.sql index c3041914..365f1d32 100644 --- a/localization/ko_esx_policejob.sql +++ b/localization/ko_esx_policejob.sql @@ -25,7 +25,6 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ; CREATE TABLE `fine_types` ( - `id` int(11) NOT NULL AUTO_INCREMENT, `label` varchar(255) DEFAULT NULL, `amount` int(11) DEFAULT NULL, diff --git a/localization/sv_esx_policejob.sql b/localization/sv_esx_policejob.sql index d880d38e..7ba82bf0 100644 --- a/localization/sv_esx_policejob.sql +++ b/localization/sv_esx_policejob.sql @@ -18,14 +18,13 @@ INSERT INTO `jobs` (name, label) VALUES INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES ('police',0,'recruit','Aspirant',20,'{}','{}'), - ('police',1,'officer','Biträdande Rikspolischef',40,'{}','{}'), - ('police',2,'sergeant','Assistent',60,'{}','{}'), - ('police',3,'lieutenant','Inspektör',85,'{}','{}'), + ('police',1,'officer','Assistent',40,'{}','{}'), + ('police',2,'sergeant','Inspektör',60,'{}','{}'), + ('police',3,'lieutenant','Kommissarie',85,'{}','{}'), ('police',4,'boss','Rikspolischef',100,'{}','{}') ; CREATE TABLE `fine_types` ( - `id` int(11) NOT NULL AUTO_INCREMENT, `label` varchar(255) DEFAULT NULL, `amount` int(11) DEFAULT NULL, From 6ed2e1c4e7c54ce5fc979d815d35bda6241253f1 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 1 Feb 2020 13:02:23 +0100 Subject: [PATCH 2506/3224] Minor changes --- client/main.lua | 2 +- config.lua | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/main.lua b/client/main.lua index 489d4ae8..17a3db65 100644 --- a/client/main.lua +++ b/client/main.lua @@ -406,7 +406,7 @@ Citizen.CreateThread(function() local weaponHash = GetHashKey(weaponName) local weaponComponents = {} - if HasPedGotWeapon(playerPed, weaponHash, false) and weaponName ~= 'WEAPON_UNARMED' then + if HasPedGotWeapon(playerPed, weaponHash, false) then local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) for k2,v2 in ipairs(v.components) do diff --git a/config.lua b/config.lua index 5dfee80f..d3bf0edb 100644 --- a/config.lua +++ b/config.lua @@ -1,8 +1,8 @@ Config = {} Config.Locale = 'fr' -Config.Accounts = { 'bank', 'black_money' } -Config.AccountLabels = { bank = _U('bank'), black_money = _U('black_money') } +Config.Accounts = {'bank', 'black_money'} +Config.AccountLabels = {bank = _U('bank'), black_money = _U('black_money')} Config.EnableSocietyPayouts = false -- pay from the society account that the player is employed at? Requirement: esx_society Config.DisableWantedLevel = true From 71315bcd1756bf6ed39173003a73111215f5eab3 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 3 Feb 2020 11:12:55 +0100 Subject: [PATCH 2507/3224] Use async to limit paying rent --- README.md | 4 +++- config.lua | 6 ++---- fxmanifest.lua | 4 +++- server/main.lua | 40 ++++++++++++++++++++++++++-------------- 4 files changed, 34 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 37449fa6..8c230af9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # esx_property ### Requirements + +- [async](https://github.com/ESX-Org/async) - [instance](https://github.com/ESX-Org/instance) - [cron](https://github.com/ESX-Org/cron) - [esx_addonaccount](https://github.com/ESX-Org/esx_addonaccount) @@ -37,7 +39,7 @@ start esx_property ### License esx_property - own a property! -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. diff --git a/config.lua b/config.lua index 2666d3c2..f71a9871 100644 --- a/config.lua +++ b/config.lua @@ -4,9 +4,7 @@ Config.MarkerSize = {x = 1.5, y = 1.5, z = 1.0} Config.MarkerColor = {r = 102, g = 102, b = 204} Config.RoomMenuMarkerColor = {r = 102, g = 204, b = 102} Config.MarkerType = 1 -Config.Zones = {} -Config.Properties = {} -Config.EnablePlayerManagement = false -- If set to true you need esx_realestateagentjob -Config.Locale = 'fr' Config.Properties = {} +Config.EnablePlayerManagement = false -- If set to true you use esx_realestateagentjob +Config.Locale = 'fr' diff --git a/fxmanifest.lua b/fxmanifest.lua index 53d33fb4..1c060718 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -7,8 +7,9 @@ description 'ESX Property' version '1.0.4' server_scripts { - '@es_extended/locale.lua', + '@async/async.lua', '@mysql-async/lib/MySQL.lua', + '@es_extended/locale.lua', 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', @@ -36,6 +37,7 @@ client_scripts { } dependencies { + 'async', 'es_extended', 'instance', 'cron', diff --git a/server/main.lua b/server/main.lua index 2e0a6e5a..ef07a67a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -416,25 +416,37 @@ AddEventHandler('esx_property:removeOutfit', function(label) end) function PayRent(d, h, m) - MySQL.Async.fetchAll('SELECT * FROM owned_properties WHERE rented = 1', {}, function (result) + 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) for i=1, #result, 1 do - local xPlayer = ESX.GetPlayerFromIdentifier(result[i].owner) + table.insert(tasks, function(cb) + local xPlayer = ESX.GetPlayerFromIdentifier(result[i].owner) - -- message player if connected - if xPlayer then - xPlayer.removeAccountMoney('bank', result[i].price) - xPlayer.showNotification(_U('paid_rent', ESX.Math.GroupDigits(result[i].price))) - else -- pay rent either way - MySQL.Sync.execute('UPDATE users SET bank = bank - @bank WHERE identifier = @identifier', { - ['@bank'] = result[i].price, - ['@identifier'] = result[i].owner - }) - end + -- message player if connected + if xPlayer then + xPlayer.removeAccountMoney('bank', result[i].price) + xPlayer.showNotification(_U('paid_rent', ESX.Math.GroupDigits(result[i].price))) + else -- pay rent either way + MySQL.Sync.execute('UPDATE users SET bank = bank - @bank WHERE identifier = @identifier', { + ['@bank'] = result[i].price, + ['@identifier'] = result[i].owner + }) + end - TriggerEvent('esx_addonaccount:getSharedAccount', 'society_realestateagent', function(account) - account.addMoney(result[i].price) + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_realestateagent', function(account) + account.addMoney(result[i].price) + end) + + cb() end) end + + Async.parallelLimit(tasks, 5, function(results) end) + + local elapsedTime = os.clock() - timeStart + print(('[esx_property] [^2INFO^7] Paying rent cron job took %s seconds'):format(elapsedTime)) end) end From 897d60bf1359bb52f19d02c92bf1df56aa212e30 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 3 Feb 2020 11:25:19 +0100 Subject: [PATCH 2508/3224] Fixed taking random weapon, added missing weapon checks --- server/main.lua | 84 ++++++++++++++++++------------------------------- 1 file changed, 31 insertions(+), 53 deletions(-) diff --git a/server/main.lua b/server/main.lua index ef07a67a..c4e3773f 100644 --- a/server/main.lua +++ b/server/main.lua @@ -58,19 +58,19 @@ MySQL.ready(function() local isGateway = nil local roomMenu = nil - if properties[i].entering ~= nil then + if properties[i].entering then entering = json.decode(properties[i].entering) end - if properties[i].exit ~= nil then + if properties[i].exit then exit = json.decode(properties[i].exit) end - if properties[i].inside ~= nil then + if properties[i].inside then inside = json.decode(properties[i].inside) end - if properties[i].outside ~= nil then + if properties[i].outside then outside = json.decode(properties[i].outside) end @@ -92,7 +92,7 @@ MySQL.ready(function() isGateway = true end - if properties[i].room_menu ~= nil then + if properties[i].room_menu then roomMenu = json.decode(properties[i].room_menu) end @@ -201,19 +201,15 @@ end) RegisterServerEvent('esx_property:getItem') AddEventHandler('esx_property:getItem', function(owner, type, item, count) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) + local xPlayer = ESX.GetPlayerFromId(source) local xPlayerOwner = ESX.GetPlayerFromIdentifier(owner) if type == 'item_standard' then - - TriggerEvent('esx_addoninventory:getInventory', 'property', xPlayerOwner.identifier, function(inventory) local inventoryItem = inventory.getItem(item) -- is there enough in the property? if count > 0 and inventoryItem.count >= count then - -- can the player carry the said amount of x item? if xPlayer.canCarryItem(item, count) then inventory.removeItem(item, count) @@ -226,52 +222,38 @@ AddEventHandler('esx_property:getItem', function(owner, type, item, count) xPlayer.showNotification(_U('not_enough_in_property')) end end) - elseif type == 'item_account' then - TriggerEvent('esx_addonaccount:getAccount', 'property_' .. item, xPlayerOwner.identifier, function(account) - local roomAccountMoney = account.money - - if roomAccountMoney >= count then + if account.money >= count then account.removeMoney(count) xPlayer.addAccountMoney(item, count) else xPlayer.showNotification(_U('amount_invalid')) end end) - elseif type == 'item_weapon' then - TriggerEvent('esx_datastore:getDataStore', 'property', xPlayerOwner.identifier, function(store) local storeWeapons = store.get('weapons') or {} - local weaponName = nil - local ammo = nil + local weapon = storeWeapons[data.current.count] -- count is the index - for i=1, #storeWeapons, 1 do - if storeWeapons[i].name == item then - weaponName = storeWeapons[i].name - ammo = storeWeapons[i].ammo + if weapon then + if not xPlayer.hasWeapon(weaponName) then + table.remove(storeWeapons, data.current.count) + store.set('weapons', storeWeapons) - table.remove(storeWeapons, i) - break + xPlayer.addWeapon(weapon.name, weapon.ammo) end end - - store.set('weapons', storeWeapons) - xPlayer.addWeapon(weaponName, ammo) end) - end end) RegisterServerEvent('esx_property:putItem') AddEventHandler('esx_property:putItem', function(owner, type, item, count) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) + local xPlayer = ESX.GetPlayerFromId(source) local xPlayerOwner = ESX.GetPlayerFromIdentifier(owner) if type == 'item_standard' then - local playerItemCount = xPlayer.getInventoryItem(item).count if playerItemCount >= count and count > 0 then @@ -283,12 +265,8 @@ AddEventHandler('esx_property:putItem', function(owner, type, item, count) else xPlayer.showNotification(_U('invalid_quantity')) end - elseif type == 'item_account' then - - local playerAccountMoney = xPlayer.getAccount(item).money - - if playerAccountMoney >= count and count > 0 then + if xPlayer.getAccount(item).money >= count and count > 0 then xPlayer.removeAccountMoney(item, count) TriggerEvent('esx_addonaccount:getAccount', 'property_' .. item, xPlayerOwner.identifier, function(account) @@ -297,34 +275,34 @@ AddEventHandler('esx_property:putItem', function(owner, type, item, count) else xPlayer.showNotification(_U('amount_invalid')) end - elseif type == 'item_weapon' then - - TriggerEvent('esx_datastore:getDataStore', 'property', xPlayerOwner.identifier, function(store) - local storeWeapons = store.get('weapons') or {} - - table.insert(storeWeapons, { - name = item, - ammo = count - }) - - store.set('weapons', storeWeapons) + if xPlayer.hasWeapon(item) then xPlayer.removeWeapon(item) - end) + TriggerEvent('esx_datastore:getDataStore', 'property', xPlayerOwner.identifier, function(store) + local storeWeapons = store.get('weapons') or {} + + table.insert(storeWeapons, { + name = item, + ammo = count + }) + + store.set('weapons', storeWeapons) + end) + end end end) ESX.RegisterServerCallback('esx_property:getOwnedProperties', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.fetchAll('SELECT * FROM owned_properties WHERE owner = @owner', { + MySQL.Async.fetchAll('SELECT name FROM owned_properties WHERE owner = @owner', { ['@owner'] = xPlayer.identifier - }, function(ownedProperties) + }, function(result) local properties = {} - for i=1, #ownedProperties, 1 do - table.insert(properties, ownedProperties[i].name) + for i=1, #result, 1 do + table.insert(properties, result[i].name) end cb(properties) From 96c1ab491f924fc7e454f26eeeb45d07e475ded1 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 3 Feb 2020 13:19:55 +0100 Subject: [PATCH 2509/3224] Implemented pay when selling property, added prices to menu and more (desc) - Improved dialogs, differnet for owning / renting - Updated locale names - Get half money back when selling - Added configurable rent & sell prices in config --- client/main.lua | 80 +++++++++++++++++++++++++------------------------ config.lua | 21 ++++++++----- locales/br.lua | 17 ++++++----- locales/de.lua | 17 ++++++----- locales/en.lua | 21 ++++++------- locales/es.lua | 17 ++++++----- locales/fi.lua | 19 ++++++------ locales/fr.lua | 17 ++++++----- locales/pl.lua | 19 ++++++------ locales/sv.lua | 25 ++++++++-------- server/main.lua | 40 +++++++++++++++---------- 11 files changed, 159 insertions(+), 134 deletions(-) diff --git a/client/main.lua b/client/main.lua index 90c5e60e..29b19aa1 100644 --- a/client/main.lua +++ b/client/main.lua @@ -17,9 +17,9 @@ AddEventHandler('esx:playerLoaded', function(xPlayer) CreateBlips() end) - ESX.TriggerServerCallback('esx_property:getOwnedProperties', function(ownedProperties) - for i=1, #ownedProperties, 1 do - SetPropertyOwned(ownedProperties[i], true) + ESX.TriggerServerCallback('esx_property:getOwnedProperties', function(result) + for k,v in ipairs(result) do + SetPropertyOwned(v.name, true, v.rented) end end) end) @@ -30,9 +30,9 @@ AddEventHandler('esx_property:sendProperties', function(properties) Config.Properties = properties CreateBlips() - ESX.TriggerServerCallback('esx_property:getOwnedProperties', function(ownedProperties) - for i=1, #ownedProperties, 1 do - SetPropertyOwned(ownedProperties[i], true) + ESX.TriggerServerCallback('esx_property:getOwnedProperties', function(result) + for k,v in ipairs(result) do + SetPropertyOwned(v.name, true, v.rented) end end) end) @@ -168,7 +168,7 @@ function ExitProperty(name) end) end -function SetPropertyOwned(name, owned) +function SetPropertyOwned(name, owned, rented) local property = GetProperty(name) local entering = nil local enteringName = nil @@ -183,7 +183,7 @@ function SetPropertyOwned(name, owned) end if owned then - OwnedProperties[name] = true + OwnedProperties[name] = rented RemoveBlip(Blips[enteringName]) Blips[enteringName] = AddBlipForCoord(entering.x, entering.y, entering.z) @@ -224,7 +224,7 @@ function SetPropertyOwned(name, owned) end function PropertyIsOwned(property) - return OwnedProperties[property.name] == true + return OwnedProperties[property.name] ~= nil end function OpenPropertyMenu(property) @@ -233,16 +233,24 @@ function OpenPropertyMenu(property) if PropertyIsOwned(property) then table.insert(elements, {label = _U('enter'), value = 'enter'}) + -- add move out if not Config.EnablePlayerManagement then - table.insert(elements, {label = _U('leave'), value = 'leave'}) + local leaveLabel = _U('move_out') + + if not OwnedProperties[property.name] then + leaveLabel = _U('move_out_sold', ESX.Math.GroupDigits(ESX.Math.Round(property.price / Config.SellModifier))) + end + + table.insert(elements, {label = leaveLabel, value = 'leave'}) end else if not Config.EnablePlayerManagement then - table.insert(elements, {label = _U('buy'), value = 'buy'}) - table.insert(elements, {label = _U('rent'), value = 'rent'}) - end + table.insert(elements, {label = _U('buy', ESX.Math.GroupDigits(property.price)), value = 'buy'}) - table.insert(elements, {label = _U('visit'), value = 'visit'}) + -- display rent price + local rent = ESX.Math.Round(property.price / Config.RentModifier) + table.insert(elements, {label = _U('rent', ESX.Math.GroupDigits(rent)), value = 'rent'}) + end end ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'property', { @@ -260,8 +268,6 @@ function OpenPropertyMenu(property) TriggerServerEvent('esx_property:buyProperty', property.name) elseif data.current.value == 'rent' then TriggerServerEvent('esx_property:rentProperty', property.name) - elseif data.current.value == 'visit' then - TriggerEvent('instance:create', 'property', {property = property.name, owner = ESX.GetPlayerData().identifier}) end end, function(data, menu) menu.close() @@ -276,7 +282,6 @@ function OpenGatewayMenu(property) if Config.EnablePlayerManagement then OpenGatewayOwnedPropertiesMenu(gatewayProperties) else - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'gateway', { title = property.name, align = 'top-left', @@ -301,7 +306,7 @@ end function OpenGatewayOwnedPropertiesMenu(property) local gatewayProperties = GetGatewayProperties(property) - local elements = {} + local elements = {} for i=1, #gatewayProperties, 1 do if PropertyIsOwned(gatewayProperties[i]) then @@ -318,10 +323,7 @@ function OpenGatewayOwnedPropertiesMenu(property) elements = elements }, function(data, menu) menu.close() - - local elements = { - {label = _U('enter'), value = 'enter'} - } + local elements = {{label = _U('enter'), value = 'enter'}} if not Config.EnablePlayerManagement then table.insert(elements, {label = _U('leave'), value = 'leave'}) @@ -350,14 +352,15 @@ end function OpenGatewayAvailablePropertiesMenu(property) local gatewayProperties = GetGatewayProperties(property) - local elements = {} + local elements = {} for i=1, #gatewayProperties, 1 do if not PropertyIsOwned(gatewayProperties[i]) then table.insert(elements, { - label = gatewayProperties[i].label .. ' $' .. ESX.Math.GroupDigits(gatewayProperties[i].price), + label = gatewayProperties[i].label, value = gatewayProperties[i].name, - price = gatewayProperties[i].price + buyPrice = gatewayProperties[i].price, + rentPrice = ESX.Math.Round(gatewayProperties[i].price / Config.RentModifier) }) end end @@ -367,24 +370,20 @@ function OpenGatewayAvailablePropertiesMenu(property) align = 'top-left', elements = elements }, function(data, menu) - menu.close() - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'gateway_available_properties_actions', { title = property.label .. ' - ' .. _U('available_properties'), align = 'top-left', elements = { - {label = _U('buy'), value = 'buy'}, - {label = _U('rent'), value = 'rent'}, - {label = _U('visit'), value = 'visit'} + {label = _U('buy', ESX.Math.GroupDigits(data.current.buyPrice)), value = 'buy'}, + {label = _U('rent', ESX.Math.GroupDigits(data.current.rentPrice)), value = 'rent'} }}, function(data2, menu2) + menu.close() menu2.close() if data2.current.value == 'buy' then TriggerServerEvent('esx_property:buyProperty', data.current.value) elseif data2.current.value == 'rent' then TriggerServerEvent('esx_property:rentProperty', data.current.value) - elseif data2.current.value == 'visit' then - TriggerEvent('instance:create', 'property', {property = data.current.value, owner = ESX.GetPlayerData().identifier}) end end, function(data2, menu2) menu2.close() @@ -545,7 +544,7 @@ function OpenRoomInventoryMenu(property, owner) label = ESX.GetWeaponLabel(weapon.name) .. ' [' .. weapon.ammo .. ']', type = 'item_weapon', value = weapon.name, - ammo = weapon.ammo + index = i }) end @@ -558,7 +557,7 @@ function OpenRoomInventoryMenu(property, owner) if data.current.type == 'item_weapon' then menu.close() - TriggerServerEvent('esx_property:getItem', owner, data.current.type, data.current.value, data.current.ammo) + TriggerServerEvent('esx_property:getItem', owner, data.current.type, data.current.value, data.current.index) ESX.SetTimeout(300, function() OpenRoomInventoryMenu(property, owner) end) @@ -684,7 +683,7 @@ AddEventHandler('playerSpawned', function() for i=1, #property.ipls, 1 do RequestIpl(property.ipls[i]) - + while not IsIplActive(property.ipls[i]) do Citizen.Wait(0) end @@ -713,8 +712,8 @@ AddEventHandler('esx_property:getGateway', function(property, cb) end) RegisterNetEvent('esx_property:setPropertyOwned') -AddEventHandler('esx_property:setPropertyOwned', function(name, owned) - SetPropertyOwned(name, owned) +AddEventHandler('esx_property:setPropertyOwned', function(name, owned, rented) + SetPropertyOwned(name, owned, rented) end) RegisterNetEvent('instance:onCreate') @@ -779,6 +778,8 @@ AddEventHandler('esx_property:hasExitedMarker', function(name, part) CurrentAction = nil end) +local index = 0 +RegisterCommand('s', function(a, b, c) -- Enter / Exit marker events & Draw markers Citizen.CreateThread(function() while true do @@ -797,6 +798,7 @@ Citizen.CreateThread(function() if distance < Config.DrawDistance then DrawMarker(Config.MarkerType, property.entering.x, property.entering.y, property.entering.z, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Config.MarkerSize.x, Config.MarkerSize.y, Config.MarkerSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, nil, nil, false) + ESX.Game.Utils.DrawText3D(property.entering, property.name, 2) letSleep = false end @@ -824,7 +826,7 @@ Citizen.CreateThread(function() end -- Room menu - if property.roomMenu and hasChest and not property.disabled then + if property.roomMenu then local distance = GetDistanceBetweenCoords(coords, property.roomMenu.x, property.roomMenu.y, property.roomMenu.z, true) if distance < Config.DrawDistance then @@ -865,7 +867,7 @@ Citizen.CreateThread(function() Citizen.Wait(0) if CurrentAction then - ESX.ShowHelpNotification(CurrentActionMsg) + --ESX.ShowHelpNotification(CurrentActionMsg) if IsControlJustReleased(0, 38) then if CurrentAction == 'property_menu' then diff --git a/config.lua b/config.lua index f71a9871..d1888658 100644 --- a/config.lua +++ b/config.lua @@ -1,10 +1,15 @@ -Config = {} -Config.DrawDistance = 100 -Config.MarkerSize = {x = 1.5, y = 1.5, z = 1.0} -Config.MarkerColor = {r = 102, g = 102, b = 204} -Config.RoomMenuMarkerColor = {r = 102, g = 204, b = 102} -Config.MarkerType = 1 +Config = {} + +Config.DrawDistance = 100 +Config.MarkerSize = {x = 1.5, y = 1.5, z = 1.0} +Config.MarkerColor = {r = 102, g = 102, b = 204} +Config.RoomMenuMarkerColor = {r = 102, g = 204, b = 102} +Config.MarkerType = 1 + +Config.RentModifier = 200 -- rent price: / (rounded) +Config.SellModifier = 2 -- sell price: / (rounded) + +Config.Properties = {} -Config.Properties = {} Config.EnablePlayerManagement = false -- If set to true you use esx_realestateagentjob -Config.Locale = 'fr' +Config.Locale = 'fr' diff --git a/locales/br.lua b/locales/br.lua index 152bdacb..98d5e412 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -4,10 +4,14 @@ Locales['br'] = { ['free_prop'] = 'Propriedade a Venda', ['property'] = 'Propriedade', ['enter'] = 'Entrar', - ['leave'] = 'Sair', - ['buy'] = 'Comprar', - ['rent'] = 'Alugar', - ['visit'] = 'Visitar', + ['move_out'] = 'move out from property', + ['move_out_sold'] = 'sell property for $%s', + ['moved_out'] = 'you moved out and do no longer rent the property.', + ['moved_out_sold'] = 'you have sold the property for ~g~$%s~s~', + ['buy'] = 'buy property for $%s', + ['buy_for'] = 'você comprou uma propriedade por ~g~$%s~s~', + ['rent'] = 'rent property for $%s / week', + ['rent_for'] = 'você alugou uma propriedade por ~g~$%s~s~', ['press_to_menu'] = 'Pressione ~INPUT_CONTEXT~ para acessar o menu', ['owned_properties'] = 'Propriedades adquiridas', ['available_properties'] = 'Propriedades disponíveis', @@ -19,14 +23,11 @@ Locales['br'] = { ['remove_object'] = 'Remover objeto', ['deposit_object'] = 'Depositar objeto', ['invite'] = 'Convidar', - ['dirty_money'] = 'Dinheiro sujo: $%s', + ['dirty_money'] = 'Dinheiro sujo: $%s', ['inventory'] = 'Inventário', ['amount'] = 'valor?', ['amount_invalid'] = 'quantidade inválida', ['press_to_exit'] = 'Pressione ~INPUT_CONTEXT~ para sair da propriedade', - ['rented_for'] = 'Você alugou uma propriedade por ~g~$%s~s~', - ['purchased_for'] = 'Você comprou uma propriedade por ~g~$%s~s~', - ['made_property'] = 'Você criou uma propriedade', ['not_enough'] = 'Você não tem dinheiro suficiente', ['invalid_quantity'] = 'Quantidade inválida', ['paid_rent'] = 'Você ~g~pagou~s~ seu aluguel: ~g~$%s~s~', diff --git a/locales/de.lua b/locales/de.lua index cd4f3cb5..9373025a 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -4,10 +4,14 @@ Locales['de'] = { ['free_prop'] = 'Kostenlose Immobilie', ['property'] = 'Immobilie', ['enter'] = 'Eintreten', - ['leave'] = 'Verlassen', - ['buy'] = 'Kaufen', - ['rent'] = 'Mieten', - ['visit'] = 'Ansehen', + ['move_out'] = 'move out from property', + ['move_out_sold'] = 'sell property for $%s', + ['moved_out'] = 'you moved out and do no longer rent the property.', + ['moved_out_sold'] = 'you have sold the property for ~g~$%s~s~', + ['buy'] = 'buy property for $%s', + ['buy_for'] = 'you purchased a property for ~g~$%s~s~', + ['rent'] = 'rent property for $%s / week', + ['rent_for'] = 'you rented a property for ~g~$%s~s~ / week, payment is automatic', ['press_to_menu'] = 'Drücke ~INPUT_CONTEXT~ um das Menü zu öffnen', ['owned_properties'] = 'Gekaufte Immobilien', ['available_properties'] = 'Verfügbare Immobilien', @@ -19,14 +23,13 @@ Locales['de'] = { ['remove_object'] = 'Objekt nehmen', ['deposit_object'] = 'Objekt deponieren', ['invite'] = 'Einladen', - ['dirty_money'] = 'Schwarzgeld: $%s', + ['dirty_money'] = 'Schwarzgeld: $%s', ['inventory'] = 'Inventar', ['amount'] = 'Anzahlt?', ['amount_invalid'] = 'Ungültiger Wert', ['press_to_exit'] = 'Drücke ~INPUT_CONTEXT~ um die Immobilie zu verlassen', - ['rented_for'] = 'Du hast eine Immobilie gemietet ~g~$%s~s~', + ['rent_for'] = 'Du hast eine Immobilie gemietet ~g~$%s~s~', ['purchased_for'] = 'Du hast eine Immobilie gekauft ~g~$%s~s~', - ['made_property'] = 'Du hast eine Immobilie gemacht', ['not_enough'] = 'du hast nicht genug Geld', ['invalid_quantity'] = 'Ungültiger Betrag', ['paid_rent'] = 'du ~g~bezahlst~s~ deine Miete: ~g~$%s~s~', diff --git a/locales/en.lua b/locales/en.lua index b1f86229..75d34bda 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -4,11 +4,15 @@ Locales['en'] = { ['free_prop'] = 'property For Sale', ['property'] = 'property', ['enter'] = 'enter', - ['leave'] = 'sell', - ['buy'] = 'buy', - ['rent'] = 'rent', - ['visit'] = 'visit', - ['press_to_menu'] = 'press ~INPUT_CONTEXT~ to access the menu', + ['move_out'] = 'move out from property', + ['move_out_sold'] = 'sell property for $%s', + ['moved_out'] = 'you moved out and do no longer rent the property.', + ['moved_out_sold'] = 'you have sold the property for ~g~$%s~s~', + ['buy'] = 'buy property for $%s', + ['buy_for'] = 'you purchased a property for ~g~$%s~s~', + ['rent'] = 'rent property for $%s / week', + ['rent_for'] = 'you rented a property for ~g~$%s~s~ / week, payment is automatic', + ['press_to_menu'] = 'press ~INPUT_CONTEXT~ to access the ~y~Property Menu~s~.', ['owned_properties'] = 'acquired properties', ['available_properties'] = 'available properties', ['invite_player'] = 'invite a player', @@ -19,17 +23,14 @@ Locales['en'] = { ['remove_object'] = 'remove object', ['deposit_object'] = 'deposit object', ['invite'] = 'invite', - ['dirty_money'] = 'dirty money: $%s', + ['dirty_money'] = 'dirty money: $%s', ['inventory'] = 'inventory', ['amount'] = 'amount?', ['amount_invalid'] = 'invalid amount', ['press_to_exit'] = 'press ~INPUT_CONTEXT~ to exit the property', - ['rented_for'] = 'you rented a property for ~g~$%s~s~', - ['purchased_for'] = 'you purchased a property for ~g~$%s~s~', - ['made_property'] = 'you have made a property', ['not_enough'] = 'you do not have enough money', ['invalid_quantity'] = 'invalid quantity', ['paid_rent'] = 'you ~g~paid~s~ your rent: ~g~$%s~s~', ['not_enough_in_property'] = 'there\'s not enough of ~r~that item~s~ in the property!', ['player_cannot_hold'] = 'you do ~r~not~s~ have enough ~y~free space~s~ in your inventory!', -} \ No newline at end of file +} diff --git a/locales/es.lua b/locales/es.lua index c2477884..387ff6c0 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -4,10 +4,14 @@ Locales['es'] = { ['free_prop'] = 'Propiedad libre', ['property'] = 'Propiedad', ['enter'] = 'Entrar', - ['leave'] = 'Salir', - ['buy'] = 'Comprar', - ['rent'] = 'Alquilar', - ['visit'] = 'Visitar', + ['move_out'] = 'move out from property', + ['move_out_sold'] = 'sell property for €%s', + ['moved_out'] = 'you moved out and do no longer rent the property.', + ['moved_out_sold'] = 'you have sold the property for ~g~€%s~s~', + ['buy'] = 'buy property for €%s', + ['buy_for'] = 'has comprado una propiedad por ~g~€%s~s~', + ['rent'] = 'rent property for €%s / week', + ['rent_for'] = 'has alquilado una propiedad por ~g~€%s~s~', ['press_to_menu'] = 'Presionar ~INPUT_CONTEXT~ para acceder al menú', ['owned_properties'] = 'Propiedad adquirida', ['available_properties'] = 'Propiedades disponibles', @@ -19,14 +23,11 @@ Locales['es'] = { ['remove_object'] = 'Retirar objeto', ['deposit_object'] = 'Depositar objeto', ['invite'] = 'Invitar', - ['dirty_money'] = 'Dinero sucio: €%s', + ['dirty_money'] = 'Dinero sucio: €%s', ['inventory'] = 'Inventario', ['amount'] = '¿Cantidad?', ['amount_invalid'] = 'Cantidad inválida', ['press_to_exit'] = 'Presione ~INPUT_CONTEXT~ para salir de la propiedad', - ['rented_for'] = 'Has alquilado una propiedad por ~g~€%s~s~', - ['purchased_for'] = 'Has comprado una propiedad por ~g~€%s~s~', - ['made_property'] = 'Ha hecho una propiedad', ['not_enough'] = 'n\'No tiene suficiente d\'dinero', ['invalid_quantity'] = 'Cantidad inválida', ['paid_rent'] = 'Has ~g~pagado~s~ por el alquiler: ~g~€%s~s~', diff --git a/locales/fi.lua b/locales/fi.lua index fd958a43..ffebd828 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -4,10 +4,14 @@ Locales['fi'] = { ['free_prop'] = 'vapaa kiinteistö', ['property'] = 'asunto', ['enter'] = 'sisään', - ['leave'] = 'myy', - ['buy'] = 'osta', - ['rent'] = 'vuokraa', - ['visit'] = 'vieraile', + ['move_out'] = 'move out from property', + ['move_out_sold'] = 'sell property for $%s', + ['moved_out'] = 'you moved out and do no longer rent the property.', + ['moved_out_sold'] = 'you have sold the property for ~g~$%s~s~', + ['buy'] = 'buy property for $%s', + ['buy_for'] = 'sinä ostit kiinteistön hintaan ~g~$%s~s~', + ['rent'] = 'rent property for $%s / week', + ['rent_for'] = 'sinä vuokrasit kiinteistön hintaan ~g~$%s~s~', ['press_to_menu'] = 'paina ~INPUT_CONTEXT~ avataksesi talon valikko', ['owned_properties'] = 'omistuksessa olevat asunnot', ['available_properties'] = 'vapaat asunnot', @@ -19,17 +23,14 @@ Locales['fi'] = { ['remove_object'] = 'poista esine', ['deposit_object'] = 'talleta esine', ['invite'] = 'kutsu', - ['dirty_money'] = 'likainen raha: $%s', + ['dirty_money'] = 'likainen raha: $%s', ['inventory'] = 'reppu', ['amount'] = 'määrä?', ['amount_invalid'] = 'virheellinen määrä', ['press_to_exit'] = 'paina ~INPUT_CONTEXT~ poistuaksesi kiinteistöstä', - ['rented_for'] = 'sinä vuokrasit kiinteistön hintaan ~g~$%s~s~', - ['purchased_for'] = 'sinä ostit kiinteistön hintaan ~g~$%s~s~', - ['made_property'] = 'sinä teit kiinteistön', ['not_enough'] = 'sinulla ei ole tarpeeksi rahaa', ['invalid_quantity'] = 'virheellinen määrä', ['paid_rent'] = 'sinä ~g~maksoit~s~ vuokraasi: ~g~$%s~s~', ['not_enough_in_property'] = 'täällä ei ole enempää ~r~tätä itemiä~s~ tässä kiinteistössä!', ['player_cannot_hold'] = 'sinulla ~r~ei ole~s~ tarpeeksi ~y~vapaata tilaa~s~ repussasi!', -} \ No newline at end of file +} diff --git a/locales/fr.lua b/locales/fr.lua index 4aa55cf7..ad663e14 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -4,10 +4,14 @@ Locales['fr'] = { ['free_prop'] = 'propriété libre', ['property'] = 'propriété', ['enter'] = 'entrer', - ['leave'] = 'rendre', - ['buy'] = 'acheter', - ['rent'] = 'louer', - ['visit'] = 'visiter', + ['move_out'] = 'move out from property', + ['move_out_sold'] = 'sell property for $%s', + ['moved_out'] = 'you moved out and do no longer rent the property.', + ['moved_out_sold'] = 'you have sold the property for ~g~$%s~s~', + ['buy'] = 'buy property for $%s', + ['buy_for'] = 'vous avez acheté une propriété pour ~g~$%s~s~', + ['rent'] = 'rent property for $%s / week', + ['rent_for'] = 'vous avez loué une propriété pour ~g~$%s~s~', ['press_to_menu'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder au menu', ['owned_properties'] = 'propriétés acquises', ['available_properties'] = 'propriétés disponibles', @@ -19,14 +23,11 @@ Locales['fr'] = { ['remove_object'] = 'retirer objet', ['deposit_object'] = 'déposer objet', ['invite'] = 'inviter', - ['dirty_money'] = 'argent sale: $%s', + ['dirty_money'] = 'argent sale: $%s', ['inventory'] = 'inventaire', ['amount'] = 'quantité ?', ['amount_invalid'] = 'montant invalide', ['press_to_exit'] = 'appuyez sur ~INPUT_CONTEXT~ pour sortir de la propriété', - ['rented_for'] = 'vous avez loué une propriété pour ~g~$%s~s~', - ['purchased_for'] = 'vous avez acheté une propriété pour ~g~$%s~s~', - ['made_property'] = 'vous avez rendu une propriété', ['not_enough'] = 'vous n\'avez pas assez d\'argent', ['invalid_quantity'] = 'quantité invalide', ['paid_rent'] = 'vous avez ~g~payé~s~ votre loyer: ~g~$%s~s~', diff --git a/locales/pl.lua b/locales/pl.lua index 0c6fe04d..985fcb2f 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -4,10 +4,14 @@ Locales['pl'] = { ['free_prop'] = 'wolne mieszkanie', ['property'] = 'mieszkanie', ['enter'] = 'wejdz', - ['leave'] = 'sprzedzaj', - ['buy'] = 'kup', - ['rent'] = 'wynajmij', - ['visit'] = 'odwiedz', + ['move_out'] = 'move out from property', + ['move_out_sold'] = 'sell property for $%s', + ['moved_out'] = 'you moved out and do no longer rent the property.', + ['moved_out_sold'] = 'you have sold the property for ~g~$%s~s~', + ['buy'] = 'buy property for $%s', + ['buy_for'] = 'kupiłeś/aś mieszkanie za ~g~$%s~s~', + ['rent'] = 'rent property for $%s / week', + ['rent_for'] = 'wynająłeś/aś mieszkanie za ~g~$%s~s~', ['press_to_menu'] = 'wciśnij ~INPUT_CONTEXT~ aby otworzyć menu', ['owned_properties'] = 'twoje mieszkania', ['available_properties'] = 'dostępne mieszkania', @@ -19,17 +23,14 @@ Locales['pl'] = { ['remove_object'] = 'usuń objekt', ['deposit_object'] = 'deponuj objekt', ['invite'] = 'zaproś', - ['dirty_money'] = 'brudne pieniądze: $%s', + ['dirty_money'] = 'brudne pieniądze: $%s', ['inventory'] = 'ekwipunek', ['amount'] = 'suma?', ['amount_invalid'] = 'nieprawidłowa suma', ['press_to_exit'] = 'wciśnij ~INPUT_CONTEXT~ aby wyjść z mieszkania', - ['rented_for'] = 'wynająłeś/aś mieszkanie za ~g~$%s~s~', - ['purchased_for'] = 'kupiłeś/aś mieszkanie za ~g~$%s~s~', - ['made_property'] = 'stworzyłeś/aś mieszkanie', ['not_enough'] = 'nie posiadasz wystarczająco pieniędzy', ['invalid_quantity'] = 'nieprawidłowa ilość', ['paid_rent'] = '~g~zapłaciłeś/aś~s~ za wynajem: ~g~$%s~s~', ['not_enough_in_property'] = 'nie ma wystarczająco ~r~tego przedmiotu~s~ w mieszkaniu!', ['player_cannot_hold'] = '~r~nie masz~s~ wystarczająco ~y~wolnego~s~ miejsca w ekwipunku!', -} \ No newline at end of file +} diff --git a/locales/sv.lua b/locales/sv.lua index 0eacaf54..bf3a6d07 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -4,14 +4,18 @@ Locales['sv'] = { ['free_prop'] = 'ledig fastighet', ['property'] = 'fastighet', ['enter'] = 'gå in', - ['leave'] = 'sälj', - ['buy'] = 'köp', - ['rent'] = 'hyr', - ['visit'] = 'besök', + ['move_out'] = 'flytta ut', + ['move_out_sold'] = 'sälj fastighet för %s SEK', + ['moved_out'] = 'du har flyttat ut och hyr inte fastigheten längre', + ['moved_out_sold'] = 'du har sålt fastigheten för ~g~%s SEK~s~', + ['buy'] = 'köp fastighet för %s SEK', + ['buy_for'] = 'du hyrde en fastighet för ~g~%s SEK~s~ / vecka, betalning sker automatiskt', + ['rent'] = 'hyr fastighet för %s SEK / vecka', + ['rent_for'] = 'du köpte en fastighet för ~g~%s SEK~s~', ['press_to_menu'] = 'tryck ~INPUT_CONTEXT~ för att komma åt menyn', - ['owned_properties'] = 'upptagna fastigheter', - ['available_properties'] = 'lediga fastigheter', - ['invite_player'] = 'bjud in granne', + ['owned_properties'] = 'ägda fastigheter', + ['available_properties'] = 'fastigheter till salu', + ['invite_player'] = 'bjud in spelare', ['you_invited'] = 'du bjöd in ~y~%s~s~ till din fastighet', ['player_clothes'] = 'Kläder', ['remove_cloth'] = 'ta bort klädstil', @@ -19,17 +23,14 @@ Locales['sv'] = { ['remove_object'] = 'ta ut objekt', ['deposit_object'] = 'lagra objekt', ['invite'] = 'bjud in', - ['dirty_money'] = 'smutsiga pengar: %s SEK', + ['dirty_money'] = 'smutsiga pengar: %s SEK', ['inventory'] = 'inventory', ['amount'] = 'summa?', ['amount_invalid'] = 'ogiltlig summa', ['press_to_exit'] = 'tryck ~INPUT_CONTEXT~ för att lämna fastigheten', - ['rented_for'] = 'du hyrde en fastighet för: ~g~%s SEK~s~', - ['purchased_for'] = 'du köpte en fastighet för: ~g~%s SEK~s~', - ['made_property'] = 'you have made a property', ['not_enough'] = 'du har inte tillräckligt med pengar!', ['invalid_quantity'] = 'ogiltlig mängd', ['paid_rent'] = 'du ~y~betalade~s~ din hyra: ~g~%s SEK~s~', ['not_enough_in_property'] = 'det finns ~r~inte~s~ tillräckligt av ~r~det objektet~s~ i fastigheten!', ['player_cannot_hold'] = 'du har ~r~inte~s~ tillräckligt med ~y~utrymme~s~ för att hålla det!', -} \ No newline at end of file +} diff --git a/server/main.lua b/server/main.lua index c4e3773f..1ef54c8d 100644 --- a/server/main.lua +++ b/server/main.lua @@ -20,7 +20,7 @@ function SetPropertyOwned(name, price, rented, owner) local xPlayer = ESX.GetPlayerFromIdentifier(owner) if xPlayer then - TriggerClientEvent('esx_property:setPropertyOwned', xPlayer.source, name, true) + TriggerClientEvent('esx_property:setPropertyOwned', xPlayer.source, name, true, rented) if rented then xPlayer.showNotification(_U('rented_for', ESX.Math.GroupDigits(price))) @@ -32,15 +32,29 @@ function SetPropertyOwned(name, price, rented, owner) end function RemoveOwnedProperty(name, owner) - MySQL.Async.execute('DELETE FROM owned_properties WHERE name = @name AND owner = @owner', { + MySQL.Async.fetchAll('SELECT id, rented, price FROM owned_properties WHERE name = @name AND owner = @owner', { ['@name'] = name, ['@owner'] = owner - }, function(rowsChanged) - local xPlayer = ESX.GetPlayerFromIdentifier(owner) + }, function(result) + if result[1] then + MySQL.Async.execute('DELETE FROM owned_properties WHERE id = @id', { + ['@id'] = result[1].id + }, function(rowsChanged) + local xPlayer = ESX.GetPlayerFromIdentifier(owner) - if xPlayer then - TriggerClientEvent('esx_property:setPropertyOwned', xPlayer.source, name, false) - xPlayer.showNotification(_U('made_property')) + if xPlayer then + xPlayer.triggerEvent('esx_property:setPropertyOwned', name, false) + + if result[1].rented == 1 then + xPlayer.showNotification(_U('moved_out')) + else + local sellPrice = ESX.Math.Round(result[1].price / Config.SellModifier) + + xPlayer.showNotification(_U('moved_out_sold', ESX.Math.GroupDigits(sellPrice))) + xPlayer.addAccountMoney('bank', sellPrice) + end + end + end) end end) end @@ -152,7 +166,7 @@ RegisterServerEvent('esx_property:rentProperty') AddEventHandler('esx_property:rentProperty', function(propertyName) local xPlayer = ESX.GetPlayerFromId(source) local property = GetProperty(propertyName) - local rent = ESX.Math.Round(property.price / 200) + local rent = ESX.Math.Round(property.price / Config.RentModifier) SetPropertyOwned(propertyName, rent, true, xPlayer.identifier) end) @@ -296,16 +310,10 @@ end) ESX.RegisterServerCallback('esx_property:getOwnedProperties', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.fetchAll('SELECT name FROM owned_properties WHERE owner = @owner', { + MySQL.Async.fetchAll('SELECT name, rented FROM owned_properties WHERE owner = @owner', { ['@owner'] = xPlayer.identifier }, function(result) - local properties = {} - - for i=1, #result, 1 do - table.insert(properties, result[i].name) - end - - cb(properties) + cb(result) end) end) From 108cad0a6db90f1dddaebe9eb1f6d2f2a9dbcf31 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 3 Feb 2020 13:28:25 +0100 Subject: [PATCH 2510/3224] Correct locale strings --- server/main.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/main.lua b/server/main.lua index 1ef54c8d..980850e8 100644 --- a/server/main.lua +++ b/server/main.lua @@ -23,9 +23,9 @@ function SetPropertyOwned(name, price, rented, owner) TriggerClientEvent('esx_property:setPropertyOwned', xPlayer.source, name, true, rented) if rented then - xPlayer.showNotification(_U('rented_for', ESX.Math.GroupDigits(price))) + xPlayer.showNotification(_U('rent_for', ESX.Math.GroupDigits(price))) else - xPlayer.showNotification(_U('purchased_for', ESX.Math.GroupDigits(price))) + xPlayer.showNotification(_U('buy_for', ESX.Math.GroupDigits(price))) end end end) From 49d0b5b883160c90b72f1963e7efb1283d70d81d Mon Sep 17 00:00:00 2001 From: Luis26x <60543200+Luis26x@users.noreply.github.com> Date: Tue, 4 Feb 2020 07:31:58 -0500 Subject: [PATCH 2511/3224] es.lua Here is the full translation in Spanish, I hope you can add it --- locales/es.lua | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 locales/es.lua diff --git a/locales/es.lua b/locales/es.lua new file mode 100644 index 00000000..0f1788b2 --- /dev/null +++ b/locales/es.lua @@ -0,0 +1,17 @@ +Locales['es'] = { + ['actions'] = 'acciones', + ['amount'] = 'cantidad', + ['balance'] = 'balance', + ['bank'] = 'Banco', + ['bill_amount'] = 'total de la factura', + ['billing'] = 'facturación', + ['customer'] = 'cliente', + ['customers'] = 'Clientes', + ['deposit'] = 'depositar', + ['invalid_amount'] = 'Monto invalido', + ['no_player_nearby'] = 'no hay jugadores cerca', +['press_input_context_to_open_menu'] = 'presione ~INPUT_CONTEXT~ para abrir el ~g~Menú del banc ~s~.', + ['withdraw'] = 'retirar', + ['boss_actions'] = 'Acciones del jefe', + ['phone_receive'] = 'Cliente bancario', + ['phone_label'] = 'banco', From 044a318a93adeaa5b39489d80719e5d47ae690d8 Mon Sep 17 00:00:00 2001 From: Luis26x <60543200+Luis26x@users.noreply.github.com> Date: Tue, 4 Feb 2020 07:36:58 -0500 Subject: [PATCH 2512/3224] esx_es_esx_bankerjob.sql Here is the full translation in Spanish, I hope you can add it --- localization/esx_es_esx_bankerjob.sql | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 localization/esx_es_esx_bankerjob.sql diff --git a/localization/esx_es_esx_bankerjob.sql b/localization/esx_es_esx_bankerjob.sql new file mode 100644 index 00000000..1b60b113 --- /dev/null +++ b/localization/esx_es_esx_bankerjob.sql @@ -0,0 +1,18 @@ +USE `essentialmode`; + +INSERT INTO `addon_account` (name, label, shared) VALUES + ('society_banker','Bank',1), + ('bank_savings','Ahorro bancario',0) +; + +INSERT INTO `jobs` (name, label) VALUES + ('banker','Banquero') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('banker',0,'advisor','Asesores',10,'{}','{}'), + ('banker',1,'banker','Banquero',20,'{}','{}'), + ('banker',2,'business_banker','Banquero de negocios',30,'{}','{}'), + ('banker',3,'trader','Comerciante',40,'{}','{}'), + ('banker',4,'boss','Banquero principal',0,'{}','{}') +; From 1cee8032cb5a6ec143ef2ed6dc6b49ca3fccf28d Mon Sep 17 00:00:00 2001 From: Luis26x <60543200+Luis26x@users.noreply.github.com> Date: Tue, 4 Feb 2020 07:38:45 -0500 Subject: [PATCH 2513/3224] locales/es.lua add 'locales/es.lua', --- fxmanifest.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fxmanifest.lua b/fxmanifest.lua index 733c50e0..ea46e12e 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -14,6 +14,7 @@ server_scripts { 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', + 'locales/es.lua', 'locales/fi.lua', 'locales/fr.lua', 'locales/sv.lua', @@ -26,6 +27,7 @@ client_scripts { 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', + 'locales/es.lua', 'locales/fi.lua', 'locales/fr.lua', 'locales/sv.lua', From 65abc5b490c56ab62052d715ebbdc8e102bb0790 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 4 Feb 2020 20:58:03 +0100 Subject: [PATCH 2514/3224] Reverted accedental dev code --- client/main.lua | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/client/main.lua b/client/main.lua index 29b19aa1..9420831a 100644 --- a/client/main.lua +++ b/client/main.lua @@ -778,8 +778,6 @@ AddEventHandler('esx_property:hasExitedMarker', function(name, part) CurrentAction = nil end) -local index = 0 -RegisterCommand('s', function(a, b, c) -- Enter / Exit marker events & Draw markers Citizen.CreateThread(function() while true do @@ -826,7 +824,7 @@ Citizen.CreateThread(function() end -- Room menu - if property.roomMenu then + if property.roomMenu and hasChest and not property.disabled then local distance = GetDistanceBetweenCoords(coords, property.roomMenu.x, property.roomMenu.y, property.roomMenu.z, true) if distance < Config.DrawDistance then @@ -867,7 +865,7 @@ Citizen.CreateThread(function() Citizen.Wait(0) if CurrentAction then - --ESX.ShowHelpNotification(CurrentActionMsg) + ESX.ShowHelpNotification(CurrentActionMsg) if IsControlJustReleased(0, 38) then if CurrentAction == 'property_menu' then From 19a54ee7501947444964a244183261e9c8214899 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 5 Feb 2020 11:10:51 +0100 Subject: [PATCH 2515/3224] Minor cleanup, use RegisterKeyMapping() native, fixed not working on latest esx, closes #34 --- client/main.lua | 36 +++--- locales/br.lua | 1 + locales/de.lua | 1 + locales/en.lua | 1 + locales/es.lua | 1 + locales/fi.lua | 1 + locales/fr.lua | 1 + locales/pl.lua | 1 + locales/sv.lua | 1 + server/main.lua | 283 ++++++++++++++++++++---------------------------- 10 files changed, 138 insertions(+), 189 deletions(-) diff --git a/client/main.lua b/client/main.lua index 9b6fe351..eb624e21 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,4 +1,4 @@ -ESX = nil +ESX = nil local isDead = false Citizen.CreateThread(function() @@ -9,20 +9,18 @@ Citizen.CreateThread(function() end) function ShowBillsMenu() - ESX.TriggerServerCallback('esx_billing:getBills', function(bills) ESX.UI.Menu.CloseAll() local elements = {} - for i=1, #bills, 1 do + for k,v in ipairs(bills) do table.insert(elements, { - label = ('%s - %s'):format(bills[i].label, _U('invoices_item', ESX.Math.GroupDigits(bills[i].amount))), - billID = bills[i].id + label = ('%s - %s'):format(v.label, _U('invoices_item', ESX.Math.GroupDigits(v.amount))), + billId = v.id }) end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'billing', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'billing', { title = _U('invoices'), align = 'bottom-right', elements = elements @@ -31,28 +29,20 @@ function ShowBillsMenu() ESX.TriggerServerCallback('esx_billing:payBill', function() ShowBillsMenu() - end, data.current.billID) + end, data.current.billId) end, function(data, menu) menu.close() end) end) - end --- Key controls -Citizen.CreateThread(function() - while true do - Citizen.Wait(0) - if IsControlJustReleased(0, 168) and not isDead and not ESX.UI.Menu.IsOpen('default', GetCurrentResourceName(), 'billing') then - ShowBillsMenu() - end +RegisterCommand('showbills', function() + if not isDead and not ESX.UI.Menu.IsOpen('default', GetCurrentResourceName(), 'billing') then + ShowBillsMenu() end -end) +end, false) -AddEventHandler('esx:onPlayerDeath', function(data) - isDead = true -end) +RegisterKeyMapping('showbills', _U('keymap_showbills'), 'keyboard', 'F7') -AddEventHandler('playerSpawned', function(spawn) - isDead = false -end) +AddEventHandler('esx:onPlayerDeath', function() isDead = true end) +AddEventHandler('playerSpawned', function(spawn) isDead = false end) diff --git a/locales/br.lua b/locales/br.lua index bee997ed..c0b129c1 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -7,4 +7,5 @@ Locales['br'] = { ['player_not_online'] = 'o jogador não está na cidade', ['no_money'] = 'você não tem dinheiro suficiente para pagar esta fatura', ['target_no_money'] = 'o cidadão ~r~não tem~s~ dinheiro suficiente para pagar a conta!', + ['keymap_showbills'] = 'open bills menu', } diff --git a/locales/de.lua b/locales/de.lua index d705bb66..3e4eaef1 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -7,4 +7,5 @@ Locales['de'] = { ['player_not_online'] = 'der Spieler ist nicht online', ['no_money'] = 'you do not have enough money to pay this bill', ['target_no_money'] = 'the player ~r~does not~s~ have enough money to pay the bill!', + ['keymap_showbills'] = 'open bills menu', } diff --git a/locales/en.lua b/locales/en.lua index 3973ba13..2d03ba00 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -7,4 +7,5 @@ Locales['en'] = { ['player_not_online'] = 'the player is not logged in', ['no_money'] = 'you do not have enough money to pay this bill', ['target_no_money'] = 'the player ~r~does not~s~ have enough money to pay the bill!', + ['keymap_showbills'] = 'open bills menu', } diff --git a/locales/es.lua b/locales/es.lua index 50f1ad23..10788119 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -7,4 +7,5 @@ Locales['es'] = { ['player_not_online'] = 'el jugador no está conectado', ['no_money'] = 'you do not have enough money to pay this bill', ['target_no_money'] = 'the player ~r~does not~s~ have enough money to pay the bill!', + ['keymap_showbills'] = 'open bills menu', } diff --git a/locales/fi.lua b/locales/fi.lua index 6c6327a9..34a45010 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -7,4 +7,5 @@ Locales['fi'] = { ['player_not_online'] = 'pelaaja ei ole sisäänkirjautuneena', ['no_money'] = 'sinulla ei ole tarpeeksi rahaa maksaaksesi tätä laskua.', ['target_no_money'] = 'pelaajalla ~r~ei ole~s~ tarpeeksi rahaa maksaakseentätä laskua', + ['keymap_showbills'] = 'open bills menu', } diff --git a/locales/fr.lua b/locales/fr.lua index a372d0e6..d8e23916 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -7,4 +7,5 @@ Locales['fr'] = { ['player_not_online'] = 'le joueur n\'est pas connecté', ['no_money'] = 'you do not have enough money to pay this bill', ['target_no_money'] = 'the player ~r~does not~s~ have enough money to pay the bill!', + ['keymap_showbills'] = 'open bills menu', } diff --git a/locales/pl.lua b/locales/pl.lua index e2cac017..59cebbff 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -7,4 +7,5 @@ Locales['pl'] = { ['player_not_online'] = 'gracz nie jest zalogowany', ['no_money'] = 'nie masz wystarczająco pieniędzy aby zapłacić tą fakture', ['target_no_money'] = 'gracz ~r~nie posiada~s~ wystarczająco pieniędzy aby zapłacić tą fakture!', + ['keymap_showbills'] = 'open bills menu', } diff --git a/locales/sv.lua b/locales/sv.lua index 496cc6d2..600246c0 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -7,4 +7,5 @@ Locales['sv'] = { ['player_not_online'] = 'personen är inte online', ['no_money'] = 'du har ~r~inte råd~s~ för att kunna betala räkningen', ['target_no_money'] = 'personen har ~r~inte råd~s~ för att betala räkningen', + ['keymap_showbills'] = 'open bills menu', } diff --git a/server/main.lua b/server/main.lua index ca96824a..c4e71ad5 100644 --- a/server/main.lua +++ b/server/main.lua @@ -4,205 +4,156 @@ TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) RegisterServerEvent('esx_billing:sendBill') AddEventHandler('esx_billing:sendBill', function(playerId, sharedAccountName, label, amount) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) + local xPlayer = ESX.GetPlayerFromId(source) local xTarget = ESX.GetPlayerFromId(playerId) - amount = ESX.Math.Round(amount) + amount = ESX.Math.Round(amount) - TriggerEvent('esx_addonaccount:getSharedAccount', sharedAccountName, function(account) - - if amount < 0 then - print(('esx_billing: %s attempted to send a negative bill!'):format(xPlayer.identifier)) - elseif account == nil then - - if xTarget ~= nil 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'] = 'player', - ['@target'] = xPlayer.identifier, - ['@label'] = label, - ['@amount'] = amount - }, function(rowsChanged) - TriggerClientEvent('esx:showNotification', xTarget.source, _U('received_invoice')) - end) - end - - else - - if xTarget ~= nil 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, + 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 + ['@target'] = sharedAccountName, + ['@label'] = label, + ['@amount'] = amount }, function(rowsChanged) - TriggerClientEvent('esx:showNotification', xTarget.source, _U('received_invoice')) + 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) + xTarget.showNotification(_U('received_invoice')) end) end - - end - end) - + end) + end end) ESX.RegisterServerCallback('esx_billing:getBills', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.fetchAll('SELECT * FROM billing WHERE identifier = @identifier', { + MySQL.Async.fetchAll('SELECT amount, id, label FROM billing WHERE identifier = @identifier', { ['@identifier'] = xPlayer.identifier }, function(result) - local bills = {} - for i=1, #result, 1 do - table.insert(bills, { - id = result[i].id, - identifier = result[i].identifier, - sender = result[i].sender, - targetType = result[i].target_type, - target = result[i].target, - label = result[i].label, - amount = result[i].amount - }) - end - - cb(bills) + cb(result) end) end) ESX.RegisterServerCallback('esx_billing:getTargetBills', function(source, cb, target) local xPlayer = ESX.GetPlayerFromId(target) - MySQL.Async.fetchAll('SELECT * FROM billing WHERE identifier = @identifier', { - ['@identifier'] = xPlayer.identifier - }, function(result) - local bills = {} - for i=1, #result, 1 do - table.insert(bills, { - id = result[i].id, - identifier = result[i].identifier, - sender = result[i].sender, - targetType = result[i].target_type, - target = result[i].target, - label = result[i].label, - amount = result[i].amount - }) - end - - cb(bills) - end) + if xPlayer then + MySQL.Async.fetchAll('SELECT amount, id, label FROM billing WHERE identifier = @identifier', { + ['@identifier'] = xPlayer.identifier + }, function(result) + cb(result) + end) + else + cb({}) + end end) - -ESX.RegisterServerCallback('esx_billing:payBill', function(source, cb, id) +ESX.RegisterServerCallback('esx_billing:payBill', function(source, cb, billId) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.fetchAll('SELECT * FROM billing WHERE id = @id', { - ['@id'] = id + 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) - local sender = result[1].sender - local targetType = result[1].target_type - local target = result[1].target - local amount = result[1].amount + if result[1].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) + if rowsChanged == 1 then + xPlayer.removeMoney(amount) + xTarget.addMoney(amount) - local xTarget = ESX.GetPlayerFromIdentifier(sender) + xPlayer.showNotification(_U('paid_invoice', ESX.Math.GroupDigits(amount))) + xTarget.showNotification(_U('received_payment', ESX.Math.GroupDigits(amount))) + end - if targetType == 'player' then + cb() + end) + elseif xPlayer.getAccount('bank').money >= amount then + MySQL.Async.execute('DELETE FROM billing WHERE id = @id', { + ['@id'] = billId + }, function(rowsChanged) + if rowsChanged == 1 then + xPlayer.removeAccountMoney('bank', amount) + xTarget.addAccountMoney('bank', amount) - if xTarget ~= nil then - - if xPlayer.getMoney() >= amount then - - MySQL.Async.execute('DELETE from billing WHERE id = @id', { - ['@id'] = id - }, function(rowsChanged) - xPlayer.removeMoney(amount) - xTarget.addMoney(amount) - - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('paid_invoice', ESX.Math.GroupDigits(amount))) - TriggerClientEvent('esx:showNotification', xTarget.source, _U('received_payment', ESX.Math.GroupDigits(amount))) + xPlayer.showNotification(_U('paid_invoice', ESX.Math.GroupDigits(amount))) + xTarget.showNotification(_U('received_payment', ESX.Math.GroupDigits(amount))) + end + cb() + end) + else + xTarget.showNotification(_U('target_no_money')) + xPlayer.showNotification(_U('no_money')) cb() - end) - - elseif xPlayer.getBank() >= amount then - - MySQL.Async.execute('DELETE from billing WHERE id = @id', { - ['@id'] = id - }, function(rowsChanged) - xPlayer.removeAccountMoney('bank', amount) - xTarget.addAccountMoney('bank', amount) - - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('paid_invoice', ESX.Math.GroupDigits(amount))) - TriggerClientEvent('esx:showNotification', xTarget.source, _U('received_payment', ESX.Math.GroupDigits(amount))) - - cb() - end) - - else - TriggerClientEvent('esx:showNotification', xTarget.source, _U('target_no_money')) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('no_money')) - - cb() - end - - else - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('player_not_online')) - cb() - end - - else - - TriggerEvent('esx_addonaccount:getSharedAccount', target, function(account) - - if xPlayer.getMoney() >= amount then - - MySQL.Async.execute('DELETE from billing WHERE id = @id', { - ['@id'] = id - }, function(rowsChanged) - xPlayer.removeMoney(amount) - account.addMoney(amount) - - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('paid_invoice', ESX.Math.GroupDigits(amount))) - if xTarget ~= nil then - TriggerClientEvent('esx:showNotification', xTarget.source, _U('received_payment', ESX.Math.GroupDigits(amount))) - end - - cb() - end) - - elseif xPlayer.getBank() >= amount then - - MySQL.Async.execute('DELETE from billing WHERE id = @id', { - ['@id'] = id - }, function(rowsChanged) - xPlayer.removeAccountMoney('bank', amount) - account.addMoney(amount) - - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('paid_invoice', ESX.Math.GroupDigits(amount))) - if xTarget ~= nil then - TriggerClientEvent('esx:showNotification', xTarget.source, _U('received_payment', ESX.Math.GroupDigits(amount))) - end - - cb() - end) - - else - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('no_money')) - - if xTarget ~= nil then - TriggerClientEvent('esx:showNotification', xTarget.source, _U('target_no_money')) end - + else + xPlayer.showNotification(_U('player_not_online')) cb() end - end) + 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) + if rowsChanged == 1 then + xPlayer.removeMoney(amount) + account.addMoney(amount) + xPlayer.showNotification(_U('paid_invoice', ESX.Math.GroupDigits(amount))) + if xTarget then + xTarget.showNotification(_U('received_payment', ESX.Math.GroupDigits(amount))) + end + end + + cb() + end) + elseif xPlayer.getAccount('bank').money >= amount then + MySQL.Async.execute('DELETE FROM billing WHERE id = @id', { + ['@id'] = billId + }, function(rowsChanged) + if rowsChanged == 1 then + xPlayer.removeAccountMoney('bank', amount) + account.addMoney(amount) + xPlayer.showNotification(_U('paid_invoice', ESX.Math.GroupDigits(amount))) + + if xTarget then + xTarget.showNotification(_U('received_payment', ESX.Math.GroupDigits(amount))) + end + end + + cb() + end) + else + if xTarget then + xTarget.showNotification(_U('target_no_money')) + end + + xPlayer.showNotification(_U('no_money')) + cb() + end + end) + end end - end) -end) \ No newline at end of file +end) From 146328ddea5fc8e96a39c8eee2cff9ee4800e9de Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 5 Feb 2020 11:16:02 +0100 Subject: [PATCH 2516/3224] Implemented only show menu if bills available, closes #25 --- client/main.lua | 46 +++++++++++++++++++++++++--------------------- locales/br.lua | 1 + locales/de.lua | 1 + locales/en.lua | 1 + locales/es.lua | 1 + locales/fi.lua | 1 + locales/fr.lua | 1 + locales/pl.lua | 1 + locales/sv.lua | 9 +++++---- 9 files changed, 37 insertions(+), 25 deletions(-) diff --git a/client/main.lua b/client/main.lua index eb624e21..f9a8e4df 100644 --- a/client/main.lua +++ b/client/main.lua @@ -10,29 +10,33 @@ end) function ShowBillsMenu() ESX.TriggerServerCallback('esx_billing:getBills', function(bills) - ESX.UI.Menu.CloseAll() - local elements = {} + if #bills > 0 then + ESX.UI.Menu.CloseAll() + local elements = {} - for k,v in ipairs(bills) do - table.insert(elements, { - label = ('%s - %s'):format(v.label, _U('invoices_item', ESX.Math.GroupDigits(v.amount))), - billId = v.id - }) + for k,v in ipairs(bills) do + table.insert(elements, { + label = ('%s - %s'):format(v.label, _U('invoices_item', ESX.Math.GroupDigits(v.amount))), + billId = v.id + }) + end + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'billing', { + title = _U('invoices'), + align = 'bottom-right', + elements = elements + }, function(data, menu) + menu.close() + + ESX.TriggerServerCallback('esx_billing:payBill', function() + ShowBillsMenu() + end, data.current.billId) + end, function(data, menu) + menu.close() + end) + else + ESX.ShowNotification(_U('no_invoices')) end - - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'billing', { - title = _U('invoices'), - align = 'bottom-right', - elements = elements - }, function(data, menu) - menu.close() - - ESX.TriggerServerCallback('esx_billing:payBill', function() - ShowBillsMenu() - end, data.current.billId) - end, function(data, menu) - menu.close() - end) end) end diff --git a/locales/br.lua b/locales/br.lua index c0b129c1..01825293 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -3,6 +3,7 @@ Locales['br'] = { ['invoices_item'] = '$%s', ['received_invoice'] = 'você ~r~recebeu~s~ uma fatura', ['paid_invoice'] = 'você ~g~pagou~s~ uma fatura de ~r~$%s~s~', + ['no_invoices'] = 'you do not have any bills to pay at this moment', ['received_payment'] = 'você ~g~recebeu~s~ um pagamento de ~r~$%s~s~', ['player_not_online'] = 'o jogador não está na cidade', ['no_money'] = 'você não tem dinheiro suficiente para pagar esta fatura', diff --git a/locales/de.lua b/locales/de.lua index 3e4eaef1..80991e28 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -3,6 +3,7 @@ Locales['de'] = { ['invoices_item'] = '$%s', ['received_invoice'] = 'you hast eine Rechnung ~r~erhlaten~s~', ['paid_invoice'] = 'du ~g~bezahlst~s~ eine Rechnung von ~r~$%s~s~', + ['no_invoices'] = 'you do not have any bills to pay at this moment', ['received_payment'] = 'du ~g~erhältst~s~ eine Zahlung von ~r~$%s~s~', ['player_not_online'] = 'der Spieler ist nicht online', ['no_money'] = 'you do not have enough money to pay this bill', diff --git a/locales/en.lua b/locales/en.lua index 2d03ba00..07f47970 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -3,6 +3,7 @@ Locales['en'] = { ['invoices_item'] = '$%s', ['received_invoice'] = 'you have just ~r~received~s~ an invoice', ['paid_invoice'] = 'you ~g~paid~s~ an invoice of ~r~$%s~s~', + ['no_invoices'] = 'you do not have any bills to pay at this moment', ['received_payment'] = 'you ~g~received~s~ a payment of ~r~$%s~s~', ['player_not_online'] = 'the player is not logged in', ['no_money'] = 'you do not have enough money to pay this bill', diff --git a/locales/es.lua b/locales/es.lua index 10788119..8351147b 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -3,6 +3,7 @@ Locales['es'] = { ['invoices_item'] = '€%s', ['received_invoice'] = 'has ~r~recibido~s~ una multa', ['paid_invoice'] = 'has ~g~pagado~s~ una multa de ~r~€%s~s~', + ['no_invoices'] = 'you do not have any bills to pay at this moment', ['received_payment'] = 'has ~g~recibido~s~ un pago de ~g~€%s~s~', ['player_not_online'] = 'el jugador no está conectado', ['no_money'] = 'you do not have enough money to pay this bill', diff --git a/locales/fi.lua b/locales/fi.lua index 34a45010..4303012d 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -3,6 +3,7 @@ Locales['fi'] = { ['invoices_item'] = '$%s', ['received_invoice'] = 'sinä ~r~sait~s~ laskun', ['paid_invoice'] = 'sinä ~g~maksoit~s~ laskun suuruudelta ~r~$%s~s~', + ['no_invoices'] = 'you do not have any bills to pay at this moment', ['received_payment'] = 'sinä ~g~sait~s~ maksun suuruudelta ~r~$%s~s~', ['player_not_online'] = 'pelaaja ei ole sisäänkirjautuneena', ['no_money'] = 'sinulla ei ole tarpeeksi rahaa maksaaksesi tätä laskua.', diff --git a/locales/fr.lua b/locales/fr.lua index d8e23916..1fbac84d 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -3,6 +3,7 @@ Locales['fr'] = { ['invoices_item'] = '$%s', ['received_invoice'] = 'vous avez ~r~reçu~s~ une facture', ['paid_invoice'] = 'vous avez ~g~payé~s~ une facture de ~r~$%s~s~', + ['no_invoices'] = 'you do not have any bills to pay at this moment', ['received_payment'] = 'vous avez ~g~reçu~s~ un paiement de ~g~$%s~s~', ['player_not_online'] = 'le joueur n\'est pas connecté', ['no_money'] = 'you do not have enough money to pay this bill', diff --git a/locales/pl.lua b/locales/pl.lua index 59cebbff..1275092f 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -3,6 +3,7 @@ Locales['pl'] = { ['invoices_item'] = '$%s', ['received_invoice'] = 'właśnie ~r~dostałeś/aś~s~ fakture', ['paid_invoice'] = '~g~Zapłaciłeś/aś~s~ fakture: ~r~$%s~s~', + ['no_invoices'] = 'you do not have any bills to pay at this moment', ['received_payment'] = '~g~Otrzymałeś/aś~s~ zapłate: ~r~$%s~s~', ['player_not_online'] = 'gracz nie jest zalogowany', ['no_money'] = 'nie masz wystarczająco pieniędzy aby zapłacić tą fakture', diff --git a/locales/sv.lua b/locales/sv.lua index 600246c0..44eb3466 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -3,9 +3,10 @@ Locales['sv'] = { ['invoices_item'] = '%s SEK', ['received_invoice'] = 'du har ~y~mottagit~s~ en räkning', ['paid_invoice'] = 'du ~y~betalade~s~ precis en räkning på ~g~%s SEK~s~', + ['no_invoices'] = 'du har inga inkommande räkningar', ['received_payment'] = 'du har ~y~mottagit~s~ en räkning på ~g~%s SEK~s~', - ['player_not_online'] = 'personen är inte online', - ['no_money'] = 'du har ~r~inte råd~s~ för att kunna betala räkningen', - ['target_no_money'] = 'personen har ~r~inte råd~s~ för att betala räkningen', - ['keymap_showbills'] = 'open bills menu', + ['player_not_online'] = 'spelaren är inte online', + ['no_money'] = 'du har ~r~inte råd~s~ för att betala räkningen', + ['target_no_money'] = 'spelaren har ~r~inte råd~s~ för att betala räkningen', + ['keymap_showbills'] = 'öppna menyn för räkningar', } From b221c33800ca6606e33522d1edfb351da7f0e44c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 5 Feb 2020 11:21:12 +0100 Subject: [PATCH 2517/3224] Final commit v1.2.0 --- README.md | 6 +++++- fxmanifest.lua | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c4f408ee..2fcfd7ae 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # esx_billing +This resource for ESX adds possibility for different jobs to send bills to players, for example making police units able to give people fines. It comes with a menu for paying bills, to open the menu the default keybind is `F7`. + +There is a developer server event available in order to register bills in the database, see default resources for examples. + ## Download & Installation ### Using [fvm](https://github.com/qlaffont/fvm-installer) @@ -44,7 +48,7 @@ end ### License esx_billing - billing for ESX -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. diff --git a/fxmanifest.lua b/fxmanifest.lua index c0669a48..dacdfe59 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -4,7 +4,7 @@ game 'gta5' description 'ESX Billing' -version '1.1.0' +version '1.2.0' server_scripts { '@mysql-async/lib/MySQL.lua', From 0b2754a8e221d3ca7d38a120dc7d54af5bd58c74 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Wed, 5 Feb 2020 23:29:57 +0100 Subject: [PATCH 2518/3224] Added czech locale (#36) Added Czech locale --- fxmanifest.lua | 2 ++ locales/cs.lua | 12 ++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 locales/cs.lua diff --git a/fxmanifest.lua b/fxmanifest.lua index dacdfe59..b3db998e 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -17,6 +17,7 @@ server_scripts { 'locales/es.lua', 'locales/sv.lua', 'locales/pl.lua', + 'locales/cs.lua', 'config.lua', 'server/main.lua' } @@ -31,6 +32,7 @@ client_scripts { 'locales/es.lua', 'locales/sv.lua', 'locales/pl.lua', + 'locales/cs.lua', 'config.lua', 'client/main.lua' } diff --git a/locales/cs.lua b/locales/cs.lua new file mode 100644 index 00000000..1f365d83 --- /dev/null +++ b/locales/cs.lua @@ -0,0 +1,12 @@ +Locales['cs'] = { + ['invoices'] = 'faktury', + ['invoices_item'] = '$%s', + ['received_invoice'] = 'právě jsi ~r~obdrzel~s~ fakturu', + ['paid_invoice'] = '~g~zaplatil jsi~s~ fakturu za ~r~$%s~s~', + ['no_invoices'] = 'momentalne nemas zadnou fatkuru k zaplaceni', + ['received_payment'] = '~g~obdržel jsi~s~ platbu za ~r~$%s~s~', + ['player_not_online'] = 'hráč není přihlášen', + ['no_money'] = 'nemáš dostatek peněz na zaplacení této faktury', + ['target_no_money'] = 'hráč ~r~nemá~s~ dostatek peněz na zaplacení faktury!', + ['keymap_showbills'] = 'otevrit menu faktur', +} From 98a68bd107383163bd62788c01dcec0dcd3755d0 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 6 Feb 2020 10:54:04 +0100 Subject: [PATCH 2519/3224] Added "exception handler" to missing authorized vehicle list --- client/vehicle.lua | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/client/vehicle.lua b/client/vehicle.lua index a0af0aec..2a0d04b4 100644 --- a/client/vehicle.lua +++ b/client/vehicle.lua @@ -17,24 +17,28 @@ function OpenVehicleSpawnerMenu(type, station, part, partNum) local shopCoords = Config.PoliceStations[station][part][partNum].InsideShop local authorizedVehicles = Config.AuthorizedVehicles[type][ESX.PlayerData.job.grade_name] - if #authorizedVehicles > 0 then - for k,vehicle in ipairs(authorizedVehicles) do - if IsModelInCdimage(vehicle.model) then - local vehicleLabel = GetLabelText(GetDisplayNameFromVehicleModel(vehicle.model)) + if authorizedVehicles then + if #authorizedVehicles > 0 then + for k,vehicle in ipairs(authorizedVehicles) do + if IsModelInCdimage(vehicle.model) then + local vehicleLabel = GetLabelText(GetDisplayNameFromVehicleModel(vehicle.model)) - table.insert(shopElements, { - label = ('%s - %s'):format(vehicleLabel, _U('shop_item', ESX.Math.GroupDigits(vehicle.price))), - name = vehicleLabel, - model = vehicle.model, - price = vehicle.price, - props = vehicle.props, - type = type - }) + table.insert(shopElements, { + label = ('%s - %s'):format(vehicleLabel, _U('shop_item', ESX.Math.GroupDigits(vehicle.price))), + name = vehicleLabel, + model = vehicle.model, + price = vehicle.price, + props = vehicle.props, + type = type + }) + end end - end - if #shopElements > 0 then - OpenShopMenu(shopElements, playerCoords, shopCoords) + if #shopElements > 0 then + OpenShopMenu(shopElements, playerCoords, shopCoords) + else + ESX.ShowNotification(_U('garage_notauthorized')) + end else ESX.ShowNotification(_U('garage_notauthorized')) end From 6d89fd9283bc04a2fb10a6b6802c67a23f3cc6fe Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 6 Feb 2020 11:22:43 +0100 Subject: [PATCH 2520/3224] Corrected locales --- locales/br.lua | 2 +- locales/cs.lua | 2 +- locales/sv.lua | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index e47dda49..5bd1cbee 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -48,7 +48,7 @@ Locales['br'] = { ['shop_item'] = '$%s', ['vehicleshop_title'] = 'vehicle Shop', ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', - ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~', + ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~g~$%s~s~', ['vehicleshop_money'] = 'you cannot afford that vehicle', ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', ['confirm_no'] = 'no', diff --git a/locales/cs.lua b/locales/cs.lua index eff426e6..be112891 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -20,7 +20,7 @@ Locales['cs'] = { ['armory_item'] = '$%s', ['armory_weapontitle'] = 'zbrojnice', ['armory_componenttitle'] = 'zbrojnice - Příslušenství ke zbraním', - ['armory_bought'] = 'zakoupil jsi ~y~%s~s~ za ~r~$%s~s~', + ['armory_bought'] = 'zakoupil jsi ~y~%s~s~ za ~g~$%s~s~', ['armory_money'] = 'nemáš dostatek peněz na tuto zbraň', ['armory_hascomponent'] = 'toto příslušenství máš již nainstalováno!', ['get_weapon_menu'] = 'zbrojnice - Vzít zbraň', diff --git a/locales/sv.lua b/locales/sv.lua index 04f52ed0..8a7d4295 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -20,7 +20,7 @@ Locales['sv'] = { ['armory_item'] = '%s SEK', ['armory_weapontitle'] = 'vapenförråd - Köp vapen', ['armory_componenttitle'] = 'vapenförråd - Vapen tillbehör', - ['armory_bought'] = 'du köpte ~y~%s~s~ för ~r~%s SEK~s~', + ['armory_bought'] = 'du köpte ~y~%s~s~ för ~g~%s SEK~s~', ['armory_money'] = 'du har inte råd med det vapnet', ['armory_hascomponent'] = 'du har redan det tillbehöret!', ['get_weapon_menu'] = 'vapenförråd - Ta ut vapen', From 259cbc5b08c0d1587225d1d7389db8d82ea9443e Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 6 Feb 2020 13:05:43 +0100 Subject: [PATCH 2521/3224] Fixed identity job --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 94676317..f0dfacaf 100644 --- a/client/main.lua +++ b/client/main.lua @@ -400,7 +400,7 @@ function OpenIdentityCardMenu(player) ESX.TriggerServerCallback('esx_policejob:getOtherPlayerData', function(data) local elements = { {label = _U('name', data.name)}, - {label = _U('job', ('%s - %s'):format(data.job.label, data.job.grade_label))} + {label = _U('job', ('%s - %s'):format(data.job, data.grade))} } if Config.EnableESXIdentity then From 783a5eeae2a8d45033949fa9ee48393af63c1471 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 6 Feb 2020 13:06:25 +0100 Subject: [PATCH 2522/3224] Fixed remove blips on change job, fixed blip not properly registering --- client/job.lua | 17 ++++++++++++++--- client/main.lua | 3 +-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/client/job.lua b/client/job.lua index 2dbeaf01..6802391e 100644 --- a/client/job.lua +++ b/client/job.lua @@ -4,9 +4,7 @@ local isBusy, deadPlayers, deadPlayerBlips, isOnDuty = false, {}, {}, false isInShopMenu = false function OpenAmbulanceActionsMenu() - local elements = { - {label = _U('cloakroom'), value = 'cloakroom'} - } + local elements = {{label = _U('cloakroom'), value = 'cloakroom'}} if Config.EnablePlayerManagement and ESX.PlayerData.job.grade_name == 'boss' then table.insert(elements, {label = _U('boss_actions'), value = 'boss_actions'}) @@ -437,6 +435,7 @@ function OpenCloakroomMenu() end isOnDuty = true + TriggerEvent('esx_ambulancejob:setDeadPlayers', deadPlayers) end) end @@ -480,6 +479,18 @@ AddEventHandler('esx_ambulancejob:heal', function(healType, quiet) end end) +RegisterNetEvent('esx:setJob') +AddEventHandler('esx:setJob', function(job) + if isOnDuty and job ~= 'ambulance' then + for playerId,v in pairs(deadPlayerBlips) do + RemoveBlip(v) + deadPlayerBlips[playerId] = nil + end + + isOnDuty = false + end +end) + RegisterNetEvent('esx_ambulancejob:setDeadPlayers') AddEventHandler('esx_ambulancejob:setDeadPlayers', function(_deadPlayers) deadPlayers = _deadPlayers diff --git a/client/main.lua b/client/main.lua index 30f62169..3b8dcdae 100644 --- a/client/main.lua +++ b/client/main.lua @@ -30,6 +30,7 @@ end) AddEventHandler('playerSpawned', function() isDead = false + TriggerServerEvent('esx_ambulancejob:onPlayerSpawn') if firstSpawn then exports.spawnmanager:setAutoSpawn(false) -- disable respawn @@ -45,8 +46,6 @@ AddEventHandler('playerSpawned', function() RemoveItemsAfterRPDeath() end end) - else - TriggerServerEvent('esx_ambulancejob:onPlayerSpawn') end end) From 14fbc69357dc5cb1d1a2bb87a7ad9a6e5ce3f828 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 8 Feb 2020 12:36:18 +0100 Subject: [PATCH 2523/3224] Major improvements, see desc - Fixed selling same vehicle multiple times - Fixed selling vehicle - Major security improvements - Removed buying vehicle for society - Code cleanup - Fixed depopping vehicle not working (not respecting network owner) --- README.md | 18 +- client/main.lua | 417 ++++++++++++++++++----------------------------- client/utils.lua | 4 +- config.lua | 6 +- locales/br.lua | 5 +- locales/en.lua | 13 +- locales/fi.lua | 5 +- locales/fr.lua | 5 +- locales/pl.lua | 5 +- locales/sv.lua | 7 +- server/main.lua | 409 +++++++++++++++++++++------------------------- 11 files changed, 371 insertions(+), 523 deletions(-) diff --git a/README.md b/README.md index 5a7cf9a3..77e40f64 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ # esx_vehicleshop +ESX Vehicle Shop adds an vehicle shop to the game, where employeed players can sell vehicles to other players. You can also disable the job part so any player can buy vehicles with a menu based interaction. + ## Requirements * Auto mode (everyone can buy vehicles from the dealer) - * No need to download another resource + * No need to download other resources * Player management (the car dealer job): billing, boss actions and more! * [esx_society](https://github.com/ESX-Org/esx_society) @@ -15,21 +17,25 @@ ## Download & Installation ### Using [fvm](https://github.com/qlaffont/fvm-installer) + ``` fvm install --save --folder=esx esx-org/esx_vehicleshop ``` ### Using Git + ``` cd resources git clone https://github.com/ESX-Org/esx_vehicleshop [esx]/esx_vehicleshop ``` ### Manually + - Download https://github.com/ESX-Org/esx_vehicleshop/archive/master.zip - Put it in the `[esx]` directory -## Installation +### Installation + - Import `esx_vehicleshop.sql` in your database - Add this in your `server.cfg`: @@ -38,14 +44,16 @@ start esx_vehicleshop ``` - If you want player management you have to set `Config.EnablePlayerManagement` to `true` in `config.lua` -# Legal +## Legal + ### License + esx_vehicleshop - vehicle shop for ESX -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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 http://www.gnu.org/licenses/. \ No newline at end of file +You should have received a copy Of the GNU General Public License along with this program. If Not, see http://www.gnu.org/licenses/. diff --git a/client/main.lua b/client/main.lua index a6d2a2b8..e6de7966 100644 --- a/client/main.lua +++ b/client/main.lua @@ -6,7 +6,7 @@ local CurrentActionData = {} local IsInShopMenu = false local Categories = {} local Vehicles = {} -local LastVehicles = {} +local currentDisplayVehicle local CurrentVehicleData ESX = nil @@ -42,6 +42,16 @@ Citizen.CreateThread(function() end end) +function getVehicleLabelFromModel(model) + for k,v in ipairs(Vehicles) do + if v.model == model then + return v.name + end + end + + return +end + RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) ESX.PlayerData = xPlayer @@ -71,26 +81,33 @@ AddEventHandler('esx_vehicleshop:sendVehicles', function(vehicles) Vehicles = vehicles end) -function DeleteShopInsideVehicles() - while #LastVehicles > 0 do - local vehicle = LastVehicles[1] +function DeleteDisplayVehicleInsideShop() + local attempt = 0 - ESX.Game.DeleteVehicle(vehicle) - table.remove(LastVehicles, 1) + if currentDisplayVehicle and DoesEntityExist(currentDisplayVehicle) then + while DoesEntityExist(currentDisplayVehicle) and not NetworkHasControlOfEntity(currentDisplayVehicle) and attempt < 100 do + Citizen.Wait(100) + NetworkRequestControlOfEntity(currentDisplayVehicle) + attempt = attempt + 1 + end + + if DoesEntityExist(currentDisplayVehicle) and NetworkHasControlOfEntity(currentDisplayVehicle) then + ESX.Game.DeleteVehicle(currentDisplayVehicle) + end end end function ReturnVehicleProvider() ESX.TriggerServerCallback('esx_vehicleshop:getCommercialVehicles', function(vehicles) local elements = {} - local returnPrice - for i=1, #vehicles, 1 do - returnPrice = ESX.Math.Round(vehicles[i].price * 0.75) + for k,v in ipairs(vehicles) do + local returnPrice = ESX.Math.Round(v.price * 0.75) + local vehicleLabel = getVehicleLabelFromModel(v.vehicle) table.insert(elements, { - label = ('%s [%s]'):format(vehicles[i].name, _U('generic_shopitem', ESX.Math.GroupDigits(returnPrice))), - value = vehicles[i].name + label = ('%s [%s]'):format(vehicleLabel, _U('generic_shopitem', ESX.Math.GroupDigits(returnPrice))), + value = v.vehicle }) end @@ -145,7 +162,7 @@ function OpenShopMenu() if IsModelInCdimage(GetHashKey(Vehicles[i].model)) then table.insert(vehiclesByCategory[Vehicles[i].category], Vehicles[i]) else - print(('esx_vehicleshop: vehicle "%s" does not exist'):format(Vehicles[i].model)) + print(('[esx_vehicleshop] [^3ERROR^7] Vehicle "%s" does not exist'):format(Vehicles[i].model)) end end @@ -190,147 +207,58 @@ function OpenShopMenu() }}, function(data2, menu2) if data2.current.value == 'yes' then if Config.EnablePlayerManagement then - ESX.TriggerServerCallback('esx_vehicleshop:buyVehicleSociety', function(hasEnoughMoney) - if hasEnoughMoney then + ESX.TriggerServerCallback('esx_vehicleshop:buyCarDealerVehicle', function(success) + if success then IsInShopMenu = false - - DeleteShopInsideVehicles() - - local playerPed = PlayerPedId() + DeleteDisplayVehicleInsideShop() CurrentAction = 'shop_menu' CurrentActionMsg = _U('shop_menu') CurrentActionData = {} + local playerPed = PlayerPedId() FreezeEntityPosition(playerPed, false) SetEntityVisible(playerPed, true) SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos) menu2.close() menu.close() - ESX.ShowNotification(_U('vehicle_purchased')) else ESX.ShowNotification(_U('broke_company')) end - end, 'cardealer', vehicleData.model) + end, vehicleData.model) else - local playerData = ESX.GetPlayerData() + local generatedPlate = GeneratePlate() - if Config.EnableSocietyOwnedVehicles and playerData.job.grade_name == 'boss' then - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'shop_confirm_buy_type', { - title = _U('purchase_type'), - align = 'top-left', - elements = { - {label = _U('staff_type'), value = 'personnal'}, - {label = _U('society_type'), value = 'society'} - }}, function(data3, menu3) + ESX.TriggerServerCallback('esx_vehicleshop:buyVehicle', function(success) + if success then + IsInShopMenu = false + menu2.close() + menu.close() + DeleteDisplayVehicleInsideShop() - if data3.current.value == 'personnal' then - - ESX.TriggerServerCallback('esx_vehicleshop:buyVehicle', function(hasEnoughMoney) - if hasEnoughMoney then - IsInShopMenu = false - - menu3.close() - menu2.close() - menu.close() - DeleteShopInsideVehicles() - - ESX.Game.SpawnVehicle(vehicleData.model, Config.Zones.ShopOutside.Pos, Config.Zones.ShopOutside.Heading, function(vehicle) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - - local newPlate = GeneratePlate() - local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) - vehicleProps.plate = newPlate - SetVehicleNumberPlateText(vehicle, newPlate) - - if Config.EnableOwnedVehicles then - TriggerServerEvent('esx_vehicleshop:setVehicleOwned', vehicleProps) - end - - ESX.ShowNotification(_U('vehicle_purchased')) - end) - - FreezeEntityPosition(playerPed, false) - SetEntityVisible(playerPed, true) - else - ESX.ShowNotification(_U('not_enough_money')) - end - end, vehicleData.model) - - elseif data3.current.value == 'society' then - - ESX.TriggerServerCallback('esx_vehicleshop:buyVehicleSociety', function(hasEnoughMoney) - if hasEnoughMoney then - IsInShopMenu = false - - menu3.close() - menu2.close() - menu.close() - - DeleteShopInsideVehicles() - - ESX.Game.SpawnVehicle(vehicleData.model, Config.Zones.ShopOutside.Pos, Config.Zones.ShopOutside.Heading, function(vehicle) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - - local newPlate = GeneratePlate() - local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) - vehicleProps.plate = newPlate - SetVehicleNumberPlateText(vehicle, newPlate) - TriggerServerEvent('esx_vehicleshop:setVehicleOwnedSociety', playerData.job.name, vehicleProps) - ESX.ShowNotification(_U('vehicle_purchased')) - end) - - FreezeEntityPosition(playerPed, false) - SetEntityVisible(playerPed, true) - else - ESX.ShowNotification(_U('broke_company')) - end - end, playerData.job.name, vehicleData.model) - - end - end, function(data3, menu3) - menu3.close() - end) - else - ESX.TriggerServerCallback('esx_vehicleshop:buyVehicle', function(hasEnoughMoney) - if hasEnoughMoney then - IsInShopMenu = false - menu2.close() - menu.close() - DeleteShopInsideVehicles() - - ESX.Game.SpawnVehicle(vehicleData.model, Config.Zones.ShopOutside.Pos, Config.Zones.ShopOutside.Heading, function(vehicle) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - - local newPlate = GeneratePlate() - local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) - vehicleProps.plate = newPlate - SetVehicleNumberPlateText(vehicle, newPlate) - - if Config.EnableOwnedVehicles then - TriggerServerEvent('esx_vehicleshop:setVehicleOwned', vehicleProps) - end - - ESX.ShowNotification(_U('vehicle_purchased')) - end) + ESX.Game.SpawnVehicle(vehicleData.model, Config.Zones.ShopOutside.Pos, Config.Zones.ShopOutside.Heading, function(vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + SetVehicleNumberPlateText(vehicle, generatedPlate) FreezeEntityPosition(playerPed, false) SetEntityVisible(playerPed, true) - else - ESX.ShowNotification(_U('not_enough_money')) - end - end, vehicleData.model) - end + end) + else + ESX.ShowNotification(_U('not_enough_money')) + end + end, vehicleData.model, generatedPlate) end + else + menu2.close() end end, function(data2, menu2) menu2.close() end) end, function(data, menu) menu.close() - DeleteShopInsideVehicles() + DeleteDisplayVehicleInsideShop() local playerPed = PlayerPedId() CurrentAction = 'shop_menu' @@ -346,22 +274,22 @@ function OpenShopMenu() local vehicleData = vehiclesByCategory[data.current.name][data.current.value + 1] local playerPed = PlayerPedId() - DeleteShopInsideVehicles() + DeleteDisplayVehicleInsideShop() WaitForVehicleToLoad(vehicleData.model) ESX.Game.SpawnLocalVehicle(vehicleData.model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function(vehicle) - table.insert(LastVehicles, vehicle) + currentDisplayVehicle = vehicle TaskWarpPedIntoVehicle(playerPed, vehicle, -1) FreezeEntityPosition(vehicle, true) SetModelAsNoLongerNeeded(vehicleData.model) end) end) - DeleteShopInsideVehicles() + DeleteDisplayVehicleInsideShop() WaitForVehicleToLoad(firstVehicleData.model) ESX.Game.SpawnLocalVehicle(firstVehicleData.model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function(vehicle) - table.insert(LastVehicles, vehicle) + currentDisplayVehicle = vehicle TaskWarpPedIntoVehicle(playerPed, vehicle, -1) FreezeEntityPosition(vehicle, true) SetModelAsNoLongerNeeded(firstVehicleData.model) @@ -374,16 +302,16 @@ function WaitForVehicleToLoad(modelHash) if not HasModelLoaded(modelHash) then RequestModel(modelHash) - BeginTextCommandBusyString('STRING') + BeginTextCommandBusyspinnerOn('STRING') AddTextComponentSubstringPlayerName(_U('shop_awaiting_model')) - EndTextCommandBusyString(4) + EndTextCommandBusyspinnerOn(4) while not HasModelLoaded(modelHash) do Citizen.Wait(0) DisableAllControlActions(0) end - RemoveLoadingPrompt() + BusyspinnerOff() end end @@ -402,7 +330,6 @@ function OpenResellerMenu() {label = _U('get_rented_vehicles'), value = 'get_rented_vehicles'}, {label = _U('set_vehicle_owner_sell'), value = 'set_vehicle_owner_sell'}, {label = _U('set_vehicle_owner_rent'), value = 'set_vehicle_owner_rent'}, - {label = _U('set_vehicle_owner_sell_society'), value = 'set_vehicle_owner_sell_society'}, {label = _U('deposit_stock'), value = 'put_stock'}, {label = _U('take_stock'), value = 'get_stock'} }}, function(data, menu) @@ -417,125 +344,94 @@ function OpenResellerMenu() elseif action == 'pop_vehicle' then OpenPopVehicleMenu() elseif action == 'depop_vehicle' then - DeleteShopInsideVehicles() + if currentDisplayVehicle then + DeleteDisplayVehicleInsideShop() + else + ESX.ShowNotification(_U('no_current_vehicle')) + end elseif action == 'return_provider' then ReturnVehicleProvider() elseif action == 'create_bill' then - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(_U('no_players')) - return - end - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'set_vehicle_owner_sell_amount', { - title = _U('invoice_amount') - }, function(data2, menu2) - local amount = tonumber(data2.value) + if closestPlayer ~= -1 and closestDistance < 3 then + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'set_vehicle_owner_sell_amount', { + title = _U('invoice_amount') + }, function(data2, menu2) + local amount = tonumber(data2.value) - if amount == nil then - ESX.ShowNotification(_U('invalid_amount')) - else - menu2.close() - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(_U('no_players')) + if amount == nil then + ESX.ShowNotification(_U('invalid_amount')) else - TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_cardealer', _U('car_dealer'), tonumber(data2.value)) - end - end - end, function(data2, menu2) - menu2.close() - end) + menu2.close() + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(_U('no_players')) + else + TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_cardealer', _U('car_dealer'), tonumber(data2.value)) + end + end + end, function(data2, menu2) + menu2.close() + end) + else + ESX.ShowNotification(_U('no_players')) + end elseif action == 'get_rented_vehicles' then OpenRentedVehiclesMenu() elseif action == 'set_vehicle_owner_sell' then + if currentDisplayVehicle then + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(_U('no_players')) - else - local newPlate = GeneratePlate() - local vehicleProps = ESX.Game.GetVehicleProperties(LastVehicles[#LastVehicles]) - local model = CurrentVehicleData.model - vehicleProps.plate = newPlate - SetVehicleNumberPlateText(LastVehicles[#LastVehicles], newPlate) - - TriggerServerEvent('esx_vehicleshop:sellVehicle', model) - TriggerServerEvent('esx_vehicleshop:addToList', GetPlayerServerId(closestPlayer), model, newPlate) - - if Config.EnableOwnedVehicles then - TriggerServerEvent('esx_vehicleshop:setVehicleOwnedPlayerId', GetPlayerServerId(closestPlayer), vehicleProps) - ESX.ShowNotification(_U('vehicle_set_owned', vehicleProps.plate, GetPlayerName(closestPlayer))) - else - ESX.ShowNotification(_U('vehicle_sold_to', vehicleProps.plate, GetPlayerName(closestPlayer))) - end - end - - elseif action == 'set_vehicle_owner_sell_society' then - - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(_U('no_players')) - else - ESX.TriggerServerCallback('esx:getOtherPlayerData', function(xPlayer) - - local newPlate = GeneratePlate() - local vehicleProps = ESX.Game.GetVehicleProperties(LastVehicles[#LastVehicles]) - local model = CurrentVehicleData.model + if closestPlayer ~= -1 and closestDistance < 3 then + local newPlate = GeneratePlate() + local vehicleProps = ESX.Game.GetVehicleProperties(currentDisplayVehicle) vehicleProps.plate = newPlate - SetVehicleNumberPlateText(LastVehicles[#LastVehicles], newPlate) - TriggerServerEvent('esx_vehicleshop:sellVehicle', model) - TriggerServerEvent('esx_vehicleshop:addToList', GetPlayerServerId(closestPlayer), model, newPlate) - - if Config.EnableSocietyOwnedVehicles then - TriggerServerEvent('esx_vehicleshop:setVehicleOwnedSociety', xPlayer.job.name, vehicleProps) - ESX.ShowNotification(_U('vehicle_set_owned', vehicleProps.plate, GetPlayerName(closestPlayer))) - else - ESX.ShowNotification(_U('vehicle_sold_to', vehicleProps.plate, GetPlayerName(closestPlayer))) - end - - end, GetPlayerServerId(closestPlayer)) - end - - elseif action == 'set_vehicle_owner_rent' then - - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'set_vehicle_owner_rent_amount', { - title = _U('rental_amount') - }, function(data2, menu2) - local amount = tonumber(data2.value) - - if amount == nil then - ESX.ShowNotification(_U('invalid_amount')) + SetVehicleNumberPlateText(currentDisplayVehicle, newPlate) + TriggerServerEvent('esx_vehicleshop:setVehicleOwnedPlayerId', GetPlayerServerId(closestPlayer), vehicleProps, CurrentVehicleData.model, CurrentVehicleData.name) + currentDisplayVehicle = nil else - menu2.close() - - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - - if closestPlayer == -1 or closestDistance > 5.0 then - ESX.ShowNotification(_U('no_players')) - else - local newPlate = 'RENT' .. string.upper(ESX.GetRandomString(4)) - local vehicleProps = ESX.Game.GetVehicleProperties(LastVehicles[#LastVehicles]) - local model = CurrentVehicleData.model - vehicleProps.plate = newPlate - SetVehicleNumberPlateText(LastVehicles[#LastVehicles], newPlate) - TriggerServerEvent('esx_vehicleshop:rentVehicle', model, vehicleProps.plate, GetPlayerName(closestPlayer), CurrentVehicleData.price, amount, GetPlayerServerId(closestPlayer)) - - if Config.EnableOwnedVehicles then - TriggerServerEvent('esx_vehicleshop:setVehicleOwnedPlayerId', GetPlayerServerId(closestPlayer), vehicleProps) - end - - ESX.ShowNotification(_U('vehicle_set_rented', vehicleProps.plate, GetPlayerName(closestPlayer))) - end + ESX.ShowNotification(_U('no_players')) end - end, function(data2, menu2) - menu2.close() - end) + else + ESX.ShowNotification(_U('no_current_vehicle')) + end + elseif action == 'set_vehicle_owner_rent' then + if currentDisplayVehicle then + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + + if closestPlayer ~= -1 and closestDistance < 3 then + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'set_vehicle_owner_rent_amount', { + title = _U('rental_amount') + }, function(data2, menu2) + local amount = tonumber(data2.value) + + if not amount then + ESX.ShowNotification(_U('invalid_amount')) + else + menu2.close() + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + + if closestPlayer ~= -1 and closestDistance < 3 then + local newPlate = 'RENT' .. string.upper(ESX.GetRandomString(4)) + local model = CurrentVehicleData.model + SetVehicleNumberPlateText(currentDisplayVehicle, newPlate) + TriggerServerEvent('esx_vehicleshop:rentVehicle', model, newPlate, amount, GetPlayerServerId(closestPlayer)) + currentDisplayVehicle = nil + else + ESX.ShowNotification(_U('no_players')) + end + end + end, function(data2, menu2) + menu2.close() + end) + else + ESX.ShowNotification(_U('no_players')) + end + else + ESX.ShowNotification(_U('no_current_vehicle')) + end end end, function(data, menu) menu.close() @@ -550,10 +446,12 @@ function OpenPopVehicleMenu() ESX.TriggerServerCallback('esx_vehicleshop:getCommercialVehicles', function(vehicles) local elements = {} - for i=1, #vehicles, 1 do + for k,v in ipairs(vehicles) do + local vehicleLabel = getVehicleLabelFromModel(v.vehicle) + table.insert(elements, { - label = ('%s [MSRP %s]'):format(vehicles[i].name, _U('generic_shopitem', ESX.Math.GroupDigits(vehicles[i].price))), - value = vehicles[i].name + label = ('%s [MSRP %s]'):format(vehicleLabel, _U('generic_shopitem', ESX.Math.GroupDigits(v.price))), + value = v.vehicle }) end @@ -563,11 +461,10 @@ function OpenPopVehicleMenu() elements = elements }, function(data, menu) local model = data.current.value - - DeleteShopInsideVehicles() + DeleteDisplayVehicleInsideShop() ESX.Game.SpawnVehicle(model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function(vehicle) - table.insert(LastVehicles, vehicle) + currentDisplayVehicle = vehicle for i=1, #Vehicles, 1 do if model == Vehicles[i].model then @@ -586,10 +483,12 @@ function OpenRentedVehiclesMenu() ESX.TriggerServerCallback('esx_vehicleshop:getRentedVehicles', function(vehicles) local elements = {} - for i=1, #vehicles, 1 do + for k,v in ipairs(vehicles) do + local vehicleLabel = getVehicleLabelFromModel(v.name) + table.insert(elements, { - label = ('%s: %s - %s'):format(vehicles[i].playerName, vehicles[i].name, vehicles[i].plate), - value = vehicles[i].name + label = ('%s: %s - %s'):format(v.playerName, vehicleLabel, v.plate), + value = v.name }) end @@ -660,10 +559,12 @@ function OpenGetStocksMenu() local elements = {} for i=1, #items, 1 do - table.insert(elements, { - label = 'x' .. items[i].count .. ' ' .. items[i].label, - value = items[i].name - }) + if items[i].count > 0 then + table.insert(elements, { + label = 'x' .. items[i].count .. ' ' .. items[i].label, + value = items[i].name + }) + end end ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', { @@ -774,7 +675,6 @@ AddEventHandler('esx_vehicleshop:hasEnteredMarker', function(zone) end elseif zone == 'GiveBackVehicle' and Config.EnablePlayerManagement then - local playerPed = PlayerPedId() if IsPedInAnyVehicle(playerPed, false) then @@ -784,14 +684,11 @@ AddEventHandler('esx_vehicleshop:hasEnteredMarker', function(zone) CurrentActionMsg = _U('vehicle_menu') CurrentActionData = {vehicle = vehicle} end - elseif zone == 'ResellVehicle' then - local playerPed = PlayerPedId() if IsPedSittingInAnyVehicle(playerPed) then - - local vehicle = GetVehiclePedIsIn(playerPed, false) + local vehicle = GetVehiclePedIsIn(playerPed, false) local vehicleData, model, resellPrice, plate if GetPedInVehicleSeat(vehicle, -1) == playerPed then @@ -817,15 +714,12 @@ AddEventHandler('esx_vehicleshop:hasEnteredMarker', function(zone) plate = plate } end - end elseif zone == 'BossActions' and Config.EnablePlayerManagement and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'cardealer' and ESX.PlayerData.job.grade_name == 'boss' then - CurrentAction = 'boss_actions_menu' CurrentActionMsg = _U('shop_menu') CurrentActionData = {} - end end) @@ -842,13 +736,14 @@ AddEventHandler('onResourceStop', function(resource) if IsInShopMenu then ESX.UI.Menu.CloseAll() - DeleteShopInsideVehicles() local playerPed = PlayerPedId() FreezeEntityPosition(playerPed, false) SetEntityVisible(playerPed, true) SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos) end + + DeleteDisplayVehicleInsideShop() end end) @@ -874,8 +769,8 @@ Citizen.CreateThread(function() SetBlipScale (blip, 1.0) SetBlipAsShortRange(blip, true) - BeginTextCommandSetBlipName("STRING") - AddTextComponentString(_U('car_dealer')) + BeginTextCommandSetBlipName('STRING') + AddTextComponentSubstringPlayerName(_U('car_dealer')) EndTextCommandSetBlipName(blip) end) @@ -979,4 +874,4 @@ Citizen.CreateThread(function() LoadInterior(interiorID) EnableInteriorProp(interiorID, 'csr_beforeMission') -- Load large window RefreshInterior(interiorID) -end) \ No newline at end of file +end) diff --git a/client/utils.lua b/client/utils.lua index 26e586bb..88a30d50 100644 --- a/client/utils.lua +++ b/client/utils.lua @@ -19,7 +19,7 @@ function GeneratePlate() generatedPlate = string.upper(GetRandomLetter(Config.PlateLetters) .. GetRandomNumber(Config.PlateNumbers)) end - ESX.TriggerServerCallback('esx_vehicleshop:isPlateTaken', function (isPlateTaken) + ESX.TriggerServerCallback('esx_vehicleshop:isPlateTaken', function(isPlateTaken) if not isPlateTaken then doBreak = true end @@ -66,4 +66,4 @@ function GetRandomLetter(length) else return '' end -end \ No newline at end of file +end diff --git a/config.lua b/config.lua index 0c87297e..61b2c2ff 100644 --- a/config.lua +++ b/config.lua @@ -1,9 +1,7 @@ Config = {} -Config.DrawDistance = 100.0 -Config.MarkerColor = { r = 120, g = 120, b = 240 } +Config.DrawDistance = 100 +Config.MarkerColor = {r = 120, g = 120, b = 240} Config.EnablePlayerManagement = false -- enables the actual car dealer job. You'll need esx_addonaccount, esx_billing and esx_society -Config.EnableOwnedVehicles = true -Config.EnableSocietyOwnedVehicles = false -- use with EnablePlayerManagement disabled, or else it wont have any effects Config.ResellPercentage = 50 Config.Locale = 'fr' diff --git a/locales/br.lua b/locales/br.lua index c70a5d4d..442ea74c 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -5,9 +5,6 @@ Locales['br'] = { ['vehicle_belongs'] = 'um veículo com placa ~y~%s~s~ agora pertence a ~b~you~s~', ['broke_company'] = 'você não tem dinheiro suficiente na conta da empresa', ['license_missing'] = 'você não tem carteira de motorista!', - ['purchase_type'] = 'tipo de compra', - ['society_type'] = 'sociedade', - ['staff_type'] = 'uso pessoal', ['buy_vehicle_shop'] = 'comprar %s por $%s?', ['buy_vehicle'] = 'comprar veículo', ['car_dealer'] = 'Concessionária de carros', @@ -18,6 +15,7 @@ Locales['br'] = { ['depop_vehicle'] = 'volte ao veiculo', ['return_provider'] = 'devolver veículo ao fornecedor', ['get_rented_vehicles'] = 'veículos para alugar', + ['no_current_vehicle'] = 'you do not currently have an vehicle displayed', ['invalid_amount'] = 'Montante inválido', ['invoice_amount'] = 'valor da fatura', ['no'] = 'não', @@ -34,7 +32,6 @@ Locales['br'] = { ['sell_menu'] = 'Pressione ~INPUT_CONTEXT~ para vender ', ['set_vehicle_owner_rent'] = 'Atribuir veículo [Alugar]', ['set_vehicle_owner_sell'] = 'Veículos para [Venda]', - ['set_vehicle_owner_sell_society'] = 'atribuir veículo [Sale] [Society]', ['shop_menu'] = 'pressione ~INPUT_CONTEXT~ para acessar o menu', ['generic_shopitem'] = '$%s', ['vehicle_dealer'] = 'Veículo - Concessionária', diff --git a/locales/en.lua b/locales/en.lua index 69197a9c..40c7a1d2 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -5,9 +5,6 @@ Locales['en'] = { ['vehicle_belongs'] = 'an vehicle with plate ~y~%s~s~ now belongs to ~b~you~s~', ['broke_company'] = 'you do not have enough money in the company account', ['license_missing'] = 'you don\'t have a driver\'s license!', - ['purchase_type'] = 'type of purchase', - ['society_type'] = 'society', - ['staff_type'] = 'personal usage', ['buy_vehicle_shop'] = 'do you want to purchase %s for $%s?', ['buy_vehicle'] = 'buy vehicle', ['car_dealer'] = 'car Dealership', @@ -15,14 +12,15 @@ Locales['en'] = { ['create_bill'] = 'create bill', ['dealer_boss'] = 'car Dealer - Boss', ['delivered'] = 'the vehicle has been ~g~delivered~s~ to the dealer', - ['depop_vehicle'] = 'return vehicle', + ['depop_vehicle'] = 'return vehicle to garage', ['return_provider'] = 'return vehicle to provider', ['get_rented_vehicles'] = 'vehicles for rent', + ['no_current_vehicle'] = 'you do not currently have an vehicle displayed', ['invalid_amount'] = 'invalid amount', ['invoice_amount'] = 'invoice amount', ['no'] = 'no', ['yes'] = 'yes', - ['no_players'] = 'no players nearby', + ['no_players'] = 'there is no players near you', ['not_enough_money'] = 'you do not have enough money', ['not_rental'] = 'this is not a ~r~rental vehicle~s~', ['not_yours'] = 'this vehicle does not belong to you', @@ -32,14 +30,13 @@ Locales['en'] = { ['return_provider_menu'] = 'car Dealer - Return vehicle to provider', ['rental_amount'] = 'rental amount', ['sell_menu'] = 'press ~INPUT_CONTEXT~ to sell your ~y~%s~s~ for ~g~$%s~s~', - ['set_vehicle_owner_rent'] = 'assign vehicle [Location]', + ['set_vehicle_owner_rent'] = 'rent vehicle', ['set_vehicle_owner_sell'] = 'sell vehicle', - ['set_vehicle_owner_sell_society'] = 'assign Vehicle [Sale] [Society]', ['shop_menu'] = 'press ~INPUT_CONTEXT~ to access the menu', ['generic_shopitem'] = '$%s', ['vehicle_dealer'] = 'vehicle - Car Dealer', ['vehicle_menu'] = 'press ~INPUT_CONTEXT~ to give back the rented vehicle', - ['vehicle_purchased'] = 'you bought a vehicle', + ['vehicle_purchased'] = 'you bought an vehicle', ['vehicle_set_owned'] = 'vehicle ~y~%s~s~ has been assigned to ~b~%s~s~', ['vehicle_set_rented'] = 'vehicle ~y~%s~s~ has been rented to ~b~%s~s~', ['vehicle_sold_for'] = 'the ~b~%s~s~ has been ~y~sold~s~ for ~g~$%s~s~', diff --git a/locales/fi.lua b/locales/fi.lua index 3eff6100..03f2804a 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -5,9 +5,6 @@ Locales['fi'] = { ['vehicle_belongs'] = 'ajoneuvo kilvellä ~y~%s~s~ on nyt ~b~sinun~s~ omistuksessasi', ['broke_company'] = 'sinulla ei ole tarpeeksi rahaa yrityksen tilillä', ['license_missing'] = 'you don\'t have a driver\'s license!', - ['purchase_type'] = 'osto tyyppi', - ['society_type'] = 'firma', - ['staff_type'] = 'henkilökunta', ['buy_vehicle_shop'] = 'haluatko ostaa ajoneuvon %s hintaan $%s?', ['buy_vehicle'] = 'osta ajoneuvo', ['car_dealer'] = 'autokauppa', @@ -18,6 +15,7 @@ Locales['fi'] = { ['depop_vehicle'] = 'palauta ajoneuvo', ['return_provider'] = 'return vehicle to provider', ['get_rented_vehicles'] = 'vuokrattavat ajoneuvot', + ['no_current_vehicle'] = 'you do not currently have an vehicle displayed', ['invalid_amount'] = 'virheellinen summa', ['invoice_amount'] = 'laskun summa', ['no'] = 'ei', @@ -34,7 +32,6 @@ Locales['fi'] = { ['sell_menu'] = 'paina ~INPUT_CONTEXT~ myydäksesi ~y~%s~s~ hintaan: ~g~$%s~s~', ['set_vehicle_owner_rent'] = 'määritä ajoneuvon [Vuokra]', ['set_vehicle_owner_sell'] = 'myy ajoneuvo', - ['set_vehicle_owner_sell_society'] = 'määritä ajoneuvon [Hinta] [Firma]', ['shop_menu'] = 'paina ~INPUT_CONTEXT~ avataksesi menu', ['generic_shopitem'] = '$%s', ['vehicle_dealer'] = 'ajonevuo - Autokauppa', diff --git a/locales/fr.lua b/locales/fr.lua index 4c53116f..9a2a8ea4 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -5,9 +5,6 @@ Locales['fr'] = { ['vehicle_belongs'] = 'le véhicule avec la plaque ~y~%s~s~ est désormais à ~b~vous~s~', ['broke_company'] = 'vous n\avez pas assez d\'argent sur le compte de la societé', ['license_missing'] = 'you don\'t have a driver\'s license!', - ['purchase_type'] = 'type d\'achat', - ['society_type'] = 'societé', - ['staff_type'] = 'personnel', ['buy_vehicle_shop'] = 'acheter %s pour $%s?', ['buy_vehicle'] = 'acheter véhicule', ['car_dealer'] = 'concessionnaire', @@ -18,6 +15,7 @@ Locales['fr'] = { ['depop_vehicle'] = 'rentrer véhicule', ['return_provider'] = 'rendre le véhicule', ['get_rented_vehicles'] = 'véhicules en location', + ['no_current_vehicle'] = 'you do not currently have an vehicle displayed', ['invalid_amount'] = 'montant invalide', ['invoice_amount'] = 'montant de la facture', ['no'] = 'non', @@ -34,7 +32,6 @@ Locales['fr'] = { ['sell_menu'] = 'appuyez sur ~INPUT_CONTEXT~ pour vendre ~y~%s~s~ au prix de ~g~$%s~s~', ['set_vehicle_owner_rent'] = 'attribuer véhicule [Location]', ['set_vehicle_owner_sell'] = 'attribuer véhicule [Vente]', - ['set_vehicle_owner_sell_society'] = 'attribuer véhicule [Vente] [Société]', ['shop_menu'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder au menu', ['generic_shopitem'] = '$%s', ['vehicle_dealer'] = 'concessionnaire - Véhicules', diff --git a/locales/pl.lua b/locales/pl.lua index c0b19aa7..d2eef57a 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -5,9 +5,6 @@ Locales['pl'] = { ['vehicle_belongs'] = 'pojazd z rejestracją ~y~%s~s~ teraz należy do ~b~ciebie~s~', ['broke_company'] = 'twoja firma nie ma wystarczająco pieniedzy', ['license_missing'] = 'you don\'t have a driver\'s license!', - ['purchase_type'] = 'rodzaj zakupu', - ['society_type'] = 'firma', - ['staff_type'] = 'pracownicy', ['buy_vehicle_shop'] = 'czy chcesz kupić %s za $%s?', ['buy_vehicle'] = 'kup pojazd', ['car_dealer'] = 'sprzedawca Aut', @@ -18,6 +15,7 @@ Locales['pl'] = { ['depop_vehicle'] = 'oddaj pojazd', ['return_provider'] = 'return vehicle to provider', ['get_rented_vehicles'] = 'pojazdy do wynajęcia', + ['no_current_vehicle'] = 'you do not currently have an vehicle displayed', ['invalid_amount'] = 'nieprawidłowa ilość', ['invoice_amount'] = 'suma faktury', ['no'] = 'nie', @@ -34,7 +32,6 @@ Locales['pl'] = { ['sell_menu'] = 'wcisnij ~INPUT_CONTEXT~ aby sprzedać ~y~%s~s~ za ~g~$%s~s~', ['set_vehicle_owner_rent'] = 'zarejestruj pojazd [Wynajem]', ['set_vehicle_owner_sell'] = 'zarejestruj pojazd [Kupno]', - ['set_vehicle_owner_sell_society'] = 'zarejestruj pojazd [Firmowe]', ['shop_menu'] = 'wcisnij ~INPUT_CONTEXT~ aby wejść do menu', ['generic_shopitem'] = '$%s', ['vehicle_dealer'] = 'pojazdy - Sprzedawca aut', diff --git a/locales/sv.lua b/locales/sv.lua index 15618054..0ab74f45 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -1,13 +1,10 @@ Locales['sv'] = { -- global menus - ['not_enough_in_society'] = 'det finns inte tillräckligt många ~r~ det föremålet~s~ i förrådet!', + ['not_enough_in_society'] = 'det finns inte tillräckligt många av ~r~det föremålet~s~ i förrådet!', ['player_cannot_hold'] = 'du har ~r~inte~s~ tillräckligt mycket~y~plats~s~ på dig!', ['vehicle_belongs'] = 'fordonet med reg numret ~y~%s~s~ tillhör nu ~b~dig~s~', ['broke_company'] = 'det finns inte tillräckligt mycket pengar i företagskontot', ['license_missing'] = 'du är inte behörig att köpa bilar, B-körkort krävs!', - ['purchase_type'] = 'till vem är fordonet?', - ['society_type'] = 'företag', - ['staff_type'] = 'personlig användning', ['buy_vehicle_shop'] = 'vill du köpa in %s för %s SEK?', ['buy_vehicle'] = 'Köp in fordon', ['car_dealer'] = 'bilförsäljare', @@ -18,6 +15,7 @@ Locales['sv'] = { ['depop_vehicle'] = 'ställ tillbaka fordonet', ['return_provider'] = 'sälj tillbaka fordon till leverantör', ['get_rented_vehicles'] = 'uthyrda fordon', + ['no_current_vehicle'] = 'du har inget fordon ute till salu', ['invalid_amount'] = 'ogiltigt belopp', ['invoice_amount'] = 'belopp att betala', ['no'] = 'nej', @@ -34,7 +32,6 @@ Locales['sv'] = { ['sell_menu'] = 'tryck ~INPUT_CONTEXT~ för att sälja ~y~%s~s~ för ~g~%s SEK~s~', ['set_vehicle_owner_rent'] = 'hyr ut fordon', ['set_vehicle_owner_sell'] = 'sälj fordon', - ['set_vehicle_owner_sell_society'] = 'sälj fordon till företag', ['shop_menu'] = 'tryck ~INPUT_CONTEXT~ för öppna ~y~bilförsäljarsmenyn~s~.', ['generic_shopitem'] = '%s SEK', ['vehicle_dealer'] = 'bilförsäljare - fordon för visning', diff --git a/server/main.lua b/server/main.lua index 00108026..030141a5 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,5 +1,5 @@ ESX = nil -local Categories, Vehicles = {}, {} +local categories, vehicles = {}, {} TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) @@ -12,7 +12,7 @@ Citizen.CreateThread(function() if Config.PlateUseSpace then char = char + 1 end if char > 8 then - print(('esx_vehicleshop: ^1WARNING^7 plate character count reached, %s/8 characters.'):format(char)) + print(('[esx_vehicleshop] [^3WARNING^7] Plate character count reached, %s/8 characters!'):format(char)) end end) @@ -23,132 +23,117 @@ function RemoveOwnedVehicle(plate) end MySQL.ready(function() - Categories = MySQL.Sync.fetchAll('SELECT * FROM vehicle_categories') - local vehicles = MySQL.Sync.fetchAll('SELECT * FROM vehicles') + MySQL.Async.fetchAll('SELECT * FROM vehicle_categories', {}, function(_categories) + categories = _categories - for i=1, #vehicles, 1 do - local vehicle = vehicles[i] + MySQL.Async.fetchAll('SELECT * FROM vehicles', {}, function(_vehicles) + vehicles = _vehicles - for j=1, #Categories, 1 do - if Categories[j].name == vehicle.category then - vehicle.categoryLabel = Categories[j].label - break + 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 + break + end + end end - end - table.insert(Vehicles, vehicle) + -- send information after db has loaded, making sure everyone gets vehicle information + TriggerClientEvent('esx_vehicleshop:sendCategories', -1, categories) + TriggerClientEvent('esx_vehicleshop:sendVehicles', -1, vehicles) + end) + end) +end) + +function getVehicleLabelFromModel(model) + for k,v in ipairs(vehicles) do + if v.model == model then + return v.name + end end - -- send information after db has loaded, making sure everyone gets vehicle information - TriggerClientEvent('esx_vehicleshop:sendCategories', -1, Categories) - TriggerClientEvent('esx_vehicleshop:sendVehicles', -1, Vehicles) -end) + return +end -RegisterServerEvent('esx_vehicleshop:setVehicleOwned') -AddEventHandler('esx_vehicleshop:setVehicleOwned', function(vehicleProps) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) +RegisterNetEvent('esx_vehicleshop:setVehicleOwnedPlayerId') +AddEventHandler('esx_vehicleshop:setVehicleOwnedPlayerId', function(playerId, vehicleProps, model, label) + local xPlayer, xTarget = ESX.GetPlayerFromId(source), ESX.GetPlayerFromId(playerId) - MySQL.Async.execute('INSERT INTO owned_vehicles (owner, plate, vehicle) VALUES (@owner, @plate, @vehicle)', - { - ['@owner'] = xPlayer.identifier, - ['@plate'] = vehicleProps.plate, - ['@vehicle'] = json.encode(vehicleProps) - }, function(rowsChanged) - xPlayer.showNotification(_U('vehicle_belongs', vehicleProps.plate)) - end) -end) + 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 -RegisterServerEvent('esx_vehicleshop:setVehicleOwnedPlayerId') -AddEventHandler('esx_vehicleshop:setVehicleOwnedPlayerId', function(playerId, vehicleProps) - local xPlayer = ESX.GetPlayerFromId(playerId) + MySQL.Async.execute('DELETE FROM cardealer_vehicles WHERE id = @id', { + ['@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) + xPlayer.showNotification(_U('vehicle_set_owned', vehicleProps.plate, xTarget.getName())) + xTarget.showNotification(_U('vehicle_belongs', vehicleProps.plate)) + end) - MySQL.Async.execute('INSERT INTO owned_vehicles (owner, plate, vehicle) VALUES (@owner, @plate, @vehicle)', - { - ['@owner'] = xPlayer.identifier, - ['@plate'] = vehicleProps.plate, - ['@vehicle'] = json.encode(vehicleProps) - }, function(rowsChanged) - xPlayer.showNotification(_U('vehicle_belongs', vehicleProps.plate)) - end) -end) + local dateNow = os.date('%Y-%m-%d %H:%M') -RegisterServerEvent('esx_vehicleshop:setVehicleOwnedSociety') -AddEventHandler('esx_vehicleshop:setVehicleOwnedSociety', function(society, vehicleProps) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) - - MySQL.Async.execute('INSERT INTO owned_vehicles (owner, plate, vehicle) VALUES (@owner, @plate, @vehicle)', { - ['@owner'] = 'society:' .. society, - ['@plate'] = vehicleProps.plate, - ['@vehicle'] = json.encode(vehicleProps), - }, function(rowsChanged) end) -end) - -RegisterServerEvent('esx_vehicleshop:sellVehicle') -AddEventHandler('esx_vehicleshop:sellVehicle', function(vehicle) - MySQL.Async.fetchAll('SELECT * FROM cardealer_vehicles WHERE vehicle = @vehicle LIMIT 1', { - ['@vehicle'] = vehicle - }, function(result) - local id = result[1].id - - MySQL.Async.execute('DELETE FROM cardealer_vehicles WHERE id = @id', { - ['@id'] = id - }) - end) -end) - -RegisterServerEvent('esx_vehicleshop:addToList') -AddEventHandler('esx_vehicleshop:addToList', function(target, model, plate) - local xPlayer, xTarget = ESX.GetPlayerFromId(source), ESX.GetPlayerFromId(target) - local dateNow = os.date('%Y-%m-%d %H:%M') - - if xPlayer.job.name == 'cardealer' then - MySQL.Async.execute('INSERT INTO vehicle_sold (client, model, plate, soldby, date) VALUES (@client, @model, @plate, @soldby, @date)', { - ['@client'] = xTarget.getName(), - ['@model'] = model, - ['@plate'] = plate, - ['@soldby'] = xPlayer.getName(), - ['@date'] = dateNow - }) - else - print(('esx_vehicleshop: %s attempted to add a sold vehicle to list!'):format(xPlayer.identifier)) + 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 + }) + end + end) + end + end) end end) ESX.RegisterServerCallback('esx_vehicleshop:getSoldVehicles', function(source, cb) - MySQL.Async.fetchAll('SELECT * FROM vehicle_sold', {}, function(result) + MySQL.Async.fetchAll('SELECT client, model, plate, soldby, date FROM vehicle_sold', {}, function(result) cb(result) end) end) -RegisterServerEvent('esx_vehicleshop:rentVehicle') -AddEventHandler('esx_vehicleshop:rentVehicle', function(vehicle, plate, playerName, basePrice, rentPrice, target) - local xPlayer = ESX.GetPlayerFromId(target) +RegisterNetEvent('esx_vehicleshop:rentVehicle') +AddEventHandler('esx_vehicleshop:rentVehicle', function(vehicle, plate, rentPrice, playerId) + local xPlayer, xTarget = ESX.GetPlayerFromId(source), ESX.GetPlayerFromId(playerId) - MySQL.Async.fetchAll('SELECT * FROM cardealer_vehicles WHERE vehicle = @vehicle LIMIT 1', { - ['@vehicle'] = vehicle - }, function(result) - local id = result[1].id - local price = result[1].price - local owner = xPlayer.identifier + 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'] = id - }) - - 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'] = playerName, - ['@base_price'] = basePrice, - ['@rent_price'] = rentPrice, - ['@owner'] = owner - }) - end) + MySQL.Async.execute('DELETE FROM cardealer_vehicles WHERE id = @id', { + ['@id'] = result[1].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) + xPlayer.showNotification(_U('vehicle_set_rented', plate, xTarget.getName())) + end) + end + end) + end + end) + end end) -RegisterServerEvent('esx_vehicleshop:getStockItem') +RegisterNetEvent('esx_vehicleshop:getStockItem') AddEventHandler('esx_vehicleshop:getStockItem', function(itemName, count) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) @@ -173,7 +158,7 @@ AddEventHandler('esx_vehicleshop:getStockItem', function(itemName, count) end) end) -RegisterServerEvent('esx_vehicleshop:putStockItems') +RegisterNetEvent('esx_vehicleshop:putStockItems') AddEventHandler('esx_vehicleshop:putStockItems', function(itemName, count) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) @@ -192,98 +177,107 @@ AddEventHandler('esx_vehicleshop:putStockItems', function(itemName, count) end) ESX.RegisterServerCallback('esx_vehicleshop:getCategories', function(source, cb) - cb(Categories) + cb(categories) end) ESX.RegisterServerCallback('esx_vehicleshop:getVehicles', function(source, cb) - cb(Vehicles) + cb(vehicles) end) -ESX.RegisterServerCallback('esx_vehicleshop:buyVehicle', function(source, cb, vehicleModel) +ESX.RegisterServerCallback('esx_vehicleshop:buyVehicle', function(source, cb, model, plate) local xPlayer = ESX.GetPlayerFromId(source) - local vehicleData + local modelPrice - for i=1, #Vehicles, 1 do - if Vehicles[i].model == vehicleModel then - vehicleData = Vehicles[i] + for k,v in ipairs(vehicles) do + if model == v.model then + modelPrice = v.price break end end - if vehicleData and xPlayer.getMoney() >= vehicleData.price then - xPlayer.removeMoney(vehicleData.price) - cb(true) + 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)}) + }, function(rowsChanged) + xPlayer.showNotification(_U('vehicle_belongs', plate)) + cb(true) + end) else cb(false) end end) -ESX.RegisterServerCallback('esx_vehicleshop:buyVehicleSociety', function(source, cb, society, vehicleModel) - local vehicleData +ESX.RegisterServerCallback('esx_vehicleshop:getCommercialVehicles', function(source, cb) + MySQL.Async.fetchAll('SELECT price, vehicle FROM cardealer_vehicles ORDER BY vehicle ASC', {}, function(result) + cb(result) + end) +end) - for i=1, #Vehicles, 1 do - if Vehicles[i].model == vehicleModel then - vehicleData = Vehicles[i] - break +ESX.RegisterServerCallback('esx_vehicleshop:buyCarDealerVehicle', function(source, cb, model) + 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 + + 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) + cb(true) + end) + else + cb(false) + end + end) end end - - TriggerEvent('esx_addonaccount:getSharedAccount', 'society_' .. society, function(account) - if account.money >= vehicleData.price then - account.removeMoney(vehicleData.price) - - MySQL.Async.execute('INSERT INTO cardealer_vehicles (vehicle, price) VALUES (@vehicle, @price)', { - ['@vehicle'] = vehicleData.model, - ['@price'] = vehicleData.price - }, function(rowsChanged) - cb(true) - end) - else - cb(false) - end - end) end) -ESX.RegisterServerCallback('esx_vehicleshop:getCommercialVehicles', function(source, cb) - MySQL.Async.fetchAll('SELECT * FROM cardealer_vehicles ORDER BY vehicle ASC', {}, function(result) - local vehicles = {} - - for i=1, #result, 1 do - table.insert(vehicles, { - name = result[i].vehicle, - price = result[i].price - }) - end - - cb(vehicles) - end) -end) - - -RegisterServerEvent('esx_vehicleshop:returnProvider') +RegisterNetEvent('esx_vehicleshop:returnProvider') AddEventHandler('esx_vehicleshop:returnProvider', function(vehicleModel) - local _source = source + local xPlayer = ESX.GetPlayerFromId(source) - MySQL.Async.fetchAll('SELECT * FROM cardealer_vehicles WHERE vehicle = @vehicle LIMIT 1', { - ['@vehicle'] = vehicleModel - }, function(result) - if result[1] then - local id = result[1].id - local price = ESX.Math.Round(result[1].price * 0.75) + 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 - TriggerEvent('esx_addonaccount:getSharedAccount', 'society_cardealer', function(account) - account.addMoney(price) - end) + MySQL.Async.execute('DELETE FROM cardealer_vehicles WHERE id = @id', { + ['@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) - MySQL.Async.execute('DELETE FROM cardealer_vehicles WHERE id = @id', { - ['@id'] = id - }) - - xPlayer.showNotification(_U('vehicle_sold_for', vehicleModel, ESX.Math.GroupDigits(price))) - else - print(('esx_vehicleshop: %s attempted selling an invalid vehicle!'):format(GetPlayerIdentifiers(_source)[1])) - end - end) + account.addMoney(price) + xPlayer.showNotification(_U('vehicle_sold_for', vehicleLabel, ESX.Math.GroupDigits(price))) + end) + end + end) + else + print(('[esx_vehicleshop] [^3WARNING^7] %s attempted selling an invalid vehicle!'):format(xPlayer.identifier)) + end + end) + end end) ESX.RegisterServerCallback('esx_vehicleshop:getRentedVehicles', function(source, cb) @@ -303,24 +297,24 @@ ESX.RegisterServerCallback('esx_vehicleshop:getRentedVehicles', function(source, end) ESX.RegisterServerCallback('esx_vehicleshop:giveBackVehicle', function(source, cb, plate) - MySQL.Async.fetchAll('SELECT * FROM rented_vehicles WHERE plate = @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.Async.execute('INSERT INTO cardealer_vehicles (vehicle, price) VALUES (@vehicle, @price)', { - ['@vehicle'] = vehicle, - ['@price'] = basePrice - }) - MySQL.Async.execute('DELETE FROM rented_vehicles WHERE plate = @plate', { ['@plate'] = plate - }) - - RemoveOwnedVehicle(plate) - cb(true) + }, function(rowsChanged) + MySQL.Async.execute('INSERT INTO cardealer_vehicles (vehicle, price) VALUES (@vehicle, @price)', { + ['@vehicle'] = vehicle, + ['@price'] = basePrice + }) + + RemoveOwnedVehicle(plate) + cb(true) + end) else cb(false) end @@ -328,18 +322,18 @@ ESX.RegisterServerCallback('esx_vehicleshop:giveBackVehicle', function(source, c end) ESX.RegisterServerCallback('esx_vehicleshop:resellVehicle', function(source, cb, plate, model) - local resellPrice = 0 + local resellPrice -- calculate the resell price - for i=1, #Vehicles, 1 do - if GetHashKey(Vehicles[i].model) == model then - resellPrice = ESX.Math.Round(Vehicles[i].price / 100 * Config.ResellPercentage) + for i=1, #vehicles, 1 do + if GetHashKey(vehicles[i].model) == model then + resellPrice = ESX.Math.Round(vehicles[i].price / 100 * Config.ResellPercentage) break end end - if resellPrice == 0 then - print(('esx_vehicleshop: %s attempted to sell an unknown vehicle!'):format(GetPlayerIdentifiers(source)[1])) + if not resellPrice then + print(('[esx_vehicleshop] [^3WARNING^7] %s attempted to sell an unknown vehicle!'):format(GetPlayerIdentifiers(source)[1])) cb(false) else MySQL.Async.fetchAll('SELECT * FROM rented_vehicles WHERE plate = @plate', { @@ -363,40 +357,11 @@ ESX.RegisterServerCallback('esx_vehicleshop:resellVehicle', function(source, cb, RemoveOwnedVehicle(plate) cb(true) else - print(('esx_vehicleshop: %s attempted to sell an vehicle with plate mismatch!'):format(xPlayer.identifier)) + print(('[esx_vehicleshop] [^3WARNING^7] %s attempted to sell an vehicle with plate mismatch!'):format(xPlayer.identifier)) cb(false) end else - print(('esx_vehicleshop: %s attempted to sell an vehicle with model mismatch!'):format(xPlayer.identifier)) - cb(false) - end - else - if xPlayer.job.grade_name == 'boss' then - MySQL.Async.fetchAll('SELECT * FROM owned_vehicles WHERE owner = @owner AND @plate = plate', { - ['@owner'] = 'society:' .. xPlayer.job.name, - ['@plate'] = plate - }, function(result) - if result[1] then - local vehicle = json.decode(result[1].vehicle) - - if vehicle.model == model then - if vehicle.plate == plate then - xPlayer.addMoney(resellPrice) - RemoveOwnedVehicle(plate) - cb(true) - else - print(('esx_vehicleshop: %s attempted to sell an vehicle with plate mismatch!'):format(xPlayer.identifier)) - cb(false) - end - else - print(('esx_vehicleshop: %s attempted to sell an vehicle with model mismatch!'):format(xPlayer.identifier)) - cb(false) - end - else - cb(false) - end - end) - else + print(('[esx_vehicleshop] [^3WARNING^7] %s attempted to sell an vehicle with model mismatch!'):format(xPlayer.identifier)) cb(false) end end @@ -439,7 +404,7 @@ ESX.RegisterServerCallback('esx_vehicleshop:retrieveJobVehicles', function(sourc end) end) -RegisterServerEvent('esx_vehicleshop:setJobVehicleState') +RegisterNetEvent('esx_vehicleshop:setJobVehicleState') AddEventHandler('esx_vehicleshop:setJobVehicleState', function(plate, state) local xPlayer = ESX.GetPlayerFromId(source) @@ -449,7 +414,7 @@ AddEventHandler('esx_vehicleshop:setJobVehicleState', function(plate, state) ['@job'] = xPlayer.job.name }, function(rowsChanged) if rowsChanged == 0 then - print(('esx_vehicleshop: %s exploited the garage!'):format(xPlayer.identifier)) + print(('[esx_vehicleshop] [^3WARNING^7] %s exploited the garage!'):format(xPlayer.identifier)) end end) end) From b623f11a73b080f6480821a715b1ec2a84f3e179 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 8 Feb 2020 12:54:45 +0100 Subject: [PATCH 2524/3224] Sort vehicles in chronological order, dont open shop menu if vehicle list is empty --- client/main.lua | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/client/main.lua b/client/main.lua index e6de7966..4814b249 100644 --- a/client/main.lua +++ b/client/main.lua @@ -139,6 +139,11 @@ function StartShopRestriction() end function OpenShopMenu() + if #Vehicles == 0 then + print('[esx_vehicleshop] [^3ERROR^7] No vehicles found') + return + end + IsInShopMenu = true StartShopRestriction() @@ -181,6 +186,8 @@ function OpenShopMenu() table.insert(options, ('%s %s'):format(vehicle.name, _U('generic_shopitem', ESX.Math.GroupDigits(vehicle.price)))) end + table.sort(options) + table.insert(elements, { name = category.name, label = category.label, From 637fe9e80b6b15b3a5bfea7999830951c27323e5 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sat, 8 Feb 2020 14:54:17 +0100 Subject: [PATCH 2525/3224] Added czech locale (#236) * Create cs.lua * Update fxmanifest.lua --- fxmanifest.lua | 2 ++ locales/cs.lua | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 locales/cs.lua diff --git a/fxmanifest.lua b/fxmanifest.lua index 638263f9..e4fe09c4 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -15,6 +15,7 @@ server_scripts { 'locales/fr.lua', 'locales/sv.lua', 'locales/pl.lua', + 'locales/cs.lua', 'config.lua', 'server/main.lua' } @@ -27,6 +28,7 @@ client_scripts { 'locales/fr.lua', 'locales/sv.lua', 'locales/pl.lua', + 'locales/cs.lua', 'config.lua', 'client/utils.lua', 'client/main.lua' diff --git a/locales/cs.lua b/locales/cs.lua new file mode 100644 index 00000000..9725ab8a --- /dev/null +++ b/locales/cs.lua @@ -0,0 +1,63 @@ +Locales['cs'] = { + -- global menus + ['not_enough_in_society'] = 'neni zde dostatek ~r~tohoto predmetu~s~ ve spolecnosti!', + ['player_cannot_hold'] = '~r~nemas~s~ dostatek ~y~volneho mista~s~ ve tvem inventari!', + ['vehicle_belongs'] = 'vozidlo se značkou ~y~%s~s~ nyní patří ~b~tobě~s~', + ['broke_company'] = 'nemáš dostatek peněz na účtě společnosti', + ['license_missing'] = 'nemáš ridicský prukaz!', + ['buy_vehicle_shop'] = 'přeješ si zakoupit %s za $%s?', + ['buy_vehicle'] = 'zakoupit vozidlo', + ['car_dealer'] = 'autosalon', + ['shop_awaiting_model'] = 'vozidlo se právě ~g~STAHUJE & NAČÍTÁ~s~, čekej prosím', + ['create_bill'] = 'vytvořit účtenku', + ['dealer_boss'] = 'prodejce aut - Sef', + ['delivered'] = 'vozidlo bylo ~g~doruceno~s~ dealerovi', + ['depop_vehicle'] = 'vrátit vozidlo do garaze', + ['return_provider'] = 'vratit vozidlo zprostredkovateli', + ['get_rented_vehicles'] = 'vozidla na pujceni', + ['no_current_vehicle'] = 'momentalne nemas zobrazene vozidlo', + ['invalid_amount'] = 'neplatná částka', + ['invoice_amount'] = 'castka na fakture', + ['no'] = 'ne', + ['yes'] = 'ano', + ['no_players'] = 'žádní hráči poblíž tebe', + ['not_enough_money'] = 'nemáš dostatek peněz', + ['not_rental'] = 'tohle není ~r~půjčitelné vozidlo~s~', + ['not_yours'] = 'tohle auto ti nepatří', + ['paid_rental'] = '~g~zaplatil jsii~s~ za pujceni auta: ~g~$%s~s~', + ['pop_vehicle'] = 'vlozit vozidlo k prodeji', + ['rent_vehicle'] = 'autosalon - Vozidla k pujceni', + ['return_provider_menu'] = 'autosalon - Vratit vozidlo zprostredkovateli', + ['rental_amount'] = 'cena pujceni', + ['sell_menu'] = 'stiskni ~INPUT_CONTEXT~ pro prodani ~y~%s~s~ za ~g~$%s~s~', + ['set_vehicle_owner_rent'] = 'pujcit vozidlo', + ['set_vehicle_owner_sell'] = 'prodat vozidlo', + ['shop_menu'] = 'stiskni ~INPUT_CONTEXT~ pro přístup do menu', + ['generic_shopitem'] = '$%s', + ['vehicle_dealer'] = 'vozidlo - Prodejce aut', + ['vehicle_menu'] = 'stiskni ~INPUT_CONTEXT~ pro vraceni vozidla zpet', + ['vehicle_purchased'] = 'zakoupil jsi vozidlo', + ['vehicle_set_owned'] = 'vozidlo ~y~%s~s~ bylo prirazeno ~b~%s~s~', + ['vehicle_set_rented'] = 'vozidlo ~y~%s~s~ bylo pujceno za ~b~%s~s~', + ['vehicle_sold_for'] = '~b~%s~s~ bylo ~y~prodano~s~ za ~g~$%s~s~', + ['vehicle_sold_to'] = 'vozidlo se znackou ~y~%s~s~ bylo prodano za ~b~%s~s~', + ['deposit_stock'] = 'vlozit do skladu', + ['take_stock'] = 'vybraz ze skladu', + ['dealership_stock'] = 'sklad Autosalonu', + ['amount'] = 'castka', + ['quantity_invalid'] = 'to je neplatne mnozstvi', + ['inventory'] = 'inventar', + ['dealership'] = 'autodealer', + ['dealer_customers'] = 'zakaznici dealera', + ['have_withdrawn'] = 'vybral jsi ~y~x%s~s~ ~b~%s~s~', + ['have_deposited'] = 'vlozil jsi ~y~x%s~s~ ~b~%s~s~', + ['boss_actions'] = 'akce šéfa', + + -- sold vehicles + ['boss_sold'] = 'seznam prodaných vozidel', + ['customer_client'] = 'jméno zákazníka', + ['customer_model'] = 'model auta', + ['customer_plate'] = 'značka auta', + ['customer_soldby'] = 'prodáno zaměstnancem', + ['customer_date'] = 'datum', +} From 5c1feb05ad12bc99112a761abf85eece6d68cfdf Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 8 Feb 2020 19:52:41 +0100 Subject: [PATCH 2526/3224] Fixed missing plate --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 030141a5..6ee336f6 100644 --- a/server/main.lua +++ b/server/main.lua @@ -201,7 +201,7 @@ ESX.RegisterServerCallback('esx_vehicleshop:buyVehicle', function(source, cb, mo 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)}) + ['@vehicle'] = json.encode({model = GetHashKey(model), plate = plate}) }, function(rowsChanged) xPlayer.showNotification(_U('vehicle_belongs', plate)) cb(true) From 6a0fcb42b93031afc296e3ab820519f13b455f60 Mon Sep 17 00:00:00 2001 From: Oldarorn <36448848+Oldarorn@users.noreply.github.com> Date: Mon, 10 Feb 2020 22:10:56 +0100 Subject: [PATCH 2527/3224] Update fr.lua --- locales/fr.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index 9a2a8ea4..471d8dc3 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -4,18 +4,18 @@ Locales['fr'] = { ['player_cannot_hold'] = 'vous n\'avez ~r~pas~s~ assez ~y~d\'espace~s~ dans votre inventaire!', ['vehicle_belongs'] = 'le véhicule avec la plaque ~y~%s~s~ est désormais à ~b~vous~s~', ['broke_company'] = 'vous n\avez pas assez d\'argent sur le compte de la societé', - ['license_missing'] = 'you don\'t have a driver\'s license!', + ['license_missing'] = 'vous n\'avez pas de permis de conduire !', ['buy_vehicle_shop'] = 'acheter %s pour $%s?', ['buy_vehicle'] = 'acheter véhicule', ['car_dealer'] = 'concessionnaire', - ['shop_awaiting_model'] = 'the vehicle is currently loading, please wait', + ['shop_awaiting_model'] = 'le véhicule est en train de charger, veuillez patienter...', ['create_bill'] = 'créer facture', ['dealer_boss'] = 'concessionnaire - Patron', ['delivered'] = 'véhicule ~g~rendu~s~ au concessionnaire', ['depop_vehicle'] = 'rentrer véhicule', ['return_provider'] = 'rendre le véhicule', ['get_rented_vehicles'] = 'véhicules en location', - ['no_current_vehicle'] = 'you do not currently have an vehicle displayed', + ['no_current_vehicle'] = 'vous n\'avez aucun véhicule d\'affiché pour le moment', ['invalid_amount'] = 'montant invalide', ['invoice_amount'] = 'montant de la facture', ['no'] = 'non', @@ -28,7 +28,7 @@ Locales['fr'] = { ['pop_vehicle'] = 'sortir véhicule', ['rent_vehicle'] = 'concessionnaire - Véhicules en location', ['return_provider_menu'] = 'concessionnaire - Retour de véhicule', - ['rental_amount'] = 'contant de la location', + ['rental_amount'] = 'montant de la location', ['sell_menu'] = 'appuyez sur ~INPUT_CONTEXT~ pour vendre ~y~%s~s~ au prix de ~g~$%s~s~', ['set_vehicle_owner_rent'] = 'attribuer véhicule [Location]', ['set_vehicle_owner_sell'] = 'attribuer véhicule [Vente]', From 8f0ff81b04156c4d5c413ca33521069b8c801672 Mon Sep 17 00:00:00 2001 From: Oldarorn <36448848+Oldarorn@users.noreply.github.com> Date: Tue, 11 Feb 2020 08:27:01 +0100 Subject: [PATCH 2528/3224] Adding french translation (#16) * Create fr.lua * Update fxmanifest.lua --- fxmanifest.lua | 1 + locales/fr.lua | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 locales/fr.lua diff --git a/fxmanifest.lua b/fxmanifest.lua index 03bc591a..0c38cf9b 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -18,6 +18,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', 'locales/en.lua', + 'locales/fr.lua', 'locales/sv.lua', 'config.lua', 'client/main.lua', diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..c72137a9 --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,31 @@ +Locales['fr'] = { + -- shop + ['boat_shop'] = 'magasin de bateaux', + ['boat_shop_open'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder au ~y~magasin de bateaux~s~.', + ['boat_shop_confirm'] = 'voulez-vous acheter %s pour $%s?', + ['boat_shop_bought'] = 'vous avez ~y~acheté~s~ le ~b~%s~s~ pour ~g~$%s~s~', + ['boat_shop_nomoney'] = 'vous n\'avez pas les moyens ~r~pour acheter~s~ ce bateau !', + ['confirm_no'] = 'non', + ['confirm_yes'] = 'oui', + + -- garage + ['garage'] = 'garage à bateaux', + ['garage_open'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder à votre ~y~garage à bateaux~s~.', + ['garage_store'] = 'appuyez sur ~INPUT_CONTEXT~ pour ~y~ranger~s~ votre bateau dans votre garage.', + ['garage_taken'] = 'le bateau est sorti !', + ['garage_stored'] = 'le bateau a bien été rangé dans votre garage !', + ['garage_noboats'] = 'vous n\'avez aucun bateau ici ! Rendez-vous au ~y~magasin de bateaux~s~ pour en acheter un.', + ['garage_blocked'] = 'le bateau ne peux pas être sorti car un autre véhicule bloque le point !', + ['garage_notowner'] = 'ce bateau ne vous appartient pas !', + + -- license + ['license_menu'] = 'acheter un permis de naviguer', + ['license_buy_no'] = 'non', + ['license_buy_yes'] = 'acheter le permis pour $%s', + ['license_bought'] = 'vous avez acheté le ~y~permis de naviguer~s~ pour ~g~$%s~s~', + ['license_nomoney'] = 'vous n\'avez pas les moyens ~r~pour acheter~s~ ce permis !', + + -- blips + ['blip_garage'] = 'garage à bateaux', + ['blip_shop'] = 'magasin de bateaux', +} From e25f5dee2ec828fa1e80118087813240f1477093 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 11 Feb 2020 11:37:47 +0100 Subject: [PATCH 2529/3224] Temp code revert for loadout updating, fixes ammo sync --- client/main.lua | 1 + server/main.lua | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/client/main.lua b/client/main.lua index 17a3db65..39bdf327 100644 --- a/client/main.lua +++ b/client/main.lua @@ -438,6 +438,7 @@ Citizen.CreateThread(function() if loadoutChanged and isLoadoutLoaded then ESX.PlayerData.loadout = loadout + TriggerServerEvent('esx:updateLoadout', loadout) end end end) diff --git a/server/main.lua b/server/main.lua index 16047c86..329fc379 100644 --- a/server/main.lua +++ b/server/main.lua @@ -236,6 +236,12 @@ AddEventHandler('esx:updateCoords', function(coords) end end) +RegisterNetEvent('esx:updateLoadout') +AddEventHandler('esx:updateLoadout', function(loadout) + local xPlayer = ESX.GetPlayerFromId(source) + xPlayer.loadout = loadout +end) + RegisterNetEvent('esx:giveInventoryItem') AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCount) local playerId = source From f11e97e0a5c64573e3fe525e0dd9eb9084678c08 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 11 Feb 2020 11:50:59 +0100 Subject: [PATCH 2530/3224] Improved ammo label handling, extended weapon configuration file with ammo hash and label --- client/functions.lua | 62 +++++++++-------- config.weapons.lua | 157 +++++++++++++++++++++++++------------------ locales/br.lua | 34 +++++++--- locales/cs.lua | 33 ++++++--- locales/de.lua | 33 ++++++--- locales/en.lua | 33 ++++++--- locales/fi.lua | 33 ++++++--- locales/fr.lua | 33 ++++++--- locales/pl.lua | 33 ++++++--- locales/sv.lua | 37 ++++++---- server/commands.lua | 6 +- server/main.lua | 42 +++++++----- 12 files changed, 345 insertions(+), 191 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index ef8b71cc..f15797ed 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -869,12 +869,12 @@ ESX.ShowInventory = function() local formattedMoney = _U('locale_currency', ESX.Math.GroupDigits(ESX.PlayerData.money)) table.insert(elements, { - label = ('%s: %s'):format(_U('cash'), formattedMoney), - count = ESX.PlayerData.money, - type = 'item_money', - value = 'money', - usable = false, - rare = false, + label = ('%s: %s'):format(_U('cash'), formattedMoney), + count = ESX.PlayerData.money, + type = 'item_money', + value = 'money', + usable = false, + rare = false, canRemove = true }) end @@ -885,12 +885,12 @@ ESX.ShowInventory = function() local canDrop = v.name ~= 'bank' table.insert(elements, { - label = ('%s: %s'):format(v.label, formattedMoney), - count = v.money, - type = 'item_account', - value = v.name, - usable = false, - rare = false, + label = ('%s: %s'):format(v.label, formattedMoney), + count = v.money, + type = 'item_account', + value = v.name, + usable = false, + rare = false, canRemove = canDrop }) end @@ -899,13 +899,14 @@ ESX.ShowInventory = function() for k,v in ipairs(ESX.PlayerData.inventory) do if v.count > 0 then currentWeight = currentWeight + (v.weight * v.count) + table.insert(elements, { - label = ('%s x%s'):format(v.label, v.count), - count = v.count, - type = 'item_standard', - value = v.name, - usable = v.usable, - rare = v.rare, + label = ('%s x%s'):format(v.label, v.count), + count = v.count, + type = 'item_standard', + value = v.name, + usable = v.usable, + rare = v.rare, canRemove = v.canRemove }) end @@ -915,16 +916,23 @@ ESX.ShowInventory = function() local weaponHash = GetHashKey(v.name) if HasPedGotWeapon(playerPed, weaponHash, false) then - local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) + local ammo, label = GetAmmoInPedWeapon(playerPed, weaponHash) + + if v.ammo then + label = ('%s - %s %s'):format(v.label, ammo, v.ammo.label) + else + label = v.label + end table.insert(elements, { - label = ('%s [%s]'):format(v.label, ammo), - count = 1, - type = 'item_weapon', - value = v.name, - ammo = ammo, - usable = false, - rare = false, + label = label, + count = 1, + type = 'item_weapon', + value = v.name, + usable = false, + rare = false, + ammo = ammo, + canGiveAmmo = (v.ammo ~= nil), canRemove = true }) end @@ -953,7 +961,7 @@ ESX.ShowInventory = function() table.insert(elements, {label = _U('remove'), action = 'remove', type = data.current.type, value = data.current.value}) end - if data.current.type == 'item_weapon' and data.current.ammo > 0 and player ~= -1 and distance <= 3.0 then + if data.current.type == 'item_weapon' and data.current.canGiveAmmo and data.current.ammo > 0 and player ~= -1 and distance <= 3.0 then table.insert(elements, {label = _U('giveammo'), action = 'give_ammo', type = data.current.type, value = data.current.value}) end diff --git a/config.weapons.lua b/config.weapons.lua index 8dd7676c..037062fc 100644 --- a/config.weapons.lua +++ b/config.weapons.lua @@ -1,14 +1,8 @@ Config.Weapons = { - {name = 'WEAPON_KNIFE', label = _U('weapon_knife'), components = {}}, - {name = 'WEAPON_NIGHTSTICK', label = _U('weapon_nightstick'), components = {}}, - {name = 'WEAPON_HAMMER', label = _U('weapon_hammer'), components = {}}, - {name = 'WEAPON_BAT', label = _U('weapon_bat'), components = {}}, - {name = 'WEAPON_GOLFCLUB', label = _U('weapon_golfclub'), components = {}}, - {name = 'WEAPON_CROWBAR', label = _U('weapon_crowbar'), components = {}}, - { name = 'WEAPON_PISTOL', label = _U('weapon_pistol'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_PISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_PISTOL_CLIP_02')}, @@ -21,6 +15,7 @@ Config.Weapons = { { name = 'WEAPON_COMBATPISTOL', label = _U('weapon_combatpistol'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATPISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATPISTOL_CLIP_02')}, @@ -33,6 +28,7 @@ Config.Weapons = { { name = 'WEAPON_APPISTOL', label = _U('weapon_appistol'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_APPISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_APPISTOL_CLIP_02')}, @@ -45,6 +41,7 @@ Config.Weapons = { { name = 'WEAPON_PISTOL50', label = _U('weapon_pistol50'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_PISTOL50_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_PISTOL50_CLIP_02')}, @@ -54,11 +51,10 @@ Config.Weapons = { } }, - {name = 'WEAPON_REVOLVER', label = _U('weapon_revolver'), components = {}}, - { name = 'WEAPON_SNSPISTOL', label = _U('weapon_snspistol'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SNSPISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SNSPISTOL_CLIP_02')}, @@ -69,6 +65,7 @@ Config.Weapons = { { name = 'WEAPON_HEAVYPISTOL', label = _U('weapon_heavypistol'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_HEAVYPISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_HEAVYPISTOL_CLIP_02')}, @@ -81,6 +78,7 @@ Config.Weapons = { { name = 'WEAPON_VINTAGEPISTOL', label = _U('weapon_vintagepistol'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_VINTAGEPISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_VINTAGEPISTOL_CLIP_02')}, @@ -89,21 +87,25 @@ Config.Weapons = { }, { - name = 'WEAPON_MICROSMG', - label = _U('weapon_microsmg'), + name = 'WEAPON_MACHINEPISTOL', + label = _U('weapon_machinepistol'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, components = { - {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MICROSMG_CLIP_01')}, - {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MICROSMG_CLIP_02')}, - {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH')}, - {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO')}, - {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, - {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_MICROSMG_VARMOD_LUXE')} + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_02')}, + {name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_03')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP')} } }, + {name = 'WEAPON_REVOLVER', label = _U('weapon_revolver'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}}, + {name = 'WEAPON_MARKSMANPISTOL', label = _U('weapon_marksmanpistol'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}}, + {name = 'WEAPON_DOUBLEACTION', label = _U('weapon_doubleaction'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}}, + { name = 'WEAPON_SMG', label = _U('weapon_smg'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SMG')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SMG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SMG_CLIP_02')}, @@ -118,6 +120,7 @@ Config.Weapons = { { name = 'WEAPON_ASSAULTSMG', label = _U('weapon_assaultsmg'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SMG')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTSMG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTSMG_CLIP_02')}, @@ -128,29 +131,34 @@ Config.Weapons = { } }, + { + name = 'WEAPON_MICROSMG', + label = _U('weapon_microsmg'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SMG')}, + components = { + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MICROSMG_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MICROSMG_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_MICROSMG_VARMOD_LUXE')} + } + }, + { name = 'WEAPON_MINISMG', label = _U('weapon_minismg'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SMG')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MINISMG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MINISMG_CLIP_02')} } }, - { - name = 'WEAPON_MACHINEPISTOL', - label = _U('weapon_machinepistol'), - components = { - {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_01')}, - {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_02')}, - {name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_03')}, - {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP')} - } - }, - { name = 'WEAPON_COMBATPDW', label = _U('weapon_combatpdw'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SMG')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATPDW_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATPDW_CLIP_02')}, @@ -160,10 +168,11 @@ Config.Weapons = { {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_SMALL')} } }, - + { name = 'WEAPON_PUMPSHOTGUN', label = _U('weapon_pumpshotgun'), + ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}, components = { {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_SR_SUPP')}, @@ -174,6 +183,7 @@ Config.Weapons = { { name = 'WEAPON_SAWNOFFSHOTGUN', label = _U('weapon_sawnoffshotgun'), + ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}, components = { {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SAWNOFFSHOTGUN_VARMOD_LUXE')} } @@ -182,6 +192,7 @@ Config.Weapons = { { name = 'WEAPON_ASSAULTSHOTGUN', label = _U('weapon_assaultshotgun'), + ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTSHOTGUN_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTSHOTGUN_CLIP_02')}, @@ -194,6 +205,7 @@ Config.Weapons = { { name = 'WEAPON_BULLPUPSHOTGUN', label = _U('weapon_bullpupshotgun'), + ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}, components = { {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, @@ -204,6 +216,7 @@ Config.Weapons = { { name = 'WEAPON_HEAVYSHOTGUN', label = _U('weapon_heavyshotgun'), + ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_HEAVYSHOTGUN_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_HEAVYSHOTGUN_CLIP_02')}, @@ -214,9 +227,14 @@ Config.Weapons = { } }, + {name = 'WEAPON_DBSHOTGUN', label = _U('weapon_dbshotgun'), components = {}, ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}}, + {name = 'WEAPON_AUTOSHOTGUN', label = _U('weapon_autoshotgun'), components = {}, ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}}, + {name = 'WEAPON_MUSKET', label = _U('weapon_musket'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SHOTGUN')}}, + { name = 'WEAPON_ASSAULTRIFLE', label = _U('weapon_assaultrifle'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_CLIP_02')}, @@ -232,6 +250,7 @@ Config.Weapons = { { name = 'WEAPON_CARBINERIFLE', label = _U('weapon_carbinerifle'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_CARBINERIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_CARBINERIFLE_CLIP_02')}, @@ -247,6 +266,7 @@ Config.Weapons = { { name = 'WEAPON_ADVANCEDRIFLE', label = _U('weapon_advancedrifle'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ADVANCEDRIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ADVANCEDRIFLE_CLIP_02')}, @@ -260,6 +280,7 @@ Config.Weapons = { { name = 'WEAPON_SPECIALCARBINE', label = _U('weapon_specialcarbine'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_CLIP_02')}, @@ -275,6 +296,7 @@ Config.Weapons = { { name = 'WEAPON_BULLPUPRIFLE', label = _U('weapon_bullpuprifle'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_BULLPUPRIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_BULLPUPRIFLE_CLIP_02')}, @@ -289,6 +311,7 @@ Config.Weapons = { { name = 'WEAPON_COMPACTRIFLE', label = _U('weapon_compactrifle'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMPACTRIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMPACTRIFLE_CLIP_02')}, @@ -299,6 +322,7 @@ Config.Weapons = { { name = 'WEAPON_MG', label = _U('weapon_mg'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_MG')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MG_CLIP_02')}, @@ -310,6 +334,7 @@ Config.Weapons = { { name = 'WEAPON_COMBATMG', label = _U('weapon_combatmg'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_MG')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATMG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATMG_CLIP_02')}, @@ -322,6 +347,7 @@ Config.Weapons = { { name = 'WEAPON_GUSENBERG', label = _U('weapon_gusenberg'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_MG')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_GUSENBERG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_GUSENBERG_CLIP_02')}, @@ -331,6 +357,7 @@ Config.Weapons = { { name = 'WEAPON_SNIPERRIFLE', label = _U('weapon_sniperrifle'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SNIPER')}, components = { {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_LARGE')}, {name = 'scope_advanced', label = _U('component_scope_advanced'), hash = GetHashKey('COMPONENT_AT_SCOPE_MAX')}, @@ -342,6 +369,7 @@ Config.Weapons = { { name = 'WEAPON_HEAVYSNIPER', label = _U('weapon_heavysniper'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SNIPER')}, components = { {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_LARGE')}, {name = 'scope_advanced', label = _U('component_scope_advanced'), hash = GetHashKey('COMPONENT_AT_SCOPE_MAX')} @@ -351,6 +379,7 @@ Config.Weapons = { { name = 'WEAPON_MARKSMANRIFLE', label = _U('weapon_marksmanrifle'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SNIPER')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MARKSMANRIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MARKSMANRIFLE_CLIP_02')}, @@ -362,46 +391,44 @@ Config.Weapons = { } }, - {name = 'WEAPON_GRENADELAUNCHER', label = _U('weapon_grenadelauncher'), components = {}}, - {name = 'WEAPON_RPG', label = _U('weapon_rpg'), components = {}}, - {name = 'WEAPON_STINGER', label = _U('weapon_stinger'), components = {}}, - {name = 'WEAPON_MINIGUN', label = _U('weapon_minigun'), components = {}}, - {name = 'WEAPON_GRENADE', label = _U('weapon_grenade'), components = {}}, - {name = 'WEAPON_STICKYBOMB', label = _U('weapon_stickybomb'), components = {}}, - {name = 'WEAPON_SMOKEGRENADE', label = _U('weapon_smokegrenade'), components = {}}, - {name = 'WEAPON_BZGAS', label = _U('weapon_bzgas'), components = {}}, - {name = 'WEAPON_MOLOTOV', label = _U('weapon_molotov'), components = {}}, - {name = 'WEAPON_FIREEXTINGUISHER', label = _U('weapon_fireextinguisher'), components = {}}, - {name = 'WEAPON_PETROLCAN', label = _U('weapon_petrolcan'), components = {}}, - {name = 'WEAPON_DIGISCANNER', label = _U('weapon_digiscanner'), components = {}}, - {name = 'WEAPON_BALL', label = _U('weapon_ball'), components = {}}, - {name = 'WEAPON_BOTTLE', label = _U('weapon_bottle'), components = {}}, - {name = 'WEAPON_DAGGER', label = _U('weapon_dagger'), components = {}}, - {name = 'WEAPON_FIREWORK', label = _U('weapon_firework'), components = {}}, - {name = 'WEAPON_MUSKET', label = _U('weapon_musket'), components = {}}, + {name = 'WEAPON_FIREEXTINGUISHER', label = _U('weapon_fireextinguisher'), components = {}, ammo = {label = _U('ammo_charge'), hash = GetHashKey('AMMO_FIREEXTINGUISHER')}}, + {name = 'WEAPON_PETROLCAN', label = _U('weapon_petrolcan'), components = {}, ammo = {label = _U('ammo_petrol'), hash = GetHashKey('AMMO_PETROLCAN')}}, + {name = 'WEAPON_MINIGUN', label = _U('weapon_minigun'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_MINIGUN')}}, + {name = 'WEAPON_RAILGUN', label = _U('weapon_railgun'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RAILGUN')}}, {name = 'WEAPON_STUNGUN', label = _U('weapon_stungun'), components = {}}, - {name = 'WEAPON_HOMINGLAUNCHER', label = _U('weapon_hominglauncher'), components = {}}, - {name = 'WEAPON_PROXMINE', label = _U('weapon_proxmine'), components = {}}, - {name = 'WEAPON_SNOWBALL', label = _U('weapon_snowball'), components = {}}, - {name = 'WEAPON_FLAREGUN', label = _U('weapon_flaregun'), components = {}}, - {name = 'WEAPON_GARBAGEBAG', label = _U('weapon_garbagebag'), components = {}}, - {name = 'WEAPON_HANDCUFFS', label = _U('weapon_handcuffs'), components = {}}, - {name = 'WEAPON_MARKSMANPISTOL', label = _U('weapon_marksmanpistol'), components = {}}, + {name = 'WEAPON_FIREWORK', label = _U('weapon_firework'), components = {}, ammo = {label = _U('ammo_firework'), hash = GetHashKey('AMMO_FIREWORK')}}, + {name = 'WEAPON_RPG', label = _U('weapon_rpg'), components = {}, ammo = {label = _U('ammo_rockets'), hash = GetHashKey('AMMO_RPG')}}, + {name = 'WEAPON_HOMINGLAUNCHER', label = _U('weapon_hominglauncher'), components = {}, ammo = {label = _U('ammo_rockets'), hash = GetHashKey('AMMO_HOMINGLAUNCHER')}}, + {name = 'WEAPON_GRENADELAUNCHER', label = _U('weapon_grenadelauncher'), components = {}, ammo = {label = _U('ammo_grenadelauncher'), hash = GetHashKey('AMMO_GRENADELAUNCHER')}}, + {name = 'WEAPON_COMPACTLAUNCHER', label = _U('weapon_compactlauncher'), components = {}, ammo = {label = _U('ammo_grenadelauncher'), hash = GetHashKey('AMMO_GRENADELAUNCHER')}}, + {name = 'WEAPON_FLASHLIGHT', label = _U('weapon_flashlight'), components = {}}, + {name = 'GADGET_PARACHUTE', label = _U('gadget_parachute'), components = {}}, + {name = 'WEAPON_KNUCKLE', label = _U('weapon_knuckle'), components = {}}, {name = 'WEAPON_HATCHET', label = _U('weapon_hatchet'), components = {}}, - {name = 'WEAPON_RAILGUN', label = _U('weapon_railgun'), components = {}}, {name = 'WEAPON_MACHETE', label = _U('weapon_machete'), components = {}}, {name = 'WEAPON_SWITCHBLADE', label = _U('weapon_switchblade'), components = {}}, - {name = 'WEAPON_DBSHOTGUN', label = _U('weapon_dbshotgun'), components = {}}, - {name = 'WEAPON_AUTOSHOTGUN', label = _U('weapon_autoshotgun'), components = {}}, - {name = 'WEAPON_BATTLEAXE', label = _U('weapon_battleaxe'), components = {}}, - {name = 'WEAPON_COMPACTLAUNCHER', label = _U('weapon_compactlauncher'), components = {}}, - {name = 'WEAPON_PIPEBOMB', label = _U('weapon_pipebomb'), components = {}}, + {name = 'WEAPON_BOTTLE', label = _U('weapon_bottle'), components = {}}, + {name = 'WEAPON_DAGGER', label = _U('weapon_dagger'), components = {}}, {name = 'WEAPON_POOLCUE', label = _U('weapon_poolcue'), components = {}}, {name = 'WEAPON_WRENCH', label = _U('weapon_wrench'), components = {}}, - {name = 'WEAPON_FLASHLIGHT', label = _U('weapon_flashlight'), components = {}}, - {name = 'GADGET_NIGHTVISION', label = _U('gadget_nightvision'), components = {}}, - {name = 'GADGET_PARACHUTE', label = _U('gadget_parachute'), components = {}}, - {name = 'WEAPON_FLARE', label = _U('weapon_flare'), components = {}}, - {name = 'WEAPON_DOUBLEACTION', label = _U('weapon_doubleaction'), components = {}} -} \ No newline at end of file + {name = 'WEAPON_BATTLEAXE', label = _U('weapon_battleaxe'), components = {}}, + {name = 'WEAPON_KNIFE', label = _U('weapon_knife'), components = {}}, + {name = 'WEAPON_NIGHTSTICK', label = _U('weapon_nightstick'), components = {}}, + {name = 'WEAPON_HAMMER', label = _U('weapon_hammer'), components = {}}, + {name = 'WEAPON_BAT', label = _U('weapon_bat'), components = {}}, + {name = 'WEAPON_GOLFCLUB', label = _U('weapon_golfclub'), components = {}}, + {name = 'WEAPON_CROWBAR', label = _U('weapon_crowbar'), components = {}}, + + {name = 'WEAPON_GRENADE', label = _U('weapon_grenade'), components = {}, ammo = {label = _U('ammo_grenade'), hash = GetHashKey('AMMO_GRENADE')}}, + {name = 'WEAPON_STICKYBOMB', label = _U('weapon_stickybomb'), components = {}, ammo = {label = _U('ammo_stickybomb'), hash = GetHashKey('AMMO_STICKYBOMB')}}, + {name = 'WEAPON_PIPEBOMB', label = _U('weapon_pipebomb'), components = {}, ammo = {label = _U('ammo_pipebomb'), hash = GetHashKey('AMMO_PIPEBOMB')}}, + {name = 'WEAPON_SMOKEGRENADE', label = _U('weapon_smokegrenade'), components = {}, ammo = {label = _U('ammo_smokebomb'), hash = GetHashKey('AMMO_SMOKEGRENADE')}}, + {name = 'WEAPON_BZGAS', label = _U('weapon_bzgas'), components = {}, ammo = {label = _U('ammo_bzgas'), hash = GetHashKey('AMMO_BZGAS')}}, + {name = 'WEAPON_MOLOTOV', label = _U('weapon_molotov'), components = {}, ammo = {label = _U('ammo_molotov'), hash = GetHashKey('AMMO_MOLOTOV')}}, + {name = 'WEAPON_PROXMINE', label = _U('weapon_proxmine'), components = {}, ammo = {label = _U('ammo_proxmine'), hash = GetHashKey('AMMO_PROXMINE')}}, + {name = 'WEAPON_BALL', label = _U('weapon_ball'), components = {}, ammo = {label = _U('ammo_ball'), hash = GetHashKey('AMMO_BALL')}}, + {name = 'WEAPON_SNOWBALL', label = _U('weapon_snowball'), components = {}, ammo = {label = _U('ammo_snowball'), hash = GetHashKey('AMMO_SNOWBALL')}}, + {name = 'WEAPON_FLARE', label = _U('weapon_flare'), components = {}, ammo = {label = _U('ammo_flare'), hash = GetHashKey('AMMO_FLARE')}}, + {name = 'WEAPON_FLAREGUN', label = _U('weapon_flaregun'), components = {}, ammo = {label = _U('ammo_flaregun'), hash = GetHashKey('AMMO_FLAREGUN')}} +} diff --git a/locales/br.lua b/locales/br.lua index af7e0f9a..7b69f877 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -14,20 +14,19 @@ Locales['br'] = { ['gave_item'] = 'voce deu ~y~%sx~s~ ~b~%s~s~ para ~y~%s~s~', ['received_item'] = 'voce recebeu ~y~%sx~s~ ~b~%s~s~ de ~b~%s~s~', ['gave_weapon'] = 'você deu ~b~%s~s~ para ~y~%s~s~', - ['gave_weapon_ammo'] = 'você deu ~o~%sx~s~ balas para ~b~%s~s~ de ~y~%s~s~', - ['gave_weapon_withammo'] = 'você deu ~b~%s~s~ com ~o~%sx~s~ balas para ~y~%s~s~', + ['gave_weapon_ammo'] = 'você deu ~o~%sx %s~s~ para ~b~%s~s~ de ~y~%s~s~', + ['gave_weapon_withammo'] = 'você deu ~b~%s~s~ com ~o~%sx %s~s~ para ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ já tem um(a) ~y~%s~s~', ['gave_weapon_noweapon'] = 'não tem essa arma ~y~%s~s~', ['received_weapon'] = 'você recebeu ~b~%s~s~ de ~b~%s~s~', - ['received_weapon_ammo'] = 'você recebeu ~o~%sx~s~ balas para a sua(o seu) ~b~%s~s~ de ~b~%s~s~', - ['received_weapon_withammo'] = 'você recebeu ~b~%s~s~ com ~o~%sx~s~ balas de ~b~%s~s~', + ['received_weapon_ammo'] = 'você recebeu ~o~%sx %s~s~ para a sua(o seu) ~b~%s~s~ de ~b~%s~s~', + ['received_weapon_withammo'] = 'você recebeu ~b~%s~s~ com ~o~%sx %s~s~ de ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ tentou lhe dar uma ~y~%s~s~, mas você já tem um(a)', ['received_weapon_noweapon'] = '~b~%s~s~ tentou lhe dar munição para ~y~%s~s~, mas você não tem um(a)', ['gave_money'] = 'voce deu ~g~$%s~s~ para ~y~%s~s~', ['received_money'] = 'voce recebeu ~g~$%s~s~ de ~b~%s~s~', ['gave_account_money'] = 'voce deu ~g~$%s~s~ (%s) para ~y~%s~s~', ['received_account_money'] = 'voce recebeu ~g~$%s~s~ (%s) de ~b~%s~s~', - ['amount_invalid'] = 'quantidade inválida', ['players_nearby'] = 'nenhum cidadão por perto', ['ex_inv_lim'] = 'ação não e possivel, excedendo o limite de estoque para ~y~%s~s~', @@ -37,7 +36,7 @@ Locales['br'] = { ['threw_money'] = 'você jogou ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'você jogou ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'você jogou ~b~%s~s~', - ['threw_weapon_ammo'] = 'você jogou ~b~%s~s~ com ~o~%sx~s~ balas', + ['threw_weapon_ammo'] = 'você jogou ~b~%s~s~ com ~o~%sx %s~s~', ['threw_weapon_already'] = 'você já esta com essa arma', ['threw_cannot_pickup'] = 'você não pode pegar porque seu inventário está cheio!', ['threw_pickup_prompt'] = 'pressione ~y~E~s~ para pegar', @@ -112,7 +111,6 @@ Locales['br'] = { ['weapon_heavysniper'] = 'heavy sniper', ['weapon_grenadelauncher'] = 'lançador de granada', ['weapon_rpg'] = 'lançador de foguetes', - ['weapon_stinger'] = 'stinger', ['weapon_minigun'] = 'minigun', ['weapon_grenade'] = 'granada', ['weapon_stickybomb'] = 'bomba pegajosa', @@ -121,7 +119,6 @@ Locales['br'] = { ['weapon_molotov'] = 'molotov', ['weapon_fireextinguisher'] = 'extintor', ['weapon_petrolcan'] = 'galao de combustivel', - ['weapon_digiscanner'] = 'digiscanner', ['weapon_ball'] = 'bola', ['weapon_snspistol'] = 'sns pistol', ['weapon_bottle'] = 'garrafa', @@ -139,8 +136,6 @@ Locales['br'] = { ['weapon_proxmine'] = 'mina de proximidade', ['weapon_snowball'] = 'bola de neve', ['weapon_flaregun'] = 'sinalizador', - ['weapon_garbagebag'] = 'saco de lixo', - ['weapon_handcuffs'] = 'algemas', ['weapon_combatpdw'] = 'combat pdw', ['weapon_marksmanpistol'] = 'marksman pistol', ['weapon_knuckle'] = 'soco ingles', @@ -160,7 +155,6 @@ Locales['br'] = { ['weapon_poolcue'] = 'taco de sinuca', ['weapon_wrench'] = 'chave de cano', ['weapon_flashlight'] = 'laterna', - ['gadget_nightvision'] = 'visao noturna', ['gadget_parachute'] = 'paraquedas', ['weapon_flare'] = 'flare', ['weapon_doubleaction'] = 'double-Action Revolver', @@ -176,4 +170,22 @@ Locales['br'] = { ['component_suppressor'] = 'supressor', ['component_grip'] = 'grip', ['component_luxary_finish'] = 'acabamento de arma de luxo', + + -- Weapon Ammo + ['ammo_rounds'] = 'round(s)', + ['ammo_shells'] = 'shell(s)', + ['ammo_charge'] = 'charge', + ['ammo_petrol'] = 'gallons of fuel', + ['ammo_firework'] = 'firework(s)', + ['ammo_rockets'] = 'rocket(s)', + ['ammo_grenadelauncher'] = 'grenade(s)', + ['ammo_grenade'] = 'grenade(s)', + ['ammo_stickybomb'] = 'bomb(s)', + ['ammo_pipebomb'] = 'bomb(s)', + ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_bzgas'] = 'can(s)', + ['ammo_ball'] = 'ball(s)', + ['ammo_snowball'] = 'snowball(s)', + ['ammo_flare'] = 'flare(s)', + ['ammo_flaregun'] = 'flare(s)', } diff --git a/locales/cs.lua b/locales/cs.lua index 7c537b59..565d764d 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -14,13 +14,13 @@ Locales['cs'] = { ['gave_item'] = 'dali jste ~y~%sx~s~ ~b~%s~s~ ~y~%s~s~', ['received_item'] = 'obdrželi jste ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', ['gave_weapon'] = 'you gave ~b~%s~s~ to ~y~%s~s~', - ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', - ['gave_weapon_withammo'] = 'you gave ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx %s~s~ for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'you gave ~b~%s~s~ with ~o~%sx %s~s~ to ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', ['received_weapon'] = 'you received ~b~%s~s~ from ~b~%s~s~', - ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', - ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx %s~s~ for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx %s~s~ from ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', ['gave_money'] = 'dali jste ~g~$%s~s~ ~y~%s~s~', @@ -36,7 +36,7 @@ Locales['cs'] = { ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx %s~s~', ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', @@ -111,7 +111,6 @@ Locales['cs'] = { ['weapon_heavysniper'] = 'heavy sniper', ['weapon_grenadelauncher'] = 'grenade launcher', ['weapon_rpg'] = 'rocket launcher', - ['weapon_stinger'] = 'stinger', ['weapon_minigun'] = 'minigun', ['weapon_grenade'] = 'grenade', ['weapon_stickybomb'] = 'sticky bomb', @@ -120,7 +119,6 @@ Locales['cs'] = { ['weapon_molotov'] = 'molotov cocktail', ['weapon_fireextinguisher'] = 'fire extinguisher', ['weapon_petrolcan'] = 'jerrycan', - ['weapon_digiscanner'] = 'digiscanner', ['weapon_ball'] = 'ball', ['weapon_snspistol'] = 'sns pistol', ['weapon_bottle'] = 'bottle', @@ -138,8 +136,6 @@ Locales['cs'] = { ['weapon_proxmine'] = 'proximity mine', ['weapon_snowball'] = 'snow ball', ['weapon_flaregun'] = 'flaregun', - ['weapon_garbagebag'] = 'garbage bag', - ['weapon_handcuffs'] = 'handcuffs', ['weapon_combatpdw'] = 'combat pdw', ['weapon_marksmanpistol'] = 'marksman pistol', ['weapon_knuckle'] = 'knuckledusters', @@ -159,7 +155,6 @@ Locales['cs'] = { ['weapon_poolcue'] = 'pool cue', ['weapon_wrench'] = 'pipe wrench', ['weapon_flashlight'] = 'flashlight', - ['gadget_nightvision'] = 'night vision', ['gadget_parachute'] = 'parachute', ['weapon_flare'] = 'flare gun', ['weapon_doubleaction'] = 'double-Action Revolver', @@ -175,4 +170,22 @@ Locales['cs'] = { ['component_suppressor'] = 'suppressor', ['component_grip'] = 'grip', ['component_luxary_finish'] = 'luxary Weapon Finish', + + -- Weapon Ammo + ['ammo_rounds'] = 'round(s)', + ['ammo_shells'] = 'shell(s)', + ['ammo_charge'] = 'charge', + ['ammo_petrol'] = 'gallons of fuel', + ['ammo_firework'] = 'firework(s)', + ['ammo_rockets'] = 'rocket(s)', + ['ammo_grenadelauncher'] = 'grenade(s)', + ['ammo_grenade'] = 'grenade(s)', + ['ammo_stickybomb'] = 'bomb(s)', + ['ammo_pipebomb'] = 'bomb(s)', + ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_bzgas'] = 'can(s)', + ['ammo_ball'] = 'ball(s)', + ['ammo_snowball'] = 'snowball(s)', + ['ammo_flare'] = 'flare(s)', + ['ammo_flaregun'] = 'flare(s)', } diff --git a/locales/de.lua b/locales/de.lua index 4a9a5f7f..63b4c090 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -14,13 +14,13 @@ Locales['de'] = { ['gave_item'] = 'du gibst ~y~%sx~s~ ~b~%s~s~ an ~y~%s~s~', ['received_item'] = 'du empfängst ~y~%sx~s~ ~b~%s~s~ von ~b~%s~s~', ['gave_weapon'] = 'du gibst ~b~%s~s~ an ~y~%s~s~', - ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', - ['gave_weapon_withammo'] = 'du gibst ~b~%s~s~ mit ~o~%sx~s~ Schuss an ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx %s~s~ for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'du gibst ~b~%s~s~ mit ~o~%sx %s~s~ an ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ hat bereits eine(n) ~y~%s~s~', ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', ['received_weapon'] = 'du erhälst ~b~%s~s~ von ~b~%s~s~', - ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', - ['received_weapon_withammo'] = 'du erhälst ~b~%s~s~ mit ~o~%sx~s~ Schuss von ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx %s~s~ for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'du erhälst ~b~%s~s~ mit ~o~%sx %s~s~ von ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ hat versucht dir eine(n) ~y~%s~s~ zu geben, aber du hast bereits eine(n)', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', ['gave_money'] = 'du gibst ~g~$%s~s~ an ~y~%s~s~', @@ -36,7 +36,7 @@ Locales['de'] = { ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx %s~s~', ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', @@ -110,7 +110,6 @@ Locales['de'] = { ['weapon_heavysniper'] = 'Schweres Sniper', ['weapon_grenadelauncher'] = 'Granatwerfer', ['weapon_rpg'] = 'RPG', - ['weapon_stinger'] = 'Stinger', ['weapon_minigun'] = 'Minigun', ['weapon_grenade'] = 'Granate', ['weapon_stickybomb'] = 'Haftbombe', @@ -119,7 +118,6 @@ Locales['de'] = { ['weapon_molotov'] = 'Molotov Cocktail', ['weapon_fireextinguisher'] = 'Feuerlöscher', ['weapon_petrolcan'] = 'Benzinkanister', - ['weapon_digiscanner'] = 'Digiscanner', ['weapon_ball'] = 'Ball', ['weapon_snspistol'] = 'SNS Pistole', ['weapon_bottle'] = 'Flasche', @@ -137,8 +135,6 @@ Locales['de'] = { ['weapon_proxmine'] = 'Annäherungsmine', ['weapon_snowball'] = 'Schneeball', ['weapon_flaregun'] = 'Leuchtpistole', - ['weapon_garbagebag'] = 'Müllsack', - ['weapon_handcuffs'] = 'Handschellen', ['weapon_combatpdw'] = 'Kampf PDW', ['weapon_marksmanpistol'] = 'Marksman Pistole', ['weapon_knuckle'] = 'Schlagring', @@ -158,7 +154,6 @@ Locales['de'] = { ['weapon_poolcue'] = 'Kö', ['weapon_wrench'] = 'Rohrzange', ['weapon_flashlight'] = 'Taschenlampe', - ['gadget_nightvision'] = 'Nachtsichtgerät', ['gadget_parachute'] = 'Fallschirm', ['weapon_flare'] = 'Leuchtpistole', ['weapon_doubleaction'] = 'double-Action Revolver', @@ -174,4 +169,22 @@ Locales['de'] = { ['component_suppressor'] = 'suppressor', ['component_grip'] = 'grip', ['component_luxary_finish'] = 'luxary Weapon Finish', + + -- Weapon Ammo + ['ammo_rounds'] = 'round(s)', + ['ammo_shells'] = 'shell(s)', + ['ammo_charge'] = 'charge', + ['ammo_petrol'] = 'gallons of fuel', + ['ammo_firework'] = 'firework(s)', + ['ammo_rockets'] = 'rocket(s)', + ['ammo_grenadelauncher'] = 'grenade(s)', + ['ammo_grenade'] = 'grenade(s)', + ['ammo_stickybomb'] = 'bomb(s)', + ['ammo_pipebomb'] = 'bomb(s)', + ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_bzgas'] = 'can(s)', + ['ammo_ball'] = 'ball(s)', + ['ammo_snowball'] = 'snowball(s)', + ['ammo_flare'] = 'flare(s)', + ['ammo_flaregun'] = 'flare(s)', } diff --git a/locales/en.lua b/locales/en.lua index a41b982d..a7207cad 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -14,13 +14,13 @@ Locales['en'] = { ['gave_item'] = 'you gave ~y~%sx~s~ ~b~%s~s~ to ~y~%s~s~', ['received_item'] = 'you received ~y~%sx~s~ ~b~%s~s~ from ~b~%s~s~', ['gave_weapon'] = 'you gave ~b~%s~s~ to ~y~%s~s~', - ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', - ['gave_weapon_withammo'] = 'you gave ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx %s~s~ for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'you gave ~b~%s~s~ with ~o~%sx %s~s~ to ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', ['received_weapon'] = 'you received ~b~%s~s~ from ~b~%s~s~', - ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', - ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx %s~s~ for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx %s~s~ from ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', ['gave_money'] = 'you gave ~g~$%s~s~ to ~y~%s~s~', @@ -36,7 +36,7 @@ Locales['en'] = { ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ %s', ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', @@ -110,7 +110,6 @@ Locales['en'] = { ['weapon_heavysniper'] = 'heavy sniper', ['weapon_grenadelauncher'] = 'grenade launcher', ['weapon_rpg'] = 'rocket launcher', - ['weapon_stinger'] = 'stinger', ['weapon_minigun'] = 'minigun', ['weapon_grenade'] = 'grenade', ['weapon_stickybomb'] = 'sticky bomb', @@ -119,7 +118,6 @@ Locales['en'] = { ['weapon_molotov'] = 'molotov cocktail', ['weapon_fireextinguisher'] = 'fire extinguisher', ['weapon_petrolcan'] = 'jerrycan', - ['weapon_digiscanner'] = 'digiscanner', ['weapon_ball'] = 'ball', ['weapon_snspistol'] = 'sns pistol', ['weapon_bottle'] = 'bottle', @@ -137,8 +135,6 @@ Locales['en'] = { ['weapon_proxmine'] = 'proximity mine', ['weapon_snowball'] = 'snow ball', ['weapon_flaregun'] = 'flaregun', - ['weapon_garbagebag'] = 'garbage bag', - ['weapon_handcuffs'] = 'handcuffs', ['weapon_combatpdw'] = 'combat pdw', ['weapon_marksmanpistol'] = 'marksman pistol', ['weapon_knuckle'] = 'knuckledusters', @@ -158,7 +154,6 @@ Locales['en'] = { ['weapon_poolcue'] = 'pool cue', ['weapon_wrench'] = 'pipe wrench', ['weapon_flashlight'] = 'flashlight', - ['gadget_nightvision'] = 'night vision', ['gadget_parachute'] = 'parachute', ['weapon_flare'] = 'flare gun', ['weapon_doubleaction'] = 'double-Action Revolver', @@ -174,4 +169,22 @@ Locales['en'] = { ['component_suppressor'] = 'suppressor', ['component_grip'] = 'grip', ['component_luxary_finish'] = 'luxary Weapon Finish', + + -- Weapon Ammo + ['ammo_rounds'] = 'round(s)', + ['ammo_shells'] = 'shell(s)', + ['ammo_charge'] = 'charge', + ['ammo_petrol'] = 'gallons of fuel', + ['ammo_firework'] = 'firework(s)', + ['ammo_rockets'] = 'rocket(s)', + ['ammo_grenadelauncher'] = 'grenade(s)', + ['ammo_grenade'] = 'grenade(s)', + ['ammo_stickybomb'] = 'bomb(s)', + ['ammo_pipebomb'] = 'bomb(s)', + ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_bzgas'] = 'can(s)', + ['ammo_ball'] = 'ball(s)', + ['ammo_snowball'] = 'snowball(s)', + ['ammo_flare'] = 'flare(s)', + ['ammo_flaregun'] = 'flare(s)', } diff --git a/locales/fi.lua b/locales/fi.lua index a3a32e6c..20fd8173 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -14,13 +14,13 @@ Locales['fi'] = { ['gave_item'] = 'sinä annoit ~y~%sx~s~ ~b~%s~s~ henkilölle ~y~%s~s~', ['received_item'] = 'sinä sait ~y~%sx~s~ ~b~%s~s~ henkilöltä ~b~%s~s~', ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ to ~y~%s~s~', - ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', - ['gave_weapon_withammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx %s~s~ for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx %s~s~ to ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ from ~b~%s~s~', - ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', - ['received_weapon_withammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx %s~s~ for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx %s~s~ from ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', ['gave_money'] = 'sinä annoit ~g~$%s~s~ henkilölle ~y~%s~s~', @@ -36,7 +36,7 @@ Locales['fi'] = { ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx %s~s~', ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', @@ -110,7 +110,6 @@ Locales['fi'] = { ['weapon_heavysniper'] = 'raskas tarkkuuskivääri', ['weapon_grenadelauncher'] = 'kranaatinheitin', ['weapon_rpg'] = 'raketinheitin', - ['weapon_stinger'] = 'stinger', ['weapon_minigun'] = 'minigun', ['weapon_grenade'] = 'kranaatti', ['weapon_stickybomb'] = 'tahma pommi', @@ -119,7 +118,6 @@ Locales['fi'] = { ['weapon_molotov'] = 'polttopullo', ['weapon_fireextinguisher'] = 'palosammutin', ['weapon_petrolcan'] = 'jerrykannu', - ['weapon_digiscanner'] = 'digiskanneri', ['weapon_ball'] = 'pallo', ['weapon_snspistol'] = 'pienpistooli', ['weapon_bottle'] = 'pullo', @@ -137,8 +135,6 @@ Locales['fi'] = { ['weapon_proxmine'] = 'lähellä räjähtävä miina', ['weapon_snowball'] = 'lumipallo', ['weapon_flaregun'] = 'valopyssy', - ['weapon_garbagebag'] = 'roskapussi', - ['weapon_handcuffs'] = 'käsiraudat', ['weapon_combatpdw'] = 'rynnäkkö pdw', ['weapon_marksmanpistol'] = 'marksman pistooli', ['weapon_knuckle'] = 'nyrkkirauta', @@ -158,7 +154,6 @@ Locales['fi'] = { ['weapon_poolcue'] = 'biljardimaila', ['weapon_wrench'] = 'putkipihdit', ['weapon_flashlight'] = 'taskulamppu', - ['gadget_nightvision'] = 'yökiikarit', ['gadget_parachute'] = 'laskuvarjo', ['weapon_flare'] = 'hätäraketti', ['weapon_doubleaction'] = 'double-Action Revolver', @@ -174,4 +169,22 @@ Locales['fi'] = { ['component_suppressor'] = 'suppressor', ['component_grip'] = 'grip', ['component_luxary_finish'] = 'luxary Weapon Finish', + + -- Weapon Ammo + ['ammo_rounds'] = 'round(s)', + ['ammo_shells'] = 'shell(s)', + ['ammo_charge'] = 'charge', + ['ammo_petrol'] = 'gallons of fuel', + ['ammo_firework'] = 'firework(s)', + ['ammo_rockets'] = 'rocket(s)', + ['ammo_grenadelauncher'] = 'grenade(s)', + ['ammo_grenade'] = 'grenade(s)', + ['ammo_stickybomb'] = 'bomb(s)', + ['ammo_pipebomb'] = 'bomb(s)', + ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_bzgas'] = 'can(s)', + ['ammo_ball'] = 'ball(s)', + ['ammo_snowball'] = 'snowball(s)', + ['ammo_flare'] = 'flare(s)', + ['ammo_flaregun'] = 'flare(s)', } diff --git a/locales/fr.lua b/locales/fr.lua index 6a984c9b..eed3a2f6 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -14,13 +14,13 @@ Locales['fr'] = { ['gave_item'] = 'vous avez donné ~y~%sx~s~ ~b~%s~s~ à ~y~%s~s~', ['received_item'] = 'vous avez reçu ~y~%sx~s~ ~b~%s~s~ par ~b~%s~s~', ['gave_weapon'] = 'vous avez donné ~y~1x~s~ ~b~%s~s~ à ~y~%s~s~', - ['gave_weapon_ammo'] = 'vous avez donné ~o~%sx~s~ balles pour ~b~%s~s~ à ~y~%s~s~', - ['gave_weapon_withammo'] = 'vous avez donné ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles à ~y~%s~s~', + ['gave_weapon_ammo'] = 'vous avez donné ~o~%sx %s~s~ pour ~b~%s~s~ à ~y~%s~s~', + ['gave_weapon_withammo'] = 'vous avez donné ~y~1x~s~ ~b~%s~s~ avec ~o~%sx %s~s~ à ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ a déjà ~y~%s~s~', ['gave_weapon_noweapon'] = '~y~%s~s~ n\'a pas cette arme', ['received_weapon'] = 'vous recevez ~y~1x~s~ ~b~%s~s~ de ~b~%s~s~', - ['received_weapon_ammo'] = 'vous avez reçu ~o~%sx~s~ balles pour votre ~b~%s~s~ de ~b~%s~s~', - ['received_weapon_withammo'] = 'vous avez reçu ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles de ~b~%s~s~', + ['received_weapon_ammo'] = 'vous avez reçu ~o~%sx %s~s~ pour votre ~b~%s~s~ de ~b~%s~s~', + ['received_weapon_withammo'] = 'vous avez reçu ~y~1x~s~ ~b~%s~s~ avec ~o~%sx %s~s~ de ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ a tenté de vous donner ~y~%s~s~, mais vous en aviez déjà un exemplaire', ['received_weapon_noweapon'] = '~b~%s~s~ tente de vous donner des munitions pour ~y~%s~s~, mais vous n\'en avez pas', ['gave_money'] = 'vous avez donné ~g~$%s~s~ à ~y~%s~s~', @@ -36,7 +36,7 @@ Locales['fr'] = { ['threw_money'] = 'vous avez jeté ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'vous avez jeté ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~', - ['threw_weapon_ammo'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles', + ['threw_weapon_ammo'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~ avec ~o~%sx %s~s~', ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', @@ -110,7 +110,6 @@ Locales['fr'] = { ['weapon_heavysniper'] = 'fusil de sniper lourd', ['weapon_grenadelauncher'] = 'lance-grenade', ['weapon_rpg'] = 'lance-rocket', - ['weapon_stinger'] = 'lance-missile stinger', ['weapon_minigun'] = 'minigun', ['weapon_grenade'] = 'grenade', ['weapon_stickybomb'] = 'bombe collante', @@ -119,7 +118,6 @@ Locales['fr'] = { ['weapon_molotov'] = 'cocktail molotov', ['weapon_fireextinguisher'] = 'extincteur', ['weapon_petrolcan'] = 'jerrican d\'essence', - ['weapon_digiscanner'] = 'digiscanner', ['weapon_ball'] = 'balle', ['weapon_snspistol'] = 'pistolet sns', ['weapon_bottle'] = 'bouteille', @@ -137,8 +135,6 @@ Locales['fr'] = { ['weapon_proxmine'] = 'mine de proximité', ['weapon_snowball'] = 'boule de neige', ['weapon_flaregun'] = 'lance fusée de détresse', - ['weapon_garbagebag'] = 'sac poubelle', - ['weapon_handcuffs'] = 'menottes', ['weapon_combatpdw'] = 'arme de défense personnelle', ['weapon_marksmanpistol'] = 'pistolet marksman', ['weapon_knuckle'] = 'poing américain', @@ -158,7 +154,6 @@ Locales['fr'] = { ['weapon_poolcue'] = 'queue de billard', ['weapon_wrench'] = 'clé', ['weapon_flashlight'] = 'lampe torche', - ['gadget_nightvision'] = 'vision nocturne', ['gadget_parachute'] = 'parachute', ['weapon_flare'] = 'fusée Détresse', ['weapon_doubleaction'] = 'double-Action Revolver', @@ -174,4 +169,22 @@ Locales['fr'] = { ['component_suppressor'] = 'réducteur de son', ['component_grip'] = 'poignée', ['component_luxary_finish'] = 'finission de luxe', + + -- Weapon Ammo + ['ammo_rounds'] = 'round(s)', + ['ammo_shells'] = 'shell(s)', + ['ammo_charge'] = 'charge', + ['ammo_petrol'] = 'gallons of fuel', + ['ammo_firework'] = 'firework(s)', + ['ammo_rockets'] = 'rocket(s)', + ['ammo_grenadelauncher'] = 'grenade(s)', + ['ammo_grenade'] = 'grenade(s)', + ['ammo_stickybomb'] = 'bomb(s)', + ['ammo_pipebomb'] = 'bomb(s)', + ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_bzgas'] = 'can(s)', + ['ammo_ball'] = 'ball(s)', + ['ammo_snowball'] = 'snowball(s)', + ['ammo_flare'] = 'flare(s)', + ['ammo_flaregun'] = 'flare(s)', } diff --git a/locales/pl.lua b/locales/pl.lua index 37408c76..45793958 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -14,13 +14,13 @@ Locales['pl'] = { ['gave_item'] = 'dajesz ~y~%sx~s~ ~b~%s~s~ dla ~y~%s~s~', ['received_item'] = 'otrzymujesz ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', ['gave_weapon'] = 'dajesz ~b~%s~s~ dla ~y~%s~s~', - ['gave_weapon_ammo'] = 'dałeś/aś ~o~%sx~s~ naboi do ~b~%s~s~ dla ~y~%s~s~', - ['gave_weapon_withammo'] = 'dałeś/aś ~b~%s~s~ z ~o~%sx~s~ nabojami dla ~y~%s~s~', + ['gave_weapon_ammo'] = 'dałeś/aś ~o~%sx %s~s~ do ~b~%s~s~ dla ~y~%s~s~', + ['gave_weapon_withammo'] = 'dałeś/aś ~b~%s~s~ z ~o~%sx %s~s~ dla ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ już posiada ~y~%s~s~', ['gave_weapon_noweapon'] = '~y~%s~s~ nie posiada tej broni', ['received_weapon'] = 'otrzymałeś/aś ~b~%s~s~ od ~b~%s~s~', - ['received_weapon_ammo'] = 'otrzymałeś/aś ~o~%sx~s~ naboi do twojego ~b~%s~s~ od ~b~%s~s~', - ['received_weapon_withammo'] = 'otrzymałeś/aś ~b~%s~s~ z ~o~%sx~s~ nabojami od ~b~%s~s~', + ['received_weapon_ammo'] = 'otrzymałeś/aś ~o~%sx %s~s~ do twojego ~b~%s~s~ od ~b~%s~s~', + ['received_weapon_withammo'] = 'otrzymałeś/aś ~b~%s~s~ z ~o~%sx %s~s~ od ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ próbował/a przekazać ci ~y~%s~s~, lecz już posiadasz jedno', ['received_weapon_noweapon'] = '~b~%s~s~ próbował/a przekazać ci amunicje do ~y~%s~s~, lecz nie posiadasz tej broni', ['gave_money'] = 'dajesz ~g~%s$~s~ dla ~y~%s~s~', @@ -36,7 +36,7 @@ Locales['pl'] = { ['threw_money'] = 'wyrzuciłeś/aś ~g~$%s~s~ ~b~gotówki~s~', ['threw_account'] = 'wyrzuciłeś/aś ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'wyrzuciłeś/aś ~b~%s~s~', - ['threw_weapon_ammo'] = 'wyrzuciłeś/aś ~b~%s~s~ z ~o~%sx~s~ nabojami', + ['threw_weapon_ammo'] = 'wyrzuciłeś/aś ~b~%s~s~ z ~o~%sx %s~s~', ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', @@ -110,7 +110,6 @@ Locales['pl'] = { ['weapon_heavysniper'] = 'ciężki karabin snajperski', ['weapon_grenadelauncher'] = 'granatnik', ['weapon_rpg'] = 'wyrzutnia rakiet', - ['weapon_stinger'] = 'stinger', ['weapon_minigun'] = 'minigun', ['weapon_grenade'] = 'granat', ['weapon_stickybomb'] = 'ładunek przylepny', @@ -119,7 +118,6 @@ Locales['pl'] = { ['weapon_molotov'] = 'koktajl Mołotowa', ['weapon_fireextinguisher'] = 'gaśnica', ['weapon_petrolcan'] = 'kanister', - ['weapon_digiscanner'] = 'skaner częstotliwości', ['weapon_ball'] = 'piłka', ['weapon_snspistol'] = 'sns pistolet', ['weapon_bottle'] = 'butelka', @@ -137,8 +135,6 @@ Locales['pl'] = { ['weapon_proxmine'] = 'mina zbliżeniowa', ['weapon_snowball'] = 'śnieżka', ['weapon_flaregun'] = 'flara', - ['weapon_garbagebag'] = 'worek na śmieci', - ['weapon_handcuffs'] = 'kajdanki', ['weapon_combatpdw'] = 'combat pdw', ['weapon_marksmanpistol'] = 'marksman pistol', ['weapon_knuckle'] = 'kastety', @@ -158,7 +154,6 @@ Locales['pl'] = { ['weapon_poolcue'] = 'kij bilardowy', ['weapon_wrench'] = 'klucz do rur', ['weapon_flashlight'] = 'latarka', - ['gadget_nightvision'] = 'noktowizor', ['gadget_parachute'] = 'spadochron', ['weapon_flare'] = 'pistolet sygnałowy', ['weapon_doubleaction'] = 'double-Action Revolver', @@ -174,4 +169,22 @@ Locales['pl'] = { ['component_suppressor'] = 'tłumik', ['component_grip'] = 'uchwyt', ['component_luxary_finish'] = 'luxary Weapon Finish', + + -- Weapon Ammo + ['ammo_rounds'] = 'round(s)', + ['ammo_shells'] = 'shell(s)', + ['ammo_charge'] = 'charge', + ['ammo_petrol'] = 'gallons of fuel', + ['ammo_firework'] = 'firework(s)', + ['ammo_rockets'] = 'rocket(s)', + ['ammo_grenadelauncher'] = 'grenade(s)', + ['ammo_grenade'] = 'grenade(s)', + ['ammo_stickybomb'] = 'bomb(s)', + ['ammo_pipebomb'] = 'bomb(s)', + ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_bzgas'] = 'can(s)', + ['ammo_ball'] = 'ball(s)', + ['ammo_snowball'] = 'snowball(s)', + ['ammo_flare'] = 'flare(s)', + ['ammo_flaregun'] = 'flare(s)', } diff --git a/locales/sv.lua b/locales/sv.lua index 47bc4bde..dcc161c0 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -14,14 +14,14 @@ Locales['sv'] = { ['gave_item'] = 'du gav ~y~%sx~s~ ~b~%s~s~ till ~y~%s~s~', ['received_item'] = 'du tog emot ~y~%sx~s~ ~b~%s~s~ från ~b~%s~s~', ['gave_weapon'] = 'du gav ~b~%s~s~ till ~y~%s~s~', - ['gave_weapon_ammo'] = 'du gav ~o~%sx~s~ skott för ~b~%s~s~ till ~y~%s~s~', - ['gave_weapon_withammo'] = 'du gav ~b~%s~s~ med ~o~%sx~s~ skott till ~y~%s~s~', + ['gave_weapon_ammo'] = 'du gav ~o~%sx %s~s~ för ~b~%s~s~ till ~y~%s~s~', + ['gave_weapon_withammo'] = 'du gav ~b~%s~s~ med ~o~%sx %s~s~ till ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ har redan en ~y~%s~s~', ['gave_weapon_noweapon'] = '~y~%s~s~ har inte det vapnet', ['received_weapon'] = 'du tog emot ~b~%s~s~ från ~b~%s~s~', - ['received_weapon_ammo'] = 'du tog emot ~o~%sx~s~ skott för ~b~%s~s~ från ~b~%s~s~', - ['received_weapon_withammo'] = 'du tog emot ~b~%s~s~ med ~o~%sx~s~ skott från ~b~%s~s~', - ['received_weapon_hasalready'] = '~b~%s~s~ försökte ge dig en ~y~%s~s~, men det har du redan', + ['received_weapon_ammo'] = 'du tog emot ~o~%sx %s~s~ för ~b~%s~s~ från ~b~%s~s~', + ['received_weapon_withammo'] = 'du tog emot ~b~%s~s~ med ~o~%sx %s~s~ från ~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~ försökte ge dig en ~y~%s~s~, men det vapnet har du redan', ['received_weapon_noweapon'] = '~b~%s~s~ försökte ge dig ammunition för ett ~y~%s~s~, men du har inget sådant vapen', ['gave_money'] = 'du gav ~g~%s SEK~s~ till ~y~%s~s~', ['received_money'] = 'du tog emot ~g~%s SEK~s~ från ~b~%s~s~', @@ -36,7 +36,7 @@ Locales['sv'] = { ['threw_money'] = 'du kastade ~g~%s SEK~s~ ~b~kontanter~s~', ['threw_account'] = 'du kastade ~g~%s SEK~s~ ~b~%s~s~', ['threw_weapon'] = 'du kastade ~b~%s~s~', - ['threw_weapon_ammo'] = 'du kastade ~b~%s~s~ med ~o~%sx~s~ skott', + ['threw_weapon_ammo'] = 'du kastade ~b~%s~s~ med ~o~%sx %s~s~', ['threw_weapon_already'] = 'du har redan ett sådant vapen på dig', ['threw_cannot_pickup'] = 'du kan inte plocka upp det på grund av att det kommer ej få plats i ditt förråd!', ['threw_pickup_prompt'] = 'tryck ~y~E~s~ för att plocka upp', @@ -110,7 +110,6 @@ Locales['sv'] = { ['weapon_heavysniper'] = 'tung prickskytt', ['weapon_grenadelauncher'] = 'granatkastare', ['weapon_rpg'] = 'raketgevär', - ['weapon_stinger'] = 'stinger', ['weapon_minigun'] = 'minigun', ['weapon_grenade'] = 'granat', ['weapon_stickybomb'] = 'klibbig bomb', @@ -119,7 +118,6 @@ Locales['sv'] = { ['weapon_molotov'] = 'molotov cocktail', ['weapon_fireextinguisher'] = 'brandsläckare', ['weapon_petrolcan'] = 'bensindunk', - ['weapon_digiscanner'] = 'digiscanner', ['weapon_ball'] = 'boll', ['weapon_snspistol'] = 'sns pistol', ['weapon_bottle'] = 'flaska', @@ -129,7 +127,7 @@ Locales['sv'] = { ['weapon_bullpuprifle'] = 'bullpup rifle', ['weapon_dagger'] = 'dolk', ['weapon_vintagepistol'] = 'vintage pistol', - ['weapon_firework'] = 'fyrverkeri', + ['weapon_fireworkfirework'] = 'fyrverkeri', ['weapon_musket'] = 'musköt', ['weapon_heavyshotgun'] = 'heavy shotgun', ['weapon_marksmanrifle'] = 'marksman rifle', @@ -137,8 +135,6 @@ Locales['sv'] = { ['weapon_proxmine'] = 'proximity mine', ['weapon_snowball'] = 'snöboll', ['weapon_flaregun'] = 'signalpistol', - ['weapon_garbagebag'] = 'soppåse', - ['weapon_handcuffs'] = 'handklovar', ['weapon_combatpdw'] = 'combat pdw', ['weapon_marksmanpistol'] = 'marksman pistol', ['weapon_knuckle'] = 'knogjärn', @@ -158,7 +154,6 @@ Locales['sv'] = { ['weapon_poolcue'] = 'biljardkö', ['weapon_wrench'] = 'rörtång', ['weapon_flashlight'] = 'ficklampa', - ['gadget_nightvision'] = 'mörkerseende', ['gadget_parachute'] = 'fallskärm', ['weapon_flare'] = 'signalpistol', ['weapon_doubleaction'] = 'double-Action Revolver', @@ -174,4 +169,22 @@ Locales['sv'] = { ['component_suppressor'] = 'ljuddämpare', ['component_grip'] = 'handtag', ['component_luxary_finish'] = 'lyxvapen behandling', + + -- Weapon Ammo + ['ammo_rounds'] = 'ammunition', + ['ammo_shells'] = 'hagel', + ['ammo_charge'] = 'laddning', + ['ammo_petrol'] = 'liter bensin', + ['ammo_firework'] = 'fyrverkeri', + ['ammo_rockets'] = 'raket', + ['ammo_grenadelauncher'] = 'granat(er)', + ['ammo_grenade'] = 'granat(er)', + ['ammo_stickybomb'] = 'bomb(er)', + ['ammo_pipebomb'] = 'bomb(er)', + ['ammo_smokebomb'] = 'bomb(er)', + ['ammo_bzgas'] = 'burk(ar)', + ['ammo_ball'] = 'boll(ar)', + ['ammo_snowball'] = 'snöboll(ar)', + ['ammo_flare'] = 'lysraket(er)', + ['ammo_flaregun'] = 'lysraket(er)', } diff --git a/server/commands.lua b/server/commands.lua index 90c50375..965e5bf2 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -134,7 +134,11 @@ TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, if xPlayer.hasWeapon(weaponName) then TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player already has that weapon.' } }) else - xPlayer.addWeapon(weaponName, tonumber(args[3])) + if tonumber(args[3]) then + xPlayer.addWeapon(weaponName, tonumber(args[3])) + else + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid ammo amount.' } }) + end end else TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid weapon.' } }) diff --git a/server/main.lua b/server/main.lua index 329fc379..ae630198 100644 --- a/server/main.lua +++ b/server/main.lua @@ -290,15 +290,17 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo local weaponLabel = ESX.GetWeaponLabel(itemName) if not targetXPlayer.hasWeapon(itemName) then - local weaponNum, weapon = sourceXPlayer.getWeapon(itemName) + local _, weapon = sourceXPlayer.getWeapon(itemName) + local _, weaponObject = ESX.GetWeapon(itemName) itemCount = weapon.ammo sourceXPlayer.removeWeapon(itemName) targetXPlayer.addWeapon(itemName, itemCount) - if itemCount > 0 then - sourceXPlayer.showNotification(_U('gave_weapon_withammo', weaponLabel, itemCount, targetXPlayer.name)) - targetXPlayer.showNotification(_U('received_weapon_withammo', weaponLabel, itemCount, sourceXPlayer.name)) + if weaponObject.ammo and itemCount > 0 then + local ammoLabel = weaponObject.ammo.label + sourceXPlayer.showNotification(_U('gave_weapon_withammo', weaponLabel, itemCount, ammoLabel, targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_weapon_withammo', weaponLabel, itemCount, ammoLabel, sourceXPlayer.name)) else sourceXPlayer.showNotification(_U('gave_weapon', weaponLabel, targetXPlayer.name)) targetXPlayer.showNotification(_U('received_weapon', weaponLabel, sourceXPlayer.name)) @@ -312,13 +314,18 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo if sourceXPlayer.hasWeapon(itemName) then if targetXPlayer.hasWeapon(itemName) then local weaponNum, weapon = sourceXPlayer.getWeapon(itemName) + local _, weaponObject = ESX.GetWeapon(itemName) - if weapon.ammo >= itemCount then - sourceXPlayer.removeWeaponAmmo(itemName, itemCount) - targetXPlayer.addWeaponAmmo(itemName, itemCount) + if weaponObject.ammo then + local ammoLabel = weaponObject.ammo.label - sourceXPlayer.showNotification(_U('gave_weapon_ammo', itemCount, weapon.label, targetXPlayer.name)) - targetXPlayer.showNotification(_U('received_weapon_ammo', itemCount, weapon.label, sourceXPlayer.name)) + if weapon.ammo >= itemCount then + sourceXPlayer.removeWeaponAmmo(itemName, itemCount) + targetXPlayer.addWeaponAmmo(itemName, itemCount) + + sourceXPlayer.showNotification(_U('gave_weapon_ammo', itemCount, ammoLabel, weapon.label, targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_weapon_ammo', itemCount, ammoLabel, weapon.label, sourceXPlayer.name)) + end end else sourceXPlayer.showNotification(_U('gave_weapon_noweapon', targetXPlayer.name)) @@ -382,17 +389,22 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) itemName = string.upper(itemName) if xPlayer.hasWeapon(itemName) then - local weaponNum, weapon = xPlayer.getWeapon(itemName) + local _, weapon = xPlayer.getWeapon(itemName) + local _, weaponObject = ESX.GetWeapon(itemName) + local pickupLabel + xPlayer.removeWeapon(itemName) - local pickupLabel = ('~y~%s~s~ [~g~%s~s~ ammo]'):format(weapon.label, weapon.ammo) - ESX.CreatePickup('item_weapon', itemName, weapon.ammo, pickupLabel, playerId, weapon.components) - - if weapon.ammo > 0 then - xPlayer.showNotification(_U('threw_weapon_ammo', weapon.label, weapon.ammo)) + if weaponObject.ammo and weapon.ammo > 0 then + local ammoLabel = weaponObject.ammo.label + pickupLabel = ('~y~%s~s~ [~g~%s~s~ %s]'):format(weapon.label, weapon.ammo, ammoLabel) + xPlayer.showNotification(_U('threw_weapon_ammo', weapon.label, weapon.ammo, ammoLabel)) else + pickupLabel = ('~y~%s~s~'):format(weapon.label) xPlayer.showNotification(_U('threw_weapon', weapon.label)) end + + ESX.CreatePickup('item_weapon', itemName, weapon.ammo, pickupLabel, playerId, weapon.components) end end end) From d15cd7d0ec63f78b3cc2bb4f6cccba0513058902 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 11 Feb 2020 11:54:57 +0100 Subject: [PATCH 2531/3224] Update en.lua --- locales/en.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/en.lua b/locales/en.lua index a7207cad..d519928b 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -36,7 +36,7 @@ Locales['en'] = { ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ %s', + ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx %s~s~', ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', From 548b676e5d321b72f547caceadd591908211cafa Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 11 Feb 2020 12:01:39 +0100 Subject: [PATCH 2532/3224] Added missing translations --- locales/br.lua | 2 ++ locales/cs.lua | 2 ++ locales/de.lua | 2 ++ locales/en.lua | 2 ++ locales/fi.lua | 2 ++ locales/fr.lua | 2 ++ locales/pl.lua | 2 ++ locales/sv.lua | 4 +++- 8 files changed, 17 insertions(+), 1 deletion(-) diff --git a/locales/br.lua b/locales/br.lua index 7b69f877..b3db1ee3 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -183,6 +183,8 @@ Locales['br'] = { ['ammo_stickybomb'] = 'bomb(s)', ['ammo_pipebomb'] = 'bomb(s)', ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_molotov'] = 'cocktail(s)', + ['ammo_proxmine'] = 'mine(s)', ['ammo_bzgas'] = 'can(s)', ['ammo_ball'] = 'ball(s)', ['ammo_snowball'] = 'snowball(s)', diff --git a/locales/cs.lua b/locales/cs.lua index 565d764d..b980fc6a 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -183,6 +183,8 @@ Locales['cs'] = { ['ammo_stickybomb'] = 'bomb(s)', ['ammo_pipebomb'] = 'bomb(s)', ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_molotov'] = 'cocktail(s)', + ['ammo_proxmine'] = 'mine(s)', ['ammo_bzgas'] = 'can(s)', ['ammo_ball'] = 'ball(s)', ['ammo_snowball'] = 'snowball(s)', diff --git a/locales/de.lua b/locales/de.lua index 63b4c090..0068ed65 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -182,6 +182,8 @@ Locales['de'] = { ['ammo_stickybomb'] = 'bomb(s)', ['ammo_pipebomb'] = 'bomb(s)', ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_molotov'] = 'cocktail(s)', + ['ammo_proxmine'] = 'mine(s)', ['ammo_bzgas'] = 'can(s)', ['ammo_ball'] = 'ball(s)', ['ammo_snowball'] = 'snowball(s)', diff --git a/locales/en.lua b/locales/en.lua index d519928b..babcb272 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -182,6 +182,8 @@ Locales['en'] = { ['ammo_stickybomb'] = 'bomb(s)', ['ammo_pipebomb'] = 'bomb(s)', ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_molotov'] = 'cocktail(s)', + ['ammo_proxmine'] = 'mine(s)', ['ammo_bzgas'] = 'can(s)', ['ammo_ball'] = 'ball(s)', ['ammo_snowball'] = 'snowball(s)', diff --git a/locales/fi.lua b/locales/fi.lua index 20fd8173..2dd566c4 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -182,6 +182,8 @@ Locales['fi'] = { ['ammo_stickybomb'] = 'bomb(s)', ['ammo_pipebomb'] = 'bomb(s)', ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_molotov'] = 'cocktail(s)', + ['ammo_proxmine'] = 'mine(s)', ['ammo_bzgas'] = 'can(s)', ['ammo_ball'] = 'ball(s)', ['ammo_snowball'] = 'snowball(s)', diff --git a/locales/fr.lua b/locales/fr.lua index eed3a2f6..5e946a4e 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -182,6 +182,8 @@ Locales['fr'] = { ['ammo_stickybomb'] = 'bomb(s)', ['ammo_pipebomb'] = 'bomb(s)', ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_molotov'] = 'cocktail(s)', + ['ammo_proxmine'] = 'mine(s)', ['ammo_bzgas'] = 'can(s)', ['ammo_ball'] = 'ball(s)', ['ammo_snowball'] = 'snowball(s)', diff --git a/locales/pl.lua b/locales/pl.lua index 45793958..9ad79c2e 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -182,6 +182,8 @@ Locales['pl'] = { ['ammo_stickybomb'] = 'bomb(s)', ['ammo_pipebomb'] = 'bomb(s)', ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_molotov'] = 'cocktail(s)', + ['ammo_proxmine'] = 'mine(s)', ['ammo_bzgas'] = 'can(s)', ['ammo_ball'] = 'ball(s)', ['ammo_snowball'] = 'snowball(s)', diff --git a/locales/sv.lua b/locales/sv.lua index dcc161c0..d1e41405 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -127,7 +127,7 @@ Locales['sv'] = { ['weapon_bullpuprifle'] = 'bullpup rifle', ['weapon_dagger'] = 'dolk', ['weapon_vintagepistol'] = 'vintage pistol', - ['weapon_fireworkfirework'] = 'fyrverkeri', + ['weapon_firework'] = 'fyrverkeriraket', ['weapon_musket'] = 'musköt', ['weapon_heavyshotgun'] = 'heavy shotgun', ['weapon_marksmanrifle'] = 'marksman rifle', @@ -182,6 +182,8 @@ Locales['sv'] = { ['ammo_stickybomb'] = 'bomb(er)', ['ammo_pipebomb'] = 'bomb(er)', ['ammo_smokebomb'] = 'bomb(er)', + ['ammo_molotov'] = 'cocktail(s)', + ['ammo_proxmine'] = 'bomb(er)', ['ammo_bzgas'] = 'burk(ar)', ['ammo_ball'] = 'boll(ar)', ['ammo_snowball'] = 'snöboll(ar)', From 8d308f7c82c96d9f6f101924d470493cfdc3040f Mon Sep 17 00:00:00 2001 From: Oldarorn <36448848+Oldarorn@users.noreply.github.com> Date: Tue, 11 Feb 2020 12:32:20 +0100 Subject: [PATCH 2533/3224] Update fr.lua --- locales/fr.lua | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index 5e946a4e..55d849d6 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -37,9 +37,9 @@ Locales['fr'] = { ['threw_account'] = 'vous avez jeté ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~', ['threw_weapon_ammo'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~ avec ~o~%sx %s~s~', - ['threw_weapon_already'] = 'you already carry the same weapon', - ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', - ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', + ['threw_weapon_already'] = 'vous portez déjà cette arme', + ['threw_cannot_pickup'] = 'vous ne pouvez pas ramasser ça votre inventaire est plein !', + ['threw_pickup_prompt'] = 'appuyez sur ~y~E~s~ pour ramasser', -- Key mapping ['keymap_showinventory'] = 'show Inventory', @@ -155,8 +155,8 @@ Locales['fr'] = { ['weapon_wrench'] = 'clé', ['weapon_flashlight'] = 'lampe torche', ['gadget_parachute'] = 'parachute', - ['weapon_flare'] = 'fusée Détresse', - ['weapon_doubleaction'] = 'double-Action Revolver', + ['weapon_flare'] = 'fusée de détresse', + ['weapon_doubleaction'] = 'revolver double action', -- Weapon Components ['component_clip_default'] = 'chargeur par défaut', @@ -168,25 +168,25 @@ Locales['fr'] = { ['component_scope_advanced'] = 'lunette', ['component_suppressor'] = 'réducteur de son', ['component_grip'] = 'poignée', - ['component_luxary_finish'] = 'finission de luxe', + ['component_luxary_finish'] = 'finition de luxe', -- Weapon Ammo - ['ammo_rounds'] = 'round(s)', - ['ammo_shells'] = 'shell(s)', - ['ammo_charge'] = 'charge', - ['ammo_petrol'] = 'gallons of fuel', - ['ammo_firework'] = 'firework(s)', - ['ammo_rockets'] = 'rocket(s)', + ['ammo_rounds'] = 'cartouche(s)', + ['ammo_shells'] = 'obus', + ['ammo_charge'] = 'charge(s)', + ['ammo_petrol'] = 'jerrican d\'essence', + ['ammo_firework'] = 'feu(x) d\'artifice', + ['ammo_rockets'] = 'roquette(s)', ['ammo_grenadelauncher'] = 'grenade(s)', ['ammo_grenade'] = 'grenade(s)', - ['ammo_stickybomb'] = 'bomb(s)', - ['ammo_pipebomb'] = 'bomb(s)', - ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_stickybomb'] = 'bombe(s)', + ['ammo_pipebomb'] = 'bombe(s)', + ['ammo_smokebomb'] = 'bombe(s)', ['ammo_molotov'] = 'cocktail(s)', ['ammo_proxmine'] = 'mine(s)', - ['ammo_bzgas'] = 'can(s)', - ['ammo_ball'] = 'ball(s)', - ['ammo_snowball'] = 'snowball(s)', - ['ammo_flare'] = 'flare(s)', - ['ammo_flaregun'] = 'flare(s)', + ['ammo_bzgas'] = 'grenade(s)', + ['ammo_ball'] = 'balle(s)', + ['ammo_snowball'] = 'boule(s) de neige', + ['ammo_flare'] = 'fusée(s) éclairante(s)', + ['ammo_flaregun'] = 'fusée(s)', } From 8e13cf6613bb18d7f7711f6d6b5856ee50500fbe Mon Sep 17 00:00:00 2001 From: Jay Date: Tue, 11 Feb 2020 13:45:48 -0500 Subject: [PATCH 2534/3224] esx:spawnVehicle using Player Heading (#486) * esx:spawnVehicle using Player Heading Updated esx:spawnVehicle to use the players heading as opposed to the default 90.0 degree angle * Update main.lua --- client/main.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/main.lua b/client/main.lua index 39bdf327..d99ef51f 100644 --- a/client/main.lua +++ b/client/main.lua @@ -243,10 +243,11 @@ AddEventHandler('esx:spawnVehicle', function(vehicle) local model = (type(vehicle) == 'number' and vehicle or GetHashKey(vehicle)) if IsModelInCdimage(model) then - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) + local playerHeading = GetEntityHeading(playerPed) - ESX.Game.SpawnVehicle(model, coords, 90.0, function(vehicle) + ESX.Game.SpawnVehicle(model, coords, playerHeading, function(vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) end) else From b50fb3ba65979f74814217b22be30fa25679243e Mon Sep 17 00:00:00 2001 From: Lorenzo Date: Tue, 11 Feb 2020 20:29:01 +0100 Subject: [PATCH 2535/3224] fixxxx (#35) --- server/main.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/main.lua b/server/main.lua index 3442f910..cb3c5c11 100644 --- a/server/main.lua +++ b/server/main.lua @@ -29,7 +29,7 @@ RegisterCommand('twt', function(playerId, args, rawCommand) end, false) RegisterCommand('me', function(playerId, args, rawCommand) - if source == 0 then + if playerId == 0 then print('esx_rpchat: you can\'t use this command from console!') else args = table.concat(args, ' ') @@ -40,7 +40,7 @@ RegisterCommand('me', function(playerId, args, rawCommand) end, false) RegisterCommand('do', function(playerId, args, rawCommand) - if source == 0 then + if playerId == 0 then print('esx_rpchat: you can\'t use this command from console!') else args = table.concat(args, ' ') From baa9ca3afc109ec9f34bcfd997810fbebc8ad5e3 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 11 Feb 2020 21:11:54 +0100 Subject: [PATCH 2536/3224] Implemented weapon tint support (desc), closes #477 - Implemented two new xPlayer functions: - .getWeaponTint(weaponName) - .setWeaponTint(weaponName, weaponTintIndex) Thanks to @profex1999 for co authoring this! Co-Authored-By: Andrea Passarini --- client/main.lua | 35 +++++++++++------- config.weapons.lua | 74 ++++++++++++++++++++++++++++++--------- locales/br.lua | 10 ++++++ locales/cs.lua | 10 ++++++ locales/de.lua | 10 ++++++ locales/en.lua | 10 ++++++ locales/fi.lua | 10 ++++++ locales/fr.lua | 10 ++++++ locales/pl.lua | 10 ++++++ locales/sv.lua | 12 ++++++- server/classes/player.lua | 27 +++++++++++++- server/functions.lua | 5 +-- server/main.lua | 8 ++--- 13 files changed, 194 insertions(+), 37 deletions(-) diff --git a/client/main.lua b/client/main.lua index d99ef51f..7e74d212 100644 --- a/client/main.lua +++ b/client/main.lua @@ -85,6 +85,8 @@ AddEventHandler('esx:restoreLoadout', function() local weaponHash = GetHashKey(weaponName) GiveWeaponToPed(playerPed, weaponHash, 0, false, false) + SetPedWeaponTintIndex(playerPed, weaponHash, v.tintIndex) + local ammoType = GetPedAmmoTypeFromWeapon(playerPed, weaponHash) for k2,v2 in ipairs(v.components) do @@ -168,7 +170,7 @@ end) RegisterNetEvent('esx:addWeapon') AddEventHandler('esx:addWeapon', function(weaponName, ammo) - local playerPed = PlayerPedId() + local playerPed = PlayerPedId() local weaponHash = GetHashKey(weaponName) GiveWeaponToPed(playerPed, weaponHash, ammo, false, false) @@ -176,7 +178,7 @@ end) RegisterNetEvent('esx:addWeaponComponent') AddEventHandler('esx:addWeaponComponent', function(weaponName, weaponComponent) - local playerPed = PlayerPedId() + local playerPed = PlayerPedId() local weaponHash = GetHashKey(weaponName) local componentHash = ESX.GetWeaponComponent(weaponName, weaponComponent).hash @@ -185,15 +187,23 @@ end) RegisterNetEvent('esx:setWeaponAmmo') AddEventHandler('esx:setWeaponAmmo', function(weaponName, weaponAmmo) - local playerPed = PlayerPedId() + local playerPed = PlayerPedId() local weaponHash = GetHashKey(weaponName) SetPedAmmo(playerPed, weaponHash, weaponAmmo) end) +RegisterNetEvent('esx:setWeaponTint') +AddEventHandler('esx:setWeaponTint', function(weaponName, weaponTintIndex) + local playerPed = PlayerPedId() + local weaponHash = GetHashKey(weaponName) + + SetPedWeaponTintIndex(playerPed, weaponHash, weaponTintIndex) +end) + RegisterNetEvent('esx:removeWeapon') AddEventHandler('esx:removeWeapon', function(weaponName, ammo) - local playerPed = PlayerPedId() + local playerPed = PlayerPedId() local weaponHash = GetHashKey(weaponName) RemoveWeaponFromPed(playerPed, weaponHash) @@ -209,7 +219,7 @@ end) RegisterNetEvent('esx:removeWeaponComponent') AddEventHandler('esx:removeWeaponComponent', function(weaponName, weaponComponent) - local playerPed = PlayerPedId() + local playerPed = PlayerPedId() local weaponHash = GetHashKey(weaponName) local componentHash = ESX.GetWeaponComponent(weaponName, weaponComponent).hash @@ -243,9 +253,8 @@ AddEventHandler('esx:spawnVehicle', function(vehicle) local model = (type(vehicle) == 'number' and vehicle or GetHashKey(vehicle)) if IsModelInCdimage(model) then - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - local playerHeading = GetEntityHeading(playerPed) + local playerPed = PlayerPedId() + local playerCoords, playerHeading = GetEntityCoords(playerPed), GetEntityHeading(playerPed) ESX.Game.SpawnVehicle(model, coords, playerHeading, function(vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) @@ -256,7 +265,7 @@ AddEventHandler('esx:spawnVehicle', function(vehicle) end) RegisterNetEvent('esx:createPickup') -AddEventHandler('esx:createPickup', function(pickupId, label, playerId, type, name, components) +AddEventHandler('esx:createPickup', function(pickupId, label, playerId, type, name, components, tintIndex) local playerPed = GetPlayerPed(GetPlayerFromServerId(playerId)) local entityCoords, forward, pickupObject = GetEntityCoords(playerPed), GetEntityForwardVector(playerPed) local objectCoords = (entityCoords + forward * 1.0) @@ -264,6 +273,7 @@ AddEventHandler('esx:createPickup', function(pickupId, label, playerId, type, na if type == 'item_weapon' then ESX.Streaming.RequestWeaponAsset(GetHashKey(name)) pickupObject = CreateWeaponObject(GetHashKey(name), 50, objectCoords, true, 1.0, 0) + SetWeaponObjectTintIndex(pickupObject, tintIndex) for k,v in ipairs(components) do local component = ESX.GetWeaponComponent(name, v) @@ -300,6 +310,7 @@ AddEventHandler('esx:createMissingPickups', function(missingPickups) if pickup.type == 'item_weapon' then ESX.Streaming.RequestWeaponAsset(GetHashKey(pickup.name)) pickupObject = CreateWeaponObject(GetHashKey(pickup.name), 50, pickup.coords.x, pickup.coords.y, pickup.coords.z, true, 1.0, 0) + SetWeaponObjectTintIndex(pickupObject, pickup.tintIndex) for k,componentName in ipairs(pickup.components) do local component = ESX.GetWeaponComponent(pickup.name, componentName) @@ -405,10 +416,9 @@ Citizen.CreateThread(function() for k,v in ipairs(Config.Weapons) do local weaponName = v.name local weaponHash = GetHashKey(weaponName) - local weaponComponents = {} if HasPedGotWeapon(playerPed, weaponHash, false) then - local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) + local ammo, tintIndex, weaponComponents = GetAmmoInPedWeapon(playerPed, weaponHash), GetPedWeaponTintIndex(playerPed, weaponHash), {} for k2,v2 in ipairs(v.components) do if HasPedGotWeaponComponent(playerPed, weaponHash, v2.hash) then @@ -426,7 +436,8 @@ Citizen.CreateThread(function() name = weaponName, ammo = ammo, label = v.label, - components = weaponComponents + components = weaponComponents, + tintIndex = tintIndex }) else if lastLoadout[weaponName] then diff --git a/config.weapons.lua b/config.weapons.lua index 037062fc..6c08d1a7 100644 --- a/config.weapons.lua +++ b/config.weapons.lua @@ -1,8 +1,20 @@ +Config.DefaultWeaponTints = { + [0] = _U('tint_default'), + [1] = _U('tint_green'), + [2] = _U('tint_gold'), + [3] = _U('tint_pink'), + [4] = _U('tint_army'), + [5] = _U('tint_lspd'), + [6] = _U('tint_orange'), + [7] = _U('tint_platinum') +} + Config.Weapons = { { name = 'WEAPON_PISTOL', label = _U('weapon_pistol'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_PISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_PISTOL_CLIP_02')}, @@ -16,6 +28,7 @@ Config.Weapons = { name = 'WEAPON_COMBATPISTOL', label = _U('weapon_combatpistol'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATPISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATPISTOL_CLIP_02')}, @@ -29,6 +42,7 @@ Config.Weapons = { name = 'WEAPON_APPISTOL', label = _U('weapon_appistol'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_APPISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_APPISTOL_CLIP_02')}, @@ -42,6 +56,7 @@ Config.Weapons = { name = 'WEAPON_PISTOL50', label = _U('weapon_pistol50'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_PISTOL50_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_PISTOL50_CLIP_02')}, @@ -55,6 +70,7 @@ Config.Weapons = { name = 'WEAPON_SNSPISTOL', label = _U('weapon_snspistol'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SNSPISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SNSPISTOL_CLIP_02')}, @@ -66,6 +82,7 @@ Config.Weapons = { name = 'WEAPON_HEAVYPISTOL', label = _U('weapon_heavypistol'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_HEAVYPISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_HEAVYPISTOL_CLIP_02')}, @@ -79,6 +96,7 @@ Config.Weapons = { name = 'WEAPON_VINTAGEPISTOL', label = _U('weapon_vintagepistol'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_VINTAGEPISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_VINTAGEPISTOL_CLIP_02')}, @@ -90,6 +108,7 @@ Config.Weapons = { name = 'WEAPON_MACHINEPISTOL', label = _U('weapon_machinepistol'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_02')}, @@ -98,14 +117,15 @@ Config.Weapons = { } }, - {name = 'WEAPON_REVOLVER', label = _U('weapon_revolver'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}}, - {name = 'WEAPON_MARKSMANPISTOL', label = _U('weapon_marksmanpistol'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}}, + {name = 'WEAPON_REVOLVER', label = _U('weapon_revolver'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}}, + {name = 'WEAPON_MARKSMANPISTOL', label = _U('weapon_marksmanpistol'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}}, {name = 'WEAPON_DOUBLEACTION', label = _U('weapon_doubleaction'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}}, { name = 'WEAPON_SMG', label = _U('weapon_smg'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SMG')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SMG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SMG_CLIP_02')}, @@ -121,6 +141,7 @@ Config.Weapons = { name = 'WEAPON_ASSAULTSMG', label = _U('weapon_assaultsmg'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SMG')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTSMG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTSMG_CLIP_02')}, @@ -135,6 +156,7 @@ Config.Weapons = { name = 'WEAPON_MICROSMG', label = _U('weapon_microsmg'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SMG')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MICROSMG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MICROSMG_CLIP_02')}, @@ -149,6 +171,7 @@ Config.Weapons = { name = 'WEAPON_MINISMG', label = _U('weapon_minismg'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SMG')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MINISMG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MINISMG_CLIP_02')} @@ -159,6 +182,7 @@ Config.Weapons = { name = 'WEAPON_COMBATPDW', label = _U('weapon_combatpdw'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SMG')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATPDW_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATPDW_CLIP_02')}, @@ -173,6 +197,7 @@ Config.Weapons = { name = 'WEAPON_PUMPSHOTGUN', label = _U('weapon_pumpshotgun'), ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}, + tints = Config.DefaultWeaponTints, components = { {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_SR_SUPP')}, @@ -184,6 +209,7 @@ Config.Weapons = { name = 'WEAPON_SAWNOFFSHOTGUN', label = _U('weapon_sawnoffshotgun'), ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}, + tints = Config.DefaultWeaponTints, components = { {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SAWNOFFSHOTGUN_VARMOD_LUXE')} } @@ -193,6 +219,7 @@ Config.Weapons = { name = 'WEAPON_ASSAULTSHOTGUN', label = _U('weapon_assaultshotgun'), ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTSHOTGUN_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTSHOTGUN_CLIP_02')}, @@ -206,6 +233,7 @@ Config.Weapons = { name = 'WEAPON_BULLPUPSHOTGUN', label = _U('weapon_bullpupshotgun'), ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}, + tints = Config.DefaultWeaponTints, components = { {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, @@ -217,6 +245,7 @@ Config.Weapons = { name = 'WEAPON_HEAVYSHOTGUN', label = _U('weapon_heavyshotgun'), ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_HEAVYSHOTGUN_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_HEAVYSHOTGUN_CLIP_02')}, @@ -227,14 +256,15 @@ Config.Weapons = { } }, - {name = 'WEAPON_DBSHOTGUN', label = _U('weapon_dbshotgun'), components = {}, ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}}, - {name = 'WEAPON_AUTOSHOTGUN', label = _U('weapon_autoshotgun'), components = {}, ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}}, - {name = 'WEAPON_MUSKET', label = _U('weapon_musket'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SHOTGUN')}}, + {name = 'WEAPON_DBSHOTGUN', label = _U('weapon_dbshotgun'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}}, + {name = 'WEAPON_AUTOSHOTGUN', label = _U('weapon_autoshotgun'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}}, + {name = 'WEAPON_MUSKET', label = _U('weapon_musket'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SHOTGUN')}}, { name = 'WEAPON_ASSAULTRIFLE', label = _U('weapon_assaultrifle'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_CLIP_02')}, @@ -251,6 +281,7 @@ Config.Weapons = { name = 'WEAPON_CARBINERIFLE', label = _U('weapon_carbinerifle'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_CARBINERIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_CARBINERIFLE_CLIP_02')}, @@ -267,6 +298,7 @@ Config.Weapons = { name = 'WEAPON_ADVANCEDRIFLE', label = _U('weapon_advancedrifle'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ADVANCEDRIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ADVANCEDRIFLE_CLIP_02')}, @@ -281,6 +313,7 @@ Config.Weapons = { name = 'WEAPON_SPECIALCARBINE', label = _U('weapon_specialcarbine'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_CLIP_02')}, @@ -297,6 +330,7 @@ Config.Weapons = { name = 'WEAPON_BULLPUPRIFLE', label = _U('weapon_bullpuprifle'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_BULLPUPRIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_BULLPUPRIFLE_CLIP_02')}, @@ -312,6 +346,7 @@ Config.Weapons = { name = 'WEAPON_COMPACTRIFLE', label = _U('weapon_compactrifle'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMPACTRIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMPACTRIFLE_CLIP_02')}, @@ -323,6 +358,7 @@ Config.Weapons = { name = 'WEAPON_MG', label = _U('weapon_mg'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_MG')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MG_CLIP_02')}, @@ -335,6 +371,7 @@ Config.Weapons = { name = 'WEAPON_COMBATMG', label = _U('weapon_combatmg'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_MG')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATMG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATMG_CLIP_02')}, @@ -348,6 +385,7 @@ Config.Weapons = { name = 'WEAPON_GUSENBERG', label = _U('weapon_gusenberg'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_MG')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_GUSENBERG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_GUSENBERG_CLIP_02')}, @@ -358,6 +396,7 @@ Config.Weapons = { name = 'WEAPON_SNIPERRIFLE', label = _U('weapon_sniperrifle'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SNIPER')}, + tints = Config.DefaultWeaponTints, components = { {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_LARGE')}, {name = 'scope_advanced', label = _U('component_scope_advanced'), hash = GetHashKey('COMPONENT_AT_SCOPE_MAX')}, @@ -370,6 +409,7 @@ Config.Weapons = { name = 'WEAPON_HEAVYSNIPER', label = _U('weapon_heavysniper'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SNIPER')}, + tints = Config.DefaultWeaponTints, components = { {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_LARGE')}, {name = 'scope_advanced', label = _U('component_scope_advanced'), hash = GetHashKey('COMPONENT_AT_SCOPE_MAX')} @@ -380,6 +420,7 @@ Config.Weapons = { name = 'WEAPON_MARKSMANRIFLE', label = _U('weapon_marksmanrifle'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SNIPER')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MARKSMANRIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MARKSMANRIFLE_CLIP_02')}, @@ -391,19 +432,19 @@ Config.Weapons = { } }, + {name = 'WEAPON_MINIGUN', label = _U('weapon_minigun'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_MINIGUN')}}, + {name = 'WEAPON_RAILGUN', label = _U('weapon_railgun'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RAILGUN')}}, + {name = 'WEAPON_STUNGUN', label = _U('weapon_stungun'), tints = Config.DefaultWeaponTints, components = {}}, + {name = 'WEAPON_RPG', label = _U('weapon_rpg'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_rockets'), hash = GetHashKey('AMMO_RPG')}}, + {name = 'WEAPON_HOMINGLAUNCHER', label = _U('weapon_hominglauncher'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_rockets'), hash = GetHashKey('AMMO_HOMINGLAUNCHER')}}, + {name = 'WEAPON_GRENADELAUNCHER', label = _U('weapon_grenadelauncher'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_grenadelauncher'), hash = GetHashKey('AMMO_GRENADELAUNCHER')}}, + {name = 'WEAPON_COMPACTLAUNCHER', label = _U('weapon_compactlauncher'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_grenadelauncher'), hash = GetHashKey('AMMO_GRENADELAUNCHER')}}, + {name = 'WEAPON_FLAREGUN', label = _U('weapon_flaregun'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_flaregun'), hash = GetHashKey('AMMO_FLAREGUN')}}, {name = 'WEAPON_FIREEXTINGUISHER', label = _U('weapon_fireextinguisher'), components = {}, ammo = {label = _U('ammo_charge'), hash = GetHashKey('AMMO_FIREEXTINGUISHER')}}, {name = 'WEAPON_PETROLCAN', label = _U('weapon_petrolcan'), components = {}, ammo = {label = _U('ammo_petrol'), hash = GetHashKey('AMMO_PETROLCAN')}}, - {name = 'WEAPON_MINIGUN', label = _U('weapon_minigun'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_MINIGUN')}}, - {name = 'WEAPON_RAILGUN', label = _U('weapon_railgun'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RAILGUN')}}, - {name = 'WEAPON_STUNGUN', label = _U('weapon_stungun'), components = {}}, {name = 'WEAPON_FIREWORK', label = _U('weapon_firework'), components = {}, ammo = {label = _U('ammo_firework'), hash = GetHashKey('AMMO_FIREWORK')}}, - {name = 'WEAPON_RPG', label = _U('weapon_rpg'), components = {}, ammo = {label = _U('ammo_rockets'), hash = GetHashKey('AMMO_RPG')}}, - {name = 'WEAPON_HOMINGLAUNCHER', label = _U('weapon_hominglauncher'), components = {}, ammo = {label = _U('ammo_rockets'), hash = GetHashKey('AMMO_HOMINGLAUNCHER')}}, - {name = 'WEAPON_GRENADELAUNCHER', label = _U('weapon_grenadelauncher'), components = {}, ammo = {label = _U('ammo_grenadelauncher'), hash = GetHashKey('AMMO_GRENADELAUNCHER')}}, - {name = 'WEAPON_COMPACTLAUNCHER', label = _U('weapon_compactlauncher'), components = {}, ammo = {label = _U('ammo_grenadelauncher'), hash = GetHashKey('AMMO_GRENADELAUNCHER')}}, {name = 'WEAPON_FLASHLIGHT', label = _U('weapon_flashlight'), components = {}}, {name = 'GADGET_PARACHUTE', label = _U('gadget_parachute'), components = {}}, - {name = 'WEAPON_KNUCKLE', label = _U('weapon_knuckle'), components = {}}, {name = 'WEAPON_HATCHET', label = _U('weapon_hatchet'), components = {}}, {name = 'WEAPON_MACHETE', label = _U('weapon_machete'), components = {}}, @@ -421,14 +462,13 @@ Config.Weapons = { {name = 'WEAPON_CROWBAR', label = _U('weapon_crowbar'), components = {}}, {name = 'WEAPON_GRENADE', label = _U('weapon_grenade'), components = {}, ammo = {label = _U('ammo_grenade'), hash = GetHashKey('AMMO_GRENADE')}}, + {name = 'WEAPON_SMOKEGRENADE', label = _U('weapon_smokegrenade'), components = {}, ammo = {label = _U('ammo_smokebomb'), hash = GetHashKey('AMMO_SMOKEGRENADE')}}, {name = 'WEAPON_STICKYBOMB', label = _U('weapon_stickybomb'), components = {}, ammo = {label = _U('ammo_stickybomb'), hash = GetHashKey('AMMO_STICKYBOMB')}}, {name = 'WEAPON_PIPEBOMB', label = _U('weapon_pipebomb'), components = {}, ammo = {label = _U('ammo_pipebomb'), hash = GetHashKey('AMMO_PIPEBOMB')}}, - {name = 'WEAPON_SMOKEGRENADE', label = _U('weapon_smokegrenade'), components = {}, ammo = {label = _U('ammo_smokebomb'), hash = GetHashKey('AMMO_SMOKEGRENADE')}}, {name = 'WEAPON_BZGAS', label = _U('weapon_bzgas'), components = {}, ammo = {label = _U('ammo_bzgas'), hash = GetHashKey('AMMO_BZGAS')}}, {name = 'WEAPON_MOLOTOV', label = _U('weapon_molotov'), components = {}, ammo = {label = _U('ammo_molotov'), hash = GetHashKey('AMMO_MOLOTOV')}}, {name = 'WEAPON_PROXMINE', label = _U('weapon_proxmine'), components = {}, ammo = {label = _U('ammo_proxmine'), hash = GetHashKey('AMMO_PROXMINE')}}, - {name = 'WEAPON_BALL', label = _U('weapon_ball'), components = {}, ammo = {label = _U('ammo_ball'), hash = GetHashKey('AMMO_BALL')}}, {name = 'WEAPON_SNOWBALL', label = _U('weapon_snowball'), components = {}, ammo = {label = _U('ammo_snowball'), hash = GetHashKey('AMMO_SNOWBALL')}}, - {name = 'WEAPON_FLARE', label = _U('weapon_flare'), components = {}, ammo = {label = _U('ammo_flare'), hash = GetHashKey('AMMO_FLARE')}}, - {name = 'WEAPON_FLAREGUN', label = _U('weapon_flaregun'), components = {}, ammo = {label = _U('ammo_flaregun'), hash = GetHashKey('AMMO_FLAREGUN')}} + {name = 'WEAPON_BALL', label = _U('weapon_ball'), components = {}, ammo = {label = _U('ammo_ball'), hash = GetHashKey('AMMO_BALL')}}, + {name = 'WEAPON_FLARE', label = _U('weapon_flare'), components = {}, ammo = {label = _U('ammo_flare'), hash = GetHashKey('AMMO_FLARE')}} } diff --git a/locales/br.lua b/locales/br.lua index b3db1ee3..a7b54c8f 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -190,4 +190,14 @@ Locales['br'] = { ['ammo_snowball'] = 'snowball(s)', ['ammo_flare'] = 'flare(s)', ['ammo_flaregun'] = 'flare(s)', + + -- Weapon Tints + ['tint_default'] = 'default skin', + ['tint_green'] = 'green skin', + ['tint_gold'] = 'gold skin', + ['tint_pink'] = 'pink skin', + ['tint_army'] = 'army skin', + ['tint_lspd'] = 'blue skin', + ['tint_orange'] = 'orange skin', + ['tint_platinum'] = 'platinum skin', } diff --git a/locales/cs.lua b/locales/cs.lua index b980fc6a..72b398de 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -190,4 +190,14 @@ Locales['cs'] = { ['ammo_snowball'] = 'snowball(s)', ['ammo_flare'] = 'flare(s)', ['ammo_flaregun'] = 'flare(s)', + + -- Weapon Tints + ['tint_default'] = 'default skin', + ['tint_green'] = 'green skin', + ['tint_gold'] = 'gold skin', + ['tint_pink'] = 'pink skin', + ['tint_army'] = 'army skin', + ['tint_lspd'] = 'blue skin', + ['tint_orange'] = 'orange skin', + ['tint_platinum'] = 'platinum skin', } diff --git a/locales/de.lua b/locales/de.lua index 0068ed65..37beefe7 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -189,4 +189,14 @@ Locales['de'] = { ['ammo_snowball'] = 'snowball(s)', ['ammo_flare'] = 'flare(s)', ['ammo_flaregun'] = 'flare(s)', + + -- Weapon Tints + ['tint_default'] = 'default skin', + ['tint_green'] = 'green skin', + ['tint_gold'] = 'gold skin', + ['tint_pink'] = 'pink skin', + ['tint_army'] = 'army skin', + ['tint_lspd'] = 'blue skin', + ['tint_orange'] = 'orange skin', + ['tint_platinum'] = 'platinum skin', } diff --git a/locales/en.lua b/locales/en.lua index babcb272..e8ed9a67 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -189,4 +189,14 @@ Locales['en'] = { ['ammo_snowball'] = 'snowball(s)', ['ammo_flare'] = 'flare(s)', ['ammo_flaregun'] = 'flare(s)', + + -- Weapon Tints + ['tint_default'] = 'default skin', + ['tint_green'] = 'green skin', + ['tint_gold'] = 'gold skin', + ['tint_pink'] = 'pink skin', + ['tint_army'] = 'army skin', + ['tint_lspd'] = 'blue skin', + ['tint_orange'] = 'orange skin', + ['tint_platinum'] = 'platinum skin', } diff --git a/locales/fi.lua b/locales/fi.lua index 2dd566c4..5e987651 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -189,4 +189,14 @@ Locales['fi'] = { ['ammo_snowball'] = 'snowball(s)', ['ammo_flare'] = 'flare(s)', ['ammo_flaregun'] = 'flare(s)', + + -- Weapon Tints + ['tint_default'] = 'default skin', + ['tint_green'] = 'green skin', + ['tint_gold'] = 'gold skin', + ['tint_pink'] = 'pink skin', + ['tint_army'] = 'army skin', + ['tint_lspd'] = 'blue skin', + ['tint_orange'] = 'orange skin', + ['tint_platinum'] = 'platinum skin', } diff --git a/locales/fr.lua b/locales/fr.lua index 55d849d6..4d83dd0e 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -189,4 +189,14 @@ Locales['fr'] = { ['ammo_snowball'] = 'boule(s) de neige', ['ammo_flare'] = 'fusée(s) éclairante(s)', ['ammo_flaregun'] = 'fusée(s)', + + -- Weapon Tints + ['tint_default'] = 'default skin', + ['tint_green'] = 'green skin', + ['tint_gold'] = 'gold skin', + ['tint_pink'] = 'pink skin', + ['tint_army'] = 'army skin', + ['tint_lspd'] = 'blue skin', + ['tint_orange'] = 'orange skin', + ['tint_platinum'] = 'platinum skin', } diff --git a/locales/pl.lua b/locales/pl.lua index 9ad79c2e..2c9d3bdc 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -189,4 +189,14 @@ Locales['pl'] = { ['ammo_snowball'] = 'snowball(s)', ['ammo_flare'] = 'flare(s)', ['ammo_flaregun'] = 'flare(s)', + + -- Weapon Tints + ['tint_default'] = 'default skin', + ['tint_green'] = 'green skin', + ['tint_gold'] = 'gold skin', + ['tint_pink'] = 'pink skin', + ['tint_army'] = 'army skin', + ['tint_lspd'] = 'blue skin', + ['tint_orange'] = 'orange skin', + ['tint_platinum'] = 'platinum skin', } diff --git a/locales/sv.lua b/locales/sv.lua index d1e41405..66060f6f 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -152,7 +152,7 @@ Locales['sv'] = { ['weapon_minismg'] = 'mini smg', ['weapon_pipebomb'] = 'pipe bomb', ['weapon_poolcue'] = 'biljardkö', - ['weapon_wrench'] = 'rörtång', + ['weapon_wrench'] = 'skiftnyckel', ['weapon_flashlight'] = 'ficklampa', ['gadget_parachute'] = 'fallskärm', ['weapon_flare'] = 'signalpistol', @@ -189,4 +189,14 @@ Locales['sv'] = { ['ammo_snowball'] = 'snöboll(ar)', ['ammo_flare'] = 'lysraket(er)', ['ammo_flaregun'] = 'lysraket(er)', + + -- Weapon Tints + ['tint_default'] = 'standardutseende', + ['tint_green'] = 'grönskinn', + ['tint_gold'] = 'guldskinn', + ['tint_pink'] = 'råsaskinn', + ['tint_army'] = 'arméskinn', + ['tint_lspd'] = 'blåskinn', + ['tint_orange'] = 'orangeskinn', + ['tint_platinum'] = 'platinaskinn', } diff --git a/server/classes/player.lua b/server/classes/player.lua index 3b931af8..0f5bf295 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -375,7 +375,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c name = weaponName, ammo = ammo, label = weaponLabel, - components = {} + components = {}, + tintIndex = 0 }) self.triggerEvent('esx:addWeapon', weaponName, ammo) @@ -408,6 +409,30 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c end end + self.setWeaponTint = function(weaponName, weaponTintIndex) + local loadoutNum, weapon = self.getWeapon(weaponName) + + if weapon then + local weaponNum, weaponObject = ESX.GetWeapon(weaponName) + + if weaponObject.tints and weaponObject.tints[weaponTintIndex] then + self.loadout[loadoutNum].tintIndex = weaponTintIndex + self.triggerEvent('esx:setWeaponTint', weaponName, weaponTintIndex) + self.triggerEvent('esx:addInventoryItem', weaponObject.tints[weaponTintIndex], false, true) + end + end + end + + self.getWeaponTint = function(weaponName) + local loadoutNum, weapon = self.getWeapon(weaponName) + + if weapon then + return weapon.tintIndex + end + + return 0 + end + self.removeWeapon = function(weaponName, ammo) local weaponLabel diff --git a/server/functions.lua b/server/functions.lua index 2a20eeea..b9cc7b87 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -159,7 +159,7 @@ ESX.GetItemLabel = function(item) end end -ESX.CreatePickup = function(type, name, count, label, playerId, components) +ESX.CreatePickup = function(type, name, count, label, playerId, components, tintIndex) local pickupId = (ESX.PickupId == 65635 and 0 or ESX.PickupId + 1) local xPlayer = ESX.GetPlayerFromId(playerId) @@ -173,9 +173,10 @@ ESX.CreatePickup = function(type, name, count, label, playerId, components) if type == 'item_weapon' then ESX.Pickups[pickupId].components = components + ESX.Pickups[pickupId].tintIndex = tintIndex end - TriggerClientEvent('esx:createPickup', -1, pickupId, label, playerId, type, name, components) + TriggerClientEvent('esx:createPickup', -1, pickupId, label, playerId, type, name, components, tintIndex) ESX.PickupId = pickupId end diff --git a/server/main.lua b/server/main.lua index ae630198..6e59e989 100644 --- a/server/main.lua +++ b/server/main.lua @@ -159,9 +159,8 @@ AddEventHandler('es:playerLoaded', function(playerId, player) -- Compatibility with old loadouts prior to components update for k,v in ipairs(userData.loadout) do - if v.components == nil then - v.components = {} - end + if not v.components then v.components = {} end + if not v.tintIndex then v.tintIndex = 0 end end end @@ -404,7 +403,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) xPlayer.showNotification(_U('threw_weapon', weapon.label)) end - ESX.CreatePickup('item_weapon', itemName, weapon.ammo, pickupLabel, playerId, weapon.components) + ESX.CreatePickup('item_weapon', itemName, weapon.ammo, pickupLabel, playerId, weapon.components, weapon.tintIndex) end end end) @@ -445,6 +444,7 @@ AddEventHandler('esx:onPickup', function(id) else success = true xPlayer.addWeapon(pickup.name, pickup.count) + xPlayer.setWeaponTint(pickup.name, pickup.tintIndex) for k,v in ipairs(pickup.components) do xPlayer.addWeaponComponent(pickup.name, v) From 48dfa27397be0348eecfe74a68b8dbf649e40c5c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 11 Feb 2020 21:13:25 +0100 Subject: [PATCH 2537/3224] Removed /disc command, closes #464 Co-Authored-By: Andrea Passarini --- locales/br.lua | 2 -- locales/cs.lua | 1 - locales/de.lua | 1 - locales/en.lua | 1 - locales/fi.lua | 1 - locales/fr.lua | 1 - locales/pl.lua | 1 - locales/sv.lua | 1 - server/commands.lua | 6 ------ 9 files changed, 15 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index a7b54c8f..86fb98d2 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -71,8 +71,6 @@ Locales['br'] = { ['giveitem'] = 'dar item', ['weapon'] = 'arma', ['giveweapon'] = 'dar arma', - - ['disconnect'] = 'desconectar do servidor', ['chat_clear'] = 'limpar o chat', ['chat_clear_all'] = 'limpar o chat para todos', ['command_clearinventory'] = 'remover todos os itens do inventário', diff --git a/locales/cs.lua b/locales/cs.lua index 72b398de..5c1283b8 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -72,7 +72,6 @@ Locales['cs'] = { ['giveitem'] = 'dát věc', ['weapon'] = 'zbraň', ['giveweapon'] = 'dát zbraň', - ['disconnect'] = 'odpojit od serveru', ['chat_clear'] = 'vyčistit chat', ['chat_clear_all'] = 'vyčistit chat pro všechny', ['command_clearinventory'] = 'clear all items from inventory', diff --git a/locales/de.lua b/locales/de.lua index 37beefe7..44f23ed0 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -71,7 +71,6 @@ Locales['de'] = { ['giveitem'] = 'give item', ['weapon'] = 'weapon', ['giveweapon'] = 'give weapon', - ['disconnect'] = 'disconnect from the server', ['chat_clear'] = 'clear the chat', ['chat_clear_all'] = 'clear the chat for everyone', ['command_clearinventory'] = 'clear all items from inventory', diff --git a/locales/en.lua b/locales/en.lua index e8ed9a67..73ad1b84 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -71,7 +71,6 @@ Locales['en'] = { ['giveitem'] = 'give item', ['weapon'] = 'weapon', ['giveweapon'] = 'give weapon', - ['disconnect'] = 'disconnect from the server', ['chat_clear'] = 'clear the chat', ['chat_clear_all'] = 'clear the chat for everyone', ['command_clearinventory'] = 'clear all items from inventory', diff --git a/locales/fi.lua b/locales/fi.lua index 5e987651..e996ad77 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -71,7 +71,6 @@ Locales['fi'] = { ['giveitem'] = 'anna itemi', ['weapon'] = 'ase', ['giveweapon'] = 'anna ase', - ['disconnect'] = 'poistu serveriltä', ['chat_clear'] = 'tyhjennä chatti', ['chat_clear_all'] = 'tyhjennä chatti kaikilta', ['command_clearinventory'] = 'clear all items from inventory', diff --git a/locales/fr.lua b/locales/fr.lua index 4d83dd0e..3483566a 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -71,7 +71,6 @@ Locales['fr'] = { ['giveitem'] = 'donner un article', ['weapon'] = 'arme', ['giveweapon'] = 'donner l\'arme', - ['disconnect'] = 'déconnecter du serveur', ['chat_clear'] = 'vider le chat', ['chat_clear_all'] = 'vider le chat pour tous le monde', ['command_clearinventory'] = 'effacer tout les items de l\'inventaire', diff --git a/locales/pl.lua b/locales/pl.lua index 2c9d3bdc..4cdfe07e 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -71,7 +71,6 @@ Locales['pl'] = { ['giveitem'] = 'daj przedmiot', ['weapon'] = 'broń', ['giveweapon'] = 'daj broń', - ['disconnect'] = 'odłącz się od serwera', ['chat_clear'] = 'wyczyść czat', ['chat_clear_all'] = 'wyczyść czat dla wszystkich', ['command_clearinventory'] = 'usuń wszystkie przedmioty z ekwipunku', diff --git a/locales/sv.lua b/locales/sv.lua index 66060f6f..1f23cbc4 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -71,7 +71,6 @@ Locales['sv'] = { ['giveitem'] = 'ge föremål', ['weapon'] = 'vapen', ['giveweapon'] = 'ge vapen', - ['disconnect'] = 'koppla från servern', ['chat_clear'] = 'töm chatten', ['chat_clear_all'] = 'töm chatten för alla', ['command_clearinventory'] = 'clear all items from inventory', diff --git a/server/commands.lua b/server/commands.lua index 965e5bf2..dea5e1ee 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -192,12 +192,6 @@ end, {help = 'Give weapon component', params = { {name = 'componentName', help = 'weapon component'} }}) -TriggerEvent('es:addGroupCommand', 'disc', 'admin', function(source, args, user) - DropPlayer(source, 'You have been disconnected') -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('disconnect')}) - TriggerEvent('es:addGroupCommand', 'clear', 'user', function(source, args, user) TriggerClientEvent('chat:clear', source) end, function(source, args, user) From f147a7be8109e8bd94c1df5be4f32c27bf67ae02 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 11 Feb 2020 21:25:46 +0100 Subject: [PATCH 2538/3224] Minor changes --- README.md | 6 ++++-- client/main.lua | 29 ++++++++++++----------------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index c1882150..cc46a37a 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,12 @@ # esx_taxijob +ESX Taxi Job adds driving cabs as a service, and more including NPC missions. + ## Requirements * Auto mode * [esx_service](https://github.com/ESX-Org/esx_service) - + * Player management (billing and boss actions) * [esx_society](https://github.com/ESX-Org/esx_society) * [esx_billing](https://github.com/ESX-Org/esx_billing) @@ -38,7 +40,7 @@ start esx_taxijob ### License esx_taxijob -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. diff --git a/client/main.lua b/client/main.lua index debf7487..becd6c01 100644 --- a/client/main.lua +++ b/client/main.lua @@ -27,12 +27,12 @@ function ShowLoadingPromt(msg, time, type) Citizen.CreateThread(function() Citizen.Wait(0) - BeginTextCommandBusyString('STRING') + BeginTextCommandBusyspinnerOn('STRING') AddTextComponentSubstringPlayerName(msg) - EndTextCommandBusyString(type) + EndTextCommandBusyspinnerOn(type) Citizen.Wait(time) - RemoveLoadingPrompt() + BusyspinnerOff() end) end @@ -108,15 +108,13 @@ end function OpenCloakroom() ESX.UI.Menu.CloseAll() - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'taxi_cloakroom', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'taxi_cloakroom', { title = _U('cloakroom_menu'), align = 'top-left', elements = { - { label = _U('wear_citizen'), value = 'wear_citizen' }, - { label = _U('wear_work'), value = 'wear_work'} - } - }, function(data, menu) + {label = _U('wear_citizen'), value = 'wear_citizen'}, + {label = _U('wear_work'), value = 'wear_work'} + }}, function(data, menu) if data.current.value == 'wear_citizen' then ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin) TriggerEvent('skinchanger:loadSkin', skin) @@ -155,8 +153,7 @@ function OpenVehicleSpawnerMenu() }) end - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_spawner', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_spawner', { title = _U('spawn_veh'), align = 'top-left', elements = elements @@ -176,7 +173,6 @@ function OpenVehicleSpawnerMenu() end) TriggerServerEvent('esx_society:removeVehicleFromGarage', 'taxi', vehicleProps) - end, function(data, menu) CurrentAction = 'vehicle_spawner' CurrentActionMsg = _U('spawner_prompt') @@ -188,11 +184,10 @@ function OpenVehicleSpawnerMenu() else -- not society vehicles - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_spawner', - { - title = _U('spawn_veh'), - align = 'top-left', - elements = Config.AuthorizedVehicles + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_spawner', { + title = _U('spawn_veh'), + align = 'top-left', + elements = Config.AuthorizedVehicles }, function(data, menu) if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then ESX.ShowNotification(_U('spawnpoint_blocked')) From f2c646366591b909d8f576ea5f3585ac5d865aed Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 11 Feb 2020 21:28:20 +0100 Subject: [PATCH 2539/3224] Minor changes --- README.md | 4 +++- client/main.lua | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b5cb8d14..04c5b0d3 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # esx_weaponshop +ESX Weapon Shop adds.. well you guessed it - weapon shops to the already existing shops in the world. + ## Download & Installation ### Using [fvm](https://github.com/qlaffont/fvm-installer) @@ -29,7 +31,7 @@ start esx_weaponshop ### License esx_weaponshop - Legal and illegal weapon shops -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. diff --git a/client/main.lua b/client/main.lua index 8d2ec4b5..b213fe8b 100644 --- a/client/main.lua +++ b/client/main.lua @@ -33,8 +33,8 @@ function OpenBuyLicenseMenu(zone) title = _U('buy_license'), align = 'top-left', elements = { - { label = _U('no'), value = 'no' }, - { label = _U('yes', ('%s'):format((_U('shop_menu_item', ESX.Math.GroupDigits(Config.LicensePrice))))), value = 'yes' }, + {label = _U('no'), value = 'no'}, + {label = _U('yes', ('%s'):format((_U('shop_menu_item', ESX.Math.GroupDigits(Config.LicensePrice))))), value = 'yes'}, } }, function(data, menu) if data.current.value == 'yes' then From 11a541b67268334a2901fd2f311167a7551086e7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 12 Feb 2020 10:32:23 +0100 Subject: [PATCH 2540/3224] Fixed #496 --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 7e74d212..5365f53c 100644 --- a/client/main.lua +++ b/client/main.lua @@ -256,7 +256,7 @@ AddEventHandler('esx:spawnVehicle', function(vehicle) local playerPed = PlayerPedId() local playerCoords, playerHeading = GetEntityCoords(playerPed), GetEntityHeading(playerPed) - ESX.Game.SpawnVehicle(model, coords, playerHeading, function(vehicle) + ESX.Game.SpawnVehicle(model, playerCoords, playerHeading, function(vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) end) else From f83e05c83b4a2accb4c97782910faf49f51bef87 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 12 Feb 2020 10:48:21 +0100 Subject: [PATCH 2541/3224] Fixed searching for vehicles, closes #398 Co-Authored-By: mortdudley --- client/main.lua | 30 ++++++++++++++++++++---------- locales/br.lua | 2 -- locales/cs.lua | 2 -- locales/de.lua | 2 -- locales/en.lua | 2 -- locales/es.lua | 2 -- locales/fi.lua | 2 -- locales/fr.lua | 2 -- locales/ko.lua | 2 -- locales/pl.lua | 2 -- locales/sv.lua | 2 -- server/main.lua | 35 +++++------------------------------ 12 files changed, 25 insertions(+), 60 deletions(-) diff --git a/client/main.lua b/client/main.lua index f0dfacaf..1305acde 100644 --- a/client/main.lua +++ b/client/main.lua @@ -543,17 +543,28 @@ function LookupVehicle() title = _U('search_database_title'), }, function(data, menu) local length = string.len(data.value) - if data.value == nil or length < 2 or length > 13 then + if not data.value or length < 2 or length > 8 then ESX.ShowNotification(_U('search_database_error_invalid')) else - ESX.TriggerServerCallback('esx_policejob:getVehicleFromPlate', function(owner, found) - if found then - ESX.ShowNotification(_U('search_database_found', owner)) + ESX.TriggerServerCallback('esx_policejob:getVehicleInfos', function(retrivedInfo) + local elements = {{label = _U('plate', retrivedInfo.plate)}} + menu.close() + + if not retrivedInfo.owner then + table.insert(elements, {label = _U('owner_unknown')}) else - ESX.ShowNotification(_U('search_database_error_not_found')) + table.insert(elements, {label = _U('owner', retrivedInfo.owner)}) end + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_infos', { + title = _U('vehicle_info'), + align = 'top-left', + elements = elements + }, nil, function(data2, menu2) + menu2.close() + end) end, data.value) - menu.close() + end end, function(data, menu) menu.close() @@ -620,7 +631,7 @@ function OpenVehicleInfosMenu(vehicleData) ESX.TriggerServerCallback('esx_policejob:getVehicleInfos', function(retrivedInfo) local elements = {{label = _U('plate', retrivedInfo.plate)}} - if retrivedInfo.owner == nil then + if not retrivedInfo.owner then table.insert(elements, {label = _U('owner_unknown')}) else table.insert(elements, {label = _U('owner', retrivedInfo.owner)}) @@ -699,7 +710,6 @@ end function OpenBuyWeaponsMenu() local elements = {} local playerPed = PlayerPedId() - PlayerData = ESX.GetPlayerData() for k,v in ipairs(Config.AuthorizedWeapons[ESX.PlayerData.job.grade_name]) do local weaponNum, weapon = ESX.GetWeapon(v.weapon) @@ -836,7 +846,7 @@ function OpenGetStocksMenu() }, function(data2, menu2) local count = tonumber(data2.value) - if count == nil then + if not count then ESX.ShowNotification(_U('quantity_invalid')) else menu2.close() @@ -883,7 +893,7 @@ function OpenPutStocksMenu() }, function(data2, menu2) local count = tonumber(data2.value) - if count == nil then + if not count then ESX.ShowNotification(_U('quantity_invalid')) else menu2.close() diff --git a/locales/br.lua b/locales/br.lua index 5bd1cbee..cadc743f 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -93,8 +93,6 @@ Locales['br'] = { ['search_database'] = 'informação do veículo', ['search_database_title'] = 'informações do veículo - pesquisa com número de registro', ['search_database_error_invalid'] = 'que ~r~não~s~ é um número de registro ~y~válido~s~', - ['search_database_error_not_found'] = 'esse número de ~y~registror~s~ ~r~não~s~ está registrado em um veículo!', - ['search_database_found'] = 'o veículo está ~y~registrado~s~ para ~b~%s~s~', -- Traffic interaction ['traffic_interaction'] = 'Interagir com as rodovias', ['cone'] = 'Cones', diff --git a/locales/cs.lua b/locales/cs.lua index be112891..0c494b2f 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -93,8 +93,6 @@ Locales['cs'] = { ['search_database'] = 'informace o vozidle', ['search_database_title'] = 'informace o vozidle - pomocí registracnich cisel', ['search_database_error_invalid'] = 'tohle ~r~neni~s~ ~y~spravne~s~ registracni cislo', - ['search_database_error_not_found'] = 'toto ~y~registracni cislo~s~ je ~r~nespravne~s~ pro toto vozidlo!', - ['search_database_found'] = 'vozidlo bylo ~y~registrovano~s~ k ~b~%s~s~', -- Traffic interaction ['traffic_interaction'] = 'interakce provozu', ['cone'] = 'kuzel', diff --git a/locales/de.lua b/locales/de.lua index 7492e226..5ed2776f 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -93,8 +93,6 @@ Locales['de'] = { ['search_database'] = 'vehicle information', ['search_database_title'] = 'vehicle information - search with registration number', ['search_database_error_invalid'] = 'that is ~r~not~s~ a ~y~valid~s~ registration number', - ['search_database_error_not_found'] = 'that ~y~registration number~s~ is ~r~not~s~ registered to an vehicle!', - ['search_database_found'] = 'the vehicle is ~y~registered~s~ to ~b~%s~s~', -- Traffic interaction ['traffic_interaction'] = 'Straßeninteraktionen', ['cone'] = 'Hütchen', diff --git a/locales/en.lua b/locales/en.lua index 2a08acd5..e7585c78 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -93,8 +93,6 @@ Locales['en'] = { ['search_database'] = 'vehicle information', ['search_database_title'] = 'vehicle information - search with registration number', ['search_database_error_invalid'] = 'that is ~r~not~s~ a ~y~valid~s~ registration number', - ['search_database_error_not_found'] = 'that ~y~registration number~s~ is ~r~not~s~ registered to an vehicle!', - ['search_database_found'] = 'the vehicle is ~y~registered~s~ to ~b~%s~s~', -- Traffic interaction ['traffic_interaction'] = 'interaction Traffic', ['cone'] = 'cone', diff --git a/locales/es.lua b/locales/es.lua index 354c89e6..ce0001cb 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -93,8 +93,6 @@ Locales['es'] = { ['search_database'] = 'vehicle information', ['search_database_title'] = 'vehicle information - search with registration number', ['search_database_error_invalid'] = 'that is ~r~not~s~ a ~y~valid~s~ registration number', - ['search_database_error_not_found'] = 'that ~y~registration number~s~ is ~r~not~s~ registered to an vehicle!', - ['search_database_found'] = 'the vehicle is ~y~registered~s~ to ~b~%s~s~', -- Traffic interaction ['traffic_interaction'] = 'Rutas de interacción', ['cone'] = 'Cono', diff --git a/locales/fi.lua b/locales/fi.lua index b0f5d7d9..abf04045 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -93,8 +93,6 @@ Locales['fi'] = { ['search_database'] = 'ajoneuvon tiedot', ['search_database_title'] = 'ajoneuvon tiedot - etsi rekisterinumerolla', ['search_database_error_invalid'] = 'tämä ~r~ei ole~s~ ~y~voimassa oleva~s~ rekisterinumero', - ['search_database_error_not_found'] = 'tämä ~y~rekisterinumero~s~ ~r~ei~s~ ole rekistöröity ajoneuvoon!', - ['search_database_found'] = 'ajoneuvo on ~y~rekistöröity~s~ henkilölle ~b~%s~s~', -- Traffic interaction ['traffic_interaction'] = 'liikenteen vuorovaikutus', ['cone'] = 'kartio', diff --git a/locales/fr.lua b/locales/fr.lua index d30a825b..3eaf1a6d 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -93,8 +93,6 @@ Locales['fr'] = { ['search_database'] = 'vehicle information', ['search_database_title'] = 'informations sur le véhicule - recherche avec numéro d\'enregistrement', ['search_database_error_invalid'] = 'Ce n\'est ~r~pas~s~ un ~y~numéro d\'enregistrement valide~s~', - ['search_database_error_not_found'] = 'ce ~y~numéro d\'enregistrement ~s~est~r~ pas ~s~ enregistré sur un véhicule!', - ['search_database_found'] = 'le véhicule est ~y~enregistré~s~ à ~b~%s~s~', -- Traffic interaction ['traffic_interaction'] = 'interaction routière', ['cone'] = 'plot', diff --git a/locales/ko.lua b/locales/ko.lua index ea2c093c..e85e9998 100644 --- a/locales/ko.lua +++ b/locales/ko.lua @@ -93,8 +93,6 @@ Locales['ko'] = { ['search_database'] = '차량 정보', ['search_database_title'] = '차량 정보 - 등록번호로 검색', ['search_database_error_invalid'] = '~y~유효한~s~ 등록 번호가 ~r~아닙니다.~s~', - ['search_database_error_not_found'] = '그 ~y~등록 번호~s~는 차량에 등록되지 ~r~않았습니다!~s~', - ['search_database_found'] = '이 차량은 ~b~%s~s~에 ~y~등록되었습니다~s~', -- Traffic interaction ['traffic_interaction'] = '교통 상호 작용', ['cone'] = '원뿔', diff --git a/locales/pl.lua b/locales/pl.lua index ab5e8678..2f2a0479 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -93,8 +93,6 @@ Locales['pl'] = { ['search_database'] = 'informacje o pojeździe', ['search_database_title'] = 'informacjeo pojeździe - przeszukaj używając numeru rejestracyjnego', ['search_database_error_invalid'] = 'to ~r~nie~s~ jest ~y~poprawny~s~ rnumer rejestracyjny', - ['search_database_error_not_found'] = 'ten ~y~numer rejestracyjny~s~ ~r~nie jest~s~ zarejestrowany do tego pojazdu!', - ['search_database_found'] = 'pojazd jest ~y~zarejestrowany~s~ do ~b~%s~s~', -- Traffic interaction ['traffic_interaction'] = 'interakcje dla ruchu drogowego', ['cone'] = 'pachołek', diff --git a/locales/sv.lua b/locales/sv.lua index 8a7d4295..ba2c2179 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -93,8 +93,6 @@ Locales['sv'] = { ['search_database'] = 'fordonsuppgifter', ['search_database_title'] = 'fordonsuppgifter - sök med registreringsnummer', ['search_database_error_invalid'] = 'det är ~r~inte~s~ ett ~y~giltigt~s~ registreringsnummer', - ['search_database_error_not_found'] = 'det ~y~registreringsnummeret~s~ är ~r~inte~s~ registrerat till något fordon!', - ['search_database_found'] = 'detta fordon är ~y~registrerat~s~ till ~b~%s~s~', -- Traffic interaction ['traffic_interaction'] = 'trafiksåtgärder', ['cone'] = 'kon', diff --git a/server/main.lua b/server/main.lua index e328e551..b15030ce 100644 --- a/server/main.lua +++ b/server/main.lua @@ -207,22 +207,19 @@ ESX.RegisterServerCallback('esx_policejob:getVehicleInfos', function(source, cb, if xPlayer then retrivedInfo.owner = xPlayer.getName() cb(retrivedInfo) - else - MySQL.Async.fetchAll('SELECT name, firstname, lastname FROM users WHERE identifier = @identifier', { + 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 - if Config.EnableESXIdentity then - retrivedInfo.owner = ('%s %s'):format(result2[1].firstname, result2[1].lastname) - else - retrivedInfo.owner = result2[1].name - end - + retrivedInfo.owner = ('%s %s'):format(result2[1].firstname, result2[1].lastname) cb(retrivedInfo) else cb(retrivedInfo) end end) + else + cb(retrivedInfo) end else cb(retrivedInfo) @@ -230,28 +227,6 @@ ESX.RegisterServerCallback('esx_policejob:getVehicleInfos', function(source, cb, end) end) -ESX.RegisterServerCallback('esx_policejob:getVehicleFromPlate', function(source, cb, plate) - MySQL.Async.fetchAll('SELECT owner FROM owned_vehicles WHERE plate = @plate', { - ['@plate'] = plate - }, function(result) - if result[1] then - MySQL.Async.fetchAll('SELECT name, firstname, lastname FROM users WHERE identifier = @identifier', { - ['@identifier'] = result[1].owner - }, function(result2) - - if Config.EnableESXIdentity then - cb(('%s %s'):format(result2[1].firstname, result2[1].lastname), true) - else - cb(result2[1].name, true) - end - - end) - else - cb(_U('unknown'), false) - end - end) -end) - ESX.RegisterServerCallback('esx_policejob:getArmoryWeapons', function(source, cb) TriggerEvent('esx_datastore:getSharedDataStore', 'society_police', function(store) local weapons = store.get('weapons') From dae665f77ad8a98ebffe78bcc9a21bef85bafebf Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 12 Feb 2020 10:59:01 +0100 Subject: [PATCH 2542/3224] Cron job use async to not kill server paying rent --- fxmanifest.lua | 1 + server/main.lua | 42 +++++++++++++++++++++++++++--------------- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/fxmanifest.lua b/fxmanifest.lua index e4fe09c4..5f171a6d 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -7,6 +7,7 @@ description 'ESX Vehicle Shop' version '1.1.0' server_scripts { + '@async/async.lua', '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', 'locales/br.lua', diff --git a/server/main.lua b/server/main.lua index 6ee336f6..3955bd95 100644 --- a/server/main.lua +++ b/server/main.lua @@ -234,7 +234,7 @@ ESX.RegisterServerCallback('esx_vehicleshop:buyCarDealerVehicle', function(sourc 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 @@ -311,7 +311,7 @@ ESX.RegisterServerCallback('esx_vehicleshop:giveBackVehicle', function(source, c ['@vehicle'] = vehicle, ['@price'] = basePrice }) - + RemoveOwnedVehicle(plate) cb(true) end) @@ -420,24 +420,36 @@ AddEventHandler('esx_vehicleshop:setJobVehicleState', function(plate, state) end) function PayRent(d, h, m) - MySQL.Async.fetchAll('SELECT * FROM rented_vehicles', {}, function(result) + local tasks, timeStart = {}, os.clock() + print('[esx_vehicleshop] [^2INFO^7] Paying rent cron job started') + + MySQL.Async.fetchAll('SELECT owner, rent_price FROM rented_vehicles', {}, function(result) for i=1, #result, 1 do - local xPlayer = ESX.GetPlayerFromIdentifier(result[i].owner) + table.insert(tasks, function(cb) + local xPlayer = ESX.GetPlayerFromIdentifier(result[i].owner) - if xPlayer then -- message player if connected - xPlayer.removeAccountMoney('bank', result[i].rent_price) - xPlayer.showNotification(_U('paid_rental', ESX.Math.GroupDigits(result[i].rent_price))) - else -- pay rent by updating SQL - MySQL.Sync.execute('UPDATE users SET bank = bank - @bank WHERE identifier = @identifier', { - ['@bank'] = result[i].rent_price, - ['@identifier'] = result[i].owner - }) - end + if xPlayer then -- message player if connected + xPlayer.removeAccountMoney('bank', result[i].rent_price) + xPlayer.showNotification(_U('paid_rental', ESX.Math.GroupDigits(result[i].rent_price))) + else -- pay rent by updating SQL + MySQL.Sync.execute('UPDATE users SET bank = bank - @bank WHERE identifier = @identifier', { + ['@bank'] = result[i].rent_price, + ['@identifier'] = result[i].owner + }) + end - TriggerEvent('esx_addonaccount:getSharedAccount', 'society_cardealer', function(account) - account.addMoney(result[i].rent_price) + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_cardealer', function(account) + account.addMoney(result[i].rent_price) + end) + + cb() end) end + + Async.parallelLimit(tasks, 5, function(results) end) + + local elapsedTime = os.clock() - timeStart + print(('[esx_vehicleshop] [^2INFO^7] Paying rent cron job took %s seconds'):format(elapsedTime)) end) end From c5da295ed690c9376f50abb7614c6f598b1e123f Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 12 Feb 2020 11:35:07 +0100 Subject: [PATCH 2543/3224] Fixed #237 --- client/main.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/main.lua b/client/main.lua index 4814b249..2a41c15f 100644 --- a/client/main.lua +++ b/client/main.lua @@ -171,6 +171,12 @@ function OpenShopMenu() end end + for k,v in pairs(vehiclesByCategory) do + table.sort(v, function(a, b) + return a.name < b.name + end) + end + for i=1, #Categories, 1 do local category = Categories[i] local categoryVehicles = vehiclesByCategory[category.name] From 68712016ed029b392c64b616654fcebe7d97d2d2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 12 Feb 2020 12:04:00 +0100 Subject: [PATCH 2544/3224] Added failsafe default coords --- server/main.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 6e59e989..5face95b 100644 --- a/server/main.lua +++ b/server/main.lua @@ -164,7 +164,13 @@ AddEventHandler('es:playerLoaded', function(playerId, player) end end - userData.coords = json.decode(result[1].position) + if result[1].position and result[1].position ~= '' then + userData.coords = json.decode(result[1].position) + else + print('[es_extended] [^3WARNING^7] Column "position" in "users" 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 + cb2() end) From b2a46fdfb36fbbc5e5e579255422d0b75c8818fb Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 12 Feb 2020 12:06:05 +0100 Subject: [PATCH 2545/3224] Reverted new RegisterKeyMapping() native usage for now, its broken :/ --- client/main.lua | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/client/main.lua b/client/main.lua index 5365f53c..4905e97c 100644 --- a/client/main.lua +++ b/client/main.lua @@ -455,13 +455,17 @@ Citizen.CreateThread(function() end end) -RegisterCommand('showinventory', function() - if not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then - ESX.ShowInventory() - end -end, false) +Citizen.CreateThread(function() + while true do + Citizen.Wait(0) -RegisterKeyMapping('showinventory', _U('keymap_showinventory'), 'keyboard', 'F2') + if IsControlJustReleased(0, 289) then + if IsInputDisabled(0) and not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then + ESX.ShowInventory() + end + end + end +end) -- Disable wanted level if Config.DisableWantedLevel then From f236a67d63d2ec5979cff3d7ee12e7f3356b84e6 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 12 Feb 2020 12:33:14 +0100 Subject: [PATCH 2546/3224] Implemented json encoded inventory, closes #177 --- server/classes/player.lua | 16 +++++- server/functions.lua | 32 +++--------- server/main.lua | 104 +++++++++++++------------------------- 3 files changed, 58 insertions(+), 94 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 0f5bf295..d5035e09 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -129,8 +129,20 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c end end - self.getInventory = function() - return self.inventory + self.getInventory = function(minimal) + if minimal then + local items = {} + + for k,v in ipairs(self.inventory) do + if v.count > 0 then + items[v.name] = v.count + end + end + + return items + else + return self.inventory + end end self.getJob = function() diff --git a/server/functions.lua b/server/functions.lua index b9cc7b87..83c2debc 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -56,31 +56,15 @@ ESX.SavePlayer = function(xPlayer, cb) end end - -- Inventory items - for k,v in ipairs(xPlayer.inventory) do - if ESX.LastPlayerData[xPlayer.source].items[v.name] ~= v.count then - table.insert(asyncTasks, function(cb) - MySQL.Async.execute('UPDATE user_inventory SET count = @count WHERE identifier = @identifier AND item = @item', { - ['@count'] = v.count, - ['@identifier'] = xPlayer.identifier, - ['@item'] = v.name - }, function(rowsChanged) - cb() - end) - end) - - ESX.LastPlayerData[xPlayer.source].items[v.name] = v.count - end - end - - -- Job, loadout and position + -- Job, loadout, inventory and position table.insert(asyncTasks, function(cb) - MySQL.Async.execute('UPDATE users SET job = @job, job_grade = @job_grade, loadout = @loadout, position = @position WHERE identifier = @identifier', { - ['@job'] = xPlayer.job.name, - ['@job_grade'] = xPlayer.job.grade, - ['@loadout'] = json.encode(xPlayer.getLoadout()), - ['@position'] = json.encode(xPlayer.getCoords()), - ['@identifier'] = xPlayer.identifier + MySQL.Async.execute('UPDATE users SET job = @job, job_grade = @job_grade, loadout = @loadout, position = @position, inventory = @inventory WHERE identifier = @identifier', { + ['@job'] = xPlayer.job.name, + ['@job_grade'] = xPlayer.job.grade, + ['@loadout'] = json.encode(xPlayer.getLoadout()), + ['@position'] = json.encode(xPlayer.getCoords()), + ['@identifier'] = xPlayer.identifier, + ['@inventory'] = json.encode(xPlayer.getInventory(true)) }, function(rowsChanged) cb() end) diff --git a/server/main.lua b/server/main.lua index 5face95b..d079ded5 100644 --- a/server/main.lua +++ b/server/main.lua @@ -30,72 +30,6 @@ AddEventHandler('es:playerLoaded', function(playerId, player) end) end) - -- Get inventory - table.insert(tasks, function(cb) - MySQL.Async.fetchAll('SELECT item, count FROM user_inventory WHERE identifier = @identifier', { - ['@identifier'] = player.getIdentifier() - }, function(inventory) - local tasks2, foundItems = {}, {} - - for k,v in ipairs(inventory) do - local item = ESX.Items[v.item] - - if item then - foundItems[v.item] = true - - table.insert(userData.inventory, { - name = v.item, - count = v.count, - label = item.label, - weight = item.weight, - usable = ESX.UsableItemsCallbacks[v.item] ~= nil, - rare = item.rare, - canRemove = item.canRemove - }) - else - print(('[es_extended] [^3WARNING^7] Ignoring invalid item "%s" for "%s"'):format(v.item, player.getIdentifier())) - end - end - - for name,item in pairs(ESX.Items) do - if not foundItems[name] then - table.insert(userData.inventory, { - name = name, - count = 0, - label = item.label, - weight = item.weight, - usable = ESX.UsableItemsCallbacks[name] ~= nil, - rare = item.rare, - canRemove = item.canRemove - }) - - local scope = function(item, identifier) - table.insert(tasks2, function(cb2) - MySQL.Async.execute('INSERT INTO user_inventory (identifier, item, count) VALUES (@identifier, @item, @count)', { - ['@identifier'] = identifier, - ['@item'] = item, - ['@count'] = 0 - }, function(rowsChanged) - cb2() - end) - end) - end - - scope(name, player.getIdentifier()) - end - end - - Async.parallelLimit(tasks2, 5, function(results) end) - - table.sort(userData.inventory, function(a,b) - return a.label < b.label - end) - - cb() - end) - - end) - -- Get job and loadout table.insert(tasks, function(cb) @@ -104,7 +38,7 @@ AddEventHandler('es:playerLoaded', function(playerId, player) -- Get job name, grade and coords table.insert(tasks2, function(cb2) - MySQL.Async.fetchAll('SELECT job, job_grade, loadout, position FROM users WHERE identifier = @identifier', { + MySQL.Async.fetchAll('SELECT job, job_grade, loadout, position, inventory FROM users WHERE identifier = @identifier', { ['@identifier'] = player.getIdentifier() }, function(result) local job, grade = result[1].job, tostring(result[1].job_grade) @@ -154,10 +88,44 @@ AddEventHandler('es:playerLoaded', function(playerId, player) userData.job.skin_female = {} end + local foundItems = {} + + 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(('[es_extended] [^3WARNING^7] Ignoring invalid item "%s" for "%s"'):format(name, player.getIdentifier())) + end + end + end + + for name,item in pairs(ESX.Items) do + local count = foundItems[name] or 0 + + 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) + if result[1].loadout then userData.loadout = json.decode(result[1].loadout) - -- Compatibility with old loadouts prior to components update + -- compatibility with old loadouts for k,v in ipairs(userData.loadout) do if not v.components then v.components = {} end if not v.tintIndex then v.tintIndex = 0 end From d2bf5cc73be348bb485a189db4963a16ccae3402 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 12 Feb 2020 12:36:02 +0100 Subject: [PATCH 2547/3224] Updated sql file --- es_extended.sql | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/es_extended.sql b/es_extended.sql index 253af3b9..dce1fe4d 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -5,7 +5,8 @@ ALTER TABLE `users` ADD COLUMN `job` VARCHAR(50) NULL DEFAULT 'unemployed' AFTER `skin`, ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, - ADD COLUMN `position` VARCHAR(53) NULL DEFAULT '{"x":-269.4,"y":-955.3,"z":31.2,"heading":205.8}' AFTER `loadout` + ADD COLUMN `inventory` LONGTEXT NULL AFTER `loadout`, + ADD COLUMN `position` VARCHAR(53) NULL DEFAULT '{"x":-269.4,"y":-955.3,"z":31.2,"heading":205.8}' AFTER `inventory` ; CREATE TABLE `items` ( @@ -50,12 +51,3 @@ CREATE TABLE `user_accounts` ( PRIMARY KEY (`id`) ); - -CREATE TABLE `user_inventory` ( - `id` INT(11) NOT NULL AUTO_INCREMENT, - `identifier` VARCHAR(22) NOT NULL, - `item` VARCHAR(50) NOT NULL, - `count` INT(11) NOT NULL, - - PRIMARY KEY (`id`) -); From e6c90ea30eb401798b21c9dcadebcf6c413345ee Mon Sep 17 00:00:00 2001 From: Deliux Date: Wed, 12 Feb 2020 15:40:19 +0200 Subject: [PATCH 2548/3224] Xenon Color addition Could be used in esx_lscustoms, to change colors of xenons --- client/functions.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/functions.lua b/client/functions.lua index f15797ed..8cff77c4 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -676,6 +676,7 @@ ESX.Game.GetVehicleProperties = function(vehicle) wheels = GetVehicleWheelType(vehicle), windowTint = GetVehicleWindowTint(vehicle), + xenonColor = GetVehicleXenonLightsColour(vehicle), neonEnabled = { IsVehicleNeonLightEnabled(vehicle, 0), @@ -780,6 +781,7 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) end if props.neonColor then SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) end + if props.xenonColor then SetVehicleXenonLightsColour(vehicle, props.xenonColor) end if props.modSmokeEnabled then ToggleVehicleMod(vehicle, 20, true) end if props.tyreSmokeColor then SetVehicleTyreSmokeColor(vehicle, props.tyreSmokeColor[1], props.tyreSmokeColor[2], props.tyreSmokeColor[3]) end if props.modSpoilers then SetVehicleMod(vehicle, 0, props.modSpoilers, false) end From e8e3eaa4d1c84f5833d92e16878224f8a3fb865f Mon Sep 17 00:00:00 2001 From: Alex Garcio Date: Thu, 13 Feb 2020 16:44:14 -0500 Subject: [PATCH 2549/3224] Added ability to find an invisible dead player https://github.com/ESX-Org/esx_ambulancejob/issues/20 --- client/job.lua | 7 +++++-- client/main.lua | 37 ++++++++++++++++++++++++++++++++++++- locales/br.lua | 1 + locales/cs.lua | 1 + locales/en.lua | 1 + locales/es.lua | 1 + locales/fi.lua | 1 + locales/fr.lua | 1 + locales/pl.lua | 1 + locales/sv.lua | 1 + server/main.lua | 5 +++++ 11 files changed, 54 insertions(+), 3 deletions(-) diff --git a/client/job.lua b/client/job.lua index 6802391e..c2d977f2 100644 --- a/client/job.lua +++ b/client/job.lua @@ -46,13 +46,16 @@ function OpenMobileAmbulanceActionsMenu() {label = _U('ems_menu_revive'), value = 'revive'}, {label = _U('ems_menu_small'), value = 'small'}, {label = _U('ems_menu_big'), value = 'big'}, - {label = _U('ems_menu_putincar'), value = 'put_in_vehicle'} + {label = _U('ems_menu_putincar'), value = 'put_in_vehicle'}, + {label = _U('ems_menu_search'), value = 'search'} }}, function(data, menu) if isBusy then return end local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if closestPlayer == -1 or closestDistance > 1.0 then + if data.current.value == 'search' then + TriggerServerEvent('esx_ambulancejob:svsearch') + elseif closestPlayer == -1 or closestDistance > 1.0 then ESX.ShowNotification(_U('no_players')) else if data.current.value == 'revive' then diff --git a/client/main.lua b/client/main.lua index 3b8dcdae..3746ee40 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,6 +1,6 @@ local firstSpawn, PlayerLoaded = true, false -isDead = false +isDead, isSearched, medic = false, false, 0 ESX = nil Citizen.CreateThread(function() @@ -81,6 +81,41 @@ Citizen.CreateThread(function() end end) +Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + if isDead and isSearched then + local playerPed = PlayerPedId() + local ped = GetPlayerPed(GetPlayerFromServerId(medic)) + isSearched = false + + AttachEntityToEntity(playerPed, ped, 11816, 0.54, 0.54, 0.0, 0.0, 0.0, 0.0, false, false, false, false, 2, true) + Citizen.Wait(1000) + DetachEntity(playerPed, true, false) + ClearPedTasksImmediately(playerPed) + end + end +end) + +RegisterNetEvent('esx_ambulancejob:clsearch') +AddEventHandler('esx_ambulancejob:clsearch', function(medicId) + local playerPed = PlayerPedId() + + if isDead then + local coords = GetEntityCoords(playerPed) + local playersInArea = ESX.Game.GetPlayersInArea(coords, 50.0) + + for i=1, #playersInArea, 1 do + local player = playersInArea[i] + if player == GetPlayerFromServerId(medicId) then + medic = tonumber(medicId) + isSearched = true + break + end + end + end +end) + function OnPlayerDeath() isDead = true ESX.UI.Menu.CloseAll() diff --git a/locales/br.lua b/locales/br.lua index 9e3147d0..dead693d 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -60,6 +60,7 @@ Locales['br'] = { ['ems_menu_putincar'] = 'colocar no veiculo', ['ems_menu_small'] = 'curar pequenas feridas', ['ems_menu_big'] = 'tratando lesões graves', + ['ems_menu_search'] = 'paciente não encontrado', -- Phone ['alert_ambulance'] = 'alerta socorrista', -- Death diff --git a/locales/cs.lua b/locales/cs.lua index 37d65c5a..dfc9a125 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -60,6 +60,7 @@ Locales['cs'] = { ['ems_menu_putincar'] = 'naložit do vozidla', ['ems_menu_small'] = 'ošetřit malé zranění', ['ems_menu_big'] = 'ošetřit vážné zranění', + ['ems_menu_search'] = 'pacient nebyl nalezen', -- Phone ['alert_ambulance'] = 'zdravotnický poplach', -- Death diff --git a/locales/en.lua b/locales/en.lua index 5b5f6d24..d00b4ab4 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -60,6 +60,7 @@ Locales['en'] = { ['ems_menu_putincar'] = 'put in Vehicle', ['ems_menu_small'] = 'heal small wounds', ['ems_menu_big'] = 'treat serious injuries', + ['ems_menu_search'] = 'patient not found', -- Phone ['alert_ambulance'] = 'alert Ambulance', -- Death diff --git a/locales/es.lua b/locales/es.lua index e231db54..afd81dac 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -60,6 +60,7 @@ Locales['es'] = { ['ems_menu_putincar'] = 'meter en el vehículo', ['ems_menu_small'] = 'heal small wounds', ['ems_menu_big'] = 'treat serious injuries', + ['ems_menu_search'] = 'Paciente no encontrado', -- Phone ['alert_ambulance'] = 'Alerta de ambulancia', -- Death diff --git a/locales/fi.lua b/locales/fi.lua index 9ef6caf8..bc100b14 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -60,6 +60,7 @@ Locales['fi'] = { ['ems_menu_putincar'] = 'Laita ajoneuvoon', ['ems_menu_small'] = 'hoida pieniä haavoja', ['ems_menu_big'] = 'hoida isoja haavoja', + ['ems_menu_search'] = 'potilasta ei löydy', -- Phone ['alert_ambulance'] = 'hälyytys Ensihoidolle', -- Death diff --git a/locales/fr.lua b/locales/fr.lua index fb750289..ce6c7e83 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -60,6 +60,7 @@ Locales['fr'] = { ['ems_menu_putincar'] = 'mettre dans véhicule', ['ems_menu_small'] = 'soigner petites blessures', ['ems_menu_big'] = 'soigner blessures graves', + ['ems_menu_search'] = 'patient introuvable', -- Phone ['alert_ambulance'] = 'alerte Ambulance', -- Death diff --git a/locales/pl.lua b/locales/pl.lua index ebf082c1..80b1378b 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -60,6 +60,7 @@ Locales['pl'] = { ['ems_menu_putincar'] = 'umieścić w pojeździe', ['ems_menu_small'] = 'ulecz małe rany', ['ems_menu_big'] = 'ulecz poważne obrażenia', + ['ems_menu_search'] = 'nie znaleziono pacjenta', -- Phone ['alert_ambulance'] = 'wezwij ambulans', -- Death diff --git a/locales/sv.lua b/locales/sv.lua index b0d736aa..71f4740e 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -60,6 +60,7 @@ Locales['sv'] = { ['ems_menu_putincar'] = 'sätt i fordon', ['ems_menu_small'] = 'behandla mindre skador', ['ems_menu_big'] = 'behandla svåra skador', + ['ems_menu_search'] = 'patienten hittades inte', -- Phone ['alert_ambulance'] = 'ambulanssamtal', -- Death diff --git a/server/main.lua b/server/main.lua index 4b24fb5e..eb92dfdc 100644 --- a/server/main.lua +++ b/server/main.lua @@ -35,6 +35,11 @@ AddEventHandler('esx:onPlayerDeath', function(data) TriggerClientEvent('esx_ambulancejob:setDeadPlayers', -1, deadPlayers) end) +RegisterServerEvent('esx_ambulancejob:svsearch') +AddEventHandler('esx_ambulancejob:svsearch', function() + TriggerClientEvent('esx_ambulancejob:clsearch', -1, source) +end) + RegisterNetEvent('esx_ambulancejob:onPlayerDistress') AddEventHandler('esx_ambulancejob:onPlayerDistress', function() if deadPlayers[source] then From bf52a544119bbe35cc824dfe65477510cc239d06 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sat, 15 Feb 2020 19:22:30 +0100 Subject: [PATCH 2550/3224] Minor cleanup --- client/main.lua | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/client/main.lua b/client/main.lua index 2a41c15f..28b00811 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,13 +1,6 @@ -local HasAlreadyEnteredMarker = false -local LastZone -local CurrentAction -local CurrentActionMsg = '' -local CurrentActionData = {} -local IsInShopMenu = false -local Categories = {} -local Vehicles = {} -local currentDisplayVehicle -local CurrentVehicleData +local HasAlreadyEnteredMarker, IsInShopMenu = false, false +local CurrentAction, CurrentActionMsg, LastZone, currentDisplayVehicle, CurrentVehicleData +local CurrentActionData, Vehicles, Categories = {}, {}, {} ESX = nil From 35a726685e81c7e74d13e05d6f9b8e4d5f9bea23 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 15:22:09 +0100 Subject: [PATCH 2551/3224] =?UTF-8?q?=E2=9A=A0=EF=B8=8F=E2=9A=A0=EF=B8=8FB?= =?UTF-8?q?REAKING=20COMMIT=E2=9A=A0=EF=B8=8F=E2=9A=A0=EF=B8=8F:=20Complet?= =?UTF-8?q?e=20ES=20ditch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/functions.lua | 14 -- client/main.lua | 38 ++-- config.lua | 11 +- es_extended.sql | 21 ++- fxmanifest.lua | 5 +- html/img/accounts/money.png | Bin 0 -> 662 bytes locales/br.lua | 9 +- locales/cs.lua | 9 +- locales/de.lua | 9 +- locales/en.lua | 9 +- locales/fi.lua | 9 +- locales/fr.lua | 9 +- locales/pl.lua | 11 +- locales/sv.lua | 19 +- server/classes/player.lua | 140 ++++++--------- server/commands.lua | 334 ++++++++++-------------------------- server/common.lua | 14 +- server/functions.lua | 113 +++++++++++- server/main.lua | 262 +++++++++++++--------------- 19 files changed, 439 insertions(+), 597 deletions(-) create mode 100644 html/img/accounts/money.png diff --git a/client/functions.lua b/client/functions.lua index f15797ed..d801c1b5 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -865,20 +865,6 @@ ESX.ShowInventory = function() local playerPed = PlayerPedId() local elements, currentWeight = {}, 0 - if ESX.PlayerData.money > 0 then - local formattedMoney = _U('locale_currency', ESX.Math.GroupDigits(ESX.PlayerData.money)) - - table.insert(elements, { - label = ('%s: %s'):format(_U('cash'), formattedMoney), - count = ESX.PlayerData.money, - type = 'item_money', - value = 'money', - usable = false, - rare = false, - canRemove = true - }) - end - for k,v in pairs(ESX.PlayerData.accounts) do if v.money > 0 then local formattedMoney = _U('locale_currency', ESX.Math.GroupDigits(v.money)) diff --git a/client/main.lua b/client/main.lua index 4905e97c..caccc586 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,40 +1,29 @@ local isLoadoutLoaded, isPaused, isDead, isFirstSpawn, pickups = false, false, false, true, {} RegisterNetEvent('esx:playerLoaded') -AddEventHandler('esx:playerLoaded', function(xPlayer) +AddEventHandler('esx:playerLoaded', function(playerData) ESX.PlayerLoaded = true - ESX.PlayerData = xPlayer + ESX.PlayerData = playerData if Config.EnableHud then - for k,v in ipairs(xPlayer.accounts) do + for k,v in ipairs(playerData.accounts) do local accountTpl = '
     {{money}}
    ' - ESX.UI.HUD.RegisterElement('account_' .. v.name, k - 1, 0, accountTpl, { - money = 0 - }) - - ESX.UI.HUD.UpdateElement('account_' .. v.name, { + ESX.UI.HUD.RegisterElement('account_' .. v.name, k, 0, accountTpl, { money = ESX.Math.GroupDigits(v.money) }) end local jobTpl = '
    {{job_label}} - {{grade_label}}
    ' - if xPlayer.job.grade_label == '' then + if playerData.job.grade_label == '' or playerData.job.grade_label == playerData.job.label then jobTpl = '
    {{job_label}}
    ' end - ESX.UI.HUD.RegisterElement('job', #xPlayer.accounts, 0, jobTpl, { - job_label = '', - grade_label = '' + ESX.UI.HUD.RegisterElement('job', #playerData.accounts, 0, jobTpl, { + job_label = playerData.job.label, + grade_label = playerData.job.grade_label }) - - ESX.UI.HUD.UpdateElement('job', { - job_label = xPlayer.job.label, - grade_label = xPlayer.job.grade_label - }) - else - TriggerEvent('es:setMoneyDisplay', 0.0) end end) @@ -44,6 +33,10 @@ AddEventHandler('esx:setMaxWeight', function(newMaxWeight) end) AddEventHandler('playerSpawned', function() + if isFirstSpawn then + TriggerServerEvent('esx:playerJoined') + end + while not ESX.PlayerLoaded do Citizen.Wait(10) end @@ -120,11 +113,6 @@ AddEventHandler('esx:setAccountMoney', function(account) end end) -RegisterNetEvent('es:activateMoney') -AddEventHandler('es:activateMoney', function(money) - ESX.PlayerData.money = money -end) - RegisterNetEvent('esx:addInventoryItem') AddEventHandler('esx:addInventoryItem', function(item, count, showNotification) for k,v in ipairs(ESX.PlayerData.inventory) do @@ -394,11 +382,9 @@ if Config.EnableHud then if IsPauseMenuActive() and not isPaused then isPaused = true - TriggerEvent('es:setMoneyDisplay', 0.0) ESX.UI.HUD.SetDisplay(0.0) elseif not IsPauseMenuActive() and isPaused then isPaused = false - TriggerEvent('es:setMoneyDisplay', 1.0) ESX.UI.HUD.SetDisplay(1.0) end end diff --git a/config.lua b/config.lua index d3bf0edb..be3e5171 100644 --- a/config.lua +++ b/config.lua @@ -1,8 +1,11 @@ -Config = {} -Config.Locale = 'fr' +Config = {} +Config.Locale = 'fr' -Config.Accounts = {'bank', 'black_money'} -Config.AccountLabels = {bank = _U('bank'), black_money = _U('black_money')} +Config.Accounts = { + bank = _U('account_bank'), + black_money = _U('account_black_money'), + money = _U('account_money') +} Config.EnableSocietyPayouts = false -- pay from the society account that the player is employed at? Requirement: esx_society Config.DisableWantedLevel = true diff --git a/es_extended.sql b/es_extended.sql index dce1fe4d..111cef1f 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -1,13 +1,16 @@ USE `essentialmode`; -ALTER TABLE `users` - ADD COLUMN `skin` LONGTEXT NULL, - ADD COLUMN `job` VARCHAR(50) NULL DEFAULT 'unemployed' AFTER `skin`, - ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, - ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, - ADD COLUMN `inventory` LONGTEXT NULL AFTER `loadout`, - ADD COLUMN `position` VARCHAR(53) NULL DEFAULT '{"x":-269.4,"y":-955.3,"z":31.2,"heading":205.8}' AFTER `inventory` -; +CREATE TABLE `users` ( + `identifier` VARCHAR(40) NOT NULL, + `group` VARCHAR(50) NULL DEFAULT 'user', + `job` VARCHAR(20) NULL DEFAULT 'unemployed', + `job_grade` INT(11) NULL DEFAULT 0, + `inventory` LONGTEXT NULL DEFAULT NULL, + `loadout` LONGTEXT NULL DEFAULT NULL, + `position` VARCHAR(53) NULL DEFAULT '{"x":-269.4,"y":-955.3,"z":31.2,"heading":205.8}', + + PRIMARY KEY (`identifier`) +); CREATE TABLE `items` ( `name` VARCHAR(50) NOT NULL, @@ -45,7 +48,7 @@ INSERT INTO `jobs` VALUES ('unemployed','Unemployed'); CREATE TABLE `user_accounts` ( `id` INT(11) NOT NULL AUTO_INCREMENT, - `identifier` VARCHAR(22) NOT NULL, + `identifier` VARCHAR(40) NOT NULL, `name` VARCHAR(50) NOT NULL, `money` INT(11) NOT NULL DEFAULT '0', diff --git a/fxmanifest.lua b/fxmanifest.lua index a4be3e72..f40e04a9 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -82,7 +82,8 @@ files { 'html/fonts/bankgothic.ttf', 'html/img/accounts/bank.png', - 'html/img/accounts/black_money.png' + 'html/img/accounts/black_money.png', + 'html/img/accounts/money.png', } exports { @@ -95,7 +96,5 @@ server_exports { dependencies { 'mysql-async', - 'essentialmode', - 'esplugin_mysql', 'async' } diff --git a/html/img/accounts/money.png b/html/img/accounts/money.png new file mode 100644 index 0000000000000000000000000000000000000000..e05c91b0bb0c4faaa5f7a756c8d755f79f16ef1b GIT binary patch literal 662 zcmV;H0%`q;P)X^iM1 zwrODs(MFhlOeu(NQ0k`3E;Jz*K^GS-(n(r$SyU$3qJ?eD zMP*mpn2qSn_kAq}bmn)YvwhF=@_y%VJ|R%M(p`JORs)2MydFE;JyWQAK|q{IAQ}hA zsyhM{0U8AUS5g$`?U^t?HoXv$CIFnf3%s=G2Ql8*L~|;W2a-vRHD=GMab2iXm9)0} zRdo#>4v9U^4yvOKm6E;rerq!GWmBG??mUXnR-`)j9C(kQSg8T_h|1_>OKQn;aJnw#49Ea}Z>7Q03CLP55lYp)h)ynn7D zS6Pu+NrmzJ;Y5uMX`O7DeLCUyXA6OBWqCZ{_|bE!t?IaJzi*t2jdY9)OanO)c3@?H z;Qo*$`xzffB@0Rx;H`nAI~(;KCr0F?*IS*07*qoM6N<$g3p&H&Hw-a literal 0 HcmV?d00001 diff --git a/locales/br.lua b/locales/br.lua index 86fb98d2..f8573d2d 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,6 +1,5 @@ Locales['br'] = { -- Inventory - ['cash'] = 'dinheiro', ['inventory'] = 'inventário %s / %s', ['use'] = 'usar', ['give'] = 'dar', @@ -23,8 +22,6 @@ Locales['br'] = { ['received_weapon_withammo'] = 'você recebeu ~b~%s~s~ com ~o~%sx %s~s~ de ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ tentou lhe dar uma ~y~%s~s~, mas você já tem um(a)', ['received_weapon_noweapon'] = '~b~%s~s~ tentou lhe dar munição para ~y~%s~s~, mas você não tem um(a)', - ['gave_money'] = 'voce deu ~g~$%s~s~ para ~y~%s~s~', - ['received_money'] = 'voce recebeu ~g~$%s~s~ de ~b~%s~s~', ['gave_account_money'] = 'voce deu ~g~$%s~s~ (%s) para ~y~%s~s~', ['received_account_money'] = 'voce recebeu ~g~$%s~s~ (%s) de ~b~%s~s~', ['amount_invalid'] = 'quantidade inválida', @@ -33,7 +30,6 @@ Locales['br'] = { ['imp_invalid_quantity'] = 'ação impossível, quantidade inválida', ['imp_invalid_amount'] = 'ação impossível, valor invalido', ['threw_standard'] = 'você jogou ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'você jogou ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'você jogou ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'você jogou ~b~%s~s~', ['threw_weapon_ammo'] = 'você jogou ~b~%s~s~ com ~o~%sx %s~s~', @@ -50,7 +46,9 @@ Locales['br'] = { ['company_nomoney'] = 'a empresa em que voce esta empregado esta muito pobre para pagar seu salário', ['received_paycheck'] = 'recebeu dinheiro', ['bank'] = 'banco', - ['black_money'] = 'dinheiro sujo', + ['account_bank'] = 'bank', + ['account_black_money'] = 'dirty Money', + ['account_money'] = 'cash', ['act_imp'] = 'ação impossível', ['in_vehicle'] = 'voce não pode dar nada para alguem no veículo', @@ -75,7 +73,6 @@ Locales['br'] = { ['chat_clear_all'] = 'limpar o chat para todos', ['command_clearinventory'] = 'remover todos os itens do inventário', ['command_clearloadout'] = 'remova todas as armas do carregamento', - ['command_playerid_param'] = 'especifique playerId ou deixe em branco para si mesmo', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/locales/cs.lua b/locales/cs.lua index 5c1283b8..de60f089 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -1,6 +1,5 @@ Locales['cs'] = { -- Inventory - ['cash'] = 'hotovost', ['inventory'] = 'inventář %s / %s', ['use'] = 'použít', ['give'] = 'dát', @@ -23,8 +22,6 @@ Locales['cs'] = { ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx %s~s~ from ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', - ['gave_money'] = 'dali jste ~g~$%s~s~ ~y~%s~s~', - ['received_money'] = 'obdrželi jste ~g~$%s~s~ od ~b~%s~s~', ['gave_account_money'] = 'dali jste ~g~$%s~s~ (%s) ~y~%s~s~', ['received_account_money'] = 'obdrželi jste ~g~$%s~s~ (%s) od ~b~%s~s~', ['amount_invalid'] = 'neplatné množství', @@ -33,7 +30,6 @@ Locales['cs'] = { ['imp_invalid_quantity'] = 'akce není možná, neplatný počet', ['imp_invalid_amount'] = 'akce není možná, neplatné množství', ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx %s~s~', @@ -51,7 +47,9 @@ Locales['cs'] = { ['company_nomoney'] = 'společnost u které jste zaměstananí nemá peníze na váš plat', ['received_paycheck'] = 'obdržena výplata', ['bank'] = 'bankovní účet', - ['black_money'] = 'špinavé peníze', + ['account_bank'] = 'bank', + ['account_black_money'] = 'dirty Money', + ['account_money'] = 'cash', ['act_imp'] = 'akce není možná', ['in_vehicle'] = 'nemůže nic dát osobě ve vozidle', @@ -76,7 +74,6 @@ Locales['cs'] = { ['chat_clear_all'] = 'vyčistit chat pro všechny', ['command_clearinventory'] = 'clear all items from inventory', ['command_clearloadout'] = 'remove all weapons from loadout', - ['command_playerid_param'] = 'specify playerId or leave blank for yourself', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/locales/de.lua b/locales/de.lua index 44f23ed0..61f77920 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -1,6 +1,5 @@ Locales['de'] = { -- Inventory - ['cash'] = 'bargeld', ['inventory'] = 'inventar %s / %s', ['use'] = 'benutzen', ['give'] = 'geben', @@ -23,8 +22,6 @@ Locales['de'] = { ['received_weapon_withammo'] = 'du erhälst ~b~%s~s~ mit ~o~%sx %s~s~ von ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ hat versucht dir eine(n) ~y~%s~s~ zu geben, aber du hast bereits eine(n)', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', - ['gave_money'] = 'du gibst ~g~$%s~s~ an ~y~%s~s~', - ['received_money'] = 'du erhälst ~g~$%s~s~ von ~b~%s~s~', ['gave_account_money'] = 'du gibst ~g~$%s~s~ (%s) an ~y~%s~s~', ['received_account_money'] = 'du empfängst ~g~$%s~s~ (%s) von ~b~%s~s~', ['amount_invalid'] = 'ungültiger Betrag', @@ -33,7 +30,6 @@ Locales['de'] = { ['imp_invalid_quantity'] = 'aktion nicht möglich, ungültige Anzahl', ['imp_invalid_amount'] = 'aktion nicht möglich, ungültiger Betrag', ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx %s~s~', @@ -50,7 +46,9 @@ Locales['de'] = { ['company_nomoney'] = 'die Firma in der du angestellt bist, ist zu arm um dein Gehalt zu zahlen', ['received_paycheck'] = 'erhaltener Gehaltsscheck', ['bank'] = 'bank', - ['black_money'] = 'schwarzgeld', + ['account_bank'] = 'bank', + ['account_black_money'] = 'dirty Money', + ['account_money'] = 'cash', ['act_imp'] = 'Aktion nicht möglich', ['in_vehicle'] = 'you can\'t give anything to someone in a vehicle', @@ -75,7 +73,6 @@ Locales['de'] = { ['chat_clear_all'] = 'clear the chat for everyone', ['command_clearinventory'] = 'clear all items from inventory', ['command_clearloadout'] = 'remove all weapons from loadout', - ['command_playerid_param'] = 'specify playerId or leave blank for yourself', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/locales/en.lua b/locales/en.lua index 73ad1b84..44c4c680 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,6 +1,5 @@ Locales['en'] = { -- Inventory - ['cash'] = 'cash', ['inventory'] = 'inventory %s / %s', ['use'] = 'use', ['give'] = 'give', @@ -23,8 +22,6 @@ Locales['en'] = { ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx %s~s~ from ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', - ['gave_money'] = 'you gave ~g~$%s~s~ to ~y~%s~s~', - ['received_money'] = 'you received ~g~$%s~s~ from ~b~%s~s~', ['gave_account_money'] = 'you gave ~g~$%s~s~ (%s) to ~y~%s~s~', ['received_account_money'] = 'you received ~g~$%s~s~ (%s) from ~b~%s~s~', ['amount_invalid'] = 'invalid amount', @@ -33,7 +30,6 @@ Locales['en'] = { ['imp_invalid_quantity'] = 'action impossible, invalid quantity', ['imp_invalid_amount'] = 'action impossible, invalid amount', ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx %s~s~', @@ -50,7 +46,9 @@ Locales['en'] = { ['company_nomoney'] = 'the company you\'re employeed at is too poor to pay out your salary', ['received_paycheck'] = 'received paycheck', ['bank'] = 'maze Bank', - ['black_money'] = 'dirty Money', + ['account_bank'] = 'bank', + ['account_black_money'] = 'dirty Money', + ['account_money'] = 'cash', ['act_imp'] = 'action impossible', ['in_vehicle'] = 'you can\'t give anything to someone in a vehicle', @@ -75,7 +73,6 @@ Locales['en'] = { ['chat_clear_all'] = 'clear the chat for everyone', ['command_clearinventory'] = 'clear all items from inventory', ['command_clearloadout'] = 'remove all weapons from loadout', - ['command_playerid_param'] = 'specify playerId or leave blank for yourself', -- Locale settings ['locale_digit_grouping_symbol'] = ',', diff --git a/locales/fi.lua b/locales/fi.lua index e996ad77..6e113511 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -1,6 +1,5 @@ Locales['fi'] = { -- Inventory - ['cash'] = 'käteinen', ['inventory'] = 'reppu %s / %s', ['use'] = 'käytä', ['give'] = 'anna', @@ -23,8 +22,6 @@ Locales['fi'] = { ['received_weapon_withammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx %s~s~ from ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', - ['gave_money'] = 'sinä annoit ~g~$%s~s~ henkilölle ~y~%s~s~', - ['received_money'] = 'sinä sait ~g~$%s~s~ henkilöltä ~b~%s~s~', ['gave_account_money'] = 'sinä annoit ~g~$%s~s~ (%s) henkilölle ~y~%s~s~', ['received_account_money'] = 'sinä sait ~g~$%s~s~ (%s) henkilöltä ~b~%s~s~', ['amount_invalid'] = 'virheellinen määrä', @@ -33,7 +30,6 @@ Locales['fi'] = { ['imp_invalid_quantity'] = 'toiminto mahdoton, virheellinen määrä', ['imp_invalid_amount'] = 'toiminto mahdoton, virhellinen summa', ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx %s~s~', @@ -50,7 +46,9 @@ Locales['fi'] = { ['company_nomoney'] = 'yritys jolle teet töitä on köyhä eikä voi maksaa palkkaasi', ['received_paycheck'] = 'sait palkan', ['bank'] = 'pankki', - ['black_money'] = 'likainen Raha', + ['account_bank'] = 'bank', + ['account_black_money'] = 'dirty Money', + ['account_money'] = 'cash', ['act_imp'] = 'toiminto mahdoton', ['in_vehicle'] = 'et voi antaa ajoneuvossa olevalle mitään', @@ -75,7 +73,6 @@ Locales['fi'] = { ['chat_clear_all'] = 'tyhjennä chatti kaikilta', ['command_clearinventory'] = 'clear all items from inventory', ['command_clearloadout'] = 'remove all weapons from loadout', - ['command_playerid_param'] = 'specify playerId or leave blank for yourself', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/locales/fr.lua b/locales/fr.lua index 3483566a..0295f845 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,6 +1,5 @@ Locales['fr'] = { -- Inventory - ['cash'] = 'espèces', ['inventory'] = 'inventaire %s / %s', ['use'] = 'utiliser', ['give'] = 'donner', @@ -23,8 +22,6 @@ Locales['fr'] = { ['received_weapon_withammo'] = 'vous avez reçu ~y~1x~s~ ~b~%s~s~ avec ~o~%sx %s~s~ de ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ a tenté de vous donner ~y~%s~s~, mais vous en aviez déjà un exemplaire', ['received_weapon_noweapon'] = '~b~%s~s~ tente de vous donner des munitions pour ~y~%s~s~, mais vous n\'en avez pas', - ['gave_money'] = 'vous avez donné ~g~$%s~s~ à ~y~%s~s~', - ['received_money'] = 'vous avez reçu ~g~$%s~s~ par ~b~%s~s~', ['gave_account_money'] = 'vous avez donné ~g~$%s~s~ (%s) à ~y~%s~s~', ['received_account_money'] = 'vous avez reçu ~g~$%s~s~ (%s) par ~b~%s~s~', ['amount_invalid'] = 'montant invalide', @@ -33,7 +30,6 @@ Locales['fr'] = { ['imp_invalid_quantity'] = 'action impossible, ~r~quantité invalide', ['imp_invalid_amount'] = 'action impossible, ~r~montant invalide', ['threw_standard'] = 'vous avez jeté ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'vous avez jeté ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'vous avez jeté ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~', ['threw_weapon_ammo'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~ avec ~o~%sx %s~s~', @@ -50,7 +46,9 @@ Locales['fr'] = { ['company_nomoney'] = 'votre entreprise n\'a plus d\'argent pour vous payer!', ['received_paycheck'] = 'paiement reçu', ['bank'] = 'banque', - ['black_money'] = 'argent sale', + ['account_bank'] = 'bank', + ['account_black_money'] = 'dirty Money', + ['account_money'] = 'cash', ['act_imp'] = 'action impossible', ['in_vehicle'] = 'Vous ne pouvez rien donner à quelqu\'un dans un véhicule', @@ -75,7 +73,6 @@ Locales['fr'] = { ['chat_clear_all'] = 'vider le chat pour tous le monde', ['command_clearinventory'] = 'effacer tout les items de l\'inventaire', ['command_clearloadout'] = 'retirer toutes les armes de l\'équipement', - ['command_playerid_param'] = 'spécifiez un playerid ou laissez vide pour vous-même', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/locales/pl.lua b/locales/pl.lua index 4cdfe07e..a691437a 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -1,6 +1,5 @@ Locales['pl'] = { -- Inventory - ['cash'] = 'gotówka', ['inventory'] = 'ekwipunek %s / %s', ['use'] = 'użyj', ['give'] = 'daj', @@ -23,8 +22,6 @@ Locales['pl'] = { ['received_weapon_withammo'] = 'otrzymałeś/aś ~b~%s~s~ z ~o~%sx %s~s~ od ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ próbował/a przekazać ci ~y~%s~s~, lecz już posiadasz jedno', ['received_weapon_noweapon'] = '~b~%s~s~ próbował/a przekazać ci amunicje do ~y~%s~s~, lecz nie posiadasz tej broni', - ['gave_money'] = 'dajesz ~g~%s$~s~ dla ~y~%s~s~', - ['received_money'] = 'otrzymujesz ~g~%s$~s~ od ~b~%s~s~', ['gave_account_money'] = 'dajesz ~g~%s$~s~ (%s) dla ~y~%s~s~', ['received_account_money'] = 'otrzymujesz ~g~%s$~s~ (%s) od ~b~%s~s~', ['amount_invalid'] = 'nieprawidłowa ilość', @@ -33,7 +30,6 @@ Locales['pl'] = { ['imp_invalid_quantity'] = 'akcja jest niemożliwa, nieprawidłowa ilość', ['imp_invalid_amount'] = 'akcja jest niemożliwa, nieprawidłowa kwota', ['threw_standard'] = 'wyrzuciłeś/aś ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'wyrzuciłeś/aś ~g~$%s~s~ ~b~gotówki~s~', ['threw_account'] = 'wyrzuciłeś/aś ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'wyrzuciłeś/aś ~b~%s~s~', ['threw_weapon_ammo'] = 'wyrzuciłeś/aś ~b~%s~s~ z ~o~%sx %s~s~', @@ -44,14 +40,16 @@ Locales['pl'] = { -- Key mapping ['keymap_showinventory'] = 'show Inventory', - -- Salary related ['received_salary'] = 'otrzymałeś wynagrodzenie: ~g~%s$~s~', ['received_help'] = 'otrzymałem zapomogę: ~g~$%s~s~', ['company_nomoney'] = 'firma, w której pracujesz, jest zbyt biedna, by wypłacić twoją pensję', ['received_paycheck'] = 'otrzymana wypłata', ['bank'] = 'bank', - ['black_money'] = 'brudne pieniądze', + ['account_bank'] = 'bank', + ['account_black_money'] = 'dirty Money', + ['account_money'] = 'cash', + ['act_imp'] = 'działanie niemożliwe', ['in_vehicle'] = 'nie możesz przekazywać przedmiotów w pojeździe', @@ -75,7 +73,6 @@ Locales['pl'] = { ['chat_clear_all'] = 'wyczyść czat dla wszystkich', ['command_clearinventory'] = 'usuń wszystkie przedmioty z ekwipunku', ['command_clearloadout'] = 'usuń wszystkie bronie z wyposażenia', - ['command_playerid_param'] = 'id gracza lub zostaw puste dla siebie', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/locales/sv.lua b/locales/sv.lua index 1f23cbc4..8be097c6 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -1,6 +1,5 @@ Locales['sv'] = { -- Inventory - ['cash'] = 'kontanter', ['inventory'] = 'mitt förråd %s / %s', ['use'] = 'använd', ['give'] = 'ge', @@ -23,8 +22,6 @@ Locales['sv'] = { ['received_weapon_withammo'] = 'du tog emot ~b~%s~s~ med ~o~%sx %s~s~ från ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ försökte ge dig en ~y~%s~s~, men det vapnet har du redan', ['received_weapon_noweapon'] = '~b~%s~s~ försökte ge dig ammunition för ett ~y~%s~s~, men du har inget sådant vapen', - ['gave_money'] = 'du gav ~g~%s SEK~s~ till ~y~%s~s~', - ['received_money'] = 'du tog emot ~g~%s SEK~s~ från ~b~%s~s~', ['gave_account_money'] = 'du gav ~g~%s SEK~s~ (%s) till ~y~%s~s~', ['received_account_money'] = 'du tog emot ~g~%s SEK~s~ (%s) från ~b~%s~s~', ['amount_invalid'] = 'ogiltig mängd', @@ -33,7 +30,6 @@ Locales['sv'] = { ['imp_invalid_quantity'] = 'åtgärd omöjlig, ogiltig mängd', ['imp_invalid_amount'] = 'åtgärd omöjlig, ogiltig belopp', ['threw_standard'] = 'du kastade ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'du kastade ~g~%s SEK~s~ ~b~kontanter~s~', ['threw_account'] = 'du kastade ~g~%s SEK~s~ ~b~%s~s~', ['threw_weapon'] = 'du kastade ~b~%s~s~', ['threw_weapon_ammo'] = 'du kastade ~b~%s~s~ med ~o~%sx %s~s~', @@ -50,7 +46,9 @@ Locales['sv'] = { ['company_nomoney'] = 'företaget du är anställt hos har inte råd att betala ut din lön', ['received_paycheck'] = 'mottagit lön', ['bank'] = 'bank', - ['black_money'] = 'svarta pengar', + ['account_bank'] = 'bank', + ['account_black_money'] = 'svarta pengar', + ['account_money'] = 'kontakter', ['act_imp'] = 'åtgärd omöjlig', ['in_vehicle'] = 'du kan inte ge saker till en som sitter i ett fordon!', @@ -59,7 +57,7 @@ Locales['sv'] = { ['setjob'] = 'tilldela ett jobb till en spelare', ['id_param'] = 'spelarens ID', ['setjob_param2'] = 'det jobb du vill tilldela', - ['setjob_param3'] = 'job level', + ['setjob_param3'] = 'job nivå', ['spawn_car'] = 'spawna ett fordon', ['spawn_car_param'] = 'namn på fordon', ['delete_vehicle'] = 'ta bort fordon', @@ -68,14 +66,13 @@ Locales['sv'] = { ['giveaccountmoney'] = 'ge spelarkonto pengar', ['invalid_item'] = 'ogiltigt föremål', ['item'] = 'föremål', - ['giveitem'] = 'ge föremål', + ['giveitem'] = 'ge ett föremål', ['weapon'] = 'vapen', - ['giveweapon'] = 'ge vapen', + ['giveweapon'] = 'ge ett vapen', ['chat_clear'] = 'töm chatten', ['chat_clear_all'] = 'töm chatten för alla', - ['command_clearinventory'] = 'clear all items from inventory', - ['command_clearloadout'] = 'remove all weapons from loadout', - ['command_playerid_param'] = 'specify playerId or leave blank for yourself', + ['command_clearinventory'] = 'töm en spelares inventory', + ['command_clearloadout'] = 'töm en spelares loadout', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/server/classes/player.lua b/server/classes/player.lua index d5035e09..4a41d30b 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -1,41 +1,32 @@ -function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, coords) +function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, job, loadout, name, coords) local self = {} - self.player = player - self.accounts = accounts + self.accounts = accounts self.inventory = inventory - self.job = job - self.loadout = loadout - self.name = name + self.job = job + self.group = group + self.loadout = loadout + self.name = name self.maxWeight = Config.MaxWeight - self.coords = coords + self.coords = coords + self.variables = {} + self.source = playerId + self.playerId = playerId + self.identifier = identifier - self.source = self.player.get('source') - self.identifier = self.player.get('identifier') + ExecuteCommand(('add_principal identifier.license:%s group.%s'):format(self.identifier, self.group)) self.triggerEvent = function(eventName, ...) TriggerClientEvent(eventName, self.source, ...) end - self.setMoney = function(money) - money = ESX.Math.Round(money) - - if money >= 0 then - self.player.setMoney(money) - end - end - - self.getMoney = function() - return self.player.get('money') - end - self.setCoords = function(coords) self.updateCoords(coords) self.triggerEvent('esx:teleport', coords) end self.updateCoords = function(coords) - self.coords = {x = ESX.Math.Round(coords.x, 1), y = ESX.Math.Round(coords.y, 1), z = ESX.Math.Round(coords.z, 1), heading = ESX.Math.Round(coords.heading, 1)} + self.coords = {x = ESX.Math.Round(coords.x, 1), y = ESX.Math.Round(coords.y, 1), z = ESX.Math.Round(coords.z, 1), heading = ESX.Math.Round(coords.heading or 0.0, 1)} end self.getCoords = function(vector) @@ -50,78 +41,52 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c DropPlayer(self.source, reason) end + self.setMoney = function(money) + money = ESX.Math.Round(money) + self.setAccountMoney('money', money) + end + + self.getMoney = function() + return self.getAccount('money').money + end + self.addMoney = function(money) money = ESX.Math.Round(money) - - if money >= 0 then - self.player.addMoney(money) - end + self.addAccountMoney('money', money) end self.removeMoney = function(money) money = ESX.Math.Round(money) - - if money > 0 then - self.player.removeMoney(money) - end - end - - self.displayMoney = function(money) - self.player.displayMoney(money) + self.removeAccountMoney('money', money) end self.getIdentifier = function() - return self.player.getIdentifier() + return self.identifier + end + + self.setGroup = function(newGroup) + ExecuteCommand(('remove_principal identifier.license:%s group.%s'):format(self.identifier, self.group)) + self.group = newGroup + ExecuteCommand(('add_principal identifier.license:%s group.%s'):format(self.identifier, self.group)) end self.getGroup = function() - return self.player.getGroup() + return self.group end self.set = function(k, v) - self.player.set(k, v) + self.variables[k] = v end self.get = function(k) - return self.player.get(k) - end - - self.getPlayer = function() - return self.player + return self.variables[k] end self.getAccounts = function() - local accounts = {} - - for k,account in ipairs(Config.Accounts) do - if account == 'bank' then - table.insert(accounts, { - name = 'bank', - money = self.get('bank'), - label = Config.AccountLabels.bank - }) - else - for k2,v2 in ipairs(self.accounts) do - if v2.name == account then - table.insert(accounts, v2) - break - end - end - end - end - - return accounts + return self.accounts end self.getAccount = function(account) - if account == 'bank' then - return { - name = 'bank', - money = self.get('bank'), - label = Config.AccountLabels.bank - } - end - for k,v in ipairs(self.accounts) do if v.name == account then return v @@ -162,36 +127,29 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c end self.getMissingAccounts = function(cb) - MySQL.Async.fetchAll('SELECT name FROM user_accounts WHERE identifier = @identifier', { - ['@identifier'] = self.getIdentifier() - }, function(result) - local missingAccounts = {} + local missingAccounts = {} - for k,v in ipairs(Config.Accounts) do - if v ~= 'bank' then - local found = false + for account,label in pairs(Config.Accounts) do + local found = false - for k2,v2 in ipairs(result) do - if v == v2.name then - found = true - break - end - end - - if not found then - table.insert(missingAccounts, v) - end + for k2,v2 in ipairs(self.accounts) do + if account == v2.name then + found = true end end - cb(missingAccounts) - end) + if not found then + table.insert(missingAccounts, account) + end + end + + cb(missingAccounts) end - self.createAccounts = function(missingAccounts, cb) + self.createMissingAccounts = function(missingAccounts, cb) for k,v in ipairs(missingAccounts) do MySQL.Async.execute('INSERT INTO user_accounts (identifier, name) VALUES (@identifier, @name)', { - ['@identifier'] = self.getIdentifier(), + ['@identifier'] = self.identifier, ['@name'] = v }, function(rowsChanged) if cb then diff --git a/server/commands.lua b/server/commands.lua index dea5e1ee..23892beb 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -1,259 +1,111 @@ -TriggerEvent('es:addGroupCommand', 'tp', 'admin', function(source, args, user) - local x = tonumber(args[1]) - local y = tonumber(args[2]) - local z = tonumber(args[3]) - - if x and y and z then - TriggerClientEvent('esx:teleport', source, { - x = x, - y = y, - z = z - }) - else - TriggerClientEvent('chatMessage', source, 'SYSTEM', {255, 0, 0}, 'Invalid coordinates!') - end -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = 'Teleport to coordinates', params = { - {name = 'x', help = 'X coords'}, - {name = 'y', help = 'Y coords'}, - {name = 'z', help = 'Z coords'} +ESX.RegisterCommand('setcoords', 'admin', function(xPlayer, args, showError) + xPlayer.setCoords({x = args.x, y = args.y, z = args.z}) +end, false, {help = 'Teleport to coordinates', validate = true, arguments = { + {name = 'x', help = 'X coords', type = 'number'}, + {name = 'y', help = 'Y coords', type = 'number'}, + {name = 'z', help = 'Z coords', type = 'number'} }}) -TriggerEvent('es:addGroupCommand', 'setjob', 'admin', function(source, args, user) - if tonumber(args[1]) and args[2] and tonumber(args[3]) then - local xPlayer = ESX.GetPlayerFromId(args[1]) +ESX.RegisterCommand('setjob', 'admin', function(xPlayer, args, showError) + if ESX.DoesJobExist(args.job, args.grade) then + args.playerId.setJob(args.job, args.grade) + else + showError('That job does not exist') + end +end, true, {help = _U('setjob'), validate = true, arguments = { + {name = 'playerId', help = _U('id_param'), type = 'player'}, + {name = 'job', help = _U('setjob_param2'), type = 'string'}, + {name = 'grade', help = _U('setjob_param3'), type = 'number'} +}}) - if xPlayer then - if ESX.DoesJobExist(args[2], args[3]) then - xPlayer.setJob(args[2], args[3]) +ESX.RegisterCommand('car', 'admin', function(xPlayer, args, showError) + xPlayer.triggerEvent('esx:spawnVehicle', args.car) +end, false, {help = _U('spawn_car'), validate = false, arguments = { + {name = 'car', help = _U('spawn_car_param'), type = 'any'} +}}) + +ESX.RegisterCommand({'cardel', 'dv'}, 'admin', function(xPlayer, args, showError) + xPlayer.triggerEvent('esx:deleteVehicle', args.radius) +end, false, {help = _U('spawn_car'), validate = false, arguments = { + {name = 'radius', help = 'Optional, delete every vehicle within the specified radius', type = 'any'} +}}) + +ESX.RegisterCommand('giveaccountmoney', 'admin', function(xPlayer, args, showError) + if args.playerId.getAccount(args.account) then + args.playerId.addAccountMoney(args.account, args.amount) + else + showError(_U('invalid_account')) + end +end, true, {help = _U('giveaccountmoney'), validate = true, arguments = { + {name = 'playerId', help = _U('id_param'), type = 'player'}, + {name = 'account', help = _U('account'), type = 'string'}, + {name = 'amount', help = _U('money_amount'), type = 'number'} +}}) + +ESX.RegisterCommand('giveitem', 'admin', function(xPlayer, args, showError) + args.playerId.addInventoryItem(args.item, args.count) +end, true, {help = _U('giveitem'), validate = true, arguments = { + {name = 'playerId', help = _U('id_param'), type = 'player'}, + {name = 'item', help = _U('item'), type = 'item'}, + {name = 'count', help = _U('amount'), type = 'number'} +}}) + +ESX.RegisterCommand('giveweapon', 'admin', function(xPlayer, args, showError) + if args.playerId.hasWeapon(args.weapon) then + showError('Player already has that weapon') + else + xPlayer.addWeapon(args.weapon, args.ammo) + end +end, true, {help = _U('giveweapon'), validate = true, arguments = { + {name = 'playerId', help = _U('id_param'), type = 'player'}, + {name = 'weapon', help = _U('weapon'), type = 'weapon'}, + {name = 'ammo', help = _U('amountammo'), type = 'number'} +}}) + +ESX.RegisterCommand('giveweaponcomponent', 'admin', function(xPlayer, args, showError) + if args.playerId.hasWeapon(args.weaponName) then + local component = ESX.GetWeaponComponent(args.weaponName, args.componentName) + + if component then + if xPlayer.hasWeaponComponent(args.weaponName, args.componentName) then + showError('Player already has that weapon component') else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'That job does not exist.' } }) + xPlayer.addWeaponComponent(args.weaponName, args.componentName) end else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) + showError('Invalid weapon component') end else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid usage.' } }) + showError('Player does not have that weapon') end -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('setjob'), params = { - {name = 'playerId', help = _U('id_param')}, - {name = 'job', help = _U('setjob_param2')}, - {name = 'grade_id', help = _U('setjob_param3')} +end, true, {help = 'Give weapon component', validate = true, arguments = { + {name = 'playerId', help = _U('id_param'), type = 'player'}, + {name = 'weaponName', help = _U('weapon'), type = 'weapon'}, + {name = 'componentName', help = 'weapon component', type = 'string'} }}) -TriggerEvent('es:addGroupCommand', 'car', 'admin', function(source, args, user) - TriggerClientEvent('esx:spawnVehicle', source, args[1]) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('spawn_car'), params = {{name = 'car', help = _U('spawn_car_param')}}}) +ESX.RegisterCommand({'clear', 'cls'}, 'user', function(xPlayer, args, showError) + xPlayer.triggerEvent('chat:clear') +end, false, {help = _U('chat_clear')}) -TriggerEvent('es:addGroupCommand', 'cardel', 'admin', function(source, args, user) - TriggerClientEvent('esx:deleteVehicle', source, args[1]) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('delete_vehicle'), params = { - {name = 'radius', help = 'Optional, delete every vehicle within the specified radius'} -}}) - -TriggerEvent('es:addGroupCommand', 'dv', 'admin', function(source, args, user) - TriggerClientEvent('esx:deleteVehicle', source, args[1]) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('delete_vehicle'), params = { - {name = 'radius', help = 'Optional, delete every vehicle within the specified radius'} -}}) - -TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, args, user) - local xPlayer = ESX.GetPlayerFromId(args[1]) - - if xPlayer then - local account = args[2] - local amount = tonumber(args[3]) - - if amount then - if account == 'cash' then - xPlayer.addMoney(amount) - elseif xPlayer.getAccount(account) then - xPlayer.addAccountMoney(account, amount) - else - TriggerClientEvent('esx:showNotification', source, _U('invalid_account')) - end - else - TriggerClientEvent('esx:showNotification', source, _U('amount_invalid')) - end - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) - end -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('giveaccountmoney'), params = { - {name = 'playerId', help = _U('id_param')}, - {name = 'account', help = _U('account')}, - {name = 'amount', help = _U('money_amount')} -}}) - -TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, user) - local xPlayer = ESX.GetPlayerFromId(args[1]) - - if xPlayer then - local item = args[2] - local count = tonumber(args[3]) - - if count then - if xPlayer.getInventoryItem(item) then - xPlayer.addInventoryItem(item, count) - else - TriggerClientEvent('esx:showNotification', source, _U('invalid_item')) - end - else - TriggerClientEvent('esx:showNotification', source, _U('invalid_amount')) - end - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) - end -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('giveitem'), params = { - {name = 'playerId', help = _U('id_param')}, - {name = 'item', help = _U('item')}, - {name = 'amount', help = _U('amount')} -}}) - -TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, user) - local xPlayer = ESX.GetPlayerFromId(args[1]) - - if xPlayer then - local weaponName = args[2] or 'unknown' - - if ESX.GetWeapon(weaponName) then - weaponName = string.upper(weaponName) - - if xPlayer.hasWeapon(weaponName) then - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player already has that weapon.' } }) - else - if tonumber(args[3]) then - xPlayer.addWeapon(weaponName, tonumber(args[3])) - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid ammo amount.' } }) - end - end - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid weapon.' } }) - end - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) - end -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('giveweapon'), params = { - {name = 'playerId', help = _U('id_param')}, - {name = 'weapon', help = _U('weapon')}, - {name = 'ammo', help = _U('amountammo')} -}}) - -TriggerEvent('es:addGroupCommand', 'giveweaponcomponent', 'admin', function(source, args, user) - local xPlayer = ESX.GetPlayerFromId(args[1]) - - if xPlayer then - local weaponName = args[2] or 'unknown' - - if ESX.GetWeapon(weaponName) then - weaponName = string.upper(weaponName) - - if xPlayer.hasWeapon(weaponName) then - local component = ESX.GetWeaponComponent(weaponName, args[3] or 'unknown') - - if component then - if xPlayer.hasWeaponComponent(weaponName, args[3]) then - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player already has that weapon component.' } }) - else - xPlayer.addWeaponComponent(weaponName, args[3]) - end - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid weapon component.' } }) - end - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player does not have that weapon.' } }) - end - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid weapon.' } }) - end - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) - end -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = 'Give weapon component', params = { - {name = 'playerId', help = _U('id_param')}, - {name = 'weaponName', help = _U('weapon')}, - {name = 'componentName', help = 'weapon component'} -}}) - -TriggerEvent('es:addGroupCommand', 'clear', 'user', function(source, args, user) - TriggerClientEvent('chat:clear', source) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('chat_clear')}) - -TriggerEvent('es:addGroupCommand', 'cls', 'user', function(source, args, user) - TriggerClientEvent('chat:clear', source) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end) - -TriggerEvent('es:addGroupCommand', 'clsall', 'admin', function(source, args, user) +ESX.RegisterCommand({'clearall', 'clsall'}, 'admin', function(xPlayer, args, showError) TriggerClientEvent('chat:clear', -1) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end) +end, false, {help = _U('chat_clear_all')}) -TriggerEvent('es:addGroupCommand', 'clearall', 'admin', function(source, args, user) - TriggerClientEvent('chat:clear', -1) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('chat_clear_all')}) - -TriggerEvent('es:addGroupCommand', 'clearinventory', 'admin', function(source, args, user) - local xPlayer - - if args[1] then - xPlayer = ESX.GetPlayerFromId(args[1]) - else - xPlayer = ESX.GetPlayerFromId(source) - end - - if xPlayer then - for i=1, #xPlayer.inventory, 1 do - if xPlayer.inventory[i].count > 0 then - xPlayer.setInventoryItem(xPlayer.inventory[i].name, 0) - end +ESX.RegisterCommand('clearinventory', 'admin', function(xPlayer, args, showError) + for k,v in ipairs(args.playerId.inventory) do + if v.count > 0 then + args.playerId.setInventoryItem(v.name, 0) end - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) end -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('command_clearinventory'), params = {{name = 'playerId', help = _U('command_playerid_param')}}}) +end, true, {help = _U('command_clearinventory'), validate = true, arguments = { + {name = 'playerId', help = _U('id_param'), type = 'player'} +}}) -TriggerEvent('es:addGroupCommand', 'clearloadout', 'admin', function(source, args, user) - local xPlayer - - if args[1] then - xPlayer = ESX.GetPlayerFromId(args[1]) - else - xPlayer = ESX.GetPlayerFromId(source) +ESX.RegisterCommand('clearloadout', 'admin', function(xPlayer, args, showError) + for k,v in ipairs(args.playerId.loadout) do + args.playerId.removeWeapon(v.name) end - - if xPlayer then - for i=#xPlayer.loadout, 1, -1 do - xPlayer.removeWeapon(xPlayer.loadout[i].name) - end - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) - end -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('command_clearloadout'), params = {{name = 'playerId', help = _U('command_playerid_param')}}}) +end, true, {help = _U('command_clearloadout'), validate = true, arguments = { + {name = 'playerId', help = _U('id_param'), type = 'player'} +}}) diff --git a/server/common.lua b/server/common.lua index e2496d75..b9d5f601 100644 --- a/server/common.lua +++ b/server/common.lua @@ -9,6 +9,7 @@ ESX.LastPlayerData = {} ESX.Pickups = {} ESX.PickupId = 0 ESX.Jobs = {} +ESX.RegisteredCommands = {} AddEventHandler('esx:getSharedObject', function(cb) cb(ESX) @@ -58,21 +59,14 @@ MySQL.ready(function() end) AddEventHandler('esx:playerLoaded', function(playerId) - local xPlayer, accounts, items = ESX.GetPlayerFromId(playerId), {}, {} - local xPlayerAccounts, xPlayerItems = xPlayer.getAccounts(), xPlayer.getInventory() + local xPlayer, accounts = ESX.GetPlayerFromId(playerId), {} + local xPlayerAccounts = xPlayer.getAccounts() for i=1, #xPlayerAccounts, 1 do accounts[xPlayerAccounts[i].name] = xPlayerAccounts[i].money end - for i=1, #xPlayerItems, 1 do - items[xPlayerItems[i].name] = xPlayerItems[i].count - end - - ESX.LastPlayerData[playerId] = { - accounts = accounts, - items = items - } + ESX.LastPlayerData[playerId] = {accounts = accounts} end) RegisterServerEvent('esx:clientLog') diff --git a/server/functions.lua b/server/functions.lua index 83c2debc..6cfd5860 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -20,6 +20,115 @@ ESX.SetTimeout = function(msec, cb) return id end +ESX.RegisterCommand = function(name, group, cb, allowConsole, suggestion) + if type(name) == 'table' then + for k,v in ipairs(name) do + ESX.RegisterCommand(v, group, cb, allowConsole, suggestion) + end + + return + end + + if ESX.RegisteredCommands[name] then + print(('[es_extended] [^3WARNING^7] An command "%s" is already registered'):format(name)) + else + if suggestion then + if not suggestion.arguments then suggestion.arguments = {} end + if not suggestion.help then suggestion.help = '' end + end + + ESX.RegisteredCommands[name] = {group = group, cb = cb, allowConsole = allowConsole, suggestion = suggestion} + + RegisterCommand(name, function(playerId, args, rawCommand) + local command = ESX.RegisteredCommands[name] + + if not command.allowConsole and playerId == 0 then + print('[es_extended] [^3WARNING^7] That command can not be run from console') + else + local xPlayer, error = ESX.GetPlayerFromId(playerId), nil + + if command.suggestion then + if command.suggestion.validate then + if #args ~= #command.suggestion.arguments then + error = ('Argument count mismatch (passed %s, wanted %s)'):format(#args, #command.suggestion.arguments) + end + end + + if not error and command.suggestion.arguments then + local newArgs = {} + + for k,v in ipairs(command.suggestion.arguments) do + if v.type then + if v.type == 'number' then + local newArg = tonumber(args[k]) + + if newArg then + newArgs[v.name] = newArg + else + error = ('Argument #%s type mismatch (passed string, wanted number)'):format(k) + end + elseif v.type == 'player' then + local targetPlayer = tonumber(args[k]) + + if targetPlayer then + local xTargetPlayer = ESX.GetPlayerFromId(targetPlayer) + + if xTargetPlayer then + newArgs[v.name] = xTargetPlayer + else + error = 'Player not online' + end + else + error = ('Argument #%s type mismatch (passed string, wanted number)'):format(k) + end + elseif v.type == 'string' then + newArgs[v.name] = args[k] + elseif v.type == 'item' then + if ESX.Items[args[k]] then + newArgs[v.name] = args[k] + else + error = _U('invalid_item') + end + elseif v.type == 'weapon' then + if ESX.GetWeapon(args[k]) then + newArgs[v.name] = string.upper(args[k]) + else + error = 'Invalid weapon' + end + elseif v.type == 'any' then + newArgs[v.name] = args[k] + end + end + + if error then break end + end + + args = newArgs + end + end + + if error then + if playerId == 0 then + print(('[es_extended] [^3WARNING^7] %s^7'):format(error)) + else + xPlayer.triggerEvent('chat:addMessage', {args = {'^1SYSTEM', error}}) + end + else + cb(xPlayer, args, function(msg) + if playerId == 0 then + print(('[es_extended] [^3WARNING^7] %s^7'):format(msg)) + else + xPlayer.triggerEvent('chat:addMessage', {args = {'^1SYSTEM', msg}}) + end + end) + end + end + end, true) + + ExecuteCommand(('add_ace group.%s command.%s allow'):format(group, name)) + end +end + ESX.ClearTimeout = function(id) ESX.CancelledTimeouts[id] = true end @@ -44,9 +153,9 @@ ESX.SavePlayer = function(xPlayer, cb) if ESX.LastPlayerData[xPlayer.source].accounts[v.name] ~= v.money then table.insert(asyncTasks, function(cb) MySQL.Async.execute('UPDATE user_accounts SET money = @money WHERE identifier = @identifier AND name = @name', { - ['@money'] = v.money, + ['@money'] = v.money, ['@identifier'] = xPlayer.identifier, - ['@name'] = v.name + ['@name'] = v.name }, function(rowsChanged) cb() end) diff --git a/server/main.lua b/server/main.lua index d079ded5..38bd8926 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,4 +1,38 @@ -AddEventHandler('es:playerLoaded', function(playerId, player) +RegisterNetEvent('esx:playerJoined') +AddEventHandler('esx:playerJoined', function() + onPlayerJoined(source) +end) + +function onPlayerJoined(playerId) + local identifier + + for k,v in ipairs(GetPlayerIdentifiers(playerId)) do + if string.match(v, 'license:') then + identifier = string.sub(v, 9) + break + end + end + + if identifier then + MySQL.Async.fetchScalar('SELECT 1 FROM users WHERE identifier = @identifier', { + ['@identifier'] = identifier + }, function(result) + if result then + loadESXPlayer(identifier, playerId) + else + MySQL.Async.execute('INSERT INTO users (identifier) VALUES (@identifier)', { + ['@identifier'] = identifier + }, function(rowsChanged) + loadESXPlayer(identifier, playerId) + end) + end + end) + else + DropPlayer(playerId, 'Your Rockstar license could not be found') + end +end + +function loadESXPlayer(identifier, playerId) local tasks = {} local userData = { @@ -6,22 +40,20 @@ AddEventHandler('es:playerLoaded', function(playerId, player) inventory = {}, job = {}, loadout = {}, - playerName = GetPlayerName(playerId), - coords = nil + playerName = GetPlayerName(playerId) } - -- Get accounts + -- get accounts table.insert(tasks, function(cb) MySQL.Async.fetchAll('SELECT name, money FROM user_accounts WHERE identifier = @identifier', { - ['@identifier'] = player.getIdentifier() + ['@identifier'] = identifier }, function(accounts) - local validAccounts = ESX.Table.Set(Config.Accounts) for k,v in ipairs(accounts) do - if validAccounts[v.name] then + if Config.Accounts[v.name] then table.insert(userData.accounts, { name = v.name, money = v.money, - label = Config.AccountLabels[v.name] + label = Config.Accounts[v.name] }) end end @@ -30,147 +62,120 @@ AddEventHandler('es:playerLoaded', function(playerId, player) end) end) - -- Get job and loadout table.insert(tasks, function(cb) + MySQL.Async.fetchAll('SELECT job, job_grade, `group`, loadout, position, inventory FROM users WHERE identifier = @identifier', { + ['@identifier'] = identifier + }, function(result) + local job, grade, jobObject, gradeObject = result[1].job, tostring(result[1].job_grade) - local tasks2 = {} + if ESX.DoesJobExist(job, grade) then + jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] + else + print(('[es_extended] [^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 - -- Get job name, grade and coords - table.insert(tasks2, function(cb2) + userData.job = {} - MySQL.Async.fetchAll('SELECT job, job_grade, loadout, position, inventory FROM users WHERE identifier = @identifier', { - ['@identifier'] = player.getIdentifier() - }, function(result) - local job, grade = result[1].job, tostring(result[1].job_grade) + userData.job.id = jobObject.id + userData.job.name = jobObject.name + userData.job.label = jobObject.label - if ESX.DoesJobExist(job, grade) then - local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] + 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 = {} + userData.job.skin_male = {} + userData.job.skin_female = {} - userData.job.id = jobObject.id - userData.job.name = jobObject.name - userData.job.label = jobObject.label + 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 - userData.job.grade = tonumber(grade) - userData.job.grade_name = gradeObject.name - userData.job.grade_label = gradeObject.label - userData.job.grade_salary = gradeObject.salary + local foundItems = {} - userData.job.skin_male = {} - userData.job.skin_female = {} + if result[1].inventory and result[1].inventory ~= '' then + local inventory = json.decode(result[1].inventory) - if gradeObject.skin_male then - userData.job.skin_male = json.decode(gradeObject.skin_male) - end + for name,count in pairs(inventory) do + local item = ESX.Items[name] - if gradeObject.skin_female then - userData.job.skin_female = json.decode(gradeObject.skin_female) - end - else - print(('[es_extended] [^3WARNING^7] Ignoring invalid job for %s [job: %s, grade: %s]'):format(player.getIdentifier(), job, grade)) - - local job, grade = 'unemployed', '0' - local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] - - userData.job = {} - - 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 = {} - end - - local foundItems = {} - - 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(('[es_extended] [^3WARNING^7] Ignoring invalid item "%s" for "%s"'):format(name, player.getIdentifier())) - end + if item then + foundItems[name] = count + else + print(('[es_extended] [^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 + for name,item in pairs(ESX.Items) do + local count = foundItems[name] or 0 - 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.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) + if result[1].group then + userData.group = result[1].group + else + userData.group = 'user' + end - if result[1].loadout then - userData.loadout = json.decode(result[1].loadout) - - -- compatibility with old loadouts - for k,v in ipairs(userData.loadout) do - if not v.components then v.components = {} end - if not v.tintIndex then v.tintIndex = 0 end - end - end - - if result[1].position and result[1].position ~= '' then - userData.coords = json.decode(result[1].position) - else - print('[es_extended] [^3WARNING^7] Column "position" in "users" 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 - - cb2() + table.sort(userData.inventory, function(a, b) + return a.label < b.label end) + if result[1].loadout then + userData.loadout = json.decode(result[1].loadout) + + -- compatibility with old loadouts + for k,v in ipairs(userData.loadout) do + if not v.components then v.components = {} end + if not v.tintIndex then v.tintIndex = 0 end + end + end + + if result[1].position and result[1].position ~= '' then + userData.coords = json.decode(result[1].position) + else + print('[es_extended] [^3WARNING^7] Column "position" in "users" 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 + + cb() end) - - Async.series(tasks2, cb) - end) - -- Run Tasks Async.parallel(tasks, function(results) - local xPlayer = CreateExtendedPlayer(player, userData.accounts, userData.inventory, userData.job, userData.loadout, userData.playerName, userData.coords) + local xPlayer = CreateExtendedPlayer(playerId, identifier, userData.group, userData.accounts, userData.inventory, userData.job, userData.loadout, userData.playerName, userData.coords) xPlayer.getMissingAccounts(function(missingAccounts) if #missingAccounts > 0 then - for i=1, #missingAccounts, 1 do + for k,v in ipairs(missingAccounts) do table.insert(xPlayer.accounts, { - name = missingAccounts[i], + name = v, money = 0, - label = Config.AccountLabels[missingAccounts[i]] + label = Config.Accounts[v] }) end - xPlayer.createAccounts(missingAccounts) + xPlayer.createMissingAccounts(missingAccounts) end ESX.Players[playerId] = xPlayer - TriggerEvent('esx:playerLoaded', playerId, xPlayer) xPlayer.triggerEvent('esx:playerLoaded', { identifier = xPlayer.identifier, + money = xPlayer.getMoney(), accounts = xPlayer.getAccounts(), coords = xPlayer.getCoords(), inventory = xPlayer.getInventory(), @@ -180,11 +185,10 @@ AddEventHandler('es:playerLoaded', function(playerId, player) maxWeight = xPlayer.maxWeight }) - xPlayer.displayMoney(xPlayer.getMoney()) xPlayer.triggerEvent('esx:createMissingPickups', ESX.Pickups) end) end) -end) +end AddEventHandler('playerDropped', function(reason) local playerId = source @@ -238,23 +242,13 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo else sourceXPlayer.showNotification(_U('imp_invalid_quantity')) end - elseif type == 'item_money' then - if itemCount > 0 and sourceXPlayer.getMoney() >= itemCount then - sourceXPlayer.removeMoney(itemCount) - targetXPlayer.addMoney (itemCount) - - sourceXPlayer.showNotification(_U('gave_money', ESX.Math.GroupDigits(itemCount), targetXPlayer.name)) - targetXPlayer.showNotification(_U('received_money', ESX.Math.GroupDigits(itemCount), sourceXPlayer.name)) - else - sourceXPlayer.showNotification(_U('imp_invalid_amount')) - end elseif type == 'item_account' then if itemCount > 0 and sourceXPlayer.getAccount(itemName).money >= itemCount then sourceXPlayer.removeAccountMoney(itemName, itemCount) targetXPlayer.addAccountMoney (itemName, itemCount) - sourceXPlayer.showNotification(_U('gave_account_money', ESX.Math.GroupDigits(itemCount), Config.AccountLabels[itemName], targetXPlayer.name)) - targetXPlayer.showNotification(_U('received_account_money', ESX.Math.GroupDigits(itemCount), Config.AccountLabels[itemName], sourceXPlayer.name)) + sourceXPlayer.showNotification(_U('gave_account_money', ESX.Math.GroupDigits(itemCount), Config.Accounts[itemName], targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_account_money', ESX.Math.GroupDigits(itemCount), Config.Accounts[itemName], sourceXPlayer.name)) else sourceXPlayer.showNotification(_U('imp_invalid_amount')) end @@ -328,21 +322,6 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) xPlayer.showNotification(_U('threw_standard', itemCount, xItem.label)) end end - elseif type == 'item_money' then - if itemCount == nil or itemCount < 1 then - xPlayer.showNotification(_U('imp_invalid_amount')) - else - local playerCash = xPlayer.getMoney() - - if (itemCount > playerCash or playerCash < 1) then - xPlayer.showNotification(_U('imp_invalid_amount')) - else - xPlayer.removeMoney(itemCount) - local pickupLabel = ('~y~%s~s~ [~g~%s~s~]'):format(_U('cash'), _U('locale_currency', ESX.Math.GroupDigits(itemCount))) - ESX.CreatePickup('item_money', 'money', itemCount, pickupLabel, playerId) - xPlayer.showNotification(_U('threw_money', ESX.Math.GroupDigits(itemCount))) - end - end elseif type == 'item_account' then if itemCount == nil or itemCount < 1 then xPlayer.showNotification(_U('imp_invalid_amount')) @@ -406,9 +385,6 @@ AddEventHandler('esx:onPickup', function(id) else xPlayer.showNotification(_U('threw_cannot_pickup')) end - elseif pickup.type == 'item_money' then - success = true - xPlayer.addMoney(pickup.count) elseif pickup.type == 'item_account' then success = true xPlayer.addAccountMoney(pickup.name, pickup.count) From d8112af6e6cc92e948795cd93b41be149836c5d1 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 15:24:32 +0100 Subject: [PATCH 2552/3224] Final commit v1.2.0 --- fxmanifest.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fxmanifest.lua b/fxmanifest.lua index f40e04a9..a9fe16ba 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -4,7 +4,7 @@ game 'gta5' description 'ES Extended' -version '1.1.0' +version '1.2.0' server_scripts { '@async/async.lua', From baf7af69b9d50cc765206fe76fb37de0c984c216 Mon Sep 17 00:00:00 2001 From: Oldarorn <36448848+Oldarorn@users.noreply.github.com> Date: Mon, 17 Feb 2020 16:04:57 +0100 Subject: [PATCH 2553/3224] Update fr.lua Welcome new ESX without ES :D --- locales/fr.lua | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index 0295f845..9e5bd015 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -46,9 +46,9 @@ Locales['fr'] = { ['company_nomoney'] = 'votre entreprise n\'a plus d\'argent pour vous payer!', ['received_paycheck'] = 'paiement reçu', ['bank'] = 'banque', - ['account_bank'] = 'bank', - ['account_black_money'] = 'dirty Money', - ['account_money'] = 'cash', + ['account_bank'] = 'banque', + ['account_black_money'] = 'argent sale', + ['account_money'] = 'espèces', ['act_imp'] = 'action impossible', ['in_vehicle'] = 'Vous ne pouvez rien donner à quelqu\'un dans un véhicule', @@ -187,12 +187,12 @@ Locales['fr'] = { ['ammo_flaregun'] = 'fusée(s)', -- Weapon Tints - ['tint_default'] = 'default skin', - ['tint_green'] = 'green skin', - ['tint_gold'] = 'gold skin', - ['tint_pink'] = 'pink skin', - ['tint_army'] = 'army skin', - ['tint_lspd'] = 'blue skin', - ['tint_orange'] = 'orange skin', - ['tint_platinum'] = 'platinum skin', + ['tint_default'] = 'skin par défaut', + ['tint_green'] = 'skin vert', + ['tint_gold'] = 'skin doré', + ['tint_pink'] = 'skin rose', + ['tint_army'] = 'skin militaire', + ['tint_lspd'] = 'skin bleu', + ['tint_orange'] = 'skin orange', + ['tint_platinum'] = 'skin platine', } From 056633d88a117849108d53480afc5ca69f79ad5d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 20:27:47 +0100 Subject: [PATCH 2554/3224] Update README.md --- README.md | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index fd1543f1..ee747927 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # es_extended -es_extended is a roleplay framework for FiveM. It is developed on top of EssentialMode (aka ES), where the project ESX is originating from - the **Es**sentialMode E**x**tended framework for FiveM. +es_extended is a roleplay framework for FiveM. ESX is short for **Es**sentialMode E**x**tended. ## Links & Read more @@ -11,20 +11,18 @@ es_extended is a roleplay framework for FiveM. It is developed on top of Essenti ## Features - Weight based inventory system -- Weapons support, including support for attachments -- Supports different money accounts (defaulted with bank & black money) +- Weapons support, including support for attachments and tints +- Supports different money accounts (defaulted with cash, bank and black money) - Many official resources available in our GitHub - Job system, with grades and clothes support - Supports multiple languages, most strings are localized -- Easy to use API +- Easy to use API for developers to easily integrate ESX to their projects ## Requirements This order also applies in the startup order. - [mysql-async](https://github.com/brouznouf/fivem-mysql-async) -- [essentialmode](https://github.com/kanersps/essentialmode) -- [esplugin_mysql](https://github.com/kanersps/esplugin_mysql) - [async](https://github.com/ESX-Org/async) ## Download & Installation @@ -66,9 +64,6 @@ git clone https://github.com/ESX-Org/esx_menu_list [esx]/[ui]/esx_menu_list ``` start mysql-async -start essentialmode -start esplugin_mysql - start es_extended start esx_menu_default From b6761d106eecbb9a39cc7245c0803d5266ed1d89 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 20:31:45 +0100 Subject: [PATCH 2555/3224] Added missing required configuration file modification --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index ee747927..a4e358c1 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,9 @@ git clone https://github.com/ESX-Org/esx_menu_list [esx]/[ui]/esx_menu_list - Configure your `server.cfg` to look like this ``` +add_ace resource.es_extended command.add_ace allow +add_ace resource.es_extended command.add_principal allow + start mysql-async start es_extended From e822960057213728d06547f9800c07089d062488 Mon Sep 17 00:00:00 2001 From: Raven-RP <45501870+DecodazTV@users.noreply.github.com> Date: Mon, 17 Feb 2020 20:36:31 +0100 Subject: [PATCH 2556/3224] Improved German translation (#495) * german language update * Update de.lua * Update de.lua requested Change * Update de.lua * Update de.lua * Update de.lua Co-authored-by: Samuel --- locales/de.lua | 138 ++++++++++++++++++++++++------------------------- 1 file changed, 69 insertions(+), 69 deletions(-) diff --git a/locales/de.lua b/locales/de.lua index 61f77920..4ccb00a9 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -6,22 +6,22 @@ Locales['de'] = { ['remove'] = 'entfernen', ['return'] = 'zurück', ['give_to'] = 'geben an', - ['amount'] = 'Betrag', + ['amount'] = 'betrag', ['giveammo'] = 'munition geben', ['amountammo'] = 'anzahl der munition', ['noammo'] = 'du hast keine munition!', ['gave_item'] = 'du gibst ~y~%sx~s~ ~b~%s~s~ an ~y~%s~s~', ['received_item'] = 'du empfängst ~y~%sx~s~ ~b~%s~s~ von ~b~%s~s~', ['gave_weapon'] = 'du gibst ~b~%s~s~ an ~y~%s~s~', - ['gave_weapon_ammo'] = 'you gave ~o~%sx %s~s~ for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_ammo'] = 'du gibst ~o~%sx %s~s~ von ~b~%s~s~ an ~y~%s~s~', ['gave_weapon_withammo'] = 'du gibst ~b~%s~s~ mit ~o~%sx %s~s~ an ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ hat bereits eine(n) ~y~%s~s~', - ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['gave_weapon_noweapon'] = '~y~%s~s~ hat diese Waffe nicht', ['received_weapon'] = 'du erhälst ~b~%s~s~ von ~b~%s~s~', - ['received_weapon_ammo'] = 'you received ~o~%sx %s~s~ for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_ammo'] = 'du erhälst ~o~%sx %s~s~ für dein ~b~%s~s~ von ~b~%s~s~', ['received_weapon_withammo'] = 'du erhälst ~b~%s~s~ mit ~o~%sx %s~s~ von ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ hat versucht dir eine(n) ~y~%s~s~ zu geben, aber du hast bereits eine(n)', - ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['received_weapon_noweapon'] = '~b~%s~s~ ahat versucht dir Munition für eine(n) ~y~%s~s~, aber du besitzt diese Waffe nicht', ['gave_account_money'] = 'du gibst ~g~$%s~s~ (%s) an ~y~%s~s~', ['received_account_money'] = 'du empfängst ~g~$%s~s~ (%s) von ~b~%s~s~', ['amount_invalid'] = 'ungültiger Betrag', @@ -30,15 +30,15 @@ Locales['de'] = { ['imp_invalid_quantity'] = 'aktion nicht möglich, ungültige Anzahl', ['imp_invalid_amount'] = 'aktion nicht möglich, ungültiger Betrag', ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', - ['threw_weapon'] = 'you threw ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx %s~s~', - ['threw_weapon_already'] = 'you already carry the same weapon', - ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', - ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', + ['threw_account'] = 'du wirfst ~g~$%s~s~ ~b~%s~s~ weg', + ['threw_weapon'] = 'du wirfst ~b~%s~s~ weg', + ['threw_weapon_ammo'] = 'du wirfst ~b~%s~s~ mit ~o~%sx %s~s~ weg', + ['threw_weapon_already'] = 'Du hast bereits diese Waffe', + ['threw_cannot_pickup'] = 'Du kannst das nicht aufheben, da dein Inventar voll ist', + ['threw_pickup_prompt'] = 'drücke ~y~E~s~ um aufzuheben', -- Key mapping - ['keymap_showinventory'] = 'show Inventory', + ['keymap_showinventory'] = 'inventar anzeigen', -- Salary related ['received_salary'] = 'du hast dein Gehalt erhalten: ~g~$%s~s~', @@ -51,28 +51,28 @@ Locales['de'] = { ['account_money'] = 'cash', ['act_imp'] = 'Aktion nicht möglich', - ['in_vehicle'] = 'you can\'t give anything to someone in a vehicle', + ['in_vehicle'] = 'du kannst keine Items in einem Fahrzeug weitergeben', -- Commands - ['setjob'] = 'assign a job to a user', - ['id_param'] = 'the ID of the player', - ['setjob_param2'] = 'the job you wish to assign', - ['setjob_param3'] = 'the job level', - ['spawn_car'] = 'spawn a car', - ['spawn_car_param'] = 'name of car', - ['delete_vehicle'] = 'deletes Vehicle', - ['invalid_account'] = 'invalid account', - ['account'] = 'account', - ['giveaccountmoney'] = 'give account money', - ['invalid_item'] = 'invalid item', + ['setjob'] = 'spieler Job zuweisen', + ['id_param'] = 'ID von Spieler', + ['setjob_param2'] = 'der zu vergebende Job', + ['setjob_param3'] = 'der Jobgrad', + ['spawn_car'] = 'fahrzeug spawnen', + ['spawn_car_param'] = 'fahrzeugname', + ['delete_vehicle'] = 'entfernt Fahrzeuge', + ['invalid_account'] = 'ungültige Anzahl', + ['account'] = 'bank', + ['giveaccountmoney'] = 'bankgeld geben', + ['invalid_item'] = 'ungültiges Item', ['item'] = 'item', - ['giveitem'] = 'give item', - ['weapon'] = 'weapon', - ['giveweapon'] = 'give weapon', - ['chat_clear'] = 'clear the chat', - ['chat_clear_all'] = 'clear the chat for everyone', - ['command_clearinventory'] = 'clear all items from inventory', - ['command_clearloadout'] = 'remove all weapons from loadout', + ['giveitem'] = 'item geben', + ['weapon'] = 'waffe', + ['giveweapon'] = 'waffe geben', + ['chat_clear'] = 'chat leeren', + ['chat_clear_all'] = 'chat für jeden leeren', + ['command_clearinventory'] = 'alle Items aus dem Inventar entfernen', + ['command_clearloadout'] = 'alle Waffen aus dem Loadout entfernen', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', @@ -142,12 +142,12 @@ Locales['de'] = { ['weapon_revolver'] = 'Schwerer Revolver', ['weapon_dbshotgun'] = 'Doppelläufige Schrotflinte', ['weapon_compactrifle'] = 'Kampfgewehr', - ['weapon_autoshotgun'] = 'Auto Shotgun', + ['weapon_autoshotgun'] = 'Auto Schrotflinte', ['weapon_battleaxe'] = 'Kampfaxt', - ['weapon_compactlauncher'] = 'Kompakt Launcher', + ['weapon_compactlauncher'] = 'Kompakt Granatwerfer', ['weapon_minismg'] = 'Mini SMG', ['weapon_pipebomb'] = 'Rohrbombe', - ['weapon_poolcue'] = 'Kö', + ['weapon_poolcue'] = 'Billiard-Kö', ['weapon_wrench'] = 'Rohrzange', ['weapon_flashlight'] = 'Taschenlampe', ['gadget_parachute'] = 'Fallschirm', @@ -155,44 +155,44 @@ Locales['de'] = { ['weapon_doubleaction'] = 'double-Action Revolver', -- Weapon Components - ['component_clip_default'] = 'default Grip', - ['component_clip_extended'] = 'extended Grip', - ['component_clip_drum'] = 'drum Magazine', - ['component_clip_box'] = 'box Magazine', - ['component_flashlight'] = 'flashlight', - ['component_scope'] = 'scope', - ['component_scope_advanced'] = 'advanced Scope', - ['component_suppressor'] = 'suppressor', - ['component_grip'] = 'grip', - ['component_luxary_finish'] = 'luxary Weapon Finish', + ['component_clip_default'] = 'standart Griff', + ['component_clip_extended'] = 'erweiterter Griff', + ['component_clip_drum'] = 'trommelmagazin', + ['component_clip_box'] = 'kastenmagazin', + ['component_flashlight'] = 'taschenlampe', + ['component_scope'] = 'zielfernrohr', + ['component_scope_advanced'] = 'erweitertes Zielfernrohr', + ['component_suppressor'] = 'schalldämpfer', + ['component_grip'] = 'griff', + ['component_luxary_finish'] = 'luxus Waffen Design', -- Weapon Ammo - ['ammo_rounds'] = 'round(s)', - ['ammo_shells'] = 'shell(s)', - ['ammo_charge'] = 'charge', - ['ammo_petrol'] = 'gallons of fuel', - ['ammo_firework'] = 'firework(s)', - ['ammo_rockets'] = 'rocket(s)', - ['ammo_grenadelauncher'] = 'grenade(s)', - ['ammo_grenade'] = 'grenade(s)', - ['ammo_stickybomb'] = 'bomb(s)', - ['ammo_pipebomb'] = 'bomb(s)', - ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_rounds'] = 'kugel(n)', + ['ammo_shells'] = 'schrotpatrone(n)', + ['ammo_charge'] = 'ladung', + ['ammo_petrol'] = 'liter Benzin', + ['ammo_firework'] = 'feuerwerksrakete(n)', + ['ammo_rockets'] = 'rakete(n)', + ['ammo_grenadelauncher'] = 'granate(n)', + ['ammo_grenade'] = 'granate(n)', + ['ammo_stickybomb'] = 'bombe(n)', + ['ammo_pipebomb'] = 'bombe(n)', + ['ammo_smokebomb'] = 'bombe(n)', ['ammo_molotov'] = 'cocktail(s)', - ['ammo_proxmine'] = 'mine(s)', - ['ammo_bzgas'] = 'can(s)', - ['ammo_ball'] = 'ball(s)', - ['ammo_snowball'] = 'snowball(s)', - ['ammo_flare'] = 'flare(s)', - ['ammo_flaregun'] = 'flare(s)', + ['ammo_proxmine'] = 'mine(n)', + ['ammo_bzgas'] = 'can(n)', + ['ammo_ball'] = 'ball', + ['ammo_snowball'] = 'schneebälle', + ['ammo_flare'] = 'signalfackel(n)', + ['ammo_flaregun'] = 'signalfackeln(munition)', -- Weapon Tints - ['tint_default'] = 'default skin', - ['tint_green'] = 'green skin', - ['tint_gold'] = 'gold skin', - ['tint_pink'] = 'pink skin', - ['tint_army'] = 'army skin', - ['tint_lspd'] = 'blue skin', - ['tint_orange'] = 'orange skin', - ['tint_platinum'] = 'platinum skin', + ['tint_default'] = 'standard', + ['tint_green'] = 'grün', + ['tint_gold'] = 'gold', + ['tint_pink'] = 'pink', + ['tint_army'] = 'camouflage', + ['tint_lspd'] = 'blau', + ['tint_orange'] = 'orange', + ['tint_platinum'] = 'platin', } From 739a228dd28bab665033b6ed97839ef2889572b2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 21:15:52 +0100 Subject: [PATCH 2557/3224] Updated to work with latest ESX --- client/main.lua | 20 +++++++++++--------- server/main.lua | 29 ++++++++++------------------- 2 files changed, 21 insertions(+), 28 deletions(-) diff --git a/client/main.lua b/client/main.lua index 3b8dcdae..2298cbb1 100644 --- a/client/main.lua +++ b/client/main.lua @@ -36,16 +36,18 @@ AddEventHandler('playerSpawned', function() exports.spawnmanager:setAutoSpawn(false) -- disable respawn firstSpawn = false - ESX.TriggerServerCallback('esx_ambulancejob:getDeathStatus', function(shouldDie) - if shouldDie and Config.AntiCombatLog then - while not PlayerLoaded do - Citizen.Wait(1000) - end - - ESX.ShowNotification(_U('combatlog_message')) - RemoveItemsAfterRPDeath() + if Config.AntiCombatLog then + while not PlayerLoaded do + Citizen.Wait(1000) end - end) + + ESX.TriggerServerCallback('esx_ambulancejob:getDeathStatus', function(shouldDie) + if shouldDie then + ESX.ShowNotification(_U('combatlog_message')) + RemoveItemsAfterRPDeath() + end + end) + end end end) diff --git a/server/main.lua b/server/main.lua index 4b24fb5e..57fed8ae 100644 --- a/server/main.lua +++ b/server/main.lua @@ -250,20 +250,11 @@ AddEventHandler('esx_ambulancejob:giveItem', function(itemName, amount) end end) -TriggerEvent('es:addGroupCommand', 'revive', 'admin', function(source, args, user) - if args[1] then - local playerId = tonumber(args[1]) - if playerId and ESX.GetPlayerFromId(playerId) then - TriggerClientEvent('esx_ambulancejob:revive', playerId) - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) - end - else - TriggerClientEvent('esx_ambulancejob:revive', source) - end -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, { help = _U('revive_help'), params = {{ name = 'playerId' }} }) +ESX.RegisterCommand('revive', 'admin', function(xPlayer, args, showError) + args.playerId.triggerEvent('esx_ambulancejob:revive') +end, true, {help = _U('revive_help'), validate = true, arguments = { + {name = 'playerId', help = 'The player id', type = 'player'} +}}) ESX.RegisterUsableItem('medikit', function(source) if not playersHealing[source] then @@ -292,13 +283,13 @@ ESX.RegisterUsableItem('bandage', function(source) end) ESX.RegisterServerCallback('esx_ambulancejob:getDeathStatus', function(source, cb) - local identifier = GetPlayerIdentifiers(source)[1] + local xPlayer = ESX.GetPlayerFromId(source) MySQL.Async.fetchScalar('SELECT is_dead FROM users WHERE identifier = @identifier', { - ['@identifier'] = identifier + ['@identifier'] = xPlayer.identifier }, function(isDead) if isDead then - print(('[esx_ambulancejob] [^2INFO^7] "%s" attempted combat logging'):format(identifier)) + print(('[esx_ambulancejob] [^2INFO^7] "%s" attempted combat logging'):format(xPlayer.identifier)) end cb(isDead) @@ -307,11 +298,11 @@ end) RegisterNetEvent('esx_ambulancejob:setDeathStatus') AddEventHandler('esx_ambulancejob:setDeathStatus', function(isDead) - local identifier = GetPlayerIdentifiers(source)[1] + local xPlayer = ESX.GetPlayerFromId(source) if type(isDead) == 'boolean' then MySQL.Sync.execute('UPDATE users SET is_dead = @isDead WHERE identifier = @identifier', { - ['@identifier'] = identifier, + ['@identifier'] = xPlayer.identifier, ['@isDead'] = isDead }) end From 2821e1ee1f7df34db3876b03dd1f9988e8d2f1fd Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 21:24:19 +0100 Subject: [PATCH 2558/3224] Support for latest ESX --- server/main.lua | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/server/main.lua b/server/main.lua index 4ebad086..94cecd05 100644 --- a/server/main.lua +++ b/server/main.lua @@ -28,11 +28,12 @@ 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) VALUES (@owner, @plate, @vehicle, @type)', { + MySQL.Async.execute('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), - ['@type'] = 'boat' + ['@type'] = 'boat', + ['@stored'] = true }, function(rowsChanged) cb(true) end) @@ -44,25 +45,29 @@ end) 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', { ['@stored'] = false, - ['@owner'] = GetPlayerIdentifiers(source)[1], + ['@owner'] = xPlayer.identifier, ['@plate'] = plate }, function(rowsChanged) if rowsChanged == 0 then - print(('esx_boat: %s exploited the garage!'):format(GetPlayerIdentifiers(source)[1])) + print(('esx_boat: %s exploited the garage!'):format(xPlayer.identifier)) end end) 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', { ['@stored'] = true, - ['@owner'] = GetPlayerIdentifiers(source)[1], + ['@owner'] = xPlayer.identifier, ['@plate'] = plate }, function(rowsChanged) if rowsChanged == 0 then - print(('esx_boat: %s attempted to store an boat they don\'t own!'):format(GetPlayerIdentifiers(source)[1])) + print(('esx_boat: %s attempted to store an boat they don\'t own!'):format(xPlayer.identifier)) end cb(rowsChanged) @@ -70,8 +75,10 @@ ESX.RegisterServerCallback('esx_boat:storeVehicle', function (source, cb, plate) 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', { - ['@owner'] = GetPlayerIdentifiers(source)[1], + ['@owner'] = xPlayer.identifier, ['@type'] = 'boat', ['@stored'] = true }, function(result) From e957ab62dafc95ed383e9b2e17d2f049d8a101e7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 21:44:14 +0100 Subject: [PATCH 2559/3224] Added missing sql file --- README.md | 3 ++- esx_skin.sql | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 esx_skin.sql diff --git a/README.md b/README.md index dc324102..64e2b8fc 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ git clone https://github.com/ESX-Org/esx_skin [esx]/esx_skin - Put it in the `[esx]` directory ## Installation +- Import `esx_skin.sql` to your database - Add this in your `server.cfg`: ``` @@ -31,7 +32,7 @@ start esx_skin ### License esx_skin - skin selector for ESX -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. diff --git a/esx_skin.sql b/esx_skin.sql new file mode 100644 index 00000000..43339a25 --- /dev/null +++ b/esx_skin.sql @@ -0,0 +1 @@ +ALTER TABLE `users` ADD COLUMN `skin` LONGTEXT NULL DEFAULT NULL; \ No newline at end of file From a27e3383b6b980582607a189e9343fb59e4c85de Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 21:51:16 +0100 Subject: [PATCH 2560/3224] Update main.lua --- server/main.lua | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/server/main.lua b/server/main.lua index ee80b636..acac591a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -60,15 +60,10 @@ ESX.RegisterServerCallback('esx_skin:getPlayerSkin', function(source, cb) end) end) --- Commands -TriggerEvent('es:addGroupCommand', 'skin', 'admin', function(source, args, user) - TriggerClientEvent('esx_skin:openSaveableMenu', source) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('skin')}) +ESX.RegisterCommand('skin', 'admin', function(xPlayer, args, showError) + xPlayer.triggerEvent('esx_skin:openSaveableMenu') +end, false, {help = _U('skin')}) -TriggerEvent('es:addGroupCommand', 'skinsave', 'admin', function(source, args, user) - TriggerClientEvent('esx_skin:requestSaveSkin', source) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('saveskin')}) +ESX.RegisterCommand('skinsave', 'admin', function(xPlayer, args, showError) + xPlayer.triggerEvent('esx_skin:requestSaveSkin') +end, false, {help = _U('saveskin')}) From 02f1e4082f68fb6c7bea280dec2c544015651ff0 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 21:52:26 +0100 Subject: [PATCH 2561/3224] Fix for latest ESX --- server/main.lua | 85 ++++++++++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 37 deletions(-) diff --git a/server/main.lua b/server/main.lua index 92497842..8d8a8303 100644 --- a/server/main.lua +++ b/server/main.lua @@ -3,33 +3,45 @@ ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) function AddLicense(target, type, cb) - local identifier = GetPlayerIdentifier(target, 0) + local xPlayer = ESX.GetPlayerFromId(target) - MySQL.Async.execute('INSERT INTO user_licenses (type, owner) VALUES (@type, @owner)', { - ['@type'] = type, - ['@owner'] = identifier - }, function(rowsChanged) - if cb ~= nil then + if xPlayer then + MySQL.Async.execute('INSERT INTO user_licenses (type, owner) VALUES (@type, @owner)', { + ['@type'] = type, + ['@owner'] = xPlayer.identifier + }, function(rowsChanged) + if cb then + cb() + end + end) + else + if cb then cb() end - end) + end end function RemoveLicense(target, type, cb) - local identifier = GetPlayerIdentifier(target, 0) + local xPlayer = ESX.GetPlayerFromId(target) - MySQL.Async.execute('DELETE FROM user_licenses WHERE type = @type AND owner = @owner', { - ['@type'] = type, - ['@owner'] = identifier - }, function(rowsChanged) - if cb ~= nil then + if xPlayer then + MySQL.Async.execute('DELETE FROM user_licenses WHERE type = @type AND owner = @owner', { + ['@type'] = type, + ['@owner'] = xPlayer.identifier + }, function(rowsChanged) + if cb then + cb() + end + end) + else + if cb then cb() end - end) + end end function GetLicense(type, cb) - MySQL.Async.fetchAll('SELECT * FROM licenses WHERE type = @type', { + MySQL.Async.fetchAll('SELECT label FROM licenses WHERE type = @type', { ['@type'] = type }, function(result) local data = { @@ -42,19 +54,17 @@ function GetLicense(type, cb) end function GetLicenses(target, cb) - local identifier = GetPlayerIdentifier(target, 0) + local xPlayer = ESX.GetPlayerFromId(target) - MySQL.Async.fetchAll('SELECT * FROM user_licenses WHERE owner = @owner', { - ['@owner'] = identifier + MySQL.Async.fetchAll('SELECT type FROM user_licenses WHERE owner = @owner', { + ['@owner'] = xPlayer.identifier }, function(result) - local licenses = {} - local asyncTasks = {} + local licenses, asyncTasks = {}, {} for i=1, #result, 1 do - local scope = function(type) table.insert(asyncTasks, function(cb) - MySQL.Async.fetchAll('SELECT * FROM licenses WHERE type = @type', { + MySQL.Async.fetchAll('SELECT label FROM licenses WHERE type = @type', { ['@type'] = type }, function(result2) table.insert(licenses, { @@ -68,34 +78,35 @@ function GetLicenses(target, cb) end scope(result[i].type) - end Async.parallel(asyncTasks, function(results) cb(licenses) end) - end) end function CheckLicense(target, type, cb) - local identifier = GetPlayerIdentifier(target, 0) + local xPlayer = ESX.GetPlayerFromId(target) - MySQL.Async.fetchAll('SELECT COUNT(*) as count FROM user_licenses WHERE type = @type AND owner = @owner', { - ['@type'] = type, - ['@owner'] = identifier - }, function(result) - if tonumber(result[1].count) > 0 then - cb(true) - else - cb(false) - end - - end) + 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 + cb(true) + else + cb(false) + end + end) + else + cb(false) + end end function GetLicensesList(cb) - MySQL.Async.fetchAll('SELECT * FROM licenses', { + MySQL.Async.fetchAll('SELECT type, label FROM licenses', { ['@type'] = type }, function(result) local licenses = {} From ef84cb54d2519a638963e374d5c0a4eed22d11ae Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 21:52:50 +0100 Subject: [PATCH 2562/3224] Dont select * --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index b7a2d509..5ab094c3 100644 --- a/server/main.lua +++ b/server/main.lua @@ -4,7 +4,7 @@ local availableJobs = {} TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) MySQL.ready(function() - MySQL.Async.fetchAll('SELECT * FROM jobs WHERE whitelisted = @whitelisted', { + MySQL.Async.fetchAll('SELECT name, label FROM jobs WHERE whitelisted = @whitelisted', { ['@whitelisted'] = false }, function(result) for i=1, #result, 1 do From 7a4968a6e0b0104f424591b6772730c6e7c72581 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 21:53:39 +0100 Subject: [PATCH 2563/3224] Fix for latest ESX --- README.md | 2 +- server/main.lua | 33 ++++++--------------------------- 2 files changed, 7 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 6e4a7189..d1d13813 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ start esx_basicneeds ### License esx_basicneeds - thirst and hunger system -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. diff --git a/server/main.lua b/server/main.lua index bddea2ca..a3fa31e0 100644 --- a/server/main.lua +++ b/server/main.lua @@ -4,7 +4,6 @@ TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) ESX.RegisterUsableItem('bread', function(source) local xPlayer = ESX.GetPlayerFromId(source) - xPlayer.removeInventoryItem('bread', 1) TriggerClientEvent('esx_status:add', source, 'hunger', 200000) @@ -14,7 +13,6 @@ end) ESX.RegisterUsableItem('water', function(source) local xPlayer = ESX.GetPlayerFromId(source) - xPlayer.removeInventoryItem('water', 1) TriggerClientEvent('esx_status:add', source, 'thirst', 200000) @@ -22,28 +20,9 @@ ESX.RegisterUsableItem('water', function(source) xPlayer.showNotification(_U('used_water')) end) -TriggerEvent('es:addGroupCommand', 'heal', 'admin', function(source, args, user) - -- heal another player - don't heal source - if args[1] then - local playerId = tonumber(args[1]) - - -- is the argument a number? - if playerId then - -- is the number a valid player? - if GetPlayerName(playerId) then - print(('esx_basicneeds: %s healed %s'):format(GetPlayerIdentifier(source, 0), GetPlayerIdentifier(playerId, 0))) - TriggerClientEvent('esx_basicneeds:healPlayer', playerId) - TriggerClientEvent('chat:addMessage', source, { args = { '^5HEAL', 'You have been healed.' } }) - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) - end - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid player id.' } }) - end - else - print(('esx_basicneeds: %s healed self'):format(GetPlayerIdentifier(source, 0))) - TriggerClientEvent('esx_basicneeds:healPlayer', source) - end -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = 'Heal a player, or yourself - restores thirst, hunger and health.', params = {{name = 'playerId', help = '(optional) player id'}}}) +ESX.RegisterCommand('heal', 'admin', function(xPlayer, args, showError) + args.playerId.triggerEvent('esx_basicneeds:healPlayer') + args.playerId.triggerEvent('chat:addMessage', {args = {'^5HEAL', 'You have been healed.'}}) +end, true, {help = 'Heal a player, or yourself - restores thirst, hunger and health.', validate = true, arguments = { + {name = 'playerId', help = 'the player id', type = 'player'} +}}) From 74347293c0530ce2aaf8dd74f68ca30d15b4d5c7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 21:53:54 +0100 Subject: [PATCH 2564/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ea1dceab..a0018489 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ start esx_barbershop ### License esx_barbershop - barber shop! -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. From c8625fad65a73721faea1f36c3314ae14204797a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 21:54:11 +0100 Subject: [PATCH 2565/3224] Minor edits --- README.md | 2 +- client/main.lua | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ae11cc3d..5ce9a720 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ start esx_bankerjob ### License esx_bankerjob - bank script -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. diff --git a/client/main.lua b/client/main.lua index 8ec0e10c..36467b27 100644 --- a/client/main.lua +++ b/client/main.lua @@ -26,8 +26,8 @@ end) function OpenBankActionsMenu() local elements = { - { label = _U('customers'), value = 'customers' }, - { label = _U('billing'), value = 'billing' } + {label = _U('customers'), value = 'customers'}, + {label = _U('billing'), value = 'billing'} } if ESX.PlayerData.job.grade_name == 'boss' then From 84b061a1fbf7e17875a1c9d35013832654e4809e Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 21:54:47 +0100 Subject: [PATCH 2566/3224] Minor edits --- README.md | 2 +- config.lua | 64 +++++++++++++++++++++++++++--------------------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index e21c4e36..199b94db 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ start esx_lscustom ### License esx_lscustoms - The best LS Custom out there for FX -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. diff --git a/config.lua b/config.lua index c633e2fa..c2881bbf 100644 --- a/config.lua +++ b/config.lua @@ -53,19 +53,19 @@ Config.Zones = { } Config.Colors = { - { label = _U('black'), value = 'black'}, - { label = _U('white'), value = 'white'}, - { label = _U('grey'), value = 'grey'}, - { label = _U('red'), value = 'red'}, - { label = _U('pink'), value = 'pink'}, - { label = _U('blue'), value = 'blue'}, - { label = _U('yellow'), value = 'yellow'}, - { label = _U('green'), value = 'green'}, - { label = _U('orange'), value = 'orange'}, - { label = _U('brown'), value = 'brown'}, - { label = _U('purple'), value = 'purple'}, - { label = _U('chrome'), value = 'chrome'}, - { label = _U('gold'), value = 'gold'} + {label = _U('black'), value = 'black'}, + {label = _U('white'), value = 'white'}, + {label = _U('grey'), value = 'grey'}, + {label = _U('red'), value = 'red'}, + {label = _U('pink'), value = 'pink'}, + {label = _U('blue'), value = 'blue'}, + {label = _U('yellow'), value = 'yellow'}, + {label = _U('green'), value = 'green'}, + {label = _U('orange'), value = 'orange'}, + {label = _U('brown'), value = 'brown'}, + {label = _U('purple'), value = 'purple'}, + {label = _U('chrome'), value = 'chrome'}, + {label = _U('gold'), value = 'gold'} } function GetColors(color) @@ -401,25 +401,25 @@ end function GetNeons() local neons = { - { label = _U('white'), r = 255, g = 255, b = 255}, - { label = "Slate Gray", r = 112, g = 128, b = 144}, - { label = "Blue", r = 0, g = 0, b = 255}, - { label = "Light Blue", r = 0, g = 150, b = 255}, - { label = "Navy Blue", r = 0, g = 0, b = 128}, - { label = "Sky Blue", r = 135, g = 206, b = 235}, - { label = "Turquoise", r = 0, g = 245, b = 255}, - { label = "Mint Green", r = 50, g = 255, b = 155}, - { label = "Lime Green", r = 0, g = 255, b = 0}, - { label = "Olive", r = 128, g = 128, b = 0}, - { label = _U('yellow'), r = 255, g = 255, b = 0}, - { label = _U('gold'), r = 255, g = 215, b = 0}, - { label = _U('orange'), r = 255, g = 165, b = 0}, - { label = _U('wheat'), r = 245, g = 222, b = 179}, - { label = _U('red'), r = 255, g = 0, b = 0}, - { label = _U('pink'), r = 255, g = 161, b = 211}, - { label = _U('brightpink'), r = 255, g = 0, b = 255}, - { label = _U('purple'), r = 153, g = 0, b = 153}, - { label = "Ivory", r = 41, g = 36, b = 33} + {label = _U('white'), r = 255, g = 255, b = 255}, + {label = "Slate Gray", r = 112, g = 128, b = 144}, + {label = "Blue", r = 0, g = 0, b = 255}, + {label = "Light Blue", r = 0, g = 150, b = 255}, + {label = "Navy Blue", r = 0, g = 0, b = 128}, + {label = "Sky Blue", r = 135, g = 206, b = 235}, + {label = "Turquoise", r = 0, g = 245, b = 255}, + {label = "Mint Green", r = 50, g = 255, b = 155}, + {label = "Lime Green", r = 0, g = 255, b = 0}, + {label = "Olive", r = 128, g = 128, b = 0}, + {label = _U('yellow'), r = 255, g = 255, b = 0}, + {label = _U('gold'), r = 255, g = 215, b = 0}, + {label = _U('orange'), r = 255, g = 165, b = 0}, + {label = _U('wheat'), r = 245, g = 222, b = 179}, + {label = _U('red'), r = 255, g = 0, b = 0}, + {label = _U('pink'), r = 255, g = 161, b = 211}, + {label = _U('brightpink'), r = 255, g = 0, b = 255}, + {label = _U('purple'), r = 153, g = 0, b = 153}, + {label = "Ivory", r = 41, g = 36, b = 33} } return neons From 67aa4df06558f04ea7911e7ae3be2ae222e1dbf1 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 21:55:11 +0100 Subject: [PATCH 2567/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 53522b3f..b10470a1 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ start esx_menu_dialog ### License esx_menu_dialog - input dialog for ESX -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. From c4c88a9afd475074213d2586d09ac091c389c369 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 21:55:21 +0100 Subject: [PATCH 2568/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index deb8039f..80093819 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ start esx_menu_list ### License esx_menu_list - advanced menu inputs for ESX -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. From b1fc7b392ed66a30fcdad564f45fdaab18ea5203 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 21:57:00 +0100 Subject: [PATCH 2569/3224] Fixed security issue --- server/main.lua | 76 ++++++++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/server/main.lua b/server/main.lua index 3955bd95..014d19b8 100644 --- a/server/main.lua +++ b/server/main.lua @@ -322,52 +322,52 @@ ESX.RegisterServerCallback('esx_vehicleshop:giveBackVehicle', function(source, c end) ESX.RegisterServerCallback('esx_vehicleshop:resellVehicle', function(source, cb, plate, model) - local resellPrice + local xPlayer, resellPrice = ESX.GetPlayerFromId(source) - -- calculate the resell price - for i=1, #vehicles, 1 do - if GetHashKey(vehicles[i].model) == model then - resellPrice = ESX.Math.Round(vehicles[i].price / 100 * Config.ResellPercentage) - break + if xPlayer.job.name == 'cardealer' then + -- calculate the resell price + for i=1, #vehicles, 1 do + if GetHashKey(vehicles[i].model) == model then + resellPrice = ESX.Math.Round(vehicles[i].price / 100 * Config.ResellPercentage) + break + end end - end - if not resellPrice then - print(('[esx_vehicleshop] [^3WARNING^7] %s attempted to sell an unknown vehicle!'):format(GetPlayerIdentifiers(source)[1])) - 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? - cb(false) -- it is, don't let the player sell it since he doesn't own it - else - local xPlayer = ESX.GetPlayerFromId(source) + if not resellPrice then + 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? + 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.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) - - if vehicle.model == model then - if vehicle.plate == plate then - xPlayer.addMoney(resellPrice) - RemoveOwnedVehicle(plate) - cb(true) + if vehicle.model == model then + if vehicle.plate == plate then + xPlayer.addMoney(resellPrice) + RemoveOwnedVehicle(plate) + cb(true) + else + print(('[esx_vehicleshop] [^3WARNING^7] %s attempted to sell an vehicle with plate mismatch!'):format(xPlayer.identifier)) + cb(false) + end else - print(('[esx_vehicleshop] [^3WARNING^7] %s attempted to sell an vehicle with plate mismatch!'):format(xPlayer.identifier)) + print(('[esx_vehicleshop] [^3WARNING^7] %s attempted to sell an vehicle with model mismatch!'):format(xPlayer.identifier)) cb(false) end - else - print(('[esx_vehicleshop] [^3WARNING^7] %s attempted to sell an vehicle with model mismatch!'):format(xPlayer.identifier)) - cb(false) end - end - end) - end - end) + end) + end + end) + end end end) From 7c0290649b575dc4c20936a01490ff7e3ed5d0ef Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 21:57:35 +0100 Subject: [PATCH 2570/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 847aea6c..21d5fdb5 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ git clone https://github.com/ESX-Org/esx_realestateagentjob [esx]/esx_realestate ### License esx_realestateagentjob - real estate job -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. From c73b222a1e3d04f8f1b87a79e7a6e006190d601c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 22:12:33 +0100 Subject: [PATCH 2571/3224] Code cleanup --- README.md | 2 +- esx_whitelist.sql | 2 +- locales/en.lua | 2 +- locales/fr.lua | 2 +- locales/sv.lua | 2 +- server/commands.lua | 48 +++++++++++++++------------------------------ server/main.lua | 48 ++++++++++++++++++++------------------------- 7 files changed, 42 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index a1c2d105..c4acb4fb 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ start esx_whitelist ### License esx_whitelist - Whitelist script -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. diff --git a/esx_whitelist.sql b/esx_whitelist.sql index 2798b56a..bcdddb77 100644 --- a/esx_whitelist.sql +++ b/esx_whitelist.sql @@ -1,7 +1,7 @@ USE `essentialmode`; CREATE TABLE `whitelist` ( - `identifier` varchar(60) NOT NULL, + `identifier` varchar(40) NOT NULL, PRIMARY KEY (`identifier`) ); diff --git a/locales/en.lua b/locales/en.lua index ad20b913..8b7443c6 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,8 +1,8 @@ Locales['en'] = { ['whitelist_check'] = 'making sure you\'re whitelisted on this server . . .', ['not_whitelisted'] = 'you are not whitelisted on this server', - ['steamid_error'] = 'your Steam ID was not found, is Steam running?', ['whitelist_empty'] = 'the whitelist hasn\'t been loaded yet, or alternatively no one has been whitelisted!', + ['license_missing'] = 'your license could not be found', ['help_whitelist_add'] = 'add someone to the whitelist', ['help_whitelist_load'] = 'reload the whitelist', } diff --git a/locales/fr.lua b/locales/fr.lua index 59a3f71e..028ba663 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,8 +1,8 @@ Locales['fr'] = { ['whitelist_check'] = 'making sure you\'re whitelisted on this server . . .', ['not_whitelisted'] = 'ceci est un serveur avec whitelist', - ['steamid_error'] = 'nous n\'arrivons pas à lire votre SteamID', ['whitelist_empty'] = 'the whitelist hasn\'t been loaded yet, or alternatively no one has been whitelisted!', + ['license_missing'] = 'your license could not be found', ['help_whitelist_add'] = 'ajouter quelqu\'un dans la Whitelist', ['help_whitelist_load'] = 'recharger la Whitelist', } diff --git a/locales/sv.lua b/locales/sv.lua index 918f1461..6270ffb0 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -1,8 +1,8 @@ Locales['sv'] = { ['whitelist_check'] = 'making sure you\'re whitelisted on this server . . .', ['not_whitelisted'] = 'du är inte whitelistad på denna server!', - ['steamid_error'] = 'ditt Steam ID kunde ej hittas, är Steam påslaget?', ['whitelist_empty'] = 'whitelisten har ännu inte laddats in, eller så är ingen whitelitad!', + ['license_missing'] = 'din licens kunde ej hittas', ['help_whitelist_add'] = 'lägg till någon till whitelisten', ['help_whitelist_load'] = 'ladda om whitelist', } diff --git a/server/commands.lua b/server/commands.lua index c05873bb..ef87f319 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -1,42 +1,26 @@ -TriggerEvent('es:addGroupCommand', 'wlrefresh', 'admin', function (source, args, user) +ESX.RegisterCommand('wlrefresh', 'admin', function(xPlayer, args, showError) loadWhiteList(function() - TriggerEvent('esx_whitelist:sendMessage', source, 'Whitelist', 'Whitelist reloaded') + showError('Whitelist reloaded') end) -end, function (source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficienct permissions!' } }) -end, { help = _U('help_whitelist_load') }) +end, true, {help = _U('help_whitelist_load')}) -TriggerEvent('es:addGroupCommand', 'wladd', 'admin', function (source, args, user) - local steamID = 'steam:' .. args[1]:lower() +ESX.RegisterCommand('wladd', 'admin', function(xPlayer, args, showError) + args.license = args.license:lower() - if string.len(steamID) ~= 21 then - TriggerEvent('esx_whitelist:sendMessage', source, '^1SYSTEM', 'Invalid steam ID length!') - return - end - - MySQL.Async.fetchAll('SELECT * FROM whitelist WHERE identifier = @identifier', { - ['@identifier'] = steamID - }, function(result) - if result[1] ~= nil then - TriggerEvent('esx_whitelist:sendMessage', source, '^1SYSTEM', 'The player is already whitelisted on this server!') + if string.len(args.license) == 40 then + if WhiteList[args.license] then + showError('The player is already whitelisted on this server!') else MySQL.Async.execute('INSERT INTO whitelist (identifier) VALUES (@identifier)', { - ['@identifier'] = steamID - }, function (rowsChanged) - table.insert(WhiteList, steamID) - TriggerEvent('esx_whitelist:sendMessage', source, 'Whitelist', 'The player has been whitelisted!') + ['@identifier'] = args.license + }, function(rowsChanged) + WhiteList[args.license] = true + showError('The player has been whitelisted!') end) end - end) -end, function (source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficienct permissions!' } }) -end, { help = _U('help_whitelist_add'), params = { steam = 'SteamID', help = 'SteamID formated to hex, begins with 11' }}) - --- console / rcon can also utilize es:command events, but breaks since the source isn't a connected player, ending up in error messages -AddEventHandler('esx_whitelist:sendMessage', function(source, title, message) - if source ~= 0 then - TriggerClientEvent('chat:addMessage', source, { args = { title, message } }) else - print('esx_whitelist: ' .. message) + showError('Invalid steam ID length!') end -end) \ No newline at end of file +end, true, {help = _U('help_whitelist_add'), validate = true, arguments = { + {name = 'license', help = 'the player license', type = 'string'} +}}) diff --git a/server/main.lua b/server/main.lua index 33a6c76c..d239c7c6 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,14 +1,14 @@ -WhiteList = {} +WhiteList = {} function loadWhiteList(cb) Whitelist = {} - MySQL.Async.fetchAll('SELECT * FROM whitelist', {}, function (identifiers) - for i=1, #identifiers, 1 do - table.insert(WhiteList, tostring(identifiers[i].identifier):lower()) + MySQL.Async.fetchAll('SELECT identifier FROM whitelist', {}, function(result) + for k,v in ipairs(result) do + WhiteList[v.identifier] = true end - if cb ~= nil then + if cb then cb() end end) @@ -22,7 +22,7 @@ AddEventHandler('playerConnecting', function(name, setCallback, deferrals) -- Mark this connection as deferred, this is to prevent problems while checking player identifiers. deferrals.defer() - local _source = source + local playerId, kickReason, identifier = source -- Letting the user know what's going on. deferrals.update(_U('whitelist_check')) @@ -30,30 +30,24 @@ AddEventHandler('playerConnecting', function(name, setCallback, deferrals) -- Needed, not sure why. Citizen.Wait(100) - local whitelisted, kickReason, steamID = false, nil, GetPlayerIdentifiers(_source)[1] - - if #WhiteList == 0 then - kickReason = _U('whitelist_empty') - elseif not string.match(steamID, 'steam:1') then - kickReason = _U('steamid_error') - else - - for i = 1, #WhiteList, 1 do - if tostring(WhiteList[i]) == tostring(steamID) then - whitelisted = true - break - end + for k,v in ipairs(GetPlayerIdentifiers(playerId)) do + if string.match(v, 'license:') then + identifier = string.sub(v, 9) + break end - - if not whitelisted then - kickReason = _U('not_whitelisted') - end - end - if whitelisted then - deferrals.done() - else + if ESX.Table.SizeOf(WhiteList) == 0 then + kickReason = _U('whitelist_empty') + elseif not identifier then + kickReason = _U('license_missing') + elseif not WhiteList[identifier] then + kickReason = _U('not_whitelisted') + end + + if kickReason then deferrals.done(kickReason) + else + deferrals.done() end end) From c2e63b08009665f131ffa22dd7b2f5d44a7e7643 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 22:47:25 +0100 Subject: [PATCH 2572/3224] Fixed commands not registering --- server/commands.lua | 2 +- server/main.lua | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/server/commands.lua b/server/commands.lua index ef87f319..70bfd3e0 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -19,7 +19,7 @@ ESX.RegisterCommand('wladd', 'admin', function(xPlayer, args, showError) end) end else - showError('Invalid steam ID length!') + showError('Invalid license ID length!') end end, true, {help = _U('help_whitelist_add'), validate = true, arguments = { {name = 'license', help = 'the player license', type = 'string'} diff --git a/server/main.lua b/server/main.lua index d239c7c6..54c693a1 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,4 +1,6 @@ -WhiteList = {} +ESX, WhiteList = nil, {} + +TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) function loadWhiteList(cb) Whitelist = {} From 4b648a8bef4bd897891abd5508d5f4e5a1f63331 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 22:48:44 +0100 Subject: [PATCH 2573/3224] Override existing commands, and fixed rare bug with cb args all nil --- server/functions.lua | 150 ++++++++++++++++++++++--------------------- 1 file changed, 77 insertions(+), 73 deletions(-) diff --git a/server/functions.lua b/server/functions.lua index 6cfd5860..e9f0d5be 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -30,103 +30,107 @@ ESX.RegisterCommand = function(name, group, cb, allowConsole, suggestion) end if ESX.RegisteredCommands[name] then - print(('[es_extended] [^3WARNING^7] An command "%s" is already registered'):format(name)) - else - if suggestion then - if not suggestion.arguments then suggestion.arguments = {} end - if not suggestion.help then suggestion.help = '' end - end + print(('[es_extended] [^3WARNING^7] An command "%s" is already registered, overriding command'):format(name)) + end - ESX.RegisteredCommands[name] = {group = group, cb = cb, allowConsole = allowConsole, suggestion = suggestion} + if suggestion then + if not suggestion.arguments then suggestion.arguments = {} end + if not suggestion.help then suggestion.help = '' end + end - RegisterCommand(name, function(playerId, args, rawCommand) - local command = ESX.RegisteredCommands[name] + ESX.RegisteredCommands[name] = {group = group, cb = cb, allowConsole = allowConsole, suggestion = suggestion} - if not command.allowConsole and playerId == 0 then - print('[es_extended] [^3WARNING^7] That command can not be run from console') - else - local xPlayer, error = ESX.GetPlayerFromId(playerId), nil + RegisterCommand(name, function(playerId, args, rawCommand) + local command = ESX.RegisteredCommands[name] - if command.suggestion then - if command.suggestion.validate then - if #args ~= #command.suggestion.arguments then - error = ('Argument count mismatch (passed %s, wanted %s)'):format(#args, #command.suggestion.arguments) - end + if not command.allowConsole and playerId == 0 then + print('[es_extended] [^3WARNING^7] That command can not be run from console') + else + local xPlayer, error = ESX.GetPlayerFromId(playerId), nil + + if command.suggestion then + if command.suggestion.validate then + if #args ~= #command.suggestion.arguments then + error = ('Argument count mismatch (passed %s, wanted %s)'):format(#args, #command.suggestion.arguments) end + end - if not error and command.suggestion.arguments then - local newArgs = {} + if not error and command.suggestion.arguments then + local newArgs = {} - for k,v in ipairs(command.suggestion.arguments) do - if v.type then - if v.type == 'number' then - local newArg = tonumber(args[k]) + for k,v in ipairs(command.suggestion.arguments) do + if v.type then + if v.type == 'number' then + local newArg = tonumber(args[k]) - if newArg then - newArgs[v.name] = newArg - else - error = ('Argument #%s type mismatch (passed string, wanted number)'):format(k) - end - elseif v.type == 'player' then - local targetPlayer = tonumber(args[k]) + if newArg then + newArgs[v.name] = newArg + else + error = ('Argument #%s type mismatch (passed string, wanted number)'):format(k) + end + elseif v.type == 'player' or v.type == 'playerId' then + local targetPlayer = tonumber(args[k]) - if targetPlayer then - local xTargetPlayer = ESX.GetPlayerFromId(targetPlayer) + if targetPlayer then + local xTargetPlayer = ESX.GetPlayerFromId(targetPlayer) - if xTargetPlayer then + if xTargetPlayer then + if v.type == 'player' then newArgs[v.name] = xTargetPlayer else - error = 'Player not online' + newArgs[v.name] = targetPlayer end else - error = ('Argument #%s type mismatch (passed string, wanted number)'):format(k) + error = 'Player not online' end - elseif v.type == 'string' then - newArgs[v.name] = args[k] - elseif v.type == 'item' then - if ESX.Items[args[k]] then - newArgs[v.name] = args[k] - else - error = _U('invalid_item') - end - elseif v.type == 'weapon' then - if ESX.GetWeapon(args[k]) then - newArgs[v.name] = string.upper(args[k]) - else - error = 'Invalid weapon' - end - elseif v.type == 'any' then - newArgs[v.name] = args[k] + else + error = ('Argument #%s type mismatch (passed string, wanted number)'):format(k) end + elseif v.type == 'string' then + newArgs[v.name] = args[k] + elseif v.type == 'item' then + if ESX.Items[args[k]] then + newArgs[v.name] = args[k] + else + error = _U('invalid_item') + end + elseif v.type == 'weapon' then + if ESX.GetWeapon(args[k]) then + newArgs[v.name] = string.upper(args[k]) + else + error = 'Invalid weapon' + end + elseif v.type == 'any' then + newArgs[v.name] = args[k] end - - if error then break end end - args = newArgs + if error then break end end - end - if error then - if playerId == 0 then - print(('[es_extended] [^3WARNING^7] %s^7'):format(error)) - else - xPlayer.triggerEvent('chat:addMessage', {args = {'^1SYSTEM', error}}) - end - else - cb(xPlayer, args, function(msg) - if playerId == 0 then - print(('[es_extended] [^3WARNING^7] %s^7'):format(msg)) - else - xPlayer.triggerEvent('chat:addMessage', {args = {'^1SYSTEM', msg}}) - end - end) + args = newArgs end end - end, true) - ExecuteCommand(('add_ace group.%s command.%s allow'):format(group, name)) - end + if error then + if playerId == 0 then + print(('[es_extended] [^3WARNING^7] %s^7'):format(error)) + else + xPlayer.triggerEvent('chat:addMessage', {args = {'^1SYSTEM', error}}) + end + else + cb(xPlayer or false, args, function(msg) + if playerId == 0 then + print(('[es_extended] [^3WARNING^7] %s^7'):format(msg)) + else + xPlayer.triggerEvent('chat:addMessage', {args = {'^1SYSTEM', msg}}) + end + end) + end + end + end, true) + + ExecuteCommand(('add_ace group.%s command.%s allow'):format(group, name)) end ESX.ClearTimeout = function(id) From 107634913af69a49a28f59c47c8b0e2d9dc8eeac Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 22:57:44 +0100 Subject: [PATCH 2574/3224] Fixed file --- locales/tr.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/tr.lua b/locales/tr.lua index 7eccb556..1b00002f 100644 --- a/locales/tr.lua +++ b/locales/tr.lua @@ -6,7 +6,7 @@ Locales['tr'] = { ['invalid_amount'] = 'Geçersiz miktar', ['press_to_access'] = 'Menüye erişmek için ~INPUT_CONTEXT~ tuşuna basın.', ['amount'] = 'Miktar', - ['no_play_near'] = 'Yakında kimse yok, + ['no_play_near'] = 'Yakında kimse yok', ['realtors'] = 'Emlak Bürosu çalışanları', ['boss_action'] = 'Patron eylemleri', ['client_poor'] = 'Müşterinin bunu ödeyecek kadar parası yok.', From 8a832aee3bed36c734d1a34705289c9a7b2a9416 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 23:07:18 +0100 Subject: [PATCH 2575/3224] Implemented adding chat suggestions, closes #512 --- client/main.lua | 9 +++++++++ server/functions.lua | 2 ++ 2 files changed, 11 insertions(+) diff --git a/client/main.lua b/client/main.lua index caccc586..fd2fc759 100644 --- a/client/main.lua +++ b/client/main.lua @@ -328,6 +328,15 @@ AddEventHandler('esx:createMissingPickups', function(missingPickups) end end) +RegisterNetEvent('esx:registerSuggestions') +AddEventHandler('esx:registerSuggestions', function(registeredCommands) + for name,command in pairs(registeredCommands) do + if command.suggestion then + TriggerEvent('chat:addSuggestion', ('/%s'):format(name), command.suggestion.help, command.suggestion.arguments) + end + end +end) + RegisterNetEvent('esx:removePickup') AddEventHandler('esx:removePickup', function(id) ESX.Game.DeleteObject(pickups[id].obj) diff --git a/server/functions.lua b/server/functions.lua index e9f0d5be..0abdb9a7 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -36,6 +36,8 @@ ESX.RegisterCommand = function(name, group, cb, allowConsole, suggestion) if suggestion then if not suggestion.arguments then suggestion.arguments = {} end if not suggestion.help then suggestion.help = '' end + + TriggerClientEvent('chat:addSuggestion', -1, ('/%s'):format(name), suggestion.help, suggestion.arguments) end ESX.RegisteredCommands[name] = {group = group, cb = cb, allowConsole = allowConsole, suggestion = suggestion} From 73a818aed94a319d26ffb0a028ea6254334d99f5 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 23:07:38 +0100 Subject: [PATCH 2576/3224] Implemented adding chat suggestions --- server/main.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/server/main.lua b/server/main.lua index 38bd8926..d1838418 100644 --- a/server/main.lua +++ b/server/main.lua @@ -186,6 +186,7 @@ function loadESXPlayer(identifier, playerId) }) xPlayer.triggerEvent('esx:createMissingPickups', ESX.Pickups) + xPlayer.triggerEvent('esx:registerSuggestions', ESX.RegisteredCommands) end) end) end From 21de2f9420cb439381f33b95e82f5c8423260c68 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 23:21:04 +0100 Subject: [PATCH 2577/3224] Remove suggestion on command override --- server/functions.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server/functions.lua b/server/functions.lua index 0abdb9a7..053f58e1 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -31,6 +31,10 @@ ESX.RegisterCommand = function(name, group, cb, allowConsole, suggestion) if ESX.RegisteredCommands[name] then print(('[es_extended] [^3WARNING^7] An command "%s" is already registered, overriding command'):format(name)) + + if ESX.RegisteredCommands[name].suggestion then + TriggerClientEvent('chat:removeSuggestion', -1, ('/%s'):format(name)) + end end if suggestion then From f074a1bca504b1195b732a085ddd8bc10d532b55 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 23:26:08 +0100 Subject: [PATCH 2578/3224] Update esx_addonaccount.sql --- esx_addonaccount.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_addonaccount.sql b/esx_addonaccount.sql index e0e25a81..fcbbb6b5 100644 --- a/esx_addonaccount.sql +++ b/esx_addonaccount.sql @@ -12,7 +12,7 @@ CREATE TABLE `addon_account_data` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `account_name` VARCHAR(100) DEFAULT NULL, `money` INT(11) NOT NULL, - `owner` VARCHAR(100) DEFAULT NULL, + `owner` VARCHAR(40) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE INDEX `index_addon_account_data_account_name_owner` (`account_name`, `owner`), From 113ebe790c7990f89d0bfb4de9f7c58c7a9935e8 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 23:26:14 +0100 Subject: [PATCH 2579/3224] Update esx_addoninventory.sql --- esx_addoninventory.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_addoninventory.sql b/esx_addoninventory.sql index 770cda76..eacaaff8 100644 --- a/esx_addoninventory.sql +++ b/esx_addoninventory.sql @@ -13,7 +13,7 @@ CREATE TABLE `addon_inventory_items` ( `inventory_name` VARCHAR(100) NOT NULL, `name` VARCHAR(100) NOT NULL, `count` INT(11) NOT NULL, - `owner` VARCHAR(60) DEFAULT NULL, + `owner` VARCHAR(40) DEFAULT NULL, PRIMARY KEY (`id`), INDEX `index_addon_inventory_items_inventory_name_name` (`inventory_name`, `name`), From 0bb08e6f3ef054d989140f289d15fe6cf47ec2e8 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 23:26:20 +0100 Subject: [PATCH 2580/3224] Update esx_billing.sql --- esx_billing.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/esx_billing.sql b/esx_billing.sql index a418175c..b57c4838 100644 --- a/esx_billing.sql +++ b/esx_billing.sql @@ -2,10 +2,10 @@ USE `essentialmode`; CREATE TABLE `billing` ( `id` int(11) NOT NULL AUTO_INCREMENT, - `identifier` varchar(255) NOT NULL, - `sender` varchar(255) NOT NULL, + `identifier` varchar(40) NOT NULL, + `sender` varchar(40) NOT NULL, `target_type` varchar(50) NOT NULL, - `target` varchar(255) NOT NULL, + `target` varchar(40) NOT NULL, `label` varchar(255) NOT NULL, `amount` int(11) NOT NULL, From 135e5ee8d228c8a882ecf9ab74484b1248dcbdbd Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 23:29:11 +0100 Subject: [PATCH 2581/3224] Fix for latest esx --- README.md | 3 ++- server/main.lua | 15 +++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 258d20ed..983abdd2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # esx_society + Society management for ESX. Adds employee management (hire, fire, promote / demote, change salary), society bank accounts and money washing. It's crucial that this script gets started before all resources that utilize societies do, or else many things will go wrong. ## Requirements @@ -52,7 +53,7 @@ end, {wash = false}) -- set custom options, e.g disable washing ### License esx_society - societies for ESX -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. diff --git a/server/main.lua b/server/main.lua index 4cb443e4..9960b071 100644 --- a/server/main.lua +++ b/server/main.lua @@ -272,10 +272,9 @@ ESX.RegisterServerCallback('esx_society:setJob', function(source, cb, identifier end) ESX.RegisterServerCallback('esx_society:setJobSalary', function(source, cb, job, grade, salary) - local isBoss = isPlayerBoss(source, job) - local identifier = GetPlayerIdentifier(source, 0) + local xPlayer = ESX.GetPlayerFromId(source) - if isBoss then + 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, @@ -286,21 +285,21 @@ ESX.RegisterServerCallback('esx_society:setJobSalary', function(source, cb, job, local xPlayers = ESX.GetPlayers() for i=1, #xPlayers, 1 do - local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + local xTarget = ESX.GetPlayerFromId(xPlayers[i]) - if xPlayer.job.name == job and xPlayer.job.grade == grade then - xPlayer.setJob(job, grade) + if xTarget.job.name == job and xTarget.job.grade == grade then + xTarget.setJob(job, grade) end end cb() end) else - print(('esx_society: %s attempted to setJobSalary over config limit!'):format(identifier)) + print(('esx_society: %s attempted to setJobSalary over config limit!'):format(xPlayer.identifier)) cb() end else - print(('esx_society: %s attempted to setJobSalary'):format(identifier)) + print(('esx_society: %s attempted to setJobSalary'):format(xPlayer.identifier)) cb() end end) From 67d1279039d507691acb1cbbdd503b683be274b5 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 23:30:39 +0100 Subject: [PATCH 2582/3224] Updated sql for new license length --- esx_vehicleshop.sql | 2 +- localization/br_esx_vehicleshop.sql | 2 +- localization/de_esx_vehicleshop.sql | 2 +- localization/en_esx_vehicleshop.sql | 2 +- localization/fi_esx_vehicleshop.sql | 2 +- localization/pl_esx_vehicleshop.sql | 2 +- localization/sv_esx_vehicleshop.sql | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/esx_vehicleshop.sql b/esx_vehicleshop.sql index 29ec7cae..eb70f9b2 100644 --- a/esx_vehicleshop.sql +++ b/esx_vehicleshop.sql @@ -38,7 +38,7 @@ CREATE TABLE `vehicle_sold` ( ); CREATE TABLE `owned_vehicles` ( - `owner` varchar(22) NOT NULL, + `owner` varchar(40) NOT NULL, `plate` varchar(12) NOT NULL, `vehicle` longtext, `type` VARCHAR(20) NOT NULL DEFAULT 'car', diff --git a/localization/br_esx_vehicleshop.sql b/localization/br_esx_vehicleshop.sql index 5a6db334..b693bc07 100644 --- a/localization/br_esx_vehicleshop.sql +++ b/localization/br_esx_vehicleshop.sql @@ -38,7 +38,7 @@ CREATE TABLE `vehicle_sold` ( ); CREATE TABLE `owned_vehicles` ( - `owner` varchar(22) NOT NULL, + `owner` varchar(40) NOT NULL, `plate` varchar(12) NOT NULL, `vehicle` longtext, `type` VARCHAR(20) NOT NULL DEFAULT 'car', diff --git a/localization/de_esx_vehicleshop.sql b/localization/de_esx_vehicleshop.sql index 2bdb37e7..65623800 100644 --- a/localization/de_esx_vehicleshop.sql +++ b/localization/de_esx_vehicleshop.sql @@ -38,7 +38,7 @@ CREATE TABLE `vehicle_sold` ( ); CREATE TABLE `owned_vehicles` ( - `owner` varchar(22) NOT NULL, + `owner` varchar(40) NOT NULL, `plate` varchar(12) NOT NULL, `vehicle` longtext, `type` VARCHAR(20) NOT NULL DEFAULT 'car', diff --git a/localization/en_esx_vehicleshop.sql b/localization/en_esx_vehicleshop.sql index ef2c803f..aec45099 100644 --- a/localization/en_esx_vehicleshop.sql +++ b/localization/en_esx_vehicleshop.sql @@ -38,7 +38,7 @@ CREATE TABLE `vehicle_sold` ( ); CREATE TABLE `owned_vehicles` ( - `owner` varchar(22) NOT NULL, + `owner` varchar(40) NOT NULL, `plate` varchar(12) NOT NULL, `vehicle` longtext, `type` VARCHAR(20) NOT NULL DEFAULT 'car', diff --git a/localization/fi_esx_vehicleshop.sql b/localization/fi_esx_vehicleshop.sql index 7d88a3c6..5194acb4 100644 --- a/localization/fi_esx_vehicleshop.sql +++ b/localization/fi_esx_vehicleshop.sql @@ -38,7 +38,7 @@ CREATE TABLE `vehicle_sold` ( ); CREATE TABLE `owned_vehicles` ( - `owner` varchar(22) NOT NULL, + `owner` varchar(40) NOT NULL, `plate` varchar(12) NOT NULL, `vehicle` longtext, `type` VARCHAR(20) NOT NULL DEFAULT 'car', diff --git a/localization/pl_esx_vehicleshop.sql b/localization/pl_esx_vehicleshop.sql index a0b1bd49..c94d1055 100644 --- a/localization/pl_esx_vehicleshop.sql +++ b/localization/pl_esx_vehicleshop.sql @@ -38,7 +38,7 @@ CREATE TABLE `vehicle_sold` ( ); CREATE TABLE `owned_vehicles` ( - `owner` varchar(22) NOT NULL, + `owner` varchar(40) NOT NULL, `plate` varchar(12) NOT NULL, `vehicle` longtext, `type` VARCHAR(20) NOT NULL DEFAULT 'car', diff --git a/localization/sv_esx_vehicleshop.sql b/localization/sv_esx_vehicleshop.sql index c52539e3..176b11ff 100644 --- a/localization/sv_esx_vehicleshop.sql +++ b/localization/sv_esx_vehicleshop.sql @@ -38,7 +38,7 @@ CREATE TABLE `vehicle_sold` ( ); CREATE TABLE `owned_vehicles` ( - `owner` varchar(22) NOT NULL, + `owner` varchar(40) NOT NULL, `plate` varchar(12) NOT NULL, `vehicle` longtext, `type` VARCHAR(20) NOT NULL DEFAULT 'car', From f0db3d57defcfd77fe0d0ef8737a10008dd990d8 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 23:30:54 +0100 Subject: [PATCH 2583/3224] Update esx_datastore.sql --- esx_datastore.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_datastore.sql b/esx_datastore.sql index 1fdd9049..feb0f6f1 100644 --- a/esx_datastore.sql +++ b/esx_datastore.sql @@ -11,7 +11,7 @@ CREATE TABLE `datastore` ( CREATE TABLE `datastore_data` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `name` VARCHAR(60) NOT NULL, - `owner` VARCHAR(60), + `owner` VARCHAR(40), `data` LONGTEXT, PRIMARY KEY (`id`), From fe3faa5c6c54490fc35d52433f04f56258c39467 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 23:31:11 +0100 Subject: [PATCH 2584/3224] Update esx_license.sql --- esx_license.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esx_license.sql b/esx_license.sql index 993eec50..21d90c46 100644 --- a/esx_license.sql +++ b/esx_license.sql @@ -10,7 +10,7 @@ CREATE TABLE `licenses` ( CREATE TABLE `user_licenses` ( `id` int(11) NOT NULL AUTO_INCREMENT, `type` varchar(60) NOT NULL, - `owner` varchar(60) NOT NULL, + `owner` varchar(40) NOT NULL, PRIMARY KEY (`id`) ); \ No newline at end of file From 4b95e6a2b0ad60b4626b724f740846fa69a37776 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Tue, 18 Feb 2020 22:33:46 +0100 Subject: [PATCH 2585/3224] Updated Czech locale (#515) * Update cs.lua * Fix --- locales/cs.lua | 325 ++++++++++++++++++++++++------------------------- 1 file changed, 162 insertions(+), 163 deletions(-) diff --git a/locales/cs.lua b/locales/cs.lua index de60f089..bc69b191 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -12,16 +12,16 @@ Locales['cs'] = { ['noammo'] = 'nemáte dostatek munice!', ['gave_item'] = 'dali jste ~y~%sx~s~ ~b~%s~s~ ~y~%s~s~', ['received_item'] = 'obdrželi jste ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', - ['gave_weapon'] = 'you gave ~b~%s~s~ to ~y~%s~s~', - ['gave_weapon_ammo'] = 'you gave ~o~%sx %s~s~ for ~b~%s~s~ to ~y~%s~s~', - ['gave_weapon_withammo'] = 'you gave ~b~%s~s~ with ~o~%sx %s~s~ to ~y~%s~s~', - ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', - ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', - ['received_weapon'] = 'you received ~b~%s~s~ from ~b~%s~s~', - ['received_weapon_ammo'] = 'you received ~o~%sx %s~s~ for your ~b~%s~s~ from ~b~%s~s~', - ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx %s~s~ from ~b~%s~s~', - ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', - ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['gave_weapon'] = 'dal jsi ~b~%s~s~ hráči ~y~%s~s~', + ['gave_weapon_ammo'] = 'dal jsi ~o~%sx %s~s~ za ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'dal jwi ~b~%s~s~ s ~o~%sx %s~s~ to ~y~%s~s~', + ['gave_weapon_hasalready'] = '~y~%s~s~ již má ~y~%s~s~', + ['gave_weapon_noweapon'] = '~y~%s~s~ nemá tuhle zbraň', + ['received_weapon'] = 'obdrzel jsi ~b~%s~s~ od ~b~%s~s~', + ['received_weapon_ammo'] = 'obdrzel jsi ~o~%sx %s~s~ za tvůj ~b~%s~s~ od ~b~%s~s~', + ['received_weapon_withammo'] = 'obdzel jsi ~b~%s~s~ s ~o~%sx %s~s~ od ~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~ se pokusil ti dat ~y~%s~s~, ale jiz tento predmet jednou mas', + ['received_weapon_noweapon'] = '~b~%s~s~ se pokusil ti dat naboje pro ~y~%s~s~, ale tuhle zbran nemas', ['gave_account_money'] = 'dali jste ~g~$%s~s~ (%s) ~y~%s~s~', ['received_account_money'] = 'obdrželi jste ~g~$%s~s~ (%s) od ~b~%s~s~', ['amount_invalid'] = 'neplatné množství', @@ -29,171 +29,170 @@ Locales['cs'] = { ['ex_inv_lim'] = 'akce není možná, překročen limit inventáře pro ~y~%s~s~', ['imp_invalid_quantity'] = 'akce není možná, neplatný počet', ['imp_invalid_amount'] = 'akce není možná, neplatné množství', - ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', - ['threw_weapon'] = 'you threw ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx %s~s~', - ['threw_weapon_already'] = 'you already carry the same weapon', - ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', - ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', + ['threw_standard'] = 'vyhodil jsi ~y~%sx~s~ ~b~%s~s~', + ['threw_account'] = 'vyhodil jsi ~g~$%s~s~ ~b~%s~s~', + ['threw_weapon'] = 'vzhodil jsi ~b~%s~s~', + ['threw_weapon_ammo'] = 'vyhodil jsi ~b~%s~s~ s ~o~%sx %s~s~', + ['threw_weapon_already'] = 'jiz stejnou zbraan mas', + ['threw_cannot_pickup'] = 'tohle nemuzes sebrat, protoze tvuj inventar je plny', + ['threw_pickup_prompt'] = 'stiskni ~y~E~s~ po zvednuti', -- Key mapping - ['keymap_showinventory'] = 'show Inventory', + ['keymap_showinventory'] = 'zobrazit inventar', + -- Salary related + ['received_salary'] = 'obdrželi jste výplatu: ~g~$%s~s~', + ['received_help'] = 'obdrželi jste sociální dávku: ~g~$%s~s~', + ['company_nomoney'] = 'společnost u které jste zaměstananí nemá peníze na váš plat', + ['received_paycheck'] = 'obdržena výplata', + ['bank'] = 'bankovní účet', + ['account_bank'] = 'banka', + ['account_black_money'] = 'spinave penize', + ['account_money'] = 'kapesne', - -- Salary related - ['received_salary'] = 'obdrželi jste výplatu: ~g~$%s~s~', - ['received_help'] = 'obdrželi jste sociální dávku: ~g~$%s~s~', - ['company_nomoney'] = 'společnost u které jste zaměstananí nemá peníze na váš plat', - ['received_paycheck'] = 'obdržena výplata', - ['bank'] = 'bankovní účet', - ['account_bank'] = 'bank', - ['account_black_money'] = 'dirty Money', - ['account_money'] = 'cash', + ['act_imp'] = 'akce není možná', + ['in_vehicle'] = 'nemůže nic dát osobě ve vozidle', - ['act_imp'] = 'akce není možná', - ['in_vehicle'] = 'nemůže nic dát osobě ve vozidle', + -- Commands + ['setjob'] = 'přiřadit práci hráči', + ['id_param'] = 'iD hráče', + ['setjob_param2'] = 'název přiřazované práce', + ['setjob_param3'] = 'úroveň práce', + ['spawn_car'] = 'spawn auto', + ['spawn_car_param'] = 'název auta', + ['delete_vehicle'] = 'odstranit vozidlo', + ['invalid_account'] = 'neplatný účet', + ['account'] = 'účet', + ['giveaccountmoney'] = 'dát peníze na účet', + ['invalid_item'] = 'neplatná věc', + ['item'] = 'věc', + ['giveitem'] = 'dát věc', + ['weapon'] = 'zbraň', + ['giveweapon'] = 'dát zbraň', + ['chat_clear'] = 'vyčistit chat', + ['chat_clear_all'] = 'vyčistit chat pro všechny', + ['command_clearinventory'] = 'vycistit vsechny predmety v invetari', + ['command_clearloadout'] = 'odebrat vsechny zbrane z rukz', - -- Commands - ['setjob'] = 'přiřadit práci hráči', - ['id_param'] = 'iD hráče', - ['setjob_param2'] = 'název přiřazované práce', - ['setjob_param3'] = 'úroveň práce', - ['spawn_car'] = 'spawn auto', - ['spawn_car_param'] = 'název auta', - ['delete_vehicle'] = 'odstranit vozidlo', - ['invalid_account'] = 'neplatný účet', - ['account'] = 'účet', - ['giveaccountmoney'] = 'dát peníze na účet', - ['invalid_item'] = 'neplatná věc', - ['item'] = 'věc', - ['giveitem'] = 'dát věc', - ['weapon'] = 'zbraň', - ['giveweapon'] = 'dát zbraň', - ['chat_clear'] = 'vyčistit chat', - ['chat_clear_all'] = 'vyčistit chat pro všechny', - ['command_clearinventory'] = 'clear all items from inventory', - ['command_clearloadout'] = 'remove all weapons from loadout', + -- Locale settings + ['locale_digit_grouping_symbol'] = ' ', + ['locale_currency'] = '$%s', - -- Locale settings - ['locale_digit_grouping_symbol'] = ' ', - ['locale_currency'] = '$%s', - - -- Weapons - ['weapon_knife'] = 'knife', - ['weapon_nightstick'] = 'nightstick', - ['weapon_hammer'] = 'hammer', - ['weapon_bat'] = 'bat', - ['weapon_golfclub'] = 'golf club', - ['weapon_crowbar'] = 'crow bar', - ['weapon_pistol'] = 'pistol', - ['weapon_combatpistol'] = 'combat pistol', - ['weapon_appistol'] = 'ap pistol', - ['weapon_pistol50'] = 'pistol .50', - ['weapon_microsmg'] = 'micro smg', - ['weapon_smg'] = 'smg', - ['weapon_assaultsmg'] = 'assault smg', - ['weapon_assaultrifle'] = 'assault rifle', - ['weapon_carbinerifle'] = 'carbine rifle', - ['weapon_advancedrifle'] = 'advanced rifle', - ['weapon_mg'] = 'mg', - ['weapon_combatmg'] = 'combat mg', - ['weapon_pumpshotgun'] = 'pump shotgun', - ['weapon_sawnoffshotgun'] = 'sawed off shotgun', - ['weapon_assaultshotgun'] = 'assault shotgun', - ['weapon_bullpupshotgun'] = 'bullpup shotgun', - ['weapon_stungun'] = 'tazer', - ['weapon_sniperrifle'] = 'sniper rifle', - ['weapon_heavysniper'] = 'heavy sniper', - ['weapon_grenadelauncher'] = 'grenade launcher', - ['weapon_rpg'] = 'rocket launcher', - ['weapon_minigun'] = 'minigun', - ['weapon_grenade'] = 'grenade', - ['weapon_stickybomb'] = 'sticky bomb', - ['weapon_smokegrenade'] = 'smoke grenade', - ['weapon_bzgas'] = 'bz gas', - ['weapon_molotov'] = 'molotov cocktail', - ['weapon_fireextinguisher'] = 'fire extinguisher', - ['weapon_petrolcan'] = 'jerrycan', - ['weapon_ball'] = 'ball', - ['weapon_snspistol'] = 'sns pistol', - ['weapon_bottle'] = 'bottle', - ['weapon_gusenberg'] = 'gusenberg sweeper', - ['weapon_specialcarbine'] = 'special carbine', - ['weapon_heavypistol'] = 'heavy pistol', - ['weapon_bullpuprifle'] = 'bullpup rifle', - ['weapon_dagger'] = 'dagger', - ['weapon_vintagepistol'] = 'vintage pistol', - ['weapon_firework'] = 'firework', - ['weapon_musket'] = 'musket', - ['weapon_heavyshotgun'] = 'heavy shotgun', - ['weapon_marksmanrifle'] = 'marksman rifle', - ['weapon_hominglauncher'] = 'homing launcher', - ['weapon_proxmine'] = 'proximity mine', - ['weapon_snowball'] = 'snow ball', - ['weapon_flaregun'] = 'flaregun', - ['weapon_combatpdw'] = 'combat pdw', - ['weapon_marksmanpistol'] = 'marksman pistol', - ['weapon_knuckle'] = 'knuckledusters', - ['weapon_hatchet'] = 'hatchet', - ['weapon_railgun'] = 'railgun', - ['weapon_machete'] = 'machete', - ['weapon_machinepistol'] = 'machine pistol', - ['weapon_switchblade'] = 'switchblade', - ['weapon_revolver'] = 'heavy revolver', - ['weapon_dbshotgun'] = 'double barrel shotgun', - ['weapon_compactrifle'] = 'compact rifle', - ['weapon_autoshotgun'] = 'auto shotgun', - ['weapon_battleaxe'] = 'battle axe', - ['weapon_compactlauncher'] = 'compact launcher', + -- Weapons + ['weapon_knife'] = 'nuz', + ['weapon_nightstick'] = 'policejni obusek', + ['weapon_hammer'] = 'kladivo', + ['weapon_bat'] = 'basseballka', + ['weapon_golfclub'] = 'gollfova hul', + ['weapon_crowbar'] = 'pacidlo', + ['weapon_pistol'] = 'pistole', + ['weapon_combatpistol'] = 'utocna pistole', + ['weapon_appistol'] = 'ap pistole', + ['weapon_pistol50'] = 'pistole .50', + ['weapon_microsmg'] = 'micro smg', + ['weapon_smg'] = 'smg', + ['weapon_assaultsmg'] = 'utocne smg', + ['weapon_assaultrifle'] = 'utocna puska', + ['weapon_carbinerifle'] = 'carbine puska', + ['weapon_advancedrifle'] = 'pokrocily puska', + ['weapon_mg'] = 'mg', + ['weapon_combatmg'] = 'utocne mg', + ['weapon_pumpshotgun'] = 'pumpovana brokovnice', + ['weapon_sawnoffshotgun'] = 'upilovana brokovnice', + ['weapon_assaultshotgun'] = 'utocna brokovnice', + ['weapon_bullpupshotgun'] = 'bullpup brokovnice', + ['weapon_stungun'] = 'tazer', + ['weapon_sniperrifle'] = 'sniperka', + ['weapon_heavysniper'] = 'tezka sniperka', + ['weapon_grenadelauncher'] = 'launcher granatu', + ['weapon_rpg'] = 'raketomet', + ['weapon_minigun'] = 'minigun', + ['weapon_grenade'] = 'granat', + ['weapon_stickybomb'] = 'lepkava bomba', + ['weapon_smokegrenade'] = 'kourovy granat', + ['weapon_bzgas'] = 'bz gas', + ['weapon_molotov'] = 'molotov koktejl', + ['weapon_fireextinguisher'] = 'hasicak', + ['weapon_petrolcan'] = 'kanystr', + ['weapon_ball'] = 'koule', + ['weapon_snspistol'] = 'sns pistole', + ['weapon_bottle'] = 'lahev', + ['weapon_gusenberg'] = 'gusenberguv zametac', + ['weapon_specialcarbine'] = 'specialni karabina', + ['weapon_heavypistol'] = 'tezka pistole', + ['weapon_bullpuprifle'] = 'bullpup puska', + ['weapon_dagger'] = 'dyka', + ['weapon_vintagepistol'] = 'velmi stara pistole', + ['weapon_firework'] = 'ohnostroj', + ['weapon_musket'] = 'musketa', + ['weapon_heavyshotgun'] = 'tezka brokovnice', + ['weapon_marksmanrifle'] = 'puska strelce', + ['weapon_hominglauncher'] = 'navadeci launcher', + ['weapon_proxmine'] = 'mina na blizko', + ['weapon_snowball'] = 'snehova koule', + ['weapon_flaregun'] = 'svetlice', + ['weapon_combatpdw'] = 'utocne pdw', + ['weapon_marksmanpistol'] = 'pistole strelce', + ['weapon_knuckle'] = 'knuckledusters', + ['weapon_hatchet'] = 'sekerka', + ['weapon_railgun'] = 'vlakovy launcher', + ['weapon_machete'] = 'maceta', + ['weapon_machinepistol'] = 'kulomet', + ['weapon_switchblade'] = 'vystrelovaci nuz', + ['weapon_revolver'] = 'tezky revolver', + ['weapon_dbshotgun'] = 'dvouhlavnova brokovnice', + ['weapon_compactrifle'] = 'kompaktni puska', + ['weapon_autoshotgun'] = 'automaticka brokovnice', + ['weapon_battleaxe'] = 'bojova sekera', + ['weapon_compactlauncher'] = 'kompaktni launcher', ['weapon_minismg'] = 'mini smg', - ['weapon_pipebomb'] = 'pipe bomb', - ['weapon_poolcue'] = 'pool cue', - ['weapon_wrench'] = 'pipe wrench', - ['weapon_flashlight'] = 'flashlight', - ['gadget_parachute'] = 'parachute', - ['weapon_flare'] = 'flare gun', - ['weapon_doubleaction'] = 'double-Action Revolver', + ['weapon_pipebomb'] = 'dymkova bomba', + ['weapon_poolcue'] = 'kulecnikove tago', + ['weapon_wrench'] = 'klic na trubky', + ['weapon_flashlight'] = 'baterka', + ['gadget_parachute'] = 'padak', + ['weapon_flare'] = 'svetlice', + ['weapon_doubleaction'] = 'dvojhlavnovy revolver', -- Weapon Components - ['component_clip_default'] = 'default Grip', - ['component_clip_extended'] = 'extended Grip', + ['component_clip_default'] = 'zakladni rukojet', + ['component_clip_extended'] = 'prodloucena rukojet', ['component_clip_drum'] = 'drum Magazine', - ['component_clip_box'] = 'box Magazine', - ['component_flashlight'] = 'flashlight', - ['component_scope'] = 'scope', - ['component_scope_advanced'] = 'advanced Scope', - ['component_suppressor'] = 'suppressor', - ['component_grip'] = 'grip', - ['component_luxary_finish'] = 'luxary Weapon Finish', + ['component_clip_box'] = 'krabice s naboji', + ['component_flashlight'] = 'baterka', + ['component_scope'] = 'zamerovac', + ['component_scope_advanced'] = 'pokrocily zamerovac', + ['component_suppressor'] = 'tlumic', + ['component_grip'] = 'rukojet', + ['component_luxary_finish'] = 'luxusni vzhled zbrane', - -- Weapon Ammo - ['ammo_rounds'] = 'round(s)', - ['ammo_shells'] = 'shell(s)', - ['ammo_charge'] = 'charge', - ['ammo_petrol'] = 'gallons of fuel', - ['ammo_firework'] = 'firework(s)', - ['ammo_rockets'] = 'rocket(s)', - ['ammo_grenadelauncher'] = 'grenade(s)', - ['ammo_grenade'] = 'grenade(s)', - ['ammo_stickybomb'] = 'bomb(s)', - ['ammo_pipebomb'] = 'bomb(s)', - ['ammo_smokebomb'] = 'bomb(s)', - ['ammo_molotov'] = 'cocktail(s)', - ['ammo_proxmine'] = 'mine(s)', - ['ammo_bzgas'] = 'can(s)', - ['ammo_ball'] = 'ball(s)', - ['ammo_snowball'] = 'snowball(s)', - ['ammo_flare'] = 'flare(s)', - ['ammo_flaregun'] = 'flare(s)', + -- Weapon Ammo + ['ammo_rounds'] = 'naboj(e)', + ['ammo_shells'] = 'patrona(y)', + ['ammo_charge'] = 'naboj(e)', + ['ammo_petrol'] = 'galonu paliva', + ['ammo_firework'] = 'ohnostroj(e)', + ['ammo_rockets'] = 'raketa(y)', + ['ammo_grenadelauncher'] = 'granat(y)', + ['ammo_grenade'] = 'granat(y)', + ['ammo_stickybomb'] = 'bomba(y)', + ['ammo_pipebomb'] = 'bomba(y)', + ['ammo_smokebomb'] = 'bomba(y)', + ['ammo_molotov'] = 'koktejl(y)', + ['ammo_proxmine'] = 'mina(y)', + ['ammo_bzgas'] = 'kanystr(y)', + ['ammo_ball'] = 'koule', + ['ammo_snowball'] = 'snehova(e) koule', + ['ammo_flare'] = 'svetlice', + ['ammo_flaregun'] = 'svetlice', -- Weapon Tints - ['tint_default'] = 'default skin', - ['tint_green'] = 'green skin', - ['tint_gold'] = 'gold skin', - ['tint_pink'] = 'pink skin', - ['tint_army'] = 'army skin', - ['tint_lspd'] = 'blue skin', - ['tint_orange'] = 'orange skin', - ['tint_platinum'] = 'platinum skin', + ['tint_default'] = 'zakladni skin', + ['tint_green'] = 'zeleny skin', + ['tint_gold'] = 'zlaty skin', + ['tint_pink'] = 'ruzovy skin', + ['tint_army'] = 'armadni skin', + ['tint_lspd'] = 'modry skin', + ['tint_orange'] = 'oranzovy skin', + ['tint_platinum'] = 'platinovy skin', } From 66b14d2300db2b664a13e1af74d885c50c97a324 Mon Sep 17 00:00:00 2001 From: ArkSeyonet <31637812+ArkSeyonet@users.noreply.github.com> Date: Wed, 19 Feb 2020 13:37:25 -0600 Subject: [PATCH 2586/3224] Update ESX Identity For The New ESX (#61) * Update ESX Identity For New ESX Updated ESX Identity For The New ESX - Added locales - Added ESX.RegisterCommand support - Removed Multiple Characters * Update main.lua --- client/main.lua | 2 +- config.lua | 3 + esx_identity.sql | 14 +- fxmanifest.lua | 8 +- locales/en.lua | 11 ++ server/main.lua | 362 +++++------------------------------------------ 6 files changed, 56 insertions(+), 344 deletions(-) create mode 100644 config.lua create mode 100644 locales/en.lua diff --git a/client/main.lua b/client/main.lua index 9b1f08f0..791f84f7 100644 --- a/client/main.lua +++ b/client/main.lua @@ -52,7 +52,7 @@ RegisterNUICallback('escape', function(data, cb) if hasIdentity then EnableGui(false) else - TriggerEvent('chat:addMessage', { args = { '^1[IDENTITY]', '^1You must create your first character in order to play' } }) + ESX.ShowNotification(_U('create_a_character')) end end) diff --git a/config.lua b/config.lua new file mode 100644 index 00000000..aaec53d7 --- /dev/null +++ b/config.lua @@ -0,0 +1,3 @@ +Config = {} + +Config.Locale = 'en' \ No newline at end of file diff --git a/esx_identity.sql b/esx_identity.sql index 42d5c152..e6a39cc3 100644 --- a/esx_identity.sql +++ b/esx_identity.sql @@ -6,16 +6,4 @@ ALTER TABLE `users` ADD COLUMN `dateofbirth` VARCHAR(25) NULL DEFAULT '', ADD COLUMN `sex` VARCHAR(10) NULL DEFAULT '', ADD COLUMN `height` VARCHAR(5) NULL DEFAULT '' -; - -CREATE TABLE `characters` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `identifier` VARCHAR(255) NOT NULL, - `firstname` VARCHAR(255) NOT NULL, - `lastname` VARCHAR(255) NOT NULL, - `dateofbirth` VARCHAR(255) NOT NULL, - `sex` VARCHAR(1) NOT NULL DEFAULT 'M', - `height` VARCHAR(128) NOT NULL, - - PRIMARY KEY (`id`) -); \ No newline at end of file +; \ No newline at end of file diff --git a/fxmanifest.lua b/fxmanifest.lua index fdf64c89..55dd13ec 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -4,16 +4,20 @@ game 'gta5' description 'ESX Identity' -version '1.1.0' +version '1.2.0' server_scripts { - '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', + '@mysql-async/lib/MySQL.lua', + 'locales/en.lua', + 'config.lua', 'server/main.lua' } client_scripts { '@es_extended/locale.lua', + 'locales/en.lua', + 'config.lua', 'client/main.lua' } diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..99a27f34 --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,11 @@ +Locales['en'] = { + ['show_registration'] = 'Show Registration Menu', + ['show_active_character'] = 'Show Active Character', + ['delete_character'] = 'Delete Your Character And Create A New One', + ['deleted_character'] = 'Your character has been deleted.', + ['not_registered'] = 'You do not have a character reistered.', + ['active_character'] = '~b~Active Character:~s~ %s %s', + ['already_registered'] = 'You already have a character registered.', + ['failed_identity'] = 'Failed to set your character, try again later or contact the server admin!', + ['create_a_character'] = 'You have to create a character in order to play.' +} \ No newline at end of file diff --git a/server/main.lua b/server/main.lua index 27c243c2..f96f4495 100644 --- a/server/main.lua +++ b/server/main.lua @@ -3,10 +3,10 @@ ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) function getIdentity(source, callback) - local identifier = GetPlayerIdentifiers(source)[1] + local xPlayer = ESX.GetPlayerFromId(source) MySQL.Async.fetchAll('SELECT identifier, firstname, lastname, dateofbirth, sex, height FROM `users` WHERE `identifier` = @identifier', { - ['@identifier'] = identifier + ['@identifier'] = xPlayer.identifier }, function(result) if result[1].firstname ~= nil then local data = { @@ -34,108 +34,6 @@ function getIdentity(source, callback) end) end -function getCharacters(source, callback) - local identifier = GetPlayerIdentifiers(source)[1] - - MySQL.Async.fetchAll('SELECT * FROM `characters` WHERE `identifier` = @identifier', { - ['@identifier'] = identifier - }, function(result) - if result[1] and result[2] and result[3] then - - local data = { - identifier = result[1].identifier, - firstname1 = result[1].firstname, - lastname1 = result[1].lastname, - dateofbirth1 = result[1].dateofbirth, - sex1 = result[1].sex, - height1 = result[1].height, - firstname2 = result[2].firstname, - lastname2 = result[2].lastname, - dateofbirth2 = result[2].dateofbirth, - sex2 = result[2].sex, - height2 = result[2].height, - firstname3 = result[3].firstname, - lastname3 = result[3].lastname, - dateofbirth3 = result[3].dateofbirth, - sex3 = result[3].sex, - height3 = result[3].height - } - - callback(data) - - elseif result[1] and result[2] and not result[3] then - - local data = { - identifier = result[1].identifier, - firstname1 = result[1].firstname, - lastname1 = result[1].lastname, - dateofbirth1 = result[1].dateofbirth, - sex1 = result[1].sex, - height1 = result[1].height, - firstname2 = result[2].firstname, - lastname2 = result[2].lastname, - dateofbirth2 = result[2].dateofbirth, - sex2 = result[2].sex, - height2 = result[2].height, - firstname3 = '', - lastname3 = '', - dateofbirth3 = '', - sex3 = '', - height3 = '' - } - - callback(data) - - elseif result[1] and not result[2] and not result[3] then - - local data = { - identifier = result[1].identifier, - firstname1 = result[1].firstname, - lastname1 = result[1].lastname, - dateofbirth1 = result[1].dateofbirth, - sex1 = result[1].sex, - height1 = result[1].height, - firstname2 = '', - lastname2 = '', - dateofbirth2 = '', - sex2 = '', - height2 = '', - firstname3 = '', - lastname3 = '', - dateofbirth3 = '', - sex3 = '', - height3 = '' - } - - callback(data) - - else - - local data = { - identifier = '', - firstname1 = '', - lastname1 = '', - dateofbirth1 = '', - sex1 = '', - height1 = '', - firstname2 = '', - lastname2 = '', - dateofbirth2 = '', - sex2 = '', - height2 = '', - firstname3 = '', - lastname3 = '', - dateofbirth3 = '', - sex3 = '', - height3 = '' - } - - callback(data) - - end - end) -end - function setIdentity(identifier, data, callback) MySQL.Async.execute('UPDATE `users` SET `firstname` = @firstname, `lastname` = @lastname, `dateofbirth` = @dateofbirth, `sex` = @sex, `height` = @height WHERE identifier = @identifier', { ['@identifier'] = identifier, @@ -149,15 +47,6 @@ function setIdentity(identifier, data, callback) callback(true) end end) - - MySQL.Async.execute('INSERT INTO characters (identifier, firstname, lastname, dateofbirth, sex, height) VALUES (@identifier, @firstname, @lastname, @dateofbirth, @sex, @height)', { - ['@identifier'] = identifier, - ['@firstname'] = data.firstname, - ['@lastname'] = data.lastname, - ['@dateofbirth'] = data.dateofbirth, - ['@sex'] = data.sex, - ['@height'] = data.height - }) end function updateIdentity(playerId, data, callback) @@ -178,29 +67,28 @@ function updateIdentity(playerId, data, callback) end) end -function deleteIdentity(identifier, data, callback) - MySQL.Async.execute('DELETE FROM `characters` WHERE identifier = @identifier AND firstname = @firstname AND lastname = @lastname AND dateofbirth = @dateofbirth AND sex = @sex AND height = @height', { - ['@identifier'] = identifier, - ['@firstname'] = data.firstname, - ['@lastname'] = data.lastname, - ['@dateofbirth'] = data.dateofbirth, - ['@sex'] = data.sex, - ['@height'] = data.height - }, function(rowsChanged) - if callback then - callback(true) - end - end) +function deleteIdentity(source) + local xPlayer = ESX.GetPlayerFromId(source) + + MySQL.Async.execute('UPDATE `users` SET `firstname` = @firstname, `lastname` = @lastname, `dateofbirth` = @dateofbirth, `sex` = @sex, `height` = @height WHERE identifier = @identifier', { + ['@identifier'] = xPlayer.identifier, + ['@firstname'] = '', + ['@lastname'] = '', + ['@dateofbirth'] = '', + ['@sex'] = '', + ['@height'] = '', + }) end RegisterServerEvent('esx_identity:setIdentity') AddEventHandler('esx_identity:setIdentity', function(data, myIdentifiers) + local xPlayer = ESX.GetPlayerFromId(source) setIdentity(myIdentifiers.steamid, data, function(callback) if callback then TriggerClientEvent('esx_identity:identityCheck', myIdentifiers.playerid, true) TriggerEvent('esx_identity:characterUpdated', myIdentifiers.playerid, data) else - TriggerClientEvent('chat:addMessage', myIdentifiers.playerid, { args = { '^1[IDENTITY]', 'Failed to set character, try again later or contact the server admin!' } }) + xPlayer.showNotification(_U('failed_identity')) end end) end) @@ -268,216 +156,34 @@ AddEventHandler('onResourceStart', function(resource) end end) -TriggerEvent('es:addCommand', 'register', function(source, args, user) - getCharacters(source, function(data) - if data.firstname3 ~= '' then - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'You can only have 3 registered characters. Use the ^3/chardel^0 command in order to delete existing characters.' } }) +ESX.RegisterCommand('register', 'user', function(xPlayer, args, showError) + getIdentity(xPlayer.source, function(data) + if data.firstname ~= '' then + xPlayer.showNotification(_U('already_registered')) else - TriggerClientEvent('esx_identity:showRegisterIdentity', source) + TriggerClientEvent('esx_identity:showRegisterIdentity', xPlayer.source) end end) -end, {help = "Register a new character"}) +end, false, {help = _U('show_registration')}) -TriggerEvent('es:addGroupCommand', 'char', 'user', function(source, args, user) - getIdentity(source, function(data) +ESX.RegisterCommand('char', 'user', function(xPlayer, args, showError) + getIdentity(xPlayer.source, function(data) if data.firstname == '' then - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'You do not have an active character!' } }) + xPlayer.showNotification(_U('not_registered')) else - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'Active character: ^2' .. data.firstname .. ' ' .. data.lastname } }) + xPlayer.showNotification(_U('active_character', data.firstname, data.lastname)) end end) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient permissions!' } }) -end, {help = "List your current character"}) +end, false, {help = _U('show_active_character')}) -TriggerEvent('es:addGroupCommand', 'charlist', 'user', function(source, args, user) - getCharacters(source, function(data) - if data.firstname1 ~= '' then - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY] Character 1:', data.firstname1 .. ' ' .. data.lastname1 } }) - - if data.firstname2 ~= '' then - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY] Character 2:', data.firstname2 .. ' ' .. data.lastname2 } }) - - if data.firstname3 ~= '' then - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY] Character 3:', data.firstname3 .. ' ' .. data.lastname3 } }) - end - end +ESX.RegisterCommand('chardel', 'user', function(xPlayer, args, showError) + getIdentity(xPlayer.source, function(data) + if data.firstname == '' then + xPlayer.showNotification(_U('not_registered')) else - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'You have no registered characters. Use the ^3/register^0 command to register a character.' } }) + deleteIdentity(xPlayer.source) + xPlayer.showNotification(_U('deleted_character')) + TriggerClientEvent('esx_identity:showRegisterIdentity', xPlayer.source) end end) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient permissions!' } }) -end, {help = "List all your registered characters"}) - -TriggerEvent('es:addGroupCommand', 'charselect', 'user', function(source, args, user) - local charNumber = tonumber(args[1]) - - if charNumber == nil or charNumber > 3 or charNumber < 1 then - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'That\'s an invalid character!' } }) - return - end - - getCharacters(source, function(data) - if charNumber == 1 then - local data = { - identifier = data.identifier, - firstname = data.firstname1, - lastname = data.lastname1, - dateofbirth = data.dateofbirth1, - sex = data.sex1, - height = data.height1 - } - - if data.firstname ~= '' then - updateIdentity(source, data, function(callback) - - if callback then - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'Updated your active character to ^2' .. data.firstname .. ' ' .. data.lastname } }) - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'Failed to update your identity, try again later or contact the server admin!' } }) - end - end) - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'You don\'t have a character in slot 1!' } }) - end - elseif charNumber == 2 then - - local data = { - identifier = data.identifier, - firstname = data.firstname2, - lastname = data.lastname2, - dateofbirth = data.dateofbirth2, - sex = data.sex2, - height = data.height2 - } - - if data.firstname ~= '' then - updateIdentity(source, data, function(callback) - - if callback then - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'Updated your active character to ^2' .. data.firstname .. ' ' .. data.lastname } }) - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'Failed to update your identity, try again later or contact the server admin!' } }) - end - end) - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'You don\'t have a character in slot 2!' } }) - end - elseif charNumber == 3 then - - local data = { - identifier = data.identifier, - firstname = data.firstname3, - lastname = data.lastname3, - dateofbirth = data.dateofbirth3, - sex = data.sex3, - height = data.height3 - } - - if data.firstname ~= '' then - updateIdentity(source, data, function(callback) - - if callback then - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'Updated your active character to ^2' .. data.firstname .. ' ' .. data.lastname } }) - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'Failed to update your identity, try again later or contact the server admin!' } }) - end - end) - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'You don\'t have a character in slot 3!' } }) - end - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'Failed to update your identity, try again later or contact the server admin!' } }) - end - - end) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient permissions!' } }) -end, {help = "Switch between character", params = {{name = "char", help = "the character id, ranges from 1-3"}}}) - -TriggerEvent('es:addGroupCommand', 'chardel', 'user', function(source, args, user) - local charNumber = tonumber(args[1]) - - if charNumber == nil or charNumber > 3 or charNumber < 1 then - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'That\'s an invalid character!' } }) - return - end - - getCharacters(source, function(data) - - if charNumber == 1 then - - local data = { - identifier = data.identifier, - firstname = data.firstname1, - lastname = data.lastname1, - dateofbirth = data.dateofbirth1, - sex = data.sex1, - height = data.height1 - } - - if data.firstname ~= '' then - deleteIdentity(GetPlayerIdentifiers(source)[1], data, function(callback) - if callback then - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'You have deleted ^1' .. data.firstname .. ' ' .. data.lastname } }) - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'Failed to delete the character, try again later or contact the server admin!' } }) - end - end) - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'You don\'t have a character in slot 1!' } }) - end - - elseif charNumber == 2 then - - local data = { - identifier = data.identifier, - firstname = data.firstname2, - lastname = data.lastname2, - dateofbirth = data.dateofbirth2, - sex = data.sex2, - height = data.height2 - } - - if data.firstname ~= '' then - deleteIdentity(GetPlayerIdentifiers(source)[1], data, function(callback) - if callback then - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'You have deleted ^1' .. data.firstname .. ' ' .. data.lastname } }) - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'Failed to delete the character, try again later or contact the server admin!' } }) - end - end) - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'You don\'t have a character in slot 2!' } }) - end - - elseif charNumber == 3 then - - local data = { - identifier = data.identifier, - firstname = data.firstname3, - lastname = data.lastname3, - dateofbirth = data.dateofbirth3, - sex = data.sex3, - height = data.height3 - } - - if data.firstname ~= '' then - deleteIdentity(GetPlayerIdentifiers(source)[1], data, function(callback) - if callback then - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'You have deleted ^1' .. data.firstname .. ' ' .. data.lastname } }) - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'Failed to delete the character, try again later or contact the server admin!' } }) - end - end) - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'You don\'t have a character in slot 3!' } }) - end - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1[IDENTITY]', 'Failed to delete the character, try again!' } }) - end - end) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient permissions!' } }) -end, {help = "Delete a registered character", params = {{name = "char", help = "the character id, ranges from 1-3"}}}) +end, false, {help = _U('delete_character')}) \ No newline at end of file From 133f21190631e0fb1e21c350f9f722c524de8924 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Fri, 21 Feb 2020 10:15:53 +0100 Subject: [PATCH 2587/3224] Added czech locale + Minor changes (#62) * Fixed upper case * Added czech locale * Update fxmanifest.lua * Minor cleanup * Added czech UI * Fixed name --- client/main.lua | 7 ++----- fxmanifest.lua | 2 ++ html/cs_index.html | 22 ++++++++++++++++++++++ locales/cs.lua | 11 +++++++++++ locales/en.lua | 20 ++++++++++---------- 5 files changed, 47 insertions(+), 15 deletions(-) create mode 100644 html/cs_index.html create mode 100644 locales/cs.lua diff --git a/client/main.lua b/client/main.lua index 791f84f7..45d474e8 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,8 +1,5 @@ -local guiEnabled = false -local myIdentity = {} -local myIdentifiers = {} -local hasIdentity = false -local isDead = false +local guiEnabled, hasIdentity, isDead = false, false, false +local myIdentity, myIdentifiers = {}, {} ESX = nil diff --git a/fxmanifest.lua b/fxmanifest.lua index 55dd13ec..256ab072 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -10,6 +10,7 @@ server_scripts { '@es_extended/locale.lua', '@mysql-async/lib/MySQL.lua', 'locales/en.lua', + 'locales/cs.lua', 'config.lua', 'server/main.lua' } @@ -17,6 +18,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', 'locales/en.lua', + 'locales/cs.lua', 'config.lua', 'client/main.lua' } diff --git a/html/cs_index.html b/html/cs_index.html new file mode 100644 index 00000000..1dd357a9 --- /dev/null +++ b/html/cs_index.html @@ -0,0 +1,22 @@ + + + + + + + +
    +
    +

    Register

    +
    +
    +
    +
    + Male + Female
    + +
    +
    + + + diff --git a/locales/cs.lua b/locales/cs.lua new file mode 100644 index 00000000..80c6a267 --- /dev/null +++ b/locales/cs.lua @@ -0,0 +1,11 @@ +Locales['cs'] = { + ['show_registration'] = 'zobrazit registracni menu', + ['show_active_character'] = 'zobrazit aktivni postavy', + ['delete_character'] = 'smazat svou stavajici postavu a vytvorit novou', + ['deleted_character'] = 'vase postava byla smazana.', + ['not_registered'] = 'nemas zaregistrovanou postavu.', + ['active_character'] = '~b~aktivni postava:~s~ %s %s', + ['already_registered'] = 'jiz mas zaregistrovanou postavu.', + ['failed_identity'] = 'nastaveni vasi postavy selhalo, zkus to prosim znovu pozdeji nebo kontaktuj majitele serveru!', + ['create_a_character'] = 'aby jsi mohl/a hrat, tak se musis registrovat.' +} diff --git a/locales/en.lua b/locales/en.lua index 99a27f34..53fac161 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,11 +1,11 @@ Locales['en'] = { - ['show_registration'] = 'Show Registration Menu', - ['show_active_character'] = 'Show Active Character', - ['delete_character'] = 'Delete Your Character And Create A New One', - ['deleted_character'] = 'Your character has been deleted.', - ['not_registered'] = 'You do not have a character reistered.', - ['active_character'] = '~b~Active Character:~s~ %s %s', - ['already_registered'] = 'You already have a character registered.', - ['failed_identity'] = 'Failed to set your character, try again later or contact the server admin!', - ['create_a_character'] = 'You have to create a character in order to play.' -} \ No newline at end of file + ['show_registration'] = 'show Registration Menu', + ['show_active_character'] = 'show Active Character', + ['delete_character'] = 'delete Your Character And Create A New One', + ['deleted_character'] = 'your character has been deleted.', + ['not_registered'] = 'you do not have a character reistered.', + ['active_character'] = '~b~active Character:~s~ %s %s', + ['already_registered'] = 'you already have a character registered.', + ['failed_identity'] = 'failed to set your character, try again later or contact the server admin!', + ['create_a_character'] = 'you have to create a character in order to play.' +} From ecbf340e391f1a3d91607d0e7d1b61917fbd86f5 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 22 Feb 2020 10:05:10 +0100 Subject: [PATCH 2588/3224] Accept "me" in player or playerId type Co-Authored-By: Dan Sadler --- server/functions.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/functions.lua b/server/functions.lua index 053f58e1..f910b945 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -77,6 +77,8 @@ ESX.RegisterCommand = function(name, group, cb, allowConsole, suggestion) elseif v.type == 'player' or v.type == 'playerId' then local targetPlayer = tonumber(args[k]) + if args[k] == 'me' then targetPlayer = playerId end + if targetPlayer then local xTargetPlayer = ESX.GetPlayerFromId(targetPlayer) From 8927aebae13760cc2351ebd096cb195bb27ef4a2 Mon Sep 17 00:00:00 2001 From: Dione Batista Date: Sun, 23 Feb 2020 14:48:37 -0300 Subject: [PATCH 2589/3224] Updated Portuguese translation (#523) * Update br.lua * uppercase "corrections" --- locales/br.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index f8573d2d..3258ea49 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -38,7 +38,7 @@ Locales['br'] = { ['threw_pickup_prompt'] = 'pressione ~y~E~s~ para pegar', -- Key mapping - ['keymap_showinventory'] = 'show Inventory', + ['keymap_showinventory'] = 'exibir inventario', -- Salary related ['received_salary'] = 'voce recebeu seu salário: ~g~$%s~s~ ', @@ -46,9 +46,9 @@ Locales['br'] = { ['company_nomoney'] = 'a empresa em que voce esta empregado esta muito pobre para pagar seu salário', ['received_paycheck'] = 'recebeu dinheiro', ['bank'] = 'banco', - ['account_bank'] = 'bank', - ['account_black_money'] = 'dirty Money', - ['account_money'] = 'cash', + ['account_bank'] = 'banco', + ['account_black_money'] = 'dinheiro sujo', + ['account_money'] = 'dinheiro', ['act_imp'] = 'ação impossível', ['in_vehicle'] = 'voce não pode dar nada para alguem no veículo', @@ -76,7 +76,7 @@ Locales['br'] = { -- Locale settings ['locale_digit_grouping_symbol'] = ' ', - ['locale_currency'] = '$%s', + ['locale_currency'] = 'R$%s', -- Weapons ['weapon_knife'] = 'faca', From 22b88b59b5f68d8e8ab20fc034ea53c84cd23e76 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 23 Feb 2020 20:57:29 +0100 Subject: [PATCH 2590/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 75e4a94a..8df3fb52 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ start instance ### License instance - enter buildings! -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. From ad4f678399719caa2763172c719990568c7b19b2 Mon Sep 17 00:00:00 2001 From: medina102 Date: Mon, 24 Feb 2020 07:13:06 +0100 Subject: [PATCH 2591/3224] Update en.lua Typo corrected. --- locales/en.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/en.lua b/locales/en.lua index f7c4babe..0735fe34 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,5 +1,5 @@ Locales['en'] = { - ['new_message'] = '~b~You have recived a message:~s~ %s', + ['new_message'] = '~b~You have received a message:~s~ %s', ['press_take_call'] = '%s - Press ~INPUT_CONTEXT~ to take the call', ['taken_call'] = '~y~%s~s~ has taken the call', ['gps_position'] = 'the destination has been added to your GPS', From 998b91e9712faa6d7b0a94804f0118069741342b Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 24 Feb 2020 21:43:50 +0100 Subject: [PATCH 2592/3224] Fixed leftover ES code --- server/main.lua | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/server/main.lua b/server/main.lua index acac591a..cd92fa3f 100644 --- a/server/main.lua +++ b/server/main.lua @@ -22,21 +22,17 @@ end) RegisterServerEvent('esx_skin:responseSaveSkin') AddEventHandler('esx_skin:responseSaveSkin', function(skin) + local xPlayer = ESX.GetPlayerFromId(source) - TriggerEvent('es:getPlayerFromId', source, function(user) - TriggerEvent('es:canGroupTarget', user.getGroup(), "admin", function(available) - if available then - local file = io.open('resources/[esx]/esx_skin/skins.txt', "a") - - file:write(json.encode(skin) .. "\n\n") - file:flush() - file:close() - else - print(('esx_skin: %s attempted saving skin to file'):format(user.getIdentifier())) - end - end) - end) + if xPlayer.getGroup() == 'admin' then + local file = io.open('resources/[esx]/esx_skin/skins.txt', "a") + file:write(json.encode(skin) .. "\n\n") + file:flush() + file:close() + else + print(('esx_skin: %s attempted saving skin to file'):format(xPlayer.getIdentifier())) + end end) ESX.RegisterServerCallback('esx_skin:getPlayerSkin', function(source, cb) From 24a9defca418492b25a91e32efedec8c855746f2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 25 Feb 2020 15:54:38 +0100 Subject: [PATCH 2593/3224] Removed xPlayer.removeWeapon() second argument --- client/main.lua | 11 ++--------- fxmanifest.lua | 2 +- server/classes/player.lua | 4 ++-- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/client/main.lua b/client/main.lua index fd2fc759..106e0032 100644 --- a/client/main.lua +++ b/client/main.lua @@ -190,19 +190,12 @@ AddEventHandler('esx:setWeaponTint', function(weaponName, weaponTintIndex) end) RegisterNetEvent('esx:removeWeapon') -AddEventHandler('esx:removeWeapon', function(weaponName, ammo) +AddEventHandler('esx:removeWeapon', function(weaponName) local playerPed = PlayerPedId() local weaponHash = GetHashKey(weaponName) RemoveWeaponFromPed(playerPed, weaponHash) - - if ammo then - local pedAmmo = GetAmmoInPedWeapon(playerPed, weaponHash) - local finalAmmo = math.floor(pedAmmo - ammo) - SetPedAmmo(playerPed, weaponHash, finalAmmo) - else - SetPedAmmo(playerPed, weaponHash, 0) -- remove leftover ammo - end + SetPedAmmo(playerPed, weaponHash, 0) -- remove leftover ammo end) RegisterNetEvent('esx:removeWeaponComponent') diff --git a/fxmanifest.lua b/fxmanifest.lua index a9fe16ba..eb6e6f19 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -83,7 +83,7 @@ files { 'html/img/accounts/bank.png', 'html/img/accounts/black_money.png', - 'html/img/accounts/money.png', + 'html/img/accounts/money.png' } exports { diff --git a/server/classes/player.lua b/server/classes/player.lua index 4a41d30b..845b6f8d 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -403,7 +403,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, return 0 end - self.removeWeapon = function(weaponName, ammo) + self.removeWeapon = function(weaponName) local weaponLabel for k,v in ipairs(self.loadout) do @@ -420,7 +420,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end if weaponLabel then - self.triggerEvent('esx:removeWeapon', weaponName, ammo) + self.triggerEvent('esx:removeWeapon', weaponName) self.triggerEvent('esx:removeInventoryItem', weaponLabel, false, true) end end From 6a0e69e9a1708174f4e66566cdfc5c7098018cb2 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Wed, 26 Feb 2020 13:46:39 +0100 Subject: [PATCH 2594/3224] Support for newest ESX + Minor cleanup (#29) * Support for newest ESX * Minor cleanup * Moved all coords to vector3 types * Moved all coords to vector3 types --- client/main.lua | 47 ++++++++-------------- config.lua | 104 +++++++++++++++++++++++------------------------- server/main.lua | 2 +- 3 files changed, 67 insertions(+), 86 deletions(-) diff --git a/client/main.lua b/client/main.lua index 93a982c4..46759861 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,10 +1,7 @@ -ESX = nil -local HasAlreadyEnteredMarker = false -local LastZone = nil -local CurrentAction = nil -local CurrentActionMsg = '' -local CurrentActionData = {} -local isDead = false +ESX = nil +local HasAlreadyEnteredMarker, isDead = false, false +local LastZone, CurrentAction, CurrentActionMsg +local CurrentActionData = {} Citizen.CreateThread(function() while ESX == nil do @@ -14,8 +11,7 @@ Citizen.CreateThread(function() end) function OpenAccessoryMenu() - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'set_unset_accessory', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'set_unset_accessory', { title = _U('set_unset'), align = 'top-left', elements = { @@ -23,11 +19,9 @@ function OpenAccessoryMenu() {label = _U('ears'), value = 'Ears'}, {label = _U('mask'), value = 'Mask'}, {label = _U('glasses'), value = 'Glasses'} - } - }, function(data, menu) + }}, function(data, menu) menu.close() SetUnsetAccessory(data.current.value) - end, function(data, menu) menu.close() end) @@ -59,7 +53,6 @@ function SetUnsetAccessory(accessory) else ESX.ShowNotification(_U('no_' .. _accessory)) end - end, accessory) end @@ -68,20 +61,18 @@ function OpenShopMenu(accessory) local restrict = {} restrict = { _accessory .. '_1', _accessory .. '_2' } - + TriggerEvent('esx_skin:openRestrictedMenu', function(data, menu) menu.close() - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'shop_confirm', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'shop_confirm', { title = _U('valid_purchase'), align = 'top-left', elements = { {label = _U('no'), value = 'no'}, {label = _U('yes', ESX.Math.GroupDigits(Config.Price)), value = 'yes'} - } - }, function(data, menu) + }}, function(data, menu) menu.close() if data.current.value == 'yes' then ESX.TriggerServerCallback('esx_accessories:checkMoney', function(hasEnoughMoney) @@ -122,7 +113,6 @@ function OpenShopMenu(accessory) CurrentAction = 'shop_menu' CurrentActionMsg = _U('press_access') CurrentActionData = {} - end) end, function(data, menu) menu.close() @@ -156,7 +146,7 @@ Citizen.CreateThread(function() for k,v in pairs(Config.ShopsBlips) do if v.Pos ~= nil then for i=1, #v.Pos, 1 do - local blip = AddBlipForCoord(v.Pos[i].x, v.Pos[i].y, v.Pos[i].z) + local blip = AddBlipForCoord(v.Pos[i]) SetBlipSprite (blip, v.Blip.sprite) SetBlipDisplay(blip, 4) @@ -179,25 +169,24 @@ Citizen.CreateThread(function() local coords = GetEntityCoords(PlayerPedId()) for k,v in pairs(Config.Zones) do for i = 1, #v.Pos, 1 do - if(Config.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos[i].x, v.Pos[i].y, v.Pos[i].z, true) < Config.DrawDistance) then - DrawMarker(Config.Type, v.Pos[i].x, v.Pos[i].y, v.Pos[i].z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.Size.x, Config.Size.y, Config.Size.z, Config.Color.r, Config.Color.g, Config.Color.b, 100, false, true, 2, false, false, false, false) + if(Config.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos[i], true) < Config.DrawDistance) then + DrawMarker(Config.Type, v.Pos[i], 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.Size.x, Config.Size.y, Config.Size.z, Config.Color.r, Config.Color.g, Config.Color.b, 100, false, true, 2, false, false, false, false) end end end end end) - Citizen.CreateThread(function() while true do Citizen.Wait(200) - local coords = GetEntityCoords(PlayerPedId()) - local isInMarker = false + local coords = GetEntityCoords(PlayerPedId()) + local isInMarker = false local currentZone = nil for k,v in pairs(Config.Zones) do for i = 1, #v.Pos, 1 do - if GetDistanceBetweenCoords(coords, v.Pos[i].x, v.Pos[i].y, v.Pos[i].z, true) < Config.Size.x then + if GetDistanceBetweenCoords(coords, v.Pos[i], true) < Config.Size.x then isInMarker = true currentZone = k end @@ -214,7 +203,6 @@ Citizen.CreateThread(function() HasAlreadyEnteredMarker = false TriggerEvent('esx_accessories:hasExitedMarker', LastZone) end - end end) @@ -223,14 +211,14 @@ Citizen.CreateThread(function() while true do Citizen.Wait(0) - if CurrentAction ~= nil then + if CurrentAction then ESX.ShowHelpNotification(CurrentActionMsg) if IsControlJustReleased(0, 38) and CurrentActionData.accessory then OpenShopMenu(CurrentActionData.accessory) CurrentAction = nil end - elseif CurrentAction == nil and not Config.EnableControls then + elseif CurrentAction and not Config.EnableControls then Citizen.Wait(500) end @@ -239,6 +227,5 @@ Citizen.CreateThread(function() OpenAccessoryMenu() end end - end end) diff --git a/config.lua b/config.lua index ea21f3af..3a9ecdd3 100644 --- a/config.lua +++ b/config.lua @@ -21,9 +21,9 @@ Config.ShopsBlips = { }, Mask = { Pos = { - { x = -1338.129, y = -1278.200, z = 3.872 }, + vector3(-1338.1, -1278.2, 3.8), }, - Blip = { sprite = 362, color = 2 } + Blip = {sprite = 362, color = 2} }, Helmet = { Pos = nil, @@ -38,66 +38,60 @@ Config.ShopsBlips = { Config.Zones = { Ears = { Pos = { - {x= 80.374, y= -1389.493, z= 28.406}, - {x= -709.426, y= -153.829, z= 36.535}, - {x= -163.093, y= -302.038, z= 38.853}, - {x= 420.787, y= -809.654, z= 28.611}, - {x= -817.070, y= -1075.96, z= 10.448}, - {x= -1451.300, y= -238.254, z= 48.929}, - {x= -0.756, y= 6513.685, z= 30.997}, - {x= 123.431, y= -208.060, z= 53.677}, - {x= 1687.318, y= 4827.685, z= 41.183}, - {x= 622.806, y= 2749.221, z= 41.208}, - {x= 1200.085, y= 2705.428, z= 37.342}, - {x= -1199.959, y= -782.534, z= 16.452}, - {x= -3171.867, y= 1059.632, z= 19.983}, - {x= -1095.670, y= 2709.245, z= 18.227}, - } - - }, + vector3(80.3, -1389.4, 28.4), + vector3(-163.0, -302.0, 38.8), + vector3(-163.0,-302.0, 38.8), + vector3(420.7, -809.6, 28.6), + vector3(-817.0, -1075.9, 10.4), + vector3(-1451.3, -238.2, 48.9), + vector3(-0.7, 6513.6, 30.9), + vector3(123.4, -208.0, 53.6), + vector3(1687.3, 4827.6, 41.1), + vector3(622.8, 2749.2, 41.2), + vector3(1200.0, 2705.4, 37.3), + vector3(-1199.9, -782.5, 16.4), + vector3(-3171.8, 1059.6, 19.9), + vector3(-1095.6, 2709.2, 18.2), + }}, Mask = { Pos = { - {x = -1338.129, y = -1278.200, z = 3.872}, - } - }, + vector3(-1338.1, -1278.2, 3.8), + }}, Helmet = { Pos = { - {x= 81.576, y= -1400.602, z= 28.406}, - {x= -705.845, y= -159.015, z= 36.535}, - {x= -161.349, y= -295.774, z= 38.853}, - {x= 419.319, y= -800.647, z= 28.611}, - {x= -824.362, y= -1081.741, z= 10.448}, - {x= -1454.888, y= -242.911, z= 48.931}, - {x= 4.770, y= 6520.935, z= 30.997}, - {x= 121.071, y= -223.266, z= 53.377}, - {x= 1689.648, y= 4818.805, z= 41.183}, - {x= 613.971, y= 2749.978, z= 41.208}, - {x= 1189.513, y= 2703.947, z= 37.342}, - {x= -1204.025, y= -774.439, z= 16.452}, - {x= -3164.280, y= 1054.705, z= 19.983}, - {x= -1103.125, y= 2700.599, z= 18.227}, - } - }, + vector3(81.5, -1400.6, 28.4), + vector3(-705.8, -159.0, 36.5), + vector3(-161.3, -295.7, 38.8), + vector3(419.3, -800.6, 28.6), + vector3(-824.3, -1081.7, 10.4), + vector3(-1454.8, -242.9, 48.9), + vector3(4.7, 6520.9, 30.9), + vector3(121.0, -223.2, 53.3), + vector3(1689.6, 4818.8, 41.1), + vector3(613.9, 2749.9, 41.2), + vector3(1189.5, 2703.9, 37.3), + vector3(-1204.0, -774.4, 16.4), + vector3(-3164.2, 1054.7, 19.9), + vector3(-1103.1, 2700.5, 18.2), + }}, Glasses = { Pos = { - {x= 75.287, y= -1391.131, z= 28.406}, - {x= -713.102, y= -160.116, z= 36.535}, - {x= -156.171, y= -300.547, z= 38.853}, - {x= 425.478, y= -807.866, z= 28.611}, - {x= -820.853, y= -1072.940, z= 10.448}, - {x= -1458.052, y= -236.783, z= 48.918}, - {x= 3.587, y= 6511.585, z= 30.997}, - {x= 131.335, y= -212.336, z= 53.677}, - {x= 1694.936, y= 4820.837, z= 41.183}, - {x= 613.972, y= 2768.814, z= 41.208}, - {x= 1198.678, y= 2711.011, z= 37.342}, - {x= -1188.227, y= -764.594, z= 16.452}, - {x= -3173.192, y= 1038.228, z= 19.983}, - {x= -1100.494, y= 2712.481, z= 18.227}, - } - } - + vector3(75.2, -1391.1, 28.4), + vector3(-713.1, -160.1, 36.5), + vector3(-156.1, -300.5, 38.8), + vector3(425.4, -807.8, 28.6), + vector3(-820.8, -1072.9, 10.4), + vector3(-1458.0, -236.7, 48.9), + vector3(3.5, 6511.5, 30.9), + vector3(131.3, -212.3, 53.6), + vector3(1694.9, 4820.8, 41.1), + vector3(613.9, 2768.8, 41.2), + vector3(1198.6, 2711.0, 37.3), + vector3(-1188.2, -764.5, 16.4), + vector3(-3173.1, 1038.2, 19.9), + vector3(-1100.4, 2712.4, 18.2), + }} } diff --git a/server/main.lua b/server/main.lua index 83d1d255..74446a04 100644 --- a/server/main.lua +++ b/server/main.lua @@ -43,5 +43,5 @@ end) ESX.RegisterServerCallback('esx_accessories:checkMoney', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) - cb(xPlayer.get('money') >= Config.Price) + cb(xPlayer.getMoney() >= Config.Price) end) From fe041c05b844a41b555109768af55be425d7ae6c Mon Sep 17 00:00:00 2001 From: rex2630 Date: Thu, 27 Feb 2020 13:30:13 +0100 Subject: [PATCH 2595/3224] Moved all coords to vector3 types --- config.lua | 63 ++++++++++++++++++++++++++---------------------------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/config.lua b/config.lua index e1d07b2b..f2b1f236 100644 --- a/config.lua +++ b/config.lua @@ -1,49 +1,46 @@ -Config = {} +Config = {} Config.DrawDistance = 100 -Config.Size = {x = 1.5, y = 1.5, z = 1.5} -Config.Color = {r = 0, g = 128, b = 255} -Config.Type = 1 -Config.Locale = 'en' +Config.Size = {x = 1.5, y = 1.5, z = 1.5} +Config.Color = {r = 0, g = 128, b = 255} +Config.Type = 1 +Config.Locale = 'en' Config.Zones = { TwentyFourSeven = { Items = {}, Pos = { - {x = 373.875, y = 325.896, z = 102.566}, - {x = 2557.458, y = 382.282, z = 107.622}, - {x = -3038.939, y = 585.954, z = 6.908}, - {x = -3241.927, y = 1001.462, z = 11.830}, - {x = 547.431, y = 2671.710, z = 41.156}, - {x = 1961.464, y = 3740.672, z = 31.343}, - {x = 2678.916, y = 3280.671, z = 54.241}, - {x = 1729.216, y = 6414.131, z = 34.037} - } - }, + vector3(373.8, 325.8, 102.5), + vector3(2557.4, 382.2, 107.6), + vector3(-3038.9, 585.9, 6.9), + vector3(-3241.9, 1001.4, 11.8), + vector3(547.4, 2671.7, 41.1), + vector3(1961.4, 3740.6, 31.3), + vector3(2678.9, 3280.6, 54.2), + vector3(1729.2, 6414.1, 34.0) + }}, RobsLiquor = { Items = {}, Pos = { - {x = 1135.808, y = -982.281, z = 45.415}, - {x = -1222.915, y = -906.983, z = 11.326}, - {x = -1487.553, y = -379.107, z = 39.163}, - {x = -2968.243, y = 390.910, z = 14.043}, - {x = 1166.024, y = 2708.930, z = 37.157}, - {x = 1392.562, y = 3604.684, z = 33.980}, - {x = 127.830, y = -1284.796, z = 28.280}, --StripClub - {x = -1393.409, y = -606.624, z = 29.319}, --Tequila la - {x = -559.906, y = 287.093, z = 81.176} --Bahamamas - } - }, + vector3(1135.8, -982.2, 45.4), + vector3(-1222.9, -906.9, 11.3), + vector3(-1487.5, -379.1, 39.1), + vector3(-2968.2, 390.9, 14.0), + vector3(1166.0, 2708.9, 37.1), + vector3(1392.5, 3604.6, 33.9), + vector3(127.8, -1284.7, 28.2), --StripClub + vector3(-1393.4, -606.6, 29.3), --Tequila la + vector3(-559.9, 287.0, 81.1) --Bahamamas + }}, LTDgasoline = { Items = {}, Pos = { - {x = -48.519, y = -1757.514, z = 28.421}, - {x = 1163.373, y = -323.801, z = 68.205}, - {x = -707.501, y = -914.260, z = 18.215}, - {x = -1820.523, y = 792.518, z = 137.118}, - {x = 1698.388, y = 4924.404, z = 41.063} - } - } + vector3(-48.5, -1757.5, 28.4), + vector3(1163.3, -323.8, 68.2), + vector3(-707.5, -914.2, 18.2), + vector3(-1820.5, 792.5, 137.1), + vector3(1698.3, 4924.4, 41.0) + }} } From aefe034d6c2190ad053723d1be64fd100ea5ae9a Mon Sep 17 00:00:00 2001 From: rex2630 Date: Thu, 27 Feb 2020 13:35:26 +0100 Subject: [PATCH 2596/3224] Moved all coords to vector3 types --- client/main.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/main.lua b/client/main.lua index c6df4379..fc33dabc 100644 --- a/client/main.lua +++ b/client/main.lua @@ -82,7 +82,7 @@ end) Citizen.CreateThread(function() for k,v in pairs(Config.Zones) do for i = 1, #v.Pos, 1 do - local blip = AddBlipForCoord(v.Pos[i].x, v.Pos[i].y, v.Pos[i].z) + local blip = AddBlipForCoord(v.Pos[i]) SetBlipSprite (blip, 52) SetBlipScale (blip, 1.0) @@ -108,7 +108,7 @@ Citizen.CreateThread(function() local distance = GetDistanceBetweenCoords(playerCoords, v.Pos[i].x, v.Pos[i].y, v.Pos[i].z, true) if distance < Config.DrawDistance then - DrawMarker(Config.Type, v.Pos[i].x, v.Pos[i].y, v.Pos[i].z, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Config.Size.x, Config.Size.y, Config.Size.z, Config.Color.r, Config.Color.g, Config.Color.b, 100, false, true, 2, false, nil, nil, false) + DrawMarker(Config.Type, v.Pos[i], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Config.Size.x, Config.Size.y, Config.Size.z, Config.Color.r, Config.Color.g, Config.Color.b, 100, false, true, 2, false, nil, nil, false) letSleep = false if distance < Config.Size.x then @@ -155,4 +155,4 @@ Citizen.CreateThread(function() Citizen.Wait(500) end end -end) \ No newline at end of file +end) From 79d53a5550673b73b349132d5be76312c97909b2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 28 Feb 2020 20:05:27 +0100 Subject: [PATCH 2597/3224] ESX.Game.GetPedMugshot() second argument transparent --- client/functions.lua | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index e2bace44..07c9cab4 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -281,9 +281,15 @@ ESX.UI.ShowInventoryItemNotification = function(add, item, count) }) end -ESX.Game.GetPedMugshot = function(ped) +ESX.Game.GetPedMugshot = function(ped, transparent) if DoesEntityExist(ped) then - local mugshot = RegisterPedheadshot(ped) + local mugshot + + if transparent then + mugshot = RegisterPedheadshotTransparent(ped) + else + mugshot = RegisterPedheadshot(ped) + end while not IsPedheadshotReady(mugshot) do Citizen.Wait(0) From 4d9af4e1abd8ae8cafedd74c3da0f797a4183ffd Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 1 Mar 2020 10:54:03 +0100 Subject: [PATCH 2598/3224] Improved saving loadouts (see desc) - Only save weapon components if needed, wont save default clip anymore, and if no other component is available then its not saved at all - Tint index not stored if not above 0 - Weapon label not saved in database since its useless - Validate weapon on player load --- server/classes/player.lua | 43 +++++++++++++++++++++++++++++++-------- server/functions.lua | 2 +- server/main.lua | 23 +++++++++++++++------ 3 files changed, 52 insertions(+), 16 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 845b6f8d..d474a566 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -96,15 +96,15 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, self.getInventory = function(minimal) if minimal then - local items = {} + local minimalInventory = {} for k,v in ipairs(self.inventory) do if v.count > 0 then - items[v.name] = v.count + minimalInventory[v.name] = v.count end end - return items + return minimalInventory else return self.inventory end @@ -114,8 +114,33 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, return self.job end - self.getLoadout = function() - return self.loadout + self.getLoadout = function(minimal) + if minimal then + local minimalLoadout = {} + + for k,v in ipairs(self.loadout) do + minimalLoadout[v.name] = {ammo = v.ammo} + if v.tintIndex > 0 then minimalLoadout[v.name].tintIndex = v.tintIndex end + + if #v.components > 0 then + local components = {} + + for k2,component in ipairs(v.components) do + if component ~= 'clip_default' then + table.insert(components, component) + end + end + + if #components > 0 then + minimalLoadout[v.name].components = components + end + end + end + + return minimalLoadout + else + return self.loadout + end end self.getName = function() @@ -185,11 +210,11 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, if account then local newMoney = account.money + ESX.Math.Round(money) account.money = newMoney - + if accountName == 'bank' then self.set('bank', newMoney) end - + self.triggerEvent('esx:setAccountMoney', account) end end @@ -202,11 +227,11 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, if account then local newMoney = account.money - ESX.Math.Round(money) account.money = newMoney - + if accountName == 'bank' then self.set('bank', newMoney) end - + self.triggerEvent('esx:setAccountMoney', account) end end diff --git a/server/functions.lua b/server/functions.lua index f910b945..a0f3d5aa 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -182,7 +182,7 @@ ESX.SavePlayer = function(xPlayer, cb) MySQL.Async.execute('UPDATE users SET job = @job, job_grade = @job_grade, loadout = @loadout, position = @position, inventory = @inventory WHERE identifier = @identifier', { ['@job'] = xPlayer.job.name, ['@job_grade'] = xPlayer.job.grade, - ['@loadout'] = json.encode(xPlayer.getLoadout()), + ['@loadout'] = json.encode(xPlayer.getLoadout(true)), ['@position'] = json.encode(xPlayer.getCoords()), ['@identifier'] = xPlayer.identifier, ['@inventory'] = json.encode(xPlayer.getInventory(true)) diff --git a/server/main.lua b/server/main.lua index d1838418..b52782d0 100644 --- a/server/main.lua +++ b/server/main.lua @@ -133,13 +133,24 @@ function loadESXPlayer(identifier, playerId) return a.label < b.label end) - if result[1].loadout then - userData.loadout = json.decode(result[1].loadout) + if result[1].loadout and result[1].loadout ~= '' then + local loadout = json.decode(result[1].loadout) - -- compatibility with old loadouts - for k,v in ipairs(userData.loadout) do - if not v.components then v.components = {} end - if not v.tintIndex then v.tintIndex = 0 end + 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 From 7e9cee19a8791a57202245bd80136081067b0081 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 4 Mar 2020 11:05:31 +0100 Subject: [PATCH 2599/3224] Security improvement and minor cleanup --- client/main.lua | 17 +++---- config.lua | 11 ++--- server/main.lua | 127 +++++++++++++++++++++++------------------------- 3 files changed, 69 insertions(+), 86 deletions(-) diff --git a/client/main.lua b/client/main.lua index becd6c01..0d953449 100644 --- a/client/main.lua +++ b/client/main.lua @@ -392,19 +392,14 @@ end function OpenPutStocksMenu() ESX.TriggerServerCallback('esx_taxijob:getPlayerInventory', function(inventory) - local elements = {} - for i=1, #inventory.items, 1 do - local item = inventory.items[i] - - if item.count > 0 then - table.insert(elements, { - label = item.label .. ' x' .. item.count, - type = 'item_standard', -- not used - value = item.name - }) - end + for k,v in ipairs(inventory) do + table.insert(elements, { + label = v.label .. ' x' .. v.count, + type = 'item_standard', -- not used + value = v.name + }) end ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', { diff --git a/config.lua b/config.lua index cebf1139..8b887be6 100644 --- a/config.lua +++ b/config.lua @@ -1,23 +1,18 @@ Config = {} -Config.DrawDistance = 100.0 +Config.DrawDistance = 100 Config.NPCJobEarnings = {min = 300, max = 600} Config.MinimumDistance = 3000 -- Minimum NPC job destination distance from the pickup in GTA units, a higher number prevents nearby destionations. Config.MaxInService = -1 -Config.EnablePlayerManagement = false +Config.EnablePlayerManagement = true Config.EnableSocietyOwnedVehicles = false Config.Locale = 'fr' Config.AuthorizedVehicles = { - - { - model = 'taxi', - label = 'Taxi' - } - + {model = 'taxi', label = 'Taxi'} } Config.Zones = { diff --git a/server/main.lua b/server/main.lua index ab64c9f0..1667071c 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,4 +1,5 @@ ESX = nil +local lastPlayerSuccess = {} TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) @@ -9,70 +10,67 @@ end TriggerEvent('esx_phone:registerNumber', 'taxi', _U('taxi_client'), true, true) TriggerEvent('esx_society:registerSociety', 'taxi', 'Taxi', 'society_taxi', 'society_taxi', 'society_taxi', {type = 'public'}) -RegisterServerEvent('esx_taxijob:success') +RegisterNetEvent('esx_taxijob:success') AddEventHandler('esx_taxijob:success', function() local xPlayer = ESX.GetPlayerFromId(source) + local timeNow = os.clock() - if xPlayer.job.name ~= 'taxi' then - print(('esx_taxijob: %s attempted to trigger success!'):format(xPlayer.identifier)) - return - end + if xPlayer.job.name == 'taxi' then + if not lastPlayerSuccess[source] or timeNow - lastPlayerSuccess[source] > 5 then + lastPlayerSuccess[source] = timeNow - math.randomseed(os.time()) + math.randomseed(os.time()) + local total = math.random(Config.NPCJobEarnings.min, Config.NPCJobEarnings.max) - local total = math.random(Config.NPCJobEarnings.min, Config.NPCJobEarnings.max) - local societyAccount + if xPlayer.job.grade >= 3 then + total = total * 2 + end - if xPlayer.job.grade >= 3 then - total = total * 2 - end + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_taxi', function(account) + if account then + local playerMoney = ESX.Math.Round(total / 100 * 30) + local societyMoney = ESX.Math.Round(total / 100 * 70) - TriggerEvent('esx_addonaccount:getSharedAccount', 'society_taxi', function(account) - societyAccount = account - end) + xPlayer.addMoney(playerMoney) + account.addMoney(societyMoney) - if societyAccount then - local playerMoney = ESX.Math.Round(total / 100 * 30) - local societyMoney = ESX.Math.Round(total / 100 * 70) - - xPlayer.addMoney(playerMoney) - societyAccount.addMoney(societyMoney) - - xPlayer.showNotification(_U('comp_earned', societyMoney, playerMoney)) + xPlayer.showNotification(_U('comp_earned', societyMoney, playerMoney)) + else + xPlayer.addMoney(total) + xPlayer.showNotification(_U('have_earned', total)) + end + end) + end else - xPlayer.addMoney(total) - xPlayer.showNotification(_U('have_earned', total)) + print(('[esx_taxijob] [^3WARNING^7] %s attempted to trigger success (cheating)'):format(xPlayer.identifier)) end - end) -RegisterServerEvent('esx_taxijob:getStockItem') +RegisterNetEvent('esx_taxijob:getStockItem') AddEventHandler('esx_taxijob:getStockItem', function(itemName, count) local xPlayer = ESX.GetPlayerFromId(source) - if xPlayer.job.name ~= 'taxi' then - print(('esx_taxijob: %s attempted to trigger getStockItem!'):format(xPlayer.identifier)) - return - end - - TriggerEvent('esx_addoninventory:getSharedInventory', 'society_taxi', function(inventory) - local item = inventory.getItem(itemName) + if xPlayer.job.name == 'taxi' then + TriggerEvent('esx_addoninventory:getSharedInventory', 'society_taxi', function(inventory) + local item = inventory.getItem(itemName) - -- is there enough in the society? - if count > 0 and item.count >= count then - - -- can the player carry the said amount of x item? - if xPlayer.canCarryItem(itemName, count) then - inventory.removeItem(itemName, count) - xPlayer.addInventoryItem(itemName, count) - xPlayer.showNotification(_U('have_withdrawn', count, item.label)) + -- is there enough in the society? + if count > 0 and item.count >= count then + -- can the player carry the said amount of x item? + if xPlayer.canCarryItem(itemName, count) then + inventory.removeItem(itemName, count) + xPlayer.addInventoryItem(itemName, count) + xPlayer.showNotification(_U('have_withdrawn', count, item.label)) + else + xPlayer.showNotification(_U('player_cannot_hold')) + end else - xPlayer.showNotification(_U('player_cannot_hold')) + xPlayer.showNotification(_U('quantity_invalid')) end - else - xPlayer.showNotification(_U('quantity_invalid')) - end - end) + end) + else + print(('[esx_taxijob] [^3WARNING^7] %s attempted to trigger getStockItem'):format(xPlayer.identifier)) + end end) ESX.RegisterServerCallback('esx_taxijob:getStockItems', function(source, cb) @@ -81,33 +79,28 @@ ESX.RegisterServerCallback('esx_taxijob:getStockItems', function(source, cb) end) end) -RegisterServerEvent('esx_taxijob:putStockItems') +RegisterNetEvent('esx_taxijob:putStockItems') AddEventHandler('esx_taxijob:putStockItems', function(itemName, count) local xPlayer = ESX.GetPlayerFromId(source) - if xPlayer.job.name ~= 'taxi' then - print(('esx_taxijob: %s attempted to trigger putStockItems!'):format(xPlayer.identifier)) - return + if xPlayer.job.name == 'taxi' then + TriggerEvent('esx_addoninventory:getSharedInventory', 'society_taxi', function(inventory) + local item = inventory.getItem(itemName) + + if item.count >= 0 then + xPlayer.removeInventoryItem(itemName, count) + inventory.addItem(itemName, count) + xPlayer.showNotification(_U('have_deposited', count, item.label)) + else + xPlayer.showNotification(_U('quantity_invalid')) + end + end) + else + print(('[esx_taxijob] [^3WARNING^7] %s attempted to trigger putStockItems'):format(xPlayer.identifier)) end - - TriggerEvent('esx_addoninventory:getSharedInventory', 'society_taxi', function(inventory) - local item = inventory.getItem(itemName) - - if item.count >= 0 then - xPlayer.removeInventoryItem(itemName, count) - inventory.addItem(itemName, count) - xPlayer.showNotification(_U('have_deposited', count, item.label)) - else - xPlayer.showNotification(_U('quantity_invalid')) - end - - end) - end) ESX.RegisterServerCallback('esx_taxijob:getPlayerInventory', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) - local items = xPlayer.inventory - - cb( { items = items } ) + cb(xPlayer.getInventory()) end) From 8c719dcb23f66c1328155d7d186bfeebef837d73 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 4 Mar 2020 11:23:01 +0100 Subject: [PATCH 2600/3224] Added missing crutial add_principal use to server configuration file --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a4e358c1..4dceab2d 100644 --- a/README.md +++ b/README.md @@ -17,11 +17,10 @@ es_extended is a roleplay framework for FiveM. ESX is short for **Es**sentialMod - Job system, with grades and clothes support - Supports multiple languages, most strings are localized - Easy to use API for developers to easily integrate ESX to their projects +- Register your own commands easily, with argument validation, chat suggestion and using FXServer ACL ## Requirements -This order also applies in the startup order. - - [mysql-async](https://github.com/brouznouf/fivem-mysql-async) - [async](https://github.com/ESX-Org/async) @@ -63,6 +62,7 @@ git clone https://github.com/ESX-Org/esx_menu_list [esx]/[ui]/esx_menu_list - Configure your `server.cfg` to look like this ``` +add_principal group.admin group.user add_ace resource.es_extended command.add_ace allow add_ace resource.es_extended command.add_principal allow From c4655598f99451060aed2b5f1993b2c7d50976b6 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 4 Mar 2020 11:28:34 +0100 Subject: [PATCH 2601/3224] Removed ES leftover code --- server/classes/player.lua | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index d474a566..042100fd 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -191,13 +191,8 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, if account then local prevMoney = account.money local newMoney = ESX.Math.Round(money) - account.money = newMoney - if accountName == 'bank' then - self.set('bank', newMoney) - end - self.triggerEvent('esx:setAccountMoney', account) end end @@ -211,10 +206,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, local newMoney = account.money + ESX.Math.Round(money) account.money = newMoney - if accountName == 'bank' then - self.set('bank', newMoney) - end - self.triggerEvent('esx:setAccountMoney', account) end end @@ -228,10 +219,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, local newMoney = account.money - ESX.Math.Round(money) account.money = newMoney - if accountName == 'bank' then - self.set('bank', newMoney) - end - self.triggerEvent('esx:setAccountMoney', account) end end From 4e4ebfff7b8294be49eaa5269d043e24561c5c56 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 4 Mar 2020 12:41:57 +0100 Subject: [PATCH 2602/3224] Re-done locale names for commands, moved hardcoded strings to locale and added /setgroup command --- locales/br.lua | 56 +++++++++++++++++++++--------- locales/cs.lua | 64 +++++++++++++++++++++++----------- locales/de.lua | 60 ++++++++++++++++++++++---------- locales/en.lua | 60 ++++++++++++++++++++++---------- locales/fi.lua | 60 ++++++++++++++++++++++---------- locales/fr.lua | 60 ++++++++++++++++++++++---------- locales/pl.lua | 60 ++++++++++++++++++++++---------- locales/sv.lua | 56 +++++++++++++++++++++--------- server/commands.lua | 83 ++++++++++++++++++++++++-------------------- server/functions.lua | 14 ++++---- 10 files changed, 378 insertions(+), 195 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index 3258ea49..7b115f96 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -54,25 +54,47 @@ Locales['br'] = { ['in_vehicle'] = 'voce não pode dar nada para alguem no veículo', -- Commands - ['setjob'] = 'atribuir um trabalho a um usuario', - ['id_param'] = 'o ID do jogador', - ['setjob_param2'] = 'o trabalho que voce deseja atribuir', - ['setjob_param3'] = 'o nivel de emprego', - ['spawn_car'] = 'spawn um carro', - ['spawn_car_param'] = 'nome do carro', - ['delete_vehicle'] = 'excluir veículo', - ['invalid_account'] = 'conta inválida', - ['account'] = 'conta', - ['giveaccountmoney'] = 'dar dinheiro da conta', - ['invalid_item'] = 'item invalido', - ['item'] = 'item', - ['giveitem'] = 'dar item', - ['weapon'] = 'arma', - ['giveweapon'] = 'dar arma', - ['chat_clear'] = 'limpar o chat', - ['chat_clear_all'] = 'limpar o chat para todos', + ['command_car'] = 'spawn um carro', + ['command_car_car'] = 'nome do carro', + ['command_cardel'] = 'excluir veículo', + ['command_cardel_radius'] = 'optional, delete every vehicle within the specified radius', + ['command_clear'] = 'limpar o chat', + ['command_clearall'] = 'limpar o chat para todos', ['command_clearinventory'] = 'remover todos os itens do inventário', ['command_clearloadout'] = 'remova todas as armas do carregamento', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'atribuir um trabalho a um usuario', + ['command_setjob_job'] = 'o trabalho que voce deseja atribuir', + ['command_setjob_grade'] = 'o nivel de emprego', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', + ['command_giveaccountmoney'] = 'dar dinheiro da conta', + ['command_giveaccountmoney_account'] = 'conta', + ['command_giveaccountmoney_amount'] = 'amount', + ['command_giveaccountmoney_invalid'] = 'conta inválida', + ['command_giveitem'] = 'dar item', + ['command_giveitem_item'] = 'item', + ['command_giveitem_count'] = 'count', + ['command_giveweapon'] = 'dar arma', + ['command_giveweapon_weapon'] = 'arma', + ['command_giveweapon_ammo'] = 'ammo count', + ['command_giveweapon_hasalready'] = 'player already has that weapon', + ['command_giveweaponcomponent'] = 'give weapon component', + ['command_giveweaponcomponent_component'] = 'component name', + ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', + ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', + ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', + ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', + ['commanderror_invaliditem'] = 'item invalido', + ['commanderror_invalidweapon'] = 'invalid weapon', + ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', + ['commandgeneric_playerid'] = 'o ID do jogador', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/locales/cs.lua b/locales/cs.lua index bc69b191..b99bebf0 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -53,28 +53,50 @@ Locales['cs'] = { ['act_imp'] = 'akce není možná', ['in_vehicle'] = 'nemůže nic dát osobě ve vozidle', - -- Commands - ['setjob'] = 'přiřadit práci hráči', - ['id_param'] = 'iD hráče', - ['setjob_param2'] = 'název přiřazované práce', - ['setjob_param3'] = 'úroveň práce', - ['spawn_car'] = 'spawn auto', - ['spawn_car_param'] = 'název auta', - ['delete_vehicle'] = 'odstranit vozidlo', - ['invalid_account'] = 'neplatný účet', - ['account'] = 'účet', - ['giveaccountmoney'] = 'dát peníze na účet', - ['invalid_item'] = 'neplatná věc', - ['item'] = 'věc', - ['giveitem'] = 'dát věc', - ['weapon'] = 'zbraň', - ['giveweapon'] = 'dát zbraň', - ['chat_clear'] = 'vyčistit chat', - ['chat_clear_all'] = 'vyčistit chat pro všechny', - ['command_clearinventory'] = 'vycistit vsechny predmety v invetari', - ['command_clearloadout'] = 'odebrat vsechny zbrane z rukz', + -- Commands + ['command_car'] = 'spawn an vehicle', + ['command_car_car'] = 'vehicle spawn name or hash', + ['command_cardel'] = 'delete vehicle in proximity', + ['command_cardel_radius'] = 'optional, delete every vehicle within the specified radius', + ['command_clear'] = 'clear chat', + ['command_clearall'] = 'clear chat for all players', + ['command_clearinventory'] = 'clear player inventory', + ['command_clearloadout'] = 'clear a player loadout', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'set job for a player', + ['command_setjob_job'] = 'job name', + ['command_setjob_grade'] = 'job grade', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', + ['command_giveaccountmoney'] = 'give account money', + ['command_giveaccountmoney_account'] = 'valid account name', + ['command_giveaccountmoney_amount'] = 'amount to add', + ['command_giveaccountmoney_invalid'] = 'invalid account name', + ['command_giveitem'] = 'give an item to a player', + ['command_giveitem_item'] = 'item name', + ['command_giveitem_count'] = 'item count', + ['command_giveweapon'] = 'give a weapon to a player', + ['command_giveweapon_weapon'] = 'weapon name', + ['command_giveweapon_ammo'] = 'ammo count', + ['command_giveweapon_hasalready'] = 'player already has that weapon', + ['command_giveweaponcomponent'] = 'give weapon component', + ['command_giveweaponcomponent_component'] = 'component name', + ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', + ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', + ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', + ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', + ['commanderror_invaliditem'] = 'invalid item name', + ['commanderror_invalidweapon'] = 'invalid weapon', + ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', + ['commandgeneric_playerid'] = 'player id', - -- Locale settings + -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', diff --git a/locales/de.lua b/locales/de.lua index 4ccb00a9..86247f0b 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -54,25 +54,47 @@ Locales['de'] = { ['in_vehicle'] = 'du kannst keine Items in einem Fahrzeug weitergeben', -- Commands - ['setjob'] = 'spieler Job zuweisen', - ['id_param'] = 'ID von Spieler', - ['setjob_param2'] = 'der zu vergebende Job', - ['setjob_param3'] = 'der Jobgrad', - ['spawn_car'] = 'fahrzeug spawnen', - ['spawn_car_param'] = 'fahrzeugname', - ['delete_vehicle'] = 'entfernt Fahrzeuge', - ['invalid_account'] = 'ungültige Anzahl', - ['account'] = 'bank', - ['giveaccountmoney'] = 'bankgeld geben', - ['invalid_item'] = 'ungültiges Item', - ['item'] = 'item', - ['giveitem'] = 'item geben', - ['weapon'] = 'waffe', - ['giveweapon'] = 'waffe geben', - ['chat_clear'] = 'chat leeren', - ['chat_clear_all'] = 'chat für jeden leeren', - ['command_clearinventory'] = 'alle Items aus dem Inventar entfernen', - ['command_clearloadout'] = 'alle Waffen aus dem Loadout entfernen', + ['command_car'] = 'spawn an vehicle', + ['command_car_car'] = 'vehicle spawn name or hash', + ['command_cardel'] = 'delete vehicle in proximity', + ['command_cardel_radius'] = 'optional, delete every vehicle within the specified radius', + ['command_clear'] = 'clear chat', + ['command_clearall'] = 'clear chat for all players', + ['command_clearinventory'] = 'clear player inventory', + ['command_clearloadout'] = 'clear a player loadout', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'set job for a player', + ['command_setjob_job'] = 'job name', + ['command_setjob_grade'] = 'job grade', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', + ['command_giveaccountmoney'] = 'give account money', + ['command_giveaccountmoney_account'] = 'valid account name', + ['command_giveaccountmoney_amount'] = 'amount to add', + ['command_giveaccountmoney_invalid'] = 'invalid account name', + ['command_giveitem'] = 'give an item to a player', + ['command_giveitem_item'] = 'item name', + ['command_giveitem_count'] = 'item count', + ['command_giveweapon'] = 'give a weapon to a player', + ['command_giveweapon_weapon'] = 'weapon name', + ['command_giveweapon_ammo'] = 'ammo count', + ['command_giveweapon_hasalready'] = 'player already has that weapon', + ['command_giveweaponcomponent'] = 'give weapon component', + ['command_giveweaponcomponent_component'] = 'component name', + ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', + ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', + ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', + ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', + ['commanderror_invaliditem'] = 'invalid item name', + ['commanderror_invalidweapon'] = 'invalid weapon', + ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', + ['commandgeneric_playerid'] = 'player id', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/locales/en.lua b/locales/en.lua index 44c4c680..e7a6549b 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -54,25 +54,47 @@ Locales['en'] = { ['in_vehicle'] = 'you can\'t give anything to someone in a vehicle', -- Commands - ['setjob'] = 'assign a job to a user', - ['id_param'] = 'the ID of the player', - ['setjob_param2'] = 'the job you wish to assign', - ['setjob_param3'] = 'the job level', - ['spawn_car'] = 'spawn a car', - ['spawn_car_param'] = 'name of car', - ['delete_vehicle'] = 'deletes Vehicle', - ['invalid_account'] = 'invalid account', - ['account'] = 'account', - ['giveaccountmoney'] = 'give account money', - ['invalid_item'] = 'invalid item', - ['item'] = 'item', - ['giveitem'] = 'give item', - ['weapon'] = 'weapon', - ['giveweapon'] = 'give weapon', - ['chat_clear'] = 'clear the chat', - ['chat_clear_all'] = 'clear the chat for everyone', - ['command_clearinventory'] = 'clear all items from inventory', - ['command_clearloadout'] = 'remove all weapons from loadout', + ['command_car'] = 'spawn an vehicle', + ['command_car_car'] = 'vehicle spawn name or hash', + ['command_cardel'] = 'delete vehicle in proximity', + ['command_cardel_radius'] = 'optional, delete every vehicle within the specified radius', + ['command_clear'] = 'clear chat', + ['command_clearall'] = 'clear chat for all players', + ['command_clearinventory'] = 'clear player inventory', + ['command_clearloadout'] = 'clear a player loadout', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'set job for a player', + ['command_setjob_job'] = 'job name', + ['command_setjob_grade'] = 'job grade', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', + ['command_giveaccountmoney'] = 'give account money', + ['command_giveaccountmoney_account'] = 'valid account name', + ['command_giveaccountmoney_amount'] = 'amount to add', + ['command_giveaccountmoney_invalid'] = 'invalid account name', + ['command_giveitem'] = 'give an item to a player', + ['command_giveitem_item'] = 'item name', + ['command_giveitem_count'] = 'item count', + ['command_giveweapon'] = 'give a weapon to a player', + ['command_giveweapon_weapon'] = 'weapon name', + ['command_giveweapon_ammo'] = 'ammo count', + ['command_giveweapon_hasalready'] = 'player already has that weapon', + ['command_giveweaponcomponent'] = 'give weapon component', + ['command_giveweaponcomponent_component'] = 'component name', + ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', + ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', + ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', + ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', + ['commanderror_invaliditem'] = 'invalid item name', + ['commanderror_invalidweapon'] = 'invalid weapon', + ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', + ['commandgeneric_playerid'] = 'player id', -- Locale settings ['locale_digit_grouping_symbol'] = ',', diff --git a/locales/fi.lua b/locales/fi.lua index 6e113511..cd3b3d6b 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -54,25 +54,47 @@ Locales['fi'] = { ['in_vehicle'] = 'et voi antaa ajoneuvossa olevalle mitään', -- Commands - ['setjob'] = 'määritä työ käyttäjälle', - ['id_param'] = 'käyttäjän ID', - ['setjob_param2'] = 'työ jonka haluat määrittää', - ['setjob_param3'] = 'työn taso', - ['spawn_car'] = 'spawnaa ajoneuvo', - ['spawn_car_param'] = 'ajoneuvon nimi', - ['delete_vehicle'] = 'poistaa ajoneuvon', - ['invalid_account'] = 'virheellinen tunnus', - ['account'] = 'tunnus', - ['giveaccountmoney'] = 'anna tilille rahaa', - ['invalid_item'] = 'virheellinen itemi', - ['item'] = 'esine', - ['giveitem'] = 'anna itemi', - ['weapon'] = 'ase', - ['giveweapon'] = 'anna ase', - ['chat_clear'] = 'tyhjennä chatti', - ['chat_clear_all'] = 'tyhjennä chatti kaikilta', - ['command_clearinventory'] = 'clear all items from inventory', - ['command_clearloadout'] = 'remove all weapons from loadout', + ['command_car'] = 'spawn an vehicle', + ['command_car_car'] = 'vehicle spawn name or hash', + ['command_cardel'] = 'delete vehicle in proximity', + ['command_cardel_radius'] = 'optional, delete every vehicle within the specified radius', + ['command_clear'] = 'clear chat', + ['command_clearall'] = 'clear chat for all players', + ['command_clearinventory'] = 'clear player inventory', + ['command_clearloadout'] = 'clear a player loadout', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'set job for a player', + ['command_setjob_job'] = 'job name', + ['command_setjob_grade'] = 'job grade', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', + ['command_giveaccountmoney'] = 'give account money', + ['command_giveaccountmoney_account'] = 'valid account name', + ['command_giveaccountmoney_amount'] = 'amount to add', + ['command_giveaccountmoney_invalid'] = 'invalid account name', + ['command_giveitem'] = 'give an item to a player', + ['command_giveitem_item'] = 'item name', + ['command_giveitem_count'] = 'item count', + ['command_giveweapon'] = 'give a weapon to a player', + ['command_giveweapon_weapon'] = 'weapon name', + ['command_giveweapon_ammo'] = 'ammo count', + ['command_giveweapon_hasalready'] = 'player already has that weapon', + ['command_giveweaponcomponent'] = 'give weapon component', + ['command_giveweaponcomponent_component'] = 'component name', + ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', + ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', + ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', + ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', + ['commanderror_invaliditem'] = 'invalid item name', + ['commanderror_invalidweapon'] = 'invalid weapon', + ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', + ['commandgeneric_playerid'] = 'player id', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/locales/fr.lua b/locales/fr.lua index 9e5bd015..350055bc 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -54,25 +54,47 @@ Locales['fr'] = { ['in_vehicle'] = 'Vous ne pouvez rien donner à quelqu\'un dans un véhicule', -- Commands - ['setjob'] = 'assigner job', - ['id_param'] = 'identification du joueur', - ['setjob_param2'] = 'le travail que vous souhaitez assigner', - ['setjob_param3'] = 'le niveau d\'emploi', - ['spawn_car'] = 'spawn un véhicule', - ['spawn_car_param'] = 'nom de la voiture', - ['delete_vehicle'] = 'supprimer le véhicule', - ['invalid_account'] = 'compte invalide', - ['account'] = 'compte', - ['giveaccountmoney'] = 'donner de l\'argent au compte', - ['invalid_item'] = 'item invalide', - ['item'] = 'article', - ['giveitem'] = 'donner un article', - ['weapon'] = 'arme', - ['giveweapon'] = 'donner l\'arme', - ['chat_clear'] = 'vider le chat', - ['chat_clear_all'] = 'vider le chat pour tous le monde', - ['command_clearinventory'] = 'effacer tout les items de l\'inventaire', - ['command_clearloadout'] = 'retirer toutes les armes de l\'équipement', + ['command_car'] = 'spawn an vehicle', + ['command_car_car'] = 'vehicle spawn name or hash', + ['command_cardel'] = 'delete vehicle in proximity', + ['command_cardel_radius'] = 'optional, delete every vehicle within the specified radius', + ['command_clear'] = 'clear chat', + ['command_clearall'] = 'clear chat for all players', + ['command_clearinventory'] = 'clear player inventory', + ['command_clearloadout'] = 'clear a player loadout', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'set job for a player', + ['command_setjob_job'] = 'job name', + ['command_setjob_grade'] = 'job grade', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', + ['command_giveaccountmoney'] = 'give account money', + ['command_giveaccountmoney_account'] = 'valid account name', + ['command_giveaccountmoney_amount'] = 'amount to add', + ['command_giveaccountmoney_invalid'] = 'invalid account name', + ['command_giveitem'] = 'give an item to a player', + ['command_giveitem_item'] = 'item name', + ['command_giveitem_count'] = 'item count', + ['command_giveweapon'] = 'give a weapon to a player', + ['command_giveweapon_weapon'] = 'weapon name', + ['command_giveweapon_ammo'] = 'ammo count', + ['command_giveweapon_hasalready'] = 'player already has that weapon', + ['command_giveweaponcomponent'] = 'give weapon component', + ['command_giveweaponcomponent_component'] = 'component name', + ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', + ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', + ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', + ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', + ['commanderror_invaliditem'] = 'invalid item name', + ['commanderror_invalidweapon'] = 'invalid weapon', + ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', + ['commandgeneric_playerid'] = 'player id', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/locales/pl.lua b/locales/pl.lua index a691437a..3f727d5f 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -54,25 +54,47 @@ Locales['pl'] = { ['in_vehicle'] = 'nie możesz przekazywać przedmiotów w pojeździe', -- Commands - ['setjob'] = 'przydziel prace użytkownikowi', - ['id_param'] = 'ID użytkownika', - ['setjob_param2'] = 'praca, którą chcesz przydzielić', - ['setjob_param3'] = 'poziom pracy', - ['spawn_car'] = 'sprowadź pojazd', - ['spawn_car_param'] = 'nazwa samochodu', - ['delete_vehicle'] = 'usuń pojazd', - ['invalid_account'] = 'błędne konto', - ['account'] = 'konto', - ['giveaccountmoney'] = 'daj pieniądze na konto', - ['invalid_item'] = 'nieprawidłowy przedmiot', - ['item'] = 'przedmiot', - ['giveitem'] = 'daj przedmiot', - ['weapon'] = 'broń', - ['giveweapon'] = 'daj broń', - ['chat_clear'] = 'wyczyść czat', - ['chat_clear_all'] = 'wyczyść czat dla wszystkich', - ['command_clearinventory'] = 'usuń wszystkie przedmioty z ekwipunku', - ['command_clearloadout'] = 'usuń wszystkie bronie z wyposażenia', + ['command_car'] = 'spawn an vehicle', + ['command_car_car'] = 'vehicle spawn name or hash', + ['command_cardel'] = 'delete vehicle in proximity', + ['command_cardel_radius'] = 'optional, delete every vehicle within the specified radius', + ['command_clear'] = 'clear chat', + ['command_clearall'] = 'clear chat for all players', + ['command_clearinventory'] = 'clear player inventory', + ['command_clearloadout'] = 'clear a player loadout', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'set job for a player', + ['command_setjob_job'] = 'job name', + ['command_setjob_grade'] = 'job grade', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', + ['command_giveaccountmoney'] = 'give account money', + ['command_giveaccountmoney_account'] = 'valid account name', + ['command_giveaccountmoney_amount'] = 'amount to add', + ['command_giveaccountmoney_invalid'] = 'invalid account name', + ['command_giveitem'] = 'give an item to a player', + ['command_giveitem_item'] = 'item name', + ['command_giveitem_count'] = 'item count', + ['command_giveweapon'] = 'give a weapon to a player', + ['command_giveweapon_weapon'] = 'weapon name', + ['command_giveweapon_ammo'] = 'ammo count', + ['command_giveweapon_hasalready'] = 'player already has that weapon', + ['command_giveweaponcomponent'] = 'give weapon component', + ['command_giveweaponcomponent_component'] = 'component name', + ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', + ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', + ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', + ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', + ['commanderror_invaliditem'] = 'invalid item name', + ['commanderror_invalidweapon'] = 'invalid weapon', + ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', + ['commandgeneric_playerid'] = 'player id', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/locales/sv.lua b/locales/sv.lua index 8be097c6..df1f21db 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -54,25 +54,47 @@ Locales['sv'] = { ['in_vehicle'] = 'du kan inte ge saker till en som sitter i ett fordon!', -- Commands - ['setjob'] = 'tilldela ett jobb till en spelare', - ['id_param'] = 'spelarens ID', - ['setjob_param2'] = 'det jobb du vill tilldela', - ['setjob_param3'] = 'job nivå', - ['spawn_car'] = 'spawna ett fordon', - ['spawn_car_param'] = 'namn på fordon', - ['delete_vehicle'] = 'ta bort fordon', - ['invalid_account'] = 'ogiltigt konto', - ['account'] = 'konto', - ['giveaccountmoney'] = 'ge spelarkonto pengar', - ['invalid_item'] = 'ogiltigt föremål', - ['item'] = 'föremål', - ['giveitem'] = 'ge ett föremål', - ['weapon'] = 'vapen', - ['giveweapon'] = 'ge ett vapen', - ['chat_clear'] = 'töm chatten', - ['chat_clear_all'] = 'töm chatten för alla', + ['command_car'] = 'spawna ett fordon', + ['command_car_car'] = 'namn på fordon eller hash', + ['command_cardel'] = 'radera fordon i närheten', + ['command_cardel_radius'] = 'valfri, radera alla fordon inom den angivna radien', + ['command_clear'] = 'töm chatten', + ['command_clearall'] = 'töm chatten för alla spelare', ['command_clearinventory'] = 'töm en spelares inventory', ['command_clearloadout'] = 'töm en spelares loadout', + ['command_setcoords'] = 'teleportera till koordinater', + ['command_setcoords_x'] = 'x axel', + ['command_setcoords_y'] = 'y axel', + ['command_setcoords_z'] = 'z axel', + ['command_setjob'] = 'välj jobb för en spelare', + ['command_setjob_job'] = 'jobbnamn', + ['command_setjob_grade'] = 'jobbnivå', + ['command_setjob_invalid'] = 'jobbet, nivån eller båda är ej giltiga', + ['command_setgroup'] = 'välj grupp åt en spelare', + ['command_setgroup_group'] = 'gruppnamn', + ['command_giveaccountmoney'] = 'ge pengar för ett konto', + ['command_giveaccountmoney_account'] = 'giltigt kontonamn', + ['command_giveaccountmoney_amount'] = 'mängd att ge', + ['command_giveaccountmoney_invalid'] = 'kontonamnet är ej giltigt', + ['command_giveitem'] = 'ge ett item till en spelare', + ['command_giveitem_item'] = 'itemnamn', + ['command_giveitem_count'] = 'mängd av itemet', + ['command_giveweapon'] = 'ge ett vapen till en spelare', + ['command_giveweapon_weapon'] = 'vapennamn', + ['command_giveweapon_ammo'] = 'hur mycket ammo att ge', + ['command_giveweapon_hasalready'] = 'spelaren har redan ett sådant vapen', + ['command_giveweaponcomponent'] = 'ge vapen komponent', + ['command_giveweaponcomponent_component'] = 'vapenkomponent', + ['command_giveweaponcomponent_invalid'] = 'det vapenkomponentet är ej giltigt', + ['command_giveweaponcomponent_hasalready'] = 'spelaren har redan det vapenkomponent', + ['command_giveweaponcomponent_missingweapon'] = 'spelaren har ej det vapnet', + ['commanderror_argumentmismatch'] = 'argumentstorlek mismatch (gav %s, ville ha %s)', + ['commanderror_argumentmismatch_number'] = 'argument #%s typ mismatch (gav string, ville ha number)', + ['commanderror_invaliditem'] = 'ej giltigt item', + ['commanderror_invalidweapon'] = 'ej giltigt vapen', + ['commanderror_console'] = 'detta kommando kan ej executas i konsol', + ['commanderror_invalidplayerid'] = 'det finns ingen spelare som matchar det angivna server id', + ['commandgeneric_playerid'] = 'spelarid', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/server/commands.lua b/server/commands.lua index 23892beb..1639edd2 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -1,65 +1,65 @@ ESX.RegisterCommand('setcoords', 'admin', function(xPlayer, args, showError) xPlayer.setCoords({x = args.x, y = args.y, z = args.z}) -end, false, {help = 'Teleport to coordinates', validate = true, arguments = { - {name = 'x', help = 'X coords', type = 'number'}, - {name = 'y', help = 'Y coords', type = 'number'}, - {name = 'z', help = 'Z coords', type = 'number'} +end, false, {help = _U('command_setcoords'), validate = true, arguments = { + {name = 'x', help = _U('command_setcoords_x'), type = 'number'}, + {name = 'y', help = _U('command_setcoords_y'), type = 'number'}, + {name = 'z', help = _U('command_setcoords_z'), type = 'number'} }}) ESX.RegisterCommand('setjob', 'admin', function(xPlayer, args, showError) if ESX.DoesJobExist(args.job, args.grade) then args.playerId.setJob(args.job, args.grade) else - showError('That job does not exist') + showError(_U('command_setjob_invalid')) end -end, true, {help = _U('setjob'), validate = true, arguments = { - {name = 'playerId', help = _U('id_param'), type = 'player'}, - {name = 'job', help = _U('setjob_param2'), type = 'string'}, - {name = 'grade', help = _U('setjob_param3'), type = 'number'} +end, true, {help = _U('command_setjob'), validate = true, arguments = { + {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'}, + {name = 'job', help = _U('command_setjob_job'), type = 'string'}, + {name = 'grade', help = _U('command_setjob_grade'), type = 'number'} }}) ESX.RegisterCommand('car', 'admin', function(xPlayer, args, showError) xPlayer.triggerEvent('esx:spawnVehicle', args.car) -end, false, {help = _U('spawn_car'), validate = false, arguments = { - {name = 'car', help = _U('spawn_car_param'), type = 'any'} +end, false, {help = _U('command_car'), validate = false, arguments = { + {name = 'car', help = _U('command_car_car'), type = 'any'} }}) ESX.RegisterCommand({'cardel', 'dv'}, 'admin', function(xPlayer, args, showError) xPlayer.triggerEvent('esx:deleteVehicle', args.radius) -end, false, {help = _U('spawn_car'), validate = false, arguments = { - {name = 'radius', help = 'Optional, delete every vehicle within the specified radius', type = 'any'} +end, false, {help = _U('command_cardel'), validate = false, arguments = { + {name = 'radius', help = _U('command_cardel_radius'), type = 'any'} }}) ESX.RegisterCommand('giveaccountmoney', 'admin', function(xPlayer, args, showError) if args.playerId.getAccount(args.account) then args.playerId.addAccountMoney(args.account, args.amount) else - showError(_U('invalid_account')) + showError(_U('command_giveaccountmoney_invalid')) end -end, true, {help = _U('giveaccountmoney'), validate = true, arguments = { - {name = 'playerId', help = _U('id_param'), type = 'player'}, - {name = 'account', help = _U('account'), type = 'string'}, - {name = 'amount', help = _U('money_amount'), type = 'number'} +end, true, {help = _U('command_giveaccountmoney'), validate = true, arguments = { + {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'}, + {name = 'account', help = _U('command_giveaccountmoney_account'), type = 'string'}, + {name = 'amount', help = _U('command_giveaccountmoney_amount'), type = 'number'} }}) ESX.RegisterCommand('giveitem', 'admin', function(xPlayer, args, showError) args.playerId.addInventoryItem(args.item, args.count) -end, true, {help = _U('giveitem'), validate = true, arguments = { - {name = 'playerId', help = _U('id_param'), type = 'player'}, - {name = 'item', help = _U('item'), type = 'item'}, - {name = 'count', help = _U('amount'), type = 'number'} +end, true, {help = _U('command_giveitem'), validate = true, arguments = { + {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'}, + {name = 'item', help = _U('command_giveitem_item'), type = 'item'}, + {name = 'count', help = _U('command_giveitem_count'), type = 'number'} }}) ESX.RegisterCommand('giveweapon', 'admin', function(xPlayer, args, showError) if args.playerId.hasWeapon(args.weapon) then - showError('Player already has that weapon') + showError(_U('command_giveweapon_hasalready')) else xPlayer.addWeapon(args.weapon, args.ammo) end -end, true, {help = _U('giveweapon'), validate = true, arguments = { - {name = 'playerId', help = _U('id_param'), type = 'player'}, - {name = 'weapon', help = _U('weapon'), type = 'weapon'}, - {name = 'ammo', help = _U('amountammo'), type = 'number'} +end, true, {help = _U('command_giveweapon'), validate = true, arguments = { + {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'}, + {name = 'weapon', help = _U('command_giveweapon_weapon'), type = 'weapon'}, + {name = 'ammo', help = _U('command_giveweapon_ammo'), type = 'number'} }}) ESX.RegisterCommand('giveweaponcomponent', 'admin', function(xPlayer, args, showError) @@ -68,29 +68,29 @@ ESX.RegisterCommand('giveweaponcomponent', 'admin', function(xPlayer, args, show if component then if xPlayer.hasWeaponComponent(args.weaponName, args.componentName) then - showError('Player already has that weapon component') + showError(_U('command_giveweaponcomponent_hasalready')) else xPlayer.addWeaponComponent(args.weaponName, args.componentName) end else - showError('Invalid weapon component') + showError(_U('command_giveweaponcomponent_invalid')) end else - showError('Player does not have that weapon') + showError(_U('command_giveweaponcomponent_missingweapon')) end -end, true, {help = 'Give weapon component', validate = true, arguments = { - {name = 'playerId', help = _U('id_param'), type = 'player'}, - {name = 'weaponName', help = _U('weapon'), type = 'weapon'}, - {name = 'componentName', help = 'weapon component', type = 'string'} +end, true, {help = _U('command_giveweaponcomponent'), validate = true, arguments = { + {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'}, + {name = 'weaponName', help = _U('command_giveweapon_weapon'), type = 'weapon'}, + {name = 'componentName', help = _U('command_giveweaponcomponent_component'), type = 'string'} }}) ESX.RegisterCommand({'clear', 'cls'}, 'user', function(xPlayer, args, showError) xPlayer.triggerEvent('chat:clear') -end, false, {help = _U('chat_clear')}) +end, false, {help = _U('command_clear')}) ESX.RegisterCommand({'clearall', 'clsall'}, 'admin', function(xPlayer, args, showError) TriggerClientEvent('chat:clear', -1) -end, false, {help = _U('chat_clear_all')}) +end, false, {help = _U('command_clearall')}) ESX.RegisterCommand('clearinventory', 'admin', function(xPlayer, args, showError) for k,v in ipairs(args.playerId.inventory) do @@ -99,7 +99,7 @@ ESX.RegisterCommand('clearinventory', 'admin', function(xPlayer, args, showError end end end, true, {help = _U('command_clearinventory'), validate = true, arguments = { - {name = 'playerId', help = _U('id_param'), type = 'player'} + {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'} }}) ESX.RegisterCommand('clearloadout', 'admin', function(xPlayer, args, showError) @@ -107,5 +107,12 @@ ESX.RegisterCommand('clearloadout', 'admin', function(xPlayer, args, showError) args.playerId.removeWeapon(v.name) end end, true, {help = _U('command_clearloadout'), validate = true, arguments = { - {name = 'playerId', help = _U('id_param'), type = 'player'} + {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'} +}}) + +ESX.RegisterCommand('setgroup', 'admin', function(xPlayer, args, showError) + args.playerId.setGorup(args.group) +end, true, {help = _U('command_setgroup'), validate = true, arguments = { + {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'}, + {name = 'group', help = _U('command_setgroup_group'), type = 'string'}, }}) diff --git a/server/functions.lua b/server/functions.lua index a0f3d5aa..caf97a02 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -50,14 +50,14 @@ ESX.RegisterCommand = function(name, group, cb, allowConsole, suggestion) local command = ESX.RegisteredCommands[name] if not command.allowConsole and playerId == 0 then - print('[es_extended] [^3WARNING^7] That command can not be run from console') + print(('[es_extended] [^3WARNING^7] %s'):format(_U('commanderror_console'))) else local xPlayer, error = ESX.GetPlayerFromId(playerId), nil if command.suggestion then if command.suggestion.validate then if #args ~= #command.suggestion.arguments then - error = ('Argument count mismatch (passed %s, wanted %s)'):format(#args, #command.suggestion.arguments) + error = _U('commanderror_argumentmismatch', #args, #command.suggestion.arguments) end end @@ -72,7 +72,7 @@ ESX.RegisterCommand = function(name, group, cb, allowConsole, suggestion) if newArg then newArgs[v.name] = newArg else - error = ('Argument #%s type mismatch (passed string, wanted number)'):format(k) + error = _U('commanderror_argumentmismatch_number', k) end elseif v.type == 'player' or v.type == 'playerId' then local targetPlayer = tonumber(args[k]) @@ -89,10 +89,10 @@ ESX.RegisterCommand = function(name, group, cb, allowConsole, suggestion) newArgs[v.name] = targetPlayer end else - error = 'Player not online' + error = _U('commanderror_invalidplayerid') end else - error = ('Argument #%s type mismatch (passed string, wanted number)'):format(k) + error = _U('commanderror_argumentmismatch_number', k) end elseif v.type == 'string' then newArgs[v.name] = args[k] @@ -100,13 +100,13 @@ ESX.RegisterCommand = function(name, group, cb, allowConsole, suggestion) if ESX.Items[args[k]] then newArgs[v.name] = args[k] else - error = _U('invalid_item') + error = _U('commanderror_invaliditem') end elseif v.type == 'weapon' then if ESX.GetWeapon(args[k]) then newArgs[v.name] = string.upper(args[k]) else - error = 'Invalid weapon' + error = _U('commanderror_invalidweapon') end elseif v.type == 'any' then newArgs[v.name] = args[k] From a2308dec59f9e8fe85537a72aacee964bbd513b6 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 4 Mar 2020 13:01:46 +0100 Subject: [PATCH 2603/3224] Implemented starting balance, closes #537 --- config.lua | 2 ++ server/classes/player.lua | 9 +++++---- server/main.lua | 11 +++++------ 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/config.lua b/config.lua index be3e5171..a6f10be3 100644 --- a/config.lua +++ b/config.lua @@ -7,6 +7,8 @@ Config.Accounts = { money = _U('account_money') } +Config.StartingAccountMoney = {bank = 50000} + Config.EnableSocietyPayouts = false -- pay from the society account that the player is employed at? Requirement: esx_society Config.DisableWantedLevel = true Config.EnableHud = true -- enable the default hud? Display current job and accounts (black, bank & cash) diff --git a/server/classes/player.lua b/server/classes/player.lua index 042100fd..86c2583b 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -164,7 +164,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end if not found then - table.insert(missingAccounts, account) + missingAccounts[account] = Config.StartingAccountMoney[account] or 0 end end @@ -172,10 +172,11 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end self.createMissingAccounts = function(missingAccounts, cb) - for k,v in ipairs(missingAccounts) do - MySQL.Async.execute('INSERT INTO user_accounts (identifier, name) VALUES (@identifier, @name)', { + for name,money in pairs(missingAccounts) do + MySQL.Async.execute('INSERT INTO user_accounts (identifier, name, money) VALUES (@identifier, @name, @money)', { ['@identifier'] = self.identifier, - ['@name'] = v + ['@name'] = name, + ['@money'] = money }, function(rowsChanged) if cb then cb() diff --git a/server/main.lua b/server/main.lua index b52782d0..68cc5852 100644 --- a/server/main.lua +++ b/server/main.lua @@ -169,12 +169,12 @@ function loadESXPlayer(identifier, playerId) local xPlayer = CreateExtendedPlayer(playerId, identifier, userData.group, userData.accounts, userData.inventory, userData.job, userData.loadout, userData.playerName, userData.coords) xPlayer.getMissingAccounts(function(missingAccounts) - if #missingAccounts > 0 then - for k,v in ipairs(missingAccounts) do + if ESX.Table.SizeOf(missingAccounts) > 0 then + for name,money in pairs(missingAccounts) do table.insert(xPlayer.accounts, { - name = v, - money = 0, - label = Config.Accounts[v] + name = name, + money = money, + label = Config.Accounts[name] }) end @@ -192,7 +192,6 @@ function loadESXPlayer(identifier, playerId) inventory = xPlayer.getInventory(), job = xPlayer.getJob(), loadout = xPlayer.getLoadout(), - money = xPlayer.getMoney(), maxWeight = xPlayer.maxWeight }) From e31077efbbdab1df6f3cf0217d9541b1a5ff3b46 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 4 Mar 2020 13:03:19 +0100 Subject: [PATCH 2604/3224] Update README.md --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4dceab2d..524d5018 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,14 @@ # es_extended -es_extended is a roleplay framework for FiveM. ESX is short for **Es**sentialMode E**x**tended. +es_extended is a roleplay framework for FiveM. ESX is short for EssentialMode Extended. The to-go framework for creating an economy based roleplay server on FiveM and most popular on the platform, too! + +Featuring many extra resources to fit roleplaying servers, here's a taste of what's available: + +- esx_ambulancejob: play as a medic to revive players who are bleeding out. Complete with garages and respawn & bleedout system +- esx_policejob: patrol the city and arrest players commiting crime, with armory, outfit room and garages +- esx_vehicleshop: roleplay working in an vehicle dealership where you sell cars to players + +ESX was initially developed by Gizz back in 2017 for his friend as the were creating an FiveM server and there wasn't any economy roleplaying frameworks available. The original code was written within a week or two and later open sourced, it has ever since been improved and parts been rewritten to further improve on it. ## Links & Read more From d477fce1d547aece6fccc0dbb10f289866bb6f9f Mon Sep 17 00:00:00 2001 From: Marvbell110 <34713144+Marvbell110@users.noreply.github.com> Date: Wed, 4 Mar 2020 19:59:44 +0100 Subject: [PATCH 2605/3224] Update de.lua --- locales/de.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/locales/de.lua b/locales/de.lua index 3081beee..dfbd318a 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -3,10 +3,10 @@ Locales['de'] = { ['shops'] = 'geschäfte', ['press_menu'] = 'drücke ~INPUT_CONTEXT~ um auf das Geschäft zuzugreifen.', ['shop_item'] = '$%s', - ['bought'] = 'you just bought ~y~%sx~s~ ~b~%s~s~ for ~r~$%s~s~', - ['not_enough'] = 'du ~r~hast nicht~s~ genug geld: %s', - ['player_cannot_hold'] = 'you do ~r~not~s~ have enough ~y~free space~s~ in your inventory!', - ['shop_confirm'] = 'buy %sx %s for $%s?', - ['no'] = 'no', - ['yes'] = 'yes', + ['bought'] = '~y~%sx~s~ ~b~%s~s~ wurde gekauft für ~r~$%s~s~.', + ['not_enough'] = '~r~ $%s fehlen dir!', + ['player_cannot_hold'] = 'du hast ~r~nicht genug~s~ ~y~freien Platz~s~, in deinem Inventar!', + ['shop_confirm'] = 'kaufe %sx %s für $%s?', + ['no'] = 'Nein', + ['yes'] = 'Ja', } From 3ba2ed150fda32756259d7c55c37961c2d7996a0 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 6 Mar 2020 20:41:37 +0100 Subject: [PATCH 2606/3224] Save accounts as encoded json text, migrate script found in development discord --- es_extended.sql | 12 +---- server/classes/player.lua | 48 +++++------------- server/common.lua | 14 +----- server/functions.lua | 32 +++--------- server/main.lua | 101 +++++++++++++++++--------------------- 5 files changed, 68 insertions(+), 139 deletions(-) diff --git a/es_extended.sql b/es_extended.sql index 111cef1f..9ea30491 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -2,10 +2,11 @@ USE `essentialmode`; CREATE TABLE `users` ( `identifier` VARCHAR(40) NOT NULL, + `accounts` LONGTEXT NULL DEFAULT NULL, `group` VARCHAR(50) NULL DEFAULT 'user', + `inventory` LONGTEXT NULL DEFAULT NULL, `job` VARCHAR(20) NULL DEFAULT 'unemployed', `job_grade` INT(11) NULL DEFAULT 0, - `inventory` LONGTEXT NULL DEFAULT NULL, `loadout` LONGTEXT NULL DEFAULT NULL, `position` VARCHAR(53) NULL DEFAULT '{"x":-269.4,"y":-955.3,"z":31.2,"heading":205.8}', @@ -45,12 +46,3 @@ CREATE TABLE `jobs` ( ); INSERT INTO `jobs` VALUES ('unemployed','Unemployed'); - -CREATE TABLE `user_accounts` ( - `id` INT(11) NOT NULL AUTO_INCREMENT, - `identifier` VARCHAR(40) NOT NULL, - `name` VARCHAR(50) NOT NULL, - `money` INT(11) NOT NULL DEFAULT '0', - - PRIMARY KEY (`id`) -); diff --git a/server/classes/player.lua b/server/classes/player.lua index 86c2583b..68242e13 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -82,8 +82,18 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, return self.variables[k] end - self.getAccounts = function() - return self.accounts + self.getAccounts = function(minimal) + if minimal then + local minimalAccounts = {} + + for k,v in ipairs(self.accounts) do + minimalAccounts[v.name] = v.money + end + + return minimalAccounts + else + return self.accounts + end end self.getAccount = function(account) @@ -151,40 +161,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, self.name = newName end - self.getMissingAccounts = function(cb) - local missingAccounts = {} - - for account,label in pairs(Config.Accounts) do - local found = false - - for k2,v2 in ipairs(self.accounts) do - if account == v2.name then - found = true - end - end - - if not found then - missingAccounts[account] = Config.StartingAccountMoney[account] or 0 - end - end - - cb(missingAccounts) - end - - self.createMissingAccounts = function(missingAccounts, cb) - for name,money in pairs(missingAccounts) do - MySQL.Async.execute('INSERT INTO user_accounts (identifier, name, money) VALUES (@identifier, @name, @money)', { - ['@identifier'] = self.identifier, - ['@name'] = name, - ['@money'] = money - }, function(rowsChanged) - if cb then - cb() - end - end) - end - end - self.setAccountMoney = function(accountName, money) if money >= 0 then local account = self.getAccount(accountName) diff --git a/server/common.lua b/server/common.lua index b9d5f601..4921c75c 100644 --- a/server/common.lua +++ b/server/common.lua @@ -5,7 +5,6 @@ ESX.Items = {} ESX.ServerCallbacks = {} ESX.TimeoutCount = -1 ESX.CancelledTimeouts = {} -ESX.LastPlayerData = {} ESX.Pickups = {} ESX.PickupId = 0 ESX.Jobs = {} @@ -58,17 +57,6 @@ MySQL.ready(function() print('[es_extended] [^2INFO^7] ESX developed by ESX-Org has been initialized') end) -AddEventHandler('esx:playerLoaded', function(playerId) - local xPlayer, accounts = ESX.GetPlayerFromId(playerId), {} - local xPlayerAccounts = xPlayer.getAccounts() - - for i=1, #xPlayerAccounts, 1 do - accounts[xPlayerAccounts[i].name] = xPlayerAccounts[i].money - end - - ESX.LastPlayerData[playerId] = {accounts = accounts} -end) - RegisterServerEvent('esx:clientLog') AddEventHandler('esx:clientLog', function(msg) if Config.EnableDebug then @@ -80,7 +68,7 @@ RegisterServerEvent('esx:triggerServerCallback') AddEventHandler('esx:triggerServerCallback', function(name, requestId, ...) local playerId = source - ESX.TriggerServerCallback(name, requestID, playerId, function(...) + ESX.TriggerServerCallback(name, requestId, playerId, function(...) TriggerClientEvent('esx:serverCallback', playerId, requestId, ...) end, ...) end) diff --git a/server/functions.lua b/server/functions.lua index caf97a02..6cb0b427 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -150,7 +150,7 @@ ESX.RegisterServerCallback = function(name, cb) end ESX.TriggerServerCallback = function(name, requestId, source, cb, ...) - if ESX.ServerCallbacks[name] ~= nil then + if ESX.ServerCallbacks[name] then ESX.ServerCallbacks[name](source, cb, ...) else print(('[es_extended] [^3WARNING^7] Server callback "%s" does not exist. Make sure that the server sided file really is loading, an error in that file might cause it to not load.'):format(name)) @@ -160,26 +160,9 @@ end ESX.SavePlayer = function(xPlayer, cb) local asyncTasks = {} - -- User accounts - for k,v in ipairs(xPlayer.accounts) do - if ESX.LastPlayerData[xPlayer.source].accounts[v.name] ~= v.money then - table.insert(asyncTasks, function(cb) - MySQL.Async.execute('UPDATE user_accounts SET money = @money WHERE identifier = @identifier AND name = @name', { - ['@money'] = v.money, - ['@identifier'] = xPlayer.identifier, - ['@name'] = v.name - }, function(rowsChanged) - cb() - end) - end) - - ESX.LastPlayerData[xPlayer.source].accounts[v.name] = v.money - end - end - - -- Job, loadout, inventory and position table.insert(asyncTasks, function(cb) - MySQL.Async.execute('UPDATE users SET job = @job, job_grade = @job_grade, loadout = @loadout, position = @position, inventory = @inventory WHERE identifier = @identifier', { + MySQL.Async.execute('UPDATE users SET accounts = @accounts, job = @job, job_grade = @job_grade, loadout = @loadout, position = @position, inventory = @inventory WHERE identifier = @identifier', { + ['@accounts'] = json.encode(xPlayer.getAccounts(true)), ['@job'] = xPlayer.job.name, ['@job_grade'] = xPlayer.job.grade, ['@loadout'] = json.encode(xPlayer.getLoadout(true)), @@ -194,15 +177,14 @@ ESX.SavePlayer = function(xPlayer, cb) Async.parallel(asyncTasks, function(results) print(('[es_extended] [^2INFO^7] Saved player "%s^7"'):format(xPlayer.getName())) - if cb ~= nil then + if cb then cb() end end) end ESX.SavePlayers = function(cb) - local asyncTasks = {} - local xPlayers = ESX.GetPlayers() + local xPlayers, asyncTasks = ESX.GetPlayers(), {} for i=1, #xPlayers, 1 do table.insert(asyncTasks, function(cb) @@ -213,7 +195,7 @@ ESX.SavePlayers = function(cb) Async.parallelLimit(asyncTasks, 8, function(results) print(('[es_extended] [^2INFO^7] Saved %s player(s)'):format(#xPlayers)) - if cb ~= nil then + if cb then cb() end end) @@ -259,7 +241,7 @@ ESX.UseItem = function(source, item) end ESX.GetItemLabel = function(item) - if ESX.Items[item] ~= nil then + if ESX.Items[item] then return ESX.Items[item].label end end diff --git a/server/main.lua b/server/main.lua index 68cc5852..50b82f48 100644 --- a/server/main.lua +++ b/server/main.lua @@ -20,7 +20,14 @@ function onPlayerJoined(playerId) if result then loadESXPlayer(identifier, playerId) else - MySQL.Async.execute('INSERT INTO users (identifier) VALUES (@identifier)', { + local accounts = {} + + for account,money in pairs(Config.StartingAccountMoney) do + accounts[account] = money + end + + MySQL.Async.execute('INSERT INTO users (accounts, identifier) VALUES (@accounts, @identifier)', { + ['@accounts'] = json.encode(accounts), ['@identifier'] = identifier }, function(rowsChanged) loadESXPlayer(identifier, playerId) @@ -43,31 +50,31 @@ function loadESXPlayer(identifier, playerId) playerName = GetPlayerName(playerId) } - -- get accounts table.insert(tasks, function(cb) - MySQL.Async.fetchAll('SELECT name, money FROM user_accounts WHERE identifier = @identifier', { - ['@identifier'] = identifier - }, function(accounts) - for k,v in ipairs(accounts) do - if Config.Accounts[v.name] then - table.insert(userData.accounts, { - name = v.name, - money = v.money, - label = Config.Accounts[v.name] - }) - end - end - - cb() - end) - end) - - table.insert(tasks, function(cb) - MySQL.Async.fetchAll('SELECT job, job_grade, `group`, loadout, position, inventory FROM users WHERE identifier = @identifier', { + MySQL.Async.fetchAll('SELECT accounts, job, job_grade, `group`, loadout, position, inventory FROM users WHERE identifier = @identifier', { ['@identifier'] = identifier }, function(result) local job, grade, jobObject, gradeObject = result[1].job, tostring(result[1].job_grade) + local fonudAccounts, foundItems = {}, {} + -- Accounts + if result[1].accounts and result[1].accounts ~= '' then + local accounts = json.decode(result[1].accounts) + + for account,money in pairs(accounts) do + fonudAccounts[account] = money + end + end + + for account,label in pairs(Config.Accounts) do + table.insert(userData.accounts, { + name = account, + money = fonudAccounts[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 @@ -76,8 +83,6 @@ function loadESXPlayer(identifier, playerId) jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] end - userData.job = {} - userData.job.id = jobObject.id userData.job.name = jobObject.name userData.job.label = jobObject.label @@ -93,8 +98,7 @@ function loadESXPlayer(identifier, playerId) 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 - local foundItems = {} - + -- Inventory if result[1].inventory and result[1].inventory ~= '' then local inventory = json.decode(result[1].inventory) @@ -123,6 +127,7 @@ function loadESXPlayer(identifier, playerId) }) end + -- Group if result[1].group then userData.group = result[1].group else @@ -133,6 +138,7 @@ function loadESXPlayer(identifier, playerId) return a.label < b.label end) + -- Loadout if result[1].loadout and result[1].loadout ~= '' then local loadout = json.decode(result[1].loadout) @@ -154,6 +160,7 @@ function loadESXPlayer(identifier, playerId) end end + -- Position if result[1].position and result[1].position ~= '' then userData.coords = json.decode(result[1].position) else @@ -167,37 +174,22 @@ function loadESXPlayer(identifier, playerId) Async.parallel(tasks, function(results) local xPlayer = CreateExtendedPlayer(playerId, identifier, userData.group, userData.accounts, userData.inventory, userData.job, userData.loadout, userData.playerName, userData.coords) + ESX.Players[playerId] = xPlayer + TriggerEvent('esx:playerLoaded', playerId, xPlayer) - xPlayer.getMissingAccounts(function(missingAccounts) - if ESX.Table.SizeOf(missingAccounts) > 0 then - for name,money in pairs(missingAccounts) do - table.insert(xPlayer.accounts, { - name = name, - money = money, - label = Config.Accounts[name] - }) - end + xPlayer.triggerEvent('esx:playerLoaded', { + accounts = xPlayer.getAccounts(), + coords = xPlayer.getCoords(), + identifier = xPlayer.identifier, + inventory = xPlayer.getInventory(), + job = xPlayer.getJob(), + loadout = xPlayer.getLoadout(), + maxWeight = xPlayer.maxWeight, + money = xPlayer.getMoney(), + }) - xPlayer.createMissingAccounts(missingAccounts) - end - - ESX.Players[playerId] = xPlayer - TriggerEvent('esx:playerLoaded', playerId, xPlayer) - - xPlayer.triggerEvent('esx:playerLoaded', { - identifier = xPlayer.identifier, - money = xPlayer.getMoney(), - accounts = xPlayer.getAccounts(), - coords = xPlayer.getCoords(), - inventory = xPlayer.getInventory(), - job = xPlayer.getJob(), - loadout = xPlayer.getLoadout(), - maxWeight = xPlayer.maxWeight - }) - - xPlayer.triggerEvent('esx:createMissingPickups', ESX.Pickups) - xPlayer.triggerEvent('esx:registerSuggestions', ESX.RegisteredCommands) - end) + xPlayer.triggerEvent('esx:createMissingPickups', ESX.Pickups) + xPlayer.triggerEvent('esx:registerSuggestions', ESX.RegisteredCommands) end) end @@ -210,7 +202,6 @@ AddEventHandler('playerDropped', function(reason) ESX.SavePlayer(xPlayer, function() ESX.Players[playerId] = nil - ESX.LastPlayerData[playerId] = nil end) end end) From 1d60857a7ef8087f16ba598a231704db5ee01f32 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 6 Mar 2020 20:46:28 +0100 Subject: [PATCH 2607/3224] Fixed /setgroup command --- README.md | 1 + server/commands.lua | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 524d5018..f10cdc04 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ git clone https://github.com/ESX-Org/esx_menu_list [esx]/[ui]/esx_menu_list add_principal group.admin group.user add_ace resource.es_extended command.add_ace allow add_ace resource.es_extended command.add_principal allow +add_ace resource.es_extended command.remove_principal allow start mysql-async start es_extended diff --git a/server/commands.lua b/server/commands.lua index 1639edd2..b8a187f1 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -111,7 +111,7 @@ end, true, {help = _U('command_clearloadout'), validate = true, arguments = { }}) ESX.RegisterCommand('setgroup', 'admin', function(xPlayer, args, showError) - args.playerId.setGorup(args.group) + args.playerId.setGroup(args.group) end, true, {help = _U('command_setgroup'), validate = true, arguments = { {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'}, {name = 'group', help = _U('command_setgroup_group'), type = 'string'}, From 829994dd9c26d94509cf9c08bff0fe00379839ab Mon Sep 17 00:00:00 2001 From: Oldarorn <36448848+Oldarorn@users.noreply.github.com> Date: Fri, 6 Mar 2020 20:59:18 +0100 Subject: [PATCH 2608/3224] Updated French translations (#551) * Update fr.lua * Fix indent --- locales/fr.lua | 78 +++++++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index 350055bc..502e360c 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -54,47 +54,47 @@ Locales['fr'] = { ['in_vehicle'] = 'Vous ne pouvez rien donner à quelqu\'un dans un véhicule', -- Commands - ['command_car'] = 'spawn an vehicle', - ['command_car_car'] = 'vehicle spawn name or hash', - ['command_cardel'] = 'delete vehicle in proximity', - ['command_cardel_radius'] = 'optional, delete every vehicle within the specified radius', - ['command_clear'] = 'clear chat', - ['command_clearall'] = 'clear chat for all players', - ['command_clearinventory'] = 'clear player inventory', - ['command_clearloadout'] = 'clear a player loadout', - ['command_setcoords'] = 'teleport to coordinates', - ['command_setcoords_x'] = 'x axis', - ['command_setcoords_y'] = 'y axis', - ['command_setcoords_z'] = 'z axis', - ['command_setjob'] = 'set job for a player', - ['command_setjob_job'] = 'job name', - ['command_setjob_grade'] = 'job grade', - ['command_setjob_invalid'] = 'the job, grade or both are invalid', - ['command_setgroup'] = 'set player group', - ['command_setgroup_group'] = 'group name', - ['command_giveaccountmoney'] = 'give account money', - ['command_giveaccountmoney_account'] = 'valid account name', - ['command_giveaccountmoney_amount'] = 'amount to add', - ['command_giveaccountmoney_invalid'] = 'invalid account name', - ['command_giveitem'] = 'give an item to a player', - ['command_giveitem_item'] = 'item name', - ['command_giveitem_count'] = 'item count', - ['command_giveweapon'] = 'give a weapon to a player', - ['command_giveweapon_weapon'] = 'weapon name', - ['command_giveweapon_ammo'] = 'ammo count', - ['command_giveweapon_hasalready'] = 'player already has that weapon', - ['command_giveweaponcomponent'] = 'give weapon component', - ['command_giveweaponcomponent_component'] = 'component name', - ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', - ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', - ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['command_car'] = 'faire appaitre un véhicule', + ['command_car_car'] = 'nom ou hash du véhicule', + ['command_cardel'] = 'supprimer le véhicule à proximité', + ['command_cardel_radius'] = 'optionnel, supprime les véhicules dans un rayon spécifié', + ['command_clear'] = 'vider le chat', + ['command_clearall'] = 'vider le chat pour tous', + ['command_clearinventory'] = 'vider l\'inventaire d\'un joueur', + ['command_clearloadout'] = 'vider le loadout d\'un joueur', + ['command_setcoords'] = 'se téléporter aux coordonnées', + ['command_setcoords_x'] = 'axe X', + ['command_setcoords_y'] = 'axe Y', + ['command_setcoords_z'] = 'axe Z', + ['command_setjob'] = 'assigner job à un joueur', + ['command_setjob_job'] = 'nom du job', + ['command_setjob_grade'] = 'grade du job', + ['command_setjob_invalid'] = 'le job, le grade ou les deux sont invalides', + ['command_setgroup'] = 'assigner un groupe à un joueur', + ['command_setgroup_group'] = 'nom du groupe', + ['command_giveaccountmoney'] = 'donner de l\'argent sur un compte', + ['command_giveaccountmoney_account'] = 'nom de compte valide', + ['command_giveaccountmoney_amount'] = 'quantité à ajouter', + ['command_giveaccountmoney_invalid'] = 'nom de compte invalide', + ['command_giveitem'] = 'donner un objet à un joueur', + ['command_giveitem_item'] = 'nom de l\'objet', + ['command_giveitem_count'] = 'quantité de l\'objet', + ['command_giveweapon'] = 'donner une arme à un joueur', + ['command_giveweapon_weapon'] = 'nom de l\'arme', + ['command_giveweapon_ammo'] = 'quantité de munitions', + ['command_giveweapon_hasalready'] = 'le joueur a déjà cette arme', + ['command_giveweaponcomponent'] = 'donner un accessoire d\'arme', + ['command_giveweaponcomponent_component'] = 'nom de l\'accessoire', + ['command_giveweaponcomponent_invalid'] = 'accessoire invalide', + ['command_giveweaponcomponent_hasalready'] = 'le joueur a déjà cet accessoire', + ['command_giveweaponcomponent_missingweapon'] = 'le joueur n\'a pas cette arme', ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', - ['commanderror_invaliditem'] = 'invalid item name', - ['commanderror_invalidweapon'] = 'invalid weapon', - ['commanderror_console'] = 'that command can not be run from console', - ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', - ['commandgeneric_playerid'] = 'player id', + ['commanderror_invaliditem'] = 'nom de l\'objet invalide', + ['commanderror_invalidweapon'] = 'arme invalide', + ['commanderror_console'] = 'cette commande ne peut pas être utilisée dans la console', + ['commanderror_invalidplayerid'] = 'il n\'ya aucun joueur avec cet ID en jeu', + ['commandgeneric_playerid'] = 'id joueur', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', From cf23d9c2ed5974f9179b3e4c7fd150c40d0a95fe Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 6 Mar 2020 21:03:15 +0100 Subject: [PATCH 2609/3224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9b58d298..019ba15d 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ start esx_jobs ### License esx_jobs - jobs -Copyright (C) 2015-2019 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. From dc242b97c3289159838f1439799316003e91af59 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 6 Mar 2020 21:08:39 +0100 Subject: [PATCH 2610/3224] Added Spanish translation thanks to @JuannmaCh Co-Authored-By: JuannmaCh --- fxmanifest.lua | 2 + locales/es.lua | 115 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 locales/es.lua diff --git a/fxmanifest.lua b/fxmanifest.lua index b4f6e1cc..0218f333 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -10,6 +10,7 @@ server_scripts { '@es_extended/locale.lua', 'locales/br.lua', 'locales/en.lua', + 'locales/es.lua', 'locales/fi.lua', 'locales/fr.lua', 'locales/sv.lua', @@ -31,6 +32,7 @@ client_scripts { 'locales/br.lua', 'locales/fi.lua', 'locales/en.lua', + 'locales/es.lua', 'locales/fr.lua', 'locales/sv.lua', 'config.lua', diff --git a/locales/es.lua b/locales/es.lua new file mode 100644 index 00000000..ff99dad7 --- /dev/null +++ b/locales/es.lua @@ -0,0 +1,115 @@ +Locales['es'] = { + -- Global menus + ['cloakroom'] = 'guardarropas', + ['cloak_change'] = 'presiona ~INPUT_PICKUP~ para cambiarte la ropa.', + ['citizen_wear'] = 'ropa de civil', + ['job_wear'] = 'ropa de trabajo', + ['bank_deposit_returned'] = 'un deposito de seguro de ~g~$%s~s~ se te devolvió.', + ['bank_deposit_taken'] = 'un deposito de seguro de ~r~$%s~s~ se te tomó.', + ['caution_afford'] = 'no puedes pagar el deposito de seguro de ~g~$%s~s~', + ['foot_work'] = 'debes estar en pie para trabajar.', + ['next_point'] = 've al siguiente punto tras terminar este.', + ['not_your_vehicle'] = 'no eres el conductor.', + ['in_vehicle'] = 'debes estar en un vehiculo.', + ['wrong_point'] = 'no estas en el punto correcto de entrega.', + ['max_limit'] = 'no puedes llevar mas ~y~%s~s~', + ['not_enough'] = 'no tienes suficientes ~y~%s~s~ para continuar esta tarea.', + ['spawn_veh'] = 'spawnear vehiculo', + ['spawn_veh_button'] = 'presiona ~INPUT_PICKUP~ para pedir el vehiculo de entrega.', + ['spawn_truck_button'] = 'presiona ~INPUT_PICKUP~ para spawnear un camion.', + ['spawn_blocked'] = 'el punto de spawn esta bloqueado!', + ['service_vh'] = 'vehiculo de servicio', + ['return_vh'] = 'devolver vehiculo', + ['return_vh_button'] = 'presiona ~INPUT_PICKUP~ para devolver vehiculo.', + ['delivery_point'] = 'punto de entrega', + ['delivery'] = 'entrega', + ['public_enter'] = 'presiona ~INPUT_PICKUP~ para entrar al edificio.', + ['public_leave'] = 'presiona ~INPUT_PICKUP~ para ir a la entrada del edificio.', + + -- Lumber Jack job + ['lj_locker_room'] = 'guardarropas', + ['lj_mapblip'] = 'pila de madera', + ['lj_wood'] = 'madera', + ['lj_pickup'] = 'presiona ~INPUT_PICKUP~ para agarrar madera.', + ['lj_cutwood'] = 'cortar madera', + ['lj_cutwood_button'] = 'presiona ~INPUT_PICKUP~ para cortar madera.', + ['lj_board'] = 'tablas', + ['lj_planks'] = 'empaquetar', + ['lj_cutwood'] = 'cortar madera', + ['lj_pick_boards'] = 'presiona ~INPUT_PICKUP~ para agarrar tablas.', + ['lj_deliver_button'] = 'presiona ~INPUT_PICKUP~ para entregar tablas.', + + -- Fisherman + ['fm_fish_locker'] = 'guardarropas', + ['fm_fish'] = 'pescar', + ['fm_fish_area'] = 'area de pesca', + ['fm_fish_button'] = 'presiona ~INPUT_PICKUP~ para pescar.', + ['fm_spawnboat_title'] = 'spawnear bote', + ['fm_spawnboat'] = 'presiona ~INPUT_PICKUP~ para pedir un bote.', + ['fm_boat_title'] = 'bote', + ['fm_boat_return_title'] = 'devolver bote', + ['fm_boat_return_button'] = 'presiona ~INPUT_PICKUP~ para devolver un bote.', + ['fm_deliver_fish'] = 'presiona ~INPUT_PICKUP~ para entregar pescados.', + + -- Fuel + ['f_oil_refiner'] = 'guardarropas', + ['f_drill_oil'] = 'agujerear para encontrar petroleo', + ['f_fuel'] = 'petroleo', + ['f_drillbutton'] = 'presiona ~INPUT_PICKUP~ para agujerear.', + ['f_fuel_refine'] = 'refinar petroleo', + ['f_refine_fuel_button'] = 'presiona ~INPUT_PICKUP~ para refinar.', + ['f_fuel_mixture'] = 'mezclar petroleo refinado', + ['f_gas'] = 'gas', + ['f_fuel_mixture_button'] = 'presiona ~INPUT_PICKUP~ para mezclar petroleo.', + ['f_deliver_gas'] = 'entregar gas', + ['f_deliver_gas_button'] = 'presiona ~INPUT_PICKUP~ para entregar gasolina.', + + -- Miner + ['m_miner_locker'] = 'guardarropas', + ['m_rock'] = 'roca', + ['m_pickrocks'] = 'presiona ~INPUT_PICKUP~ para agarrar rocas.', + ['m_washrock'] = 'lavado de rocas', + ['m_rock_button'] = 'presiona ~INPUT_PICKUP~ para lavar rocas.', + ['m_rock_smelting'] = 'derretir rocas', + ['m_copper'] = 'cobre', + ['m_sell_copper'] = 'vender cobre', + ['m_deliver_copper'] = 'presiona ~INPUT_PICKUP~ para entregar el cobre.', + ['m_iron'] = 'hierro', + ['m_sell_iron'] = 'vender hierro', + ['m_deliver_iron'] = 'presiona ~INPUT_PICKUP~ para entregar el hierro.', + ['m_gold'] = 'oro', + ['m_sell_gold'] = 'vender oro', + ['m_deliver_gold'] = 'presiona ~INPUT_PICKUP~ para entregar oro.', + ['m_diamond'] = 'diamantes', + ['m_sell_diamond'] = 'vender diamantes', + ['m_deliver_diamond'] = 'presiona ~INPUT_PICKUP~ para entregar los diamantes.', + ['m_melt_button'] = 'presiona ~INPUT_PICKUP~ para derretir rocas.', + + -- Reporter + ['reporter_name'] = 'periódico San Andreas', + ['reporter_garage'] = 'presiona ~INPUT_PICKUP~ para ir al garage.', + + -- Slaughterer + ['s_slaughter_locker'] = 'guardarropas', + ['s_hen'] = 'gGallinero', + ['s_alive_chicken'] = 'pollos vivos', + ['s_catch_hen'] = 'presiona ~INPUT_PICKUP~ para agarrar pollos vivos.', + ['s_slaughtered_chicken'] = 'pollo listo para empaquetar', + ['s_chop_animal'] = 'presiona ~INPUT_PICKUP~ para cortar los pollos.', + ['s_slaughtered'] = 'matadero', + ['s_package'] = 'empaquetando', + ['s_packagechicken'] = 'pollo en bandeja', + ['s_unpackaged'] = 'pollo para empaquetar', + ['s_unpackaged_button'] = 'presiona ~INPUT_PICKUP~ para poner el pollo en una bandeja.', + ['s_deliver'] = 'presiona ~INPUT_PICKUP~ para entregar bandejas de pollos.', + + -- Dress Designer + ['dd_dress_locker'] = 'guardarropas', + ['dd_wool'] = 'lana', + ['dd_pickup'] = 'presiona ~INPUT_PICKUP~ para agarrar lana.', + ['dd_fabric'] = 'tela', + ['dd_makefabric'] = 'presiona ~INPUT_PICKUP~ para hacer tela.', + ['dd_clothing'] = 'ropa', + ['dd_makeclothing'] = 'presiona ~INPUT_PICKUP~ para agarrar ropa.', + ['dd_deliver_clothes'] = 'presiona ~INPUT_PICKUP~ para entregar ropa.', +} From 086f280a77ab08f7f756f10d49c2473750d4fb66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BA=BB=E8=BE=A3=E6=88=88=E5=A3=81?= Date: Sat, 7 Mar 2020 19:59:45 +0800 Subject: [PATCH 2611/3224] Fix give weapon ammo on esx:giveInventoryItem --- server/main.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 50b82f48..e30d394a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -281,8 +281,9 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo end elseif type == 'item_ammo' then if sourceXPlayer.hasWeapon(itemName) then + local weaponNum, weapon = sourceXPlayer.getWeapon(itemName) + if targetXPlayer.hasWeapon(itemName) then - local weaponNum, weapon = sourceXPlayer.getWeapon(itemName) local _, weaponObject = ESX.GetWeapon(itemName) if weaponObject.ammo then From 7efcf85abb73d44fed3630a47a756878170fb007 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 9 Mar 2020 12:35:40 +0100 Subject: [PATCH 2612/3224] Fixed indent mistake --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index e30d394a..9dc9e753 100644 --- a/server/main.lua +++ b/server/main.lua @@ -282,7 +282,7 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo elseif type == 'item_ammo' then if sourceXPlayer.hasWeapon(itemName) then local weaponNum, weapon = sourceXPlayer.getWeapon(itemName) - + if targetXPlayer.hasWeapon(itemName) then local _, weaponObject = ESX.GetWeapon(itemName) From e0d561649b82274604a2e40c40dbfb3b50289927 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 9 Mar 2020 13:05:33 +0100 Subject: [PATCH 2613/3224] Added invalid command handler --- locales/br.lua | 1 + locales/cs.lua | 1 + locales/de.lua | 1 + locales/en.lua | 1 + locales/fi.lua | 1 + locales/fr.lua | 1 + locales/pl.lua | 1 + locales/sv.lua | 1 + server/main.lua | 8 ++++++++ 9 files changed, 16 insertions(+) diff --git a/locales/br.lua b/locales/br.lua index 7b115f96..c2b46a7b 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -93,6 +93,7 @@ Locales['br'] = { ['commanderror_invaliditem'] = 'item invalido', ['commanderror_invalidweapon'] = 'invalid weapon', ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidcommand'] = '^3%s^0 is not an valid command!', ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', ['commandgeneric_playerid'] = 'o ID do jogador', diff --git a/locales/cs.lua b/locales/cs.lua index b99bebf0..178bf89f 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -93,6 +93,7 @@ Locales['cs'] = { ['commanderror_invaliditem'] = 'invalid item name', ['commanderror_invalidweapon'] = 'invalid weapon', ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidcommand'] = '^3%s^0 is not an valid command!', ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', ['commandgeneric_playerid'] = 'player id', diff --git a/locales/de.lua b/locales/de.lua index 86247f0b..1b218200 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -93,6 +93,7 @@ Locales['de'] = { ['commanderror_invaliditem'] = 'invalid item name', ['commanderror_invalidweapon'] = 'invalid weapon', ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidcommand'] = '^3%s^0 is not an valid command!', ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', ['commandgeneric_playerid'] = 'player id', diff --git a/locales/en.lua b/locales/en.lua index e7a6549b..9c3efda4 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -93,6 +93,7 @@ Locales['en'] = { ['commanderror_invaliditem'] = 'invalid item name', ['commanderror_invalidweapon'] = 'invalid weapon', ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidcommand'] = '^3%s^0 is not an valid command!', ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', ['commandgeneric_playerid'] = 'player id', diff --git a/locales/fi.lua b/locales/fi.lua index cd3b3d6b..9831b26e 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -93,6 +93,7 @@ Locales['fi'] = { ['commanderror_invaliditem'] = 'invalid item name', ['commanderror_invalidweapon'] = 'invalid weapon', ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidcommand'] = '^3%s^0 is not an valid command!', ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', ['commandgeneric_playerid'] = 'player id', diff --git a/locales/fr.lua b/locales/fr.lua index 502e360c..78aa1bbe 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -93,6 +93,7 @@ Locales['fr'] = { ['commanderror_invaliditem'] = 'nom de l\'objet invalide', ['commanderror_invalidweapon'] = 'arme invalide', ['commanderror_console'] = 'cette commande ne peut pas être utilisée dans la console', + ['commanderror_invalidcommand'] = '^3%s^0 is not an valid command!', ['commanderror_invalidplayerid'] = 'il n\'ya aucun joueur avec cet ID en jeu', ['commandgeneric_playerid'] = 'id joueur', diff --git a/locales/pl.lua b/locales/pl.lua index 3f727d5f..db4f89ae 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -93,6 +93,7 @@ Locales['pl'] = { ['commanderror_invaliditem'] = 'invalid item name', ['commanderror_invalidweapon'] = 'invalid weapon', ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidcommand'] = '^3%s^0 is not an valid command!', ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', ['commandgeneric_playerid'] = 'player id', diff --git a/locales/sv.lua b/locales/sv.lua index df1f21db..b41a434e 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -93,6 +93,7 @@ Locales['sv'] = { ['commanderror_invaliditem'] = 'ej giltigt item', ['commanderror_invalidweapon'] = 'ej giltigt vapen', ['commanderror_console'] = 'detta kommando kan ej executas i konsol', + ['commanderror_invalidcommand'] = '^3%s^0 är inte ett giltigt kommando!', ['commanderror_invalidplayerid'] = 'det finns ingen spelare som matchar det angivna server id', ['commandgeneric_playerid'] = 'spelarid', diff --git a/server/main.lua b/server/main.lua index 9dc9e753..008bc784 100644 --- a/server/main.lua +++ b/server/main.lua @@ -193,6 +193,14 @@ function loadESXPlayer(identifier, playerId) end) end +AddEventHandler('chatMessage', function(playerId, author, message) + if message:sub(1, 1) == '/' and playerId > 0 then + CancelEvent() + local commandName = message:sub(1):gmatch("%w+")() + TriggerClientEvent('chat:addMessage', playerId, {args = {'^1SYSTEM', _U('commanderror_invalidcommand', commandName)}}) + end +end) + AddEventHandler('playerDropped', function(reason) local playerId = source local xPlayer = ESX.GetPlayerFromId(playerId) From 83914926b2c13d673994531e34279a48f50e7ad3 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 9 Mar 2020 13:08:34 +0100 Subject: [PATCH 2614/3224] Removed old invalid command handler --- locales/cs.lua | 1 - locales/en.lua | 1 - locales/fi.lua | 1 - locales/fr.lua | 1 - locales/sv.lua | 1 - server/main.lua | 8 +------- 6 files changed, 1 insertion(+), 12 deletions(-) diff --git a/locales/cs.lua b/locales/cs.lua index fabdef61..eccbecb3 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -8,5 +8,4 @@ Locales['cs'] = { ['do_prefix'] = 'do | %s', ['generic_argument_name'] = 'zpráva', ['generic_argument_help'] = 'zpráva', - ['unknown_command'] = '^3%s^0 není platný příkaz!', } diff --git a/locales/en.lua b/locales/en.lua index e850e9c7..ab717d9e 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -8,5 +8,4 @@ Locales['en'] = { ['do_prefix'] = 'do | %s', ['generic_argument_name'] = 'message', ['generic_argument_help'] = 'the message', - ['unknown_command'] = '^3%s^0 is not a valid command!', } diff --git a/locales/fi.lua b/locales/fi.lua index 8416d4e2..d76bde47 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -8,5 +8,4 @@ Locales['fi'] = { ['do_prefix'] = 'do | %s', ['generic_argument_name'] = 'viesti', ['generic_argument_help'] = 'viestin sisältö', - ['unknown_command'] = '^3%s^0 ei ole validi komento!', } diff --git a/locales/fr.lua b/locales/fr.lua index 7ae7dd6f..edb9e02a 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -8,5 +8,4 @@ Locales['fr'] = { ['do_prefix'] = 'faire | %s', ['generic_argument_name'] = 'message', ['generic_argument_help'] = 'le message', - ['unknown_command'] = '^3%s^0 n\'est pas une commande valide!', } diff --git a/locales/sv.lua b/locales/sv.lua index b79df654..5dd7fb02 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -8,5 +8,4 @@ Locales['sv'] = { ['do_prefix'] = 'gör | %s', ['generic_argument_name'] = 'meddelande', ['generic_argument_help'] = 'det meddelandet du vill skicka', - ['unknown_command'] = '^3%s^0 är inte ett giltigt kommando!', } diff --git a/server/main.lua b/server/main.lua index cb3c5c11..6671e76d 100644 --- a/server/main.lua +++ b/server/main.lua @@ -2,17 +2,11 @@ ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) -AddEventHandler('es:invalidCommandHandler', function(source, command_args, user) - CancelEvent() - TriggerClientEvent('chat:addMessage', source, {args = {'^1SYSTEM', _U('unknown_command', command_args[1])}}) -end) - AddEventHandler('chatMessage', function(playerId, playerName, message) if string.sub(message, 1, string.len('/')) ~= '/' then CancelEvent() - local xPlayer = ESX.GetPlayerFromId(playerId) - if xPlayer then playerName = xPlayer.getName() end + playerName = GetRealPlayerName(playerId) TriggerClientEvent('chat:addMessage', -1, {args = {_U('ooc_prefix', playerName), message}, color = {128, 128, 128}}) end end) From a8255ce6e39efa970525dd9a0583408bd01c76a2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 11 Mar 2020 09:44:26 +0100 Subject: [PATCH 2615/3224] Corrected spelling --- server/main.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/main.lua b/server/main.lua index 008bc784..4d89c235 100644 --- a/server/main.lua +++ b/server/main.lua @@ -55,21 +55,21 @@ function loadESXPlayer(identifier, playerId) ['@identifier'] = identifier }, function(result) local job, grade, jobObject, gradeObject = result[1].job, tostring(result[1].job_grade) - local fonudAccounts, foundItems = {}, {} + local foundAccounts, foundItems = {}, {} -- Accounts if result[1].accounts and result[1].accounts ~= '' then local accounts = json.decode(result[1].accounts) for account,money in pairs(accounts) do - fonudAccounts[account] = money + foundAccounts[account] = money end end for account,label in pairs(Config.Accounts) do table.insert(userData.accounts, { name = account, - money = fonudAccounts[account] or Config.StartingAccountMoney[account] or 0, + money = foundAccounts[account] or Config.StartingAccountMoney[account] or 0, label = label }) end From e712c0158d4835c5e2999509c9709af810aab907 Mon Sep 17 00:00:00 2001 From: MohamedAmrMahdy <36306971+MohamedAmrMahdy@users.noreply.github.com> Date: Wed, 11 Mar 2020 10:53:57 +0200 Subject: [PATCH 2616/3224] Add xPlayer.getMaxWeight() (#559) * Add xPlayer.getMaxWeight() Add ability to read current maximum weight for player * Remove the tab indent --- server/classes/player.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server/classes/player.lua b/server/classes/player.lua index 68242e13..4df91ee8 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -265,6 +265,10 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, return inventoryWeight end + self.getMaxWeight = function() + return self.maxWeight + end + self.canCarryItem = function(name, count) local currentWeight, itemWeight = self.getWeight(), ESX.Items[name].weight local newWeight = currentWeight + (itemWeight * count) From 9b97d1ea67bdb2a46bf7e3b0e00c1be94b770d91 Mon Sep 17 00:00:00 2001 From: Oldarorn <36448848+Oldarorn@users.noreply.github.com> Date: Thu, 12 Mar 2020 17:17:13 +0100 Subject: [PATCH 2617/3224] Update fr.lua --- locales/fr.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index 78aa1bbe..0e4a4fd2 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -38,7 +38,7 @@ Locales['fr'] = { ['threw_pickup_prompt'] = 'appuyez sur ~y~E~s~ pour ramasser', -- Key mapping - ['keymap_showinventory'] = 'show Inventory', + ['keymap_showinventory'] = 'montrer l\'inventaire', -- Salary related ['received_salary'] = 'vous avez reçu votre salaire: ~g~$%s~s~', @@ -93,7 +93,7 @@ Locales['fr'] = { ['commanderror_invaliditem'] = 'nom de l\'objet invalide', ['commanderror_invalidweapon'] = 'arme invalide', ['commanderror_console'] = 'cette commande ne peut pas être utilisée dans la console', - ['commanderror_invalidcommand'] = '^3%s^0 is not an valid command!', + ['commanderror_invalidcommand'] = '^3%s^0 n\'est pas une commande valide!', ['commanderror_invalidplayerid'] = 'il n\'ya aucun joueur avec cet ID en jeu', ['commandgeneric_playerid'] = 'id joueur', From ff9930068f83af6adf78275b2581a0e5ea54a3bf Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 15 Mar 2020 12:20:08 +0100 Subject: [PATCH 2618/3224] Keep weight stored --- es_extended.sql | 1 + server/classes/player.lua | 33 ++++++++++++++------------------- server/main.lua | 6 ++++-- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/es_extended.sql b/es_extended.sql index 9ea30491..c01587aa 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -1,3 +1,4 @@ +CREATE DATABASE IF NOT EXISTS `essentialmode`; USE `essentialmode`; CREATE TABLE `users` ( diff --git a/server/classes/player.lua b/server/classes/player.lua index 4df91ee8..52f661e2 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -1,18 +1,19 @@ -function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, job, loadout, name, coords) +function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, weight, job, loadout, name, coords) local self = {} self.accounts = accounts + self.coords = coords + self.group = group + self.identifier = identifier self.inventory = inventory self.job = job - self.group = group self.loadout = loadout self.name = name - self.maxWeight = Config.MaxWeight - self.coords = coords - self.variables = {} - self.source = playerId self.playerId = playerId - self.identifier = identifier + self.source = playerId + self.variables = {} + self.weight = weight + self.maxWeight = Config.MaxWeight ExecuteCommand(('add_principal identifier.license:%s group.%s'):format(self.identifier, self.group)) @@ -216,9 +217,8 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, if item then count = ESX.Math.Round(count) - - local newCount = item.count + count - item.count = newCount + item.count = item.count + count + self.weight = self.weight + (item.weight * count) TriggerEvent('esx:onAddInventoryItem', self.source, item.name, item.count) self.triggerEvent('esx:addInventoryItem', item.name, item.count) @@ -234,6 +234,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, if newCount >= 0 then item.count = newCount + self.weight = self.weight - (item.weight * count) TriggerEvent('esx:onRemoveInventoryItem', self.source, item.name, item.count) self.triggerEvent('esx:removeInventoryItem', item.name, item.count) @@ -256,13 +257,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end self.getWeight = function() - local inventoryWeight = 0 - - for k,v in ipairs(self.inventory) do - inventoryWeight = inventoryWeight + (v.count * v.weight) - end - - return inventoryWeight + return self.weight end self.getMaxWeight = function() @@ -270,7 +265,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end self.canCarryItem = function(name, count) - local currentWeight, itemWeight = self.getWeight(), ESX.Items[name].weight + local currentWeight, itemWeight = self.weight, ESX.Items[name].weight local newWeight = currentWeight + (itemWeight * count) return newWeight <= self.maxWeight @@ -281,7 +276,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, local testItemObject = self.getInventoryItem(testItem) if firstItemObject.count >= firstItemCount then - local weightWithoutFirstItem = ESX.Math.Round(self.getWeight() - (firstItemObject.weight * firstItemCount)) + local weightWithoutFirstItem = ESX.Math.Round(self.weight - (firstItemObject.weight * firstItemCount)) local weightWithTestItem = ESX.Math.Round(weightWithoutFirstItem + (testItemObject.weight * testItemCount)) return weightWithTestItem <= self.maxWeight diff --git a/server/main.lua b/server/main.lua index 4d89c235..5e6b7b61 100644 --- a/server/main.lua +++ b/server/main.lua @@ -47,7 +47,8 @@ function loadESXPlayer(identifier, playerId) inventory = {}, job = {}, loadout = {}, - playerName = GetPlayerName(playerId) + playerName = GetPlayerName(playerId), + weight = 0 } table.insert(tasks, function(cb) @@ -115,6 +116,7 @@ function loadESXPlayer(identifier, playerId) 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, @@ -173,7 +175,7 @@ function loadESXPlayer(identifier, playerId) end) Async.parallel(tasks, function(results) - local xPlayer = CreateExtendedPlayer(playerId, identifier, userData.group, userData.accounts, userData.inventory, userData.job, userData.loadout, userData.playerName, userData.coords) + 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 TriggerEvent('esx:playerLoaded', playerId, xPlayer) From 34df4887553ed4eccd78830842c94ab03b7be6e9 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Thu, 19 Mar 2020 23:01:19 +0100 Subject: [PATCH 2619/3224] French as default locale --- config.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.lua b/config.lua index f2b1f236..d91b057b 100644 --- a/config.lua +++ b/config.lua @@ -3,7 +3,7 @@ Config.DrawDistance = 100 Config.Size = {x = 1.5, y = 1.5, z = 1.5} Config.Color = {r = 0, g = 128, b = 255} Config.Type = 1 -Config.Locale = 'en' +Config.Locale = 'fr' Config.Zones = { From 9d81a54b7633c963cc7bf1be8b1e48b30ea8aece Mon Sep 17 00:00:00 2001 From: rex2630 Date: Thu, 19 Mar 2020 23:03:31 +0100 Subject: [PATCH 2620/3224] vector distance check --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index fc33dabc..f965778b 100644 --- a/client/main.lua +++ b/client/main.lua @@ -105,7 +105,7 @@ Citizen.CreateThread(function() for k,v in pairs(Config.Zones) do for i = 1, #v.Pos, 1 do - local distance = GetDistanceBetweenCoords(playerCoords, v.Pos[i].x, v.Pos[i].y, v.Pos[i].z, true) + local distance = #(playerCoords - vector3(v.Pos[i].x, v.Pos[i].y, v.Pos[i].z)) if distance < Config.DrawDistance then DrawMarker(Config.Type, v.Pos[i], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Config.Size.x, Config.Size.y, Config.Size.z, Config.Color.r, Config.Color.g, Config.Color.b, 100, false, true, 2, false, nil, nil, false) From dcc2aa762fcf9afd6c71976c5fd73a7dc67c009d Mon Sep 17 00:00:00 2001 From: Marvbell110 <34713144+Marvbell110@users.noreply.github.com> Date: Sat, 21 Mar 2020 14:20:39 +0100 Subject: [PATCH 2621/3224] Update de.lua --- locales/de.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/locales/de.lua b/locales/de.lua index dfbd318a..2e0093cf 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -1,12 +1,12 @@ Locales['de'] = { ['shop'] = 'geschäft', ['shops'] = 'geschäfte', - ['press_menu'] = 'drücke ~INPUT_CONTEXT~ um auf das Geschäft zuzugreifen.', + ['press_menu'] = 'drücke ~INPUT_CONTEXT~ um auf das Geschäft zuzugreifen', ['shop_item'] = '$%s', - ['bought'] = '~y~%sx~s~ ~b~%s~s~ wurde gekauft für ~r~$%s~s~.', - ['not_enough'] = '~r~ $%s fehlen dir!', - ['player_cannot_hold'] = 'du hast ~r~nicht genug~s~ ~y~freien Platz~s~, in deinem Inventar!', + ['bought'] = '~y~%sx~s~ ~b~%s~s~ wurde gekauft für ~r~$%s~s~', + ['not_enough'] = '~r~ $%s fehlen dir', + ['player_cannot_hold'] = 'du hast ~r~nicht genug~s~ ~y~freien Platz~s~, in deinem Inventar', ['shop_confirm'] = 'kaufe %sx %s für $%s?', - ['no'] = 'Nein', - ['yes'] = 'Ja', + ['no'] = 'nein', + ['yes'] = 'ja', } From 77bd7fa334083b5bb1e260a11d77b07cb0b63154 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Sat, 21 Mar 2020 16:34:36 +0100 Subject: [PATCH 2622/3224] vector check fixed --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index f965778b..4e1c18ab 100644 --- a/client/main.lua +++ b/client/main.lua @@ -105,7 +105,7 @@ Citizen.CreateThread(function() for k,v in pairs(Config.Zones) do for i = 1, #v.Pos, 1 do - local distance = #(playerCoords - vector3(v.Pos[i].x, v.Pos[i].y, v.Pos[i].z)) + local distance = #(playerCoords - v.Pos[i]) if distance < Config.DrawDistance then DrawMarker(Config.Type, v.Pos[i], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Config.Size.x, Config.Size.y, Config.Size.z, Config.Color.r, Config.Color.g, Config.Color.b, 100, false, true, 2, false, nil, nil, false) From 9a1dfa42ca2ed5e135f69d353d8454e1cc5eeffa Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 22 Mar 2020 09:43:43 +0100 Subject: [PATCH 2623/3224] Sync consumed ammo with server properly No more security issues here! --- client/main.lua | 51 +++++++++------------------------------ common/functions.lua | 34 +++++++++++++++----------- server/classes/player.lua | 10 ++++++++ server/main.lua | 9 ++++--- 4 files changed, 48 insertions(+), 56 deletions(-) diff --git a/client/main.lua b/client/main.lua index 106e0032..d768fc58 100644 --- a/client/main.lua +++ b/client/main.lua @@ -393,53 +393,26 @@ if Config.EnableHud then end) end --- Save loadout +-- Keep track of ammo usage Citizen.CreateThread(function() - local lastLoadout = {} - while true do - Citizen.Wait(5000) - local playerPed, loadout, loadoutChanged = PlayerPedId(), {}, false + Citizen.Wait(0) - for k,v in ipairs(Config.Weapons) do - local weaponName = v.name - local weaponHash = GetHashKey(weaponName) + if isDead then + Citizen.Wait(500) + else + local playerPed = PlayerPedId() - if HasPedGotWeapon(playerPed, weaponHash, false) then - local ammo, tintIndex, weaponComponents = GetAmmoInPedWeapon(playerPed, weaponHash), GetPedWeaponTintIndex(playerPed, weaponHash), {} + if IsPedShooting(playerPed) then + local _,weaponHash = GetCurrentPedWeapon(playerPed, true) + local weapon = ESX.GetWeaponFromHash(weaponHash) - for k2,v2 in ipairs(v.components) do - if HasPedGotWeaponComponent(playerPed, weaponHash, v2.hash) then - table.insert(weaponComponents, v2.name) - end + if weapon then + local ammoCount = GetAmmoInPedWeapon(playerPed, weaponHash) + TriggerServerEvent('esx:updateWeaponAmmo', weapon.name, ammoCount) end - - if not lastLoadout[weaponName] or lastLoadout[weaponName] ~= ammo then - loadoutChanged = true - end - - lastLoadout[weaponName] = ammo - - table.insert(loadout, { - name = weaponName, - ammo = ammo, - label = v.label, - components = weaponComponents, - tintIndex = tintIndex - }) - else - if lastLoadout[weaponName] then - loadoutChanged = true - end - - lastLoadout[weaponName] = nil end end - - if loadoutChanged and isLoadoutLoaded then - ESX.PlayerData.loadout = loadout - TriggerServerEvent('esx:updateLoadout', loadout) - end end end) diff --git a/common/functions.lua b/common/functions.lua index ed9deb82..e47b5b7f 100644 --- a/common/functions.lua +++ b/common/functions.lua @@ -20,11 +20,18 @@ end ESX.GetWeapon = function(weaponName) weaponName = string.upper(weaponName) - local weapons = ESX.GetWeaponList() - for i=1, #weapons, 1 do - if weapons[i].name == weaponName then - return i, weapons[i] + for k,v in ipairs(Config.Weapons) do + if v.name == weaponName then + return k, v + end + end +end + +ESX.GetWeaponFromHash = function(weaponHash) + for k,v in ipairs(Config.Weapons) do + if GetHashKey(v.name) == weaponHash then + return v end end end @@ -35,24 +42,23 @@ end ESX.GetWeaponLabel = function(weaponName) weaponName = string.upper(weaponName) - local weapons = ESX.GetWeaponList() - for i=1, #weapons, 1 do - if weapons[i].name == weaponName then - return weapons[i].label + for k,v in ipairs(Config.Weapons) do + if v.name == weaponName then + return v.label end end end ESX.GetWeaponComponent = function(weaponName, weaponComponent) weaponName = string.upper(weaponName) - local weapons = ESX.GetWeaponList() + local weapons = Config.Weapons - for i=1, #weapons, 1 do - if weapons[i].name == weaponName then - for j=1, #weapons[i].components, 1 do - if weapons[i].components[j].name == weaponComponent then - return weapons[i].components[j] + for k,v in ipairs(Config.Weapons) do + if v.name == weaponName then + for k2,v2 in ipairs(v.components) do + if v2.name == weaponComponent then + return v2 end end end diff --git a/server/classes/player.lua b/server/classes/player.lua index 52f661e2..0705204c 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -367,6 +367,16 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end end + self.updateWeaponAmmo = function(weaponName, ammoCount) + local loadoutNum, weapon = self.getWeapon(weaponName) + + if weapon then + if ammoCount < weapon.ammo then + weapon.ammo = ammoCount + end + end + end + self.setWeaponTint = function(weaponName, weaponTintIndex) local loadoutNum, weapon = self.getWeapon(weaponName) diff --git a/server/main.lua b/server/main.lua index 5e6b7b61..4d63e12a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -225,10 +225,13 @@ AddEventHandler('esx:updateCoords', function(coords) end end) -RegisterNetEvent('esx:updateLoadout') -AddEventHandler('esx:updateLoadout', function(loadout) +RegisterNetEvent('esx:updateWeaponAmmo') +AddEventHandler('esx:updateWeaponAmmo', function(weaponName, ammoCount) local xPlayer = ESX.GetPlayerFromId(source) - xPlayer.loadout = loadout + + if xPlayer then + xPlayer.updateWeaponAmmo(weaponName, ammoCount) + end end) RegisterNetEvent('esx:giveInventoryItem') From 986cbfb32ae03261f1d970e326cccf1f7f214cd7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 22 Mar 2020 09:47:04 +0100 Subject: [PATCH 2624/3224] Added missing trailing spaces --- client/modules/death.lua | 2 +- client/modules/scaleform.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/modules/death.lua b/client/modules/death.lua index a2aeb76b..959d8255 100644 --- a/client/modules/death.lua +++ b/client/modules/death.lua @@ -61,4 +61,4 @@ function PlayerKilled(deathCause) TriggerEvent('esx:onPlayerDeath', data) TriggerServerEvent('esx:onPlayerDeath', data) -end \ No newline at end of file +end diff --git a/client/modules/scaleform.lua b/client/modules/scaleform.lua index 20a9c6e8..681f7db1 100644 --- a/client/modules/scaleform.lua +++ b/client/modules/scaleform.lua @@ -95,4 +95,4 @@ ESX.Scaleform.Utils.RequestScaleformMovie = function(movie) end return scaleform -end \ No newline at end of file +end From 29cbe642987623683a8fd760ba5f8d6ed8f16981 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 22 Mar 2020 11:09:43 +0100 Subject: [PATCH 2625/3224] Fixed paying rent with latest ESX and added evict --- locales/br.lua | 3 +- locales/de.lua | 5 ++-- locales/en.lua | 3 +- locales/es.lua | 3 +- locales/fi.lua | 3 +- locales/fr.lua | 3 +- locales/pl.lua | 3 +- locales/sv.lua | 3 +- server/main.lua | 80 ++++++++++++++++++++++++++++++++----------------- 9 files changed, 68 insertions(+), 38 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index 98d5e412..0ff61d99 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -30,7 +30,8 @@ Locales['br'] = { ['press_to_exit'] = 'Pressione ~INPUT_CONTEXT~ para sair da propriedade', ['not_enough'] = 'Você não tem dinheiro suficiente', ['invalid_quantity'] = 'Quantidade inválida', - ['paid_rent'] = 'Você ~g~pagou~s~ seu aluguel: ~g~$%s~s~', + ['paid_rent'] = 'you paid your rent at ~g~$%s~s~ for ~y~%s~s~', + ['paid_rent_evicted'] = 'you have been ~o~evicted~s~ from ~y~%s~s~ for not affording rent at ~g~$%s~s~', ['not_enough_in_property'] = 'não há o suficiente de que esse item esteja na propriedade!', ['player_cannot_hold'] = 'você não tem espaço suficiente em seu inventário!', } diff --git a/locales/de.lua b/locales/de.lua index 9373025a..c50ebd84 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -28,11 +28,10 @@ Locales['de'] = { ['amount'] = 'Anzahlt?', ['amount_invalid'] = 'Ungültiger Wert', ['press_to_exit'] = 'Drücke ~INPUT_CONTEXT~ um die Immobilie zu verlassen', - ['rent_for'] = 'Du hast eine Immobilie gemietet ~g~$%s~s~', - ['purchased_for'] = 'Du hast eine Immobilie gekauft ~g~$%s~s~', ['not_enough'] = 'du hast nicht genug Geld', ['invalid_quantity'] = 'Ungültiger Betrag', - ['paid_rent'] = 'du ~g~bezahlst~s~ deine Miete: ~g~$%s~s~', + ['paid_rent'] = 'you paid your rent at ~g~$%s~s~ for ~y~%s~s~', + ['paid_rent_evicted'] = 'you have been ~o~evicted~s~ from ~y~%s~s~ for not affording rent at ~g~$%s~s~', ['not_enough_in_property'] = 'there\'s not enough of ~r~that item~s~ in the property!', ['player_cannot_hold'] = 'you do ~r~not~s~ have enough ~y~free space~s~ in your inventory!', } diff --git a/locales/en.lua b/locales/en.lua index 75d34bda..61296a87 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -30,7 +30,8 @@ Locales['en'] = { ['press_to_exit'] = 'press ~INPUT_CONTEXT~ to exit the property', ['not_enough'] = 'you do not have enough money', ['invalid_quantity'] = 'invalid quantity', - ['paid_rent'] = 'you ~g~paid~s~ your rent: ~g~$%s~s~', + ['paid_rent'] = 'you paid your rent at ~g~$%s~s~ for ~y~%s~s~', + ['paid_rent_evicted'] = 'you have been ~o~evicted~s~ from ~y~%s~s~ for not affording rent at ~g~$%s~s~', ['not_enough_in_property'] = 'there\'s not enough of ~r~that item~s~ in the property!', ['player_cannot_hold'] = 'you do ~r~not~s~ have enough ~y~free space~s~ in your inventory!', } diff --git a/locales/es.lua b/locales/es.lua index 387ff6c0..98966c72 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -30,7 +30,8 @@ Locales['es'] = { ['press_to_exit'] = 'Presione ~INPUT_CONTEXT~ para salir de la propiedad', ['not_enough'] = 'n\'No tiene suficiente d\'dinero', ['invalid_quantity'] = 'Cantidad inválida', - ['paid_rent'] = 'Has ~g~pagado~s~ por el alquiler: ~g~€%s~s~', + ['paid_rent'] = 'you paid your rent at ~g~€%s~s~ for ~y~%s~s~', + ['paid_rent_evicted'] = 'you have been ~o~evicted~s~ from ~y~%s~s~ for not affording rent at ~g~€%s~s~', ['not_enough_in_property'] = 'there\'s not enough of ~r~that item~s~ in the property!', ['player_cannot_hold'] = 'you do ~r~not~s~ have enough ~y~free space~s~ in your inventory!', } diff --git a/locales/fi.lua b/locales/fi.lua index ffebd828..e52417be 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -30,7 +30,8 @@ Locales['fi'] = { ['press_to_exit'] = 'paina ~INPUT_CONTEXT~ poistuaksesi kiinteistöstä', ['not_enough'] = 'sinulla ei ole tarpeeksi rahaa', ['invalid_quantity'] = 'virheellinen määrä', - ['paid_rent'] = 'sinä ~g~maksoit~s~ vuokraasi: ~g~$%s~s~', + ['paid_rent'] = 'you paid your rent at ~g~$%s~s~ for ~y~%s~s~', + ['paid_rent_evicted'] = 'you have been ~o~evicted~s~ from ~y~%s~s~ for not affording rent at ~g~$%s~s~', ['not_enough_in_property'] = 'täällä ei ole enempää ~r~tätä itemiä~s~ tässä kiinteistössä!', ['player_cannot_hold'] = 'sinulla ~r~ei ole~s~ tarpeeksi ~y~vapaata tilaa~s~ repussasi!', } diff --git a/locales/fr.lua b/locales/fr.lua index ad663e14..ed734e23 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -30,7 +30,8 @@ Locales['fr'] = { ['press_to_exit'] = 'appuyez sur ~INPUT_CONTEXT~ pour sortir de la propriété', ['not_enough'] = 'vous n\'avez pas assez d\'argent', ['invalid_quantity'] = 'quantité invalide', - ['paid_rent'] = 'vous avez ~g~payé~s~ votre loyer: ~g~$%s~s~', + ['paid_rent'] = 'you paid your rent at ~g~$%s~s~ for ~y~%s~s~', + ['paid_rent_evicted'] = 'you have been ~o~evicted~s~ from ~y~%s~s~ for not affording rent at ~g~$%s~s~', ['not_enough_in_property'] = 'il n\'a pas assez de ~r~cet objet~s~ dans votre coffre!', ['player_cannot_hold'] = 'vous n\'avez pas assez ~y~de place~s~ dans votre inventaire!', } diff --git a/locales/pl.lua b/locales/pl.lua index 985fcb2f..eb9428cb 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -30,7 +30,8 @@ Locales['pl'] = { ['press_to_exit'] = 'wciśnij ~INPUT_CONTEXT~ aby wyjść z mieszkania', ['not_enough'] = 'nie posiadasz wystarczająco pieniędzy', ['invalid_quantity'] = 'nieprawidłowa ilość', - ['paid_rent'] = '~g~zapłaciłeś/aś~s~ za wynajem: ~g~$%s~s~', + ['paid_rent'] = 'you paid your rent at ~g~$%s~s~ for ~y~%s~s~', + ['paid_rent_evicted'] = 'you have been ~o~evicted~s~ from ~y~%s~s~ for not affording rent at ~g~$%s~s~', ['not_enough_in_property'] = 'nie ma wystarczająco ~r~tego przedmiotu~s~ w mieszkaniu!', ['player_cannot_hold'] = '~r~nie masz~s~ wystarczająco ~y~wolnego~s~ miejsca w ekwipunku!', } diff --git a/locales/sv.lua b/locales/sv.lua index bf3a6d07..84ee01a2 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -30,7 +30,8 @@ Locales['sv'] = { ['press_to_exit'] = 'tryck ~INPUT_CONTEXT~ för att lämna fastigheten', ['not_enough'] = 'du har inte tillräckligt med pengar!', ['invalid_quantity'] = 'ogiltlig mängd', - ['paid_rent'] = 'du ~y~betalade~s~ din hyra: ~g~%s SEK~s~', + ['paid_rent'] = 'du betalade din hyra på ~g~%s SEK~s~ för ~y~%s~s~', + ['paid_rent_evicted'] = 'du blev ~o~vräkt~s~ från ~y~%s~s~ för att du inte har råd för att betala hyran på ~g~%s SEK~s~', ['not_enough_in_property'] = 'det finns ~r~inte~s~ tillräckligt av ~r~det objektet~s~ i fastigheten!', ['player_cannot_hold'] = 'du har ~r~inte~s~ tillräckligt med ~y~utrymme~s~ för att hålla det!', } diff --git a/server/main.lua b/server/main.lua index 980850e8..c8cd8cff 100644 --- a/server/main.lua +++ b/server/main.lua @@ -31,7 +31,7 @@ function SetPropertyOwned(name, price, rented, owner) end) end -function RemoveOwnedProperty(name, owner) +function RemoveOwnedProperty(name, owner, noPay) MySQL.Async.fetchAll('SELECT id, rented, price FROM owned_properties WHERE name = @name AND owner = @owner', { ['@name'] = name, ['@owner'] = owner @@ -45,13 +45,15 @@ function RemoveOwnedProperty(name, owner) if xPlayer then xPlayer.triggerEvent('esx_property:setPropertyOwned', name, false) - if result[1].rented == 1 then - xPlayer.showNotification(_U('moved_out')) - else - local sellPrice = ESX.Math.Round(result[1].price / Config.SellModifier) + if not noPay then + if result[1].rented == 1 then + xPlayer.showNotification(_U('moved_out')) + else + local sellPrice = ESX.Math.Round(result[1].price / Config.SellModifier) - xPlayer.showNotification(_U('moved_out_sold', ESX.Math.GroupDigits(sellPrice))) - xPlayer.addAccountMoney('bank', sellPrice) + xPlayer.showNotification(_U('moved_out_sold', ESX.Math.GroupDigits(sellPrice))) + xPlayer.addAccountMoney('bank', sellPrice) + end end end end) @@ -60,6 +62,8 @@ function RemoveOwnedProperty(name, owner) end MySQL.ready(function() + Citizen.Wait(1500) + MySQL.Async.fetchAll('SELECT * FROM properties', {}, function(properties) for i=1, #properties, 1 do @@ -162,7 +166,7 @@ AddEventHandler('esx_property:removeOwnedProperty', function(name, owner) RemoveOwnedProperty(name, owner) end) -RegisterServerEvent('esx_property:rentProperty') +RegisterNetEvent('esx_property:rentProperty') AddEventHandler('esx_property:rentProperty', function(propertyName) local xPlayer = ESX.GetPlayerFromId(source) local property = GetProperty(propertyName) @@ -171,7 +175,7 @@ AddEventHandler('esx_property:rentProperty', function(propertyName) SetPropertyOwned(propertyName, rent, true, xPlayer.identifier) end) -RegisterServerEvent('esx_property:buyProperty') +RegisterNetEvent('esx_property:buyProperty') AddEventHandler('esx_property:buyProperty', function(propertyName) local xPlayer = ESX.GetPlayerFromId(source) local property = GetProperty(propertyName) @@ -184,7 +188,7 @@ AddEventHandler('esx_property:buyProperty', function(propertyName) end end) -RegisterServerEvent('esx_property:removeOwnedProperty') +RegisterNetEvent('esx_property:removeOwnedProperty') AddEventHandler('esx_property:removeOwnedProperty', function(propertyName) local xPlayer = ESX.GetPlayerFromId(source) RemoveOwnedProperty(propertyName, xPlayer.identifier) @@ -194,7 +198,7 @@ AddEventHandler('esx_property:removeOwnedPropertyIdentifier', function(propertyN RemoveOwnedProperty(propertyName, identifier) end) -RegisterServerEvent('esx_property:saveLastProperty') +RegisterNetEvent('esx_property:saveLastProperty') AddEventHandler('esx_property:saveLastProperty', function(property) local xPlayer = ESX.GetPlayerFromId(source) @@ -204,7 +208,7 @@ AddEventHandler('esx_property:saveLastProperty', function(property) }) end) -RegisterServerEvent('esx_property:deleteLastProperty') +RegisterNetEvent('esx_property:deleteLastProperty') AddEventHandler('esx_property:deleteLastProperty', function() local xPlayer = ESX.GetPlayerFromId(source) @@ -213,7 +217,7 @@ AddEventHandler('esx_property:deleteLastProperty', function() }) end) -RegisterServerEvent('esx_property:getItem') +RegisterNetEvent('esx_property:getItem') AddEventHandler('esx_property:getItem', function(owner, type, item, count) local xPlayer = ESX.GetPlayerFromId(source) local xPlayerOwner = ESX.GetPlayerFromIdentifier(owner) @@ -262,7 +266,7 @@ AddEventHandler('esx_property:getItem', function(owner, type, item, count) end end) -RegisterServerEvent('esx_property:putItem') +RegisterNetEvent('esx_property:putItem') AddEventHandler('esx_property:putItem', function(owner, type, item, count) local xPlayer = ESX.GetPlayerFromId(source) local xPlayerOwner = ESX.GetPlayerFromIdentifier(owner) @@ -389,7 +393,7 @@ ESX.RegisterServerCallback('esx_property:getPlayerOutfit', function(source, cb, end) end) -RegisterServerEvent('esx_property:removeOutfit') +RegisterNetEvent('esx_property:removeOutfit') AddEventHandler('esx_property:removeOutfit', function(label) local xPlayer = ESX.GetPlayerFromId(source) @@ -401,28 +405,48 @@ AddEventHandler('esx_property:removeOutfit', function(label) end) end) -function PayRent(d, h, m) +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) - for i=1, #result, 1 do + for k,v in ipairs(result) do table.insert(tasks, function(cb) - local xPlayer = ESX.GetPlayerFromIdentifier(result[i].owner) + local xPlayer = ESX.GetPlayerFromIdentifier(v.owner) - -- message player if connected if xPlayer then - xPlayer.removeAccountMoney('bank', result[i].price) - xPlayer.showNotification(_U('paid_rent', ESX.Math.GroupDigits(result[i].price))) - else -- pay rent either way - MySQL.Sync.execute('UPDATE users SET bank = bank - @bank WHERE identifier = @identifier', { - ['@bank'] = result[i].price, - ['@identifier'] = result[i].owner - }) + if xPlayer.getAccount('bank').money >= v.price then + xPlayer.removeAccountMoney('bank', v.price) + xPlayer.showNotification(_U('paid_rent', ESX.Math.GroupDigits(v.price), GetProperty(v.name).label)) + else + xPlayer.showNotification(_U('paid_rent_evicted', GetProperty(v.name).label, ESX.Math.GroupDigits(v.price))) + RemoveOwnedProperty(v.name, v.owner, true) + end + 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 + RemoveOwnedProperty(v.name, v.owner, true) + end + end + end + end) end TriggerEvent('esx_addonaccount:getSharedAccount', 'society_realestateagent', function(account) - account.addMoney(result[i].price) + account.addMoney(v.price) end) cb() @@ -436,4 +460,4 @@ function PayRent(d, h, m) end) end -TriggerEvent('cron:runAt', 22, 0, PayRent) +TriggerEvent('cron:runAt', 22, 0, payRent) From d91d34670d9f1254992c158dd27008d5ffa6bee4 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 22 Mar 2020 14:32:31 +0100 Subject: [PATCH 2626/3224] =?UTF-8?q?Added=20sponsorship=20with=20Iceline?= =?UTF-8?q?=20Hosting=E2=9D=A4=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index f10cdc04..087ac490 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,20 @@ ESX was initially developed by Gizz back in 2017 for his friend as the were crea - [mysql-async](https://github.com/brouznouf/fivem-mysql-async) - [async](https://github.com/ESX-Org/async) +## Rent Server + +![Iceline hosting](https://media.discordapp.net/attachments/667787270375473183/667790233441533952/banner.gif) + +Are you thinking of starting a FiveM server of your own? [Iceline Hosting](https://iceline-hosting.com/) provide cost effective game servers, high end game VPS's with DDoS protection included, and more! + +There is an optional Managed Support Addon available for game servers and Game VPS's that add the following services: + +- Investigation and fixing errors in relation to the server or third-party scripts +- Installing third-party scripts or software +- Recovery of lost data + +Go to [Iceline Hosting](https://iceline-hosting.com/) and use promo code `ESX` for 15% off the first month on FiveM game servers, Game VPS's and Singapore VPS's. + ## Download & Installation ### Using [fvm](https://github.com/qlaffont/fvm-installer) From 4cc964b9d5b71b83c4107fef2d72e4460d69c3a4 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 22 Mar 2020 14:46:54 +0100 Subject: [PATCH 2627/3224] Updated sponsor url --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 087ac490..7f62914a 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ ESX was initially developed by Gizz back in 2017 for his friend as the were crea ![Iceline hosting](https://media.discordapp.net/attachments/667787270375473183/667790233441533952/banner.gif) -Are you thinking of starting a FiveM server of your own? [Iceline Hosting](https://iceline-hosting.com/) provide cost effective game servers, high end game VPS's with DDoS protection included, and more! +Are you thinking of starting a FiveM server of your own? [Iceline Hosting](https://iceline-hosting.com/billing/aff.php?aff=94) provide cost effective game servers, high end game VPS's with DDoS protection included, and more! There is an optional Managed Support Addon available for game servers and Game VPS's that add the following services: @@ -44,7 +44,7 @@ There is an optional Managed Support Addon available for game servers and Game V - Installing third-party scripts or software - Recovery of lost data -Go to [Iceline Hosting](https://iceline-hosting.com/) and use promo code `ESX` for 15% off the first month on FiveM game servers, Game VPS's and Singapore VPS's. +Go to [Iceline Hosting](https://iceline-hosting.com/billing/aff.php?aff=94) and use promo code `ESX` for 15% off the first month on FiveM game servers, Game VPS's and Singapore VPS's. ## Download & Installation From d8e4e8d9917dcfd92c30bf9e8ff446be537ee183 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 23 Mar 2020 11:55:55 +0100 Subject: [PATCH 2628/3224] Fixed group not storing on db when saving player --- server/functions.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/functions.lua b/server/functions.lua index 6cb0b427..eaa7bd2a 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -161,10 +161,11 @@ ESX.SavePlayer = function(xPlayer, cb) local asyncTasks = {} table.insert(asyncTasks, function(cb) - MySQL.Async.execute('UPDATE users SET accounts = @accounts, job = @job, job_grade = @job_grade, loadout = @loadout, position = @position, inventory = @inventory WHERE identifier = @identifier', { + MySQL.Async.execute('UPDATE users SET accounts = @accounts, job = @job, job_grade = @job_grade, `group` = @group, loadout = @loadout, position = @position, inventory = @inventory WHERE identifier = @identifier', { ['@accounts'] = json.encode(xPlayer.getAccounts(true)), ['@job'] = xPlayer.job.name, ['@job_grade'] = xPlayer.job.grade, + ['@group'] = xPlayer.getGroup(), ['@loadout'] = json.encode(xPlayer.getLoadout(true)), ['@position'] = json.encode(xPlayer.getCoords()), ['@identifier'] = xPlayer.identifier, From 0fc8c4d9c5028944e34ff72b73c4adb039be88d8 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 23 Mar 2020 12:10:25 +0100 Subject: [PATCH 2629/3224] Added /save and /saveall commands --- locales/br.lua | 2 ++ locales/cs.lua | 2 ++ locales/de.lua | 2 ++ locales/en.lua | 2 ++ locales/fi.lua | 2 ++ locales/fr.lua | 2 ++ locales/pl.lua | 2 ++ locales/sv.lua | 2 ++ server/commands.lua | 10 ++++++++++ 9 files changed, 26 insertions(+) diff --git a/locales/br.lua b/locales/br.lua index c2b46a7b..0dd62b99 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -62,6 +62,8 @@ Locales['br'] = { ['command_clearall'] = 'limpar o chat para todos', ['command_clearinventory'] = 'remover todos os itens do inventário', ['command_clearloadout'] = 'remova todas as armas do carregamento', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/cs.lua b/locales/cs.lua index 178bf89f..11441283 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -62,6 +62,8 @@ Locales['cs'] = { ['command_clearall'] = 'clear chat for all players', ['command_clearinventory'] = 'clear player inventory', ['command_clearloadout'] = 'clear a player loadout', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/de.lua b/locales/de.lua index 1b218200..c1d2fb9a 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -62,6 +62,8 @@ Locales['de'] = { ['command_clearall'] = 'clear chat for all players', ['command_clearinventory'] = 'clear player inventory', ['command_clearloadout'] = 'clear a player loadout', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/en.lua b/locales/en.lua index 9c3efda4..b76aba04 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -62,6 +62,8 @@ Locales['en'] = { ['command_clearall'] = 'clear chat for all players', ['command_clearinventory'] = 'clear player inventory', ['command_clearloadout'] = 'clear a player loadout', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/fi.lua b/locales/fi.lua index 9831b26e..ec4eac0e 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -62,6 +62,8 @@ Locales['fi'] = { ['command_clearall'] = 'clear chat for all players', ['command_clearinventory'] = 'clear player inventory', ['command_clearloadout'] = 'clear a player loadout', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/fr.lua b/locales/fr.lua index 0e4a4fd2..c1dd3746 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -62,6 +62,8 @@ Locales['fr'] = { ['command_clearall'] = 'vider le chat pour tous', ['command_clearinventory'] = 'vider l\'inventaire d\'un joueur', ['command_clearloadout'] = 'vider le loadout d\'un joueur', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', ['command_setcoords'] = 'se téléporter aux coordonnées', ['command_setcoords_x'] = 'axe X', ['command_setcoords_y'] = 'axe Y', diff --git a/locales/pl.lua b/locales/pl.lua index db4f89ae..1d95f19b 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -62,6 +62,8 @@ Locales['pl'] = { ['command_clearall'] = 'clear chat for all players', ['command_clearinventory'] = 'clear player inventory', ['command_clearloadout'] = 'clear a player loadout', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/sv.lua b/locales/sv.lua index b41a434e..8f9c449a 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -62,6 +62,8 @@ Locales['sv'] = { ['command_clearall'] = 'töm chatten för alla spelare', ['command_clearinventory'] = 'töm en spelares inventory', ['command_clearloadout'] = 'töm en spelares loadout', + ['command_save'] = 'spara en spelare i databas', + ['command_saveall'] = 'spara alla spelare i databas', ['command_setcoords'] = 'teleportera till koordinater', ['command_setcoords_x'] = 'x axel', ['command_setcoords_y'] = 'y axel', diff --git a/server/commands.lua b/server/commands.lua index b8a187f1..39c4a6ce 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -116,3 +116,13 @@ end, true, {help = _U('command_setgroup'), validate = true, arguments = { {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'}, {name = 'group', help = _U('command_setgroup_group'), type = 'string'}, }}) + +ESX.RegisterCommand('save', 'admin', function(xPlayer, args, showError) + ESX.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() +end, true, {help = _U('command_saveall')}) From 8a586e433cd0f68f32cc1fdf56ab364df9e35d46 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 23 Mar 2020 13:58:41 +0100 Subject: [PATCH 2630/3224] =?UTF-8?q?=E2=9A=A0=EF=B8=8F=E2=9A=A0=EF=B8=8FB?= =?UTF-8?q?REAKING=20COMMIT=E2=9A=A0=EF=B8=8F=E2=9A=A0=EF=B8=8F:=20mapmana?= =?UTF-8?q?ger=20&=20spawnmanager=20ditch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure you remove or disable mapmanager and spawnmanager --- client/main.lua | 82 ++++++++++++++++++++++++++++++------------------- server/main.lua | 8 +++-- 2 files changed, 55 insertions(+), 35 deletions(-) diff --git a/client/main.lua b/client/main.lua index d768fc58..1b2803bb 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,17 +1,44 @@ local isLoadoutLoaded, isPaused, isDead, isFirstSpawn, pickups = false, false, false, true, {} +Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + + if NetworkIsPlayerActive(PlayerId()) then + TriggerServerEvent('esx:onPlayerJoined') + break + end + end +end) + RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(playerData) ESX.PlayerLoaded = true ESX.PlayerData = playerData + local defaultModel = GetHashKey('mp_m_freemode_01') + RequestModel(defaultModel) + + while not HasModelLoaded(defaultModel) do + Citizen.Wait(100) + end + + SetPlayerModel(PlayerId(), defaultModel) + local playerPed = PlayerPedId() + + SetPedDefaultComponentVariation(playerPed) + SetModelAsNoLongerNeeded(defaultModel) + FreezeEntityPosition(playerPed, false) + + if Config.EnablePvP then + SetCanAttackFriendly(playerPed, true, false) + NetworkSetFriendlyFireOption(true) + end + if Config.EnableHud then for k,v in ipairs(playerData.accounts) do local accountTpl = '
     {{money}}
    ' - - ESX.UI.HUD.RegisterElement('account_' .. v.name, k, 0, accountTpl, { - money = ESX.Math.GroupDigits(v.money) - }) + ESX.UI.HUD.RegisterElement('account_' .. v.name, k, 0, accountTpl, {money = ESX.Math.GroupDigits(v.money)}) end local jobTpl = '
    {{job_label}} - {{grade_label}}
    ' @@ -25,43 +52,34 @@ AddEventHandler('esx:playerLoaded', function(playerData) grade_label = playerData.job.grade_label }) end + + ESX.Game.Teleport(playerPed, { + x = playerData.coords.x, + y = playerData.coords.y, + z = playerData.coords.z + 0.25, + heading = playerData.coords.heading + }, function() + isLoadoutLoaded, isDead = true, false + TriggerServerEvent('esx:onPlayerSpawn') + TriggerEvent('esx:onPlayerSpawn') + TriggerEvent('playerSpawned') -- compatibility with old scripts, will be removed soon + TriggerEvent('esx:restoreLoadout') + + Citizen.Wait(3000) + ShutdownLoadingScreen() + DoScreenFadeIn(10000) + end) end) RegisterNetEvent('esx:setMaxWeight') -AddEventHandler('esx:setMaxWeight', function(newMaxWeight) - ESX.PlayerData.maxWeight = newMaxWeight -end) - -AddEventHandler('playerSpawned', function() - if isFirstSpawn then - TriggerServerEvent('esx:playerJoined') - end - - while not ESX.PlayerLoaded do - Citizen.Wait(10) - end - - TriggerEvent('esx:restoreLoadout') - - if isFirstSpawn then - ESX.Game.Teleport(PlayerPedId(), ESX.PlayerData.coords) - isFirstSpawn = false - end - - isLoadoutLoaded, isDead = true, false - - if Config.EnablePvP then - SetCanAttackFriendly(PlayerPedId(), true, false) - NetworkSetFriendlyFireOption(true) - end -end) +AddEventHandler('esx:setMaxWeight', function(newMaxWeight) ESX.PlayerData.maxWeight = newMaxWeight end) AddEventHandler('esx:onPlayerDeath', function() isDead = true end) AddEventHandler('skinchanger:loadDefaultModel', function() isLoadoutLoaded = false end) AddEventHandler('skinchanger:modelLoaded', function() while not ESX.PlayerLoaded do - Citizen.Wait(1) + Citizen.Wait(100) end TriggerEvent('esx:restoreLoadout') diff --git a/server/main.lua b/server/main.lua index 4d63e12a..7150adad 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,6 +1,8 @@ -RegisterNetEvent('esx:playerJoined') -AddEventHandler('esx:playerJoined', function() - onPlayerJoined(source) +RegisterNetEvent('esx:onPlayerJoined') +AddEventHandler('esx:onPlayerJoined', function() + if not ESX.Players[source] then + onPlayerJoined(source) + end end) function onPlayerJoined(playerId) From 2da17bc123378100147803906bc4e805c610dab4 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 24 Mar 2020 10:33:56 +0100 Subject: [PATCH 2631/3224] Support latest esx --- client/main.lua | 9 ++++----- server/main.lua | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/client/main.lua b/client/main.lua index 2298cbb1..3596a306 100644 --- a/client/main.lua +++ b/client/main.lua @@ -28,12 +28,10 @@ AddEventHandler('esx:setJob', function(job) ESX.PlayerData.job = job end) -AddEventHandler('playerSpawned', function() +AddEventHandler('esx:onPlayerSpawn', function() isDead = false - TriggerServerEvent('esx_ambulancejob:onPlayerSpawn') if firstSpawn then - exports.spawnmanager:setAutoSpawn(false) -- disable respawn firstSpawn = false if Config.AntiCombatLog then @@ -310,10 +308,11 @@ function RespawnPed(ped, coords, heading) SetEntityCoordsNoOffset(ped, coords.x, coords.y, coords.z, false, false, false, true) NetworkResurrectLocalPlayer(coords.x, coords.y, coords.z, heading, true, false) SetPlayerInvincible(ped, false) - TriggerEvent('playerSpawned', coords.x, coords.y, coords.z) ClearPedBloodDamage(ped) - ESX.UI.Menu.CloseAll() + TriggerServerEvent('esx:onPlayerSpawn') + TriggerEvent('esx:onPlayerSpawn') + TriggerEvent('playerSpawned') -- compatibility with old scripts, will be removed soon end RegisterNetEvent('esx_phone:loaded') diff --git a/server/main.lua b/server/main.lua index 57fed8ae..664d7457 100644 --- a/server/main.lua +++ b/server/main.lua @@ -43,8 +43,8 @@ AddEventHandler('esx_ambulancejob:onPlayerDistress', function() end end) -RegisterNetEvent('esx_ambulancejob:onPlayerSpawn') -AddEventHandler('esx_ambulancejob:onPlayerSpawn', function() +RegisterNetEvent('esx:onPlayerSpawn') +AddEventHandler('esx:onPlayerSpawn', function() if deadPlayers[source] then deadPlayers[source] = nil TriggerClientEvent('esx_ambulancejob:setDeadPlayers', -1, deadPlayers) From d41b9a7d909b11a99b16eaa7f44f9e88ce36af76 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 24 Mar 2020 10:52:02 +0100 Subject: [PATCH 2632/3224] Minor locale adjustment --- locales/br.lua | 24 ++++++++++++------------ locales/cs.lua | 24 ++++++++++++------------ locales/de.lua | 24 ++++++++++++------------ locales/en.lua | 24 ++++++++++++------------ locales/fi.lua | 24 ++++++++++++------------ locales/fr.lua | 24 ++++++++++++------------ locales/pl.lua | 24 ++++++++++++------------ locales/sv.lua | 24 ++++++++++++------------ 8 files changed, 96 insertions(+), 96 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index 0dd62b99..df6faba3 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -62,18 +62,6 @@ Locales['br'] = { ['command_clearall'] = 'limpar o chat para todos', ['command_clearinventory'] = 'remover todos os itens do inventário', ['command_clearloadout'] = 'remova todas as armas do carregamento', - ['command_save'] = 'save a player to database', - ['command_saveall'] = 'save all players to database', - ['command_setcoords'] = 'teleport to coordinates', - ['command_setcoords_x'] = 'x axis', - ['command_setcoords_y'] = 'y axis', - ['command_setcoords_z'] = 'z axis', - ['command_setjob'] = 'atribuir um trabalho a um usuario', - ['command_setjob_job'] = 'o trabalho que voce deseja atribuir', - ['command_setjob_grade'] = 'o nivel de emprego', - ['command_setjob_invalid'] = 'the job, grade or both are invalid', - ['command_setgroup'] = 'set player group', - ['command_setgroup_group'] = 'group name', ['command_giveaccountmoney'] = 'dar dinheiro da conta', ['command_giveaccountmoney_account'] = 'conta', ['command_giveaccountmoney_amount'] = 'amount', @@ -90,6 +78,18 @@ Locales['br'] = { ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'atribuir um trabalho a um usuario', + ['command_setjob_job'] = 'o trabalho que voce deseja atribuir', + ['command_setjob_grade'] = 'o nivel de emprego', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', ['commanderror_invaliditem'] = 'item invalido', diff --git a/locales/cs.lua b/locales/cs.lua index 11441283..3c47581e 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -62,18 +62,6 @@ Locales['cs'] = { ['command_clearall'] = 'clear chat for all players', ['command_clearinventory'] = 'clear player inventory', ['command_clearloadout'] = 'clear a player loadout', - ['command_save'] = 'save a player to database', - ['command_saveall'] = 'save all players to database', - ['command_setcoords'] = 'teleport to coordinates', - ['command_setcoords_x'] = 'x axis', - ['command_setcoords_y'] = 'y axis', - ['command_setcoords_z'] = 'z axis', - ['command_setjob'] = 'set job for a player', - ['command_setjob_job'] = 'job name', - ['command_setjob_grade'] = 'job grade', - ['command_setjob_invalid'] = 'the job, grade or both are invalid', - ['command_setgroup'] = 'set player group', - ['command_setgroup_group'] = 'group name', ['command_giveaccountmoney'] = 'give account money', ['command_giveaccountmoney_account'] = 'valid account name', ['command_giveaccountmoney_amount'] = 'amount to add', @@ -90,6 +78,18 @@ Locales['cs'] = { ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'set job for a player', + ['command_setjob_job'] = 'job name', + ['command_setjob_grade'] = 'job grade', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', ['commanderror_invaliditem'] = 'invalid item name', diff --git a/locales/de.lua b/locales/de.lua index c1d2fb9a..34ba3e4f 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -62,18 +62,6 @@ Locales['de'] = { ['command_clearall'] = 'clear chat for all players', ['command_clearinventory'] = 'clear player inventory', ['command_clearloadout'] = 'clear a player loadout', - ['command_save'] = 'save a player to database', - ['command_saveall'] = 'save all players to database', - ['command_setcoords'] = 'teleport to coordinates', - ['command_setcoords_x'] = 'x axis', - ['command_setcoords_y'] = 'y axis', - ['command_setcoords_z'] = 'z axis', - ['command_setjob'] = 'set job for a player', - ['command_setjob_job'] = 'job name', - ['command_setjob_grade'] = 'job grade', - ['command_setjob_invalid'] = 'the job, grade or both are invalid', - ['command_setgroup'] = 'set player group', - ['command_setgroup_group'] = 'group name', ['command_giveaccountmoney'] = 'give account money', ['command_giveaccountmoney_account'] = 'valid account name', ['command_giveaccountmoney_amount'] = 'amount to add', @@ -90,6 +78,18 @@ Locales['de'] = { ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'set job for a player', + ['command_setjob_job'] = 'job name', + ['command_setjob_grade'] = 'job grade', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', ['commanderror_invaliditem'] = 'invalid item name', diff --git a/locales/en.lua b/locales/en.lua index b76aba04..8edbe2a5 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -62,18 +62,6 @@ Locales['en'] = { ['command_clearall'] = 'clear chat for all players', ['command_clearinventory'] = 'clear player inventory', ['command_clearloadout'] = 'clear a player loadout', - ['command_save'] = 'save a player to database', - ['command_saveall'] = 'save all players to database', - ['command_setcoords'] = 'teleport to coordinates', - ['command_setcoords_x'] = 'x axis', - ['command_setcoords_y'] = 'y axis', - ['command_setcoords_z'] = 'z axis', - ['command_setjob'] = 'set job for a player', - ['command_setjob_job'] = 'job name', - ['command_setjob_grade'] = 'job grade', - ['command_setjob_invalid'] = 'the job, grade or both are invalid', - ['command_setgroup'] = 'set player group', - ['command_setgroup_group'] = 'group name', ['command_giveaccountmoney'] = 'give account money', ['command_giveaccountmoney_account'] = 'valid account name', ['command_giveaccountmoney_amount'] = 'amount to add', @@ -90,6 +78,18 @@ Locales['en'] = { ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'set job for a player', + ['command_setjob_job'] = 'job name', + ['command_setjob_grade'] = 'job grade', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', ['commanderror_invaliditem'] = 'invalid item name', diff --git a/locales/fi.lua b/locales/fi.lua index ec4eac0e..a6abf874 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -62,18 +62,6 @@ Locales['fi'] = { ['command_clearall'] = 'clear chat for all players', ['command_clearinventory'] = 'clear player inventory', ['command_clearloadout'] = 'clear a player loadout', - ['command_save'] = 'save a player to database', - ['command_saveall'] = 'save all players to database', - ['command_setcoords'] = 'teleport to coordinates', - ['command_setcoords_x'] = 'x axis', - ['command_setcoords_y'] = 'y axis', - ['command_setcoords_z'] = 'z axis', - ['command_setjob'] = 'set job for a player', - ['command_setjob_job'] = 'job name', - ['command_setjob_grade'] = 'job grade', - ['command_setjob_invalid'] = 'the job, grade or both are invalid', - ['command_setgroup'] = 'set player group', - ['command_setgroup_group'] = 'group name', ['command_giveaccountmoney'] = 'give account money', ['command_giveaccountmoney_account'] = 'valid account name', ['command_giveaccountmoney_amount'] = 'amount to add', @@ -90,6 +78,18 @@ Locales['fi'] = { ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'set job for a player', + ['command_setjob_job'] = 'job name', + ['command_setjob_grade'] = 'job grade', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', ['commanderror_invaliditem'] = 'invalid item name', diff --git a/locales/fr.lua b/locales/fr.lua index c1dd3746..d0be55c0 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -62,18 +62,6 @@ Locales['fr'] = { ['command_clearall'] = 'vider le chat pour tous', ['command_clearinventory'] = 'vider l\'inventaire d\'un joueur', ['command_clearloadout'] = 'vider le loadout d\'un joueur', - ['command_save'] = 'save a player to database', - ['command_saveall'] = 'save all players to database', - ['command_setcoords'] = 'se téléporter aux coordonnées', - ['command_setcoords_x'] = 'axe X', - ['command_setcoords_y'] = 'axe Y', - ['command_setcoords_z'] = 'axe Z', - ['command_setjob'] = 'assigner job à un joueur', - ['command_setjob_job'] = 'nom du job', - ['command_setjob_grade'] = 'grade du job', - ['command_setjob_invalid'] = 'le job, le grade ou les deux sont invalides', - ['command_setgroup'] = 'assigner un groupe à un joueur', - ['command_setgroup_group'] = 'nom du groupe', ['command_giveaccountmoney'] = 'donner de l\'argent sur un compte', ['command_giveaccountmoney_account'] = 'nom de compte valide', ['command_giveaccountmoney_amount'] = 'quantité à ajouter', @@ -90,6 +78,18 @@ Locales['fr'] = { ['command_giveweaponcomponent_invalid'] = 'accessoire invalide', ['command_giveweaponcomponent_hasalready'] = 'le joueur a déjà cet accessoire', ['command_giveweaponcomponent_missingweapon'] = 'le joueur n\'a pas cette arme', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', + ['command_setcoords'] = 'se téléporter aux coordonnées', + ['command_setcoords_x'] = 'axe X', + ['command_setcoords_y'] = 'axe Y', + ['command_setcoords_z'] = 'axe Z', + ['command_setjob'] = 'assigner job à un joueur', + ['command_setjob_job'] = 'nom du job', + ['command_setjob_grade'] = 'grade du job', + ['command_setjob_invalid'] = 'le job, le grade ou les deux sont invalides', + ['command_setgroup'] = 'assigner un groupe à un joueur', + ['command_setgroup_group'] = 'nom du groupe', ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', ['commanderror_invaliditem'] = 'nom de l\'objet invalide', diff --git a/locales/pl.lua b/locales/pl.lua index 1d95f19b..31f1bf50 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -62,18 +62,6 @@ Locales['pl'] = { ['command_clearall'] = 'clear chat for all players', ['command_clearinventory'] = 'clear player inventory', ['command_clearloadout'] = 'clear a player loadout', - ['command_save'] = 'save a player to database', - ['command_saveall'] = 'save all players to database', - ['command_setcoords'] = 'teleport to coordinates', - ['command_setcoords_x'] = 'x axis', - ['command_setcoords_y'] = 'y axis', - ['command_setcoords_z'] = 'z axis', - ['command_setjob'] = 'set job for a player', - ['command_setjob_job'] = 'job name', - ['command_setjob_grade'] = 'job grade', - ['command_setjob_invalid'] = 'the job, grade or both are invalid', - ['command_setgroup'] = 'set player group', - ['command_setgroup_group'] = 'group name', ['command_giveaccountmoney'] = 'give account money', ['command_giveaccountmoney_account'] = 'valid account name', ['command_giveaccountmoney_amount'] = 'amount to add', @@ -90,6 +78,18 @@ Locales['pl'] = { ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'set job for a player', + ['command_setjob_job'] = 'job name', + ['command_setjob_grade'] = 'job grade', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', ['commanderror_invaliditem'] = 'invalid item name', diff --git a/locales/sv.lua b/locales/sv.lua index 8f9c449a..7c222e50 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -62,18 +62,6 @@ Locales['sv'] = { ['command_clearall'] = 'töm chatten för alla spelare', ['command_clearinventory'] = 'töm en spelares inventory', ['command_clearloadout'] = 'töm en spelares loadout', - ['command_save'] = 'spara en spelare i databas', - ['command_saveall'] = 'spara alla spelare i databas', - ['command_setcoords'] = 'teleportera till koordinater', - ['command_setcoords_x'] = 'x axel', - ['command_setcoords_y'] = 'y axel', - ['command_setcoords_z'] = 'z axel', - ['command_setjob'] = 'välj jobb för en spelare', - ['command_setjob_job'] = 'jobbnamn', - ['command_setjob_grade'] = 'jobbnivå', - ['command_setjob_invalid'] = 'jobbet, nivån eller båda är ej giltiga', - ['command_setgroup'] = 'välj grupp åt en spelare', - ['command_setgroup_group'] = 'gruppnamn', ['command_giveaccountmoney'] = 'ge pengar för ett konto', ['command_giveaccountmoney_account'] = 'giltigt kontonamn', ['command_giveaccountmoney_amount'] = 'mängd att ge', @@ -90,6 +78,18 @@ Locales['sv'] = { ['command_giveweaponcomponent_invalid'] = 'det vapenkomponentet är ej giltigt', ['command_giveweaponcomponent_hasalready'] = 'spelaren har redan det vapenkomponent', ['command_giveweaponcomponent_missingweapon'] = 'spelaren har ej det vapnet', + ['command_save'] = 'spara en spelare i databas', + ['command_saveall'] = 'spara alla spelare i databas', + ['command_setcoords'] = 'teleportera till koordinater', + ['command_setcoords_x'] = 'x axel', + ['command_setcoords_y'] = 'y axel', + ['command_setcoords_z'] = 'z axel', + ['command_setjob'] = 'välj jobb för en spelare', + ['command_setjob_job'] = 'jobbnamn', + ['command_setjob_grade'] = 'jobbnivå', + ['command_setjob_invalid'] = 'jobbet, nivån eller båda är ej giltiga', + ['command_setgroup'] = 'välj grupp åt en spelare', + ['command_setgroup_group'] = 'gruppnamn', ['commanderror_argumentmismatch'] = 'argumentstorlek mismatch (gav %s, ville ha %s)', ['commanderror_argumentmismatch_number'] = 'argument #%s typ mismatch (gav string, ville ha number)', ['commanderror_invaliditem'] = 'ej giltigt item', From 8a6579fd7e7c8a8469dbf92dd7c3df6d3842512d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 24 Mar 2020 10:57:25 +0100 Subject: [PATCH 2633/3224] Added /setaccountmoney command, closes #558 --- locales/br.lua | 2 ++ locales/cs.lua | 2 ++ locales/de.lua | 2 ++ locales/en.lua | 2 ++ locales/fi.lua | 2 ++ locales/fr.lua | 2 ++ locales/pl.lua | 2 ++ locales/sv.lua | 2 ++ server/commands.lua | 12 ++++++++++++ 9 files changed, 28 insertions(+) diff --git a/locales/br.lua b/locales/br.lua index df6faba3..d63f2867 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -80,6 +80,8 @@ Locales['br'] = { ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', ['command_save'] = 'save a player to database', ['command_saveall'] = 'save all players to database', + ['command_setaccountmoney'] = 'set account money for a player', + ['command_setaccountmoney_amount'] = 'amount of money to set', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/cs.lua b/locales/cs.lua index 3c47581e..10c1d3a0 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -80,6 +80,8 @@ Locales['cs'] = { ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', ['command_save'] = 'save a player to database', ['command_saveall'] = 'save all players to database', + ['command_setaccountmoney'] = 'set account money for a player', + ['command_setaccountmoney_amount'] = 'amount of money to set', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/de.lua b/locales/de.lua index 34ba3e4f..30ae1a18 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -80,6 +80,8 @@ Locales['de'] = { ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', ['command_save'] = 'save a player to database', ['command_saveall'] = 'save all players to database', + ['command_setaccountmoney'] = 'set account money for a player', + ['command_setaccountmoney_amount'] = 'amount of money to set', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/en.lua b/locales/en.lua index 8edbe2a5..a5ec7122 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -80,6 +80,8 @@ Locales['en'] = { ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', ['command_save'] = 'save a player to database', ['command_saveall'] = 'save all players to database', + ['command_setaccountmoney'] = 'set account money for a player', + ['command_setaccountmoney_amount'] = 'amount of money to set', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/fi.lua b/locales/fi.lua index a6abf874..034aebd3 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -80,6 +80,8 @@ Locales['fi'] = { ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', ['command_save'] = 'save a player to database', ['command_saveall'] = 'save all players to database', + ['command_setaccountmoney'] = 'set account money for a player', + ['command_setaccountmoney_amount'] = 'amount of money to set', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/fr.lua b/locales/fr.lua index d0be55c0..c5d74c80 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -80,6 +80,8 @@ Locales['fr'] = { ['command_giveweaponcomponent_missingweapon'] = 'le joueur n\'a pas cette arme', ['command_save'] = 'save a player to database', ['command_saveall'] = 'save all players to database', + ['command_setaccountmoney'] = 'set account money for a player', + ['command_setaccountmoney_amount'] = 'amount of money to set', ['command_setcoords'] = 'se téléporter aux coordonnées', ['command_setcoords_x'] = 'axe X', ['command_setcoords_y'] = 'axe Y', diff --git a/locales/pl.lua b/locales/pl.lua index 31f1bf50..2a04b378 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -80,6 +80,8 @@ Locales['pl'] = { ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', ['command_save'] = 'save a player to database', ['command_saveall'] = 'save all players to database', + ['command_setaccountmoney'] = 'set account money for a player', + ['command_setaccountmoney_amount'] = 'amount of money to set', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/sv.lua b/locales/sv.lua index 7c222e50..5cb32c29 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -80,6 +80,8 @@ Locales['sv'] = { ['command_giveweaponcomponent_missingweapon'] = 'spelaren har ej det vapnet', ['command_save'] = 'spara en spelare i databas', ['command_saveall'] = 'spara alla spelare i databas', + ['command_setaccountmoney'] = 'bestäm ny balans på ett spelarkonto', + ['command_setaccountmoney_amount'] = 'ny balans', ['command_setcoords'] = 'teleportera till koordinater', ['command_setcoords_x'] = 'x axel', ['command_setcoords_y'] = 'y axel', diff --git a/server/commands.lua b/server/commands.lua index 39c4a6ce..11d8f941 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -30,6 +30,18 @@ end, false, {help = _U('command_cardel'), validate = false, arguments = { {name = 'radius', help = _U('command_cardel_radius'), type = 'any'} }}) +ESX.RegisterCommand('setaccountmoney', 'admin', function(xPlayer, args, showError) + if args.playerId.getAccount(args.account) then + args.playerId.setAccountMoney(args.account, args.amount) + else + showError(_U('command_giveaccountmoney_invalid')) + end +end, true, {help = _U('command_setaccountmoney'), validate = true, arguments = { + {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'}, + {name = 'account', help = _U('command_giveaccountmoney_account'), type = 'string'}, + {name = 'amount', help = _U('command_setaccountmoney_amount'), type = 'number'} +}}) + ESX.RegisterCommand('giveaccountmoney', 'admin', function(xPlayer, args, showError) if args.playerId.getAccount(args.account) then args.playerId.addAccountMoney(args.account, args.amount) From 2c4d33defaf7b337ca7d08d308b023e9120010c1 Mon Sep 17 00:00:00 2001 From: Oldarorn <36448848+Oldarorn@users.noreply.github.com> Date: Tue, 24 Mar 2020 13:49:34 +0100 Subject: [PATCH 2634/3224] Update fr.lua --- locales/fr.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index c5d74c80..7512e33b 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -78,10 +78,10 @@ Locales['fr'] = { ['command_giveweaponcomponent_invalid'] = 'accessoire invalide', ['command_giveweaponcomponent_hasalready'] = 'le joueur a déjà cet accessoire', ['command_giveweaponcomponent_missingweapon'] = 'le joueur n\'a pas cette arme', - ['command_save'] = 'save a player to database', - ['command_saveall'] = 'save all players to database', - ['command_setaccountmoney'] = 'set account money for a player', - ['command_setaccountmoney_amount'] = 'amount of money to set', + ['command_save'] = 'sauvegarder un joueur dans la base de données', + ['command_saveall'] = 'sauvegarder tous les joueurs dans la base de données', + ['command_setaccountmoney'] = 'définir la somme d\'argent pour un joueur', + ['command_setaccountmoney_amount'] = 'quantité d\'argent à définir', ['command_setcoords'] = 'se téléporter aux coordonnées', ['command_setcoords_x'] = 'axe X', ['command_setcoords_y'] = 'axe Y', From be2dc2e9e2d94434b6d8fde1dc1d1ecfd24f89b6 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 25 Mar 2020 22:45:23 +0100 Subject: [PATCH 2635/3224] Minor adjustments --- client/main.lua | 2 +- server/functions.lua | 2 +- server/main.lua | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/client/main.lua b/client/main.lua index 1b2803bb..16d1f9c3 100644 --- a/client/main.lua +++ b/client/main.lua @@ -56,7 +56,7 @@ AddEventHandler('esx:playerLoaded', function(playerData) ESX.Game.Teleport(playerPed, { x = playerData.coords.x, y = playerData.coords.y, - z = playerData.coords.z + 0.25, + z = playerData.coords.z + 0.5, heading = playerData.coords.heading }, function() isLoadoutLoaded, isDead = true, false diff --git a/server/functions.lua b/server/functions.lua index eaa7bd2a..74e2efcc 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -168,7 +168,7 @@ ESX.SavePlayer = function(xPlayer, cb) ['@group'] = xPlayer.getGroup(), ['@loadout'] = json.encode(xPlayer.getLoadout(true)), ['@position'] = json.encode(xPlayer.getCoords()), - ['@identifier'] = xPlayer.identifier, + ['@identifier'] = xPlayer.getIdentifier(), ['@inventory'] = json.encode(xPlayer.getInventory(true)) }, function(rowsChanged) cb() diff --git a/server/main.lua b/server/main.lua index 7150adad..30e97f82 100644 --- a/server/main.lua +++ b/server/main.lua @@ -131,6 +131,10 @@ function loadESXPlayer(identifier, playerId) }) end + table.sort(userData.inventory, function(a, b) + return a.label < b.label + end) + -- Group if result[1].group then userData.group = result[1].group @@ -138,10 +142,6 @@ function loadESXPlayer(identifier, playerId) userData.group = 'user' end - table.sort(userData.inventory, function(a, b) - return a.label < b.label - end) - -- Loadout if result[1].loadout and result[1].loadout ~= '' then local loadout = json.decode(result[1].loadout) @@ -184,12 +184,12 @@ function loadESXPlayer(identifier, playerId) xPlayer.triggerEvent('esx:playerLoaded', { accounts = xPlayer.getAccounts(), coords = xPlayer.getCoords(), - identifier = xPlayer.identifier, + identifier = xPlayer.getIdentifier(), inventory = xPlayer.getInventory(), job = xPlayer.getJob(), loadout = xPlayer.getLoadout(), maxWeight = xPlayer.maxWeight, - money = xPlayer.getMoney(), + money = xPlayer.getMoney() }) xPlayer.triggerEvent('esx:createMissingPickups', ESX.Pickups) From 09e50046c0332f333ca139888a630c9e14326571 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 26 Mar 2020 11:24:51 +0100 Subject: [PATCH 2636/3224] Only apply a player model if coming from loading screen --- client/main.lua | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/client/main.lua b/client/main.lua index 16d1f9c3..a5f24ce2 100644 --- a/client/main.lua +++ b/client/main.lua @@ -16,20 +16,26 @@ AddEventHandler('esx:playerLoaded', function(playerData) ESX.PlayerLoaded = true ESX.PlayerData = playerData - local defaultModel = GetHashKey('mp_m_freemode_01') - RequestModel(defaultModel) + -- check if player is coming from loading screen + if GetEntityModel(PlayerPedId()) == GetHashKey('PLAYER_ZERO') then + local defaultModel = GetHashKey('a_m_y_stbla_02') + RequestModel(defaultModel) - while not HasModelLoaded(defaultModel) do - Citizen.Wait(100) + while not HasModelLoaded(defaultModel) do + Citizen.Wait(100) + end + + SetPlayerModel(PlayerId(), defaultModel) + local playerPed = PlayerPedId() + + SetPedDefaultComponentVariation(playerPed) + SetPedRandomComponentVariation(playerPed, true) + SetModelAsNoLongerNeeded(defaultModel) + FreezeEntityPosition(playerPed, false) end - SetPlayerModel(PlayerId(), defaultModel) local playerPed = PlayerPedId() - SetPedDefaultComponentVariation(playerPed) - SetModelAsNoLongerNeeded(defaultModel) - FreezeEntityPosition(playerPed, false) - if Config.EnablePvP then SetCanAttackFriendly(playerPed, true, false) NetworkSetFriendlyFireOption(true) From fde5571b43096bc10f5a2369f91a6574c0b28f38 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 26 Mar 2020 11:59:27 +0100 Subject: [PATCH 2637/3224] Improved error messages and fixed players joining with same identifier, fixes #605 --- server/main.lua | 68 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/server/main.lua b/server/main.lua index 30e97f82..ce395123 100644 --- a/server/main.lua +++ b/server/main.lua @@ -16,31 +16,59 @@ function onPlayerJoined(playerId) end if identifier then - MySQL.Async.fetchScalar('SELECT 1 FROM users WHERE identifier = @identifier', { - ['@identifier'] = identifier - }, function(result) - if result then - loadESXPlayer(identifier, playerId) - else - local accounts = {} - - for account,money in pairs(Config.StartingAccountMoney) do - accounts[account] = money - end - - MySQL.Async.execute('INSERT INTO users (accounts, identifier) VALUES (@accounts, @identifier)', { - ['@accounts'] = json.encode(accounts), - ['@identifier'] = identifier - }, function(rowsChanged) + 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) - end) - end - end) + else + local accounts = {} + + for account,money in pairs(Config.StartingAccountMoney) do + accounts[account] = money + end + + MySQL.Async.execute('INSERT INTO users (accounts, identifier) VALUES (@accounts, @identifier)', { + ['@accounts'] = json.encode(accounts), + ['@identifier'] = identifier + }, function(rowsChanged) + loadESXPlayer(identifier, playerId) + end) + end + end) + end else - DropPlayer(playerId, 'Your Rockstar license could not be found') + DropPlayer(playerId, 'there was an error loading your character!\nError code: identifier-missing-ingame\n\nThe cause of this error is not known, your identifier could not be found. Please come back later or report this problem to the server administration team.') end end +AddEventHandler('playerConnecting', function(name, setCallback, deferrals) + deferrals.defer() + local playerId, identifier = source + Citizen.Wait(100) + + for k,v in ipairs(GetPlayerIdentifiers(playerId)) do + if string.match(v, 'license:') then + identifier = string.sub(v, 9) + break + end + end + + if identifier then + if ESX.GetPlayerFromIdentifier(identifier) then + deferrals.done(('There was an error loading your character!\nError code: identifier-active\n\nThis error is caused by a player on this server who has the same identifier as you have. Make sure you are not playing on the same Rockstar account.\n\nYour Rockstar identifier: %s'):format(identifier)) + else + deferrals.done() + end + else + deferrals.done('There was an error loading your character!\nError code: identifier-missing\n\nThe cause of this error is not known, your identifier could not be found. Please come back later or report this problem to the server administration team.') + end +end) + + function loadESXPlayer(identifier, playerId) local tasks = {} From 77e810ce9586081fd7a79db6e11a92f08647f60b Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 26 Mar 2020 12:10:45 +0100 Subject: [PATCH 2638/3224] Fixed setting vehicle pearlescent color Co-Authored-By: Daniel Hawton Co-Authored-By: ChainTastic --- client/functions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/functions.lua b/client/functions.lua index 07c9cab4..ce849263 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -765,7 +765,7 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) if props.color1 then SetVehicleColours(vehicle, props.color1, colorSecondary) end if props.color2 then SetVehicleColours(vehicle, props.color1 or colorPrimary, props.color2) end if props.pearlescentColor then SetVehicleExtraColours(vehicle, props.pearlescentColor, wheelColor) end - if props.wheelColor then SetVehicleExtraColours(vehicle, pearlescentColor, props.wheelColor) end + if props.wheelColor then SetVehicleExtraColours(vehicle, props.pearlescentColor or pearlescentColor, props.wheelColor) end if props.wheels then SetVehicleWheelType(vehicle, props.wheels) end if props.windowTint then SetVehicleWindowTint(vehicle, props.windowTint) end From bc5bf99d4bd52daf8efe2663ea180ae0f2406ad9 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 26 Mar 2020 12:32:35 +0100 Subject: [PATCH 2639/3224] Fixed sql file for latest ESX, fixes #108 --- localization/br_esx_jobs.sql | 40 ++++++++++++++++++------------------ localization/de_esx_jobs.sql | 40 ++++++++++++++++++------------------ localization/en_esx_jobs.sql | 38 +++++++++++++++++----------------- localization/fi_esx_jobs.sql | 40 ++++++++++++++++++------------------ localization/sv_esx_jobs.sql | 40 ++++++++++++++++++------------------ 5 files changed, 99 insertions(+), 99 deletions(-) diff --git a/localization/br_esx_jobs.sql b/localization/br_esx_jobs.sql index 7892cbc6..a072620c 100644 --- a/localization/br_esx_jobs.sql +++ b/localization/br_esx_jobs.sql @@ -24,24 +24,24 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ('slaughterer',0,'employee','Temporario',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}') ; -INSERT INTO `items` (`name`, `label`) VALUES - ('alive_chicken', 'Frango Vivo', 20), - ('slaughtered_chicken', 'Frango Abatido', 20), - ('packaged_chicken', 'Frango na Bandeja', 100), - ('fish', 'Peixe', 100), - ('stone', 'Pedra', 7), - ('washed_stone', 'Pedra Limpa', 7), - ('copper', 'Cobre', 56), - ('iron', 'Ferro', 42), - ('gold', 'Ouro', 21), - ('diamond', 'Diamante', 50), - ('wood', 'Madeira', 20), - ('cutted_wood', 'Madeira Cortada', 20), - ('packaged_plank', 'Tábua Embalada', 100), - ('petrol', 'Petroleo', 24), - ('petrol_raffin', 'Petroleo Refinado', 24), - ('essence', 'Gasolina', 24), - ('wool', 'Lã', 40), - ('fabric', 'Tecido', 80), - ('clothe', 'Roupa', 40) +INSERT INTO `items` (`name`, `label`, `weight`) VALUES + ('alive_chicken', 'Frango Vivo', 1), + ('slaughtered_chicken', 'Frango Abatido', 1), + ('packaged_chicken', 'Frango na Bandeja', 1), + ('fish', 'Peixe', 1), + ('stone', 'Pedra', 1), + ('washed_stone', 'Pedra Limpa', 1), + ('copper', 'Cobre', 1), + ('iron', 'Ferro', 1), + ('gold', 'Ouro', 1), + ('diamond', 'Diamante', 1), + ('wood', 'Madeira', 1), + ('cutted_wood', 'Madeira Cortada', 1), + ('packaged_plank', 'Tábua Embalada', 1), + ('petrol', 'Petroleo', 1), + ('petrol_raffin', 'Petroleo Refinado', 1), + ('essence', 'Gasolina', 1), + ('wool', 'Lã', 1), + ('fabric', 'Tecido', 1), + ('clothe', 'Roupa', 1) ; diff --git a/localization/de_esx_jobs.sql b/localization/de_esx_jobs.sql index 9ea10827..2613a1e5 100644 --- a/localization/de_esx_jobs.sql +++ b/localization/de_esx_jobs.sql @@ -24,24 +24,24 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ('slaughterer',0,'employee','Mitarbeiter', 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}') ; -INSERT INTO `items` (`name`, `label`, `limit`) VALUES - ('alive_chicken', 'lebendes Huhn', 20), - ('slaughtered_chicken', 'geschlachtetes Huhn', 20), - ('packaged_chicken', 'Hähnchenfilet', 100), - ('fish', 'Fisch', 100), - ('stone', 'Felsbrocken', 7), - ('washed_stone', 'gewaschener Felsbrocken', 7), - ('copper', 'Kupfer', 56), - ('iron', 'Eisen', 42), - ('gold', 'Gold', 21), - ('diamond', 'Diamant', 50), - ('wood', 'Holz', 20), - ('cutted_wood', 'Holzstämme', 20), - ('packaged_plank', 'Bretterpaket', 100), - ('petrol', 'Öl', 24), - ('petrol_raffin', 'bearbeitetes Öl', 24), - ('essence', 'Benzin', 24), - ('wool', 'Wolle', 40), - ('fabric', 'Tuch', 80), - ('clothe', 'Kleidung', 40) +INSERT INTO `items` (`name`, `label`, `weight`) VALUES + ('alive_chicken', 'lebendes Huhn', 1), + ('slaughtered_chicken', 'geschlachtetes Huhn', 1), + ('packaged_chicken', 'Hähnchenfilet', 1), + ('fish', 'Fisch', 1), + ('stone', 'Felsbrocken', 1), + ('washed_stone', 'gewaschener Felsbrocken', 1), + ('copper', 'Kupfer', 1), + ('iron', 'Eisen', 1), + ('gold', 'Gold', 1), + ('diamond', 'Diamant', 1), + ('wood', 'Holz', 1), + ('cutted_wood', 'Holzstämme', 1), + ('packaged_plank', 'Bretterpaket', 1), + ('petrol', 'Öl', 1), + ('petrol_raffin', 'bearbeitetes Öl', 1), + ('essence', 'Benzin', 1), + ('wool', 'Wolle', 1), + ('fabric', 'Tuch', 1), + ('clothe', 'Kleidung', 1) ; diff --git a/localization/en_esx_jobs.sql b/localization/en_esx_jobs.sql index 89cd925f..43fa050e 100644 --- a/localization/en_esx_jobs.sql +++ b/localization/en_esx_jobs.sql @@ -25,23 +25,23 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ; INSERT INTO `items` (`name`, `label`, `limit`) VALUES - ('alive_chicken', 'living chicken', 20), - ('slaughtered_chicken', 'slaughtered chicken', 20), - ('packaged_chicken', 'chicken fillet', 100), - ('fish', 'fish', 100), - ('stone', 'stone', 7), - ('washed_stone', 'washed stone', 7), - ('copper', 'copper', 56), - ('iron', 'iron', 42), - ('gold', 'gold', 21), - ('diamond', 'diamond', 50), - ('wood', 'wood', 20), - ('cutted_wood', 'cut wood', 20), - ('packaged_plank', 'packaged wood', 100), - ('petrol', 'oil', 24), - ('petrol_raffin', 'processed oil', 24), - ('essence', 'gas', 24), - ('wool', 'wool', 40), - ('fabric', 'fabric', 80), - ('clothe', 'cloth', 40) + ('alive_chicken', 'Living chicken', 1), + ('slaughtered_chicken', 'Slaughtered chicken', 1), + ('packaged_chicken', 'Chicken fillet', 1), + ('fish', 'Fish', 1), + ('stone', 'Stone', 1), + ('washed_stone', 'Washed stone', 1), + ('copper', 'Copper', 1), + ('iron', 'Iron', 1), + ('gold', 'Gold', 1), + ('diamond', 'Diamond', 1), + ('wood', 'Wood', 1), + ('cutted_wood', 'Cut wood', 1), + ('packaged_plank', 'Packaged wood', 1), + ('petrol', 'Oil', 1), + ('petrol_raffin', 'Processed oil', 1), + ('essence', 'Gas', 1), + ('wool', 'Wool', 1), + ('fabric', 'Fabric', 1), + ('clothe', 'Cloth', 1) ; diff --git a/localization/fi_esx_jobs.sql b/localization/fi_esx_jobs.sql index 8a751f3c..4a86be05 100644 --- a/localization/fi_esx_jobs.sql +++ b/localization/fi_esx_jobs.sql @@ -24,24 +24,24 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ('slaughterer', 0, 'interim', 'Työläinen', 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}') ; -INSERT INTO `items` (`name`, `label`, `limit`) VALUES - ('alive_chicken', 'Elävä kana', 20), - ('slaughtered_chicken', 'Teurastettu kana', 20), - ('packaged_chicken', 'Kananfilee', 100), - ('fish', 'Kala', 100), - ('stone', 'Kivi', 7), - ('washed_stone', 'Puhdistettu Kivi', 7), - ('copper', 'Kupari', 56), - ('iron', 'Rauta', 42), - ('gold', 'Kulta', 21), - ('diamond', 'Timantti', 50), - ('wood', 'Puu', 20), - ('cutted_wood', 'Pilkottu Puu', 20), - ('packaged_plank', 'Paketoitu Lankku', 100), - ('petrol', 'Öljy', 24), - ('petrol_raffin', 'Prosessoitu Öljy', 24), - ('essence', 'Polttoöljy', 24), - ('wool', 'Villa', 40), - ('fabric', 'Kangas', 80), - ('clothe', 'Vaate', 40) +INSERT INTO `items` (`name`, `label`, `weight`) VALUES + ('alive_chicken', 'Elävä kana', 1), + ('slaughtered_chicken', 'Teurastettu kana', 1), + ('packaged_chicken', 'Kananfilee', 1), + ('fish', 'Kala', 1), + ('stone', 'Kivi', 1), + ('washed_stone', 'Puhdistettu Kivi', 1), + ('copper', 'Kupari', 1), + ('iron', 'Rauta', 1), + ('gold', 'Kulta', 1), + ('diamond', 'Timantti', 1), + ('wood', 'Puu', 1), + ('cutted_wood', 'Pilkottu Puu', 1), + ('packaged_plank', 'Paketoitu Lankku', 1), + ('petrol', 'Öljy', 1), + ('petrol_raffin', 'Prosessoitu Öljy', 1), + ('essence', 'Polttoöljy', 1), + ('wool', 'Villa', 1), + ('fabric', 'Kangas', 1), + ('clothe', 'Vaate', 1) ; diff --git a/localization/sv_esx_jobs.sql b/localization/sv_esx_jobs.sql index 7116073a..92ababa6 100644 --- a/localization/sv_esx_jobs.sql +++ b/localization/sv_esx_jobs.sql @@ -24,24 +24,24 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ('slaughterer', 0, 'employee', 'Anställd', 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}') ; -INSERT INTO `items` (`name`, `label`, `limit`) VALUES - ('alive_chicken', 'levande kyckling', 20), - ('slaughtered_chicken', 'slaktad kyckling', 20), - ('packaged_chicken', 'paketerad kyckling', 100), - ('fish', 'fisk', 100), - ('stone', 'sten', 7), - ('washed_stone', 'tvättad sten', 7), - ('copper', 'coppar', 56), - ('iron', 'järn', 42), - ('gold', 'guld', 21), - ('diamond', 'diamant', 50), - ('wood', 'trä', 20), - ('cutted_wood', 'sågat trä', 20), - ('packaged_plank', 'paketerad trä', 100), - ('petrol', 'olja', 24), - ('petrol_raffin', 'bearbetad olja', 24), - ('essence', 'gas', 24), - ('wool', 'ull', 40), - ('fabric', 'tyg', 80), - ('clothe', 'kläde', 40) +INSERT INTO `items` (`name`, `label`, `weight`) VALUES + ('alive_chicken', 'Levande kyckling', 1), + ('slaughtered_chicken', 'Slaktad kyckling', 1), + ('packaged_chicken', 'Paketerad kyckling', 1), + ('fish', 'Fisk', 1), + ('stone', 'Sten', 1), + ('washed_stone', 'Tvättad sten', 1), + ('copper', 'Koppar', 1), + ('iron', 'Järn', 1), + ('gold', 'Guld', 1), + ('diamond', 'Diamant', 1), + ('wood', 'Trä', 1), + ('cutted_wood', 'Sågat trä', 1), + ('packaged_plank', 'Paketerad trä', 1), + ('petrol', 'Råolja', 1), + ('petrol_raffin', 'Raffinerad olja', 1), + ('essence', 'Gas', 1), + ('wool', 'Ull', 1), + ('fabric', 'Textil', 1), + ('clothe', 'Tyg', 1) ; From 9bcddfed264521147bb240458908ca4e69c9d7f0 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 26 Mar 2020 12:33:15 +0100 Subject: [PATCH 2640/3224] Update esx_jobs.sql --- esx_jobs.sql | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/esx_jobs.sql b/esx_jobs.sql index ed88e1aa..70b8ca37 100644 --- a/esx_jobs.sql +++ b/esx_jobs.sql @@ -24,24 +24,24 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ('slaughterer',0,'employee','Intérimaire',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}') ; -INSERT INTO `items` (`name`, `label`, `limit`) VALUES - ('alive_chicken', 'Poulet vivant', 20), - ('slaughtered_chicken', 'Poulet abattu', 20), - ('packaged_chicken', 'Poulet en barquette', 100), - ('fish', 'Poisson', 100), - ('stone', 'Pierre', 7), - ('washed_stone', 'Pierre Lavée', 7), - ('copper', 'Cuivre', 56), - ('iron', 'Fer', 42), - ('gold', 'Or', 21), - ('diamond', 'Diamant', 50), - ('wood', 'Bois', 20), - ('cutted_wood', 'Bois coupé', 20), - ('packaged_plank', 'Paquet de planches', 100), - ('petrol', 'Pétrole', 24), - ('petrol_raffin', 'Pétrole Raffiné', 24), - ('essence', 'Essence', 24), - ('wool', 'Laine', 40), - ('fabric', 'Tissu', 80), - ('clothe', 'Vêtement', 40) +INSERT INTO `items` (`name`, `label`, `weight`) VALUES + ('alive_chicken', 'Poulet vivant', 1), + ('slaughtered_chicken', 'Poulet abattu', 1), + ('packaged_chicken', 'Poulet en barquette', 1), + ('fish', 'Poisson', 1), + ('stone', 'Pierre', 1), + ('washed_stone', 'Pierre Lavée', 1), + ('copper', 'Cuivre', 1), + ('iron', 'Fer', 1), + ('gold', 'Or', 1), + ('diamond', 'Diamant', 1), + ('wood', 'Bois', 1), + ('cutted_wood', 'Bois coupé', 1), + ('packaged_plank', 'Paquet de planches', 1), + ('petrol', 'Pétrole', 1), + ('petrol_raffin', 'Pétrole Raffiné', 1), + ('essence', 'Essence', 1), + ('wool', 'Laine', 1), + ('fabric', 'Tissu', 1), + ('clothe', 'Vêtement', 1) ; From 027953b624c4b1923478914c90b39a9d59e58b8d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 26 Mar 2020 21:55:41 +0100 Subject: [PATCH 2641/3224] Removed unused code --- README.md | 2 +- server/main.lua | 17 ++++------------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 7718912e..97236dcb 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ end) ### License esx_datastore - datastore inventory for ESX -Copyright (C) 2015-2019 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi 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. diff --git a/server/main.lua b/server/main.lua index 37b4b8c2..1317420c 100644 --- a/server/main.lua +++ b/server/main.lua @@ -7,10 +7,7 @@ MySQL.ready(function() local result = MySQL.Sync.fetchAll('SELECT * FROM datastore') for i=1, #result, 1 do - local name = result[i].name - local label = result[i].label - local shared = result[i].shared - + 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 }) @@ -28,7 +25,7 @@ MySQL.ready(function() table.insert(DataStores[name], dataStore) end else - local data = nil + local data if #result2 == 0 then MySQL.Sync.execute('INSERT INTO datastore_data (name, owner, data) VALUES (@name, NULL, \'{}\')', { @@ -81,13 +78,11 @@ AddEventHandler('esx_datastore:getSharedDataStore', function(name, cb) end) AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) - local dataStores = {} - for i=1, #DataStoresIndex, 1 do - local name = DataStoresIndex[i] + local name = DataStoresIndex[i] local dataStore = GetDataStore(name, xPlayer.identifier) - if dataStore == nil then + if not dataStore then MySQL.Async.execute('INSERT INTO datastore_data (name, owner, data) VALUES (@name, @owner, @data)', { ['@name'] = name, ['@owner'] = xPlayer.identifier, @@ -97,9 +92,5 @@ AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) dataStore = CreateDataStore(name, xPlayer.identifier, {}) table.insert(DataStores[name], dataStore) end - - table.insert(dataStores, dataStore) end - - xPlayer.set('dataStores', dataStores) end) From 93772d378f25d0520590a9f490a472d835efcc99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BA=BB=E8=BE=A3=E6=88=88=E5=A3=81?= Date: Mon, 30 Mar 2020 16:20:37 +0800 Subject: [PATCH 2642/3224] Add simplified Chinese and traditional Chinese language (#588) * Add simplified Chinese and traditional Chinese language * Update tc.lua * Added new translations * Added new translations * Update sc.lua * Update tc.lua * Very final strings to translate * Update sc.lua * Update tc.lua Co-authored-by: ElPumpo --- fxmanifest.lua | 4 + locales/sc.lua | 225 +++++++++++++++++++++++++++++++++++++++++++++++++ locales/tc.lua | 225 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 454 insertions(+) create mode 100644 locales/sc.lua create mode 100644 locales/tc.lua diff --git a/fxmanifest.lua b/fxmanifest.lua index eb6e6f19..0f1c2f78 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -19,6 +19,8 @@ server_scripts { 'locales/sv.lua', 'locales/pl.lua', 'locales/cs.lua', + 'locales/sc.lua', + 'locales/tc.lua', 'config.lua', 'config.weapons.lua', @@ -45,6 +47,8 @@ client_scripts { 'locales/sv.lua', 'locales/pl.lua', 'locales/cs.lua', + 'locales/sc.lua', + 'locales/tc.lua', 'config.lua', 'config.weapons.lua', diff --git a/locales/sc.lua b/locales/sc.lua new file mode 100644 index 00000000..050637e2 --- /dev/null +++ b/locales/sc.lua @@ -0,0 +1,225 @@ +Locales['sc'] = { + -- Inventory + ['inventory'] = '库存 %s / %s', + ['use'] = '使用', + ['give'] = '赠送', + ['remove'] = '丢弃', + ['return'] = '返回', + ['give_to'] = '赠给', + ['amount'] = '数量', + ['giveammo'] = '赠送弹药', + ['amountammo'] = '弹药量', + ['noammo'] = '你没有足够的弹药!', + ['gave_item'] = '你把~y~%sx~s~~b~%s~s~赠给了~y~%s~s~', + ['received_item'] = '你收到~y~%sx~s~~b~%s~s~,来自~b~%s~s~', + ['gave_weapon'] = '你把~b~%s~s~赠给了~y~%s~s~', + ['gave_weapon_ammo'] = '你把~o~%sx~s~~b~%s~s~ %s~s~赠给了~y~%s~s~', + ['gave_weapon_withammo'] = '你把~b~%s~s~和~o~%sx~s~ %s~s~赠给了~y~%s~s~', + ['gave_weapon_hasalready'] = '~y~%s~s~已经拥有~y~%s~s~', + ['gave_weapon_noweapon'] = '~y~%s~s~没有那个武器', + ['received_weapon'] = '你收到了~b~%s~s~,来自~b~%s~s~', + ['received_weapon_ammo'] = '你收到了~o~%sx~s~ %s~s~(~b~%s~s~),来自~b~%s~s~', + ['received_weapon_withammo'] = '你收到了~b~%s~s~和~o~%sx~s~ %s~s~,来自~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~试图给你~y~%s~s~,但你已经拥有了', + ['received_weapon_noweapon'] = '~b~%s~s~试图给你~y~%s~s~弹药,但你没有那个武器', + ['gave_account_money'] = '你将 ~g~$%s~s~ (%s) 给予 ~y~%s~s~', + ['received_account_money'] = '你收到了~g~$%s~s~ (%s) 来自 ~b~%s~s~', + ['amount_invalid'] = '无效数量', + ['players_nearby'] = '附近没有玩家', + ['ex_inv_lim'] = '操作失败, 超过~y~%s~s~的物品栏限制', + ['imp_invalid_quantity'] = '操作失败,无效数量', + ['imp_invalid_amount'] = '操作失败,无效金额', + ['threw_standard'] = '你丢弃了~y~%sx~s~~b~%s~s~', + ['threw_account'] = '你丢弃了~g~$%s~s~~b~%s~s~', + ['threw_weapon'] = '你丢弃了~b~%s~s~', + ['threw_weapon_ammo'] = '你丢弃了~b~%s~s~和~o~%sx%s~s~', + ['threw_weapon_already'] = '你已经有同样的武器了', + ['threw_cannot_pickup'] = '你不能再拿起那个了,因为你的库存已经满了', + ['threw_pickup_prompt'] = '按 ~y~E~s~ 拿起', + + -- Key mapping + ['keymap_showinventory'] = '显示库存', + + -- Salary related + ['received_salary'] = '你收到了你的工资: ~g~$%s~s~', + ['received_help'] = '鉴于你良好的表现,系统赠送给你一些奖励: ~g~$%s~s~', + ['company_nomoney'] = '你受雇的公司太穷了,无法支付你的工资。', + ['received_paycheck'] = '收到转账', + ['bank'] = '花园银行', + ['account_bank'] = '银行', + ['account_black_money'] = '黑钱', + ['account_money'] = '现金', + + ['act_imp'] = '操作失败', + ['in_vehicle'] = '请离开载具', + + -- Commands + ['command_car'] = '生成载具', + ['command_car_car'] = '生成载具的模型名称或哈希值', + ['command_cardel'] = '删除附近的载具', + ['command_cardel_radius'] = '可选,删除指定半径内的所有车辆', + ['command_clear'] = '清除聊天记录', + ['command_clearall'] = '清除所有玩家的聊天记录', + ['command_clearinventory'] = '清除玩家库存', + ['command_clearloadout'] = '清除玩家皮肤', + ['command_giveaccountmoney'] = '给帐户钱', + ['command_giveaccountmoney_account'] = '有效的帐户名', + ['command_giveaccountmoney_amount'] = '添加的数量', + ['command_giveaccountmoney_invalid'] = '无效的帐户名', + ['command_giveitem'] = '给玩家一件物品', + ['command_giveitem_item'] = '物品名称', + ['command_giveitem_count'] = '物品数目', + ['command_giveweapon'] = '给玩家一件武器', + ['command_giveweapon_weapon'] = '武器名称', + ['command_giveweapon_ammo'] = '弹药数目', + ['command_giveweapon_hasalready'] = '该玩家已经拥有该武器', + ['command_giveweaponcomponent'] = '给武器配件', + ['command_giveweaponcomponent_component'] = '配件名称', + ['command_giveweaponcomponent_invalid'] = '无效的武器配件', + ['command_giveweaponcomponent_hasalready'] = '玩家已经拥有该武器配件', + ['command_giveweaponcomponent_missingweapon'] = '该玩家没有那个武器', + ['command_save'] = '保存玩家数据至数据库', + ['command_saveall'] = '保存所有玩家数据至数据库', + ['command_setaccountmoney'] = '为玩家设置帐户资金', + ['command_setaccountmoney_amount'] = '要设定的金额', + ['command_setcoords'] = '传送到坐标', + ['command_setcoords_x'] = 'x 轴', + ['command_setcoords_y'] = 'y 轴', + ['command_setcoords_z'] = 'z 轴', + ['command_setjob'] = '为玩家设定工作', + ['command_setjob_job'] = '工作名称', + ['command_setjob_grade'] = '工作等级', + ['command_setjob_invalid'] = '工作、等级或两者都无效', + ['command_setgroup'] = '设置玩家用户组', + ['command_setgroup_group'] = '用户组名称', + ['commanderror_argumentmismatch'] = '参数计数不匹配(该类型为%s, 需要传递 %s)', + ['commanderror_argumentmismatch_number'] = '参数 #%s 类型不匹配(该类型为字符串,需要传递数字类型)', + ['commanderror_invaliditem'] = '无效的物品名称', + ['commanderror_invalidweapon'] = '无效武器', + ['commanderror_console'] = '该命令不能从控制台运行', + ['commanderror_invalidcommand'] = '^3%s^0 不是有效的命令!', + ['commanderror_invalidplayerid'] = '没有在线玩家匹配到该服务id', + ['commandgeneric_playerid'] = '玩家id', + + -- Locale settings + ['locale_digit_grouping_symbol'] = ',', + ['locale_currency'] = '$%s', + + -- Weapons + ['weapon_knife'] = '小刀', + ['weapon_nightstick'] = '警棍', + ['weapon_hammer'] = '铁锤', + ['weapon_bat'] = '棒球棍', + ['weapon_golfclub'] = '高尔夫球杆', + ['weapon_crowbar'] = '撬棍', + ['weapon_pistol'] = '手枪', + ['weapon_combatpistol'] = '战斗手枪', + ['weapon_appistol'] = '穿甲手枪', + ['weapon_pistol50'] = '0.5 口径手枪', + ['weapon_microsmg'] = '微型冲锋枪', + ['weapon_smg'] = '冲锋枪', + ['weapon_assaultsmg'] = '突击冲锋枪', + ['weapon_assaultrifle'] = '突击步枪', + ['weapon_carbinerifle'] = '卡宾步枪', + ['weapon_advancedrifle'] = '高级步枪', + ['weapon_mg'] = '机枪', + ['weapon_combatmg'] = '战斗机枪', + ['weapon_pumpshotgun'] = '泵动式霰弹枪', + ['weapon_sawnoffshotgun'] = '短管霰弹枪', + ['weapon_assaultshotgun'] = '突击霰弹枪', + ['weapon_bullpupshotgun'] = '无托式霰弹枪', + ['weapon_stungun'] = '电击枪', + ['weapon_sniperrifle'] = '狙击步枪', + ['weapon_heavysniper'] = '重型狙击步枪', + ['weapon_grenadelauncher'] = '榴弹发射器', + ['weapon_rpg'] = '火箭炮', + ['weapon_minigun'] = '火神机枪', + ['weapon_grenade'] = '手榴弹', + ['weapon_stickybomb'] = '黏弹', + ['weapon_smokegrenade'] = '烟雾弹', + ['weapon_bzgas'] = '催泪瓦斯', + ['weapon_molotov'] = '汽油弹', + ['weapon_fireextinguisher'] = '灭火器', + ['weapon_petrolcan'] = '汽油桶', + ['weapon_ball'] = '棒球', + ['weapon_snspistol'] = '劣质手枪', + ['weapon_bottle'] = '酒瓶', + ['weapon_gusenberg'] = '古森柏冲锋枪', + ['weapon_specialcarbine'] = '特制卡宾枪', + ['weapon_heavypistol'] = '重型手枪', + ['weapon_bullpuprifle'] = '无托式步枪', + ['weapon_dagger'] = '匕首', + ['weapon_vintagepistol'] = '老式手枪', + ['weapon_firework'] = '烟花发射器', + ['weapon_musket'] = '老式火枪', + ['weapon_heavyshotgun'] = '重型霰弹枪', + ['weapon_marksmanrifle'] = '射手步枪', + ['weapon_hominglauncher'] = '制导火箭发射器', + ['weapon_proxmine'] = '感应地雷', + ['weapon_snowball'] = '雪球', + ['weapon_flaregun'] = '信号枪', + ['weapon_combatpdw'] = '作战自卫冲锋枪', + ['weapon_marksmanpistol'] = '射手手枪', + ['weapon_knuckle'] = '手指虎', + ['weapon_hatchet'] = '手斧', + ['weapon_railgun'] = '电磁轨道炮', + ['weapon_machete'] = '开山刀', + ['weapon_machinepistol'] = '冲锋手枪', + ['weapon_switchblade'] = '弹簧刀', + ['weapon_revolver'] = '重型左轮手枪', + ['weapon_dbshotgun'] = '双管霰弹枪', + ['weapon_compactrifle'] = '紧凑型步枪', + ['weapon_autoshotgun'] = '半自动霰弹枪', + ['weapon_battleaxe'] = '战斧', + ['weapon_compactlauncher'] = '紧凑型榴弹发射器', + ['weapon_minismg'] = '迷你冲锋枪', + ['weapon_pipebomb'] = '土制炸弹', + ['weapon_poolcue'] = '台球杆', + ['weapon_wrench'] = '管钳扳手', + ['weapon_flashlight'] = '手电筒', + ['gadget_parachute'] = '降落伞', + ['weapon_flare'] = '信号棒', + ['weapon_doubleaction'] = '双动式左轮手枪', + + -- Weapon Components + ['component_clip_default'] = '默认弹夹', + ['component_clip_extended'] = '扩容弹夹', + ['component_clip_drum'] = '鼓式弹夹', + ['component_clip_box'] = '盒型弹匣', + ['component_flashlight'] = '手电筒', + ['component_scope'] = '瞄准镜', + ['component_scope_advanced'] = '高级瞄准镜', + ['component_suppressor'] = '消音器', + ['component_grip'] = '握把', + ['component_luxary_finish'] = '奢华涂饰', + + -- Weapon Ammo + ['ammo_rounds'] = '发(子弹)', + ['ammo_shells'] = '发(子弹)', + ['ammo_charge'] = '喷', + ['ammo_petrol'] = '加仑(燃料)', + ['ammo_firework'] = '发(烟花弹)', + ['ammo_rockets'] = '枚(火箭弹)', + ['ammo_grenadelauncher'] = '发(榴弹)', + ['ammo_grenade'] = '枚(手榴弹)', + ['ammo_stickybomb'] = '枚(炸弹)', + ['ammo_pipebomb'] = '枚(炸弹)', + ['ammo_smokebomb'] = '枚(炸弹)', + ['ammo_molotov'] = '瓶(汽油瓶)', + ['ammo_proxmine'] = '个(地雷)', + ['ammo_bzgas'] = '罐', + ['ammo_ball'] = '个(球)', + ['ammo_snowball'] = '个(雪球)', + ['ammo_flare'] = '根(信号棒)', + ['ammo_flaregun'] = '发(信号弹)', + + -- Weapon Tints + ['tint_default'] = '默认色调', + ['tint_green'] = '绿色调', + ['tint_gold'] = '金色调', + ['tint_pink'] = '粉色调', + ['tint_army'] = '军用色调', + ['tint_lspd'] = '洛圣都警局色调', + ['tint_orange'] = '橙色调', + ['tint_platinum'] = '铂金色调', +} diff --git a/locales/tc.lua b/locales/tc.lua new file mode 100644 index 00000000..c0b1e31c --- /dev/null +++ b/locales/tc.lua @@ -0,0 +1,225 @@ +Locales['tc'] = { + -- Inventory + ['inventory'] = '背包 %s / %s', + ['use'] = '使用', + ['give'] = '給', + ['remove'] = '丟棄', + ['return'] = '返回', + ['give_to'] = '給予', + ['amount'] = '數量', + ['giveammo'] = '給予子彈', + ['amountammo'] = '子彈量', + ['noammo'] = '您沒有足夠的子彈!', + ['gave_item'] = '您把~y~%sx~s~~b~%s~s~給予了~y~%s~s~', + ['received_item'] = '您收到~y~%sx~s~~b~%s~s~,來自~b~%s~s~', + ['gave_weapon'] = '您把~b~%s~s~給予了~y~%s~s~', + ['gave_weapon_ammo'] = '您把~o~%sx~s~~b~%s~s~ %s~s~給予了~y~%s~s~', + ['gave_weapon_withammo'] = '您把~b~%s~s~和~o~%sx~s~ %s~s~給予了~y~%s~s~', + ['gave_weapon_hasalready'] = '~y~%s~s~已經有~y~%s~s~', + ['gave_weapon_noweapon'] = '~y~%s~s~沒有那把武器', + ['received_weapon'] = '您收到了~b~%s~s~,來自~b~%s~s~', + ['received_weapon_ammo'] = '您收到了~o~%sx~s~ %s~s~(~b~%s~s~),來自~b~%s~s~', + ['received_weapon_withammo'] = '您收到了~b~%s~s~和~o~%sx~s~ %s~s~,來自~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~嘗試给您~y~%s~s~,但您已经有了', + ['received_weapon_noweapon'] = '~b~%s~s~嘗試给您~y~%s~s~子彈,但是您沒有那把武器', + ['gave_account_money'] = '您將 ~g~$%s~s~ (%s) 给予 ~y~%s~s~', + ['received_account_money'] = '您收到了~g~$%s~s~ (%s) 来自 ~b~%s~s~', + ['amount_invalid'] = '無效的數量', + ['players_nearby'] = '附近沒有玩家', + ['ex_inv_lim'] = '操作失敗, 超過~y~%s~s~物品欄位的限制', + ['imp_invalid_quantity'] = '操作失敗,無效的數量', + ['imp_invalid_amount'] = '操作失敗,無效的金額', + ['threw_standard'] = '您丟棄了~y~%sx~s~~b~%s~s~', + ['threw_account'] = '您丟棄了~g~$%s~s~~b~%s~s~', + ['threw_weapon'] = '您丟棄了~b~%s~s~', + ['threw_weapon_ammo'] = '您丟棄了~b~%s~s~和~o~%sx%s~s~', + ['threw_weapon_already'] = '您已經有相同的武器了', + ['threw_cannot_pickup'] = '您不能再撿起該物品,因為您的背包已經滿了', + ['threw_pickup_prompt'] = '按下 ~y~E~s~ 撿起', + + -- Key mapping + ['keymap_showinventory'] = '顯示背包', + + -- Salary related + ['received_salary'] = '您收到您的薪水: ~g~$%s~s~', + ['received_help'] = '由於您表現良好,系統給予您一些獎勵: ~g~$%s~s~', + ['company_nomoney'] = '您的公司太窮了,無法給予您薪水。', + ['received_paycheck'] = '收到轉帳', + ['bank'] = '花園銀行', + ['account_bank'] = '銀行', + ['account_black_money'] = '黑錢', + ['account_money'] = '現金', + + ['act_imp'] = '操作失敗', + ['in_vehicle'] = '請離開載具', + + -- Commands + ['command_car'] = '生成載具', + ['command_car_car'] = '生成載具的模型名稱或希哈值', + ['command_cardel'] = '刪除附近的載具', + ['command_cardel_radius'] = '可選擇,刪除指定半徑內的所有車輛', + ['command_clear'] = '清除聊天紀錄', + ['command_clearall'] = '清除所有玩家的聊天紀錄', + ['command_clearinventory'] = '清除玩家背包', + ['command_clearloadout'] = '清除玩家人物造型', + ['command_giveaccountmoney'] = '給予帳戶錢', + ['command_giveaccountmoney_account'] = '有效的帳戶名稱', + ['command_giveaccountmoney_amount'] = '添加的數量', + ['command_giveaccountmoney_invalid'] = '無效的帳戶名稱', + ['command_giveitem'] = '給玩家一個物品', + ['command_giveitem_item'] = '物品名稱', + ['command_giveitem_count'] = '物品數量', + ['command_giveweapon'] = '给玩家一把武器', + ['command_giveweapon_weapon'] = '武器名稱', + ['command_giveweapon_ammo'] = '子彈數量', + ['command_giveweapon_hasalready'] = '該玩家已經擁有了該武器', + ['command_giveweaponcomponent'] = '給予武器配件', + ['command_giveweaponcomponent_component'] = '配件名稱', + ['command_giveweaponcomponent_invalid'] = '無效的武器配件', + ['command_giveweaponcomponent_hasalready'] = '該玩家已經擁有了武器配件', + ['command_giveweaponcomponent_missingweapon'] = '該玩家沒有那把武器', + ['command_save'] = '保存玩家數據至資料庫', + ['command_saveall'] = '保存所有玩家數據至資料庫', + ['command_setaccountmoney'] = '為玩家設置賬戶資金', + ['command_setaccountmoney_amount'] = '要設置的金額', + ['command_setcoords'] = '傳送到座標上', + ['command_setcoords_x'] = 'x 軸', + ['command_setcoords_y'] = 'y 軸', + ['command_setcoords_z'] = 'z 軸', + ['command_setjob'] = '設定該玩家職業', + ['command_setjob_job'] = '職業名稱', + ['command_setjob_grade'] = '職業階級', + ['command_setjob_invalid'] = '職業、階級或者兩者都無效', + ['command_setgroup'] = '設定玩家群組階級', + ['command_setgroup_group'] = '玩家群組階級名稱', + ['commanderror_argumentmismatch'] = '參數數量不正確(該類型為%s, 需要給予 %s)', + ['commanderror_argumentmismatch_number'] = '參數 #%s 類型不匹配(該類型為字串,需要給予的數字類型)', + ['commanderror_invaliditem'] = '無效的物品名稱', + ['commanderror_invalidweapon'] = '無效武器', + ['commanderror_console'] = '該指令不能從控制台執行', + ['commanderror_invalidcommand'] = '^3%s^0 不是有效的指令!', + ['commanderror_invalidplayerid'] = '無效的玩家ID', + ['commandgeneric_playerid'] = '玩家id', + + -- Locale settings + ['locale_digit_grouping_symbol'] = ',', + ['locale_currency'] = '$%s', + + -- Weapons + ['weapon_knife'] = '刀', + ['weapon_nightstick'] = '警棍', + ['weapon_hammer'] = '錘子', + ['weapon_bat'] = '棒球棍', + ['weapon_golfclub'] = '高爾夫球棍', + ['weapon_crowbar'] = '撬棍', + ['weapon_pistol'] = '手槍', + ['weapon_combatpistol'] = '戰鬥手槍', + ['weapon_appistol'] = '穿甲手槍', + ['weapon_pistol50'] = '.50口徑手槍', + ['weapon_microsmg'] = '迷你衝鋒槍', + ['weapon_smg'] = '衝鋒槍', + ['weapon_assaultsmg'] = '突擊衝鋒槍', + ['weapon_assaultrifle'] = '突擊步槍', + ['weapon_carbinerifle'] = '卡賓槍步槍', + ['weapon_advancedrifle'] = '精準步槍', + ['weapon_mg'] = '機槍', + ['weapon_combatmg'] = '戰鬥機槍', + ['weapon_pumpshotgun'] = '霰彈槍', + ['weapon_sawnoffshotgun'] = '削短型霰彈槍', + ['weapon_assaultshotgun'] = '突擊霰彈槍', + ['weapon_bullpupshotgun'] = '泵動式霰彈槍', + ['weapon_stungun'] = '電擊槍', + ['weapon_sniperrifle'] = '狙擊步槍', + ['weapon_heavysniper'] = '重型狙擊槍', + ['weapon_grenadelauncher'] = '榴彈砲', + ['weapon_rpg'] = '火箭炮', + ['weapon_minigun'] = '火神機槍', + ['weapon_grenade'] = '手榴彈', + ['weapon_stickybomb'] = '黏彈', + ['weapon_smokegrenade'] = '煙霧彈', + ['weapon_bzgas'] = '催淚瓦斯', + ['weapon_molotov'] = '汽油彈', + ['weapon_fireextinguisher'] = '滅火器', + ['weapon_petrolcan'] = '汽油桶', + ['weapon_ball'] = '棒球', + ['weapon_snspistol'] = '劣質手槍', + ['weapon_bottle'] = '酒瓶', + ['weapon_gusenberg'] = '古森柏衝鋒槍', + ['weapon_specialcarbine'] = '特製卡賓槍', + ['weapon_heavypistol'] = '重型手槍', + ['weapon_bullpuprifle'] = 'AUG突擊步槍', + ['weapon_dagger'] = '匕首', + ['weapon_vintagepistol'] = '老式手槍', + ['weapon_firework'] = '煙火發射器', + ['weapon_musket'] = '老式火槍', + ['weapon_heavyshotgun'] = '重型霰彈槍', + ['weapon_marksmanrifle'] = '精確射手步槍', + ['weapon_hominglauncher'] = '火箭彈發射器', + ['weapon_proxmine'] = '感應地雷', + ['weapon_snowball'] = '雪球', + ['weapon_flaregun'] = '信號槍', + ['weapon_combatpdw'] = '戰鬥自衛衝鋒槍', + ['weapon_marksmanpistol'] = '神射手槍', + ['weapon_knuckle'] = '指虎', + ['weapon_hatchet'] = '斧頭', + ['weapon_railgun'] = '電磁軌彈炮', + ['weapon_machete'] = '開山刀', + ['weapon_machinepistol'] = '衝鋒手槍', + ['weapon_switchblade'] = '蝴蝶刀', + ['weapon_revolver'] = '重左輪手槍', + ['weapon_dbshotgun'] = '雙槍霰彈槍', + ['weapon_compactrifle'] = '半自動步槍', + ['weapon_autoshotgun'] = '半自動霰彈槍', + ['weapon_battleaxe'] = '戰斧', + ['weapon_compactlauncher'] = '精簡榴彈發射器', + ['weapon_minismg'] = '迷你衝鋒槍', + ['weapon_pipebomb'] = '土製炸彈', + ['weapon_poolcue'] = '桌球桿', + ['weapon_wrench'] = '扳手', + ['weapon_flashlight'] = '手電筒', + ['gadget_parachute'] = '降落傘', + ['weapon_flare'] = '信號棒', + ['weapon_doubleaction'] = '左輪手槍', + + -- Weapon Components + ['component_clip_default'] = '默認彈夾', + ['component_clip_extended'] = '延伸彈夾', + ['component_clip_drum'] = '彈鼓式彈匣', + ['component_clip_box'] = '盒式彈匣', + ['component_flashlight'] = '手電筒', + ['component_scope'] = '瞄準鏡', + ['component_scope_advanced'] = '高級瞄準鏡', + ['component_suppressor'] = '消音管', + ['component_grip'] = '握把', + ['component_luxary_finish'] = '豪華塗裝', + + -- Weapon Ammo + ['ammo_rounds'] = '發(子彈)', + ['ammo_shells'] = '發(子彈)', + ['ammo_charge'] = '噴', + ['ammo_petrol'] = '加崙(燃料)', + ['ammo_firework'] = '發(煙火子彈)', + ['ammo_rockets'] = '枚(火箭彈)', + ['ammo_grenadelauncher'] = '發(榴彈)', + ['ammo_grenade'] = '枚(手榴彈)', + ['ammo_stickybomb'] = '枚(炸彈)', + ['ammo_pipebomb'] = '枚(炸彈)', + ['ammo_smokebomb'] = '枚(炸彈)', + ['ammo_molotov'] = '瓶(汽油瓶)', + ['ammo_proxmine'] = '個(地雷)', + ['ammo_bzgas'] = '罐', + ['ammo_ball'] = '顆(球)', + ['ammo_snowball'] = '顆(雪球)', + ['ammo_flare'] = '根(信號棒)', + ['ammo_flaregun'] = '發(信號彈)', + + -- Weapon Tints + ['tint_default'] = '默認色調', + ['tint_green'] = '綠色調', + ['tint_gold'] = '金色調', + ['tint_pink'] = '粉色調', + ['tint_army'] = '軍用色調', + ['tint_lspd'] = '洛聖都警察局色調', + ['tint_orange'] = '橘色調', + ['tint_platinum'] = '柏金色調', +} From 6c70abd5e8393b6f58180ad22a8d3cc94247d4ef Mon Sep 17 00:00:00 2001 From: RoJea32 <57993332+RoJea32@users.noreply.github.com> Date: Tue, 31 Mar 2020 12:24:30 +0300 Subject: [PATCH 2643/3224] Fix "attempt to index a nil value field ('?')" (#612) * Update main.lua * Update main.lua --- client/main.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index a5f24ce2..65527b1f 100644 --- a/client/main.lua +++ b/client/main.lua @@ -356,8 +356,10 @@ end) RegisterNetEvent('esx:removePickup') AddEventHandler('esx:removePickup', function(id) - ESX.Game.DeleteObject(pickups[id].obj) - pickups[id] = nil + if pickups[id] and pickups[id].obj then + ESX.Game.DeleteObject(pickups[id].obj) + pickups[id] = nil + end end) RegisterNetEvent('esx:deleteVehicle') From 2855a340384b4c888368847f5f2c4b837dd2a70d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 31 Mar 2020 12:28:57 +0200 Subject: [PATCH 2644/3224] Fixed paying rent with latest ESX accounts, added automatic removal if cannot afford --- locales/br.lua | 3 ++- locales/cs.lua | 3 ++- locales/en.lua | 3 ++- locales/fi.lua | 3 ++- locales/fr.lua | 3 ++- locales/pl.lua | 3 ++- locales/sv.lua | 3 ++- server/main.lua | 50 ++++++++++++++++++++++++++++++++++++++----------- 8 files changed, 53 insertions(+), 18 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index 442ea74c..ba95cdfb 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -24,7 +24,8 @@ Locales['br'] = { ['not_enough_money'] = 'você não tem dinheiro suficiente', ['not_rental'] = 'isso não é um ~r~veículo de aluguel~s~', ['not_yours'] = 'este veículo não pertence a você', - ['paid_rental'] = 'Você tem ~g~pago~s~ para o seu aluguel de veiculos: ~g~$%s~s~', + ['paid_rental'] = 'you have paid ~g~$%s~s~ for renting an vehicle with plate ~y~%s~s~', + ['paid_rental_evicted'] = 'you could not afford to pay ~g~$%s~s~ for your rented vehicle with plate ~y~%s~s~, it has been returned to the dealership', ['pop_vehicle'] = 'sai do veiculo', ['rent_vehicle'] = 'Concessionária - Veículos para alugar', ['return_provider_menu'] = 'revendedor de carros - Devolver veículo ao fornecedor', diff --git a/locales/cs.lua b/locales/cs.lua index 9725ab8a..59e4ff1d 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -24,7 +24,8 @@ Locales['cs'] = { ['not_enough_money'] = 'nemáš dostatek peněz', ['not_rental'] = 'tohle není ~r~půjčitelné vozidlo~s~', ['not_yours'] = 'tohle auto ti nepatří', - ['paid_rental'] = '~g~zaplatil jsii~s~ za pujceni auta: ~g~$%s~s~', + ['paid_rental'] = 'you have paid ~g~$%s~s~ for renting an vehicle with plate ~y~%s~s~', + ['paid_rental_evicted'] = 'you could not afford to pay ~g~$%s~s~ for your rented vehicle with plate ~y~%s~s~, it has been returned to the dealership', ['pop_vehicle'] = 'vlozit vozidlo k prodeji', ['rent_vehicle'] = 'autosalon - Vozidla k pujceni', ['return_provider_menu'] = 'autosalon - Vratit vozidlo zprostredkovateli', diff --git a/locales/en.lua b/locales/en.lua index 40c7a1d2..17e7c3a6 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -24,7 +24,8 @@ Locales['en'] = { ['not_enough_money'] = 'you do not have enough money', ['not_rental'] = 'this is not a ~r~rental vehicle~s~', ['not_yours'] = 'this vehicle does not belong to you', - ['paid_rental'] = 'you have ~g~payed~s~ for your vehicle rental: ~g~$%s~s~', + ['paid_rental'] = 'you have paid ~g~$%s~s~ for renting an vehicle with plate ~y~%s~s~', + ['paid_rental_evicted'] = 'you could not afford to pay ~g~$%s~s~ for your rented vehicle with plate ~y~%s~s~, it has been returned to the dealership', ['pop_vehicle'] = 'put out vehicle for sale', ['rent_vehicle'] = 'car Dealer - Vehicles for rent', ['return_provider_menu'] = 'car Dealer - Return vehicle to provider', diff --git a/locales/fi.lua b/locales/fi.lua index 03f2804a..69e7bc39 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -24,7 +24,8 @@ Locales['fi'] = { ['not_enough_money'] = 'sinulla ei ole tarpeeksi rahaa', ['not_rental'] = 'tämä ei ole ~r~vuokra ajoneuvo~s~', ['not_yours'] = 'tämä ajoneuvo ei kuulu sinulle', - ['paid_rental'] = 'sinä ~g~maksoit~s~ ajoneuvon vuokraamisesta: ~g~$%s~s~', + ['paid_rental'] = 'you have paid ~g~$%s~s~ for renting an vehicle with plate ~y~%s~s~', + ['paid_rental_evicted'] = 'you could not afford to pay ~g~$%s~s~ for your rented vehicle with plate ~y~%s~s~, it has been returned to the dealership', ['pop_vehicle'] = 'ota ajoneuvo ulos näkyville myyntiä varten', ['rent_vehicle'] = 'autokauppa - Vuokrattavat ajokit', ['return_provider_menu'] = 'car Dealer - Return vehicle to provider', diff --git a/locales/fr.lua b/locales/fr.lua index 471d8dc3..6b719c91 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -24,7 +24,8 @@ Locales['fr'] = { ['not_enough_money'] = 'vous n\'avez pas assez d\'argent', ['not_rental'] = 'ce n\'est pas un ~r~véhicule de location~s~', ['not_yours'] = 'ce véhicule ne vous appartient pas', - ['paid_rental'] = 'vous avez ~g~payé~s~ votre location de véhicule: ~g~$%s~s~', + ['paid_rental'] = 'you have paid ~g~$%s~s~ for renting an vehicle with plate ~y~%s~s~', + ['paid_rental_evicted'] = 'you could not afford to pay ~g~$%s~s~ for your rented vehicle with plate ~y~%s~s~, it has been returned to the dealership', ['pop_vehicle'] = 'sortir véhicule', ['rent_vehicle'] = 'concessionnaire - Véhicules en location', ['return_provider_menu'] = 'concessionnaire - Retour de véhicule', diff --git a/locales/pl.lua b/locales/pl.lua index d2eef57a..42dfcec2 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -24,7 +24,8 @@ Locales['pl'] = { ['not_enough_money'] = 'nie masz wystarczająco pieniędzy', ['not_rental'] = 'to nie jest ~r~wypożyczone auto~s~', ['not_yours'] = 'ten pojazd nie należy do ciebie', - ['paid_rental'] = '~g~Płacisz~s~ za wynajęcie auta: ~g~$%s~s~', + ['paid_rental'] = 'you have paid ~g~$%s~s~ for renting an vehicle with plate ~y~%s~s~', + ['paid_rental_evicted'] = 'you could not afford to pay ~g~$%s~s~ for your rented vehicle with plate ~y~%s~s~, it has been returned to the dealership', ['pop_vehicle'] = 'wyciągnij auto do sprzedaży', ['rent_vehicle'] = 'salon samochodowy - Pojazdy do wynajęcia', ['return_provider_menu'] = 'car Dealer - Return vehicle to provider', diff --git a/locales/sv.lua b/locales/sv.lua index 0ab74f45..6290d767 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -24,7 +24,8 @@ Locales['sv'] = { ['not_enough_money'] = 'du har inte tillräckligt mycket pengar', ['not_rental'] = 'detta är inte ett ~r~uthyrt fordon~s~', ['not_yours'] = 'det här fordonet tillhör inte dig', - ['paid_rental'] = 'du har ~y~betalat~s~ ditt hyrda fordon: ~g~%s SEK~s~', + ['paid_rental'] = 'du har betalat ~g~%s SEK~s~ för att hyra ett fordon med reg nummer ~y~%s~s~', + ['paid_rental_evicted'] = 'du hade ej råd att betala ~g~%s SEK~s~ för ditt hyrda fordon med reg nummer ~y~%s~s~, den har tagits av bilförsäljaren', ['pop_vehicle'] = 'ställ ut fordon till salu', ['rent_vehicle'] = 'bilförsäljare - fordon för uthyrning', ['return_provider_menu'] = 'bilförsäljare - sälj tillbaka fordon till leverantör', diff --git a/server/main.lua b/server/main.lua index 014d19b8..4e78c72c 100644 --- a/server/main.lua +++ b/server/main.lua @@ -419,23 +419,51 @@ AddEventHandler('esx_vehicleshop:setJobVehicleState', function(plate, state) 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() print('[esx_vehicleshop] [^2INFO^7] Paying rent cron job started') - MySQL.Async.fetchAll('SELECT owner, rent_price FROM rented_vehicles', {}, function(result) - for i=1, #result, 1 do + 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(result[i].owner) + local xPlayer = ESX.GetPlayerFromIdentifier(v.owner) - if xPlayer then -- message player if connected - xPlayer.removeAccountMoney('bank', result[i].rent_price) - xPlayer.showNotification(_U('paid_rental', ESX.Math.GroupDigits(result[i].rent_price))) - else -- pay rent by updating SQL - MySQL.Sync.execute('UPDATE users SET bank = bank - @bank WHERE identifier = @identifier', { - ['@bank'] = result[i].rent_price, - ['@identifier'] = result[i].owner - }) + 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 + 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 + end + end) end TriggerEvent('esx_addonaccount:getSharedAccount', 'society_cardealer', function(account) From 544e0e0dc3b54d7a8bb131215effb86f8f605da4 Mon Sep 17 00:00:00 2001 From: Minikeysi <43723896+Minikeys@users.noreply.github.com> Date: Thu, 2 Apr 2020 20:24:53 +0200 Subject: [PATCH 2645/3224] Update fr.lua Better translate for FR. --- locales/fr.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index 028ba663..0693361f 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,8 +1,8 @@ Locales['fr'] = { - ['whitelist_check'] = 'making sure you\'re whitelisted on this server . . .', - ['not_whitelisted'] = 'ceci est un serveur avec whitelist', - ['whitelist_empty'] = 'the whitelist hasn\'t been loaded yet, or alternatively no one has been whitelisted!', - ['license_missing'] = 'your license could not be found', - ['help_whitelist_add'] = 'ajouter quelqu\'un dans la Whitelist', - ['help_whitelist_load'] = 'recharger la Whitelist', + ['whitelist_check'] = 'Etes vous sûr d\'être whitelisté sur ce serveur ...', + ['not_whitelisted'] = 'Ce serveur utilise une whitelist', + ['whitelist_empty'] = 'La whitelist n\'a pas été rechargé ou vous n\'avez pas été whitelisté', + ['license_missing'] = 'Votre license est introuvable', + ['help_whitelist_add'] = 'Ajouter un joueur à la Whitelist', + ['help_whitelist_load'] = 'Recharger la Whitelist', } From f4558c85e3e313b7cefba351c1e459418fe38718 Mon Sep 17 00:00:00 2001 From: Vegard Bendiktsen Date: Fri, 3 Apr 2020 09:20:58 +0200 Subject: [PATCH 2646/3224] Support table/list of groups when registering commands (#616) * Support table/list of groups when registering commands * Adhere to "unwritten code standard" --- server/functions.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/server/functions.lua b/server/functions.lua index 74e2efcc..601f27f0 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -138,7 +138,13 @@ ESX.RegisterCommand = function(name, group, cb, allowConsole, suggestion) end end, true) - ExecuteCommand(('add_ace group.%s command.%s allow'):format(group, name)) + if type(group) == 'table' then + for k,v in ipairs(group) do + ExecuteCommand(('add_ace group.%s command.%s allow'):format(v, name)) + end + else + ExecuteCommand(('add_ace group.%s command.%s allow'):format(group, name)) + end end ESX.ClearTimeout = function(id) From 1f61585917ae400151b84b79fcbbc4e1ff1c8663 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs?= <52821987+YisusTM01@users.noreply.github.com> Date: Sat, 4 Apr 2020 19:03:34 +0200 Subject: [PATCH 2647/3224] Fixed collisions of pickups items and weapons Fixed character and car collisions with objects lying on the ground (also weapons and the bat itself). --- client/main.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/main.lua b/client/main.lua index 65527b1f..c41aa5b4 100644 --- a/client/main.lua +++ b/client/main.lua @@ -297,6 +297,7 @@ AddEventHandler('esx:createPickup', function(pickupId, label, playerId, type, na SetEntityAsMissionEntity(pickupObject, true, false) PlaceObjectOnGroundProperly(pickupObject) FreezeEntityPosition(pickupObject, true) + SetEntityCollision(pickupObject, false, true) pickups[pickupId] = { id = pickupId, @@ -334,6 +335,7 @@ AddEventHandler('esx:createMissingPickups', function(missingPickups) SetEntityAsMissionEntity(pickupObject, true, false) PlaceObjectOnGroundProperly(pickupObject) FreezeEntityPosition(pickupObject, true) + SetEntityCollision(pickupObject, false, true) pickups[pickupId] = { id = pickupId, From 2c2978feaa9674862e8ac3d61281abc890520a76 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 6 Apr 2020 12:09:06 +0200 Subject: [PATCH 2648/3224] Replaced coords sync interval with sync every second Because xPlayer.getCoords() has uses it cant be out of sync code --- client/main.lua | 27 +++++++++++++++------------ config.lua | 1 - 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/client/main.lua b/client/main.lua index c41aa5b4..4c91cf7f 100644 --- a/client/main.lua +++ b/client/main.lua @@ -522,24 +522,27 @@ end) -- Update current player coords Citizen.CreateThread(function() - local previousCoords = vector3(0, 0, 0) - -- wait for player to restore coords while not isLoadoutLoaded do Citizen.Wait(1000) end - while true do - Citizen.Wait(Config.CoordsSyncInterval) - local playerPed = PlayerPedId() - local playerCoords = GetEntityCoords(playerPed) - local distance = #(playerCoords - previousCoords) + local previousCoords = vector3(ESX.PlayerData.coords.x, ESX.PlayerData.coords.y, ESX.PlayerData.coords.z) - if distance > 10 then - previousCoords = playerCoords - local playerHeading = ESX.Math.Round(GetEntityHeading(playerPed), 1) - local formattedCoords = {x = ESX.Math.Round(playerCoords.x, 1), y = ESX.Math.Round(playerCoords.y, 1), z = ESX.Math.Round(playerCoords.z, 1), heading = playerHeading} - TriggerServerEvent('esx:updateCoords', formattedCoords) + while true do + Citizen.Wait(1000) + local playerPed = PlayerPedId() + + if DoesEntityExist(playerPed) then + local playerCoords = GetEntityCoords(playerPed) + local distance = #(playerCoords - previousCoords) + + if distance > 1 then + previousCoords = playerCoords + local playerHeading = ESX.Math.Round(GetEntityHeading(playerPed), 1) + local formattedCoords = {x = ESX.Math.Round(playerCoords.x, 1), y = ESX.Math.Round(playerCoords.y, 1), z = ESX.Math.Round(playerCoords.z, 1), heading = playerHeading} + TriggerServerEvent('esx:updateCoords', formattedCoords) + end end end end) diff --git a/config.lua b/config.lua index a6f10be3..fc28850e 100644 --- a/config.lua +++ b/config.lua @@ -16,6 +16,5 @@ Config.EnablePvP = true -- enable pvp? Config.MaxWeight = 24 -- the max inventory weight without backpack Config.PaycheckInterval = 7 * 60000 -- how often to recieve pay checks in milliseconds -Config.CoordsSyncInterval = 2 * 60000 -- how often to sync coords with server in milliseconds Config.EnableDebug = false From 492f41ca45b301a5388dc317fe0bbca15885b82f Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 6 Apr 2020 13:19:34 +0200 Subject: [PATCH 2649/3224] Don't spam request asset natives --- client/functions.lua | 3 --- 1 file changed, 3 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index ce849263..8d2ea626 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -306,7 +306,6 @@ ESX.Game.Teleport = function(entity, coords, cb) RequestCollisionAtCoord(coords.x, coords.y, coords.z) while not HasCollisionLoadedAroundEntity(entity) do - RequestCollisionAtCoord(coords.x, coords.y, coords.z) Citizen.Wait(0) end @@ -378,7 +377,6 @@ ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) RequestCollisionAtCoord(coords.x, coords.y, coords.z) while not HasCollisionLoadedAroundEntity(vehicle) do - RequestCollisionAtCoord(coords.x, coords.y, coords.z) Citizen.Wait(0) end @@ -405,7 +403,6 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) RequestCollisionAtCoord(coords.x, coords.y, coords.z) while not HasCollisionLoadedAroundEntity(vehicle) do - RequestCollisionAtCoord(coords.x, coords.y, coords.z) Citizen.Wait(0) end From c67e4b96c1eea94a2502e9d462605faa8289ccb9 Mon Sep 17 00:00:00 2001 From: ArkSeyonet <31637812+ArkSeyonet@users.noreply.github.com> Date: Mon, 6 Apr 2020 08:38:00 -0500 Subject: [PATCH 2650/3224] Update ESX Identity --- README.md | 8 - client/main.lua | 167 -------------------- config.lua | 11 +- esx_identity.sql | 10 +- fxmanifest.lua | 18 +-- html/cs_index.html | 22 --- html/fi_index.html | 22 --- html/index.html | 22 --- html/ko_index.html | 22 --- html/script.js | 33 ---- html/style.css | 46 ------ html/sv_index.html | 22 --- locales/cs.lua | 12 +- locales/en.lua | 12 +- server/main.lua | 373 +++++++++++++++++++++++++-------------------- 15 files changed, 225 insertions(+), 575 deletions(-) delete mode 100644 client/main.lua delete mode 100644 html/cs_index.html delete mode 100644 html/fi_index.html delete mode 100644 html/index.html delete mode 100644 html/ko_index.html delete mode 100644 html/script.js delete mode 100644 html/style.css delete mode 100644 html/sv_index.html diff --git a/README.md b/README.md index c2edec3f..cec80b0c 100644 --- a/README.md +++ b/README.md @@ -34,14 +34,6 @@ start esx_identity - If you are using esx_policejob or esx_society, you need to enable the following in the scripts' `config.lua`: ```Config.EnableESXIdentity = true``` -### Commands -``` -/register -/charlist -/charselect -/chardel -``` - # Legal ### License esx_identity - rp characters diff --git a/client/main.lua b/client/main.lua deleted file mode 100644 index 45d474e8..00000000 --- a/client/main.lua +++ /dev/null @@ -1,167 +0,0 @@ -local guiEnabled, hasIdentity, isDead = false, false, false -local myIdentity, myIdentifiers = {}, {} - -ESX = nil - -Citizen.CreateThread(function() - while ESX == nil do - TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) - Citizen.Wait(0) - end -end) - -AddEventHandler('esx:onPlayerDeath', function(data) - isDead = true -end) - -AddEventHandler('playerSpawned', function(spawn) - isDead = false -end) - -function EnableGui(state) - SetNuiFocus(state, state) - guiEnabled = state - - SendNUIMessage({ - type = "enableui", - enable = state - }) -end - -RegisterNetEvent('esx_identity:showRegisterIdentity') -AddEventHandler('esx_identity:showRegisterIdentity', function() - if not isDead then - EnableGui(true) - end -end) - -RegisterNetEvent('esx_identity:identityCheck') -AddEventHandler('esx_identity:identityCheck', function(identityCheck) - hasIdentity = identityCheck -end) - -RegisterNetEvent('esx_identity:saveID') -AddEventHandler('esx_identity:saveID', function(data) - myIdentifiers = data -end) - -RegisterNUICallback('escape', function(data, cb) - if hasIdentity then - EnableGui(false) - else - ESX.ShowNotification(_U('create_a_character')) - end -end) - -RegisterNUICallback('register', function(data, cb) - local reason = "" - myIdentity = data - for theData, value in pairs(myIdentity) do - if theData == "firstname" or theData == "lastname" then - reason = verifyName(value) - - if reason ~= "" then - break - end - elseif theData == "dateofbirth" then - if value == "invalid" then - reason = "Invalid date of birth!" - break - end - elseif theData == "height" then - local height = tonumber(value) - if height then - if height > 200 or height < 140 then - reason = "Unacceptable player height!" - break - end - else - reason = "Unacceptable player height!" - break - end - end - end - - if reason == "" then - TriggerServerEvent('esx_identity:setIdentity', data, myIdentifiers) - EnableGui(false) - Citizen.Wait(500) - TriggerEvent('esx_skin:openSaveableMenu', myIdentifiers.id) - else - ESX.ShowNotification(reason) - end -end) - -Citizen.CreateThread(function() - while true do - Citizen.Wait(0) - - if guiEnabled then - DisableControlAction(0, 1, true) -- LookLeftRight - DisableControlAction(0, 2, true) -- LookUpDown - DisableControlAction(0, 106, true) -- VehicleMouseControlOverride - DisableControlAction(0, 142, true) -- MeleeAttackAlternate - DisableControlAction(0, 30, true) -- MoveLeftRight - DisableControlAction(0, 31, true) -- MoveUpDown - DisableControlAction(0, 21, true) -- disable sprint - DisableControlAction(0, 24, true) -- disable attack - DisableControlAction(0, 25, true) -- disable aim - DisableControlAction(0, 47, true) -- disable weapon - DisableControlAction(0, 58, true) -- disable weapon - DisableControlAction(0, 263, true) -- disable melee - DisableControlAction(0, 264, true) -- disable melee - DisableControlAction(0, 257, true) -- disable melee - DisableControlAction(0, 140, true) -- disable melee - DisableControlAction(0, 141, true) -- disable melee - DisableControlAction(0, 143, true) -- disable melee - DisableControlAction(0, 75, true) -- disable exit vehicle - DisableControlAction(27, 75, true) -- disable exit vehicle - else - Citizen.Wait(500) - end - end -end) - -function verifyName(name) - -- Don't allow short user names - local nameLength = string.len(name) - if nameLength > 25 or nameLength < 2 then - return 'Your player name is either too short or too long.' - end - - -- Don't allow special characters (doesn't always work) - local count = 0 - for i in name:gmatch('[abcdefghijklmnopqrstuvwxyzåäöABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ0123456789 -]') do - count = count + 1 - end - if count ~= nameLength then - return 'Your player name contains special characters that are not allowed on this server.' - end - - -- Does the player carry a first and last name? - -- - -- Example: - -- Allowed: 'Bob Joe' - -- Not allowed: 'Bob' - -- Not allowed: 'Bob joe' - local spacesInName = 0 - local spacesWithUpper = 0 - for word in string.gmatch(name, '%S+') do - - if string.match(word, '%u') then - spacesWithUpper = spacesWithUpper + 1 - end - - spacesInName = spacesInName + 1 - end - - if spacesInName > 2 then - return 'Your name contains more than two spaces' - end - - if spacesWithUpper ~= spacesInName then - return 'your name must start with a capital letter.' - end - - return '' -end diff --git a/config.lua b/config.lua index aaec53d7..4266ca75 100644 --- a/config.lua +++ b/config.lua @@ -1,3 +1,8 @@ -Config = {} - -Config.Locale = 'en' \ No newline at end of file +Config = {} +Config.Locale = 'en' +Config.StartingAccountMoney = {bank = 50000} +Config.MinHeight = 24 -- Minimum Height +Config.MaxHeight = 96 -- Maximum Height +Config.HighestYear = 2020 -- The highest year that can be used in date of birth +Config.LowestYear = 1900 -- The lowest year that can be used in date of birth +Config.MaxNameLength = 15 -- You must also change the SQL structure for 'firstname' and 'lastname' in the `users` table \ No newline at end of file diff --git a/esx_identity.sql b/esx_identity.sql index e6a39cc3..b8eeb2ee 100644 --- a/esx_identity.sql +++ b/esx_identity.sql @@ -1,9 +1,9 @@ USE `essentialmode`; ALTER TABLE `users` - ADD COLUMN `firstname` VARCHAR(50) NULL DEFAULT '', - ADD COLUMN `lastname` VARCHAR(50) NULL DEFAULT '', - ADD COLUMN `dateofbirth` VARCHAR(25) NULL DEFAULT '', - ADD COLUMN `sex` VARCHAR(10) NULL DEFAULT '', - ADD COLUMN `height` VARCHAR(5) NULL DEFAULT '' + ADD COLUMN `firstname` VARCHAR(15) NULL DEFAULT NULL, + ADD COLUMN `lastname` VARCHAR(15) NULL DEFAULT NULL, + ADD COLUMN `dateofbirth` VARCHAR(10) NULL DEFAULT NULL, + ADD COLUMN `sex` VARCHAR(1) NULL DEFAULT NULL, + ADD COLUMN `height` VARCHAR(3) NULL DEFAULT NULL ; \ No newline at end of file diff --git a/fxmanifest.lua b/fxmanifest.lua index 256ab072..4917c8cb 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -4,7 +4,7 @@ game 'gta5' description 'ESX Identity' -version '1.2.0' +version '1.3.0' server_scripts { '@es_extended/locale.lua', @@ -15,20 +15,4 @@ server_scripts { 'server/main.lua' } -client_scripts { - '@es_extended/locale.lua', - 'locales/en.lua', - 'locales/cs.lua', - 'config.lua', - 'client/main.lua' -} - -ui_page 'html/index.html' - -files { - 'html/index.html', - 'html/script.js', - 'html/style.css' -} - dependency 'es_extended' diff --git a/html/cs_index.html b/html/cs_index.html deleted file mode 100644 index 1dd357a9..00000000 --- a/html/cs_index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - -
    -
    -

    Register

    -
    -
    -
    -
    - Male - Female
    - -
    -
    - - - diff --git a/html/fi_index.html b/html/fi_index.html deleted file mode 100644 index 87ca250a..00000000 --- a/html/fi_index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - -
    -
    -

    Rekistöröinti

    -
    -
    -
    -
    - Mies - Nainen
    - -
    -
    - - - diff --git a/html/index.html b/html/index.html deleted file mode 100644 index 6fc5dfc7..00000000 --- a/html/index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - -
    -
    -

    Register

    -
    -
    -
    -
    - Male - Female
    - -
    -
    - - - diff --git a/html/ko_index.html b/html/ko_index.html deleted file mode 100644 index c04fe9b7..00000000 --- a/html/ko_index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - -
    -
    -

    등록

    -
    -
    -
    -
    - 남자 - 여자
    - -
    -
    - - - \ No newline at end of file diff --git a/html/script.js b/html/script.js deleted file mode 100644 index b4d4d5b4..00000000 --- a/html/script.js +++ /dev/null @@ -1,33 +0,0 @@ -$(function() { - window.addEventListener('message', function(event) { - if (event.data.type == "enableui") { - document.body.style.display = event.data.enable ? "block" : "none"; - } - }); - - document.onkeyup = function (data) { - if (data.which == 27) { // Escape key - $.post('http://esx_identity/escape', JSON.stringify({})); - } - }; - - $("#register").submit(function(event) { - event.preventDefault(); // Prevent form from submitting - - // Verify date - var date = $("#dateofbirth").val(); - var dateCheck = new Date($("#dateofbirth").val()); - - if (dateCheck == "Invalid Date") { - date == "invalid"; - } - - $.post('http://esx_identity/register', JSON.stringify({ - firstname: $("#firstname").val(), - lastname: $("#lastname").val(), - dateofbirth: date, - sex: $("input[type='radio'][name='sex']:checked").val(), - height: $("#height").val() - })); - }); -}); diff --git a/html/style.css b/html/style.css deleted file mode 100644 index 79a6b347..00000000 --- a/html/style.css +++ /dev/null @@ -1,46 +0,0 @@ -body { - font-family: sans-serif; - overflow: hidden; - display: none; -} - -.dialog { - width: 300px; - position: absolute; - margin-left: auto; - margin-right: auto; - left: 0; - right: 0; - padding: 10px; - box-shadow: 0px 0px 50px 0px #000; - background-color: #f1f1f1; - overflow: hidden; - opacity: 0.9; -} - -input[type=text] { - width: 100%; - padding: 7px; - text-align: center; -} - -button { - display: block; - margin-top: 5px; - padding: 10px; - background-color: #506be6; - border: 0; - color: #fff; - width: 100%; -} - -h1 { - display: block; - margin-top: 5px; - margin-right: 5px; - padding: 10px; - background-color: #506be6; - color: #fff; - width: 93%; - text-align: center; -} \ No newline at end of file diff --git a/html/sv_index.html b/html/sv_index.html deleted file mode 100644 index 7706c17b..00000000 --- a/html/sv_index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - -
    -
    -

    Registrera

    -
    -
    -
    -
    - Man - Kvinna
    - -
    -
    - - - diff --git a/locales/cs.lua b/locales/cs.lua index 80c6a267..f32a8888 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -1,11 +1,5 @@ Locales['cs'] = { - ['show_registration'] = 'zobrazit registracni menu', - ['show_active_character'] = 'zobrazit aktivni postavy', - ['delete_character'] = 'smazat svou stavajici postavu a vytvorit novou', - ['deleted_character'] = 'vase postava byla smazana.', - ['not_registered'] = 'nemas zaregistrovanou postavu.', - ['active_character'] = '~b~aktivni postava:~s~ %s %s', - ['already_registered'] = 'jiz mas zaregistrovanou postavu.', - ['failed_identity'] = 'nastaveni vasi postavy selhalo, zkus to prosim znovu pozdeji nebo kontaktuj majitele serveru!', - ['create_a_character'] = 'aby jsi mohl/a hrat, tak se musis registrovat.' + ['data_incorrect'] = 'Data byla zadána nesprávně. Prosím zkuste to znovu.', + ['invalid_format'] = 'Data byla nesprávně naformátována. Prosím zkuste to znovu.', + ['no_identifiers'] = '[Chyba] Nelze najít identifikátory.' } diff --git a/locales/en.lua b/locales/en.lua index 53fac161..8ab2f5b2 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,11 +1,5 @@ Locales['en'] = { - ['show_registration'] = 'show Registration Menu', - ['show_active_character'] = 'show Active Character', - ['delete_character'] = 'delete Your Character And Create A New One', - ['deleted_character'] = 'your character has been deleted.', - ['not_registered'] = 'you do not have a character reistered.', - ['active_character'] = '~b~active Character:~s~ %s %s', - ['already_registered'] = 'you already have a character registered.', - ['failed_identity'] = 'failed to set your character, try again later or contact the server admin!', - ['create_a_character'] = 'you have to create a character in order to play.' + ['data_incorrect'] = 'Data entered incorrectly. Please try again.', + ['invalid_format'] = 'Data formatted incorrectly. Please try again.', + ['no_identifiers'] = '[Error] Could not find identifiers.' } diff --git a/server/main.lua b/server/main.lua index f96f4495..01215420 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,189 +1,226 @@ ESX = nil +local registered = false +local data = { + firstName, + lastName, + dateOfBirth, + sex, + height +} TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) -function getIdentity(source, callback) - local xPlayer = ESX.GetPlayerFromId(source) +AddEventHandler("playerConnecting", function(name, setKickReason, deferrals) + local player = source + local identifiers = GetPlayerIdentifiers(player) + local identifier + deferrals.defer() - MySQL.Async.fetchAll('SELECT identifier, firstname, lastname, dateofbirth, sex, height FROM `users` WHERE `identifier` = @identifier', { - ['@identifier'] = xPlayer.identifier - }, function(result) - if result[1].firstname ~= nil then - local data = { - identifier = result[1].identifier, - firstname = result[1].firstname, - lastname = result[1].lastname, - dateofbirth = result[1].dateofbirth, - sex = result[1].sex, - height = result[1].height - } + Citizen.Wait(0) - callback(data) - else - local data = { - identifier = '', - firstname = '', - lastname = '', - dateofbirth = '', - sex = '', - height = '' - } + for k, v in pairs(identifiers) do + if string.match(v, 'license:') then + identifier = string.sub(v, 9) + break + end + end - callback(data) - end - end) -end + Citizen.Wait(0) + + 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 ~= nil then + data = { + firstName = result[1].firstname, + lastName = result[1].lastname, + dateOfBirth = result[1.].dateofbirth, + sex = result[1].sex, + height = result[1].height + } + end + end + end) -function setIdentity(identifier, data, callback) - MySQL.Async.execute('UPDATE `users` SET `firstname` = @firstname, `lastname` = @lastname, `dateofbirth` = @dateofbirth, `sex` = @sex, `height` = @height WHERE identifier = @identifier', { - ['@identifier'] = identifier, - ['@firstname'] = data.firstname, - ['@lastname'] = data.lastname, - ['@dateofbirth'] = data.dateofbirth, - ['@sex'] = data.sex, - ['@height'] = data.height - }, function(rowsChanged) - if callback then - callback(true) - end - end) -end - -function updateIdentity(playerId, data, callback) - local xPlayer = ESX.GetPlayerFromId(playerId) - - MySQL.Async.execute('UPDATE `users` SET `firstname` = @firstname, `lastname` = @lastname, `dateofbirth` = @dateofbirth, `sex` = @sex, `height` = @height WHERE identifier = @identifier', { - ['@identifier'] = xPlayer.identifier, - ['@firstname'] = data.firstname, - ['@lastname'] = data.lastname, - ['@dateofbirth'] = data.dateofbirth, - ['@sex'] = data.sex, - ['@height'] = data.height - }, function(rowsChanged) - if callback then - TriggerEvent('esx_identity:characterUpdated', playerId, data) - callback(true) - end - end) -end - -function deleteIdentity(source) - local xPlayer = ESX.GetPlayerFromId(source) - - MySQL.Async.execute('UPDATE `users` SET `firstname` = @firstname, `lastname` = @lastname, `dateofbirth` = @dateofbirth, `sex` = @sex, `height` = @height WHERE identifier = @identifier', { - ['@identifier'] = xPlayer.identifier, - ['@firstname'] = '', - ['@lastname'] = '', - ['@dateofbirth'] = '', - ['@sex'] = '', - ['@height'] = '', - }) -end - -RegisterServerEvent('esx_identity:setIdentity') -AddEventHandler('esx_identity:setIdentity', function(data, myIdentifiers) - local xPlayer = ESX.GetPlayerFromId(source) - setIdentity(myIdentifiers.steamid, data, function(callback) - if callback then - TriggerClientEvent('esx_identity:identityCheck', myIdentifiers.playerid, true) - TriggerEvent('esx_identity:characterUpdated', myIdentifiers.playerid, data) - else - xPlayer.showNotification(_U('failed_identity')) - end - end) + Citizen.Wait(500) + if data.firstName ~= nil then + registered = true + deferrals.done() + else + deferrals.presentCard([==[{"type": "AdaptiveCard", "body": [{ "type": "ColumnSet", "columns": [{ "type": "Column", "items": [ + { "type": "Input.Text", "placeholder": "First Name (Max 15 Characters)", "id": "firstname" }], "width": "stretch" }]}, + { "type": "Input.Text", "placeholder": "Last Name (Max 15 Characters)", "id": "lastname" }, + { "type": "Input.Text", "placeholder": "Height (24-96 Inches)", "id": "height" }, + { "type": "Input.Date", "id": "dateofbirth" }, + { "type": "Input.ChoiceSet", "placeholder": "Sex", "choices": [{ "title": "Male", "value": "m" }, { "title": "Female", "value": "f" }], "style": "expanded", "value": "m", "id": "sex" }], + "actions": [{ "type": "Action.Submit", "title": "Submit" }], + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "version": "1.0" + }]==], function(submittedData, rawData) + if submittedData.firstname == "" or submittedData.lastname == "" or submittedData.dateofbirth == "" or submittedData.sex == "" or submittedData.height == "" then + deferrals.done(_U('data_incorrect')) + else + if checkNameFormat(submittedData.firstname) and checkNameFormat(submittedData.lastname) and checkDOBFormat(submittedData.dateofbirth) and checkSexFormat(submittedData.sex) and checkHeightFormat(submittedData.height) then + local formattedFirstName = formatName(submittedData.firstname) + local formattedLastName = formatName(submittedData.lastname) + local formattedHeight = tonumber(submittedData.height) + data = { + firstName = formattedFirstName, + lastName = formattedLastName, + dateOfBirth = submittedData.dateofbirth, + sex = submittedData.sex, + height = formattedHeight + } + Citizen.Wait(500) + deferrals.done() + else + deferrals.done(_U('invalid_format')) + end + end + end) + end + else + deferrals.done(_U('no_identifiers')) + end end) -AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) - local myID = { - steamid = xPlayer.identifier, - playerid = playerId - } +RegisterServerEvent('esx:onPlayerSpawn') +AddEventHandler('esx:onPlayerSpawn', function() + local playerId = source + local xPlayer = ESX.GetPlayerFromId(playerId) - TriggerClientEvent('esx_identity:saveID', playerId, myID) + Citizen.Wait(4000) + + if xPlayer then + xPlayer.setName(('%s %s'):format(data.firstName, data.lastName)) + xPlayer.set('firstName', data.firstName) + xPlayer.set('lastName', data.lastName) + xPlayer.set('dateofbirth', data.dateOfBirth) + xPlayer.set('sex', data.sex) + xPlayer.set('height', data.height) + end - getIdentity(playerId, function(data) - if data.firstname == '' then - TriggerClientEvent('esx_identity:identityCheck', playerId, false) - TriggerClientEvent('esx_identity:showRegisterIdentity', playerId) - else - TriggerClientEvent('esx_identity:identityCheck', playerId, true) - TriggerEvent('esx_identity:characterUpdated', playerId, data) - end - end) + if not registered then + registered = true + SetIdentity(xPlayer.identifier, data.firstName, data.lastName, data.dateOfBirth, data.sex, data.height) + end end) -AddEventHandler('esx_identity:characterUpdated', function(playerId, data) - local xPlayer = ESX.GetPlayerFromId(playerId) - if xPlayer then - xPlayer.setName(('%s %s'):format(data.firstname, data.lastname)) - xPlayer.set('firstName', data.firstname) - xPlayer.set('lastName', data.lastname) - xPlayer.set('dateofbirth', data.dateofbirth) - xPlayer.set('sex', data.sex) - xPlayer.set('height', data.height) - end -end) +function checkNameFormat(name) + if checkAlphanumeric(name) == nil then + if checkForNumbers(name) == nil then + local stringLength = string.len(name) + if stringLength > 0 and stringLength < Config.MaxNameLength then + return true + else + return false + end + else + return false + end + else + return false + end +end --- Set all the client side variables for connected users one new time -AddEventHandler('onResourceStart', function(resource) - if resource == GetCurrentResourceName() then - Citizen.Wait(3000) - local xPlayers = ESX.GetPlayers() +function checkDOBFormat(dob) + local date = tostring(dob) + if checkDate(date) == true then + return true + else + return false + end +end - for i=1, #xPlayers, 1 do - local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) +function checkSexFormat(sex) + if sex == "m" or sex == "M" or sex == "f" or sex == "F" then + return true + else + return false + end +end - if xPlayer then - local myID = { - steamid = xPlayer.identifier, - playerid = xPlayer.source - } - - TriggerClientEvent('esx_identity:saveID', xPlayer.source, myID) - - getIdentity(xPlayer.source, function(data) - if data.firstname == '' then - TriggerClientEvent('esx_identity:identityCheck', xPlayer.source, false) - TriggerClientEvent('esx_identity:showRegisterIdentity', xPlayer.source) - else - TriggerClientEvent('esx_identity:identityCheck', xPlayer.source, true) - TriggerEvent('esx_identity:characterUpdated', xPlayer.source, data) - end - end) - end - end - end -end) +function checkHeightFormat(height) + local numHeight = tonumber(height) + if numHeight < Config.MinHeight and numHeight > Config.MaxHeight then + return false + else + return true + end +end -ESX.RegisterCommand('register', 'user', function(xPlayer, args, showError) - getIdentity(xPlayer.source, function(data) - if data.firstname ~= '' then - xPlayer.showNotification(_U('already_registered')) - else - TriggerClientEvent('esx_identity:showRegisterIdentity', xPlayer.source) - end - end) -end, false, {help = _U('show_registration')}) +function formatName(name) + local loweredName = convertToLowerCase(name) + local formattedName = convertFirstLetterToUpper(loweredName) + return formattedName +end -ESX.RegisterCommand('char', 'user', function(xPlayer, args, showError) - getIdentity(xPlayer.source, function(data) - if data.firstname == '' then - xPlayer.showNotification(_U('not_registered')) - else - xPlayer.showNotification(_U('active_character', data.firstname, data.lastname)) - end - end) -end, false, {help = _U('show_active_character')}) +function convertToLowerCase(str) + return string.lower(str) +end -ESX.RegisterCommand('chardel', 'user', function(xPlayer, args, showError) - getIdentity(xPlayer.source, function(data) - if data.firstname == '' then - xPlayer.showNotification(_U('not_registered')) - else - deleteIdentity(xPlayer.source) - xPlayer.showNotification(_U('deleted_character')) - TriggerClientEvent('esx_identity:showRegisterIdentity', xPlayer.source) - end - end) -end, false, {help = _U('delete_character')}) \ No newline at end of file +function convertFirstLetterToUpper(str) + return str:gsub("^%l", string.upper) +end + +function checkAlphanumeric(str) + return (string.match(str, "%W")) +end + +function checkForNumbers(str) + return (string.match(str,"%d")) +end + +function checkDate(str) + if string.match(str, '(%d%d%d%d)-(%d%d)-(%d%d)') ~= nil then + local y, m, d = string.match(str, '(%d+)-(%d+)-(%d+)') + y = tonumber(y) + m = tonumber(m) + d = tonumber(d) + if ((d <= 0) or (d > 31)) or ((m <= 0) or (m > 12)) or ((y <= Config.LowestYear) or (y > Config.HighestYear)) then + return false + elseif m == 4 or m == 6 or m == 9 or m == 11 then + if d > 30 then + return false + else + return true + end + elseif m == 2 then + if y%400 == 0 or (y%100 ~= 0 and y%4 == 0) then + if d > 29 then + return false + else + return true + end + else + if d > 28 then + return false + else + return true + end + end + else + if d > 31 then + return false + else + return true + end + end + else + return false + end +end + +function SetIdentity(identifier, firstName, lastName, dateOfBirth, sex, height) + MySQL.Async.execute('UPDATE `users` SET `firstname` = @firstname, `lastname` = @lastname, `dateofbirth` = @dateofbirth, `sex` = @sex, `height` = @height WHERE identifier = @identifier', { + ['@identifier'] = identifier, + ['@firstname'] = firstName, + ['@lastname'] = lastName, + ['@dateofbirth'] = dateOfBirth, + ['@sex'] = sex, + ['@height'] = height + }) +end \ No newline at end of file From bfb6e3631a52769c5d29ad2eccc19ab048a4839f Mon Sep 17 00:00:00 2001 From: ArkSeyonet <31637812+ArkSeyonet@users.noreply.github.com> Date: Mon, 6 Apr 2020 09:09:19 -0500 Subject: [PATCH 2651/3224] Update ESX Identity --- server/main.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/main.lua b/server/main.lua index 01215420..4293b824 100644 --- a/server/main.lua +++ b/server/main.lua @@ -86,8 +86,8 @@ AddEventHandler("playerConnecting", function(name, setKickReason, deferrals) end end) -RegisterServerEvent('esx:onPlayerSpawn') -AddEventHandler('esx:onPlayerSpawn', function() +RegisterServerEvent('esx:playerLoaded') +AddEventHandler('esx:playerLoaded', function() local playerId = source local xPlayer = ESX.GetPlayerFromId(playerId) From fb3f24827692e736c6fac129253f6c95711d3017 Mon Sep 17 00:00:00 2001 From: ArkSeyonet <31637812+ArkSeyonet@users.noreply.github.com> Date: Mon, 6 Apr 2020 10:12:05 -0500 Subject: [PATCH 2652/3224] Update main.lua --- server/main.lua | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/server/main.lua b/server/main.lua index 4293b824..d9e54b79 100644 --- a/server/main.lua +++ b/server/main.lua @@ -45,6 +45,7 @@ AddEventHandler("playerConnecting", function(name, setKickReason, deferrals) end) Citizen.Wait(500) + if data.firstName ~= nil then registered = true deferrals.done() @@ -73,7 +74,6 @@ AddEventHandler("playerConnecting", function(name, setKickReason, deferrals) sex = submittedData.sex, height = formattedHeight } - Citizen.Wait(500) deferrals.done() else deferrals.done(_U('invalid_format')) @@ -87,12 +87,7 @@ AddEventHandler("playerConnecting", function(name, setKickReason, deferrals) end) RegisterServerEvent('esx:playerLoaded') -AddEventHandler('esx:playerLoaded', function() - local playerId = source - local xPlayer = ESX.GetPlayerFromId(playerId) - - Citizen.Wait(4000) - +AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) if xPlayer then xPlayer.setName(('%s %s'):format(data.firstName, data.lastName)) xPlayer.set('firstName', data.firstName) From 6c1bcd330bbbc60517c38921b65afb84cbb1f55d Mon Sep 17 00:00:00 2001 From: ArkSeyonet <31637812+ArkSeyonet@users.noreply.github.com> Date: Mon, 6 Apr 2020 10:14:55 -0500 Subject: [PATCH 2653/3224] Fix Indent For Locales --- locales/cs.lua | 6 +++--- locales/en.lua | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/locales/cs.lua b/locales/cs.lua index f32a8888..e7d2ed38 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -1,5 +1,5 @@ Locales['cs'] = { - ['data_incorrect'] = 'Data byla zadána nesprávně. Prosím zkuste to znovu.', - ['invalid_format'] = 'Data byla nesprávně naformátována. Prosím zkuste to znovu.', - ['no_identifiers'] = '[Chyba] Nelze najít identifikátory.' + ['data_incorrect'] = 'Data byla zadána nesprávně. Prosím zkuste to znovu.', + ['invalid_format'] = 'Data byla nesprávně naformátována. Prosím zkuste to znovu.', + ['no_identifiers'] = '[Chyba] Nelze najít identifikátory.' } diff --git a/locales/en.lua b/locales/en.lua index 8ab2f5b2..64237849 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,5 +1,5 @@ Locales['en'] = { - ['data_incorrect'] = 'Data entered incorrectly. Please try again.', - ['invalid_format'] = 'Data formatted incorrectly. Please try again.', - ['no_identifiers'] = '[Error] Could not find identifiers.' + ['data_incorrect'] = 'Data entered incorrectly. Please try again.', + ['invalid_format'] = 'Data formatted incorrectly. Please try again.', + ['no_identifiers'] = '[Error] Could not find identifiers.' } From ab15b64fad0b933e53f6b291e83c807d5093642d Mon Sep 17 00:00:00 2001 From: ArkSeyonet <31637812+ArkSeyonet@users.noreply.github.com> Date: Mon, 6 Apr 2020 10:29:04 -0500 Subject: [PATCH 2654/3224] Update main.lua --- server/main.lua | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/server/main.lua b/server/main.lua index d9e54b79..77eb011a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -32,7 +32,7 @@ AddEventHandler("playerConnecting", function(name, setKickReason, deferrals) ['@identifier'] = identifier }, function(result) if result[1] then - if result[1].firstname ~= nil then + if result[1].firstname then data = { firstName = result[1].firstname, lastName = result[1].lastname, @@ -46,7 +46,7 @@ AddEventHandler("playerConnecting", function(name, setKickReason, deferrals) Citizen.Wait(500) - if data.firstName ~= nil then + if data.firstName then registered = true deferrals.done() else @@ -88,14 +88,12 @@ end) RegisterServerEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) - if xPlayer then - xPlayer.setName(('%s %s'):format(data.firstName, data.lastName)) - xPlayer.set('firstName', data.firstName) - xPlayer.set('lastName', data.lastName) - xPlayer.set('dateofbirth', data.dateOfBirth) - xPlayer.set('sex', data.sex) - xPlayer.set('height', data.height) - end + xPlayer.setName(('%s %s'):format(data.firstName, data.lastName)) + xPlayer.set('firstName', data.firstName) + xPlayer.set('lastName', data.lastName) + xPlayer.set('dateofbirth', data.dateOfBirth) + xPlayer.set('sex', data.sex) + xPlayer.set('height', data.height) if not registered then registered = true From b0215b9671b14054d1fde2c5bdf7070dae1acc0e Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 6 Apr 2020 17:59:40 +0200 Subject: [PATCH 2655/3224] Fixed isDead variable not updating properly, closes #635 Co-Authored-By: pitermcflebor --- client/main.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 4c91cf7f..0396dea4 100644 --- a/client/main.lua +++ b/client/main.lua @@ -65,7 +65,7 @@ AddEventHandler('esx:playerLoaded', function(playerData) z = playerData.coords.z + 0.5, heading = playerData.coords.heading }, function() - isLoadoutLoaded, isDead = true, false + isLoadoutLoaded = true TriggerServerEvent('esx:onPlayerSpawn') TriggerEvent('esx:onPlayerSpawn') TriggerEvent('playerSpawned') -- compatibility with old scripts, will be removed soon @@ -80,6 +80,7 @@ end) RegisterNetEvent('esx:setMaxWeight') AddEventHandler('esx:setMaxWeight', function(newMaxWeight) ESX.PlayerData.maxWeight = newMaxWeight end) +AddEventHandler('esx:onPlayerSpawn', function() isDead = false end) AddEventHandler('esx:onPlayerDeath', function() isDead = true end) AddEventHandler('skinchanger:loadDefaultModel', function() isLoadoutLoaded = false end) From ea3a450576ec1c06f6449a1f1b1219efdfe4b9a1 Mon Sep 17 00:00:00 2001 From: ArkSeyonet <31637812+ArkSeyonet@users.noreply.github.com> Date: Mon, 6 Apr 2020 11:25:25 -0500 Subject: [PATCH 2656/3224] Fix error, removed unused config --- config.lua | 1 - server/main.lua | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/config.lua b/config.lua index 4266ca75..96b0472d 100644 --- a/config.lua +++ b/config.lua @@ -1,6 +1,5 @@ Config = {} Config.Locale = 'en' -Config.StartingAccountMoney = {bank = 50000} Config.MinHeight = 24 -- Minimum Height Config.MaxHeight = 96 -- Maximum Height Config.HighestYear = 2020 -- The highest year that can be used in date of birth diff --git a/server/main.lua b/server/main.lua index 77eb011a..5aed770a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -36,7 +36,7 @@ AddEventHandler("playerConnecting", function(name, setKickReason, deferrals) data = { firstName = result[1].firstname, lastName = result[1].lastname, - dateOfBirth = result[1.].dateofbirth, + dateOfBirth = result[1].dateofbirth, sex = result[1].sex, height = result[1].height } @@ -86,7 +86,7 @@ AddEventHandler("playerConnecting", function(name, setKickReason, deferrals) end end) -RegisterServerEvent('esx:playerLoaded') +RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) xPlayer.setName(('%s %s'):format(data.firstName, data.lastName)) xPlayer.set('firstName', data.firstName) From b34b08eee3ad613991335fd93452967ec8d7f1e6 Mon Sep 17 00:00:00 2001 From: ArkSeyonet <31637812+ArkSeyonet@users.noreply.github.com> Date: Mon, 6 Apr 2020 11:29:04 -0500 Subject: [PATCH 2657/3224] Update main.lua --- server/main.lua | 332 ++++++++++++++++++++++++------------------------ 1 file changed, 166 insertions(+), 166 deletions(-) diff --git a/server/main.lua b/server/main.lua index 5aed770a..d0569c9b 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,219 +1,219 @@ ESX = nil local registered = false local data = { - firstName, - lastName, - dateOfBirth, - sex, - height + firstName, + lastName, + dateOfBirth, + sex, + height } TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) AddEventHandler("playerConnecting", function(name, setKickReason, deferrals) - local player = source - local identifiers = GetPlayerIdentifiers(player) - local identifier - deferrals.defer() + local player = source + local identifiers = GetPlayerIdentifiers(player) + local identifier + deferrals.defer() - Citizen.Wait(0) + Citizen.Wait(0) - for k, v in pairs(identifiers) do - if string.match(v, 'license:') then - identifier = string.sub(v, 9) - break - end - end + for k, v in pairs(identifiers) do + if string.match(v, 'license:') then + identifier = string.sub(v, 9) + break + end + end - Citizen.Wait(0) - - 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 - data = { - firstName = result[1].firstname, - lastName = result[1].lastname, - dateOfBirth = result[1].dateofbirth, - sex = result[1].sex, - height = result[1].height - } - end - end - end) + Citizen.Wait(0) + + 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 + data = { + firstName = result[1].firstname, + lastName = result[1].lastname, + dateOfBirth = result[1].dateofbirth, + sex = result[1].sex, + height = result[1].height + } + end + end + end) - Citizen.Wait(500) + Citizen.Wait(500) - if data.firstName then - registered = true - deferrals.done() - else - deferrals.presentCard([==[{"type": "AdaptiveCard", "body": [{ "type": "ColumnSet", "columns": [{ "type": "Column", "items": [ - { "type": "Input.Text", "placeholder": "First Name (Max 15 Characters)", "id": "firstname" }], "width": "stretch" }]}, - { "type": "Input.Text", "placeholder": "Last Name (Max 15 Characters)", "id": "lastname" }, - { "type": "Input.Text", "placeholder": "Height (24-96 Inches)", "id": "height" }, - { "type": "Input.Date", "id": "dateofbirth" }, - { "type": "Input.ChoiceSet", "placeholder": "Sex", "choices": [{ "title": "Male", "value": "m" }, { "title": "Female", "value": "f" }], "style": "expanded", "value": "m", "id": "sex" }], - "actions": [{ "type": "Action.Submit", "title": "Submit" }], - "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", - "version": "1.0" - }]==], function(submittedData, rawData) - if submittedData.firstname == "" or submittedData.lastname == "" or submittedData.dateofbirth == "" or submittedData.sex == "" or submittedData.height == "" then - deferrals.done(_U('data_incorrect')) - else - if checkNameFormat(submittedData.firstname) and checkNameFormat(submittedData.lastname) and checkDOBFormat(submittedData.dateofbirth) and checkSexFormat(submittedData.sex) and checkHeightFormat(submittedData.height) then - local formattedFirstName = formatName(submittedData.firstname) - local formattedLastName = formatName(submittedData.lastname) - local formattedHeight = tonumber(submittedData.height) - data = { - firstName = formattedFirstName, - lastName = formattedLastName, - dateOfBirth = submittedData.dateofbirth, - sex = submittedData.sex, - height = formattedHeight - } - deferrals.done() - else - deferrals.done(_U('invalid_format')) - end - end - end) - end - else - deferrals.done(_U('no_identifiers')) - end + if data.firstName then + registered = true + deferrals.done() + else + deferrals.presentCard([==[{"type": "AdaptiveCard", "body": [{ "type": "ColumnSet", "columns": [{ "type": "Column", "items": [ + { "type": "Input.Text", "placeholder": "First Name (Max 15 Characters)", "id": "firstname" }], "width": "stretch" }]}, + { "type": "Input.Text", "placeholder": "Last Name (Max 15 Characters)", "id": "lastname" }, + { "type": "Input.Text", "placeholder": "Height (24-96 Inches)", "id": "height" }, + { "type": "Input.Date", "id": "dateofbirth" }, + { "type": "Input.ChoiceSet", "placeholder": "Sex", "choices": [{ "title": "Male", "value": "m" }, { "title": "Female", "value": "f" }], "style": "expanded", "value": "m", "id": "sex" }], + "actions": [{ "type": "Action.Submit", "title": "Submit" }], + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "version": "1.0" + }]==], function(submittedData, rawData) + if submittedData.firstname == "" or submittedData.lastname == "" or submittedData.dateofbirth == "" or submittedData.sex == "" or submittedData.height == "" then + deferrals.done(_U('data_incorrect')) + else + if checkNameFormat(submittedData.firstname) and checkNameFormat(submittedData.lastname) and checkDOBFormat(submittedData.dateofbirth) and checkSexFormat(submittedData.sex) and checkHeightFormat(submittedData.height) then + local formattedFirstName = formatName(submittedData.firstname) + local formattedLastName = formatName(submittedData.lastname) + local formattedHeight = tonumber(submittedData.height) + data = { + firstName = formattedFirstName, + lastName = formattedLastName, + dateOfBirth = submittedData.dateofbirth, + sex = submittedData.sex, + height = formattedHeight + } + deferrals.done() + else + deferrals.done(_U('invalid_format')) + end + end + end) + end + else + deferrals.done(_U('no_identifiers')) + end end) RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) - xPlayer.setName(('%s %s'):format(data.firstName, data.lastName)) - xPlayer.set('firstName', data.firstName) - xPlayer.set('lastName', data.lastName) - xPlayer.set('dateofbirth', data.dateOfBirth) - xPlayer.set('sex', data.sex) - xPlayer.set('height', data.height) + xPlayer.setName(('%s %s'):format(data.firstName, data.lastName)) + xPlayer.set('firstName', data.firstName) + xPlayer.set('lastName', data.lastName) + xPlayer.set('dateofbirth', data.dateOfBirth) + xPlayer.set('sex', data.sex) + xPlayer.set('height', data.height) - if not registered then - registered = true - SetIdentity(xPlayer.identifier, data.firstName, data.lastName, data.dateOfBirth, data.sex, data.height) - end + if not registered then + registered = true + SetIdentity(xPlayer.identifier, data.firstName, data.lastName, data.dateOfBirth, data.sex, data.height) + end end) function checkNameFormat(name) - if checkAlphanumeric(name) == nil then - if checkForNumbers(name) == nil then - local stringLength = string.len(name) - if stringLength > 0 and stringLength < Config.MaxNameLength then - return true - else - return false - end - else - return false - end - else - return false - end + if checkAlphanumeric(name) == nil then + if checkForNumbers(name) == nil then + local stringLength = string.len(name) + if stringLength > 0 and stringLength < Config.MaxNameLength then + return true + else + return false + end + else + return false + end + else + return false + end end function checkDOBFormat(dob) - local date = tostring(dob) - if checkDate(date) == true then - return true - else - return false - end + local date = tostring(dob) + if checkDate(date) == true then + return true + else + return false + end end function checkSexFormat(sex) - if sex == "m" or sex == "M" or sex == "f" or sex == "F" then - return true - else - return false - end + if sex == "m" or sex == "M" or sex == "f" or sex == "F" then + return true + else + return false + end end function checkHeightFormat(height) - local numHeight = tonumber(height) - if numHeight < Config.MinHeight and numHeight > Config.MaxHeight then - return false - else - return true - end + local numHeight = tonumber(height) + if numHeight < Config.MinHeight and numHeight > Config.MaxHeight then + return false + else + return true + end end function formatName(name) - local loweredName = convertToLowerCase(name) - local formattedName = convertFirstLetterToUpper(loweredName) - return formattedName + local loweredName = convertToLowerCase(name) + local formattedName = convertFirstLetterToUpper(loweredName) + return formattedName end function convertToLowerCase(str) - return string.lower(str) + return string.lower(str) end function convertFirstLetterToUpper(str) - return str:gsub("^%l", string.upper) + return str:gsub("^%l", string.upper) end function checkAlphanumeric(str) - return (string.match(str, "%W")) + return (string.match(str, "%W")) end function checkForNumbers(str) - return (string.match(str,"%d")) + return (string.match(str,"%d")) end function checkDate(str) - if string.match(str, '(%d%d%d%d)-(%d%d)-(%d%d)') ~= nil then - local y, m, d = string.match(str, '(%d+)-(%d+)-(%d+)') - y = tonumber(y) - m = tonumber(m) - d = tonumber(d) - if ((d <= 0) or (d > 31)) or ((m <= 0) or (m > 12)) or ((y <= Config.LowestYear) or (y > Config.HighestYear)) then - return false - elseif m == 4 or m == 6 or m == 9 or m == 11 then - if d > 30 then - return false - else - return true - end - elseif m == 2 then - if y%400 == 0 or (y%100 ~= 0 and y%4 == 0) then - if d > 29 then - return false - else - return true - end - else - if d > 28 then - return false - else - return true - end - end - else - if d > 31 then - return false - else - return true - end - end - else - return false - end + if string.match(str, '(%d%d%d%d)-(%d%d)-(%d%d)') ~= nil then + local y, m, d = string.match(str, '(%d+)-(%d+)-(%d+)') + y = tonumber(y) + m = tonumber(m) + d = tonumber(d) + if ((d <= 0) or (d > 31)) or ((m <= 0) or (m > 12)) or ((y <= Config.LowestYear) or (y > Config.HighestYear)) then + return false + elseif m == 4 or m == 6 or m == 9 or m == 11 then + if d > 30 then + return false + else + return true + end + elseif m == 2 then + if y%400 == 0 or (y%100 ~= 0 and y%4 == 0) then + if d > 29 then + return false + else + return true + end + else + if d > 28 then + return false + else + return true + end + end + else + if d > 31 then + return false + else + return true + end + end + else + return false + end end function SetIdentity(identifier, firstName, lastName, dateOfBirth, sex, height) - MySQL.Async.execute('UPDATE `users` SET `firstname` = @firstname, `lastname` = @lastname, `dateofbirth` = @dateofbirth, `sex` = @sex, `height` = @height WHERE identifier = @identifier', { - ['@identifier'] = identifier, - ['@firstname'] = firstName, - ['@lastname'] = lastName, - ['@dateofbirth'] = dateOfBirth, - ['@sex'] = sex, - ['@height'] = height - }) + MySQL.Async.execute('UPDATE `users` SET `firstname` = @firstname, `lastname` = @lastname, `dateofbirth` = @dateofbirth, `sex` = @sex, `height` = @height WHERE identifier = @identifier', { + ['@identifier'] = identifier, + ['@firstname'] = firstName, + ['@lastname'] = lastName, + ['@dateofbirth'] = dateOfBirth, + ['@sex'] = sex, + ['@height'] = height + }) end \ No newline at end of file From 3b4fd6b2f2d8b6787dae7344afdf5882e0eba574 Mon Sep 17 00:00:00 2001 From: ArkSeyonet <31637812+ArkSeyonet@users.noreply.github.com> Date: Mon, 6 Apr 2020 12:48:49 -0500 Subject: [PATCH 2658/3224] Update ESX Identity ( tempVariable) --- server/main.lua | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/server/main.lua b/server/main.lua index d0569c9b..19e0e03e 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,12 +1,6 @@ -ESX = nil -local registered = false -local data = { - firstName, - lastName, - dateOfBirth, - sex, - height -} +ESX = nil +local registered = false +local tempIdentity = {} TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) @@ -33,12 +27,12 @@ AddEventHandler("playerConnecting", function(name, setKickReason, deferrals) }, function(result) if result[1] then if result[1].firstname then - data = { + tempIdentity[identifier] = { firstName = result[1].firstname, lastName = result[1].lastname, dateOfBirth = result[1].dateofbirth, sex = result[1].sex, - height = result[1].height + height = result[1].height } end end @@ -46,7 +40,7 @@ AddEventHandler("playerConnecting", function(name, setKickReason, deferrals) Citizen.Wait(500) - if data.firstName then + if tempIdentity[identifier] and tempIdentity[identifier].firstName then registered = true deferrals.done() else @@ -67,7 +61,7 @@ AddEventHandler("playerConnecting", function(name, setKickReason, deferrals) local formattedFirstName = formatName(submittedData.firstname) local formattedLastName = formatName(submittedData.lastname) local formattedHeight = tonumber(submittedData.height) - data = { + tempIdentity[identifier] = { firstName = formattedFirstName, lastName = formattedLastName, dateOfBirth = submittedData.dateofbirth, @@ -88,16 +82,18 @@ end) RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) - xPlayer.setName(('%s %s'):format(data.firstName, data.lastName)) - xPlayer.set('firstName', data.firstName) - xPlayer.set('lastName', data.lastName) - xPlayer.set('dateofbirth', data.dateOfBirth) - xPlayer.set('sex', data.sex) - xPlayer.set('height', data.height) + xPlayer.setName(('%s %s'):format(tempIdentity[xPlayer.identifier].firstName, tempIdentity[xPlayer.identifier].lastName)) + xPlayer.set('firstName', tempIdentity[xPlayer.identifier].firstName) + xPlayer.set('lastName', tempIdentity[xPlayer.identifier].lastName) + xPlayer.set('dateofbirth', tempIdentity[xPlayer.identifier].dateOfBirth) + xPlayer.set('sex', tempIdentity[xPlayer.identifier].sex) + xPlayer.set('height', tempIdentity[xPlayer.identifier].height) if not registered then registered = true - SetIdentity(xPlayer.identifier, data.firstName, data.lastName, data.dateOfBirth, data.sex, data.height) + SetIdentity(xPlayer.identifier, tempIdentity[xPlayer.identifier].firstName, tempIdentity[xPlayer.identifier].lastName, tempIdentity[xPlayer.identifier].dateOfBirth, tempIdentity[xPlayer.identifier].sex, tempIdentity[xPlayer.identifier].height) + else + tempIdentity[xPlayer.identifier] = nil end end) @@ -208,7 +204,7 @@ function checkDate(str) end function SetIdentity(identifier, firstName, lastName, dateOfBirth, sex, height) - MySQL.Async.execute('UPDATE `users` SET `firstname` = @firstname, `lastname` = @lastname, `dateofbirth` = @dateofbirth, `sex` = @sex, `height` = @height WHERE identifier = @identifier', { + MySQL.Async.execute('UPDATE `users` SET firstname = @firstname, lastname = @lastname, dateofbirth = @dateofbirth, sex = @sex, height = @height WHERE identifier = @identifier', { ['@identifier'] = identifier, ['@firstname'] = firstName, ['@lastname'] = lastName, @@ -216,4 +212,6 @@ function SetIdentity(identifier, firstName, lastName, dateOfBirth, sex, height) ['@sex'] = sex, ['@height'] = height }) + + tempIdentity[identifier] = nil end \ No newline at end of file From 2c557591b138ddf2b05d2a23da292fc5fc718f2f Mon Sep 17 00:00:00 2001 From: ArkSeyonet <31637812+ArkSeyonet@users.noreply.github.com> Date: Mon, 6 Apr 2020 12:51:19 -0500 Subject: [PATCH 2659/3224] Update main.lua --- server/main.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/main.lua b/server/main.lua index 19e0e03e..f195e228 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,6 +1,6 @@ -ESX = nil -local registered = false -local tempIdentity = {} +ESX = nil +local registered = false +local tempIdentity = {} TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) From 54534f196278fe0495d718aeaeea19bbcff33463 Mon Sep 17 00:00:00 2001 From: ArkSeyonet <31637812+ArkSeyonet@users.noreply.github.com> Date: Mon, 6 Apr 2020 13:06:04 -0500 Subject: [PATCH 2660/3224] Fix spacing --- server/main.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/main.lua b/server/main.lua index f195e228..6e3e2099 100644 --- a/server/main.lua +++ b/server/main.lua @@ -22,7 +22,7 @@ AddEventHandler("playerConnecting", function(name, setKickReason, deferrals) Citizen.Wait(0) if identifier then - MySQL.Async.fetchAll('SELECT firstname, lastname, dateofbirth, sex, height FROM `users` WHERE `identifier` = @identifier', { + MySQL.Async.fetchAll('SELECT firstname, lastname, dateofbirth, sex, height FROM users WHERE identifier = @identifier', { ['@identifier'] = identifier }, function(result) if result[1] then @@ -204,7 +204,7 @@ function checkDate(str) end function SetIdentity(identifier, firstName, lastName, dateOfBirth, sex, height) - MySQL.Async.execute('UPDATE `users` SET firstname = @firstname, lastname = @lastname, dateofbirth = @dateofbirth, sex = @sex, height = @height WHERE identifier = @identifier', { + MySQL.Async.execute('UPDATE users SET firstname = @firstname, lastname = @lastname, dateofbirth = @dateofbirth, sex = @sex, height = @height WHERE identifier = @identifier', { ['@identifier'] = identifier, ['@firstname'] = firstName, ['@lastname'] = lastName, From 9f1a18d4203217690ddc49304aa5bf5cb0422837 Mon Sep 17 00:00:00 2001 From: Andrea Passarini <51895814+Profex1999@users.noreply.github.com> Date: Tue, 7 Apr 2020 04:43:24 +0200 Subject: [PATCH 2661/3224] Fix removeWeaponComponent not working correctly --- server/classes/player.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 0705204c..75a7d83e 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -432,7 +432,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, if component then if self.hasWeaponComponent(weaponName, weaponComponent) then for k,v in ipairs(self.loadout[loadoutNum].components) do - if v.name == weaponComponent then + if v == weaponComponent then table.remove(self.loadout[loadoutNum].components, k) break end From 028af54c31ce556bd90c62d29cbae650f3066bf7 Mon Sep 17 00:00:00 2001 From: ArkSeyonet <31637812+ArkSeyonet@users.noreply.github.com> Date: Tue, 7 Apr 2020 11:14:53 -0500 Subject: [PATCH 2662/3224] Update main.lua --- server/main.lua | 52 +++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/server/main.lua b/server/main.lua index 6e3e2099..447cec78 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,5 +1,4 @@ ESX = nil -local registered = false local tempIdentity = {} TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) @@ -32,7 +31,8 @@ AddEventHandler("playerConnecting", function(name, setKickReason, deferrals) lastName = result[1].lastname, dateOfBirth = result[1].dateofbirth, sex = result[1].sex, - height = result[1].height + height = result[1].height, + registered = false } end end @@ -41,7 +41,7 @@ AddEventHandler("playerConnecting", function(name, setKickReason, deferrals) Citizen.Wait(500) if tempIdentity[identifier] and tempIdentity[identifier].firstName then - registered = true + tempIdentity[identifier].registered = true deferrals.done() else deferrals.presentCard([==[{"type": "AdaptiveCard", "body": [{ "type": "ColumnSet", "columns": [{ "type": "Column", "items": [ @@ -82,25 +82,27 @@ end) RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) - xPlayer.setName(('%s %s'):format(tempIdentity[xPlayer.identifier].firstName, tempIdentity[xPlayer.identifier].lastName)) - xPlayer.set('firstName', tempIdentity[xPlayer.identifier].firstName) - xPlayer.set('lastName', tempIdentity[xPlayer.identifier].lastName) - xPlayer.set('dateofbirth', tempIdentity[xPlayer.identifier].dateOfBirth) - xPlayer.set('sex', tempIdentity[xPlayer.identifier].sex) - xPlayer.set('height', tempIdentity[xPlayer.identifier].height) - - if not registered then - registered = true - SetIdentity(xPlayer.identifier, tempIdentity[xPlayer.identifier].firstName, tempIdentity[xPlayer.identifier].lastName, tempIdentity[xPlayer.identifier].dateOfBirth, tempIdentity[xPlayer.identifier].sex, tempIdentity[xPlayer.identifier].height) - else - tempIdentity[xPlayer.identifier] = nil + if tempIdentity[xPlayer.identifier] then + local currentIdentity = tempIdentity[xPlayer.identifier] + xPlayer.setName(('%s %s'):format(currentIdentity.firstName, currentIdentity.lastName)) + xPlayer.set('firstName', currentIdentity.firstName) + xPlayer.set('lastName', currentIdentity.lastName) + xPlayer.set('dateofbirth', currentIdentity.dateOfBirth) + xPlayer.set('sex', currentIdentity.sex) + xPlayer.set('height', currentIdentity.height) + if not currentIdentity.registered then + currentIdentity.registered = true + SetIdentity(xPlayer.identifier, currentIdentity) + else + tempIdentity[xPlayer.identifier] = nil + end end end) function checkNameFormat(name) - if checkAlphanumeric(name) == nil then - if checkForNumbers(name) == nil then + if not checkAlphanumeric(name) then + if not checkForNumbers(name) then local stringLength = string.len(name) if stringLength > 0 and stringLength < Config.MaxNameLength then return true @@ -117,7 +119,7 @@ end function checkDOBFormat(dob) local date = tostring(dob) - if checkDate(date) == true then + if not checkDate(date) then return true else return false @@ -203,15 +205,15 @@ function checkDate(str) end end -function SetIdentity(identifier, firstName, lastName, dateOfBirth, sex, height) +function SetIdentity(identifier, identity) MySQL.Async.execute('UPDATE users SET firstname = @firstname, lastname = @lastname, dateofbirth = @dateofbirth, sex = @sex, height = @height WHERE identifier = @identifier', { ['@identifier'] = identifier, - ['@firstname'] = firstName, - ['@lastname'] = lastName, - ['@dateofbirth'] = dateOfBirth, - ['@sex'] = sex, - ['@height'] = height + ['@firstname'] = identity.firstName, + ['@lastname'] = identity.lastName, + ['@dateofbirth'] = identity.dateOfBirth, + ['@sex'] = identity.sex, + ['@height'] = identity.height }) tempIdentity[identifier] = nil -end \ No newline at end of file +end From d69c1e0d8b91c3f16944634cf5baffbe780823c4 Mon Sep 17 00:00:00 2001 From: ArkSeyonet <31637812+ArkSeyonet@users.noreply.github.com> Date: Tue, 7 Apr 2020 14:57:07 -0500 Subject: [PATCH 2663/3224] Update main.lua --- server/main.lua | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/server/main.lua b/server/main.lua index 447cec78..e64b525a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -9,7 +9,7 @@ AddEventHandler("playerConnecting", function(name, setKickReason, deferrals) local identifier deferrals.defer() - Citizen.Wait(0) + Citizen.Wait(500) for k, v in pairs(identifiers) do if string.match(v, 'license:') then @@ -18,7 +18,7 @@ AddEventHandler("playerConnecting", function(name, setKickReason, deferrals) end end - Citizen.Wait(0) + Citizen.Wait(500) if identifier then MySQL.Async.fetchAll('SELECT firstname, lastname, dateofbirth, sex, height FROM users WHERE identifier = @identifier', { @@ -66,11 +66,12 @@ AddEventHandler("playerConnecting", function(name, setKickReason, deferrals) lastName = formattedLastName, dateOfBirth = submittedData.dateofbirth, sex = submittedData.sex, - height = formattedHeight + height = formattedHeight, + registered = false } deferrals.done() else - deferrals.done(_U('invalid_format')) + deferrals.done(_U('invalid_format') end end end) @@ -119,7 +120,7 @@ end function checkDOBFormat(dob) local date = tostring(dob) - if not checkDate(date) then + if checkDate(date) then return true else return false From 2e04fd92b996ca347d6b9d87c15e88d95acce2fd Mon Sep 17 00:00:00 2001 From: ArkSeyonet <31637812+ArkSeyonet@users.noreply.github.com> Date: Tue, 7 Apr 2020 19:38:10 -0500 Subject: [PATCH 2664/3224] Fix errors, fixing spacing --- server/main.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/server/main.lua b/server/main.lua index e64b525a..b8b9dbc0 100644 --- a/server/main.lua +++ b/server/main.lua @@ -71,7 +71,7 @@ AddEventHandler("playerConnecting", function(name, setKickReason, deferrals) } deferrals.done() else - deferrals.done(_U('invalid_format') + deferrals.done(_U('invalid_format')) end end end) @@ -208,12 +208,12 @@ end function SetIdentity(identifier, identity) MySQL.Async.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 + ['@identifier'] = identifier, + ['@firstname'] = identity.firstName, + ['@lastname'] = identity.lastName, + ['@dateofbirth'] = identity.dateOfBirth, + ['@sex'] = identity.sex, + ['@height'] = identity.height }) tempIdentity[identifier] = nil From 8de2e4311ab21781bb5da56f8c3bde17a87fff8e Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 11 Apr 2020 11:53:50 +0200 Subject: [PATCH 2665/3224] Unload model where applicable --- client/functions.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 8d2ea626..26bc233b 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -326,8 +326,8 @@ ESX.Game.SpawnObject = function(model, coords, cb) Citizen.CreateThread(function() ESX.Streaming.RequestModel(model) - local obj = CreateObject(model, coords.x, coords.y, coords.z, true, false, true) + SetModelAsNoLongerNeeded(model) if cb then cb(obj) @@ -340,8 +340,8 @@ ESX.Game.SpawnLocalObject = function(model, coords, cb) Citizen.CreateThread(function() ESX.Streaming.RequestModel(model) - local obj = CreateObject(model, coords.x, coords.y, coords.z, false, false, true) + SetModelAsNoLongerNeeded(model) if cb then cb(obj) From ddd3a88336cc336ad439e8e11291d130f20d2a0b Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 11 Apr 2020 11:55:27 +0200 Subject: [PATCH 2666/3224] Minor variable renaming --- client/main.lua | 41 ++++++++++++++++++++--------------------- server/main.lua | 8 ++++---- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/client/main.lua b/client/main.lua index 0396dea4..ac07a4fe 100644 --- a/client/main.lua +++ b/client/main.lua @@ -273,12 +273,13 @@ end) RegisterNetEvent('esx:createPickup') AddEventHandler('esx:createPickup', function(pickupId, label, playerId, type, name, components, tintIndex) local playerPed = GetPlayerPed(GetPlayerFromServerId(playerId)) - local entityCoords, forward, pickupObject = GetEntityCoords(playerPed), GetEntityForwardVector(playerPed) - local objectCoords = (entityCoords + forward * 1.0) + local entityCoords, forwardVector, pickupObject = GetEntityCoords(playerPed), GetEntityForwardVector(playerPed) + local objectCoords = (entityCoords + forwardVector * 1.0) if type == 'item_weapon' then - ESX.Streaming.RequestWeaponAsset(GetHashKey(name)) - pickupObject = CreateWeaponObject(GetHashKey(name), 50, objectCoords, true, 1.0, 0) + local weaponHash = GetHashKey(name) + ESX.Streaming.RequestWeaponAsset(weaponHash) + pickupObject = CreateWeaponObject(weaponHash, 50, objectCoords, true, 1.0, 0) SetWeaponObjectTintIndex(pickupObject, tintIndex) for k,v in ipairs(components) do @@ -301,7 +302,6 @@ AddEventHandler('esx:createPickup', function(pickupId, label, playerId, type, na SetEntityCollision(pickupObject, false, true) pickups[pickupId] = { - id = pickupId, obj = pickupObject, label = label, inRange = false, @@ -339,7 +339,6 @@ AddEventHandler('esx:createMissingPickups', function(missingPickups) SetEntityCollision(pickupObject, false, true) pickups[pickupId] = { - id = pickupId, obj = pickupObject, label = pickup.label, inRange = false, @@ -358,10 +357,10 @@ AddEventHandler('esx:registerSuggestions', function(registeredCommands) end) RegisterNetEvent('esx:removePickup') -AddEventHandler('esx:removePickup', function(id) - if pickups[id] and pickups[id].obj then - ESX.Game.DeleteObject(pickups[id].obj) - pickups[id] = nil +AddEventHandler('esx:removePickup', function(pickupId) + if pickups[pickupId] and pickups[pickupId].obj then + ESX.Game.DeleteObject(pickups[pickupId].obj) + pickups[pickupId] = nil end end) @@ -480,24 +479,24 @@ Citizen.CreateThread(function() local playerCoords, letSleep = GetEntityCoords(playerPed), true local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - for k,v in pairs(pickups) do - local distance = #(playerCoords - v.coords) + for pickupId,pickup in pairs(pickups) do + local distance = #(playerCoords - pickup.coords) if distance < 5 then - local label = v.label + local label = pickup.label letSleep = false if distance < 1 then if IsControlJustReleased(0, 38) then - if IsPedOnFoot(playerPed) and (closestDistance == -1 or closestDistance > 3) and not v.inRange then - v.inRange = true + if IsPedOnFoot(playerPed) and (closestDistance == -1 or closestDistance > 3) and not pickup.inRange then + pickup.inRange = true local dict, anim = 'weapons@first_person@aim_rng@generic@projectile@sticky_bomb@', 'plant_floor' ESX.Streaming.RequestAnimDict(dict) TaskPlayAnim(playerPed, dict, anim, 8.0, 1.0, 1000, 16, 0.0, false, false, false) Citizen.Wait(1000) - TriggerServerEvent('esx:onPickup', v.id) + TriggerServerEvent('esx:onPickup', pickupId) PlaySoundFrontend(-1, 'PICK_UP', 'HUD_FRONTEND_DEFAULT_SOUNDSET', false) end end @@ -506,12 +505,12 @@ Citizen.CreateThread(function() end ESX.Game.Utils.DrawText3D({ - x = v.coords.x, - y = v.coords.y, - z = v.coords.z + 0.25 + x = pickup.coords.x, + y = pickup.coords.y, + z = pickup.coords.z + 0.25 }, label, 1.2, 1) - elseif v.inRange then - v.inRange = false + elseif pickup.inRange then + pickup.inRange = false end end diff --git a/server/main.lua b/server/main.lua index ce395123..5992cfe6 100644 --- a/server/main.lua +++ b/server/main.lua @@ -420,8 +420,8 @@ AddEventHandler('esx:useItem', function(itemName) end) RegisterNetEvent('esx:onPickup') -AddEventHandler('esx:onPickup', function(id) - local pickup, xPlayer, success = ESX.Pickups[id], ESX.GetPlayerFromId(source) +AddEventHandler('esx:onPickup', function(pickupId) + local pickup, xPlayer, success = ESX.Pickups[pickupId], ESX.GetPlayerFromId(source) if pickup then if pickup.type == 'item_standard' then @@ -449,8 +449,8 @@ AddEventHandler('esx:onPickup', function(id) end if success then - ESX.Pickups[id] = nil - TriggerClientEvent('esx:removePickup', -1, id) + ESX.Pickups[pickupId] = nil + TriggerClientEvent('esx:removePickup', -1, pickupId) end end end) From d707b6049355554e03aaf6e5f165a29090d73049 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 12 Apr 2020 18:11:35 +0200 Subject: [PATCH 2667/3224] Added timeout on HasCollisionLoadedAroundEntity() --- client/functions.lua | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 26bc233b..87292a48 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -304,9 +304,12 @@ end ESX.Game.Teleport = function(entity, coords, cb) if DoesEntityExist(entity) then RequestCollisionAtCoord(coords.x, coords.y, coords.z) + local timeout = 0 - while not HasCollisionLoadedAroundEntity(entity) do + -- we can get stuck here if any of the axies are "invalid" + while not HasCollisionLoadedAroundEntity(entity) and timeout < 2000 do Citizen.Wait(0) + timeout = timeout + 1 end SetEntityCoords(entity, coords.x, coords.y, coords.z, false, false, false, false) @@ -366,22 +369,23 @@ ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) ESX.Streaming.RequestModel(model) local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, true, false) - local id = NetworkGetNetworkIdFromEntity(vehicle) + local networkId = NetworkGetNetworkIdFromEntity(vehicle) + local timeout = 0 - SetNetworkIdCanMigrate(id, true) + SetNetworkIdCanMigrate(networkId, true) SetEntityAsMissionEntity(vehicle, true, false) SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetVehicleNeedsToBeHotwired(vehicle, false) + SetVehRadioStation(vehicle, 'OFF') SetModelAsNoLongerNeeded(model) - RequestCollisionAtCoord(coords.x, coords.y, coords.z) - while not HasCollisionLoadedAroundEntity(vehicle) do + -- we can get stuck here if any of the axies are "invalid" + while not HasCollisionLoadedAroundEntity(vehicle) and timeout < 2000 do Citizen.Wait(0) + timeout = timeout + 1 end - SetVehRadioStation(vehicle, 'OFF') - if cb then cb(vehicle) end @@ -395,19 +399,21 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) ESX.Streaming.RequestModel(model) local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, false, false) + local timeout = 0 SetEntityAsMissionEntity(vehicle, true, false) SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetVehicleNeedsToBeHotwired(vehicle, false) + SetVehRadioStation(vehicle, 'OFF') SetModelAsNoLongerNeeded(model) RequestCollisionAtCoord(coords.x, coords.y, coords.z) - while not HasCollisionLoadedAroundEntity(vehicle) do + -- we can get stuck here if any of the axies are "invalid" + while not HasCollisionLoadedAroundEntity(vehicle) and timeout < 2000 do Citizen.Wait(0) + timeout = timeout + 1 end - SetVehRadioStation(vehicle, 'OFF') - if cb then cb(vehicle) end From 2b58041abbcc64d177219375d74dad98572661e1 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 13 Apr 2020 16:33:00 +0200 Subject: [PATCH 2668/3224] Added default map name & game type Co-Authored-By: Thuan Truong --- server/common.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/common.lua b/server/common.lua index 4921c75c..0acd1c9b 100644 --- a/server/common.lua +++ b/server/common.lua @@ -19,6 +19,9 @@ function getSharedObject() end MySQL.ready(function() + SetMapName('San Andreas') + SetGameType('Roleplay') + MySQL.Async.fetchAll('SELECT * FROM items', {}, function(result) for k,v in ipairs(result) do ESX.Items[v.name] = { From 238bcae7c0a251f134a6cf15b521d995a694d6e8 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 13 Apr 2020 17:50:20 +0200 Subject: [PATCH 2669/3224] Stop incompatible resources (see description) Automaticly stop resources that - a) not compatible with ESX, for example spawnmanager - b) does the same as esx does, but what esx probably does better --- config.lua | 14 ++++++++++++++ server/common.lua | 3 --- server/main.lua | 31 ++++++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/config.lua b/config.lua index fc28850e..888f7e65 100644 --- a/config.lua +++ b/config.lua @@ -18,3 +18,17 @@ Config.MaxWeight = 24 -- the max inventory weight without backpack Config.PaycheckInterval = 7 * 60000 -- how often to recieve pay checks in milliseconds Config.EnableDebug = false + +Config.IncompatibleResourcesToStop = { + ['essentialmode'] = 'ES for short, the performance heavy RP framework no one uses - and source for the random unwanted ZAP ads you\'re seeing', + ['es_admin2'] = 'Adminstration tool for the ancient ES framework that wont work with ESX', + ['esplugin_mysql'] = 'MySQL "plugin" for the ancient ES framework that has a SQL injection vulnerability', + ['es_ui'] = 'Money HUD for ES', + ['spawnmanager'] = 'Default resource that takes care of spawning players, ESX does this already', + ['mapmanager'] = 'Default resource that was required by spawnmanager, but neither are used', + ['basic-gamemode'] = 'Resource that is solely for choosing the default game type', + ['fivem'] = 'Resource that is solely for choosing the default game type', + ['fivem-map-hipster'] = 'Default spawn locations for mapmanager', + ['fivem-map-skater'] = 'Default spawn locations for mapmanager', + ['baseevents'] = 'Default resource for handling death events, ESX does this already' +} diff --git a/server/common.lua b/server/common.lua index 0acd1c9b..4921c75c 100644 --- a/server/common.lua +++ b/server/common.lua @@ -19,9 +19,6 @@ function getSharedObject() end MySQL.ready(function() - SetMapName('San Andreas') - SetGameType('Roleplay') - MySQL.Async.fetchAll('SELECT * FROM items', {}, function(result) for k,v in ipairs(result) do ESX.Items[v.name] = { diff --git a/server/main.lua b/server/main.lua index 5992cfe6..ea069af0 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,3 +1,32 @@ +Citizen.CreateThread(function() + SetMapName('San Andreas') + SetGameType('Roleplay') + local resourcesStopped = {} + + for resourceName,reason in pairs(Config.IncompatibleResourcesToStop) do + local status = GetResourceState(resourceName) + + if status == 'started' or status == 'starting' then + while status == 'starting' do + Citizen.Wait(100) + end + + StopResource(resourceName) + resourcesStopped[resourceName] = reason + end + end + + if ESX.Table.SizeOf(resourcesStopped) > 0 then + local allStoppedResources = '' + + for resourceName,reason in pairs(resourcesStopped) do + allStoppedResources = ('%s\n- ^3%s^7, %s'):format(allStoppedResources, resourceName, reason) + end + + print(('[es_extended] [^3WARNING^7] Stopped %s incompatible resource(s) that can cause issues when used with ESX. They are not needed and can safely be removed from your server, remove these resource(s) from your resource directory and your configuration file:%s'):format(ESX.Table.SizeOf(resourcesStopped), allStoppedResources)) + end +end) + RegisterNetEvent('esx:onPlayerJoined') AddEventHandler('esx:onPlayerJoined', function() if not ESX.Players[source] then @@ -216,7 +245,7 @@ function loadESXPlayer(identifier, playerId) inventory = xPlayer.getInventory(), job = xPlayer.getJob(), loadout = xPlayer.getLoadout(), - maxWeight = xPlayer.maxWeight, + maxWeight = xPlayer.getMaxWeight(), money = xPlayer.getMoney() }) From 71e24f0a723e6192dfbed765221efb61046ac025 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 13 Apr 2020 19:02:56 +0200 Subject: [PATCH 2670/3224] Fixed while statement --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index ea069af0..651d5c57 100644 --- a/server/main.lua +++ b/server/main.lua @@ -7,7 +7,7 @@ Citizen.CreateThread(function() local status = GetResourceState(resourceName) if status == 'started' or status == 'starting' then - while status == 'starting' do + while GetResourceState(resourceName) == 'starting' do Citizen.Wait(100) end From 779afff503b9774a96f0a35a1a63a0ebad34bc56 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 14 Apr 2020 10:23:55 +0200 Subject: [PATCH 2671/3224] Fixed typos in locales, closes #658 --- client/functions.lua | 2 +- client/main.lua | 2 +- locales/cs.lua | 156 +++++++++++++++++++++---------------------- locales/en.lua | 6 +- locales/fi.lua | 4 +- locales/sc.lua | 2 +- locales/sv.lua | 2 +- locales/tc.lua | 2 +- 8 files changed, 88 insertions(+), 88 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 87292a48..a15a7812 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -205,7 +205,7 @@ ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change, menu.setElement = function(i, key, val) menu.data.elements[i][key] = val end - + menu.setElements = function(newElements) menu.data.elements = newElements end diff --git a/client/main.lua b/client/main.lua index ac07a4fe..cbfe984d 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,4 +1,4 @@ -local isLoadoutLoaded, isPaused, isDead, isFirstSpawn, pickups = false, false, false, true, {} +local isLoadoutLoaded, isPaused, isDead, pickups = false, false, false, {} Citizen.CreateThread(function() while true do diff --git a/locales/cs.lua b/locales/cs.lua index 10c1d3a0..27963467 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -38,20 +38,20 @@ Locales['cs'] = { ['threw_pickup_prompt'] = 'stiskni ~y~E~s~ po zvednuti', -- Key mapping - ['keymap_showinventory'] = 'zobrazit inventar', + ['keymap_showinventory'] = 'zobrazit inventar', - -- Salary related - ['received_salary'] = 'obdrželi jste výplatu: ~g~$%s~s~', - ['received_help'] = 'obdrželi jste sociální dávku: ~g~$%s~s~', - ['company_nomoney'] = 'společnost u které jste zaměstananí nemá peníze na váš plat', - ['received_paycheck'] = 'obdržena výplata', - ['bank'] = 'bankovní účet', - ['account_bank'] = 'banka', - ['account_black_money'] = 'spinave penize', - ['account_money'] = 'kapesne', + -- Salary related + ['received_salary'] = 'obdrželi jste výplatu: ~g~$%s~s~', + ['received_help'] = 'obdrželi jste sociální dávku: ~g~$%s~s~', + ['company_nomoney'] = 'společnost u které jste zaměstananí nemá peníze na váš plat', + ['received_paycheck'] = 'obdržena výplata', + ['bank'] = 'bankovní účet', + ['account_bank'] = 'banka', + ['account_black_money'] = 'spinave penize', + ['account_money'] = 'kapesne', - ['act_imp'] = 'akce není možná', - ['in_vehicle'] = 'nemůže nic dát osobě ve vozidle', + ['act_imp'] = 'akce není možná', + ['in_vehicle'] = 'nemůže nic dát osobě ve vozidle', -- Commands ['command_car'] = 'spawn an vehicle', @@ -102,71 +102,71 @@ Locales['cs'] = { ['commandgeneric_playerid'] = 'player id', -- Locale settings - ['locale_digit_grouping_symbol'] = ' ', - ['locale_currency'] = '$%s', + ['locale_digit_grouping_symbol'] = ' ', + ['locale_currency'] = '$%s', - -- Weapons - ['weapon_knife'] = 'nuz', - ['weapon_nightstick'] = 'policejni obusek', - ['weapon_hammer'] = 'kladivo', - ['weapon_bat'] = 'basseballka', - ['weapon_golfclub'] = 'gollfova hul', - ['weapon_crowbar'] = 'pacidlo', - ['weapon_pistol'] = 'pistole', - ['weapon_combatpistol'] = 'utocna pistole', - ['weapon_appistol'] = 'ap pistole', - ['weapon_pistol50'] = 'pistole .50', - ['weapon_microsmg'] = 'micro smg', - ['weapon_smg'] = 'smg', - ['weapon_assaultsmg'] = 'utocne smg', - ['weapon_assaultrifle'] = 'utocna puska', - ['weapon_carbinerifle'] = 'carbine puska', - ['weapon_advancedrifle'] = 'pokrocily puska', - ['weapon_mg'] = 'mg', - ['weapon_combatmg'] = 'utocne mg', - ['weapon_pumpshotgun'] = 'pumpovana brokovnice', - ['weapon_sawnoffshotgun'] = 'upilovana brokovnice', - ['weapon_assaultshotgun'] = 'utocna brokovnice', - ['weapon_bullpupshotgun'] = 'bullpup brokovnice', - ['weapon_stungun'] = 'tazer', - ['weapon_sniperrifle'] = 'sniperka', - ['weapon_heavysniper'] = 'tezka sniperka', - ['weapon_grenadelauncher'] = 'launcher granatu', - ['weapon_rpg'] = 'raketomet', - ['weapon_minigun'] = 'minigun', - ['weapon_grenade'] = 'granat', - ['weapon_stickybomb'] = 'lepkava bomba', - ['weapon_smokegrenade'] = 'kourovy granat', - ['weapon_bzgas'] = 'bz gas', - ['weapon_molotov'] = 'molotov koktejl', - ['weapon_fireextinguisher'] = 'hasicak', - ['weapon_petrolcan'] = 'kanystr', - ['weapon_ball'] = 'koule', - ['weapon_snspistol'] = 'sns pistole', - ['weapon_bottle'] = 'lahev', - ['weapon_gusenberg'] = 'gusenberguv zametac', - ['weapon_specialcarbine'] = 'specialni karabina', - ['weapon_heavypistol'] = 'tezka pistole', - ['weapon_bullpuprifle'] = 'bullpup puska', - ['weapon_dagger'] = 'dyka', - ['weapon_vintagepistol'] = 'velmi stara pistole', - ['weapon_firework'] = 'ohnostroj', - ['weapon_musket'] = 'musketa', - ['weapon_heavyshotgun'] = 'tezka brokovnice', - ['weapon_marksmanrifle'] = 'puska strelce', - ['weapon_hominglauncher'] = 'navadeci launcher', - ['weapon_proxmine'] = 'mina na blizko', - ['weapon_snowball'] = 'snehova koule', - ['weapon_flaregun'] = 'svetlice', - ['weapon_combatpdw'] = 'utocne pdw', - ['weapon_marksmanpistol'] = 'pistole strelce', - ['weapon_knuckle'] = 'knuckledusters', - ['weapon_hatchet'] = 'sekerka', - ['weapon_railgun'] = 'vlakovy launcher', - ['weapon_machete'] = 'maceta', - ['weapon_machinepistol'] = 'kulomet', - ['weapon_switchblade'] = 'vystrelovaci nuz', - ['weapon_revolver'] = 'tezky revolver', + -- Weapons + ['weapon_knife'] = 'nuz', + ['weapon_nightstick'] = 'policejni obusek', + ['weapon_hammer'] = 'kladivo', + ['weapon_bat'] = 'basseballka', + ['weapon_golfclub'] = 'gollfova hul', + ['weapon_crowbar'] = 'pacidlo', + ['weapon_pistol'] = 'pistole', + ['weapon_combatpistol'] = 'utocna pistole', + ['weapon_appistol'] = 'ap pistole', + ['weapon_pistol50'] = 'pistole .50', + ['weapon_microsmg'] = 'micro smg', + ['weapon_smg'] = 'smg', + ['weapon_assaultsmg'] = 'utocne smg', + ['weapon_assaultrifle'] = 'utocna puska', + ['weapon_carbinerifle'] = 'carbine puska', + ['weapon_advancedrifle'] = 'pokrocily puska', + ['weapon_mg'] = 'mg', + ['weapon_combatmg'] = 'utocne mg', + ['weapon_pumpshotgun'] = 'pumpovana brokovnice', + ['weapon_sawnoffshotgun'] = 'upilovana brokovnice', + ['weapon_assaultshotgun'] = 'utocna brokovnice', + ['weapon_bullpupshotgun'] = 'bullpup brokovnice', + ['weapon_stungun'] = 'tazer', + ['weapon_sniperrifle'] = 'sniperka', + ['weapon_heavysniper'] = 'tezka sniperka', + ['weapon_grenadelauncher'] = 'launcher granatu', + ['weapon_rpg'] = 'raketomet', + ['weapon_minigun'] = 'minigun', + ['weapon_grenade'] = 'granat', + ['weapon_stickybomb'] = 'lepkava bomba', + ['weapon_smokegrenade'] = 'kourovy granat', + ['weapon_bzgas'] = 'bz gas', + ['weapon_molotov'] = 'molotov koktejl', + ['weapon_fireextinguisher'] = 'hasicak', + ['weapon_petrolcan'] = 'kanystr', + ['weapon_ball'] = 'koule', + ['weapon_snspistol'] = 'sns pistole', + ['weapon_bottle'] = 'lahev', + ['weapon_gusenberg'] = 'gusenberguv zametac', + ['weapon_specialcarbine'] = 'specialni karabina', + ['weapon_heavypistol'] = 'tezka pistole', + ['weapon_bullpuprifle'] = 'bullpup puska', + ['weapon_dagger'] = 'dyka', + ['weapon_vintagepistol'] = 'velmi stara pistole', + ['weapon_firework'] = 'ohnostroj', + ['weapon_musket'] = 'musketa', + ['weapon_heavyshotgun'] = 'tezka brokovnice', + ['weapon_marksmanrifle'] = 'puska strelce', + ['weapon_hominglauncher'] = 'navadeci launcher', + ['weapon_proxmine'] = 'mina na blizko', + ['weapon_snowball'] = 'snehova koule', + ['weapon_flaregun'] = 'svetlice', + ['weapon_combatpdw'] = 'utocne pdw', + ['weapon_marksmanpistol'] = 'pistole strelce', + ['weapon_knuckle'] = 'knuckledusters', + ['weapon_hatchet'] = 'sekerka', + ['weapon_railgun'] = 'vlakovy launcher', + ['weapon_machete'] = 'maceta', + ['weapon_machinepistol'] = 'kulomet', + ['weapon_switchblade'] = 'vystrelovaci nuz', + ['weapon_revolver'] = 'tezky revolver', ['weapon_dbshotgun'] = 'dvouhlavnova brokovnice', ['weapon_compactrifle'] = 'kompaktni puska', ['weapon_autoshotgun'] = 'automaticka brokovnice', @@ -176,7 +176,7 @@ Locales['cs'] = { ['weapon_pipebomb'] = 'dymkova bomba', ['weapon_poolcue'] = 'kulecnikove tago', ['weapon_wrench'] = 'klic na trubky', - ['weapon_flashlight'] = 'baterka', + ['weapon_flashlight'] = 'baterka', ['gadget_parachute'] = 'padak', ['weapon_flare'] = 'svetlice', ['weapon_doubleaction'] = 'dvojhlavnovy revolver', @@ -193,7 +193,7 @@ Locales['cs'] = { ['component_grip'] = 'rukojet', ['component_luxary_finish'] = 'luxusni vzhled zbrane', - -- Weapon Ammo + -- Weapon Ammo ['ammo_rounds'] = 'naboj(e)', ['ammo_shells'] = 'patrona(y)', ['ammo_charge'] = 'naboj(e)', diff --git a/locales/en.lua b/locales/en.lua index a5ec7122..7dea0545 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -178,12 +178,12 @@ Locales['en'] = { ['weapon_wrench'] = 'pipe wrench', ['weapon_flashlight'] = 'flashlight', ['gadget_parachute'] = 'parachute', - ['weapon_flare'] = 'flare gun', + ['weapon_flare'] = 'flare', ['weapon_doubleaction'] = 'double-Action Revolver', -- Weapon Components - ['component_clip_default'] = 'default Grip', - ['component_clip_extended'] = 'extended Grip', + ['component_clip_default'] = 'default Clip', + ['component_clip_extended'] = 'extended Clip', ['component_clip_drum'] = 'drum Magazine', ['component_clip_box'] = 'box Magazine', ['component_flashlight'] = 'flashlight', diff --git a/locales/fi.lua b/locales/fi.lua index 034aebd3..e69271b8 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -182,8 +182,8 @@ Locales['fi'] = { ['weapon_doubleaction'] = 'double-Action Revolver', -- Weapon Components - ['component_clip_default'] = 'default Grip', - ['component_clip_extended'] = 'extended Grip', + ['component_clip_default'] = 'default Clip', + ['component_clip_extended'] = 'extended Clip', ['component_clip_drum'] = 'drum Magazine', ['component_clip_box'] = 'box Magazine', ['component_flashlight'] = 'flashlight', diff --git a/locales/sc.lua b/locales/sc.lua index 050637e2..cfe39ae2 100644 --- a/locales/sc.lua +++ b/locales/sc.lua @@ -49,7 +49,7 @@ Locales['sc'] = { ['account_bank'] = '银行', ['account_black_money'] = '黑钱', ['account_money'] = '现金', - + ['act_imp'] = '操作失败', ['in_vehicle'] = '请离开载具', diff --git a/locales/sv.lua b/locales/sv.lua index 5cb32c29..25c682f0 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -178,7 +178,7 @@ Locales['sv'] = { ['weapon_wrench'] = 'skiftnyckel', ['weapon_flashlight'] = 'ficklampa', ['gadget_parachute'] = 'fallskärm', - ['weapon_flare'] = 'signalpistol', + ['weapon_flare'] = 'blossa', ['weapon_doubleaction'] = 'double-Action Revolver', -- Weapon Components diff --git a/locales/tc.lua b/locales/tc.lua index c0b1e31c..9e31c8db 100644 --- a/locales/tc.lua +++ b/locales/tc.lua @@ -49,7 +49,7 @@ Locales['tc'] = { ['account_bank'] = '銀行', ['account_black_money'] = '黑錢', ['account_money'] = '現金', - + ['act_imp'] = '操作失敗', ['in_vehicle'] = '請離開載具', From 26ac44b35bdfcad0f28b920a7d41f50560d65377 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 14 Apr 2020 10:29:30 +0200 Subject: [PATCH 2672/3224] Hopefully fixed #633 --- client/functions.lua | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index a15a7812..a4070355 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1001,7 +1001,7 @@ ESX.ShowInventory = function() if playersNearby[selectedPlayer] then local selectedPlayerPed = GetPlayerPed(selectedPlayer) - if IsPedOnFoot(selectedPlayerPed) then + if IsPedOnFoot(selectedPlayerPed) and not IsPedFalling(selectedPlayerPed) then if type == 'item_weapon' then TriggerServerEvent('esx:giveInventoryItem', selectedPlayerId, type, item, nil) menu2.close() @@ -1039,7 +1039,7 @@ ESX.ShowInventory = function() ESX.ShowNotification(_U('players_nearby')) end elseif data1.current.action == 'remove' then - if IsPedOnFoot(playerPed) then + if IsPedOnFoot(playerPed) and not IsPedFalling(playerPed) then local dict, anim = 'weapons@first_person@aim_rng@generic@projectile@sticky_bomb@', 'plant_floor' ESX.Streaming.RequestAnimDict(dict) @@ -1075,10 +1075,9 @@ ESX.ShowInventory = function() ESX.ShowInventory() elseif data1.current.action == 'give_ammo' then local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - local closestPed = GetPlayerPed(closestPlayer) local pedAmmo = GetAmmoInPedWeapon(playerPed, GetHashKey(item)) - if IsPedOnFoot(closestPed) then + if IsPedOnFoot(closestPed) and not IsPedFalling(closestPed) then if closestPlayer ~= -1 and closestDistance < 3.0 then if pedAmmo > 0 then ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', { From e772031094a3615f23f278b5fca00030f6ccf140 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 14 Apr 2020 10:42:03 +0200 Subject: [PATCH 2673/3224] Fixed some cases of shadowing upvalue --- client/functions.lua | 9 +++++---- client/main.lua | 6 +++--- server/functions.lua | 8 ++++---- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index a4070355..177bf7f5 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -944,7 +944,7 @@ ESX.ShowInventory = function() }, function(data, menu) menu.close() local player, distance = ESX.Game.GetClosestPlayer() - local elements = {} + elements = {} if data.current.usable then table.insert(elements, {label = _U('use'), action = 'use', type = data.current.type, value = data.current.value}) @@ -975,10 +975,11 @@ ESX.ShowInventory = function() local playersNearby = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) if #playersNearby > 0 then - local players, elements = {}, {} + local players = {} + elements = {} - for k,player in ipairs(playersNearby) do - players[GetPlayerServerId(player)] = true + for k,playerNearby in ipairs(playersNearby) do + players[GetPlayerServerId(playerNearby)] = true end ESX.TriggerServerCallback('esx:getPlayerNames', function(returnedPlayers) diff --git a/client/main.lua b/client/main.lua index cbfe984d..e66cce33 100644 --- a/client/main.lua +++ b/client/main.lua @@ -255,8 +255,8 @@ AddEventHandler('esx:setJob', function(job) end) RegisterNetEvent('esx:spawnVehicle') -AddEventHandler('esx:spawnVehicle', function(vehicle) - local model = (type(vehicle) == 'number' and vehicle or GetHashKey(vehicle)) +AddEventHandler('esx:spawnVehicle', function(vehicleName) + local model = (type(vehicleName) == 'number' and vehicleName or GetHashKey(vehicleName)) if IsModelInCdimage(model) then local playerPed = PlayerPedId() @@ -266,7 +266,7 @@ AddEventHandler('esx:spawnVehicle', function(vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) end) else - TriggerEvent('chat:addMessage', { args = { '^1SYSTEM', 'Invalid vehicle model.' } }) + TriggerEvent('chat:addMessage', {args = {'^1SYSTEM', 'Invalid vehicle model.'}}) end end) diff --git a/server/functions.lua b/server/functions.lua index 601f27f0..5038c059 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -166,7 +166,7 @@ end ESX.SavePlayer = function(xPlayer, cb) local asyncTasks = {} - table.insert(asyncTasks, function(cb) + table.insert(asyncTasks, function(cb2) MySQL.Async.execute('UPDATE users SET accounts = @accounts, job = @job, job_grade = @job_grade, `group` = @group, loadout = @loadout, position = @position, inventory = @inventory WHERE identifier = @identifier', { ['@accounts'] = json.encode(xPlayer.getAccounts(true)), ['@job'] = xPlayer.job.name, @@ -177,7 +177,7 @@ ESX.SavePlayer = function(xPlayer, cb) ['@identifier'] = xPlayer.getIdentifier(), ['@inventory'] = json.encode(xPlayer.getInventory(true)) }, function(rowsChanged) - cb() + cb2() end) end) @@ -194,9 +194,9 @@ ESX.SavePlayers = function(cb) local xPlayers, asyncTasks = ESX.GetPlayers(), {} for i=1, #xPlayers, 1 do - table.insert(asyncTasks, function(cb) + table.insert(asyncTasks, function(cb2) local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) - ESX.SavePlayer(xPlayer, cb) + ESX.SavePlayer(xPlayer, cb2) end) end From d143cbfaa3581039a6b3b3215df00506da0d6345 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 14 Apr 2020 10:57:09 +0200 Subject: [PATCH 2674/3224] Update en_esx_jobs.sql --- localization/en_esx_jobs.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/localization/en_esx_jobs.sql b/localization/en_esx_jobs.sql index 43fa050e..81bb5347 100644 --- a/localization/en_esx_jobs.sql +++ b/localization/en_esx_jobs.sql @@ -24,7 +24,7 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ('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}') ; -INSERT INTO `items` (`name`, `label`, `limit`) VALUES +INSERT INTO `items` (`name`, `label`, `weight`) VALUES ('alive_chicken', 'Living chicken', 1), ('slaughtered_chicken', 'Slaughtered chicken', 1), ('packaged_chicken', 'Chicken fillet', 1), From 55627129756a5a2dcd3cd2038cb8faa765019ce2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 14 Apr 2020 13:08:10 +0200 Subject: [PATCH 2675/3224] =?UTF-8?q?=E2=9A=A0=EF=B8=8F=E2=9A=A0=EF=B8=8FB?= =?UTF-8?q?REAKING=20COMMIT=E2=9A=A0=EF=B8=8F=E2=9A=A0=EF=B8=8F:=20Merged?= =?UTF-8?q?=20dupe=20client=20functions=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This changes arguments on the following functions: - ESX.Game.GetClosestObject() - ESX.Game.GetPeds(), no more arg for ignoreList - ESX.Game.GetClosestPed(), no longer a ignore list, instead a whitelist --- client/entityiter.lua | 6 +- client/functions.lua | 201 +++++------------------------------------- 2 files changed, 26 insertions(+), 181 deletions(-) diff --git a/client/entityiter.lua b/client/entityiter.lua index 20dd2018..c2e87406 100644 --- a/client/entityiter.lua +++ b/client/entityiter.lua @@ -45,11 +45,11 @@ local function EnumerateEntities(initFunc, moveFunc, disposeFunc) local enum = {handle = iter, destructor = disposeFunc} setmetatable(enum, entityEnumerator) - local next = true + repeat - coroutine.yield(id) - next, id = moveFunc(iter) + coroutine.yield(id) + next, id = moveFunc(iter) until not next enum.destructor, enum.handle = nil, nil diff --git a/client/functions.lua b/client/functions.lua index 177bf7f5..814a8c39 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -427,63 +427,9 @@ ESX.Game.IsVehicleEmpty = function(vehicle) return passengers == 0 and driverSeatFree end -ESX.Game.GetObjects = function() - local objects = {} - - for object in EnumerateObjects() do - table.insert(objects, object) - end - - return objects -end - -ESX.Game.GetClosestObject = function(filter, coords) - local objects = ESX.Game.GetObjects() - local closestDistance, closestObject = -1, -1 - local filter, coords = filter, coords - - if type(filter) == 'string' then - if filter ~= '' then - filter = {filter} - end - end - - if coords then - coords = vector3(coords.x, coords.y, coords.z) - else - local playerPed = PlayerPedId() - coords = GetEntityCoords(playerPed) - end - - for i=1, #objects, 1 do - local foundObject = false - - if filter == nil or (type(filter) == 'table' and #filter == 0) then - foundObject = true - else - local objectModel = GetEntityModel(objects[i]) - - for j=1, #filter, 1 do - if objectModel == GetHashKey(filter[j]) then - foundObject = true - break - end - end - end - - if foundObject then - local objectCoords = GetEntityCoords(objects[i]) - local distance = #(objectCoords - coords) - - if closestDistance == -1 or closestDistance > distance then - closestObject = objects[i] - closestDistance = distance - end - end - end - - return closestObject, closestDistance -end +ESX.Game.GetObjects = function() return EnumerateObjects() end +ESX.Game.GetPeds = function() return EnumeratePeds() end +ESX.Game.GetVehicles = function() return EnumerateVehicles() end ESX.Game.GetPlayers = function() local players = {} @@ -499,64 +445,16 @@ ESX.Game.GetPlayers = function() return players end -ESX.Game.GetClosestPlayer = function(coords) - local players, closestDistance, closestPlayer = ESX.Game.GetPlayers(), -1, -1 - local coords, usePlayerPed = coords, false - local playerPed, playerId = PlayerPedId(), PlayerId() +ESX.Game.GetClosestObject = function(coords, modelFilter) return ESX.Game.GetClosestEntity(EnumerateObjects(), coords, modelFilter) end +ESX.Game.GetClosestPed = function(coords, modelFilter) return ESX.Game.GetClosestEntity(EnumeratePeds(), coords, modelFilter) end +ESX.Game.GetClosestPlayer = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetPlayers(), coords, modelFilter) end +ESX.Game.GetClosestVehicle = function(coords, modelFilter) return ESX.Game.GetClosestEntity(EnumerateVehicles(), coords, modelFilter) end +ESX.Game.GetPlayersInArea = function(coords, area) return enumerateInArea(ESX.Game.GetPlayers(), coords, area) end +ESX.Game.GetVehiclesInArea = function(coords, area) return enumerateInArea(ESX.Game.GetVehicles(), coords, area) end +ESX.Game.IsSpawnPointClear = function(coords, radius) return #ESX.Game.GetVehiclesInArea(coords, radius) == 0 end - if coords then - coords = vector3(coords.x, coords.y, coords.z) - else - usePlayerPed = true - coords = GetEntityCoords(playerPed) - end - - for i=1, #players, 1 do - local target = GetPlayerPed(players[i]) - - if not usePlayerPed or (usePlayerPed and players[i] ~= playerId) then - local targetCoords = GetEntityCoords(target) - local distance = #(coords - targetCoords) - - if closestDistance == -1 or closestDistance > distance then - closestPlayer = players[i] - closestDistance = distance - end - end - end - - return closestPlayer, closestDistance -end - -ESX.Game.GetPlayersInArea = function(coords, area) - local players, playersInArea = ESX.Game.GetPlayers(), {} - coords = vector3(coords.x, coords.y, coords.z) - - for i=1, #players, 1 do - local target = GetPlayerPed(players[i]) - local targetCoords = GetEntityCoords(target) - - if #(coords - targetCoords) <= area then - table.insert(playersInArea, players[i]) - end - end - - return playersInArea -end - -ESX.Game.GetVehicles = function() - local vehicles = {} - - for vehicle in EnumerateVehicles() do - table.insert(vehicles, vehicle) - end - - return vehicles -end - -ESX.Game.GetClosestVehicle = function(coords) - local vehicles = ESX.Game.GetVehicles() - local closestDistance, closestVehicle, coords = -1, -1, coords +ESX.Game.GetClosestEntity = function(entities, coords, modelFilter) + local closestEntity, closestEntityDistance, filteredEntities = -1, -1, nil if coords then coords = vector3(coords.x, coords.y, coords.z) @@ -565,32 +463,25 @@ ESX.Game.GetClosestVehicle = function(coords) coords = GetEntityCoords(playerPed) end - for i=1, #vehicles, 1 do - local vehicleCoords = GetEntityCoords(vehicles[i]) - local distance = #(coords - vehicleCoords) + if modelFilter then + filteredEntities = {} - if closestDistance == -1 or closestDistance > distance then - closestVehicle, closestDistance = vehicles[i], distance + for k,entity in ipairs(entities) do + if modelFilter[GetEntityModel(entity)] then + table.insert(filteredEntities, entity) + end end end - return closestVehicle, closestDistance -end + for k,entity in ipairs(filteredEntities or entities) do + local distance = #(coords - GetEntityCoords(entity)) -ESX.Game.GetVehiclesInArea = function(coords, area) - local vehicles = ESX.Game.GetVehicles() - local vehiclesInArea = {} - - for i=1, #vehicles, 1 do - local vehicleCoords = GetEntityCoords(vehicles[i]) - local distance = GetDistanceBetweenCoords(vehicleCoords, coords.x, coords.y, coords.z, true) - - if distance <= area then - table.insert(vehiclesInArea, vehicles[i]) + if closestEntityDistance == -1 or distance < closestEntityDistance then + closestEntity, closestEntityDistance = entity, distance end end - return vehiclesInArea + return closestEntity, closestEntityDistance end ESX.Game.GetVehicleInDirection = function() @@ -607,52 +498,6 @@ ESX.Game.GetVehicleInDirection = function() return nil end -ESX.Game.IsSpawnPointClear = function(coords, radius) - local vehicles = ESX.Game.GetVehiclesInArea(coords, radius) - - return #vehicles == 0 -end - -ESX.Game.GetPeds = function(ignoreList) - local ignoreList = ignoreList or {} - local peds = {} - - for ped in EnumeratePeds() do - local found = false - - for j=1, #ignoreList, 1 do - if ignoreList[j] == ped then - found = true - end - end - - if not found then - table.insert(peds, ped) - end - end - - return peds -end - -ESX.Game.GetClosestPed = function(coords, ignoreList) - local ignoreList = ignoreList or {} - local peds = ESX.Game.GetPeds(ignoreList) - local closestDistance = -1 - local closestPed = -1 - - for i=1, #peds, 1 do - local pedCoords = GetEntityCoords(peds[i]) - local distance = GetDistanceBetweenCoords(pedCoords, coords.x, coords.y, coords.z, true) - - if closestDistance == -1 or closestDistance > distance then - closestPed = peds[i] - closestDistance = distance - end - end - - return closestPed, closestDistance -end - ESX.Game.GetVehicleProperties = function(vehicle) if DoesEntityExist(vehicle) then local colorPrimary, colorSecondary = GetVehicleColours(vehicle) From cf7f6b14f41ec4609e320df9fe8deacc9fd2abe6 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 14 Apr 2020 13:25:45 +0200 Subject: [PATCH 2676/3224] Finished new code, closes #249 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lén --- client/entityiter.lua | 21 +++++++++++++++++++++ client/functions.lua | 6 +++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/client/entityiter.lua b/client/entityiter.lua index c2e87406..11a23b8f 100644 --- a/client/entityiter.lua +++ b/client/entityiter.lua @@ -57,6 +57,27 @@ local function EnumerateEntities(initFunc, moveFunc, disposeFunc) end) end +function EnumerateEntitiesWithinDistance(entities, coords, maxDistance) + local nearbyEntities = {} + + if coords then + coords = vector3(coords.x, coords.y, coords.z) + else + local playerPed = PlayerPedId() + coords = GetEntityCoords(playerPed) + end + + for k,entity in ipairs(entities) do + local distance = #(coords - GetEntityCoords(entity)) + + if distance <= maxDistance then + table.insert(nearbyEntities, entity) + end + end + + return nearbyEntities +end + function EnumerateObjects() return EnumerateEntities(FindFirstObject, FindNextObject, EndFindObject) end diff --git a/client/functions.lua b/client/functions.lua index 814a8c39..60f497a4 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -449,9 +449,9 @@ ESX.Game.GetClosestObject = function(coords, modelFilter) return ESX.Game.GetClo ESX.Game.GetClosestPed = function(coords, modelFilter) return ESX.Game.GetClosestEntity(EnumeratePeds(), coords, modelFilter) end ESX.Game.GetClosestPlayer = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetPlayers(), coords, modelFilter) end ESX.Game.GetClosestVehicle = function(coords, modelFilter) return ESX.Game.GetClosestEntity(EnumerateVehicles(), coords, modelFilter) end -ESX.Game.GetPlayersInArea = function(coords, area) return enumerateInArea(ESX.Game.GetPlayers(), coords, area) end -ESX.Game.GetVehiclesInArea = function(coords, area) return enumerateInArea(ESX.Game.GetVehicles(), coords, area) end -ESX.Game.IsSpawnPointClear = function(coords, radius) return #ESX.Game.GetVehiclesInArea(coords, radius) == 0 end +ESX.Game.GetPlayersInArea = function(coords, maxDistance) return EnumerateEntitiesWithinDistance(ESX.Game.GetPlayers(), coords, maxDistance) end +ESX.Game.GetVehiclesInArea = function(coords, maxDistance) return EnumerateEntitiesWithinDistance(EnumerateVehicles(), coords, maxDistance) end +ESX.Game.IsSpawnPointClear = function(coords, maxDistance) return #ESX.Game.GetVehiclesInArea(coords, maxDistance) == 0 end ESX.Game.GetClosestEntity = function(entities, coords, modelFilter) local closestEntity, closestEntityDistance, filteredEntities = -1, -1, nil From 6a0f3ca45267b71c84787f3b844d88f2de570c89 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 14 Apr 2020 13:58:40 +0200 Subject: [PATCH 2677/3224] Fixed untested new code :/ --- client/functions.lua | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 60f497a4..e3b1e7ad 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -427,9 +427,35 @@ ESX.Game.IsVehicleEmpty = function(vehicle) return passengers == 0 and driverSeatFree end -ESX.Game.GetObjects = function() return EnumerateObjects() end -ESX.Game.GetPeds = function() return EnumeratePeds() end -ESX.Game.GetVehicles = function() return EnumerateVehicles() end +ESX.Game.GetObjects = function() + local objects = {} + + for object,v in EnumerateObjects() do + table.insert(objects, object) + end + + return objects +end + +ESX.Game.GetPeds = function() + local peds = {} + + for ped,v in EnumeratePeds() do + table.insert(peds, ped) + end + + return peds +end + +ESX.Game.GetVehicles = function() + local vehicles = {} + + for vehicle,v in EnumerateVehicles() do + table.insert(vehicles, vehicle) + end + + return vehicles +end ESX.Game.GetPlayers = function() local players = {} @@ -445,12 +471,12 @@ ESX.Game.GetPlayers = function() return players end -ESX.Game.GetClosestObject = function(coords, modelFilter) return ESX.Game.GetClosestEntity(EnumerateObjects(), coords, modelFilter) end -ESX.Game.GetClosestPed = function(coords, modelFilter) return ESX.Game.GetClosestEntity(EnumeratePeds(), coords, modelFilter) end +ESX.Game.GetClosestObject = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetObjects(), coords, modelFilter) end +ESX.Game.GetClosestPed = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetPeds(), coords, modelFilter) end ESX.Game.GetClosestPlayer = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetPlayers(), coords, modelFilter) end -ESX.Game.GetClosestVehicle = function(coords, modelFilter) return ESX.Game.GetClosestEntity(EnumerateVehicles(), coords, modelFilter) end +ESX.Game.GetClosestVehicle = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetVehicles(), coords, modelFilter) end ESX.Game.GetPlayersInArea = function(coords, maxDistance) return EnumerateEntitiesWithinDistance(ESX.Game.GetPlayers(), coords, maxDistance) end -ESX.Game.GetVehiclesInArea = function(coords, maxDistance) return EnumerateEntitiesWithinDistance(EnumerateVehicles(), coords, maxDistance) end +ESX.Game.GetVehiclesInArea = function(coords, maxDistance) return EnumerateEntitiesWithinDistance(ESX.Game.GetVehicles(), coords, maxDistance) end ESX.Game.IsSpawnPointClear = function(coords, maxDistance) return #ESX.Game.GetVehiclesInArea(coords, maxDistance) == 0 end ESX.Game.GetClosestEntity = function(entities, coords, modelFilter) From 5f9fc94c4d429712370960655005d877c7da6358 Mon Sep 17 00:00:00 2001 From: SW1FT Date: Tue, 14 Apr 2020 13:58:34 +0100 Subject: [PATCH 2678/3224] Fixed English locale typos (#659) * Minor en locale changes * Forgot this one --- locales/en.lua | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/locales/en.lua b/locales/en.lua index 7dea0545..515b0f50 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -15,13 +15,13 @@ Locales['en'] = { ['gave_weapon'] = 'you gave ~b~%s~s~ to ~y~%s~s~', ['gave_weapon_ammo'] = 'you gave ~o~%sx %s~s~ for ~b~%s~s~ to ~y~%s~s~', ['gave_weapon_withammo'] = 'you gave ~b~%s~s~ with ~o~%sx %s~s~ to ~y~%s~s~', - ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', + ['gave_weapon_hasalready'] = '~y~%s~s~ already has a ~y~%s~s~', ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', ['received_weapon'] = 'you received ~b~%s~s~ from ~b~%s~s~', ['received_weapon_ammo'] = 'you received ~o~%sx %s~s~ for your ~b~%s~s~ from ~b~%s~s~', ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx %s~s~ from ~b~%s~s~', - ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', - ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you a ~y~%s~s~, but you already have one', + ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for a ~y~%s~s~, but you dont have one', ['gave_account_money'] = 'you gave ~g~$%s~s~ (%s) to ~y~%s~s~', ['received_account_money'] = 'you received ~g~$%s~s~ (%s) from ~b~%s~s~', ['amount_invalid'] = 'invalid amount', @@ -42,7 +42,7 @@ Locales['en'] = { -- Salary related ['received_salary'] = 'you received your salary: ~g~$%s~s~', - ['received_help'] = 'you recieved your welfare check: ~g~$%s~s~', + ['received_help'] = 'you received your welfare check: ~g~$%s~s~', ['company_nomoney'] = 'the company you\'re employeed at is too poor to pay out your salary', ['received_paycheck'] = 'received paycheck', ['bank'] = 'maze Bank', @@ -51,10 +51,10 @@ Locales['en'] = { ['account_money'] = 'cash', ['act_imp'] = 'action impossible', - ['in_vehicle'] = 'you can\'t give anything to someone in a vehicle', + ['in_vehicle'] = 'you cannot give anything to someone in a vehicle', -- Commands - ['command_car'] = 'spawn an vehicle', + ['command_car'] = 'spawn a vehicle', ['command_car_car'] = 'vehicle spawn name or hash', ['command_cardel'] = 'delete vehicle in proximity', ['command_cardel_radius'] = 'optional, delete every vehicle within the specified radius', @@ -96,8 +96,8 @@ Locales['en'] = { ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', ['commanderror_invaliditem'] = 'invalid item name', ['commanderror_invalidweapon'] = 'invalid weapon', - ['commanderror_console'] = 'that command can not be run from console', - ['commanderror_invalidcommand'] = '^3%s^0 is not an valid command!', + ['commanderror_console'] = 'that command cannot be run from console', + ['commanderror_invalidcommand'] = '^3%s^0 is not a valid command!', ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', ['commandgeneric_playerid'] = 'player id', From 1f53d642aa5867fd7762e1c98454d616e2a66f6a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 14 Apr 2020 16:36:50 +0200 Subject: [PATCH 2679/3224] Use NUI chunking (it has performance issues) --- client/main.lua | 74 ++++++------------- fxmanifest.lua | 5 +- html/css/app.css | 2 +- html/js/app.js | 41 +++++------ html/js/app_en.js | 179 ---------------------------------------------- html/js/app_pl.js | 179 ---------------------------------------------- html/ui.html | 25 ++++--- 7 files changed, 59 insertions(+), 446 deletions(-) delete mode 100644 html/js/app_en.js delete mode 100644 html/js/app_pl.js diff --git a/client/main.lua b/client/main.lua index 36eee6b4..447ca4c3 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,11 +1,6 @@ Citizen.CreateThread(function() - -- internal variables - ESX = nil - local Timeouts = {} - local GUI = {} - GUI.Time = 0 - local MenuType = 'dialog' - local OpenedMenus = {} + ESX = nil + local Timeouts, OpenedMenus, MenuType = {}, {}, 'dialog' while ESX == nil do TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) @@ -20,10 +15,10 @@ Citizen.CreateThread(function() OpenedMenus[namespace .. '_' .. name] = true SendNUIMessage({ - action = 'openMenu', + action = 'openMenu', namespace = namespace, - name = name, - data = data + name = name, + data = data }) local timeoutId = ESX.SetTimeout(200, function() @@ -35,22 +30,15 @@ Citizen.CreateThread(function() local closeMenu = function(namespace, name) OpenedMenus[namespace .. '_' .. name] = nil - local OpenedMenuCount = 0 SendNUIMessage({ - action = 'closeMenu', + action = 'closeMenu', namespace = namespace, - name = name, - data = data + name = name, + data = data }) - for k,v in pairs(OpenedMenus) do - if v == true then - OpenedMenuCount = OpenedMenuCount + 1 - end - end - - if OpenedMenuCount == 0 then + if ESX.Table.SizeOf(OpenedMenus) == 0 then SetNuiFocus(false) end @@ -58,69 +46,53 @@ Citizen.CreateThread(function() ESX.UI.Menu.RegisterType(MenuType, openMenu, closeMenu) - RegisterNUICallback('menu_submit', function(data, cb) + AddEventHandler('esx_menu_dialog:message:menu_submit', function(data) local menu = ESX.UI.Menu.GetOpened(MenuType, data._namespace, data._name) - local post = true + local cancel = false - if menu.submit ~= nil then - - -- Is the submitted data a number? - if tonumber(data.value) ~= nil then - - -- Round float values + 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 + -- check for negative value if tonumber(data.value) <= 0 then - post = false + cancel = true end end data.value = ESX.Math.Trim(data.value) - -- Don't post if the value is negative or if it's 0 - if post then - menu.submit(data, menu) + -- don't submit if the value is negative or if it's 0 + if cancel then + ESX.ShowNotification('That input is not allowed!') else - ESX.ShowNotification('That input is invalid!') + menu.submit(data, menu) end end - - cb('OK') end) - RegisterNUICallback('menu_cancel', function(data, cb) + 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 - - cb('OK') end) - RegisterNUICallback('menu_change', function(data, cb) + 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 - - cb('OK') end) Citizen.CreateThread(function() while true do Citizen.Wait(10) - local OpenedMenuCount = 0 - for k,v in pairs(OpenedMenus) do - if v == true then - OpenedMenuCount = OpenedMenuCount + 1 - end - end - - if OpenedMenuCount > 0 then + if ESX.Table.SizeOf(OpenedMenus) > 0 then DisableControlAction(0, 1, true) -- LookLeftRight DisableControlAction(0, 2, true) -- LookUpDown DisableControlAction(0, 142, true) -- MeleeAttackAlternate diff --git a/fxmanifest.lua b/fxmanifest.lua index 0f112e25..f5dc6573 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -6,7 +6,10 @@ description 'ESX Menu Dialog' version '1.1.0' -client_script 'client/main.lua' +client_scripts { + '@es_extended/client/wrapper.lua', + 'client/main.lua' +} ui_page 'html/ui.html' diff --git a/html/css/app.css b/html/css/app.css index 459d3c37..e8f361b5 100644 --- a/html/css/app.css +++ b/html/css/app.css @@ -71,4 +71,4 @@ .dialog button[name="cancel"] { width: 25%; height: 32px; -} \ No newline at end of file +} diff --git a/html/js/app.js b/html/js/app.js index 4988e11f..85a172b6 100644 --- a/html/js/app.js +++ b/html/js/app.js @@ -1,24 +1,22 @@ (function () { - let MenuTpl = '
    -
    Home
    +
    Phone
    From d5721f363599940ff87e3efb49a34fcba21a69aa Mon Sep 17 00:00:00 2001 From: Charly Date: Mon, 21 Aug 2017 10:12:30 +0200 Subject: [PATCH 0501/3224] Correction texte --- locales/fr.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/fr.lua b/locales/fr.lua index e182eb55..eeddacb2 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -21,7 +21,7 @@ Locales['fr'] = { ['inv_full_meth'] = 'vous ne pouvez plus ramasser de Meth, votre inventaire est ~r~plein~s~', ['not_enough_meth'] = 'vous n\'avez pas assez de Meth à ~r~conditionner~s~', ['sold_one_meth'] = 'vous avez vendu ~g~x1 Pochon de meth~s~', - ['inv_full_weed'] = 'vous ne pouvez plus ramasser de weed, votre inventair est ~r~plein~s~', + ['inv_full_weed'] = 'vous ne pouvez plus ramasser de weed, votre inventaire est ~r~plein~s~', ['not_enough_weed'] = 'vous n\'avez pas assez de weed à ~r~conditionner~s~', ['sold_one_weed'] = 'vous avez vendu ~g~x1 Pochon de weed~s~', ['used_one_weed'] = 'Vous avez utilisé 1 Pochon de ~b~weed', From 0ef34c549139a5ef9b9447f903dc9507d2a013fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 21 Aug 2017 12:04:03 +0200 Subject: [PATCH 0502/3224] Add object pickups when dropping + add /spawnobject admin command --- .../es_extended/client/functions.lua | 5 + .../[essential]/es_extended/client/main.lua | 93 ++++++++++++++++++- .../[essential]/es_extended/locales/br.lua | 1 + .../[essential]/es_extended/locales/en.lua | 1 + .../[essential]/es_extended/locales/fr.lua | 1 + .../es_extended/server/commands.lua | 6 ++ .../[essential]/es_extended/server/common.lua | 2 + .../es_extended/server/functions.lua | 16 ++++ .../[essential]/es_extended/server/main.lua | 21 +++++ 9 files changed, 145 insertions(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 1ae278af..4e215f1d 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -320,6 +320,11 @@ ESX.Game.DeleteVehicle = function(vehicle) DeleteVehicle(vehicle) end +ESX.Game.DeleteObject = function(object) + SetEntityAsMissionEntity(object, false, true) + DeleteObject(object) +end + ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index d0266595..1d9ffa1e 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -16,6 +16,7 @@ local PlayerLoaded = false local LoadoutLoaded = false local IsPaused = false local LastLoadout = {} +local Pickups = {} RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) @@ -249,7 +250,65 @@ AddEventHandler('esx:spawnVehicle', function(model) end) --- Pickup Weapon +RegisterNetEvent('esx:spawnObject') +AddEventHandler('esx:spawnObject', function(model) + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + local forward = GetEntityForwardVector(playerPed) + local x, y, z = table.unpack(coords + forward * 1.0) + + ESX.Game.SpawnObject(model, { + x = x, + y = y, + z = z + }, function(obj) + SetEntityHeading(obj, GetEntityHeading(playerPed)) + PlaceObjectOnGroundProperly(obj) + end) + +end) + +RegisterNetEvent('esx:pickup') +AddEventHandler('esx:pickup', function(id, label) + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + local forward = GetEntityForwardVector(playerPed) + local x, y, z = table.unpack(coords + forward * -2.0) + + ESX.Game.SpawnLocalObject('prop_money_bag_01', { + x = x, + y = y, + z = z - 2.0, + }, function(obj) + + SetEntityAsMissionEntity(obj, true, false) + + PlaceObjectOnGroundProperly(obj) + + Pickups[id] = { + id = id, + obj = obj, + label = label, + inRange = false, + coords = { + x = x, + y = y, + z = z + }, + } + + end) + +end) + +RegisterNetEvent('esx:removePickup') +AddEventHandler('esx:removePickup', function(id) + ESX.Game.DeleteObject(Pickups[id].obj) + Pickups[id] = nil +end) + RegisterNetEvent('esx:pickupWeapon') AddEventHandler('esx:pickupWeapon', function(weaponPickup, weaponName) @@ -386,3 +445,35 @@ if Config.DisableWantedLevel then end +-- Pickups +Citizen.CreateThread(function() + while true do + + Citizen.Wait(0) + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + for k,v in pairs(Pickups) do + + local distance = GetDistanceBetweenCoords(coords.x, coords.y, coords.z, v.coords.x, v.coords.y, v.coords.z, true) + + if distance <= 5.0 then + + ESX.Game.Utils.DrawText3D({ + x = v.coords.x, + y = v.coords.y, + z = v.coords.z + 0.25 + }, v.label) + + end + + if distance <= 1.0 and not v.inRange then + TriggerServerEvent('esx:onPickup', v.id) + v.inRange = true + end + + end + + end +end) \ No newline at end of file diff --git a/resources/[essential]/es_extended/locales/br.lua b/resources/[essential]/es_extended/locales/br.lua index db4e39aa..cf47cb80 100644 --- a/resources/[essential]/es_extended/locales/br.lua +++ b/resources/[essential]/es_extended/locales/br.lua @@ -29,6 +29,7 @@ Locales['br'] = { ['play_emote'] = 'reproduzir emote', ['spawn_car'] = 'fazer aparecer um carro', ['spawn_car_param'] = 'nome do carro', + ['spawn_object'] = 'gerar um objeto', ['givemoney'] = 'dar dinheiro', ['money_amount'] = 'quantia do dinheiro', ['invalid_account'] = 'conta inválida', diff --git a/resources/[essential]/es_extended/locales/en.lua b/resources/[essential]/es_extended/locales/en.lua index 0a059de2..def2cc5e 100644 --- a/resources/[essential]/es_extended/locales/en.lua +++ b/resources/[essential]/es_extended/locales/en.lua @@ -29,6 +29,7 @@ Locales['en'] = { ['play_emote'] = 'play emote', ['spawn_car'] = 'spawn a car', ['spawn_car_param'] = 'name of car', + ['spawn_object'] = 'spawn object', ['givemoney'] = 'give money', ['money_amount'] = 'amount of money', ['invalid_account'] = 'invalid account', diff --git a/resources/[essential]/es_extended/locales/fr.lua b/resources/[essential]/es_extended/locales/fr.lua index e5af7b97..02bf1c10 100644 --- a/resources/[essential]/es_extended/locales/fr.lua +++ b/resources/[essential]/es_extended/locales/fr.lua @@ -29,6 +29,7 @@ Locales['fr'] = { ['play_emote'] = 'jouer emote', ['spawn_car'] = 'spawn un véhicule', ['spawn_car_param'] = 'nom de la voiture', + ['spawn_object'] = 'spawn un objet', ['givemoney'] = 'donner de l\'argent', ['money_amount'] = 'somme d\'argent', ['invalid_account'] = 'compete invalide', diff --git a/resources/[essential]/es_extended/server/commands.lua b/resources/[essential]/es_extended/server/commands.lua index 16def62e..e4102452 100644 --- a/resources/[essential]/es_extended/server/commands.lua +++ b/resources/[essential]/es_extended/server/commands.lua @@ -47,6 +47,12 @@ end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('spawn_car'), params = {{name = "car", help = _U('spawn_car_param')}}}) +TriggerEvent('es:addGroupCommand', 'spawnobject', 'admin', function(source, args, user) + TriggerClientEvent('esx:spawnObject', source, args[2]) +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end, {help = _U('spawn_object'), params = {{name = "name"}}}) + TriggerEvent('es:addGroupCommand', 'givemoney', 'admin', function(source, args, user) local _source = source diff --git a/resources/[essential]/es_extended/server/common.lua b/resources/[essential]/es_extended/server/common.lua index 5e6a1042..6676db37 100644 --- a/resources/[essential]/es_extended/server/common.lua +++ b/resources/[essential]/es_extended/server/common.lua @@ -4,6 +4,8 @@ ESX.UsableItemsCallbacks = {} ESX.Items = {} ESX.ServerCallbacks = {} ESX.LastPlayerData = {} +ESX.Pickups = {} +ESX.PickupId = 0 AddEventHandler('esx:getSharedObject', function(cb) cb(ESX) diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index 000402cf..45582314 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -223,3 +223,19 @@ ESX.GetWeaponLabel = function(name) end end + +ESX.CreatePickup = function(type, name, count, label) + + local pickupId = (ESX.PickupId == 65635 and 0 or ESX.PickupId + 1) + + ESX.Pickups[pickupId] = { + type = type, + name = name, + count = count + } + + TriggerClientEvent('esx:pickup', -1, pickupId, label) + + ESX.PickupId = pickupId + +end \ No newline at end of file diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index 23bab0e4..1a9134c3 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -404,6 +404,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if total > 0 then xPlayer.removeInventoryItem(itemName, total) + ESX.CreatePickup('item_standard', itemName, total, foundItem.label) TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' ' .. foundItem.label .. ' x' .. total) end @@ -438,6 +439,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if total > 0 then xPlayer.removeMoney(total) + ESX.CreatePickup('item_money', 'money', total, 'Cash') TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) end @@ -472,6 +474,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if total > 0 then xPlayer.removeAccountMoney(itemName, total) + ESX.CreatePickup('item_account', itemName, total, 'Cash') TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) end @@ -527,6 +530,24 @@ AddEventHandler('esx:useItem', function(itemName) end) +RegisterServerEvent('esx:onPickup') +AddEventHandler('esx:onPickup', function(id) + + local pickup = ESX.Pickups[id] + local xPlayer = ESX.GetPlayerFromId(source) + + if pickup.type == 'item_standard' then + xPlayer.addInventoryItem(pickup.name, pickup.count) + elseif pickup.type == 'item_money' then + xPlayer.addMoney(pickup.count) + elseif pickup.type == 'item_account' then + xPlayer.addAccountMoney(pickup.name, pickup.count) + end + + TriggerClientEvent('esx:removePickup', -1, id) + +end) + ESX.RegisterServerCallback('esx:getPlayerData', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) From 03dc3126f5dcad5cdbff43d1d68483d578e540ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 21 Aug 2017 13:25:55 +0200 Subject: [PATCH 0503/3224] Dont reload character inf sex don't changed --- client/main.lua | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/client/main.lua b/client/main.lua index 86194fc9..6f42bb3a 100644 --- a/client/main.lua +++ b/client/main.lua @@ -51,7 +51,7 @@ local Components = { {label = _U('bag_color'), name = 'bags_2', value = 0, min = 0, zoomOffset = 0.75, camOffset = 0.15, textureof = 'bags_1'} } -local LastSex = 0 +local LastSex = -1 local LoadSkin = nil local LoadClothes = nil local Character = {} @@ -299,12 +299,18 @@ end) RegisterNetEvent('skinchanger:loadSkin') AddEventHandler('skinchanger:loadSkin', function(skin) - LoadSkin = skin + if skin['sex'] ~= LastSex then + + LoadSkin = skin + + if skin['sex'] == 0 then + TriggerEvent('skinchanger:loadDefaultModel', true) + else + TriggerEvent('skinchanger:loadDefaultModel', false) + end - if skin['sex'] == 0 then - TriggerEvent('skinchanger:loadDefaultModel', true) else - TriggerEvent('skinchanger:loadDefaultModel', false) + ApplySkin(skin) end LastSex = skin['sex'] @@ -314,15 +320,21 @@ end) RegisterNetEvent('skinchanger:loadClothes') AddEventHandler('skinchanger:loadClothes', function(playerSkin, clothesSkin) - LoadClothes = { - playerSkin = playerSkin, - clothesSkin = clothesSkin - } + if playerSkin['sex'] ~= LastSex then + + LoadClothes = { + playerSkin = playerSkin, + clothesSkin = clothesSkin + } + + if playerSkin['sex'] == 0 then + TriggerEvent('skinchanger:loadDefaultModel', true) + else + TriggerEvent('skinchanger:loadDefaultModel', false) + end - if playerSkin['sex'] == 0 then - TriggerEvent('skinchanger:loadDefaultModel', true) else - TriggerEvent('skinchanger:loadDefaultModel', false) + ApplySkin(playerSkin, clothesSkin) end LastSex = playerSkin['sex'] From 93daeaaf456f3428b1b5fcc875c8a9c8c08d0100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 21 Aug 2017 13:38:27 +0200 Subject: [PATCH 0504/3224] Fix pickup spawn behind any player --- resources/[essential]/es_extended/client/main.lua | 10 +++++----- resources/[essential]/es_extended/server/functions.lua | 4 ++-- resources/[essential]/es_extended/server/main.lua | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index 1d9ffa1e..0fff86b3 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -270,12 +270,12 @@ AddEventHandler('esx:spawnObject', function(model) end) RegisterNetEvent('esx:pickup') -AddEventHandler('esx:pickup', function(id, label) +AddEventHandler('esx:pickup', function(id, label, coords) - local playerPed = GetPlayerPed(-1) - local coords = GetEntityCoords(playerPed) - local forward = GetEntityForwardVector(playerPed) - local x, y, z = table.unpack(coords + forward * -2.0) + local ped = GetPlayerPed(GetPlayerFromServerId(player)) + local coords = GetEntityCoords(ped) + local forward = GetEntityForwardVector(ped) + local x, y, z = table.unpack(coords + forward * -2.0) ESX.Game.SpawnLocalObject('prop_money_bag_01', { x = x, diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index 45582314..ae1bc2e7 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -224,7 +224,7 @@ ESX.GetWeaponLabel = function(name) end -ESX.CreatePickup = function(type, name, count, label) +ESX.CreatePickup = function(type, name, count, label, player) local pickupId = (ESX.PickupId == 65635 and 0 or ESX.PickupId + 1) @@ -234,7 +234,7 @@ ESX.CreatePickup = function(type, name, count, label) count = count } - TriggerClientEvent('esx:pickup', -1, pickupId, label) + TriggerClientEvent('esx:pickup', -1, pickupId, label, player) ESX.PickupId = pickupId diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index 1a9134c3..e634c744 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -404,7 +404,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if total > 0 then xPlayer.removeInventoryItem(itemName, total) - ESX.CreatePickup('item_standard', itemName, total, foundItem.label) + ESX.CreatePickup('item_standard', itemName, total, foundItem.label, _source) TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' ' .. foundItem.label .. ' x' .. total) end @@ -439,7 +439,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if total > 0 then xPlayer.removeMoney(total) - ESX.CreatePickup('item_money', 'money', total, 'Cash') + ESX.CreatePickup('item_money', 'money', total, 'Cash', _source) TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) end @@ -474,7 +474,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if total > 0 then xPlayer.removeAccountMoney(itemName, total) - ESX.CreatePickup('item_account', itemName, total, 'Cash') + ESX.CreatePickup('item_account', itemName, total, 'Cash', _source) TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) end From f48f9341027858043e74cb71affb40256c5c8a45 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Mon, 21 Aug 2017 09:26:32 -0400 Subject: [PATCH 0505/3224] Adds new timer --- client/main.lua | 132 ++++++++++++++++++++++++++++++++++++++++++++++-- config.lua | 4 ++ locales/br.lua | 8 +++ locales/en.lua | 8 +++ locales/fr.lua | 8 +++ server/main.lua | 47 +++++++++++++++-- 6 files changed, 198 insertions(+), 9 deletions(-) diff --git a/client/main.lua b/client/main.lua index cc574eb7..4347ba4e 100644 --- a/client/main.lua +++ b/client/main.lua @@ -118,12 +118,117 @@ function StartRespawnTimer() StopScreenEffect('DeathFailOut') DoScreenFadeIn(800) end) - end) end - end) +end +function RespawnTimer() + +local timer = Config.RespawnDelayAfterRPDeath +local allowRespawn = Config.RespawnDelayAfterRPDeath/2 +local enoughMoney = false +local money = 0 + + if IsDead and Config.ShowDeathTimer then + ESX.TriggerServerCallback('esx_ambulancejob:getBankMoney', function(money) + if money >= Config.EarlyRespawnFineAmount then + enoughMoney = true + else + enoughMoney = false + end + end) + Citizen.CreateThread(function() + + while timer > 0 and IsDead do + raw_seconds = timer/1000 + raw_minutes = raw_seconds/60 + minutes = stringsplit(raw_minutes, ".")[1] + seconds = stringsplit(raw_seconds-(minutes*60), ".")[1] + + if Config.EarlyRespawn and Config.EarlyRespawnFine and enoughMoney then + SetTextFont(4) + SetTextProportional(0) + SetTextScale(0.0, 0.5) + SetTextColour(255, 255, 255, 255) + SetTextDropshadow(0, 0, 0, 0, 255) + SetTextEdge(1, 0, 0, 0, 255) + SetTextDropShadow() + SetTextOutline() + SetTextEntry("STRING") + AddTextComponentString(_U('please_wait') .. minutes .. _U('minutes') .. seconds .. _U('seconds_fine') .. Config.EarlyRespawnFineAmount .. _U('press_respawn_fine')) + SetTextCentre(true) + DrawText(0.5, 0.8) + timer = timer - 15 + Citizen.Wait(0) + if IsControlPressed(0, Keys['E']) then + DoScreenFadeOut(800) + + while not IsScreenFadedOut() do + Citizen.Wait(0) + end + + ESX.TriggerServerCallback('esx_ambulancejob:removeItemsAfterRPDeathRemoveMoney', function() + + TriggerServerEvent('esx_ambulancejob:removeAccountMoney', source) + TriggerServerEvent('esx:updateLastPosition', Config.Zones.HospitalInteriorInside1.Pos) + + RespawnPed(GetPlayerPed(-1), Config.Zones.HospitalInteriorInside1.Pos) + StopScreenEffect('DeathFailOut') + DoScreenFadeIn(800) + end) + end + else + SetTextFont(4) + SetTextProportional(0) + SetTextScale(0.0, 0.5) + SetTextColour(255, 255, 255, 255) + SetTextDropshadow(0, 0, 0, 0, 255) + SetTextEdge(1, 0, 0, 0, 255) + SetTextDropShadow() + SetTextOutline() + SetTextEntry("STRING") + AddTextComponentString(_U('please_wait') .. minutes .. _U('minutes') .. seconds .. _U('seconds')) + SetTextCentre(true) + DrawText(0.5, 0.8) + timer = timer - 15 + Citizen.Wait(0) + end + end + + while timer <= 0 and IsDead do + SetTextFont(4) + SetTextProportional(0) + SetTextScale(0.0, 0.5) + SetTextColour(255, 255, 255, 255) + SetTextDropshadow(0, 0, 0, 0, 255) + SetTextEdge(1, 0, 0, 0, 255) + SetTextDropShadow() + SetTextOutline() + SetTextEntry("STRING") + AddTextComponentString(_U('press_respawn')) + SetTextCentre(true) + DrawText(0.5, 0.8) + Citizen.Wait(0) + if IsControlPressed(0, Keys['E']) then + DoScreenFadeOut(800) + + while not IsScreenFadedOut() do + Citizen.Wait(0) + end + + ESX.TriggerServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function() + + TriggerServerEvent('esx:updateLastPosition', Config.Zones.HospitalInteriorInside1.Pos) + + RespawnPed(GetPlayerPed(-1), Config.Zones.HospitalInteriorInside1.Pos) + --StopScreenEffect('DeathFailOut') + DoScreenFadeIn(800) + end) + end + end + end) + end end function TeleportFadeEffect(entity, coords) @@ -531,10 +636,14 @@ AddEventHandler('esx_ambulancejob:onPlayerDeath', function() IsDead = true - StartRespawnTimer() - StartRespawnToHospitalMenuTimer() + if Config.ShowDeathTimer == true then + RespawnTimer() + else + StartRespawnTimer() + StartRespawnToHospitalMenuTimer() + StartScreenEffect('DeathFailOut', 0, false) + end - StartScreenEffect('DeathFailOut', 0, false) end) RegisterNetEvent('esx_ambulancejob:revive') @@ -745,3 +854,16 @@ Citizen.CreateThread(function() EnableMpDlcMaps(true) RequestIpl('Coroner_Int_on') -- Morgue end) + +-- String string +function stringsplit(inputstr, sep) + if sep == nil then + sep = "%s" + end + local t={} ; i=1 + for str in string.gmatch(inputstr, "([^"..sep.."]+)") do + t[i] = str + i = i + 1 + end + return t +end diff --git a/config.lua b/config.lua index 8e1b8a90..f795fc7c 100644 --- a/config.lua +++ b/config.lua @@ -7,6 +7,10 @@ Config.RemoveWeaponsAfterRPDeath = true Config.RemoveCashAfterRPDeath = true Config.RemoveItemsAfterRPDeath = true Config.EnablePlayerManagement = false +Config.ShowDeathTimer = true +Config.EarlyRespawn = true +Config.EarlyRespawnFine = true +Config.EarlyRespawnFineAmount = 500 Config.Locale = 'fr' Config.Zones = { diff --git a/locales/br.lua b/locales/br.lua index a56396c1..494baed3 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -35,4 +35,12 @@ Locales['br'] = { -- Death ['respawn_at_hospital'] = 'você quer ser transportado para o hospital?', ['yes'] = 'sim', + ['please_wait'] = 'por favor, espere ~b~', + ['minutes'] = ' minutos ', + ['seconds_fine'] = ' segundos ~w~para respawn | Respawn agora para ~g~$', + ['seconds'] = ' segundos ~w~para respawn.', + ['press_respawn_fine'] = '~w~ [Pressione ~b~E~w~]', + ['press_respawn'] = 'pressione [~b~E~w~] para respawn.', + -- Revive + ['revive_help'] = 'reviver um jogador', } diff --git a/locales/en.lua b/locales/en.lua index fa8ddfce..4c86edfc 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -35,4 +35,12 @@ Locales['en'] = { -- Death ['respawn_at_hospital'] = 'do you want to be transported to the hospital?', ['yes'] = 'yes', + ['please_wait'] = 'please wait ~b~', + ['minutes'] = ' minutes ', + ['seconds_fine'] = ' seconds ~w~to respawn | Respawn now for ~g~$', + ['seconds'] = ' seconds ~w~to respawn.', + ['press_respawn_fine'] = '~w~ [Press ~b~E~w~]', + ['press_respawn'] = 'press [~b~E~w~] to respawn.', + -- Revive + ['revive_help'] = 'revive a player', } diff --git a/locales/fr.lua b/locales/fr.lua index c276c069..877b06e2 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -35,4 +35,12 @@ Locales['fr'] = { -- Death ['respawn_at_hospital'] = 'voulez-vous être transporté à l\'hôpital ?', ['yes'] = 'oui', + ['please_wait'] = 's\'il vous plaît, attendez ~b~', + ['minutes'] = ' minutes ', + ['seconds_fine'] = ' secondes ~w~to réapparaître | Réapparaître maintenant pour ~g~$', + ['seconds'] = ' secondes ~w~pour réapparaître.', + ['press_respawn_fine'] = '~w~ [Presse ~b~E~w~]', + ['press_respawn'] = 'appuyez [~b~E~w~] sur pour réapparaître.', + -- Revive + ['revive_help'] = 'relancer un joueur', } diff --git a/server/main.lua b/server/main.lua index 7b9b4870..296d8bd7 100644 --- a/server/main.lua +++ b/server/main.lua @@ -34,6 +34,45 @@ ESX.RegisterServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function( end) +ESX.RegisterServerCallback('esx_ambulancejob:removeItemsAfterRPDeathRemoveMoney', function(source, cb) + + local xPlayer = ESX.GetPlayerFromId(source) + + if Config.RemoveCashAfterRPDeath then + xPlayer.set('money', 0) + xPlayer.setAccountMoney('black_money', 0) + end + + if Config.EarlyRespawn and Config.EarlyRespawnFine then + xPlayer.removeAccountMoney('bank', Config.EarlyRespawnFineAmount) + end + + if Config.RemoveItemsAfterRPDeath then + for i=1, #xPlayer.inventory, 1 do + if xPlayer.inventory[i].count > 0 then + xPlayer.setInventoryItem(xPlayer.inventory[i].name, 0) + end + end + end + + if Config.RemoveWeaponsAfterRPDeath then + for i=1, #xPlayer.loadout, 1 do + xPlayer.removeWeapon(xPlayer.loadout[i].name) + end + end + + cb() + +end) + +ESX.RegisterServerCallback('esx_ambulancejob:getBankMoney', function(source, cb) + + local xPlayer = ESX.GetPlayerFromId(source) + local money = xPlayer.getAccount('bank').money + + cb(money) +end) + TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) local xPlayer = ESX.GetPlayerFromId(source) @@ -48,11 +87,11 @@ TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message end end end - + end) -TriggerEvent('es:addGroupCommand', 'respawn', 'admin', function(source, args, user) - +TriggerEvent('es:addGroupCommand', 'revive', 'admin', function(source, args, user) + if args[2] ~= nil then TriggerClientEvent('esx_ambulancejob:revive', tonumber(args[2])) else @@ -61,4 +100,4 @@ TriggerEvent('es:addGroupCommand', 'respawn', 'admin', function(source, args, us end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end, {help = 'Respawn', params = {{name = 'id'}}}) \ No newline at end of file +end, {help = _U('revive_help'), params = {{name = 'id'}}}) From c8a62f18abdee9041354a83ad868d1d4a5040c62 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Mon, 21 Aug 2017 12:21:56 -0400 Subject: [PATCH 0506/3224] Adds new line to text. --- locales/br.lua | 2 +- locales/en.lua | 2 +- locales/fr.lua | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index 494baed3..07949889 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -37,7 +37,7 @@ Locales['br'] = { ['yes'] = 'sim', ['please_wait'] = 'por favor, espere ~b~', ['minutes'] = ' minutos ', - ['seconds_fine'] = ' segundos ~w~para respawn | Respawn agora para ~g~$', + ['seconds_fine'] = ' segundos ~w~para respawn \nRespawn agora para ~g~$', ['seconds'] = ' segundos ~w~para respawn.', ['press_respawn_fine'] = '~w~ [Pressione ~b~E~w~]', ['press_respawn'] = 'pressione [~b~E~w~] para respawn.', diff --git a/locales/en.lua b/locales/en.lua index 4c86edfc..fb7b18a6 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -37,7 +37,7 @@ Locales['en'] = { ['yes'] = 'yes', ['please_wait'] = 'please wait ~b~', ['minutes'] = ' minutes ', - ['seconds_fine'] = ' seconds ~w~to respawn | Respawn now for ~g~$', + ['seconds_fine'] = ' seconds ~w~to respawn \nRespawn now for ~g~$', ['seconds'] = ' seconds ~w~to respawn.', ['press_respawn_fine'] = '~w~ [Press ~b~E~w~]', ['press_respawn'] = 'press [~b~E~w~] to respawn.', diff --git a/locales/fr.lua b/locales/fr.lua index 877b06e2..8b80d187 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -37,7 +37,7 @@ Locales['fr'] = { ['yes'] = 'oui', ['please_wait'] = 's\'il vous plaît, attendez ~b~', ['minutes'] = ' minutes ', - ['seconds_fine'] = ' secondes ~w~to réapparaître | Réapparaître maintenant pour ~g~$', + ['seconds_fine'] = ' secondes ~w~to réapparaître \nRéapparaître maintenant pour ~g~$', ['seconds'] = ' secondes ~w~pour réapparaître.', ['press_respawn_fine'] = '~w~ [Presse ~b~E~w~]', ['press_respawn'] = 'appuyez [~b~E~w~] sur pour réapparaître.', From 47c7ef29fc31af4723e74ce624d8ae53057af8d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 21 Aug 2017 20:59:50 +0200 Subject: [PATCH 0507/3224] Update GetPlayers --- server/main.lua | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/server/main.lua b/server/main.lua index 296d8bd7..92bfa211 100644 --- a/server/main.lua +++ b/server/main.lua @@ -79,10 +79,13 @@ TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message local xPlayers = ESX.GetPlayers() if phoneNumber == 'ambulance' then - for k, v in pairs(xPlayers) do - if v.job.name == 'ambulance' then + for i=1, #xPlayers, 1 do + + local xPlayer2 = ESX.GetPlayerFromId(xPlayer[i]) + + if xPlayer2.job.name == 'ambulance' then TriggerEvent('esx_phone:getDistpatchRequestId', function(requestId) - TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, _U('alert_ambulance'), requestId) + TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, _U('alert_ambulance'), requestId) end) end end From 5f95bd0efceadf5d4239141c0bb1d61a83414ffe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 21 Aug 2017 21:00:38 +0200 Subject: [PATCH 0508/3224] Update GetPlayers --- .../es_extended/server/functions.lua | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index ae1bc2e7..7cd575e1 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -127,11 +127,12 @@ end ESX.SavePlayers = function(cb) local asyncTasks = {} - local players = ESX.GetPlayers() + local xPlayers = ESX.GetPlayers() - for k,v in pairs(players) do + for i=1, #xPlayers, 1 do table.insert(asyncTasks, function(cb) - ESX.SavePlayer(v, cb) + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + ESX.SavePlayer(v, xPlayer) end) end @@ -164,11 +165,13 @@ ESX.StartPayCheck = function() local xPlayers = ESX.GetPlayers() - for k,v in pairs(xPlayers) do + for i=1, #xPlayers, 1 do - if v.job.grade_salary > 0 then - v.addMoney(v.job.grade_salary) - TriggerClientEvent('esx:showNotification', v.source, _U('rec_salary') .. '~g~$' .. v.job.grade_salary) + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + + if xPlayer.job.grade_salary > 0 then + xPlayer.addMoney(xPlayer.job.grade_salary) + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('rec_salary') .. '~g~$' .. xPlayer.job.grade_salary) end end @@ -182,9 +185,17 @@ ESX.StartPayCheck = function() end ESX.GetPlayers = function() - return ESX.Players + + local sources = {} + + for k,v in pairs(ESX.Players) do + table.insert(source, k) + end + + return sources end + ESX.GetPlayerFromId = function(source) return ESX.Players[tonumber(source)] end From 062ddab0c0e12a980886c7aee3c2df49c375a097 Mon Sep 17 00:00:00 2001 From: renaiku Date: Mon, 21 Aug 2017 21:00:49 +0200 Subject: [PATCH 0509/3224] update getplayers --- server/main.lua | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/server/main.lua b/server/main.lua index e827d0b8..7c70127f 100644 --- a/server/main.lua +++ b/server/main.lua @@ -401,9 +401,10 @@ TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message local xPlayers = ESX.GetPlayers() if phoneNumber == 'cardealer' then - for k, v in pairs(xPlayers) do - if v.job.name == 'cardealer' then - TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'player') + for i=1, #xPlayers, 1 do + local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) + if xPlayer2.job.name == 'cardealer' then + TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'player') end end end @@ -445,10 +446,11 @@ function PayRent(d, h, m) local foundPlayer = false local xPlayer = nil - for k,v in pairs(xPlayers) do - if v.identifier == result[i].owner then + for i=1, #xPlayers, 1 do + local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) + if xPlayer2.identifier == result[i].owner then foundPlayer = true - xPlayer = v + xPlayer = xPlayer2 end end From 1f9565b94b849742301bbc20de9214697ed0976e Mon Sep 17 00:00:00 2001 From: renaiku Date: Mon, 21 Aug 2017 21:01:13 +0200 Subject: [PATCH 0510/3224] update getplayers --- server/main.lua | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/server/main.lua b/server/main.lua index f9f2ec56..7b4b999f 100644 --- a/server/main.lua +++ b/server/main.lua @@ -37,12 +37,14 @@ ESX.RegisterServerCallback('esx_bankerjob:getCustomers', function(source, cb) local xPlayers = ESX.GetPlayers() local customers = {} - for k,v in pairs(xPlayers) do + for i=1, #xPlayers, 1 do - TriggerEvent('esx_addonaccount:getAccount', 'bank_savings', v.identifier, function(account) + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + + TriggerEvent('esx_addonaccount:getAccount', 'bank_savings', xPlayer.identifier, function(account) table.insert(customers, { - source = v.source, - name = GetPlayerName(v.source), + source = xPlayer.source, + name = GetPlayerName(xPlayer.source), bankSavings = account.money }) end) @@ -59,10 +61,11 @@ TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message local xPlayers = ESX.GetPlayers() if phoneNumber == 'banker' then - for k, v in pairs(xPlayers) do - if v.job.name == 'banker' then + for i=1, #xPlayers, 1 do + local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) + if xPlayer2.job.name == 'banker' then TriggerEvent('esx_phone:getDistpatchRequestId', function(requestId) - TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'Client Banque') + TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'Client Banque') end) end end @@ -87,10 +90,11 @@ function CalculateBankSavings(d, h, m) local foundPlayer = false local xPlayer = nil - for k,v in pairs(xPlayers) do - if v.identifier == result[i].owner then + for i=1, #xPlayers, 1 do + local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) + if xPlayer2.identifier == result[i].owner then foundPlayer = true - xPlayer = v + xPlayer = xPlayer2 end end From 8e91b303c1d326d30b7027e4ba7517c80c51d5f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 21 Aug 2017 21:01:39 +0200 Subject: [PATCH 0511/3224] Update GetPlayers --- server/main.lua | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/server/main.lua b/server/main.lua index 522ae568..3edee613 100644 --- a/server/main.lua +++ b/server/main.lua @@ -18,9 +18,12 @@ TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message local xPlayers = ESX.GetPlayers() if phoneNumber == 'mecano' then - for k, v in pairs(xPlayers) do - if v.job.name == 'mecano' then - TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'Appel Mécano') + for i=1, #xPlayers, 1 do + + local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) + + if xPlayer2.job.name == 'mecano' then + TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'Appel Mécano') end end end From 0836a87e4c6a3b7a9f9a1efb5158a9bab8e57467 Mon Sep 17 00:00:00 2001 From: renaiku Date: Mon, 21 Aug 2017 21:01:47 +0200 Subject: [PATCH 0512/3224] update getplayers --- server/main.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/server/main.lua b/server/main.lua index 4a33fc76..33eca25e 100644 --- a/server/main.lua +++ b/server/main.lua @@ -49,10 +49,11 @@ TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message local xPlayers = ESX.GetPlayers() if phoneNumber == 'taxi' then - for k, v in pairs(xPlayers) do - if v.job.name == 'taxi' then + for i=1, #xPlayers, 1 do + local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) + if xPlayer2.job.name == 'taxi' then TriggerEvent('esx_phone:getDistpatchRequestId', function(requestId) - TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'Appel Taxi', requestId) + TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'Appel Taxi', requestId) end) end end From 2b40d5116e4b13a30c3b9502317f48dc163e6ba7 Mon Sep 17 00:00:00 2001 From: renaiku Date: Mon, 21 Aug 2017 21:02:01 +0200 Subject: [PATCH 0513/3224] update getplayers --- server/main.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/server/main.lua b/server/main.lua index 29726b19..d59a8cee 100644 --- a/server/main.lua +++ b/server/main.lua @@ -92,10 +92,11 @@ function WashMoneyCRON(d, h, m) local foundPlayer = false local xPlayer = nil - for k,v in pairs(xPlayers) do - if v.identifier == result[i].identifier then + for i=1, #xPlayers, 1 do + local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) + if xPlayer2.identifier == result[i].identifier then foundPlayer = true - xPlayer = v + xPlayer = xPlayer2 end end From 08e79e8a41922bd5c959eabbdc667d29eaf0de9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 21 Aug 2017 21:02:14 +0200 Subject: [PATCH 0514/3224] Update GetPlayers --- server/main.lua | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/server/main.lua b/server/main.lua index 9fecf1a7..3fbeb136 100644 --- a/server/main.lua +++ b/server/main.lua @@ -105,8 +105,11 @@ AddEventHandler('esx:playerLoaded', function(source) local xPlayers = ESX.GetPlayers() - for k, v in pairs(xPlayers) do - if v.get('phoneNumber') == contacts[i].number then + for i=1, #xPlayers, 1 do + + local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) + + if xPlayer2.get('phoneNumber') == contacts[i].number then contacts[i].online = true end end @@ -150,8 +153,11 @@ AddEventHandler('esx_phone:reload', function(phoneNumber) local xPlayers = ESX.GetPlayers() - for k, v in pairs(xPlayers) do - if v.get('phoneNumber') == contacts[i].number then + for i=1, #xPlayers, 1 do + + local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) + + if xPlayer2.get('phoneNumber') == contacts[i].number then contacts[i].online = true end end @@ -174,7 +180,7 @@ end) RegisterServerEvent('esx_phone:send') AddEventHandler('esx_phone:send', function(phoneNumber, message, anon) - + local _source = source for i=1, #RegisteredCallbacks, 1 do @@ -187,7 +193,6 @@ AddEventHandler('esx_phone:addPlayerContact', function(phoneNumber, contactName) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) - local xPlayers = ESX.GetPlayers() local foundNumber = false local foundPlayer = nil @@ -242,8 +247,11 @@ AddEventHandler('esx_phone:addPlayerContact', function(phoneNumber, contactName) local xPlayers = ESX.GetPlayers() local isOnline = false - for k,v in pairs(xPlayers) do - if v.get('phoneNumber') == phoneNumber then + for i=1, #xPlayers, 1 do + + local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) + + if xPlayer2.get('phoneNumber') == phoneNumber then isOnline = true break end @@ -273,9 +281,12 @@ AddEventHandler('esx_phone:ready', function() print('MESSAGE => ' .. xPlayer.name .. '@' .. phoneNumber .. ' : ' .. message) - for k, v in pairs(xPlayers) do - if v.get('phoneNumber') == phoneNumber then - TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, false, anon, 'player', false) + for i=1, #xPlayers, 1 do + + local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) + + if xPlayer2.get('phoneNumber') == phoneNumber then + TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, false, anon, 'player', false) end end From e8085da1775b6c6d2153d2e20075c1f2f59337f2 Mon Sep 17 00:00:00 2001 From: renaiku Date: Mon, 21 Aug 2017 21:02:37 +0200 Subject: [PATCH 0515/3224] update getplayers --- server/main.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/server/main.lua b/server/main.lua index fdd8932e..ed21ebd2 100644 --- a/server/main.lua +++ b/server/main.lua @@ -272,10 +272,11 @@ TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message local xPlayers = ESX.GetPlayers() if phoneNumber == 'police' then - for k, v in pairs(xPlayers) do - if v.job.name == 'police' then + for i=1, #xPlayers, 1 do + local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) + if xPlayer2.job.name == 'police' then TriggerEvent('esx_phone:getDistpatchRequestId', function(requestId) - TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, _('alert_police'), requestId) + TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, _('alert_police'), requestId) end) end end From 3687fa30584a59aefb32cb5b4c39c70944f947fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 21 Aug 2017 21:03:01 +0200 Subject: [PATCH 0516/3224] Update GetPlayers --- server/main.lua | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/server/main.lua b/server/main.lua index b7f1d9fe..157da815 100644 --- a/server/main.lua +++ b/server/main.lua @@ -26,15 +26,18 @@ function SetPropertyOwned(name, price, rented, owner) local xPlayers = ESX.GetPlayers() - for k,v in pairs(xPlayers) do - if v.identifier == owner then + for i=1, #xPlayers, 1 do - TriggerClientEvent('esx_property:setPropertyOwned', v.source, name, true) + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + + if xPlayer.identifier == owner then + + TriggerClientEvent('esx_property:setPropertyOwned', xPlayer.source, name, true) if rented then - TriggerClientEvent('esx:showNotification', v.source, _U('rented_for') .. price) + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('rented_for') .. price) else - TriggerClientEvent('esx:showNotification', v.source, _U('purchased_for') .. price) + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('purchased_for') .. price) end break @@ -58,10 +61,13 @@ function RemoveOwnedProperty(name, owner) local xPlayers = ESX.GetPlayers() - for k,v in pairs(xPlayers) do - if v.identifier == owner then - TriggerClientEvent('esx_property:setPropertyOwned', v.source, name, false) - TriggerClientEvent('esx:showNotification', v.source, _U('made_property')) + for i=1, #xPlayers, 1 do + + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + + if xPlayer.identifier == owner then + TriggerClientEvent('esx_property:setPropertyOwned', xPlayer.source, name, false) + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('made_property')) break end end @@ -523,10 +529,13 @@ function PayRent(d, h, m) local foundPlayer = false local xPlayer = nil - for k,v in pairs(xPlayers) do - if v.identifier == result[i].owner then + for j=1, #xPlayers, 1 do + + local xPlayer2 = ESX.GetPlayerFromId(xPlayers[j]) + + if xPlayer2.identifier == result[i].owner then foundPlayer = true - xPlayer = v + xPlayer = xPlayer2 end end From dce64a2ff64ae837614b22cc7c54f7c6517078fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 21 Aug 2017 21:03:32 +0200 Subject: [PATCH 0517/3224] Update GetPlayers --- server/main.lua | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/server/main.lua b/server/main.lua index 2f586956..4001b962 100644 --- a/server/main.lua +++ b/server/main.lua @@ -19,9 +19,12 @@ AddEventHandler('esx_phone:ready', function() if phoneNumber == "realestateagent" then - for k, v in pairs(xPlayers) do - if v.job.name == 'realestateagent' then - TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, job) + for i=1, #xPlayers, 1 do + + local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) + + if xPlayer2.job.name == 'realestateagent' then + TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, job) end end @@ -59,9 +62,12 @@ TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message local xPlayers = ESX.GetPlayers() if phoneNumber == 'realestateagent' then - for k, v in pairs(xPlayers) do - if v.job.name == 'realestateagent' then - TriggerClientEvent('esx_phone:onMessage', v.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'player') + for i=1, #xPlayers, 1 do + + local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) + + if xPlayer2.job.name == 'realestateagent' then + TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'player') end end end @@ -76,10 +82,13 @@ ESX.RegisterServerCallback('esx_realestateagentjob:getCustomers', function(sourc local customers = {} for i=1, #properties, 1 do - for k,v in pairs(xPlayers) do - if v.identifier == properties[i].owner then + for j=1, #xPlayers, 1 do + + local xPlayer = ESX.GetPlayerFromId(xPlayers[j]) + + if xPlayer.identifier == properties[i].owner then table.insert(customers, { - name = v.name, + name = xPlayer.name, propertyOwner = properties[i].owner, propertyRented = properties[i].rented, propertyId = properties[i].id, From 57442d080e0b30cd2121d16d3cc4066b93b408a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 21 Aug 2017 21:16:47 +0200 Subject: [PATCH 0518/3224] Update GetPlayers --- server/main.lua | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/server/main.lua b/server/main.lua index 213da1e7..26cacdc8 100644 --- a/server/main.lua +++ b/server/main.lua @@ -12,13 +12,16 @@ AddEventHandler('esx_billing:sendBill', function(playerId, sharedAccountName, la if account == nil then - for k, v in pairs(xPlayers) do - if v.source == playerId then + for i=1, #xPlayers, 1 do + + local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) + + if xPlayer2.source == playerId then MySQL.Async.execute( 'INSERT INTO billing (identifier, sender, target_type, target, label, amount) VALUES (@identifier, @sender, @target_type, @target, @label, @amount)', { - ['@identifier'] = v.identifier, + ['@identifier'] = xPlayer2.identifier, ['@sender'] = xPlayer.identifier, ['@target_type'] = 'player', ['@target'] = xPlayer.identifier, @@ -26,7 +29,7 @@ AddEventHandler('esx_billing:sendBill', function(playerId, sharedAccountName, la ['@amount'] = amount }, function(rowsChanged) - TriggerClientEvent('esx:showNotification', v.source, _U('received_invoice')) + TriggerClientEvent('esx:showNotification', xPlayer2.source, _U('received_invoice')) end ) @@ -36,14 +39,16 @@ AddEventHandler('esx_billing:sendBill', function(playerId, sharedAccountName, la else - for k, v in pairs(xPlayers) do + for i=1, #xPlayers, 1 do - if v.source == playerId then + local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) + + if xPlayer2.source == playerId then MySQL.Async.execute( 'INSERT INTO billing (identifier, sender, target_type, target, label, amount) VALUES (@identifier, @sender, @target_type, @target, @label, @amount)', { - ['@identifier'] = v.identifier, + ['@identifier'] = xPlayer2.identifier, ['@sender'] = xPlayer.identifier, ['@target_type'] = 'society', ['@target'] = sharedAccountName, @@ -51,7 +56,7 @@ AddEventHandler('esx_billing:sendBill', function(playerId, sharedAccountName, la ['@amount'] = amount }, function(rowsChanged) - TriggerClientEvent('esx:showNotification', v.source, _U('received_invoice')) + TriggerClientEvent('esx:showNotification', xPlayer2.source, _U('received_invoice')) end ) @@ -116,9 +121,12 @@ ESX.RegisterServerCallback('esx_billing:payBill', function(source, cb, id) local xPlayers = ESX.GetPlayers() local foundPlayer = nil - for k,v in pairs(xPlayers) do - if v.identifier == sender then - foundPlayer = v + for i=1, #xPlayers, 1 do + + local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) + + if xPlayer2.identifier == sender then + foundPlayer = xPlayer2 break end end From dac3492ce8d203953b4f60407d501eb739b44593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 21 Aug 2017 21:25:01 +0200 Subject: [PATCH 0519/3224] Fix typo --- resources/[essential]/es_extended/server/functions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index 7cd575e1..2bbdbbcd 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -189,7 +189,7 @@ ESX.GetPlayers = function() local sources = {} for k,v in pairs(ESX.Players) do - table.insert(source, k) + table.insert(sources, k) end return sources From 1122ec02491e0bd0357160522f57de591e8b4820 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 21 Aug 2017 21:40:23 +0200 Subject: [PATCH 0520/3224] Fix error --- resources/[essential]/es_extended/server/functions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index 2bbdbbcd..4c6ee6b3 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -132,7 +132,7 @@ ESX.SavePlayers = function(cb) for i=1, #xPlayers, 1 do table.insert(asyncTasks, function(cb) local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) - ESX.SavePlayer(v, xPlayer) + ESX.SavePlayer(xPlayer, cb) end) end From d1dd31cf9331aa2be84fef8e0324c23bd38dbb1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 21 Aug 2017 21:41:46 +0200 Subject: [PATCH 0521/3224] Fix error --- server/main.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/main.lua b/server/main.lua index 3fbeb136..a453ba2a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -105,9 +105,9 @@ AddEventHandler('esx:playerLoaded', function(source) local xPlayers = ESX.GetPlayers() - for i=1, #xPlayers, 1 do + for j=1, #xPlayers, 1 do - local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) + local xPlayer2 = ESX.GetPlayerFromId(xPlayers[j]) if xPlayer2.get('phoneNumber') == contacts[i].number then contacts[i].online = true From 0e33603920a2be97a58ca62d6b99dd4c68a5f5f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 21 Aug 2017 21:48:40 +0200 Subject: [PATCH 0522/3224] Fix double i in loop --- server/main.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/main.lua b/server/main.lua index a453ba2a..e4df95f7 100644 --- a/server/main.lua +++ b/server/main.lua @@ -153,9 +153,9 @@ AddEventHandler('esx_phone:reload', function(phoneNumber) local xPlayers = ESX.GetPlayers() - for i=1, #xPlayers, 1 do + for j=1, #xPlayers, 1 do - local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) + local xPlayer2 = ESX.GetPlayerFromId(xPlayers[j]) if xPlayer2.get('phoneNumber') == contacts[i].number then contacts[i].online = true From 97f4d41ee86435e8d91d611041fe6d784acda792 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 21 Aug 2017 21:51:58 +0200 Subject: [PATCH 0523/3224] Fix missing and --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index d7409c27..97148191 100644 --- a/client/main.lua +++ b/client/main.lua @@ -484,7 +484,7 @@ Citizen.CreateThread(function() local ped = GetRandomPed() - if DoesEntityExist(ped) IsPedHuman(ped) and IsPedWalking(ped) and not IsPedAPlayer(ped) then + if DoesEntityExist(ped) and IsPedHuman(ped) and IsPedWalking(ped) and not IsPedAPlayer(ped) then CurrentCustomer = ped end From a2af4997f3270e915a6cfbc1b99b8da72f1096fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 21 Aug 2017 22:00:18 +0200 Subject: [PATCH 0524/3224] Fix typo --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 92bfa211..f1f747f6 100644 --- a/server/main.lua +++ b/server/main.lua @@ -81,7 +81,7 @@ TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message if phoneNumber == 'ambulance' then for i=1, #xPlayers, 1 do - local xPlayer2 = ESX.GetPlayerFromId(xPlayer[i]) + local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) if xPlayer2.job.name == 'ambulance' then TriggerEvent('esx_phone:getDistpatchRequestId', function(requestId) From 4ea108d89838c3d54e3f2b92df18bf8170fc01ed Mon Sep 17 00:00:00 2001 From: Don <30905704+ddh3@users.noreply.github.com> Date: Mon, 21 Aug 2017 14:53:07 -0700 Subject: [PATCH 0525/3224] Update esx_jobs_sv.lua --- server/esx_jobs_sv.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/esx_jobs_sv.lua b/server/esx_jobs_sv.lua index f47c4a56..dca0a4ea 100644 --- a/server/esx_jobs_sv.lua +++ b/server/esx_jobs_sv.lua @@ -53,7 +53,7 @@ local function Work(source, item) for i=1, #item, 1 do local itemQtty = 0 - if item[i].name ~= _U('lj_delivery') then + if item[i].name ~= _U('delivery') then itemQtty = xPlayer.getInventoryItem(item[i].db_name).count end @@ -62,7 +62,7 @@ local function Work(source, item) requiredItemQtty = xPlayer.getInventoryItem(item[1].requires).count end - if item[i].name ~= _U('lj_delivery') and itemQtty >= item[i].max then + if item[i].name ~= _U('delivery') and itemQtty >= item[i].max then TriggerClientEvent('esx:showNotification', source, _U('max_limit') .. item[i].name) elseif item[i].requires ~= "nothing" and requiredItemQtty <= 0 then TriggerClientEvent('esx:showNotification', source, _U('not_enough') .. item[1].requires_name .. _U('not_enough2')) From 6384476016471cafbc5e1a5913510c619e24fa07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 22 Aug 2017 00:58:59 +0200 Subject: [PATCH 0526/3224] Fix GetPlayers() + add GetPercent() --- server/classes/status.lua | 4 ++++ server/main.lua | 21 +++++++++++---------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/server/classes/status.lua b/server/classes/status.lua index b81969cc..7cf02782 100644 --- a/server/classes/status.lua +++ b/server/classes/status.lua @@ -43,6 +43,10 @@ function CreateStatus(xPlayer, name, default, color, visible, tickCallback, clie end end + self.getPercent = function() + return (self.val / Config.StatusMax) * 100 + end + self.updateClient = function() TriggerEvent('esx_status:updateClient', self.xPlayer.source) end diff --git a/server/main.lua b/server/main.lua index 6358de60..493065cd 100644 --- a/server/main.lua +++ b/server/main.lua @@ -130,16 +130,15 @@ function TickStatus() local xPlayers = ESX.GetPlayers() - for k,v in pairs(xPlayers) do + for i=1, #xPlayers, 1 do - local status = v.get('status') + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + local status = xPlayer.get('status') if status ~= nil then - for i=1, #status, 1 do status[i]._get('onTick')() end - end end @@ -152,8 +151,9 @@ function UpdateClients() local xPlayers = ESX.GetPlayers() - for k,v in pairs(xPlayers) do - TriggerEvent('esx_status:updateClient', v.source) + for i=1, #xPlayers, 1 do + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + TriggerEvent('esx_status:updateClient', xPlayer.source) end SetTimeout(Config.UpdateClientTime, UpdateClients) @@ -164,10 +164,11 @@ function SaveData() local xPlayers = ESX.GetPlayers() - for k,v in pairs(xPlayers) do + for i=1, #xPlayers, 1 do - local data = {} - local status = v.get('status') + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + local data = {} + local status = xPlayer.get('status') for i=1, #status, 1 do @@ -183,7 +184,7 @@ function SaveData() 'UPDATE users SET status = @status WHERE identifier = @identifier', { ['@status'] = json.encode(data), - ['@identifier'] = v.identifier + ['@identifier'] = xPlayer.identifier } ) From dd53565a9938b0de6e4400fc6b4cdafb7fddb249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 22 Aug 2017 01:22:37 +0200 Subject: [PATCH 0527/3224] Fix typo --- locales/en.lua | 2 +- locales/fr.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/en.lua b/locales/en.lua index c961e3df..6534c364 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -4,7 +4,7 @@ Locales['en'] = { ['yes'] = 'yes', ['no'] = 'no', ['not_enough_money'] = 'you do not have enough money', - ['press_access'] = 'press ~INPUT_CONTENT~ to access the menu', + ['press_access'] = 'press ~INPUT_CONTEXT~ to access the menu', ['barber_blip'] = 'barber shop', ['you_paid'] = 'you paid ', } \ No newline at end of file diff --git a/locales/fr.lua b/locales/fr.lua index 22b95b74..ac1683a6 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -4,7 +4,7 @@ Locales['fr'] = { ['yes'] = 'oui', ['no'] = 'non', ['not_enough_money'] = 'vous n\'avez pas assez d\'argent', - ['press_access'] = 'appuez sur ~INPUT_CONTENT~ pour accéder au menu', + ['press_access'] = 'appuez sur ~INPUT_CONTEXT~ pour accéder au menu', ['barber_blip'] = 'barbier', ['you_paid'] = 'vous avez payé ', } \ No newline at end of file From 27992b06fee348a7733255e5630d0cb9066f3906 Mon Sep 17 00:00:00 2001 From: renaiku Date: Tue, 22 Aug 2017 01:42:50 +0200 Subject: [PATCH 0528/3224] fix --- server/esx_drugs_sv.lua | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/server/esx_drugs_sv.lua b/server/esx_drugs_sv.lua index 82de1a90..970e799b 100644 --- a/server/esx_drugs_sv.lua +++ b/server/esx_drugs_sv.lua @@ -18,8 +18,9 @@ function CountCops() CopsConnected = 0 - for k,v in pairs(xPlayers) do - if v.job.name == 'police' then + for i=1, #xPlayers, 1 do + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + if xPlayer.job.name == 'police' then CopsConnected = CopsConnected + 1 end end @@ -65,7 +66,7 @@ AddEventHandler('esx_drugs:startHarvestCoke', function() TriggerClientEvent('esx:showNotification', _source, _U('pickup_in_prog')) - HarvestCoke(source) + HarvestCoke(_source) end) @@ -118,7 +119,7 @@ AddEventHandler('esx_drugs:startTransformCoke', function() TriggerClientEvent('esx:showNotification', _source, _U('packing_in_prog')) - TransformCoke(source) + TransformCoke(_source) end) @@ -186,7 +187,7 @@ AddEventHandler('esx_drugs:startSellCoke', function() TriggerClientEvent('esx:showNotification', _source, _U('sale_in_prog')) - SellCoke(source) + SellCoke(_source) end) @@ -234,7 +235,7 @@ AddEventHandler('esx_drugs:startHarvestMeth', function() TriggerClientEvent('esx:showNotification', _source, _U('pickup_in_prog')) - HarvestMeth(source) + HarvestMeth(_source) end) @@ -287,7 +288,7 @@ AddEventHandler('esx_drugs:startTransformMeth', function() TriggerClientEvent('esx:showNotification', _source, _U('packing_in_prog')) - TransformMeth(source) + TransformMeth(_source) end) @@ -358,7 +359,7 @@ AddEventHandler('esx_drugs:startSellMeth', function() TriggerClientEvent('esx:showNotification', _source, _U('sale_in_prog')) - SellMeth(source) + SellMeth(_source) end) @@ -406,7 +407,7 @@ AddEventHandler('esx_drugs:startHarvestWeed', function() TriggerClientEvent('esx:showNotification', _source, _U('pickup_in_prog')) - HarvestWeed(source) + HarvestWeed(_source) end) @@ -459,7 +460,7 @@ AddEventHandler('esx_drugs:startTransformWeed', function() TriggerClientEvent('esx:showNotification', _source, _U('packing_in_prog')) - TransformWeed(source) + TransformWeed(_source) end) @@ -524,7 +525,7 @@ AddEventHandler('esx_drugs:startSellWeed', function() TriggerClientEvent('esx:showNotification', _source, _U('sale_in_prog')) - SellWeed(source) + SellWeed(_source) end) @@ -542,9 +543,17 @@ RegisterServerEvent('esx_drugs:GetUserInventory') AddEventHandler('esx_drugs:GetUserInventory', function(currentZone) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) - TriggerClientEvent('esx_drugs:ReturnInventory', _source, xPlayer.getInventoryItem('coke').count, xPlayer.getInventoryItem('coke_pooch').count, - xPlayer.getInventoryItem('meth').count, xPlayer.getInventoryItem('meth_pooch').count, - xPlayer.getInventoryItem('weed').count, xPlayer.getInventoryItem('weed_pooch').count, xPlayer.job.name, currentZone) + TriggerClientEvent('esx_drugs:ReturnInventory', + _source, + xPlayer.getInventoryItem('coke').count, + xPlayer.getInventoryItem('coke_pooch').count, + xPlayer.getInventoryItem('meth').count, + xPlayer.getInventoryItem('meth_pooch').count, + xPlayer.getInventoryItem('weed').count, + xPlayer.getInventoryItem('weed_pooch').count, + xPlayer.job.name, + currentZone + ) end) -- Register Usable Item From 00f2f02750eeebd770c670aeb3746f8b65f4f655 Mon Sep 17 00:00:00 2001 From: AdrineX Date: Tue, 22 Aug 2017 03:41:31 +0300 Subject: [PATCH 0529/3224] getplayer loop fix --- server/esx_holdup_sv.lua | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/server/esx_holdup_sv.lua b/server/esx_holdup_sv.lua index 721ef341..c8da7d35 100644 --- a/server/esx_holdup_sv.lua +++ b/server/esx_holdup_sv.lua @@ -13,8 +13,9 @@ AddEventHandler('esx_holdup:toofar', function(robb) local source = source local xPlayers = ESX.GetPlayers() rob = false - for k, v in pairs(xPlayers) do - if v.job.name == 'police' then + for i=1, #xPlayers, 1 do + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + if xPlayer.job.name == 'police' then TriggerClientEvent('esx:showNotification', k, _U('robbery_cancelled_at') .. Stores[robb].nameofstore) TriggerClientEvent('esx_holdup:killblip', k) end @@ -46,8 +47,9 @@ AddEventHandler('esx_holdup:rob', function(robb) local cops = 0 - for k, v in pairs(xPlayers) do - if v.job.name == 'police' then + for i=1, #xPlayers, 1 do + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + if xPlayer.job.name == 'police' then cops = cops + 1 end end @@ -58,8 +60,9 @@ AddEventHandler('esx_holdup:rob', function(robb) if(cops > 1)then rob = true - for k, v in pairs(xPlayers) do - if v.job.name == 'police' then + for i=1, #xPlayers, 1 do + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + if xPlayer.job.name == 'police' then TriggerClientEvent('esx:showNotification', k, _U('rob_in_prog') .. store.nameofstore) TriggerClientEvent('esx_holdup:setblip', k, Stores[robb].position) end @@ -82,8 +85,9 @@ AddEventHandler('esx_holdup:rob', function(robb) xPlayer.addAccountMoney('black_money', store.reward) TriggerClientEvent('esx:showNotification', source, _U('robbery_complete')) - for k, v in pairs(xPlayers) do - if v.job.name == 'police' then + for i=1, #xPlayers, 1 do + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + if xPlayer.job.name == 'police' then TriggerClientEvent('esx:showNotification', k, _U('robbery_complete_at') .. store.nameofstore) TriggerClientEvent('esx_holdup:killblip', k) end From 5733fdd46e9a97084158d501e3a164c4d883eaaf Mon Sep 17 00:00:00 2001 From: renaiku Date: Tue, 22 Aug 2017 03:03:26 +0200 Subject: [PATCH 0530/3224] fix --- client/esx_jobs_cl.lua | 129 +++++++++++++++++++++-------------------- 1 file changed, 65 insertions(+), 64 deletions(-) diff --git a/client/esx_jobs_cl.lua b/client/esx_jobs_cl.lua index 45129934..ba16f310 100644 --- a/client/esx_jobs_cl.lua +++ b/client/esx_jobs_cl.lua @@ -434,77 +434,78 @@ Citizen.CreateThread(function() end end - local coords = GetEntityCoords(GetPlayerPed(-1)) - local currentZone = nil - local zone = nil - local lastZone = nil + if zones ~= nil then + local coords = GetEntityCoords(GetPlayerPed(-1)) + local currentZone = nil + local zone = nil + local lastZone = nil - for k,v in pairs(zones) do - if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then - isInMarker = true - currentZone = k - zone = v - break - else - isInMarker = false - end - end - - if IsControlJustReleased(0, Keys["E"]) and not menuIsShowed and isInMarker then - if onDuty or zone.Type == "cloakroom" or PlayerData.job.name == "reporter" then - TriggerEvent('esx_jobs:action', job, zone) - end - end - - -- hide or show top left zone hints - if isInMarker and not menuIsShowed then - hintIsShowed = true - if (onDuty or zone.Type == "cloakroom" or PlayerData.job.name == "reporter") and zone.Type ~= "vehdelete" then - hintToDisplay = zone.Hint - hintIsShowed = true - elseif zone.Type == "vehdelete" and (onDuty or PlayerData.job.name == "reporter") then - local playerPed = GetPlayerPed(-1) - if IsPedInAnyVehicle(playerPed, 0) then - local vehicle = GetVehiclePedIsIn(playerPed) - local driverPed = GetPedInVehicleSeat(vehicle, -1) - local isVehicleOwner = false - local plate = GetVehicleNumberPlateText(vehicle) - plate = string.gsub(plate, " ", "") - for i=1, #myPlate, 1 do - Citizen.Trace(myPlate[i]) - if (myPlate[i] == plate) and (playerPed == driverPed) then - hintToDisplay = zone.Hint .. "\n" .. _U('security_deposit') .. cautionVehicleInCaseofDrop .. "~s~." - isVehicleOwner = true - break - end - end - if not isVehicleOwner then - hintToDisplay = _U('not_your_vehicle') - end + for k,v in pairs(zones) do + if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x) then + isInMarker = true + currentZone = k + zone = v + break else - hintToDisplay = _U('in_vehicle') - end - hintIsShowed = true - elseif onDuty and zone.Spawner ~= spawner then - hintToDisplay = _U('wrong_point') - hintIsShowed = true - else - if not isInPublicMarker then - hintToDisplay = "no hint to display" - hintIsShowed = false + isInMarker = false end end - end - if isInMarker and not hasAlreadyEnteredMarker then - hasAlreadyEnteredMarker = true - end + if IsControlJustReleased(0, Keys["E"]) and not menuIsShowed and isInMarker then + if onDuty or zone.Type == "cloakroom" or PlayerData.job.name == "reporter" then + TriggerEvent('esx_jobs:action', job, zone) + end + end - if not isInMarker and hasAlreadyEnteredMarker then - hasAlreadyEnteredMarker = false - TriggerEvent('esx_jobs:hasExitedMarker', zone) - end + -- hide or show top left zone hints + if isInMarker and not menuIsShowed then + hintIsShowed = true + if (onDuty or zone.Type == "cloakroom" or PlayerData.job.name == "reporter") and zone.Type ~= "vehdelete" then + hintToDisplay = zone.Hint + hintIsShowed = true + elseif zone.Type == "vehdelete" and (onDuty or PlayerData.job.name == "reporter") then + local playerPed = GetPlayerPed(-1) + if IsPedInAnyVehicle(playerPed, 0) then + local vehicle = GetVehiclePedIsIn(playerPed) + local driverPed = GetPedInVehicleSeat(vehicle, -1) + local isVehicleOwner = false + local plate = GetVehicleNumberPlateText(vehicle) + plate = string.gsub(plate, " ", "") + for i=1, #myPlate, 1 do + Citizen.Trace(myPlate[i]) + if (myPlate[i] == plate) and (playerPed == driverPed) then + hintToDisplay = zone.Hint .. "\n" .. _U('security_deposit') .. cautionVehicleInCaseofDrop .. "~s~." + isVehicleOwner = true + break + end + end + if not isVehicleOwner then + hintToDisplay = _U('not_your_vehicle') + end + else + hintToDisplay = _U('in_vehicle') + end + hintIsShowed = true + elseif onDuty and zone.Spawner ~= spawner then + hintToDisplay = _U('wrong_point') + hintIsShowed = true + else + if not isInPublicMarker then + hintToDisplay = "no hint to display" + hintIsShowed = false + end + end + end + if isInMarker and not hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = true + end + + if not isInMarker and hasAlreadyEnteredMarker then + hasAlreadyEnteredMarker = false + TriggerEvent('esx_jobs:hasExitedMarker', zone) + end + end end end end) From 7a217d7a336e43e5c01a3c320d1b724e511ef8da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 22 Aug 2017 03:22:46 +0200 Subject: [PATCH 0531/3224] Increase UI timeout --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 652a7a17..5ba395b5 100644 --- a/client/main.lua +++ b/client/main.lua @@ -46,7 +46,7 @@ function OpenPhone() GUI.PhoneIsShowed = true - ESX.SetTimeout(200, function() + ESX.SetTimeout(250, function() SetNuiFocus(true, true) end) From b215be0db3d7438d42281c35d3c59f660ef99608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 22 Aug 2017 03:42:35 +0200 Subject: [PATCH 0532/3224] add close callback + return menu when opening --- resources/[essential]/es_extended/client/functions.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 4e215f1d..0a8f2035 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -134,7 +134,7 @@ ESX.UI.Menu.RegisterType = function(type, open, close) end -ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change) +ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change, close) local menu = {} @@ -156,6 +156,10 @@ ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change) end end + if close ~= nil then + close() + end + end menu.update = function(query, newData) @@ -192,6 +196,8 @@ ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change) ESX.UI.Menu.RegisteredTypes[type].open(namespace, name, data) + return menu + end ESX.UI.Menu.Close = function(type, namespace, name) From e537204c33fbaaf2bda7294306b9eff7f9152ad1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 22 Aug 2017 03:43:21 +0200 Subject: [PATCH 0533/3224] Close skin cam when closing menu --- client/main.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/main.lua b/client/main.lua index f6e1e557..57d823cf 100644 --- a/client/main.lua +++ b/client/main.lua @@ -147,6 +147,9 @@ function OpenMenu(submitCb, cancelCb, restrict) end) + end, + function() + DeleteSkinCam() end ) From 92c4c73f14108b7f9509ada25b3bede9c76dc65f Mon Sep 17 00:00:00 2001 From: renaiku Date: Tue, 22 Aug 2017 04:32:35 +0200 Subject: [PATCH 0534/3224] Fix security deposit, now using esx menus --- README.md | 6 +- __resource.lua | 15 +--- client/esx_jobs_cl.lua | 65 ++++++++------ html/bankgothic.ttf | Bin 36272 -> 0 bytes html/css/app.css | 61 ------------- html/img/keys/enter.png | Bin 941 -> 0 bytes html/img/keys/return.png | Bin 376 -> 0 bytes html/pdown.ttf | Bin 151512 -> 0 bytes html/scripts/app.js | 168 ----------------------------------- html/scripts/mustache.min.js | 1 - html/ui.html | 15 ---- locales/en.lua | 2 +- locales/fr.lua | 2 + server/esx_jobs_sv.lua | 21 +++-- 14 files changed, 53 insertions(+), 303 deletions(-) delete mode 100644 html/bankgothic.ttf delete mode 100644 html/css/app.css delete mode 100644 html/img/keys/enter.png delete mode 100644 html/img/keys/return.png delete mode 100644 html/pdown.ttf delete mode 100644 html/scripts/app.js delete mode 100644 html/scripts/mustache.min.js delete mode 100644 html/ui.html diff --git a/README.md b/README.md index 403d87c3..7b2d9ed0 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,9 @@ [REQUIRES] - fxserver-esx_addonaccount: https://github.com/FXServer-ESX/fxserver-esx_addonaccount -[KNOWN BUGS] - -The bail is not given back when the player disconnect or timeout. - [FEATURES] - Jobs: Slaughterer, Miner, Fisherman, Journalist, etc... -- Bails +- Security deposit when renting a job vehicle (given back in case of crash, to the amount of damage the vehicle has already taken) - Easy system to create jobs (samples in jobs folder) - Item farming jobs - On Duty system diff --git a/__resource.lua b/__resource.lua index 38393945..4947d088 100644 --- a/__resource.lua +++ b/__resource.lua @@ -22,17 +22,4 @@ client_scripts { 'jobs/slaughterer.lua', 'jobs/textil.lua', 'client/esx_jobs_cl.lua' -} - -ui_page 'html/ui.html' - -files { - 'html/ui.html', - 'html/bankgothic.ttf', - 'html/pdown.ttf', - 'html/css/app.css', - 'html/scripts/mustache.min.js', - 'html/scripts/app.js', - 'html/img/keys/enter.png', - 'html/img/keys/return.png' -} +} \ No newline at end of file diff --git a/client/esx_jobs_cl.lua b/client/esx_jobs_cl.lua index ba16f310..651aec84 100644 --- a/client/esx_jobs_cl.lua +++ b/client/esx_jobs_cl.lua @@ -66,13 +66,47 @@ AddEventHandler('esx_jobs:publicTeleports', function(position) SetEntityCoords(GetPlayerPed(-1), position.x, position.y, position.z) end) +function OpenMenu() + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'cloakroom', + { + title = _U('cloakroom'), + elements = { + {label = _U('job_wear'), value = 'job_wear'}, + {label = _U('citizen_wear'), value = 'citizen_wear'} + } + }, + function(data, menu) + if data.current.value == 'citizen_wear' then + onDuty = false + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin) + TriggerEvent('skinchanger:loadSkin', skin) + end) + end + if data.current.value == 'job_wear' then + onDuty = true + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) + if skin.sex == 0 then + TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_male) + else + TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_female) + end + end) + end + menu.close() + end, + function(data, menu) + menu.close() + end + ) +end + AddEventHandler('esx_jobs:action', function(job, zone) menuIsShowed = true if zone.Type == "cloakroom" then - SendNUIMessage({ - showMenu = true, - menu = 'cloakroom' - }) + OpenMenu() elseif zone.Type == "work" then hintToDisplay = "no hint to display" hintIsShowed = false @@ -247,29 +281,6 @@ function refreshBlips() end end --- ######################### -RegisterNUICallback('select', function(data, cb) - if data.menu == 'cloakroom' then - if data.val == 'citizen_wear' then - onDuty = false - ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin) - TriggerEvent('skinchanger:loadSkin', skin) - end) - end - if data.val == 'job_wear' then - onDuty = true - ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) - if skin.sex == 0 then - TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_male) - else - TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_female) - end - end) - end - end - cb('ok') -end) - function spawncar(spawnPoint, vehicle) hintToDisplay = "no hint to display" hintIsShowed = false diff --git a/html/bankgothic.ttf b/html/bankgothic.ttf deleted file mode 100644 index f3d8049b052a1f9cfd27557eb3675bc85ce4b9fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36272 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 D`#l06 diff --git a/html/css/app.css b/html/css/app.css deleted file mode 100644 index f5b568b8..00000000 --- a/html/css/app.css +++ /dev/null @@ -1,61 +0,0 @@ -@font-face { - font-family: bankgothic; - src: url('../bankgothic.ttf'); -} - -@font-face { - font-family: pcdown; - src: url('../pdown.ttf'); -} - -#controls { - font-family : pcdown; - font-size : 3em; - color : #FFF; - position : absolute; - bottom : 40; - right : 40; - - text-shadow: - -1px -1px 0 #000, - 1px -1px 0 #000, - -1px 1px 0 #000, - 1px 1px 0 #000 - ; -} - -.controls { - display: none; -} - -.menu { - font-family : bankgothic; - min-width : 350px; - background-color: #506be6; - color : #fff; - box-shadow : 0px 0px 50px 0px #000; - position : absolute; - left : 40; - top : 40; -} - -.menu .head { - text-align : center; - height : 40px; - line-height : 40px; -} - -.menu .menu-items .menu-item { - height : 40px; - display : block; - background-color: #f1f1f1; - box-shadow : inset 1px 0px 0px 1px #b8b8b8; - height : 32px; - line-height : 32px; - color : #3A3A3A; - text-align : center; -} - -.menu .menu-items .menu-item.selected { - background-color: #d0d0d0; -} \ No newline at end of file diff --git a/html/img/keys/enter.png b/html/img/keys/enter.png deleted file mode 100644 index 3eb9a1f69f58c651517329c92d28cdb1c605f165..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 941 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 diff --git a/html/scripts/app.js b/html/scripts/app.js deleted file mode 100644 index 6f0e1a3c..00000000 --- a/html/scripts/app.js +++ /dev/null @@ -1,168 +0,0 @@ -(function(){ - - let DefaultTpl = - '
    {{title}}
    ' + - ''+ - '
    ' - ; - - let DefaultWithTypeAndCountTpl = - '
    {{title}}
    ' + - ''+ - '
    ' - ; - - let menus = { - - cloakroom : { - title : 'Vestiaire', - visible : false, - current : 0, - hasControl: true, - template : DefaultTpl, - - items: [ - {label: 'Tenue civile', value: 'citizen_wear'}, - {label: 'Tenue de travail', value: 'job_wear'} - ] - }, - } - - let renderMenus = function(){ - for(let k in menus){ - - let elem = $('#menu_' + k); - - elem.html(Mustache.render(menus[k].template, menus[k])); - - if(menus[k].visible) - elem.show(); - else - elem.hide(); - - } - } - - let showMenu = function(menu){ - - currentMenu = menu; - - for(let k in menus) - menus[k].visible = false; - - menus[menu].visible = true; - - renderMenus(); - - if(menus[currentMenu].items.length > 0){ - - $('#menu_' + currentMenu + ' .menu-item').removeClass('selected'); - $('#menu_' + currentMenu + ' .menu-item:eq(0)').addClass('selected'); - - menus[currentMenu].current = 0; - currentVal = menus[currentMenu].items[menus[currentMenu].current].value; - currentType = $('#menu_' + currentMenu + ' .menu-item:eq(0)').data('type'); - currentCount = $('#menu_' + currentMenu + ' .menu-item:eq(0)').data('count'); - } - - isMenuOpen = true - } - - let hideMenus = function(){ - - for(let k in menus) - menus[k].visible = false; - - renderMenus(); - isMenuOpen = false; - } - - let isMenuOpen = false - let currentMenu = null; - let currentControl = null; - let currentVal = null; - let currentType = null; - let currentCount = null; - - renderMenus(); - - window.onData = function(data){ - - if(data.showMenu === true){ - showMenu(data.menu); - } - - if(data.showMenu === false){ - hideMenus(); - } - - if(data.move && isMenuOpen){ - - if(data.move == 'UP'){ - if(menus[currentMenu].current > 0) - menus[currentMenu].current--; - } - - if(data.move == 'DOWN'){ - - let max = $('#menu_' + currentMenu + ' .menu-item').length; - - if(menus[currentMenu].current < max - 1) - menus[currentMenu].current++; - } - - $('#menu_' + currentMenu + ' .menu-item').removeClass('selected'); - $('#menu_' + currentMenu + ' .menu-item:eq(' + menus[currentMenu].current + ')').addClass('selected'); - - currentVal = menus[currentMenu].items[menus[currentMenu].current].value; - currentType = $('#menu_' + currentMenu + ' .menu-item:eq(' + menus[currentMenu].current + ')').data('type'); - currentCount = $('#menu_' + currentMenu + ' .menu-item:eq(' + menus[currentMenu].current + ')').data('count'); - } - - if(data.enterPressed){ - - if(isMenuOpen) { - - $.post('http://esx_jobs/select', JSON.stringify({ - menu : currentMenu, - val : currentVal, - type : currentType, - count: currentCount - })) - - let elem = $('#menu_' + currentMenu + ' .menu-item.selected') - - if(elem.data('remove-on-select') == true){ - - elem.remove(); - - menus[currentMenu].items.splice(menus[currentMenu].current, 1) - menus[currentMenu].current = 0; - - $('#menu_' + currentMenu + ' .menu-item').removeClass('selected'); - $('#menu_' + currentMenu + ' .menu-item:eq(0)').addClass('selected'); - - currentVal = menus[currentMenu].items[0].value; - currentType = $('#menu_' + currentMenu + ' .menu-item:eq(0)').data('type'); - currentCount = $('#menu_' + currentMenu + ' .menu-item:eq(0)').data('count'); - } - - } - - } - - if(data.backspacePressed){ - if(isMenuOpen && currentMenu == 'cloakroom'){ - hideMenus(); - } - } - - } - - window.onload = function(e){ window.addEventListener('message', function(event){ onData(event.data) }); } - -})() \ No newline at end of file diff --git a/html/scripts/mustache.min.js b/html/scripts/mustache.min.js deleted file mode 100644 index 520cfcb9..00000000 --- a/html/scripts/mustache.min.js +++ /dev/null @@ -1 +0,0 @@ -(function defineMustache(global,factory){if(typeof exports==="object"&&exports&&typeof exports.nodeName!=="string"){factory(exports)}else if(typeof define==="function"&&define.amd){define(["exports"],factory)}else{global.Mustache={};factory(global.Mustache)}})(this,function mustacheFactory(mustache){var objectToString=Object.prototype.toString;var isArray=Array.isArray||function isArrayPolyfill(object){return objectToString.call(object)==="[object Array]"};function isFunction(object){return typeof object==="function"}function typeStr(obj){return isArray(obj)?"array":typeof obj}function escapeRegExp(string){return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}function hasProperty(obj,propName){return obj!=null&&typeof obj==="object"&&propName in obj}var regExpTest=RegExp.prototype.test;function testRegExp(re,string){return regExpTest.call(re,string)}var nonSpaceRe=/\S/;function isWhitespace(string){return!testRegExp(nonSpaceRe,string)}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(string){return String(string).replace(/[&<>"'`=\/]/g,function fromEntityMap(s){return entityMap[s]})}var whiteRe=/\s*/;var spaceRe=/\s+/;var equalsRe=/\s*=/;var curlyRe=/\s*\}/;var tagRe=/#|\^|\/|>|\{|&|=|!/;function parseTemplate(template,tags){if(!template)return[];var sections=[];var tokens=[];var spaces=[];var hasTag=false;var nonSpace=false;function stripSpace(){if(hasTag&&!nonSpace){while(spaces.length)delete tokens[spaces.pop()]}else{spaces=[]}hasTag=false;nonSpace=false}var openingTagRe,closingTagRe,closingCurlyRe;function compileTags(tagsToCompile){if(typeof tagsToCompile==="string")tagsToCompile=tagsToCompile.split(spaceRe,2);if(!isArray(tagsToCompile)||tagsToCompile.length!==2)throw new Error("Invalid tags: "+tagsToCompile);openingTagRe=new RegExp(escapeRegExp(tagsToCompile[0])+"\\s*");closingTagRe=new RegExp("\\s*"+escapeRegExp(tagsToCompile[1]));closingCurlyRe=new RegExp("\\s*"+escapeRegExp("}"+tagsToCompile[1]))}compileTags(tags||mustache.tags);var scanner=new Scanner(template);var start,type,value,chr,token,openSection;while(!scanner.eos()){start=scanner.pos;value=scanner.scanUntil(openingTagRe);if(value){for(var i=0,valueLength=value.length;i0?sections[sections.length-1][4]:nestedTokens;break;default:collector.push(token)}}return nestedTokens}function Scanner(string){this.string=string;this.tail=string;this.pos=0}Scanner.prototype.eos=function eos(){return this.tail===""};Scanner.prototype.scan=function scan(re){var match=this.tail.match(re);if(!match||match.index!==0)return"";var string=match[0];this.tail=this.tail.substring(string.length);this.pos+=string.length;return string};Scanner.prototype.scanUntil=function scanUntil(re){var index=this.tail.search(re),match;switch(index){case-1:match=this.tail;this.tail="";break;case 0:match="";break;default:match=this.tail.substring(0,index);this.tail=this.tail.substring(index)}this.pos+=match.length;return match};function Context(view,parentContext){this.view=view;this.cache={".":this.view};this.parent=parentContext}Context.prototype.push=function push(view){return new Context(view,this)};Context.prototype.lookup=function lookup(name){var cache=this.cache;var value;if(cache.hasOwnProperty(name)){value=cache[name]}else{var context=this,names,index,lookupHit=false;while(context){if(name.indexOf(".")>0){value=context.view;names=name.split(".");index=0;while(value!=null&&index")value=this.renderPartial(token,context,partials,originalTemplate);else if(symbol==="&")value=this.unescapedValue(token,context);else if(symbol==="name")value=this.escapedValue(token,context);else if(symbol==="text")value=this.rawValue(token);if(value!==undefined)buffer+=value}return buffer};Writer.prototype.renderSection=function renderSection(token,context,partials,originalTemplate){var self=this;var buffer="";var value=context.lookup(token[1]);function subRender(template){return self.render(template,context,partials)}if(!value)return;if(isArray(value)){for(var j=0,valueLength=value.length;j - - - - - - - - - - - - - - \ No newline at end of file diff --git a/locales/en.lua b/locales/en.lua index add423f5..427901ec 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -5,7 +5,7 @@ Locales['en'] = { ['bank_deposit'] = 'a security deposit of ~g~', ['bank_deposit_r'] = 'a security deposit of ~g~$', ['bank_deposit2'] = '$ ~s~was made to you after your fainting.', - ['bank_nodeposit'] = "you did not have a surety", + ['bank_nodeposit'] = "you did not have a security deposit", ['foot_work'] = 'you have to be on foot to be able to work.', ['next_point'] = 'go to the next step after completing this one.', ['security_deposit'] = 'the security given will be ~g~$', diff --git a/locales/fr.lua b/locales/fr.lua index d2cc73b1..e8c9a6cb 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -2,6 +2,8 @@ Locales['fr'] = { --Global menus ['cloakroom'] = 'vestiaire', ['cloak_change'] = 'appuyez sur ~INPUT_PICKUP~ pour vous changer.', + ['citizen_wear'] = 'Tenue civile', + ['job_wear'] = 'Tenue de travail', ['bank_deposit'] = 'une caution de ~g~', ['bank_deposit_r'] = 'une caution de ~g~$', ['bank_deposit2'] = '$ ~s~vous a été rendue suite à votre évanouissment.', diff --git a/server/esx_jobs_sv.lua b/server/esx_jobs_sv.lua index dca0a4ea..eef5999a 100644 --- a/server/esx_jobs_sv.lua +++ b/server/esx_jobs_sv.lua @@ -5,7 +5,8 @@ ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) AddEventHandler('esx:playerLoaded', function(source) - local xPlayer = ESX.GetPlayerFromId(source) + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) xPlayer.set('caution', 0) end) @@ -29,19 +30,17 @@ RegisterServerEvent('esx_jobs:giveBackCautionInCaseOfDrop') AddEventHandler('esx_jobs:giveBackCautionInCaseOfDrop', function() local _source = source local xPlayer = ESX.GetPlayerFromId(_source) - - local caution = 0 + TriggerEvent('esx_addonaccount:getAccount', 'caution', xPlayer.identifier, function(account) - caution = account.money + local caution = account.money account.removeMoney(caution) + if caution > 0 then + xPlayer.addAccountMoney('bank', caution) + TriggerClientEvent('esx:showNotification', _source, _U('bank_deposit_g').. caution .. _U('bank_deposit2')) + else + TriggerClientEvent('esx:showNotification', _source, _U('bank_nodeposit')) + end end) - - if caution > 0 then - xPlayer.addAccountMoney('bank', value) - TriggerClientEvent('esx:showNotification', _source, _U('bank_deposit_g').. value .. _U('bank_deposit2')) - else - TriggerClientEvent('esx:showNotification', _source, _U('bank_nodeposit')) - end end) local function Work(source, item) From 72bdade0459623160bc9b5db1430452f814dc866 Mon Sep 17 00:00:00 2001 From: Don <30905704+ddh3@users.noreply.github.com> Date: Mon, 21 Aug 2017 20:30:52 -0700 Subject: [PATCH 0535/3224] Update esx_jobs_sv.lua --- server/esx_jobs_sv.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/esx_jobs_sv.lua b/server/esx_jobs_sv.lua index eef5999a..50b84545 100644 --- a/server/esx_jobs_sv.lua +++ b/server/esx_jobs_sv.lua @@ -66,7 +66,7 @@ local function Work(source, item) elseif item[i].requires ~= "nothing" and requiredItemQtty <= 0 then TriggerClientEvent('esx:showNotification', source, _U('not_enough') .. item[1].requires_name .. _U('not_enough2')) else - if item[i].name ~= "Livraison" then + if item[i].name ~= _U('delivery') then -- Chances to drop the item if item[i].drop == 100 then xPlayer.addInventoryItem(item[i].db_name, item[i].add) From 2163d0c8d9155d493c7d717de2cade00eaf07739 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 22 Aug 2017 00:46:41 -0400 Subject: [PATCH 0536/3224] Multi-language support --- __resource.lua | 8 ++++++- client/main.lua | 36 ++++++++++++++--------------- config.lua | 61 +++++++++++++++++++++++++------------------------ locales/en.lua | 23 +++++++++++++++++++ locales/fr.lua | 23 +++++++++++++++++++ server/main.lua | 4 ++-- 6 files changed, 104 insertions(+), 51 deletions(-) create mode 100644 locales/en.lua create mode 100644 locales/fr.lua diff --git a/__resource.lua b/__resource.lua index 1baf6c0a..e46bb7eb 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,8 +1,14 @@ server_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', 'server/main.lua' } client_scripts { + '@es_extended/locale.lua', + 'locales/en.lua', + 'locales/fr.lua', 'config.lua', 'client/main.lua' -} \ No newline at end of file +} diff --git a/client/main.lua b/client/main.lua index 423eb5b4..3938d12b 100644 --- a/client/main.lua +++ b/client/main.lua @@ -40,14 +40,14 @@ function OpenLSMenu(elems, menuname, menutitle, parent) local found = false for k,v in pairs(Config.Menus) do if k == data.current.modType or isRimMod then - if data.current.label == "Par défaut" or string.match(data.current.label, "Installé") then - ESX.ShowNotification("Vous possédez déjà: ~b~" .. data.current.label) + if data.current.label == _U('by_default') or string.match(data.current.label, _U('installed')) then + ESX.ShowNotification(_U('already_own') .. data.current.label) else if isRimMod then TriggerServerEvent("esx_lscustom:buyMod", data.current.price) else TriggerServerEvent("esx_lscustom:buyMod", v.price) - end + end end menu.close() found = true @@ -64,7 +64,7 @@ function OpenLSMenu(elems, menuname, menutitle, parent) if parent == nil then lsMenuIsShowed = false local vehicle = GetVehiclePedIsIn(GetPlayerPed(-1), false) - FreezeEntityPosition(vehicle, false) + FreezeEntityPosition(vehicle, false) myCar = nil end end, @@ -122,16 +122,16 @@ function GetAction(data) if v.modType ~= nil then if v.modType == 22 then - table.insert(elements, {label = " Par défaut", modType = k, modNum = false}) + table.insert(elements, {label = " " .. _U('by_default'), modType = k, modNum = false}) else - table.insert(elements, {label = " Par défaut", modType = k, modNum = -1}) + table.insert(elements, {label = " " .. _U('by_default'), modType = k, modNum = -1}) end if v.modType == 14 then -- HORNS for j = 0, 51, 1 do local _label = '' if j == currentMods.modHorns then - _label = GetHornName(j) .. ' - Installé' + _label = GetHornName(j) .. ' - '.. _U('installed') ..'' else _label = GetHornName(j) .. ' - $' .. v.price .. ' ' end @@ -141,7 +141,7 @@ function GetAction(data) for j = 0, 4, 1 do local _label = '' if j == currentMods.plateIndex then - _label = GetPlatesName(j) .. ' - Installé' + _label = GetPlatesName(j) .. ' - '.. _U('installed') ..'' else _label = GetPlatesName(j) .. ' - $' .. v.price .. ' ' end @@ -150,7 +150,7 @@ function GetAction(data) elseif v.modType == 22 then -- XENON local _label = '' if currentMods.modXenon then - _label = 'Xénon - Installé' + _label = 'Xénon - '.. _U('installed') ..'' else _label = 'Xénon - $' .. v.price .. ' ' end @@ -177,7 +177,7 @@ function GetAction(data) for j = 1, 5, 1 do local _label = '' if j == currentMods.modHorns then - _label = GetWindowName(j) .. ' - Installé' + _label = GetWindowName(j) .. ' - '.. _U('installed') ..'' else _label = GetWindowName(j) .. ' - $' .. v.price .. ' ' end @@ -195,7 +195,7 @@ function GetAction(data) if modName ~= nil then local _label = '' if j == currentMods.modFrontWheels then - _label = GetLabelText(modName) .. ' - Installé' + _label = GetLabelText(modName) .. ' - '.. _U('installed') ..'' else _label = GetLabelText(modName) .. ' - $' .. v.price .. ' ' end @@ -207,7 +207,7 @@ function GetAction(data) for j = 0, modCount-1, 1 do local _label = '' if j == currentMods[k] then - _label = 'Niveau ' .. j .. ' - Installé' + _label = 'Niveau ' .. j .. ' - '.. _U('installed') ..'' else _label = 'Niveau ' .. j .. ' - $' .. v.price .. ' ' end @@ -220,7 +220,7 @@ function GetAction(data) if modName ~= nil then local _label = '' if j == currentMods[k] then - _label = GetLabelText(modName) .. ' - Installé' + _label = GetLabelText(modName) .. ' - '.. _U('installed') ..'' else _label = GetLabelText(modName) .. ' - $' .. v.price .. ' ' end @@ -236,12 +236,12 @@ function GetAction(data) elseif data.value == 'secondaryRespray' then table.insert(elements, {label = Config.Colors[i].label, value = 'color2', color = Config.Colors[i].value}) elseif data.value == 'pearlescentRespray' then - table.insert(elements, {label = Config.Colors[i].label, value = 'pearlescentColor', color = Config.Colors[i].value}) + table.insert(elements, {label = Config.Colors[i].label, value = 'pearlescentColor', color = Config.Colors[i].value}) elseif data.value == 'modFrontWheelsColor' then table.insert(elements, {label = Config.Colors[i].label, value = 'wheelColor', color = Config.Colors[i].value}) end end - else + else for l,w in pairs(v) do if l ~= 'label' and l ~= 'parent' then table.insert(elements, {label = w, value = l}) @@ -298,12 +298,12 @@ Citizen.CreateThread(function() end end - if IsControlJustReleased(0, 38) and not lsMenuIsShowed and isInLSMarker then + if IsControlJustReleased(0, 38) and not lsMenuIsShowed and isInLSMarker then lsMenuIsShowed = true local vehicle = GetVehiclePedIsIn(playerPed, false) - --SetVehicleUndriveable(vehicle, true) + --SetVehicleUndriveable(vehicle, true) FreezeEntityPosition(vehicle, true) myCar = ESX.Game.GetVehicleProperties(vehicle) @@ -335,4 +335,4 @@ end) --_GET_LABEL_TEXT to get the part name in the games language --local Veh = GetVehiclePedIsIn(GetPlayerPed(-1), true) ---local VehType = GetLabelText(GetDisplayNameFromVehicleModel(GetEntityModel(Veh))) \ No newline at end of file +--local VehType = GetLabelText(GetDisplayNameFromVehicleModel(GetEntityModel(Veh))) diff --git a/config.lua b/config.lua index 2866bc18..d81cefa3 100644 --- a/config.lua +++ b/config.lua @@ -1,14 +1,15 @@ Config = {} Config.DrawDistance = 100.0 +Config.Locale = 'fr' -Config.Zones = { +Config.Zones = { ls1 = { Pos = { x = -362.7962, y = -132.4005, z = 38.25239}, Size = {x = 3.0, y = 3.0, z = 0.2}, Color = {r = 204, g = 204, b = 0}, Marker= 1, Name = "LS CUSTOM", - Hint = "Appuyez sur ~INPUT_PICKUP~ pour personnaliser le véhicule." + Hint = _U('press_custom') } } @@ -31,7 +32,7 @@ Config.Colors = { function GetColors(color) local colors = {} if color == 'black' then - colors = { + colors = { { index = 0, label = 'Noir'}, { index = 1, label = 'Graphite'}, { index = 2, label = 'Noir Métallisé'}, @@ -41,10 +42,10 @@ function GetColors(color) { index = 15, label = 'Nuit Sombre'}, { index = 16, label = 'Noir Profond'}, { index = 21, label = 'Pétrol'}, - { index = 147, label = 'Carbon'} + { index = 147, label = 'Carbon'} } elseif color == 'white' then - colors = { + colors = { { index = 106, label = 'Vanille'}, { index = 107, label = 'Crème'}, { index = 111, label = 'Blanc'}, @@ -54,10 +55,10 @@ function GetColors(color) { index = 122, label = 'Neige'}, { index = 131, label = 'Coton'}, { index = 132, label = 'Albâtre'}, - { index = 134, label = 'Blanc Pure'} + { index = 134, label = 'Blanc Pure'} } elseif color == 'grey' then - colors = { + colors = { { index = 4, label = 'Argenté'}, { index = 5, label = 'Gris Métallisé'}, { index = 6, label = 'Acier Laminé'}, @@ -79,10 +80,10 @@ function GetColors(color) { index = 66, label = 'Acier Bleui'}, { index = 93, label = 'Champagne'}, { index = 144, label = 'Gris Chasseur'}, - { index = 156, label = 'Gris'} - } + { index = 156, label = 'Gris'} + } elseif color == 'red' then - colors = { + colors = { { index = 27, label = 'Rouge'}, { index = 28, label = 'Rouge Turin'}, { index = 29, label = 'Coquelicot'}, @@ -98,16 +99,16 @@ function GetColors(color) { index = 44, label = 'Rouge Brillant'}, { index = 46, label = 'Rouge Pale'}, { index = 143, label = 'Rouge Vin'}, - { index = 150, label = 'Volcano'} + { index = 150, label = 'Volcano'} } elseif color == 'pink' then - colors = { + colors = { { index = 135, label = 'Rose Electrique'}, { index = 136, label = 'Rose Saumon'}, - { index = 137, label = 'Rose Dragée'} - } + { index = 137, label = 'Rose Dragée'} + } elseif color == 'blue' then - colors = { + colors = { { index = 54, label = 'Topaze'}, { index = 60, label = 'Bleu Clair'}, { index = 61, label = 'Bleu Galaxy'}, @@ -137,17 +138,17 @@ function GetColors(color) { index = 141, label = 'Bleu Minuit'}, { index = 146, label = 'Bleu Interdit'}, { index = 157, label = 'Bleu Glacier'} - } + } elseif color == 'yellow' then - colors = { + colors = { { index = 42, label = 'Jaune'}, { index = 88, label = 'Jaune Blé'}, { index = 89, label = 'Jaune Rally'}, { index = 91, label = 'Jaune Clair'}, - { index = 126, label = 'Jaune Pale'} - } + { index = 126, label = 'Jaune Pale'} + } elseif color == 'green' then - colors = { + colors = { { index = 49, label = 'Vert Foncé'}, { index = 50, label = 'Vert Rally'}, { index = 51, label = 'Vert Sapin'}, @@ -164,20 +165,20 @@ function GetColors(color) { index = 133, label = 'Vert Army'}, { index = 151, label = 'Vert Sombre'}, { index = 152, label = 'Vert Chasseur'}, - { index = 155, label = 'Amarylisse'} + { index = 155, label = 'Amarylisse'} } elseif color == 'orange' then - colors = { + colors = { { index = 36, label = 'Tangerine'}, { index = 38, label = 'Orange'}, { index = 41, label = 'Orange Mat'}, { index = 123, label = 'Orange Clair'}, { index = 124, label = 'Pèche'}, { index = 130, label = 'Citrouille'}, - { index = 138, label = 'Orange Lambo'} + { index = 138, label = 'Orange Lambo'} } elseif color == 'brown' then - colors = { + colors = { { index = 45, label = 'Cuivre'}, { index = 47, label = 'Marron clair'}, { index = 48, label = 'Marron Foncé'}, @@ -202,7 +203,7 @@ function GetColors(color) { index = 116, label = 'Blond'}, { index = 129, label = 'Gravillon'}, { index = 153, label = 'Terre Foncé'}, - { index = 154, label = 'Désert'} + { index = 154, label = 'Désert'} } elseif color == 'purple' then colors = { @@ -213,7 +214,7 @@ function GetColors(color) { index = 142, label = 'Violet Mystique'}, { index = 145, label = 'Violet Métallisé'}, { index = 148, label = 'Vilot Mat'}, - { index = 149, label = 'Violet Profond Mat'} + { index = 149, label = 'Violet Profond Mat'} } elseif color == 'chrome' then colors = { @@ -229,7 +230,7 @@ function GetColors(color) { index = 159, label = 'Or Brossé'}, { index = 160, label = 'Or Clair'} } - end + end return colors end @@ -361,7 +362,7 @@ end function GetNeons() local neons = { - { label = "white", r = 255, g = 255, b = 255}, + { label = "white", r = 255, g = 255, b = 255}, { label = "slate_gray", r = 112, g = 128, b = 144}, { label = "blue", r = 0, g = 0, b = 255}, { label = "light_blue", r = 0, g = 150, b = 255}, @@ -538,7 +539,7 @@ Config.Menus = { wheelType = 7, price = 500 }, - modFrontWheelsColor = { + modFrontWheelsColor = { label = 'Peinture Jantes', parent = 'wheels' }, @@ -693,4 +694,4 @@ Config.Menus = { price = 500 } -} \ No newline at end of file +} diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..e69bd5e6 --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,23 @@ +Locales['en'] = { + + ['by_default'] = 'by default', + ['installed'] = 'installed', + ['already_own'] = 'you already own: ~b~', + ['not_enough_money'] = 'you do not have enough money!', + ['purchased'] = 'purchased!', + ['press_custom'] = 'press ~INPUT_PICKUP~ to personalize your vehicle.', + ['black'] = 'black', + ['white'] = 'white', + ['grey'] = 'grey', + ['red'] = 'red', + ['pink'] = 'pink', + ['blue'] = 'blue', + ['yellow'] = 'yellow', + ['green'] = 'green', + ['orange'] = 'orange', + ['brown'] = 'brown', + ['purple'] = 'purple', + ['chrome'] = 'chrome', + ['gold'] = 'gold', + +} diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..2617a8b8 --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,23 @@ +Locales['fr'] = { + + ['by_default'] = 'par défaut', + ['installed'] = 'installé', + ['already_own'] = 'vous possédez déjà: ~b~', + ['not_enough_money'] = 'vous n\'avez pas assez d\'argent !', + ['purchased'] = 'achat effectué !', + ['press_custom'] = 'appuyez sur ~INPUT_PICKUP~ pour personnaliser le véhicule.', + ['black'] = 'noir', + ['white'] = 'blanc', + ['grey'] = 'gris', + ['red'] = 'rouge', + ['pink'] = 'rose', + ['blue'] = 'bleu', + ['yellow'] = 'jaune', + ['green'] = 'vert', + ['orange'] = 'orange', + ['brown'] = 'marron', + ['purple'] = 'violet', + ['chrome'] = 'chrome', + ['gold'] = 'or', + +} diff --git a/server/main.lua b/server/main.lua index 991c4ed9..26ebe2a7 100644 --- a/server/main.lua +++ b/server/main.lua @@ -8,10 +8,10 @@ AddEventHandler('esx_lscustom:buyMod', function(price) price = tonumber(price) if price > xPlayer.getMoney() then TriggerClientEvent('esx_lscustom:cancelInstallMod', _source) - TriggerClientEvent('esx:showNotification', _source, "Vous n'avez pas assez d'argent !") + TriggerClientEvent('esx:showNotification', _source, _U('not_enough_money')) else xPlayer.removeMoney(price) TriggerClientEvent('esx_lscustom:installMod', _source) - TriggerClientEvent('esx:showNotification', _source, "Achat effectué !") + TriggerClientEvent('esx:showNotification', _source, _U('purchased')) end end) From ad7a2b5be9c9b067b3a12e16dfcba866f6ac1068 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 22 Aug 2017 00:54:22 -0400 Subject: [PATCH 0537/3224] Update language support Add color categories --- config.lua | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/config.lua b/config.lua index d81cefa3..83bfa301 100644 --- a/config.lua +++ b/config.lua @@ -14,19 +14,19 @@ Config.Zones = { } Config.Colors = { - { label = 'Noir', value = 'black'}, - { label = 'Blanc', value = 'white'}, - { label = 'Gris', value = 'grey'}, - { label = 'Rouge', value = 'red'}, - { label = 'Rose', value = 'pink'}, - { label = 'Bleu', value = 'blue'}, - { label = 'Jaune', value = 'yellow'}, - { label = 'Vert', value = 'green'}, - { label = 'Orange', value = 'orange'}, - { label = 'Marron', value = 'brown'}, - { label = 'Violet', value = 'purple'}, - { label = 'Chrome', value = 'chrome'}, - { label = 'Or', value = 'gold'}, + { label = _U('black'), value = 'black'}, + { label = _U('white'), value = 'white'}, + { label = _U('grey'), value = 'grey'}, + { label = _U('red'), value = 'red'}, + { label = _U('pink'), value = 'pink'}, + { label = _U('blue'), value = 'blue'}, + { label = _U('yellow'), value = 'yellow'}, + { label = _U('green'), value = 'green'}, + { label = _U('orange'), value = 'orange'}, + { label = _U('brown'), value = 'brown'}, + { label = _U('purple'), value = 'purple'}, + { label = _U('chrome'), value = 'chrome'}, + { label = _U('gold'), value = 'gold'}, } function GetColors(color) From 1c6880e626ce4702b0b8a451bb45694814f01085 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 22 Aug 2017 10:14:40 +0200 Subject: [PATCH 0538/3224] Remove debug code --- client/main.lua | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/client/main.lua b/client/main.lua index 4347ba4e..ad69660e 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,5 +1,3 @@ -DoScreenFadeIn(0) - local Keys = { ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, @@ -41,10 +39,8 @@ function RespawnPed(ped, coords) end function StartRespawnToHospitalMenuTimer() - Citizen.Trace('starting timer') - ESX.SetTimeout(Config.MenuRespawnToHospitalDelay, function() - Citizen.Trace('menu should appear') + ESX.SetTimeout(Config.MenuRespawnToHospitalDelay, function() if IsDead then @@ -60,17 +56,18 @@ function StartRespawnToHospitalMenuTimer() elements = elements }, function(data, menu) --Submit Cb - menu.close() + + menu.close() + + Citizen.CreateThread(function() - Citizen.CreateThread(function() + DoScreenFadeOut(800) - DoScreenFadeOut(800) + while not IsScreenFadedOut() do + Citizen.Wait(0) + end - while not IsScreenFadedOut() do - Citizen.Wait(0) - end - - ESX.TriggerServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function() + ESX.TriggerServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function() TriggerServerEvent('esx:updateLastPosition', Config.Zones.HospitalInteriorInside1.Pos) From 4d4b6b61ac0b63f8c97a05b8e11f994357cbaf82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 22 Aug 2017 10:41:24 +0200 Subject: [PATCH 0539/3224] Clsoe menus when exit marker --- client/main.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/client/main.lua b/client/main.lua index 6fbf62b9..5ef3da02 100644 --- a/client/main.lua +++ b/client/main.lua @@ -139,6 +139,7 @@ AddEventHandler('esx_barbershop:hasEnteredMarker', function(zone) end) AddEventHandler('esx_barbershop:hasExitedMarker', function(zone) + ESX.UI.Menu.CloseAll() CurrentAction = nil end) From 1400ab66b1b42b99baa81f3ddb7b568672694ac1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 22 Aug 2017 10:52:32 +0200 Subject: [PATCH 0540/3224] Check if user has payed when exiting marker --- client/main.lua | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/client/main.lua b/client/main.lua index 5ef3da02..188840d1 100644 --- a/client/main.lua +++ b/client/main.lua @@ -18,6 +18,7 @@ local LastZone = nil local CurrentAction = nil local CurrentActionMsg = '' local CurrentActionData = {} +local HasPayed = false Citizen.CreateThread(function() @@ -30,6 +31,8 @@ end) function OpenShopMenu() + HasPayed = false + TriggerEvent('esx_skin:openRestrictedMenu', function(data, menu) menu.close() @@ -59,6 +62,8 @@ function OpenShopMenu() end) TriggerServerEvent('esx_barbershop:pay') + + HasPayed = true else TriggerEvent('esx_skin:getLastSkin', function(skin) @@ -139,8 +144,18 @@ AddEventHandler('esx_barbershop:hasEnteredMarker', function(zone) end) AddEventHandler('esx_barbershop:hasExitedMarker', function(zone) + ESX.UI.Menu.CloseAll() CurrentAction = nil + + if not HasPayed then + + TriggerEvent('esx_skin:getLastSkin', function(skin) + TriggerEvent('skinchanger:loadSkin', skin) + end) + + end + end) -- Create Blips From a20c9b3cbdf466f4e1da8dec201e909a55e365d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 22 Aug 2017 10:53:07 +0200 Subject: [PATCH 0541/3224] Check if user has payed when exiting marker --- client/main.lua | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index 8023038c..945f24d2 100644 --- a/client/main.lua +++ b/client/main.lua @@ -18,6 +18,7 @@ local LastZone = nil local CurrentAction = nil local CurrentActionMsg = '' local CurrentActionData = {} +local HasPayed = false Citizen.CreateThread(function() @@ -30,6 +31,8 @@ end) function OpenShopMenu() + HasPayed = false + TriggerEvent('esx_skin:openRestrictedMenu', function(data, menu) menu.close() @@ -60,6 +63,8 @@ function OpenShopMenu() TriggerServerEvent('esx_clotheshop:pay') + HasPayed = true + ESX.TriggerServerCallback('esx_clotheshop:checkPropertyDataStore', function(foundStore) if foundStore then @@ -145,8 +150,8 @@ function OpenShopMenu() 'pants_2', 'shoes_1', 'shoes_2', - 'chain_1', - 'chain_2', + 'chain_1', + 'chain_2', 'helmet_1', 'helmet_2', 'glasses_1', @@ -162,8 +167,18 @@ AddEventHandler('esx_clotheshop:hasEnteredMarker', function(zone) end) AddEventHandler('esx_clotheshop:hasExitedMarker', function(zone) + ESX.UI.Menu.CloseAll() CurrentAction = nil + + if not HasPayed then + + TriggerEvent('esx_skin:getLastSkin', function(skin) + TriggerEvent('skinchanger:loadSkin', skin) + end) + + end + end) -- Create Blips From b3036dbeff3f1eaaebbddd22ffd1c97657b20147 Mon Sep 17 00:00:00 2001 From: Don Date: Tue, 22 Aug 2017 01:58:44 -0700 Subject: [PATCH 0542/3224] Update multi-language support Update multi-language support --- __resource.lua | 2 +- en_config.lua | 45 ++++++++++ jobs/fisherman.lua | 2 +- jobs/fuel.lua | 48 +++++------ jobs/lumberjack.lua | 2 +- jobs/miner.lua | 2 +- jobs/slaughterer.lua | 2 +- jobs/textil.lua | 2 +- locales/en.lua | 183 ++++++++++++++++++++++------------------ locales/fr.lua | 184 ++++++++++++++++++++++------------------- server/esx_jobs_sv.lua | 2 +- 11 files changed, 279 insertions(+), 195 deletions(-) create mode 100644 en_config.lua diff --git a/__resource.lua b/__resource.lua index 4947d088..49121d1a 100644 --- a/__resource.lua +++ b/__resource.lua @@ -22,4 +22,4 @@ client_scripts { 'jobs/slaughterer.lua', 'jobs/textil.lua', 'client/esx_jobs_cl.lua' -} \ No newline at end of file +} diff --git a/en_config.lua b/en_config.lua new file mode 100644 index 00000000..0c0109ba --- /dev/null +++ b/en_config.lua @@ -0,0 +1,45 @@ +Config = {} +Config.DrawDistance = 1000.0 +Config.Locale = 'en' + +Config.Plates = { + taxi = "TAXI", + fisherman = "FISH", + cop = "LSPD", + ambulance = "EMS", + depanneur = "MECA", + fuel = "FUEL", + lumberjack = "BUCH", + miner = "MINE", + reporter = "JOUR", + slaughterer = "ABAT", + textil = "COUT" +} + +Config.Jobs = {} + +Config.PublicZones = { + EnterBuilding = { + Pos = { x = -118.21381378174, y = -607.14227294922, z = 35.280723571777 }, + Size = {x = 3.0, y = 3.0, z = 0.2}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = false, + Name = "San Andreas Times", + Type = "teleport", + Hint = "Press ~INPUT_PICKUP~ to enter the building.", + Teleport = { x = -139.09838867188, y = -620.74865722656, z = 167.82052612305 } + }, + + ExitBuilding = { + Pos = { x = -139.45831298828, y = -617.32312011719, z = 167.82052612305 }, + Size = {x = 3.0, y = 3.0, z = 0.2}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = false, + Name = "San Andreas Times", + Type = "teleport", + Hint = "Press ~INPUT_PICKUP~ to go to the entrance of the building.", + Teleport = { x = -113.07, y = -604.93, z = 35.28 }, + }, +} diff --git a/jobs/fisherman.lua b/jobs/fisherman.lua index eca1756d..d28a858c 100644 --- a/jobs/fisherman.lua +++ b/jobs/fisherman.lua @@ -24,7 +24,7 @@ Config.Jobs.fisherman = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = _U('cloakroom'), + Name = _U('fm_fish_locker'), Type = "cloakroom", Hint = _U('cloak_change'), GPS = {x = 880.74462890625, y = -1663.9635009766, z = 29.370491027832} diff --git a/jobs/fuel.lua b/jobs/fuel.lua index 653906b0..83d52372 100644 --- a/jobs/fuel.lua +++ b/jobs/fuel.lua @@ -18,9 +18,9 @@ Config.Jobs.fuel = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = "Vestiaire", + Name = _U('f_oil_refiner'), Type = "cloakroom", - Hint = "Appuyez sur ~INPUT_PICKUP~ pour vous changer.", + Hint = _U('cloak_change'), GPS = {x = 554.597, y = -2314.43, z = 4.86293} }, @@ -30,11 +30,11 @@ Config.Jobs.fuel = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = "Pétrol", + Name = _U('f_drill_oil'), Type = "work", Item = { { - name = "Pétrol", + name = _U('f_fuel'), db_name= "petrol", time = 5000, max = 24, @@ -45,7 +45,7 @@ Config.Jobs.fuel = { drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour forer.", + Hint = _U('f_drillbutton'), GPS = {x = 2736.94, y = 1417.99, z = 23.4888} }, @@ -55,22 +55,22 @@ Config.Jobs.fuel = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = "Pétrol raffiné", + Name = _U('f_fuel_refine'), Type = "work", Item = { { - name = "Pétrol raffiné", + name = _U('f_fuel_refine'), db_name= "petrol_raffin", time = 5000, max = 20, add = 1, remove = 2, requires = "petrol", - requires_name = "Pétrol", + requires_name = _U('f_fuel'), drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour raffiner.", + Hint = _U('f_refine_fuel_button'), GPS = {x = 265.752, y = -3013.39, z = 4.73275} }, @@ -80,22 +80,22 @@ Config.Jobs.fuel = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = "Mélange", + Name = _U('f_fuel_mixture'), Type = "work", Item = { { - name = "Essence", + name = _U('f_gas'), db_name= "essence", time = 5000, max = 20, add = 2, remove = 1, requires = "petrol_raffin", - requires_name = "Pétrol raffiné", + requires_name = _U('f_fuel_refine'), drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour mélanger.", + Hint = _U('f_fuel_mixture_button'), GPS = {x = 491.406, y = -2163.37, z = 4.91827} }, @@ -105,10 +105,10 @@ Config.Jobs.fuel = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = false, - Name = "Spawner véhicule de fonction", + Name = _U('spawn_veh'), Type = "vehspawner", Spawner = 1, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour appeler le camion.", + Hint = _U('spawn_truck_button'), Caution = 2000, GPS = {x = 602.254, y = 2926.62, z = 39.6898} }, @@ -118,7 +118,7 @@ Config.Jobs.fuel = { Size = {x = 3.0, y = 3.0, z = 1.0}, Marker= -1, Blip = false, - Name = "Véhicule de fonction", + Name = _U('service_vh'), Type = "vehspawnpt", Spawner = 1, GPS = 0, @@ -131,9 +131,9 @@ Config.Jobs.fuel = { Color = {r = 255, g = 0, b = 0}, Marker= 1, Blip = false, - Name = "Supression du véhicule", + Name = _U('return_vh'), Type = "vehdelete", - Hint = "Appuyez sur ~INPUT_PICKUP~ pour rendre le véhicule.", + Hint = _U('return_vh_button'), Spawner = 1, Caution = 2000, GPS = 0, @@ -146,23 +146,23 @@ Config.Jobs.fuel = { Size = {x = 10.0, y = 10.0, z = 1.0}, Marker= 1, Blip = true, - Name = "Point de livraison", - Type = "delivery", + Name = _U('f_deliver_gas'), + Type = "delivery", Spawner = 1, Item = { { - name = "Livraison", + name = _U('delivery'), time = 500, remove = 1, max = 100, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 61, requires = "essence", - requires_name = "Essence", + requires_name = _U('f_gas'), drop = 100 } }, - Hint = "Appuyez sur ~INPUT_PICKUP~ pour livrer l'essence.", + Hint = _U('f_deliver_gas'), GPS = {x = 609.589, y = 2856.74, z = 39.4958} } } -} \ No newline at end of file +} diff --git a/jobs/lumberjack.lua b/jobs/lumberjack.lua index 8cd21380..5c5a8f9e 100644 --- a/jobs/lumberjack.lua +++ b/jobs/lumberjack.lua @@ -18,7 +18,7 @@ Config.Jobs.lumberjack = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = _U('cloakroom'), + Name = _U('lj_locker_room'), Type = "cloakroom", Hint = _U('cloak_change'), }, diff --git a/jobs/miner.lua b/jobs/miner.lua index 04f96390..b11ad769 100644 --- a/jobs/miner.lua +++ b/jobs/miner.lua @@ -18,7 +18,7 @@ Config.Jobs.miner = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = _U('cloakroom'), + Name = _U('m_miner_locker'), Type = "cloakroom", Hint = _U('cloak_change'), GPS = {x = 884.86889648438, y = -2176.5102539063, z = 29.519346237183} diff --git a/jobs/slaughterer.lua b/jobs/slaughterer.lua index 9e468819..b49bd3cb 100644 --- a/jobs/slaughterer.lua +++ b/jobs/slaughterer.lua @@ -18,7 +18,7 @@ Config.Jobs.slaughterer = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = _U('cloakroom'), + Name = _U('s_slaughter_locker'), Type = "cloakroom", Hint = _U('cloak_change'), }, diff --git a/jobs/textil.lua b/jobs/textil.lua index f12e6d9a..110adac9 100644 --- a/jobs/textil.lua +++ b/jobs/textil.lua @@ -18,7 +18,7 @@ Config.Jobs.textil = { Color = {r = 204, g = 204, b = 0}, Marker= 1, Blip = true, - Name = _U('cloakroom'), + Name = _U('dd_dress_locker'), Type = "cloakroom", Hint = _U('cloak_change'), GPS = {x = 740.808776855469, y = -970.066650390625, z = 23.4693908691406} diff --git a/locales/en.lua b/locales/en.lua index 427901ec..adfc5c21 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,96 +1,117 @@ Locales['en'] = { --Global menus - ['cloakroom'] = 'Locker Room', - ['cloak_change'] = 'Press ~INPUT_PICKUP~ to change clothes.', - ['bank_deposit'] = 'a security deposit of ~g~', - ['bank_deposit_r'] = 'a security deposit of ~g~$', - ['bank_deposit2'] = '$ ~s~was made to you after your fainting.', - ['bank_nodeposit'] = "you did not have a security deposit", - ['foot_work'] = 'you have to be on foot to be able to work.', - ['next_point'] = 'go to the next step after completing this one.', - ['security_deposit'] = 'the security given will be ~g~$', - ['not_your_vehicle'] = "this is not your vehicle or you must be a driver.", - ['in_vehicle'] = 'you must be in a vehicle.', - ['wrong_point'] = "you are not at the right point of delivery.", - ['max_limit'] = 'you have the maximum: ', - ['not_enough'] = "you do not have enough", - ['not_enough2'] = ' to continue this task.', - ['caution_taken'] = ' ~s~was taken from you.', - ['caution_returned'] = ' ~s~was returned to you.', - ['spawn_veh'] = 'spawn vehicle', - ['spawn_veh_button'] = 'press ~INPUT_PICKUP~ to call the delivery vehicle.', - ['service_vh'] = 'service vehicle', - ['return_vh'] = 'vehicle return', - ['return_vh_button'] = 'press ~INPUT_PICKUP~ to return the vehicle.', - ['delivery_point'] = 'delivery point', - ['delivery'] = 'delivery', + ['cloakroom'] = 'Locker Room', + ['cloak_change'] = 'press ~INPUT_PICKUP~ to change clothes.', + ['citizen_wear'] = 'civilian clothes', + ['job_wear'] = 'workers clothes', + ['bank_deposit'] = 'a security deposit of ~g~', + ['bank_deposit_r'] = 'a security deposit of ~g~$', + ['bank_deposit2'] = '$ ~s~was made to you after your fainting.', + ['bank_nodeposit'] = "you did not have a security deposit", + ['foot_work'] = 'you have to be on foot to be able to work.', + ['next_point'] = 'go to the next step after completing this one.', + ['security_deposit'] = 'the security given will be ~g~$', + ['not_your_vehicle'] = "this is not your vehicle or you must be a driver.", + ['in_vehicle'] = 'you must be in a vehicle.', + ['wrong_point'] = "you are not at the right point of delivery.", + ['max_limit'] = 'you have the maximum: ', + ['not_enough'] = "you do not have enough", + ['not_enough2'] = ' to continue this task.', + ['caution_taken'] = ' ~s~was taken from you.', + ['caution_returned'] = ' ~s~was returned to you.', + ['spawn_veh'] = 'spawn vehicle', + ['spawn_veh_button'] = 'press ~INPUT_PICKUP~ to call the delivery vehicle.', + ['spawn_truck_button'] = 'press ~INPUT_PICKUP~ to spawn the truck.', + ['service_vh'] = 'service vehicle', + ['return_vh'] = 'vehicle return', + ['return_vh_button'] = 'press ~INPUT_PICKUP~ to return the vehicle.', + ['delivery_point'] = 'delivery point', + ['delivery'] = 'delivery', --Lumber Jack job - ['lj_mapblip'] = 'Wood pile', - ['lj_wood'] = 'wood', - ['lj_pickup'] = 'press ~INPUT_PICKUP~ to retrieve wood.', - ['lj_cutwood'] = 'Wood cutting', - ['lj_cutwood_button'] = 'press ~INPUT_PICKUP~ to cut wood.', - ['lj_board'] = 'boards', - ['lj_planks'] = 'package board', - ['lj_cutwood'] = 'cut wood', - ['lj_pick_boards'] = 'press ~INPUT_PICKUP~ to retrieve boards.', - ['lj_deliver_button'] = 'press ~INPUT_PICKUP~ to deliver the boards.', + ['lj_locker_room'] = "lumberjack's Locker Room", + ['lj_mapblip'] = 'wood pile', + ['lj_wood'] = 'wood', + ['lj_pickup'] = 'press ~INPUT_PICKUP~ to retrieve wood.', + ['lj_cutwood'] = 'wood cutting', + ['lj_cutwood_button'] = 'press ~INPUT_PICKUP~ to cut wood.', + ['lj_board'] = 'boards', + ['lj_planks'] = 'package board', + ['lj_cutwood'] = 'cut wood', + ['lj_pick_boards'] = 'press ~INPUT_PICKUP~ to retrieve boards.', + ['lj_deliver_button'] = 'press ~INPUT_PICKUP~ to deliver the boards.', --fisherman - ['fm_fish'] = 'fish', - ['fm_fish_area'] = 'fishing area', - ['fm_fish_button'] = 'press ~INPUT_PICKUP~ to fish.', - ['fm_spawnboat_title'] = 'spawn boat', - ['fm_spawnboat'] = 'press ~INPUT_PICKUP~ to call the boat.', - ['fm_boat_title'] = 'boat', - ['fm_boat_return_title'] = 'boat return', - ['fm_boat_return_button'] = 'Press ~INPUT_PICKUP~ to return the boat.', - ['fm_deliver_fish'] = 'press ~INPUT_PICKUP~ to deliver the fish.', + ['fm_fish_locker'] = "fishermen's Locker Room", + ['fm_fish'] = 'fish', + ['fm_fish_area'] = 'fishing area', + ['fm_fish_button'] = 'press ~INPUT_PICKUP~ to fish.', + ['fm_spawnboat_title'] = 'spawn boat', + ['fm_spawnboat'] = 'press ~INPUT_PICKUP~ to call the boat.', + ['fm_boat_title'] = 'boat', + ['fm_boat_return_title'] = 'boat return', + ['fm_boat_return_button'] = 'Press ~INPUT_PICKUP~ to return the boat.', + ['fm_deliver_fish'] = 'press ~INPUT_PICKUP~ to deliver the fish.', + + --fuel + ['f_oil_refiner'] = 'Oil Refiner Locker Room', + ['f_drill_oil'] = 'drill for oil', + ['f_fuel'] = 'oil', + ['f_drillbutton'] = 'press ~INPUT_PICKUP~ to drill.', + ['f_fuel_refine'] = 'refine oil', + ['f_refine_fuel_button'] = 'press ~INPUT_PICKUP~ to refine.', + ['f_fuel_mixture'] = 'mix refined oil', + ['f_gas'] = 'gas', + ['f_fuel_mixture_button'] = 'press ~INPUT_PICKUP~ to mix.', + ['f_deliver_gas'] = 'deliver Gas', + ['f_deliver_gas_button'] = "press ~INPUT_PICKUP~ to deliver gasoline.", --miner - ['m_rock'] = 'rock', - ['m_pickrocks'] = 'press ~INPUT_PICKUP~ to retrieve rocks.', - ['m_washrock'] = 'rock washed', - ['m_rock_button'] = 'press ~INPUT_PICKUP~ to wash the rocks.', - ['m_rock_smelting'] = 'smelthing', - ['m_copper'] = 'copper', - ['m_sell_copper'] = 'sell copper', - ['m_deliver_copper'] = 'Press ~INPUT_PICKUP~ to deliver the copper.', - ['m_iron'] = 'Fer', - ['m_sell_iron'] = 'sell iron', - ['m_deliver_iron'] = 'press ~INPUT_PICKUP~ to deliver the iron.', - ['m_gold'] = 'gold', - ['m_sell_gold'] = "sell gold", - ['m_deliver_gold'] = "press ~INPUT_PICKUP~ to deliver the gold.", - ['m_diamond'] = 'diamond', - ['m_sell_diamond'] = "sell diamond", - ['m_deliver_diamond'] = 'press ~INPUT_PICKUP~ to deliver the diamonds.', - ['m_melt_button'] = 'press ~INPUT_PICKUP~ to melt the rocks.', + ['m_miner_locker'] = "miner's Locker Room", + ['m_rock'] = ' rock', + ['m_pickrocks'] = 'press ~INPUT_PICKUP~ to retrieve rocks.', + ['m_washrock'] = ' washed rocks ', + ['m_rock_button'] = 'press ~INPUT_PICKUP~ to wash the rocks.', + ['m_rock_smelting'] = 'smelthing', + ['m_copper'] = ' copper', + ['m_sell_copper'] = 'sell copper', + ['m_deliver_copper'] = 'Press ~INPUT_PICKUP~ to deliver the copper.', + ['m_iron'] = ' iron', + ['m_sell_iron'] = 'sell iron', + ['m_deliver_iron'] = 'press ~INPUT_PICKUP~ to deliver the iron.', + ['m_gold'] = ' gold', + ['m_sell_gold'] = "sell gold", + ['m_deliver_gold'] = 'press ~INPUT_PICKUP~ to deliver the gold.', + ['m_diamond'] = ' diamond', + ['m_sell_diamond'] = 'sell diamond', + ['m_deliver_diamond'] = 'press ~INPUT_PICKUP~ to deliver the diamonds.', + ['m_melt_button'] = 'press ~INPUT_PICKUP~ to melt the rocks.', --reporter - ['reporter_name'] = 'san Andreas Times', - ['reporter_garage'] = 'Press ~INPUT_PICKUP~ to go down to the garage.', + ['reporter_name'] = 'san Andreas Times', + ['reporter_garage'] = 'Press ~INPUT_PICKUP~ to go down to the garage.', --slaughterer - ['s_hen'] = 'chicken coop', - ['s_alive_chicken'] = 'live Chicken', - ['s_catch_hen'] = 'press ~INPUT_PICKUP~ to catch live chickens.', - ['s_slaughtered_chicken'] = 'chicken to be packed', - ['s_chop_animal'] = 'press ~INPUT_PICKUP~ to chop the chickens.', - ['s_slaughtered'] = 'slaughter house', - ['s_package'] = 'packaging', - ['s_packagechicken'] = 'chicken in tray', - ['s_unpackaged'] = 'chicken to be packed', - ['s_unpackaged_button'] = 'press ~INPUT_PICKUP~ to set the chicken in a tray.', - ['s_deliver'] = 'press ~INPUT_PICKUP~ to deliver the chicken trays.', + ['s_slaughter_locker'] = "butcher's Locker Room", + ['s_hen'] = 'chicken coop', + ['s_alive_chicken'] = 'live Chicken', + ['s_catch_hen'] = 'press ~INPUT_PICKUP~ to catch live chickens.', + ['s_slaughtered_chicken'] = 'chicken to be packed', + ['s_chop_animal'] = 'press ~INPUT_PICKUP~ to chop the chickens.', + ['s_slaughtered'] = 'slaughter house', + ['s_package'] = 'packaging', + ['s_packagechicken'] = 'chicken in tray', + ['s_unpackaged'] = 'chicken to be packed', + ['s_unpackaged_button'] = 'press ~INPUT_PICKUP~ to set the chicken in a tray.', + ['s_deliver'] = 'press ~INPUT_PICKUP~ to deliver the chicken trays.', --Dress Designer - ['dd_wool'] = 'wool', - ['dd_pickup'] = 'Press ~INPUT_PICKUP~ to retrieve wool.', - ['dd_fabric'] = 'fabric', - ['dd_makefabric'] = 'Press ~INPUT_PICKUP~ to make fabric.', - ['dd_clothing'] = 'clothing', - ['dd_makeclothing'] = 'press ~INPUT_PICKUP~ to retrieve clothing.', - ['dd_deliver_clothes'] = 'press ~INPUT_PICKUP~ to deliver the clothes.', + ['dd_dress_locker'] = "dress Designer's Locker Room", + ['dd_wool'] = 'wool', + ['dd_pickup'] = 'press ~INPUT_PICKUP~ to retrieve wool.', + ['dd_fabric'] = 'fabric', + ['dd_makefabric'] = 'Press ~INPUT_PICKUP~ to make fabric.', + ['dd_clothing'] = 'clothing', + ['dd_makeclothing'] = 'press ~INPUT_PICKUP~ to retrieve clothing.', + ['dd_deliver_clothes'] = 'press ~INPUT_PICKUP~ to deliver the clothes.', } diff --git a/locales/fr.lua b/locales/fr.lua index e8c9a6cb..d21b56db 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,98 +1,116 @@ Locales['fr'] = { --Global menus - ['cloakroom'] = 'vestiaire', - ['cloak_change'] = 'appuyez sur ~INPUT_PICKUP~ pour vous changer.', - ['citizen_wear'] = 'Tenue civile', - ['job_wear'] = 'Tenue de travail', - ['bank_deposit'] = 'une caution de ~g~', - ['bank_deposit_r'] = 'une caution de ~g~$', - ['bank_deposit2'] = '$ ~s~vous a été rendue suite à votre évanouissment.', - ['bank_nodeposit'] = "vous n'aviez pas de caution", - ['foot_work'] = 'vous devez être à pied pour pouvoir travailler.', - ['next_point'] = 'rendez-vous à la prochaine étape après avoir complété celle-ci.', - ['security_deposit'] = 'la caution rendue sera de ~g~$', - ['not_your_vehicle'] = "ce n'est pas votre véhicule ou vous devez être conducteur.", - ['in_vehicle'] = 'vous devez être dans un véhicule.', - ['wrong_point'] = "vous n'êtes pas au bon point de livraison.", - ['max_limit'] = 'vous avez le maximum de: ', - ['not_enough'] = "vous n'avez plus assez de", - ['not_enough2'] = ' pour continuer cette tâche.', - ['caution_taken'] = ' ~s~vous a été prélevée.', - ['caution_returned'] = ' ~s~vous a été rendue.', - ['spawn_veh'] = 'spawner véhicule de fonction', - ['spawn_veh_button'] = 'appuyez sur ~INPUT_PICKUP~ pour appeler le véhicule de livraison.', - ['service_vh'] = 'véhicule de fonction', - ['return_vh'] = 'supression du véhicule', - ['return_vh_button'] = 'appuyez sur ~INPUT_PICKUP~ pour rendre le véhicule.', - ['delivery_point'] = 'point de livraison', - ['delivery'] = 'livraison', + ['cloakroom'] = 'vestiaire', + ['cloak_change'] = 'appuyez sur ~INPUT_PICKUP~ pour vous changer.', + ['citizen_wear'] = 'tenue civile', + ['job_wear'] = 'tenue de travail', + ['bank_deposit'] = 'une caution de ~g~', + ['bank_deposit_r'] = 'une caution de ~g~$', + ['bank_deposit2'] = '$ ~s~vous a été rendue suite à votre évanouissment.', + ['bank_nodeposit'] = "vous n'aviez pas de caution", + ['foot_work'] = 'vous devez être à pied pour pouvoir travailler.', + ['next_point'] = 'rendez-vous à la prochaine étape après avoir complété celle-ci.', + ['security_deposit'] = 'la caution rendue sera de ~g~$', + ['not_your_vehicle'] = "ce n'est pas votre véhicule ou vous devez être conducteur.", + ['in_vehicle'] = 'vous devez être dans un véhicule.', + ['wrong_point'] = "vous n'êtes pas au bon point de livraison.", + ['max_limit'] = 'vous avez le maximum de: ', + ['not_enough'] = "vous n'avez plus assez de", + ['not_enough2'] = ' pour continuer cette tâche.', + ['caution_taken'] = ' ~s~vous a été prélevée.', + ['caution_returned'] = ' ~s~vous a été rendue.', + ['spawn_veh'] = 'spawner véhicule de fonction', + ['spawn_veh_button'] = 'appuyez sur ~INPUT_PICKUP~ pour appeler le véhicule de livraison.', + ['spawn_truck_button'] = 'appuyez sur ~INPUT_PICKUP~ pour appeler le camion.', + ['service_vh'] = 'véhicule de fonction', + ['return_vh'] = 'supression du véhicule', + ['return_vh_button'] = 'appuyez sur ~INPUT_PICKUP~ pour rendre le véhicule.', + ['delivery_point'] = 'point de livraison', + ['delivery'] = 'livraison', --Lumber Jack job - ['lj_mapblip'] = 'tas de bois', - ['lj_wood'] = 'bois', - ['lj_pickup'] = 'appuyez sur ~INPUT_PICKUP~ pour récupérer du bois.', - ['lj_cutwood'] = 'découpe du bois', - ['lj_cutwood_button'] = 'appuyez sur ~INPUT_PICKUP~ pour couper du bois.', - ['lj_board'] = 'planches', - ['lj_planks'] = 'paquet de planche', - ['lj_cutwood'] = 'bois coupé', - ['lj_pick_boards'] = 'appuyez sur ~INPUT_PICKUP~ pour récupérer des planches.', - ['lj_deliver_button'] = 'appuyez sur ~INPUT_PICKUP~ pour livrer les planches.', + ['lj_locker_room'] = "lumberjack's Locker Room", + ['lj_mapblip'] = 'tas de bois', + ['lj_wood'] = 'bois', + ['lj_pickup'] = 'appuyez sur ~INPUT_PICKUP~ pour récupérer du bois.', + ['lj_cutwood'] = 'découpe du bois', + ['lj_cutwood_button'] = 'appuyez sur ~INPUT_PICKUP~ pour couper du bois.', + ['lj_board'] = 'planches', + ['lj_planks'] = 'paquet de planche', + ['lj_cutwood'] = 'bois coupé', + ['lj_pick_boards'] = 'appuyez sur ~INPUT_PICKUP~ pour récupérer des planches.', + ['lj_deliver_button'] = 'appuyez sur ~INPUT_PICKUP~ pour livrer les planches.', --fisherman - ['fm_fish'] = 'poisson', - ['fm_fish_area'] = 'zone de pêche', - ['fm_fish_button'] = 'appuyez sur ~INPUT_PICKUP~ pour pêcher.', - ['fm_spawnboat_title'] = 'spawner bateau', - ['fm_spawnboat'] = 'appuyez sur ~INPUT_PICKUP~ pour appeler le bateau.', - ['fm_boat_title'] = 'bateau', - ['fm_boat_return_title'] = 'supression du bateau', - ['fm_boat_return_button'] = 'appuyez sur ~INPUT_PICKUP~ pour rendre le bateau.', - ['fm_deliver_fish'] = 'Appuyez sur ~INPUT_PICKUP~ pour livrer le poisson.', + ['fm_fish_locker'] = "fishermen's Locker Room", + ['fm_fish'] = 'poisson', + ['fm_fish_area'] = 'zone de pêche', + ['fm_fish_button'] = 'appuyez sur ~INPUT_PICKUP~ pour pêcher.', + ['fm_spawnboat_title'] = 'spawner bateau', + ['fm_spawnboat'] = 'appuyez sur ~INPUT_PICKUP~ pour appeler le bateau.', + ['fm_boat_title'] = 'bateau', + ['fm_boat_return_title'] = 'supression du bateau', + ['fm_boat_return_button'] = 'appuyez sur ~INPUT_PICKUP~ pour rendre le bateau.', + ['fm_deliver_fish'] = 'appuyez sur ~INPUT_PICKUP~ pour livrer le poisson.', + + --fuel + ['f_oil_refiner'] = 'oil Refiner Locker Room', + ['f_drill_oil'] = 'drill for oil', + ['f_fuel'] = 'pétrol', + ['f_drillbutton'] = 'appuyez sur ~INPUT_PICKUP~ pour forer.', + ['f_fuel_refine'] = 'pétrol raffiné', + ['f_refine_fuel_button'] = 'press ~ INPUT_PICKUP ~ to refine.', + ['f_fuel_mixture'] = 'mélange', + ['f_gas'] = 'essence', + ['f_fuel_mixture_button'] = 'appuyez sur ~INPUT_PICKUP~ pour mélanger.', + ['f_deliver_gas'] = "appuyez sur ~INPUT_PICKUP~ pour livrer l'essence.", --miner - ['m_rock'] = 'Rocher', - ['m_pickrocks'] = 'Appuyez sur ~INPUT_PICKUP~ pour récupérer des rochers.', - ['m_washrock'] = 'Roche lavé', - ['m_rock_button'] = 'Appuyez sur ~INPUT_PICKUP~ pour laver les roches.', - ['m_rock_smelting'] = 'Fonderie', - ['m_copper'] = 'cuivre', - ['m_sell_copper'] = 'Revente de cuivre', - ['m_deliver_copper'] = 'Appuyez sur ~INPUT_PICKUP~ pour livrer le cuivre.', - ['m_iron'] = 'Fer', - ['m_sell_iron'] = 'Revente de fer', - ['m_deliver_iron'] = 'Appuyez sur ~INPUT_PICKUP~ pour livrer le fer.', - ['m_gold'] = 'Or', - ['m_sell_gold'] = "Revente d'or", - ['m_deliver_gold'] = "Appuyez sur ~INPUT_PICKUP~ pour livrer l'or'.", - ['m_diamond'] = 'Diamant', - ['m_sell_diamond'] = "Revente de diamants", - ['m_deliver_diamond'] = 'Appuyez sur ~INPUT_PICKUP~ pour livrer les diamants.', - ['m_melt_button'] = 'Appuyez sur ~INPUT_PICKUP~ pour fondre les roches.', + ['m_miner_locker'] = "miner's Locker Room", + ['m_rock'] = 'rocher', + ['m_pickrocks'] = 'appuyez sur ~INPUT_PICKUP~ pour récupérer des rochers.', + ['m_washrock'] = 'roche lavé', + ['m_rock_button'] = 'appuyez sur ~INPUT_PICKUP~ pour laver les roches.', + ['m_rock_smelting'] = 'fonderie', + ['m_copper'] = 'cuivre', + ['m_sell_copper'] = 'revente de cuivre', + ['m_deliver_copper'] = 'appuyez sur ~INPUT_PICKUP~ pour livrer le cuivre.', + ['m_iron'] = 'fer', + ['m_sell_iron'] = 'revente de fer', + ['m_deliver_iron'] = 'appuyez sur ~INPUT_PICKUP~ pour livrer le fer.', + ['m_gold'] = 'or', + ['m_sell_gold'] = "revente d'or", + ['m_deliver_gold'] = "appuyez sur ~INPUT_PICKUP~ pour livrer l'or'.", + ['m_diamond'] = 'diamant', + ['m_sell_diamond'] = "revente de diamants", + ['m_deliver_diamond'] = 'appuyez sur ~INPUT_PICKUP~ pour livrer les diamants.', + ['m_melt_button'] = 'appuyez sur ~INPUT_PICKUP~ pour fondre les roches.', --reporter - ['reporter_name'] = 'Le Maclerait Libéré', - ['reporter_garage'] = 'Appuyez sur ~INPUT_PICKUP~ pour descendre au garage.', + ['reporter_name'] = 'le Maclerait Libéré', + ['reporter_garage'] = 'appuyez sur ~INPUT_PICKUP~ pour descendre au garage.', --slaughterer - ['s_hen'] = 'Poulailler', - ['s_alive_chicken'] = 'Poulet vivant', - ['s_catch_hen'] = 'Appuyez sur ~INPUT_PICKUP~ pour attrapper des poulets vivants.', - ['s_slaughtered_chicken'] = 'Poulet à conditionner', - ['s_chop_animal'] = 'Appuyez sur ~INPUT_PICKUP~ pour dépecer les poulets.', - ['s_slaughtered'] = 'Abattoir', - ['s_package'] = 'Emballage', - ['s_packagechicken'] = 'Poulet en barquette', - ['s_unpackaged'] = 'Poulet à conditionner', - ['s_unpackaged_button'] = 'Appuyez sur ~INPUT_PICKUP~ pour conditionner le poulet en barquette.', - ['s_deliver'] = 'Appuyez sur ~INPUT_PICKUP~ pour livrer les barquettes de poulet.', + ['s_slaughter_locker'] = "butcher's Locker Room", + ['s_hen'] = 'poulailler', + ['s_alive_chicken'] = 'poulet vivant', + ['s_catch_hen'] = 'appuyez sur ~INPUT_PICKUP~ pour attrapper des poulets vivants.', + ['s_slaughtered_chicken'] = 'poulet à conditionner', + ['s_chop_animal'] = 'appuyez sur ~INPUT_PICKUP~ pour dépecer les poulets.', + ['s_slaughtered'] = 'abattoir', + ['s_package'] = 'emballage', + ['s_packagechicken'] = 'poulet en barquette', + ['s_unpackaged'] = 'poulet à conditionner', + ['s_unpackaged_button'] = 'appuyez sur ~INPUT_PICKUP~ pour conditionner le poulet en barquette.', + ['s_deliver'] = 'appuyez sur ~INPUT_PICKUP~ pour livrer les barquettes de poulet.', --Dress Designer - ['dd_wool'] = 'Laine', - ['dd_pickup'] = 'Appuyez sur ~INPUT_PICKUP~ pour récupérer de la laine.', - ['dd_fabric'] = 'Tissu', - ['dd_makefabric'] = 'Appuyez sur ~INPUT_PICKUP~ pour fabriquer du tissu.', - ['dd_clothing'] = 'Vêtement', - ['dd_makeclothing'] = 'Appuyez sur ~INPUT_PICKUP~ pour récupérer des vêtements.', - ['dd_deliver_clothes'] = 'Appuyez sur ~INPUT_PICKUP~ pour livrer les vêtements.', + ['dd_dress_locker'] = "dress Designer's Locker Room", + ['dd_wool'] = 'laine', + ['dd_pickup'] = 'appuyez sur ~INPUT_PICKUP~ pour récupérer de la laine.', + ['dd_fabric'] = 'tissu', + ['dd_makefabric'] = 'appuyez sur ~INPUT_PICKUP~ pour fabriquer du tissu.', + ['dd_clothing'] = 'vêtement', + ['dd_makeclothing'] = 'appuyez sur ~INPUT_PICKUP~ pour récupérer des vêtements.', + ['dd_deliver_clothes'] = 'appuyez sur ~INPUT_PICKUP~ pour livrer les vêtements.', } diff --git a/server/esx_jobs_sv.lua b/server/esx_jobs_sv.lua index 50b84545..30d25704 100644 --- a/server/esx_jobs_sv.lua +++ b/server/esx_jobs_sv.lua @@ -30,7 +30,7 @@ RegisterServerEvent('esx_jobs:giveBackCautionInCaseOfDrop') AddEventHandler('esx_jobs:giveBackCautionInCaseOfDrop', function() local _source = source local xPlayer = ESX.GetPlayerFromId(_source) - + TriggerEvent('esx_addonaccount:getAccount', 'caution', xPlayer.identifier, function(account) local caution = account.money account.removeMoney(caution) From 0281c7a29da33bdd369e244b0179b96f43139ac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 22 Aug 2017 11:05:35 +0200 Subject: [PATCH 0543/3224] Ask for saving outfit in dressing --- client/main.lua | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/client/main.lua b/client/main.lua index 945f24d2..394d6edf 100644 --- a/client/main.lua +++ b/client/main.lua @@ -70,21 +70,44 @@ function OpenShopMenu() if foundStore then ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'outfit_name', + 'default', GetCurrentResourceName(), 'save_dressing', { - title = _U('name_outfit'), + title = _U('save_in_dressing'), + align = 'top-left', + elements = { + {label = _U('yes'), value = 'yes'}, + {label = _U('no'), value = 'no'}, + } }, - function(data, menu) + function(data2, menu2) - menu.close() + menu2.close() - TriggerEvent('skinchanger:getSkin', function(skin) - TriggerServerEvent('esx_clotheshop:saveOutfit', data.value, skin) - end) + if data2.current.value == 'yes' then + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'outfit_name', + { + title = _U('name_outfit'), + }, + function(data3, menu3) + + menu3.close() + + TriggerEvent('skinchanger:getSkin', function(skin) + TriggerServerEvent('esx_clotheshop:saveOutfit', data3.value, skin) + end) + + ESX.ShowNotification(_U('saved_outfit')) + + end, + function(data3, menu3) + menu3.close() + end + ) + + end - end, - function(data2,menu) - menu.close() end ) From f48bf5da31ddee78d0cca681e0725cd8466df421 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 22 Aug 2017 11:38:51 +0200 Subject: [PATCH 0544/3224] Don't remove rare items --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index f1f747f6..7063b953 100644 --- a/server/main.lua +++ b/server/main.lua @@ -49,7 +49,7 @@ ESX.RegisterServerCallback('esx_ambulancejob:removeItemsAfterRPDeathRemoveMoney' if Config.RemoveItemsAfterRPDeath then for i=1, #xPlayer.inventory, 1 do - if xPlayer.inventory[i].count > 0 then + if xPlayer.inventory[i].count > 0 and not xPlayer.inventory[i].rare then xPlayer.setInventoryItem(xPlayer.inventory[i].name, 0) end end From 177e38824b8e947e9b9185877d84478572ae6820 Mon Sep 17 00:00:00 2001 From: renaiku Date: Tue, 22 Aug 2017 16:58:35 +0200 Subject: [PATCH 0545/3224] fix typo --- jobs/textil.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jobs/textil.lua b/jobs/textil.lua index 110adac9..0a7eb9df 100644 --- a/jobs/textil.lua +++ b/jobs/textil.lua @@ -157,7 +157,7 @@ Config.Jobs.textil = { max = 100, -- if not present, probably an error at itemQtty >= item.max in esx_jobs_sv.lua price = 40, requires = "clothe", - requires_name = _U('dd_clothing') + requires_name = _U('dd_clothing'), drop = 100 } }, From 15e95f876e51bee0696f0cf2fcd7108dec16739f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 22 Aug 2017 18:16:05 +0200 Subject: [PATCH 0546/3224] Fix taxi crash (hopefully) and increase wait timeout --- client/main.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index 97148191..b7369919 100644 --- a/client/main.lua +++ b/client/main.lua @@ -472,7 +472,7 @@ Citizen.CreateThread(function() if IsPedInAnyVehicle(playerPed, false) and GetEntitySpeed(playerPed) > 0 then - local waitUntil = GetGameTimer() + GetRandomIntInRange(1000, 30000) + local waitUntil = GetGameTimer() + GetRandomIntInRange(30000, 45000) while OnJob and waitUntil > GetGameTimer() do Citizen.Wait(0) @@ -490,7 +490,7 @@ Citizen.CreateThread(function() end - if DoesEntityExist(ped) then + if DoesEntityExist(CurrentCustomer) then CurrentCustomerBlip = AddBlipForEntity(CurrentCustomer) From aa50d5f8b5bf019f4e139a6371ff0965decc98fe Mon Sep 17 00:00:00 2001 From: renaiku Date: Tue, 22 Aug 2017 18:37:34 +0200 Subject: [PATCH 0547/3224] fix typo after translation --- jobs/textil.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jobs/textil.lua b/jobs/textil.lua index 0a7eb9df..ec19e3a1 100644 --- a/jobs/textil.lua +++ b/jobs/textil.lua @@ -90,8 +90,8 @@ Config.Jobs.textil = { max = 40, add = 1, remove = 2, - requires = _U('dd_fabric'), - requires_name = "Tissu", + requires = "farbric", + requires_name = _U('dd_fabric'), drop = 100 } }, From 4b0e2d4a59f6e69a7b9448fb70ffe16dc465acd3 Mon Sep 17 00:00:00 2001 From: renaiku Date: Tue, 22 Aug 2017 20:40:28 +0200 Subject: [PATCH 0548/3224] small fix, not perfect --- client/main.lua | 47 +++++++++++++++++++++++++++-------------------- config.lua | 8 ++++---- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/client/main.lua b/client/main.lua index ad69660e..8e26fb33 100644 --- a/client/main.lua +++ b/client/main.lua @@ -21,6 +21,7 @@ local LastZone = nil local CurrentAction = nil local CurrentActionMsg = '' local CurrentActionData = {} +local RespawnToHospitalMenu = nil Citizen.CreateThread(function() while ESX == nil do @@ -35,20 +36,26 @@ function RespawnPed(ped, coords) SetPlayerInvincible(ped, false) TriggerEvent('playerSpawned', coords.x, coords.y, coords.z, coords.heading) ClearPedBloodDamage(ped) + if RespawnToHospitalMenu ~= nil then + RespawnToHospitalMenu.close() + RespawnToHospitalMenu = nil + end ESX.UI.Menu.CloseAll() end function StartRespawnToHospitalMenuTimer() + Citizen.Trace('player IsDead') ESX.SetTimeout(Config.MenuRespawnToHospitalDelay, function() + Citizen.Trace('timer started') if IsDead then local elements = {} table.insert(elements, {label = _U('yes'), value = 'yes'}) - ESX.UI.Menu.Open( + RespawnToHospitalMenu = ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'menuName', { title = _U('respawn_at_hospital'), @@ -56,41 +63,39 @@ function StartRespawnToHospitalMenuTimer() elements = elements }, function(data, menu) --Submit Cb - - menu.close() - - Citizen.CreateThread(function() - DoScreenFadeOut(800) + menu.close() - while not IsScreenFadedOut() do - Citizen.Wait(0) - end + Citizen.CreateThread(function() - ESX.TriggerServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function() + DoScreenFadeOut(800) - TriggerServerEvent('esx:updateLastPosition', Config.Zones.HospitalInteriorInside1.Pos) + while not IsScreenFadedOut() do + Citizen.Wait(0) + end - RespawnPed(GetPlayerPed(-1), Config.Zones.HospitalInteriorInside1.Pos) - StopScreenEffect('DeathFailOut') - DoScreenFadeIn(800) - end) + ESX.TriggerServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function() + TriggerServerEvent('esx:updateLastPosition', Config.Zones.HospitalInteriorInside1.Pos) + + RespawnPed(GetPlayerPed(-1), Config.Zones.HospitalInteriorInside1.Pos) + StopScreenEffect('DeathFailOut') + DoScreenFadeIn(800) end) + end) end, function(data, menu) --Cancel Cb --menu.close() end, function(data, menu) --Change Cb --print(data.current.value) + end, + function(data, menu) --Close Cb + RespawnToHospitalMenu = nil end ) - - end - end) - end function StartRespawnTimer() @@ -630,12 +635,14 @@ AddEventHandler('baseevents:onPlayerKilled', function(killerId, data) end) AddEventHandler('esx_ambulancejob:onPlayerDeath', function() - + Citizen.Trace('player died') IsDead = true if Config.ShowDeathTimer == true then + Citizen.Trace('player died: true') RespawnTimer() else + Citizen.Trace('player died: false') StartRespawnTimer() StartRespawnToHospitalMenuTimer() StartScreenEffect('DeathFailOut', 0, false) diff --git a/config.lua b/config.lua index f795fc7c..6331f291 100644 --- a/config.lua +++ b/config.lua @@ -1,15 +1,15 @@ Config = {} Config.DrawDistance = 100.0 Config.MarkerColor = {r = 102, g = 0, b = 102} -Config.RespawnDelayAfterRPDeath = 10 * 60 * 1000 +Config.RespawnDelayAfterRPDeath = 4 * 60 * 1000 Config.MenuRespawnToHospitalDelay= 1 * 60 * 1000 Config.RemoveWeaponsAfterRPDeath = true Config.RemoveCashAfterRPDeath = true Config.RemoveItemsAfterRPDeath = true Config.EnablePlayerManagement = false -Config.ShowDeathTimer = true -Config.EarlyRespawn = true -Config.EarlyRespawnFine = true +Config.ShowDeathTimer = false +Config.EarlyRespawn = false +Config.EarlyRespawnFine = false Config.EarlyRespawnFineAmount = 500 Config.Locale = 'fr' From 763fee9462d28f5222fbbb93675414387b92e0e3 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 22 Aug 2017 15:24:12 -0400 Subject: [PATCH 0549/3224] Add English Account Labels to Config --- config.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config.lua b/config.lua index 81e8ddf6..547c835e 100644 --- a/config.lua +++ b/config.lua @@ -1,7 +1,8 @@ Config = {} Config.accounts = {'bank', 'black_money'} -Config.accountLabels = {'Banque', 'Argent Sale'} +Config.accountLabels = {'Banque', 'Argent Sale'} -- FR +--Config.accountLabels = {'Bank', 'Dirty Money'} -- EN Config.PaycheckInterval = 7 * 60000 Config.ShowDotAbovePlayer = false Config.RemoveInventoryItemDelay = 5 * 60000 From 23cda24940f1ce29746312ee5a9b4cc125158d88 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 22 Aug 2017 15:24:25 -0400 Subject: [PATCH 0550/3224] Add English Account Labels to Config --- config.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config.lua b/config.lua index 81e8ddf6..547c835e 100644 --- a/config.lua +++ b/config.lua @@ -1,7 +1,8 @@ Config = {} Config.accounts = {'bank', 'black_money'} -Config.accountLabels = {'Banque', 'Argent Sale'} +Config.accountLabels = {'Banque', 'Argent Sale'} -- FR +--Config.accountLabels = {'Bank', 'Dirty Money'} -- EN Config.PaycheckInterval = 7 * 60000 Config.ShowDotAbovePlayer = false Config.RemoveInventoryItemDelay = 5 * 60000 From a2f1f42c1d1a5ec2175ea9eba692a47b3dc33ae6 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 22 Aug 2017 15:24:40 -0400 Subject: [PATCH 0551/3224] Add English Account Labels to Config --- config.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config.lua b/config.lua index 81e8ddf6..547c835e 100644 --- a/config.lua +++ b/config.lua @@ -1,7 +1,8 @@ Config = {} Config.accounts = {'bank', 'black_money'} -Config.accountLabels = {'Banque', 'Argent Sale'} +Config.accountLabels = {'Banque', 'Argent Sale'} -- FR +--Config.accountLabels = {'Bank', 'Dirty Money'} -- EN Config.PaycheckInterval = 7 * 60000 Config.ShowDotAbovePlayer = false Config.RemoveInventoryItemDelay = 5 * 60000 From 6db392f02ef2348c0dd98bca5a664a2886edf386 Mon Sep 17 00:00:00 2001 From: renaiku Date: Wed, 23 Aug 2017 01:31:04 +0200 Subject: [PATCH 0552/3224] fix phone callbacks --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 7b4b999f..8fb288da 100644 --- a/server/main.lua +++ b/server/main.lua @@ -65,7 +65,7 @@ TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) if xPlayer2.job.name == 'banker' then TriggerEvent('esx_phone:getDistpatchRequestId', function(requestId) - TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'Client Banque') + TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'Client Banque', false) end) end end From b0a9ce9cad6cfb29fd764791acae412ab40198cf Mon Sep 17 00:00:00 2001 From: renaiku Date: Wed, 23 Aug 2017 01:33:40 +0200 Subject: [PATCH 0553/3224] fix messages callbacks --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 4001b962..2fc0dae8 100644 --- a/server/main.lua +++ b/server/main.lua @@ -24,7 +24,7 @@ AddEventHandler('esx_phone:ready', function() local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) if xPlayer2.job.name == 'realestateagent' then - TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, job) + TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, job, false) end end From b159001b13d601dd816ba1426095f8cbfe063764 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 22 Aug 2017 20:28:04 -0400 Subject: [PATCH 0554/3224] Update multi-language support --- locales/en.lua | 1 + locales/fr.lua | 1 + server/main.lua | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/en.lua b/locales/en.lua index 3cc454a0..1d9c4029 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -18,4 +18,5 @@ Locales['en'] = { ['withdraw'] = 'withdraw', ['withdraw_amount'] = 'withdraw amount', ['withdraw_society_money'] = 'withdraw society money', + ['bank_customer'] = 'bank Customer', } \ No newline at end of file diff --git a/locales/fr.lua b/locales/fr.lua index 6e927506..9afc4061 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -18,4 +18,5 @@ Locales['fr'] = { ['withdraw'] = 'retrait', ['withdraw_amount'] = 'montant du retrait', ['withdraw_society_money'] = 'retirer argent société', + ['bank_customer'] = 'client Banque', } \ No newline at end of file diff --git a/server/main.lua b/server/main.lua index 8fb288da..59e8cf06 100644 --- a/server/main.lua +++ b/server/main.lua @@ -65,7 +65,7 @@ TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) if xPlayer2.job.name == 'banker' then TriggerEvent('esx_phone:getDistpatchRequestId', function(requestId) - TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'Client Banque', false) + TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, _U('bank_customer'), false) end) end end From 1f86f60e2c71ea9f54cc50d2bb9ded80ad221098 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 22 Aug 2017 20:29:48 -0400 Subject: [PATCH 0555/3224] Add English HTML UI --- html/ui_en.html | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 html/ui_en.html diff --git a/html/ui_en.html b/html/ui_en.html new file mode 100644 index 00000000..3579575e --- /dev/null +++ b/html/ui_en.html @@ -0,0 +1,28 @@ + + + + + + + + +
    + +
    + + + + + + + \ No newline at end of file From 60c362fde02e0fe38cbc741e97bbff641eb0192e Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 22 Aug 2017 22:44:40 -0400 Subject: [PATCH 0556/3224] Update language support --- __resource.lua | 1 + config.lua | 372 ++++++++++++++++++++++++------------------------- locales/en.lua | 140 ++++++++++++++++++- locales/fr.lua | 137 ++++++++++++++++++ 4 files changed, 463 insertions(+), 187 deletions(-) diff --git a/__resource.lua b/__resource.lua index e46bb7eb..58616817 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,6 +2,7 @@ server_scripts { '@es_extended/locale.lua', 'locales/en.lua', 'locales/fr.lua', + 'config.lua', 'server/main.lua' } diff --git a/config.lua b/config.lua index 83bfa301..cab20ac1 100644 --- a/config.lua +++ b/config.lua @@ -33,29 +33,29 @@ function GetColors(color) local colors = {} if color == 'black' then colors = { - { index = 0, label = 'Noir'}, - { index = 1, label = 'Graphite'}, - { index = 2, label = 'Noir Métallisé'}, - { index = 3, label = 'Acier Fondu'}, - { index = 11, label = 'Noir Anthracite'}, - { index = 12, label = 'Noir Mat'}, - { index = 15, label = 'Nuit Sombre'}, - { index = 16, label = 'Noir Profond'}, - { index = 21, label = 'Pétrol'}, - { index = 147, label = 'Carbon'} + { index = 0, label = _U('black')}, + { index = 1, label = _U('graphite')}, + { index = 2, label = _U('black_metallic')}, + { index = 3, label = _U('caststeel')}, + { index = 11, label = _U('black_anth')}, + { index = 12, label = _U('matteblack')}, + { index = 15, label = _U('darknight')}, + { index = 16, label = _U('deepblack')}, + { index = 21, label = _U('oil')}, + { index = 147, label = _U('carbon')} } elseif color == 'white' then colors = { - { index = 106, label = 'Vanille'}, - { index = 107, label = 'Crème'}, - { index = 111, label = 'Blanc'}, - { index = 112, label = 'Blanc Polair'}, - { index = 113, label = 'Beige'}, - { index = 121, label = 'Blanc Mat'}, - { index = 122, label = 'Neige'}, - { index = 131, label = 'Coton'}, - { index = 132, label = 'Albâtre'}, - { index = 134, label = 'Blanc Pure'} + { index = 106, label = _U('vanilla')}, + { index = 107, label = _U('creme')}, + { index = 111, label = _U('white')}, + { index = 112, label = _U('polarwhite')}, + { index = 113, label = _U('beige')}, + { index = 121, label = _U('mattewhite')}, + { index = 122, label = _U('snow')}, + { index = 131, label = _U('cotton')}, + { index = 132, label = _U('alabaster')}, + { index = 134, label = _U('purewhite')} } elseif color == 'grey' then colors = { @@ -80,11 +80,11 @@ function GetColors(color) { index = 66, label = 'Acier Bleui'}, { index = 93, label = 'Champagne'}, { index = 144, label = 'Gris Chasseur'}, - { index = 156, label = 'Gris'} + { index = 156, label = _U('grey')} } elseif color == 'red' then colors = { - { index = 27, label = 'Rouge'}, + { index = 27, label = _U('red')}, { index = 28, label = 'Rouge Turin'}, { index = 29, label = 'Coquelicot'}, { index = 30, label = 'Rouge Cuivré'}, @@ -103,9 +103,9 @@ function GetColors(color) } elseif color == 'pink' then colors = { - { index = 135, label = 'Rose Electrique'}, - { index = 136, label = 'Rose Saumon'}, - { index = 137, label = 'Rose Dragée'} + { index = 135, label = _U('electricpink')}, + { index = 136, label = _U('salmon')}, + { index = 137, label = _U('sugarplum')} } elseif color == 'blue' then colors = { @@ -141,11 +141,11 @@ function GetColors(color) } elseif color == 'yellow' then colors = { - { index = 42, label = 'Jaune'}, - { index = 88, label = 'Jaune Blé'}, - { index = 89, label = 'Jaune Rally'}, - { index = 91, label = 'Jaune Clair'}, - { index = 126, label = 'Jaune Pale'} + { index = 42, label = _U('yellow')}, + { index = 88, label = _U('wheat')}, + { index = 89, label = _U('raceyellow')}, + { index = 91, label = _U('paleyellow')}, + { index = 126, label = _U('lightyellow')} } elseif color == 'green' then colors = { @@ -169,66 +169,66 @@ function GetColors(color) } elseif color == 'orange' then colors = { - { index = 36, label = 'Tangerine'}, - { index = 38, label = 'Orange'}, - { index = 41, label = 'Orange Mat'}, - { index = 123, label = 'Orange Clair'}, - { index = 124, label = 'Pèche'}, - { index = 130, label = 'Citrouille'}, - { index = 138, label = 'Orange Lambo'} + { index = 36, label = _U('tangerine')}, + { index = 38, label = _U('orange')}, + { index = 41, label = _U('matteorange')}, + { index = 123, label = _U('lightorange')}, + { index = 124, label = _U('peach')}, + { index = 130, label = _U('pumpkin')}, + { index = 138, label = _U('orangelambo')} } elseif color == 'brown' then colors = { - { index = 45, label = 'Cuivre'}, - { index = 47, label = 'Marron clair'}, - { index = 48, label = 'Marron Foncé'}, - { index = 90, label = 'Bronze'}, - { index = 94, label = 'Marron Métallisé'}, - { index = 95, label = 'Expresso'}, - { index = 96, label = 'Chocolat'}, - { index = 97, label = 'Terre Cuite'}, - { index = 98, label = 'Marbre'}, - { index = 99, label = 'Sable'}, - { index = 100, label = 'Sépia'}, - { index = 101, label = 'Bison'}, - { index = 102, label = 'Palmier'}, - { index = 103, label = 'Caramel'}, - { index = 104, label = 'Rouille'}, - { index = 105, label = 'Chataigne'}, - { index = 108, label = 'Brun'}, - { index = 109, label = 'Noisette'}, - { index = 110, label = 'Coquillage'}, - { index = 114, label = 'Acajou'}, - { index = 115, label = 'Chaudron'}, - { index = 116, label = 'Blond'}, - { index = 129, label = 'Gravillon'}, - { index = 153, label = 'Terre Foncé'}, - { index = 154, label = 'Désert'} + { index = 45, label = _U('copper')}, + { index = 47, label = _U('lightbrown')}, + { index = 48, label = _U('darkbrown')}, + { index = 90, label = _U('bronze')}, + { index = 94, label = _U('brownmetallic')}, + { index = 95, label = _U('Expresso')}, + { index = 96, label = _U('chocolate')}, + { index = 97, label = _U('terracotta')}, + { index = 98, label = _U('marble')}, + { index = 99, label = _U('sand')}, + { index = 100, label = _U('sepia')}, + { index = 101, label = _U('bison')}, + { index = 102, label = _U('palm')}, + { index = 103, label = _U('caramel')}, + { index = 104, label = _U('rust')}, + { index = 105, label = _U('chestnut')}, + { index = 108, label = _U('brown')}, + { index = 109, label = _U('hazelnut')}, + { index = 110, label = _U('shell')}, + { index = 114, label = _U('mahogany')}, + { index = 115, label = _U('cauldron')}, + { index = 116, label = _U('blond')}, + { index = 129, label = _U('gravel')}, + { index = 153, label = _U('darkearth')}, + { index = 154, label = _U('desert')} } elseif color == 'purple' then colors = { - { index = 71, label = 'Indigo'}, - { index = 72, label = 'Violet Profond'}, - { index = 76, label = 'Violet Foncé'}, - { index = 81, label = 'Améthyste'}, - { index = 142, label = 'Violet Mystique'}, - { index = 145, label = 'Violet Métallisé'}, - { index = 148, label = 'Vilot Mat'}, - { index = 149, label = 'Violet Profond Mat'} + { index = 71, label = _U('indigo')}, + { index = 72, label = _U('deeppurple')}, + { index = 76, label = _U('darkviolet')}, + { index = 81, label = _U('amethyst')}, + { index = 142, label = _U('mysticalviolet')}, + { index = 145, label = _U('purplemetallic')}, + { index = 148, label = _U('matteviolet')}, + { index = 149, label = _U('mattedeeppurple')} } elseif color == 'chrome' then colors = { - { index = 117, label = 'Chrome Brossé'}, - { index = 118, label = 'Chrome Noir'}, - { index = 119, label = 'Aluminum Brossé'}, - { index = 120, label = 'Chrome'} + { index = 117, label = _U('brushechrome')}, + { index = 118, label = _U('blackchrome')}, + { index = 119, label = _U('brushedaluminum')}, + { index = 120, label = _U('chrome')} } elseif color == 'gold' then colors = { - { index = 37, label = 'Or'}, - { index = 158, label = 'Or Pure'}, - { index = 159, label = 'Or Brossé'}, - { index = 160, label = 'Or Clair'} + { index = 37, label = _U('gold')}, + { index = 158, label = _U('puregold')}, + { index = 159, label = _U('brushedgold')}, + { index = 160, label = _U('lightgold')} } end return colors @@ -362,40 +362,40 @@ end function GetNeons() local neons = { - { label = "white", r = 255, g = 255, b = 255}, - { label = "slate_gray", r = 112, g = 128, b = 144}, - { label = "blue", r = 0, g = 0, b = 255}, - { label = "light_blue", r = 0, g = 150, b = 255}, - { label = "navy_blue", r = 0, g = 0, b = 128}, - { label = "sky_blue", r = 135, g = 206, b = 235}, - { label = "turquoise", r = 0, g = 245, b = 255}, - { label = "mint_green", r = 50, g = 255, b = 155}, - { label = "lime_green", r = 0, g = 255, b = 0}, - { label = "olive", r = 128, g = 128, b = 0}, - { label = "yellow", r = 255, g = 255, b = 0}, - { label = "gold", r = 255, g = 215, b = 0}, - { label = "orange", r = 255, g = 165, b = 0}, - { label = "wheat", r = 245, g = 222, b = 179}, - { label = "red", r = 255, g = 0, b = 0}, - { label = "pink", r = 255, g = 161, b = 211}, - { label = "bright_pink", r = 255, g = 0, b = 255}, - { label = "purple", r = 153, g = 0, b = 153}, - { label = "ivory", r = 41, g = 36, b = 33} + { label = _U('white'), r = 255, g = 255, b = 255}, + { label = "Slate Gray", r = 112, g = 128, b = 144}, + { label = "Blue", r = 0, g = 0, b = 255}, + { label = "Light Blue", r = 0, g = 150, b = 255}, + { label = "Navy Blue", r = 0, g = 0, b = 128}, + { label = "Sky Blue", r = 135, g = 206, b = 235}, + { label = "Turquoise", r = 0, g = 245, b = 255}, + { label = "Mint Green", r = 50, g = 255, b = 155}, + { label = "Lime Green", r = 0, g = 255, b = 0}, + { label = "Olive", r = 128, g = 128, b = 0}, + { label = _U('yellow'), r = 255, g = 255, b = 0}, + { label = _U('gold'), r = 255, g = 215, b = 0}, + { label = _U('orange'), r = 255, g = 165, b = 0}, + { label = _U('wheat'), r = 245, g = 222, b = 179}, + { label = _U('red'), r = 255, g = 0, b = 0}, + { label = _U('pink'), r = 255, g = 161, b = 211}, + { label = _U('brightpink'), r = 255, g = 0, b = 255}, + { label = _U('purple'), r = 153, g = 0, b = 153}, + { label = "Ivory", r = 41, g = 36, b = 33} } return neons end function GetPlatesName(index) if (index == 0) then - return "Bleu sur fond Blanc 1" + return _U('blue_on_white_1') elseif (index == 1) then - return "Jaune sur fond Noir" + return _U('yellow_on_black') elseif (index == 2) then - return "Jaune sur fond Bleu" + return _U('yellow_blue') elseif (index == 3) then - return "Bleu sur fond Blanc 2" + return _U('blue_on_white_2') elseif (index == 4) then - return "Bleu sur fond Blanc 3" + return _U('blue_on_white_3') end end @@ -403,137 +403,137 @@ Config.Menus = { main = { label = 'LS CUSTOM', parent = nil, - upgrades = 'Upgrades', - cosmetics = 'Cosmétiques' + upgrades = _U('upgrades'), + cosmetics = _U('cosmetics') }, upgrades = { - label = 'Upgrades', + label = _U('upgrades'), parent = 'main', - modEngine = "Moteur", - modBrakes = "Freins", - modTransmission = "Transmission", - modSuspension = "Suspension", - modArmor = "Armure", - modTurbo = "Turbo" + modEngine = _U('engine'), + modBrakes = _U('brakes'), + modTransmission = _U('transmission'), + modSuspension = _U('suspension'), + modArmor = _U('armor'), + modTurbo = _U('turbo') }, modEngine = { - label = 'Moteur', + label = _U('engine'), parent = 'modEngine', modType = 11, price = 500 }, modBrakes = { - label = 'Freins', + label = _U('brakes'), parent = 'modBrakes', modType = 12, price = 500 }, modTransmission = { - label = 'Transmission', + label = _U('transmission'), parent = 'modTransmission', modType = 13, price = 500 }, modSuspension = { - label = 'Suspension', + label = _U('suspension'), parent = 'modSuspension', modType = 15, price = 500 }, modArmor = { - label = 'Armure', + label = _U('armor'), parent = 'modArmor', modType = 16, price = 500 }, modTurbo = { - label = 'Turbo', + label = _U('turbo'), parent = 'modTurbo', modType = 18, price = 500 }, cosmetics = { - label = 'Cosmétiques', + label = _U('cosmetics'), parent = 'main', - bodyparts = 'Carosserie', -- - windowTint = 'Fenêtres', -- - modHorns = 'Klaxon', -- - neonColor = "Néons", -- - resprays = 'Peinture', -- - modXenon = 'Phares', -- - plateIndex = 'Plaque', -- - wheels = 'Roues' -- + bodyparts = _U('bodyparts'), + windowTint = _U('windowtint'), + modHorns = _U('horns'), + neonColor = _U('neons'), + resprays = _U('respray'), + modXenon = _U('headlights'), + plateIndex = _U('licenseplates'), + wheels = _U('wheels') }, wheels = { - label = 'Roues', + label = _U('wheels'), parent = 'cosmetics', - modFrontWheelsTypes = "Types de Jantes", - modFrontWheelsColor = "Couleurs jantes", - tyreSmokeColor = "Fumée des pneus" + modFrontWheelsTypes = _U('wheel_type'), + modFrontWheelsColor = _U('wheel_color'), + tyreSmokeColor = _U('tiresmoke') }, modFrontWheelsTypes = { - label = 'Types de Jantes', + label = _U('wheel_type'), parent = 'wheels', - modFrontWheelsType0 = 'Jantes Sport', - modFrontWheelsType1 = 'Jantes Muscle', - modFrontWheelsType2 = 'Jantes Lowrider', - modFrontWheelsType3 = 'Jantes SUV', - modFrontWheelsType4 = 'Jantes Tout-terrain', - modFrontWheelsType5 = 'Jantes Tuning', - modFrontWheelsType6 = 'Jantes Moto', - modFrontWheelsType7 = 'Jantes Haut de gamme' + modFrontWheelsType0 = _U('sport'), + modFrontWheelsType1 = _U('muscle'), + modFrontWheelsType2 = _U('lowrider'), + modFrontWheelsType3 = _U('suv'), + modFrontWheelsType4 = _U('allterain'), + modFrontWheelsType5 = _U('tuning'), + modFrontWheelsType6 = _U('motorcycle'), + modFrontWheelsType7 = _U('highend') }, modFrontWheelsType0 = { - label = 'Jantes Sport', + label = _U('sport'), parent = 'modFrontWheelsTypes', modType = 23, wheelType = 0, price = 500 }, modFrontWheelsType1 = { - label = 'Jantes Muscle', + label = _U('muscle'), parent = 'modFrontWheelsTypes', modType = 23, wheelType = 1, price = 500 }, modFrontWheelsType2 = { - label = 'Jantes Lowrider', + label = _U('lowrider'), parent = 'modFrontWheelsTypes', modType = 23, wheelType = 2, price = 500 }, modFrontWheelsType3 = { - label = 'Jantes SUV', + label = _U('suv'), parent = 'modFrontWheelsTypes', modType = 23, wheelType = 3, price = 500 }, modFrontWheelsType4 = { - label = 'Jantes Tout-terrain', + label = _U('allterain'), parent = 'modFrontWheelsTypes', modType = 23, wheelType = 4, price = 500 }, modFrontWheelsType5 = { - label = 'Jantes Tuning', + label = _U('tuning'), parent = 'modFrontWheelsTypes', modType = 23, wheelType = 5, price = 500 }, modFrontWheelsType6 = { - label = 'Jantes Moto', + label = _U('motorcycle'), parent = 'modFrontWheelsTypes', modType = 23, wheelType = 6, price = 500 }, modFrontWheelsType7 = { - label = 'Jantes Haut de gamme', + label = _U('highend'), parent = 'modFrontWheelsTypes', modType = 23, wheelType = 7, @@ -550,145 +550,145 @@ Config.Menus = { price = 500 }, plateIndex = { - label = 'Plaque', + label = _U('licenseplates'), parent = 'cosmetics', modType = 'plateIndex', price = 500 }, resprays = { - label = 'Peinture', + label = _U('respray'), parent = 'cosmetics', - primaryRespray = 'Primaire', - secondaryRespray = 'Secondaire', - pearlescentRespray = 'Nacré', + primaryRespray = _U('primary'), + secondaryRespray = _U('secondary'), + pearlescentRespray = _U('pearlescent'), }, primaryRespray = { - label = 'Primaire', + label = _U('primary'), parent = 'resprays', }, secondaryRespray = { - label = 'Secondaire', + label = _U('secondary'), parent = 'resprays', }, pearlescentRespray = { - label = 'Nacré', + label = _U('pearlescent'), parent = 'resprays', }, color1 = { - label = 'Primaire', + label = _U('primary'), parent = 'primaryRespray', modType = 'color1', price = 500 }, color2 = { - label = 'Secondaire', + label = _U('secondary'), parent = 'secondaryRespray', modType = 'color2', price = 500 }, pearlescentColor = { - label = 'Nacré', + label = _U('pearlescent'), parent = 'pearlescentRespray', modType = 'pearlescentColor', price = 500 }, modXenon = { - label = 'Phares', + label = _U('headlights'), parent = 'cosmetics', modType = 22, price = 500 }, bodyparts = { - label = 'Carosserie', + label = _U('bodyparts'), parent = 'cosmetics', - modFender = 'Aile gauche', - modRightFender = 'Aile droite', - modSpoilers = 'Aileron', - modSideSkirt = 'Bas de caisse', - modFrame = 'Cage', - modHood = 'Capot', - modGrille = 'Grille', - modRearBumper = 'Pare-choc arrière', - modFrontBumper = 'Pare-choc avant', - modExhaust = 'Pot d\'échappement', - modRoof = 'Toit' + modFender = _U('leftfender'), + modRightFender = _U('rightfender'), + modSpoilers = _U('spoilers'), + modSideSkirt = _U('sideskirt'), + modFrame = _U('cage'), + modHood = _U('hood'), + modGrille = _U('grille'), + modRearBumper = _U('rearbumper'), + modFrontBumper = _U('frontbumper'), + modExhaust = _U('exhaust'), + modRoof = _U('roof') }, modSpoilers = { - label = 'Aileron', + label = _U('spoilers'), parent = 'bodyparts', modType = 0, price = 500 }, modFrontBumper = { - label = 'Pare-choc avant', + label = _U('frontbumper'), modType = 1, price = 500 }, modRearBumper = { - label = 'Pare-choc arrière', + label = _U('rearbumper'), modType = 2, price = 500 }, modSideSkirt = { - label = 'Bas de caisse', + label = _U('sideskirt'), modType = 3, price = 500 }, modExhaust = { - label = 'Pot d\'échappement', + label = _U('exhaust'), modType = 4, price = 500 }, modFrame = { - label = 'Cage', + label = _U('cage'), modType = 5, price = 500 }, modGrille = { - label = 'Grille', + label = _U('grille'), modType = 6, price = 500 }, modHood = { - label = 'Capot', + label = _U('hood'), modType = 7, price = 500 }, modFender = { - label = 'Aile gauche', + label = _U('leftfender'), modType = 8, price = 500 }, modRightFender = { - label = 'Aile droite', + label = _U('rightfender'), modType = 9, price = 500 }, modRoof = { - label = 'Toit', + label = _U('roof'), modType = 10, price = 500 }, windowTint = { - label = 'Fenêtres', + label = _U('windowTint'), parent = 'cosmetics', modType = 'windowTint', price = 500 }, modHorns = { - label = 'Klaxon', + label = _U('horns'), parent = 'cosmetics', modType = 14, price = 500 }, neonColor = { - label = 'Néons', + label = _U('neons'), parent = 'cosmetics', modType = 'neonColor', price = 500 }, tyreSmokeColor = { - label = 'Fumée des pneus', + label = _U('tiresmoke'), parent = 'wheels', modType = 'tyreSmokeColor', price = 500 diff --git a/locales/en.lua b/locales/en.lua index e69bd5e6..755395e0 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,23 +1,161 @@ Locales['en'] = { - ['by_default'] = 'by default', + ['by_default'] = 'default', ['installed'] = 'installed', ['already_own'] = 'you already own: ~b~', ['not_enough_money'] = 'you do not have enough money!', ['purchased'] = 'purchased!', ['press_custom'] = 'press ~INPUT_PICKUP~ to personalize your vehicle.', +-- Paint Colors + -- Black ['black'] = 'black', + ['graphite'] = 'graphite', + ['black_metallic'] = 'black Setallic', + ['caststeel'] = 'cast Steel', + ['black_anth'] = 'black Anthracite', + ['matteblack'] = 'matte Black', + ['darknight'] = 'dark Night', + ['deepblack'] = 'deep Black', + ['oil'] = 'oil', + ['carbon'] = 'carbon', + -- White ['white'] = 'white', + ['vanilla'] = 'vanilla', + ['creme'] = 'creme', + ['polarwhite'] = 'polar White', + ['beige'] = 'beige', + ['mattewhite'] = 'matte White', + ['snow'] = 'snow', + ['cotton'] = 'cotton', + ['alabaster'] = 'alabaster', + ['purewhite'] = 'pure White', + -- Grey ['grey'] = 'grey', + -- Red ['red'] = 'red', + -- Pink ['pink'] = 'pink', + ['electricpink'] = 'electric Pink', + ['brightpink'] = 'bright Pink', + ['salmon'] = 'salmon', + ['sugarplum'] = 'sugar Plum', + -- Blue ['blue'] = 'blue', + -- Yellow ['yellow'] = 'yellow', + ['wheat'] = 'wheat', + ['raceyellow'] = 'race Yellow', + ['paleyellow'] = 'pale Yellow', + ['lightyellow'] = 'light Yellow', + -- Green ['green'] = 'green', + -- Orange ['orange'] = 'orange', + ['tangerine'] = 'Tangerine', + ['matteorange'] = 'Matte Orange', + ['lightorange'] = 'Light Orange', + ['peach'] = 'Peach', + ['pumpkin'] = 'Pumpkin' + ['orangelambo'] = 'Orange Lambo', + -- Brown ['brown'] = 'brown', + ['copper'] = 'Copper', + ['lightbrown'] = 'Light Brown', + ['darkbrown'] = 'Dark Brown', + ['bronze'] = 'Bronze', + ['brownmetallic'] = 'Brown Metallic', + ['espresso'] = 'Espresso', + ['chocolate'] = 'Chocolate', + ['terracotta'] = 'Terracotta', + ['marble'] = 'Marble', + ['sand'] = 'Sand', + ['sepia'] = 'Sepia', + ['bison'] = 'Bison', + ['palm'] = 'Palm', + ['caramel'] = 'Caramel', + ['rust'] = 'Rust', + ['chestnut'] = 'Chestnut', + ['hazelnut'] = 'Hazelnut', + ['shell'] = 'Shell', + ['mahogany'] = 'Mahogany', + ['cauldron'] = 'Cauldron', + ['blond'] = 'Blond', + ['gravel'] = 'Gravel', + ['darkearth'] = 'Dark Earth', + ['desert'] = 'Desert', + -- Purple ['purple'] = 'purple', + ['indigo'] = 'Indigo', + ['deeppurple'] = 'Deep Purple' + ['darkviolet'] = 'Dark Violet', + ['amethyst'] = 'Amethyst', + ['mysticalviolet'] = 'Mystic Violet', + ['purplemetallic'] = 'Purple Metallic', + ['matteviolet'] = 'Matte Violet', + ['mattedeeppurple'] = 'Matte Deep Purple', + -- Chrome ['chrome'] = 'chrome', + ['brushedchrome'] = 'brushed Chrome', + ['blackchrome'] = 'black Chrome', + ['brushedaluminum'] = 'brushed Aluminum' + -- Metal ['gold'] = 'gold', + ['puregold'] = 'pure Gold', + ['brushedgold'] = 'brushed Gold', + ['lightgold'] = 'light Gold', +-- License Plates + ['blue_on_white_1'] = 'blue on white 1', + ['yellow_on_black'] = 'yellow on black', + ['yellow_blue'] = 'yellow on blue', + ['blue_on_white_2'] = 'blue on white 2', + ['blue_on_white_3'] = 'blue on white 3', +-- Upgrades + ['upgrades'] = 'upgrades', + ['engine'] = 'engine', + ['brakes'] = 'brakes', + ['transmission'] = 'transmission', + ['suspension'] = 'suspension', + ['armor'] = 'armor', + ['turbo'] = 'turbo', +-- Cosmetics + ['cosmetics'] = 'cosmetics', + -- Body Parts + ['bodyparts'] = 'body Parts', + ['leftfender'] = 'left fender', + ['rightfender'] = 'right fender', + ['spoilers'] = 'spoilers', + ['sideskirt'] = 'side skirts', + ['frame'] = 'cage', + ['hood'] = 'hood', + ['grille'] = 'grille', + ['rearbumper'] = 'rear bumper', + ['frontbumper'] = 'front bumper', + ['exhaust'] = 'exhaust', + ['roof'] = 'roof', + -- Paint + ['respray'] = 'respray', + ['primary'] = 'primary', + ['secondary'] = 'secondary', + ['pearlescent'] = 'pearlescent', + -- Misc + ['headlights'] = 'headlights', + ['licenseplates'] = 'license Plate', + ['windowtint'] = 'window Tint', + ['horns'] = 'horns', + -- Neon + ['neons'] = 'neons', + -- Wheels + ['wheels'] = 'wheels', + ['tiresmoke'] = 'tire smoke', + ['wheel_type'] = 'wheel type', + ['wheel_color'] = 'wheel color', + ['sport'] = 'sport', + ['muscle'] = 'muscle', + ['lowrider'] = 'lowrider', + ['suv'] = 'sUV', + ['allterrain'] = 'all terrain', + ['tuning'] = 'tuning', + ['motorcycle'] = 'motorcycle', + ['highend'] = 'high end', } diff --git a/locales/fr.lua b/locales/fr.lua index 2617a8b8..2148348e 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -6,18 +6,155 @@ Locales['fr'] = { ['not_enough_money'] = 'vous n\'avez pas assez d\'argent !', ['purchased'] = 'achat effectué !', ['press_custom'] = 'appuyez sur ~INPUT_PICKUP~ pour personnaliser le véhicule.', +-- Paint Colors + -- Black ['black'] = 'noir', + ['graphite'] = 'graphite', + ['black_metallic'] = 'noir Méttallisé', + ['caststeel'] = 'acier Fondu', + ['black_anth'] = 'noir Anthracite' + ['matteblack'] = 'noir Mat', + ['darknight'] = 'nuit Sombre', + ['deepblack'] = 'noir Profond', + ['oil'] = 'pétrol', + ['carbon'] = 'carbon', + -- White ['white'] = 'blanc', + ['vanilla'] = 'vanille', + ['creme'] = 'crème', + ['polarwhite'] = 'blanc Polair', + ['beige'] = 'beige', + ['mattewhite'] = 'blanc Mat', + ['snow'] = 'neige', + ['cotton'] = 'coton', + ['alabaster'] = 'albâtre', + ['purewhite'] = 'blanc Pure', + -- Grey ['grey'] = 'gris', + -- Red ['red'] = 'rouge', + -- Pink ['pink'] = 'rose', + ['electricpink'] = 'rose Electrique', + ['salmon'] = 'rose Saumon', + ['sugarplum'] = 'rose Dragée', + -- Blue ['blue'] = 'bleu', + -- Yellow ['yellow'] = 'jaune', + ['wheat'] = 'Jaune Blé', + ['raceyellow'] = 'Jaune Rally', + ['paleyellow'] = 'Jaune Clair', + ['lightyellow'] = 'Jaune Pâle', + -- Green ['green'] = 'vert', + -- Orange ['orange'] = 'orange', + ['tangerine'] = 'Tangerine', + ['matteorange'] = 'Orange Mat', + ['lightorange'] = 'Orange Clair', + ['peach'] = 'Pèche', + ['pumpkin'] = 'Citrouille', + ['orangelambo'] = 'Orange Lambo', + -- Brown ['brown'] = 'marron', + ['copper'] = 'Cuivre', + ['lightbrown'] = 'Marronclair', + ['darkbrown'] = 'Marron Foncé', + ['bronze'] = 'Bronze', + ['brownmetallic'] = 'Marron Métallisé', + ['espresso'] = 'Expresso', + ['chocolate'] = 'Chocolat', + ['terracotta'] = 'Terre Cuite', + ['marble'] = 'Marbre', + ['sand'] = 'Sable', + ['sepia'] = 'Sépia', + ['bison'] = 'Bison', + ['palm'] = 'Palmier', + ['caramel'] = 'Caramel', + ['rust'] = 'Rouille', + ['chestnut'] = 'Chataigne', + ['hazelnut'] = 'Noisette', + ['shell'] = 'Coquillage', + ['mahogany'] = 'Acajou', + ['cauldron'] = 'Chaudron', + ['blond'] = 'Blond', + ['gravel'] = 'Gravillon', + ['darkearth'] = 'Terre Foncé', + ['desert'] = 'Désert', + -- Purple ['purple'] = 'violet', + ['indigo'] = 'Indigo', + ['deeppurple'] = 'Violet Profond', + ['darkviolet'] = 'Violet Foncé', + ['amethyst'] = 'Améthyste', + ['mysticalviolet'] = 'Violet Mystique', + ['purplemetallic'] = 'Violet Métallisé', + ['matteviolet'] = 'Violet Mat', + ['mattedeeppurple'] = 'Violet Profond Mat', + -- Chrome ['chrome'] = 'chrome', + ['brushedchrome'] = 'chrome Brossé', + ['blackchrome'] = 'chrome Noir', + ['brushedaluminum'] = 'aluminum Brossé', + -- Metal ['gold'] = 'or', + ['puregold'] = 'Or Pure', + ['brushedgold'] = 'Or Brossé', + ['lightgold'] = 'Or Clair', +-- License Plates + ['blue_on_white_1'] = 'bleu sur fond Blanc 1', + ['yellow_on_black'] = 'jaune sur fond Noir', + ['yellow_blue'] = 'jaune sur fond Bleu', + ['blue_on_white_2'] = 'bleu sur fond Blanc 2', + ['blue_on_white_3'] = 'bleu sur fond Blanc 3', +-- Upgrades + ['upgrades'] = 'upgrades', + ['engine'] = 'moteur', + ['brakes'] = 'freins', + ['transmission'] = 'transmission', + ['suspension'] = 'suspension', + ['armor'] = 'armure', + ['turbo'] = 'turbo', +-- Cosmetics + ['cosmetics'] = 'cosmétiques', + -- Body Parts + ['bodyparts'] = 'carosserie', + ['leftfender'] = 'aile gauche', + ['rightfender'] = 'aile droite', + ['spoilers'] = 'aileron', + ['sideskirt'] = 'bas de caisse', + ['frame'] = 'cage', + ['hood'] = 'capot', + ['grille'] = 'grille', + ['rearbumper'] = 'pare-choc arrière', + ['frontbumper'] = 'pare-choc avant', + ['exhaust'] = 'pot d\'échappement', + ['roof'] = 'toit', + -- Paint + ['respray'] = 'peinture', + ['primary'] = 'primaire', + ['secondary'] = 'secondaire', + ['pearlescent'] = 'nacré', + -- Misc + ['headlights'] = 'phares', + ['licenseplates'] = 'plaque', + ['windowtint'] = 'fenêtres', + ['horns'] = 'klaxon', + -- Neon + ['neons'] = 'néons', + -- Wheels + ['wheels'] = 'roues', + ['tiresmoke'] = 'fumée des pneus', + ['wheel_type'] = 'types de Jantes', + ['wheel_color'] = 'couleurs jantes', + ['sport'] = 'Jantes Sport', + ['muscle'] = 'Jantes Muscle', + ['lowrider'] = 'Jantes Lowrider', + ['suv'] = 'Jantes SUV', + ['allterrain'] = 'Jantes Tout-terrain', + ['tuning'] = 'Jantes Tuning', + ['motorcycle'] = 'Jantes Moto', + ['highend'] = 'Jantes Haut de gamme', } From ccab8ff700abdce39c54a3a383ef87a1338c8bfe Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 22 Aug 2017 23:01:06 -0400 Subject: [PATCH 0557/3224] Added Grey Multi-Language --- config.lua | 42 +++++++++++++++++++++--------------------- locales/en.lua | 23 ++++++++++++++++++++++- locales/fr.lua | 21 +++++++++++++++++++++ 3 files changed, 64 insertions(+), 22 deletions(-) diff --git a/config.lua b/config.lua index cab20ac1..aef63381 100644 --- a/config.lua +++ b/config.lua @@ -59,27 +59,27 @@ function GetColors(color) } elseif color == 'grey' then colors = { - { index = 4, label = 'Argenté'}, - { index = 5, label = 'Gris Métallisé'}, - { index = 6, label = 'Acier Laminé'}, - { index = 7, label = 'Gris Foncé'}, - { index = 8, label = 'Gris Rocheux'}, - { index = 9, label = 'Gris Nuit'}, - { index = 10, label = 'Aluminium'}, - { index = 13, label = 'Gris Mat'}, - { index = 14, label = 'Gris Clair'}, - { index = 17, label = 'Gris Bitume'}, - { index = 18, label = 'Gris Béton'}, - { index = 19, label = 'Argent Sombre'}, - { index = 20, label = 'Magnésite'}, - { index = 22, label = 'Nickel'}, - { index = 23, label = 'Zinc'}, - { index = 24, label = 'Dolomite'}, - { index = 25, label = 'Argent Bleuté'}, - { index = 26, label = 'Titane'}, - { index = 66, label = 'Acier Bleui'}, - { index = 93, label = 'Champagne'}, - { index = 144, label = 'Gris Chasseur'}, + { index = 4, label = _U('silver')}, + { index = 5, label = _U('metallicgrey')}, + { index = 6, label = _U('laminatedsteel')}, + { index = 7, label = _U('darkgray')}, + { index = 8, label = _U('rockygray')}, + { index = 9, label = _U('graynight')}, + { index = 10, label = _U('aluminum')}, + { index = 13, label = _U('graymat')}, + { index = 14, label = _U('lightgrey')}, + { index = 17, label = _U('asphaltgray')}, + { index = 18, label = _U('grayconcrete')}, + { index = 19, label = _U('darksilver')}, + { index = 20, label = _U('magnesite')}, + { index = 22, label = _U('nickel')}, + { index = 23, label = _U('zinc')}, + { index = 24, label = _U('dolomite')}, + { index = 25, label = _U('bluesilver')}, + { index = 26, label = _U('titanium')}, + { index = 66, label = _U('steelblue')}, + { index = 93, label = _U('champagne')}, + { index = 144, label = _U('grayhunter')}, { index = 156, label = _U('grey')} } elseif color == 'red' then diff --git a/locales/en.lua b/locales/en.lua index 755395e0..16a7189b 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -10,7 +10,7 @@ Locales['en'] = { -- Black ['black'] = 'black', ['graphite'] = 'graphite', - ['black_metallic'] = 'black Setallic', + ['black_metallic'] = 'black Metallic', ['caststeel'] = 'cast Steel', ['black_anth'] = 'black Anthracite', ['matteblack'] = 'matte Black', @@ -31,6 +31,27 @@ Locales['en'] = { ['purewhite'] = 'pure White', -- Grey ['grey'] = 'grey', + ['silver'] = 'silver', + ['metallicgrey'] = 'metallic Grey', + ['laminatedsteel'] = 'laminated Steel', + ['darkgray'] = 'dark Grey', + ['rockygray'] = 'rocky Grey', + ['graynight'] = 'gray Night' + ['aluminum'] = 'aluminum', + ['graymat'] = 'matte Grey', + ['lightgrey'] = 'light Grey', + ['asphaltgray'] = 'asphalt Grey', + ['grayconcrete'] = 'concrete Grey', + ['darksilver'] = 'dark Silver', + ['magnesite'] = 'magnesite', + ['nickel'] = 'nickel', + ['zinc'] = 'zinc', + ['dolomite'] = 'dolomite', + ['bluesilver'] = 'blue Silver', + ['titanium'] = 'titanium', + ['steelblue'] = 'steel Blue', + ['champagne'] = 'champagne', + ['grayhunter'] = 'grey Hunter', -- Red ['red'] = 'red', -- Pink diff --git a/locales/fr.lua b/locales/fr.lua index 2148348e..7a915e0c 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -31,6 +31,27 @@ Locales['fr'] = { ['purewhite'] = 'blanc Pure', -- Grey ['grey'] = 'gris', + ['silver'] = 'Argenté', + ['metallicgrey'] = 'Gris Métallisé', + ['laminatedsteel'] = 'Acier Laminé', + ['darkgray'] = 'Gris Foncé', + ['rockygray'] = 'Gris Rocheux', + ['graynight'] = 'Gris Nuit' + ['aluminum'] = 'Aluminium', + ['graymat'] = 'Gris Mat', + ['lightgrey'] = 'Gris Clair', + ['asphaltgray'] = 'Gris Bitume', + ['grayconcrete'] = 'Gris Béton', + ['darksilver'] = 'Argent Sombre', + ['magnesite'] = 'Magnésite', + ['nickel'] = 'nickel', + ['zinc'] = 'zinc', + ['dolomite'] = 'dolomite', + ['bluesilver'] = 'Argent Bleuté', + ['titanium'] = 'Titane', + ['steelblue'] = 'Acier Bleui', + ['champagne'] = 'Champagne', + ['grayhunter'] = 'Gris Chasseur', -- Red ['red'] = 'rouge', -- Pink From a36e9a9dba91dd3bd36760b7327ab87a8d893699 Mon Sep 17 00:00:00 2001 From: Don <30905704+ddh3@users.noreply.github.com> Date: Tue, 22 Aug 2017 21:14:42 -0700 Subject: [PATCH 0558/3224] Update en.lua --- locales/en.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/locales/en.lua b/locales/en.lua index 16a7189b..0eb7566a 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -36,7 +36,7 @@ Locales['en'] = { ['laminatedsteel'] = 'laminated Steel', ['darkgray'] = 'dark Grey', ['rockygray'] = 'rocky Grey', - ['graynight'] = 'gray Night' + ['graynight'] = 'gray Night', ['aluminum'] = 'aluminum', ['graymat'] = 'matte Grey', ['lightgrey'] = 'light Grey', @@ -76,7 +76,7 @@ Locales['en'] = { ['matteorange'] = 'Matte Orange', ['lightorange'] = 'Light Orange', ['peach'] = 'Peach', - ['pumpkin'] = 'Pumpkin' + ['pumpkin'] = 'Pumpkin', ['orangelambo'] = 'Orange Lambo', -- Brown ['brown'] = 'brown', @@ -107,7 +107,7 @@ Locales['en'] = { -- Purple ['purple'] = 'purple', ['indigo'] = 'Indigo', - ['deeppurple'] = 'Deep Purple' + ['deeppurple'] = 'Deep Purple', ['darkviolet'] = 'Dark Violet', ['amethyst'] = 'Amethyst', ['mysticalviolet'] = 'Mystic Violet', @@ -118,7 +118,7 @@ Locales['en'] = { ['chrome'] = 'chrome', ['brushedchrome'] = 'brushed Chrome', ['blackchrome'] = 'black Chrome', - ['brushedaluminum'] = 'brushed Aluminum' + ['brushedaluminum'] = 'brushed Aluminum', -- Metal ['gold'] = 'gold', ['puregold'] = 'pure Gold', From 79c8d0f8fe45c273e672d7823e66f69d5ac78a01 Mon Sep 17 00:00:00 2001 From: Don <30905704+ddh3@users.noreply.github.com> Date: Tue, 22 Aug 2017 21:15:50 -0700 Subject: [PATCH 0559/3224] Update fr.lua --- locales/fr.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index 7a915e0c..333c2ee0 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -12,7 +12,7 @@ Locales['fr'] = { ['graphite'] = 'graphite', ['black_metallic'] = 'noir Méttallisé', ['caststeel'] = 'acier Fondu', - ['black_anth'] = 'noir Anthracite' + ['black_anth'] = 'noir Anthracite', ['matteblack'] = 'noir Mat', ['darknight'] = 'nuit Sombre', ['deepblack'] = 'noir Profond', @@ -36,7 +36,7 @@ Locales['fr'] = { ['laminatedsteel'] = 'Acier Laminé', ['darkgray'] = 'Gris Foncé', ['rockygray'] = 'Gris Rocheux', - ['graynight'] = 'Gris Nuit' + ['graynight'] = 'Gris Nuit', ['aluminum'] = 'Aluminium', ['graymat'] = 'Gris Mat', ['lightgrey'] = 'Gris Clair', From 1dfeee2a18272ca30212ffa5e0e38a6242a24232 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 23 Aug 2017 10:17:58 +0200 Subject: [PATCH 0560/3224] Increase TickTime --- client/main.lua | 6 +++--- config.lua | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/client/main.lua b/client/main.lua index fd69e2e4..4db12de3 100644 --- a/client/main.lua +++ b/client/main.lua @@ -46,7 +46,7 @@ Citizen.CreateThread(function() if Status[i].clientAction.add ~= nil then - local val = Status[i].clientAction.add + local val = math.floor(Status[i].clientAction.add / (Config.TickTime / Config.ClientTickTime)) if Status[i].val + val > Config.StatusMax then Status[i].val = StatusMax @@ -58,7 +58,7 @@ Citizen.CreateThread(function() if Status[i].clientAction.remove ~= nil then - local val = Status[i].clientAction.remove + local val = math.floor(Status[i].clientAction.remove / (Config.TickTime / Config.ClientTickTime)) if Status[i].val - val < 0 then Status[i].val = 0 @@ -75,7 +75,7 @@ Citizen.CreateThread(function() status = Status }) - Citizen.Wait(Config.TickTime) + Citizen.Wait(Config.ClientqTickTime) end end) diff --git a/config.lua b/config.lua index 862ec1bd..1baf3075 100644 --- a/config.lua +++ b/config.lua @@ -1,5 +1,6 @@ Config = {} Config.StatusMax = 1000000 -Config.TickTime = 1000 -Config.UpdateClientTime = 60000 \ No newline at end of file +Config.TickTime = 30000 +Config.ClientTickTime = 1000 +Config.UpdateClientTime = 65000 \ No newline at end of file From b64e1f2e8526316ee4d717adaff216683421dc3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 23 Aug 2017 10:18:40 +0200 Subject: [PATCH 0561/3224] Change vals because of esx_status update --- server/main.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/main.lua b/server/main.lua index 09655337..626cb07e 100644 --- a/server/main.lua +++ b/server/main.lua @@ -7,9 +7,9 @@ TriggerEvent('esx_status:registerStatus', 'hunger', 1000000, '#CFAD0F', return true end, function(status) - status.remove(200) + status.remove(6000) end, - {remove = 200} + {remove = 6000} ) TriggerEvent('esx_status:registerStatus', 'thirst', 1000000, '#0C98F1', @@ -17,9 +17,9 @@ TriggerEvent('esx_status:registerStatus', 'thirst', 1000000, '#0C98F1', return true end, function(status) - status.remove(250) + status.remove(7500) end, - {remove = 250} + {remove = 7500} ) RegisterServerEvent('esx_basicneeds:resetStatus') From 4d901b0b7764c6ebe2e6c68067a91a31b72d5c0c Mon Sep 17 00:00:00 2001 From: Don Date: Wed, 23 Aug 2017 01:20:54 -0700 Subject: [PATCH 0562/3224] Multi-language support Added en language support --- __resource.lua | 6 ++ client/main.lua | 154 ++++++++++++++++++++++++------------------------ config.lua | 1 + locales/en.lua | 47 +++++++++++++++ locales/fr.lua | 47 +++++++++++++++ server/main.lua | 22 +++---- 6 files changed, 189 insertions(+), 88 deletions(-) create mode 100644 locales/en.lua create mode 100644 locales/fr.lua diff --git a/__resource.lua b/__resource.lua index a74c4022..7ce747e8 100644 --- a/__resource.lua +++ b/__resource.lua @@ -4,11 +4,17 @@ description 'ESX Vehicle Shop' server_scripts { '@mysql-async/lib/MySQL.lua', + '@es_extended/locale.lua' , + 'locales/en.lua' , + 'locales/fr.lua' , 'config.lua', 'server/main.lua' } client_scripts { + '@es_extended/locale.lua' , + 'locales/en.lua' , + 'locales/fr.lua' , 'config.lua', 'client/main.lua' } diff --git a/client/main.lua b/client/main.lua index adf3f888..d2f18d04 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,10 +1,10 @@ local Keys = { - ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, - ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, - ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 @@ -83,7 +83,7 @@ function OpenShopMenu() local options = {} for j=1, #categoryVehicles, 1 do - + local vehicle = categoryVehicles[j] if i == 1 and j == 1 then @@ -107,7 +107,7 @@ function OpenShopMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'vehicle_shop', { - title = 'Concessionnaire', + title = _U('car_dealer'), align = 'top-left', elements = elements }, @@ -118,11 +118,11 @@ function OpenShopMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'shop_confirm', { - title = 'Acheter ' .. vehicleData.name .. ' pour $' .. vehicleData.price .. ' ?', + title = _U('buy').. vehicleData.name .. _U('for').. vehicleData.price .. ' ?', align = 'top-left', elements = { - {label = 'Oui', value = 'yes'}, - {label = 'Non', value = 'no'}, + {label = _U('yes'), value = 'yes'}, + {label = _U('no'), value = 'no'}, } }, function(data2, menu2) @@ -140,9 +140,9 @@ function OpenShopMenu() DeleteShopInsideVehicles() local playerPed = GetPlayerPed(-1) - + CurrentAction = 'shop_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('shop_menu') CurrentActionData = {} FreezeEntityPosition(playerPed, false) @@ -152,9 +152,9 @@ function OpenShopMenu() menu2.close() menu.close() - ESX.ShowNotification('Vous avez acheté un véhicule') + ESX.ShowNotification(_U('vehicle_purchased')) else - ESX.ShowNotification('Vous n\'avez pas assez d\'argent sur votre compte société') + ESX.ShowNotification(_U('broke_company')) end end, vehicleData.model) @@ -177,7 +177,7 @@ function OpenShopMenu() y = Config.Zones.ShopOutside.Pos.y, z = Config.Zones.ShopOutside.Pos.z }, -20.0, function(vehicle) - + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) @@ -190,7 +190,7 @@ function OpenShopMenu() SetEntityVisible(playerPed, true) else - ESX.ShowNotification('Vous n\'avez pas assez d\'argent') + ESX.ShowNotification(_U('not_enough_money')) end end, vehicleData.model) @@ -211,7 +211,7 @@ function OpenShopMenu() end, function(data, menu) - + menu.close() DeleteShopInsideVehicles() @@ -219,7 +219,7 @@ function OpenShopMenu() local playerPed = GetPlayerPed(-1) CurrentAction = 'shop_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('shop_menu') CurrentActionData = {} FreezeEntityPosition(playerPed, false) @@ -275,15 +275,15 @@ function OpenResellerMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'reseller', { - title = 'Concessionnaire', + title = _U('car_dealer'), align = 'top-left', elements = { - {label = 'Sortir véhicule', value = 'pop_vehicle'}, - {label = 'Rentrer véhicule', value = 'depop_vehicle'}, - {label = 'Créer facture', value = 'create_bill'}, - {label = 'Véhicules en location', value = 'get_rented_vehicles'}, - {label = 'Attribuer véhicule [Vente]', value = 'set_vehicle_owner_sell'}, - {label = 'Attribuer véhicule [Location]', value = 'set_vehicle_owner_rent'}, + {label = _U('pop_vehicle'), value = 'pop_vehicle'}, + {label = _U('depop_vehicle'), value = 'depop_vehicle'}, + {label = _U('create_bill'), value = 'create_bill'}, + {label = _U('get_rented_vehicles'), value = 'get_rented_vehicles'}, + {label = _U('set_vehicle_owner_sell'), value = 'set_vehicle_owner_sell'}, + {label = _U('set_vehicle_owner_rent'), value = 'set_vehicle_owner_rent'}, } }, function(data, menu) @@ -301,24 +301,24 @@ function OpenResellerMenu() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'set_vehicle_owner_sell_amount', { - title = 'Montant de la facture' + title = _U('invoice_amount') }, function(data2, menu) local amount = tonumber(data2.value) if amount == nil then - ESX.ShowNotification('Montant invalide') + ESX.ShowNotification(_U('invoice_amount')) else - + menu.close() local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification('Aucun joueur à proximité') + ESX.ShowNotification(_U('invoice_amount')) else - TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_cardealer', 'Concessionnaire', tonumber(data2.value)) + TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_cardealer', _U('car_dealership'), tonumber(data2.value)) end end @@ -340,7 +340,7 @@ function OpenResellerMenu() local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification('Aucun joueur à proximité') + ESX.ShowNotification(_U('no_players')) else local vehicleProps = ESX.Game.GetVehicleProperties(LastVehicles[#LastVehicles]) @@ -357,22 +357,22 @@ function OpenResellerMenu() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'set_vehicle_owner_rent_amount', { - title = 'Montant de la location' + title = _U('rental_amount') }, function(data2, menu) local amount = tonumber(data2.value) if amount == nil then - ESX.ShowNotification('Montant invalide') + ESX.ShowNotification(_U('invalid_amount')) else - + menu.close() local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() if closestPlayer == -1 or closestDistance > 5.0 then - ESX.ShowNotification('Aucun joueur à proximité') + ESX.ShowNotification(_U('no_players')) else SetVehicleNumberPlateText(LastVehicles[#LastVehicles], 'LOC ' .. ESX.GetRandomString(5)) @@ -397,11 +397,11 @@ function OpenResellerMenu() end, function(data, menu) - + menu.close() CurrentAction = 'reseller_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('shop_menu') CurrentActionData = {} end @@ -432,12 +432,12 @@ function OpenPersonnalVehicleMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'personnal_vehicle', { - title = 'Véhicule personnel', + title = _U('personal_vehicle'), align = 'top-left', elements = elements }, function(data, menu) - + local playerPed = GetPlayerPed(-1) local coords = GetEntityCoords(playerPed) local heading = GetEntityHeading(playerPed) @@ -476,7 +476,7 @@ function OpenPopVehicleMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'commercial_vehicles', { - title = 'Concessionnaire - Véhicules', + title = _U('vehicle_dealer'), align = 'top-left', elements = elements }, @@ -491,7 +491,7 @@ function OpenPopVehicleMenu() y = Config.Zones.ShopInside.Pos.y, z = Config.Zones.ShopInside.Pos.z }, 90.0, function(vehicle) - + table.insert(LastVehicles, vehicle) for i=1, #Vehicles, 1 do @@ -525,7 +525,7 @@ function OpenRentedVehiclesMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'rented_vehicles', { - title = 'Concessionnaire - Véhicules en location', + title = _U('rent_vehicle'), align = 'top-left', elements = elements }, @@ -546,13 +546,13 @@ function OpenBossActionsMenu() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'reseller', { - title = 'Concessionnaire - Patron', + title = _U('dealer_boss'), align = 'top-left', elements = { - {label = 'Acheter véhicule', value = 'buy_vehicle'}, - {label = 'Retirer argent société', value = 'withdraw_society_money'}, - {label = 'Déposer argent ', value = 'deposit_money'}, - {label = 'Blanchir argent', value = 'wash_money'} + {label = _U('buy_vehicle'), value = 'buy_vehicle'}, + {label = _U('withdraw_money'), value = 'withdraw_society_money'}, + {label = _U('deposit_money'), value = 'deposit_money'}, + {label = _U('wash_money'), value = 'wash_money'} } }, function(data, menu) @@ -566,14 +566,14 @@ function OpenBossActionsMenu() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'withdraw_society_money_amount', { - title = 'Montant du retrait' + title = _U('withdraw_amount'), }, function(data, menu) local amount = tonumber(data.value) if amount == nil then - ESX.ShowNotification('Montant invalide') + ESX.ShowNotification(_U('invalid_amount')) else menu.close() TriggerServerEvent('esx_society:withdrawMoney', 'cardealer', amount) @@ -592,14 +592,14 @@ function OpenBossActionsMenu() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'deposit_money_amount', { - title = 'Montant du dépôt' + title = _U('deposit_money'), }, function(data, menu) local amount = tonumber(data.value) if amount == nil then - ESX.ShowNotification('Montant invalide') + ESX.ShowNotification(_U('invalid_amount')) else menu.close() TriggerServerEvent('esx_society:depositMoney', 'cardealer', amount) @@ -618,14 +618,14 @@ function OpenBossActionsMenu() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'wash_money_amount', { - title = 'Montant à blanchir' + title = _U('bleach_amount'), }, function(data, menu) local amount = tonumber(data.value) if amount == nil then - ESX.ShowNotification('Montant invalide') + ESX.ShowNotification(_U('invalid_amount')) else menu.close() TriggerServerEvent('esx_society:washMoney', 'cardealer', amount) @@ -641,11 +641,11 @@ function OpenBossActionsMenu() end, function(data, menu) - + menu.close() CurrentAction = 'boss_actions_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('shop_menu') CurrentActionData = {} end @@ -655,7 +655,7 @@ end RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) - + PlayerData = xPlayer if Config.EnablePlayerManagement then @@ -679,7 +679,7 @@ end) RegisterNetEvent('esx:setJob') AddEventHandler('esx:setJob', function(job) - + PlayerData.job = job if Config.EnablePlayerManagement then @@ -714,14 +714,14 @@ AddEventHandler('esx_vehicleshop:hasEnteredMarker', function(zone) if PlayerData.job ~= nil and PlayerData.job.name == 'cardealer' then CurrentAction = 'reseller_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('shop_menu') CurrentActionData = {} end else CurrentAction = 'shop_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('shop_menu') CurrentActionData = {} end @@ -733,12 +733,12 @@ AddEventHandler('esx_vehicleshop:hasEnteredMarker', function(zone) local playerPed = GetPlayerPed(-1) if IsPedInAnyVehicle(playerPed, false) then - + local vehicle = GetVehiclePedIsIn(playerPed, false) CurrentAction = 'give_back_vehicle' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour rendre votre véhicule' - + CurrentActionMsg = _U('vehicle_menu') + CurrentActionData = { vehicle = vehicle } @@ -766,8 +766,8 @@ AddEventHandler('esx_vehicleshop:hasEnteredMarker', function(zone) local resellPrice = math.floor(vehicleData.price / 100 * Config.ResellPercentage) CurrentAction = 'resell_vehicle' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour vendre ' .. vehicleData.name .. ' au prix de $' .. resellPrice - + CurrentActionMsg = _U('sell_menu').. vehicleData.name .. _U('price') .. resellPrice + CurrentActionData = { vehicle = vehicle, price = resellPrice @@ -780,7 +780,7 @@ AddEventHandler('esx_vehicleshop:hasEnteredMarker', function(zone) if zone == 'BossActions' and Config.EnablePlayerManagement and PlayerData.job ~= nil and PlayerData.job.name == 'cardealer' and PlayerData.job.grade_name == 'boss' then CurrentAction = 'boss_actions_menu' - CurrentActionMsg = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu' + CurrentActionMsg = _U('shop_menu') CurrentActionData = {} end @@ -815,7 +815,7 @@ end -- Create Blips Citizen.CreateThread(function() - + local blip = AddBlipForCoord(Config.Zones.ShopEntering.Pos.x, Config.Zones.ShopEntering.Pos.y, Config.Zones.ShopEntering.Pos.z) SetBlipSprite (blip, 326) @@ -824,7 +824,7 @@ Citizen.CreateThread(function() SetBlipAsShortRange(blip, true) BeginTextCommandSetBlipName("STRING") - AddTextComponentString("Concessionnaire") + AddTextComponentString(_U('car_dealer')) EndTextCommandSetBlipName(blip) end) @@ -832,11 +832,11 @@ end) -- Display markers Citizen.CreateThread(function() while true do - + Wait(0) - + local coords = GetEntityCoords(GetPlayerPed(-1)) - + for k,v in pairs(Config.Zones) do if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) @@ -849,9 +849,9 @@ end) -- Enter / Exit marker events Citizen.CreateThread(function() while true do - + Wait(0) - + local coords = GetEntityCoords(GetPlayerPed(-1)) local isInMarker = false local currentZone = nil @@ -890,7 +890,7 @@ Citizen.CreateThread(function() DisplayHelpTextFromStringLabel(0, 0, 1, -1) if IsControlPressed(0, Keys['E']) and (GetGameTimer() - GUI.Time) > 300 then - + if CurrentAction == 'shop_menu' then OpenShopMenu() end @@ -905,9 +905,9 @@ Citizen.CreateThread(function() if isRentedVehicle then DeleteVehicle(CurrentActionData.vehicle) - ESX.ShowNotification('Véhicule ~g~rendu~s~ au concessionnaire') + ESX.ShowNotification(_U('delivered')) else - ESX.ShowNotification('Ce n\'est pas un ~r~véhicule de location~s~') + ESX.ShowNotification(_U('not_rental')) end end, GetVehicleNumberPlateText(CurrentActionData.vehicle)) @@ -920,9 +920,9 @@ Citizen.CreateThread(function() if isOwnedVehicle then DeleteVehicle(CurrentActionData.vehicle) - ESX.ShowNotification('Véhicule ~g~vendu~s~') + ESX.ShowNotification(_U('vehicle_sold')) else - ESX.ShowNotification('Ce véhicule ne vous appartient pas') + ESX.ShowNotification(_U('not_yours')) end end, GetVehicleNumberPlateText(CurrentActionData.vehicle), CurrentActionData.price) @@ -935,7 +935,7 @@ Citizen.CreateThread(function() CurrentAction = nil GUI.Time = GetGameTimer() - + end end @@ -953,4 +953,4 @@ Citizen.CreateThread(function() RequestIpl('v_carshowroom') RequestIpl('shr_int') RequestIpl('shutter_closed') -end) \ No newline at end of file +end) diff --git a/config.lua b/config.lua index 238ef765..81ea2e7a 100644 --- a/config.lua +++ b/config.lua @@ -4,6 +4,7 @@ Config.MarkerColor = {r = 120, g = 120, b = 240} Config.EnablePlayerManagement = false -- If set to true, you need esx_addonaccount, esx_billing and esx_society Config.EnablePvCommand = true Config.ResellPercentage = 50 +Config.Locale = 'fr' Config.Zones = { diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..4cdf1dba --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,47 @@ +Locales['en'] = { + --Global menus + ['car_dealer'] = 'car Dealership', + ['buy'] = 'buy', + ['for'] = 'for $', + ['yes'] = 'yes', + ['no'] = 'no', + ['shop_menu'] = 'press ~INPUT_CONTEXT~ to access the menu', + ['vehicle_purchase'] = 'you bought a vehicle', + ['broke_company'] = 'you do not have enough money in the company account', + ['not_enough_money'] = 'you do not have enough money', + ['pop_vehicle'] = 'exit vehicle', + ['depop_vehicle'] = 'return vehicle', + ['create_bill'] = 'create invoice', + ['get_rented_vehicles'] = 'vehicles for rent', + ['set_vehicle_owner_sell'] = 'vehicles for [sale]', + ['set_vehicle_owner_rent'] = 'assign vehicle [Location]', + ['invoice_amount'] = 'invoice amount', + ['invalid_amount'] = 'invalid amount', + ['no_players'] = 'no players nearby', + ['rental_amount'] = 'rental amount', + ['personal_vehicle'] = 'personal vehicle', + ['vehicle_dealer'] = 'vehicle - Car Dealer', + ['rent_vehicle'] = 'car Dealer - Vehicles for rent', + ['dealer_boss'] = 'car Dealer - Boss', + ['buy_vehicle'] = 'buy vehicle', + ['withdraw_money'] = 'remove company money', + ['deposit_money'] = 'deposit money', + ['wash_money'] = 'money laundering', + ['withdraw_amount'] = 'amount of withdrawal', + ['deposit_amount'] = 'deposit amount', + ['bleach amount'] = 'amount to bleach', + ['vehicle_menu'] = 'press ~INPUT_CONTEXT~ to make your vehicle', + ['sell_menu'] = 'press ~INPUT_CONTEXT~ to sell ', + ['price'] = ' for the amount of $', + ['delivered'] = 'vehicle ~g~delivered~s~ to the dealer', + ['not_rental'] = 'this is not a ~r~rental vehicle~s~', + ['vehicle_sold'] = 'vehicle ~g~sold~s~', + ['not_yours'] = 'this vehicle does not belong to you', + ['vehicle'] = 'vehicle ', + ['belongs'] = ' now belongs to you', + ['leaving'] = 'leaving a personal vehicle', + ['paid_rental'] = 'you have ~g~payed~s~ for your vehicle rental : ~g~$', + ['recruit'] = 'recruit', + ['experianced'] = 'experianced', + ['the_boss'] = 'boss', +} diff --git a/locales/fr.lua b/locales/fr.lua new file mode 100644 index 00000000..c17c077f --- /dev/null +++ b/locales/fr.lua @@ -0,0 +1,47 @@ +Locales['fr'] = { + --Global menus + ['car_dealer'] = 'Concessionnaire', + ['buy'] = 'Acheter', + ['for'] = 'pour $', + ['yes'] = 'Oui', + ['no'] = 'Non', + ['shop_menu'] = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu', + ['vehicle_purchase'] = 'Vous avez acheté un véhicule', + ['broke_company'] = 'Vous n\'avez pas assez d\'argent sur votre compte société', + ['not_enough_money'] = 'Vous n\'avez pas assez d\'argent', + ['pop_vehicle'] = 'Sortir véhicule', + ['depop_vehicle'] = 'Rentrer véhicule', + ['create_bill'] = 'Créer facture', + ['get_rented_vehicles'] = 'Véhicules en location', + ['set_vehicle_owner_sell'] = 'Attribuer véhicule [Vente]', + ['set_vehicle_owner_rent'] = 'Attribuer véhicule [Location]', + ['invoice_amount'] = 'Montant de la facture', + ['invalid_amount'] = 'Montant invalide', + ['no_players'] = 'Aucun joueur à proximité', + ['rental_amount'] = 'Montant de la location', + ['personal_vehicle'] = 'Véhicule personnel', + ['vehicle_dealer'] = 'Concessionnaire - Véhicules', + ['rent_vehicle'] = 'Concessionnaire - Véhicules en location', + ['dealer_boss'] = 'Concessionnaire - Patron', + ['buy_vehicle'] = 'Acheter véhicule', + ['withdraw_money'] = 'Retirer argent société', + ['deposit_money'] = 'Déposer argent', + ['wash_money'] = 'Blanchir argent', + ['withdraw_amount'] = 'Montant du retrait', + ['deposit_amount'] = 'Montant du dépôt', + ['bleach amount'] = 'Montant à blanchir', + ['vehicle_menu'] = 'Appuez sur ~INPUT_CONTEXT~ pour rendre votre véhicule', + ['sell_menu'] = 'Appuez sur ~INPUT_CONTEXT~ pour vendre', + ['price'] = 'au prix de $', + ['delivered'] = 'Véhicule ~g~rendu~s~ au concessionnaire', + ['not_rental'] = 'Ce n\'est pas un ~r~véhicule de location~s~', + ['vehicle_sold'] = 'Véhicule ~g~vendu~s~', + ['not_yours'] = 'Ce véhicule ne vous appartient pas', + ['vehicle'] = 'Le véhicule', + ['belongs'] = 'vous appartient désormais', + ['leaving'] = 'Sortir un véhicule personnel', + ['paid_rental'] = 'Vous avez ~g~payé~s~ votre location de véhicule : ~g~$', + ['recruit'] = 'Recrue', + ['experianced'] = 'Experimente', + ['the_boss'] = 'Patron', +} diff --git a/server/main.lua b/server/main.lua index 7c70127f..c564c4e2 100644 --- a/server/main.lua +++ b/server/main.lua @@ -67,7 +67,7 @@ AddEventHandler('esx_vehicleshop:setVehicleOwned', function(vehicleProps) ['@owner'] = xPlayer.identifier }, function(rowsChanged) - TriggerClientEvent('esx:showNotification', _source, 'Le véhicule ' .. vehicleProps.plate .. ' vous appartient désormais') + TriggerClientEvent('esx:showNotification', _source, _U('vehicle').. vehicleProps.plate .. _('belongs')) end ) @@ -85,7 +85,7 @@ AddEventHandler('esx_vehicleshop:setVehicleOwnedPlayerId', function(playerId, ve ['@owner'] = xPlayer.identifier }, function(rowsChanged) - TriggerClientEvent('esx:showNotification', playerId, 'Le véhicule ' .. vehicleProps.plate .. ' vous appartient désormais') + TriggerClientEvent('esx:showNotification', playerId, _U('vehicle').. vehicleProps.plate .. _('belongs')) end ) @@ -93,7 +93,7 @@ end) RegisterServerEvent('esx_vehicleshop:sellVehicle') AddEventHandler('esx_vehicleshop:sellVehicle', function(vehicle) - + MySQL.Async.fetchAll( 'SELECT * FROM cardealer_vehicles WHERE vehicle = @vehicle LIMIT 1', { @@ -138,7 +138,7 @@ AddEventHandler('esx_vehicleshop:rentVehicle', function(vehicle, plate, playerNa ['@id'] = id } ) - + 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)', { @@ -170,7 +170,7 @@ ESX.RegisterServerCallback('esx_vehicleshop:getVehicles', function(source, cb) end) ESX.RegisterServerCallback('esx_vehicleshop:buyVehicle', function(source, cb, vehicleModel) - + local xPlayer = ESX.GetPlayerFromId(source) local vehicleData = nil @@ -191,7 +191,7 @@ ESX.RegisterServerCallback('esx_vehicleshop:buyVehicle', function(source, cb, ve end) ESX.RegisterServerCallback('esx_vehicleshop:buyVehicleSociety', function(source, cb, vehicleModel) - + local vehicleData = nil for i=1, #Vehicles, 1 do @@ -379,7 +379,7 @@ ESX.RegisterServerCallback('esx_vehicleshop:resellVehicle', function(source, cb, xPlayer.addMoney(price) RemoveOwnedVehicle(plate) - + cb(true) else @@ -408,14 +408,14 @@ TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message end end end - + end) if Config.EnablePvCommand then TriggerEvent('es:addCommand', 'pv', function(source, args, user) TriggerClientEvent('esx_vehicleshop:openPersonnalVehicleMenu', source) - end, {help = 'Sortir un véhicule personnel'}) + end, {help = _U('leaving')}) end @@ -457,8 +457,8 @@ function PayRent(d, h, m) if foundPlayer then xPlayer.removeMoney(result[i].rent_price) - TriggerClientEvent('esx:showNotification', xPlayer.source, 'Vous avez ~g~payé~s~ votre location de véhicule : ~g~$' .. result[i].rent_price) - + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('paid_rental') .. result[i].rent_price) + else newMoney[result[i].owner] = newMoney[result[i].owner] - result[i].rent_price end From b91542016f5c88ddcf2c9706616e9032c436bd0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 23 Aug 2017 10:38:07 +0200 Subject: [PATCH 0563/3224] [TEST] Use Async.parallelLimit to calculate bank interests --- server/main.lua | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/server/main.lua b/server/main.lua index 59e8cf06..eba7d460 100644 --- a/server/main.lua +++ b/server/main.lua @@ -75,6 +75,8 @@ end) function CalculateBankSavings(d, h, m) + local asyncTasks = {} + MySQL.Async.fetchAll( 'SELECT * FROM addon_account_data WHERE account_name = @account_name', { @@ -115,14 +117,27 @@ function CalculateBankSavings(d, h, m) local newMoney = result[i].money + interests; bankInterests = bankInterests + interests - MySQL.Async.execute( - 'UPDATE addon_account_data SET money = @money WHERE owner = @owner AND account_name = @account_name', - { - ['@money'] = newMoney, - ['@owner'] = result[i].owner, - ['@account_name'] = 'bank_savings' - } - ) + 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', + { + ['@money'] = newMoney, + ['@owner'] = owner, + ['@account_name'] = 'bank_savings' + }, + function(rowsChanged) + cb() + end + ) + + end) + + end + + scope(newMoney, result[i].owner) end @@ -132,9 +147,15 @@ function CalculateBankSavings(d, h, m) account.addMoney(bankInterests) end) + Async.parallelLimit(asyncTasks, 5, function(results) + print('[BANK] Calculated interests') + end) + end ) end -TriggerEvent('cron:runAt', 22, 00, CalculateBankSavings) +TriggerEvent('cron:runAt', 22, 0, CalculateBankSavings) + + From 61e7f37c7b3d0dd12cc0168c14aecfb75effc9a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 23 Aug 2017 10:38:48 +0200 Subject: [PATCH 0564/3224] Add new __resource.lua --- __resource.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/__resource.lua b/__resource.lua index 80f8453a..e6a33645 100644 --- a/__resource.lua +++ b/__resource.lua @@ -3,6 +3,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ESX Banker job' server_scripts { + '@async/async.lua', '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', 'config.lua', From c762972e917c43eb681862b7b111c4bd367fda54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 23 Aug 2017 12:05:40 +0200 Subject: [PATCH 0565/3224] Additionnal check on customer + Now it go to vehicle when close to 100 meters --- client/main.lua | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/client/main.lua b/client/main.lua index b7369919..247d5928 100644 --- a/client/main.lua +++ b/client/main.lua @@ -490,7 +490,7 @@ Citizen.CreateThread(function() end - if DoesEntityExist(CurrentCustomer) then + if DoesEntityExist(CurrentCustomer) and IsEntityAPed(CurrentCustomer) then CurrentCustomerBlip = AddBlipForEntity(CurrentCustomer) @@ -509,6 +509,8 @@ Citizen.CreateThread(function() ESX.ShowNotification(_U('customer_found')) + else + CurrentCustomer = nil end end @@ -567,6 +569,14 @@ Citizen.CreateThread(function() RemoveBlip(DestinationBlip) + local scope = function(customer) + ESX.SetTimeout(5000, function() + DeletePed(customer) + end) + end + + scope(CurrentCustomer) + CurrentCustomer = nil CurrentCustomerBlip = nil DestinationBlip = nil @@ -614,9 +624,7 @@ Citizen.CreateThread(function() else - if not CustomerIsEnteringVehicle then - DrawMarker(1, customerCoords.x, customerCoords.y, customerCoords.z - 1.0, 0, 0, 0, 0, 0, 0, 4.0, 4.0, 2.0, 178, 236, 93, 155, 0, 0, 2, 0, 0, 0, 0) - end + DrawMarker(1, customerCoords.x, customerCoords.y, customerCoords.z - 1.0, 0, 0, 0, 0, 0, 0, 4.0, 4.0, 2.0, 178, 236, 93, 155, 0, 0, 2, 0, 0, 0, 0) if not CustomerEnteredVehicle then @@ -629,7 +637,7 @@ Citizen.CreateThread(function() end - if customerDistance <= 10.0 then + if customerDistance <= 100.0 then if not CustomerIsEnteringVehicle then From d799eea7dce236182c560a35d8decda5779843fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 23 Aug 2017 12:25:29 +0200 Subject: [PATCH 0566/3224] Increade DeletePed time --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 247d5928..239bac8b 100644 --- a/client/main.lua +++ b/client/main.lua @@ -570,7 +570,7 @@ Citizen.CreateThread(function() RemoveBlip(DestinationBlip) local scope = function(customer) - ESX.SetTimeout(5000, function() + ESX.SetTimeout(60000, function() DeletePed(customer) end) end From e14306304e3895ec45fe5804d99cdb32c1f3c901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 23 Aug 2017 12:57:42 +0200 Subject: [PATCH 0567/3224] Use ZDiff everywhere --- client/main.lua | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/client/main.lua b/client/main.lua index 3caf6ded..eda27bcb 100644 --- a/client/main.lua +++ b/client/main.lua @@ -56,6 +56,8 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) ESX.TriggerServerCallback('esx_vehicleshop:getVehiclesInGarage', function(vehicles) + print('') + for i=1, #garage.Parkings, 1 do for j=1, #vehicles, 1 do @@ -66,7 +68,7 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) ESX.Game.SpawnLocalVehicle(vehicles[j].vehicle.model, { x = garage.Parkings[i].Pos.x, y = garage.Parkings[i].Pos.y, - z = garage.Parkings[i].Pos.z + z = garage.Parkings[i].Pos.z + Config.ZDiff }, garage.Parkings[i].Heading, function(vehicle) ESX.Game.SetVehicleProperties(vehicle, vehicles[j].vehicle) end) @@ -89,7 +91,7 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) ESX.Game.Teleport(playerPed, { x = garage.InteriorSpawnPoint.Pos.x, y = garage.InteriorSpawnPoint.Pos.y, - z = garage.InteriorSpawnPoint.Pos.z + z = garage.InteriorSpawnPoint.Pos.z + Config.ZDiff }, function() TriggerEvent('instance:create', 'garage') @@ -106,7 +108,7 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) ESX.Game.SpawnLocalVehicle(vehicles[j].vehicle.model, { x = garage.Parkings[i].Pos.x, y = garage.Parkings[i].Pos.y, - z = garage.Parkings[i].Pos.z + z = garage.Parkings[i].Pos.z + Config.ZDiff }, garage.Parkings[i].Heading, function(vehicle) ESX.Game.SetVehicleProperties(vehicle, vehicles[j].vehicle) end) @@ -132,7 +134,7 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) ESX.Game.Teleport(playerPed, { x = garage.InteriorSpawnPoint.Pos.x, y = garage.InteriorSpawnPoint.Pos.y, - z = garage.InteriorSpawnPoint.Pos.z + z = garage.InteriorSpawnPoint.Pos.z + Config.ZDiff }, function() TriggerEvent('instance:create', 'garage') @@ -149,7 +151,7 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) ESX.Game.SpawnLocalVehicle(vehicles[j].vehicle.model, { x = garage.Parkings[i].Pos.x, y = garage.Parkings[i].Pos.y, - z = garage.Parkings[i].Pos.z + z = garage.Parkings[i].Pos.z + Config.ZDiff }, garage.Parkings[i].Heading, function(vehicle) ESX.Game.SetVehicleProperties(vehicle, vehicles[j].vehicle) end) From f34ea3c42fb039ec7f82183952bae834fdd3ed24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 23 Aug 2017 12:58:28 +0200 Subject: [PATCH 0568/3224] Add check on instance close --- server/main.lua | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/server/main.lua b/server/main.lua index 47dd9cc4..958bcb50 100644 --- a/server/main.lua +++ b/server/main.lua @@ -30,14 +30,18 @@ end function CloseInstance(instance) - for i=1, #Instances[instance].players, 1 do - TriggerClientEvent('instance:onClose', Instances[instance].players[i]) + if Instances[instance] ~= nil then + + for i=1, #Instances[instance].players, 1 do + TriggerClientEvent('instance:onClose', Instances[instance].players[i]) + end + + Instances[instance] = nil + + TriggerClientEvent('instance:onInstancedPlayersData', -1, GetInstancedPlayers()) + end - Instances[instance] = nil - - TriggerClientEvent('instance:onInstancedPlayersData', -1, GetInstancedPlayers()) - end function AddPlayerToInstance(instance, player) From 7730aa52f13cfb8b64caedb9d922dfd44487f7ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 23 Aug 2017 13:14:16 +0200 Subject: [PATCH 0569/3224] Add missing REgisterServerEvent --- server/main.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/server/main.lua b/server/main.lua index 0c5ac3f9..e4224f2b 100644 --- a/server/main.lua +++ b/server/main.lua @@ -23,6 +23,7 @@ AddEventHandler('esx_service:activateService', function(name, max) MaxInService[name] = max end) +RegisterServerEvent('esx_service:disableService') AddEventHandler('esx_service:disableService', function(name) InService[name][source] = nil end) From 0389a5c643fcf9255f149a370be2acaf1129cc25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 23 Aug 2017 15:29:57 +0200 Subject: [PATCH 0570/3224] Remove TeleportEntity duplicate of Teleport --- .../es_extended/client/functions.lua | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 0a8f2035..1dd6725c 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -941,27 +941,6 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) end -ESX.Game.TeleportEntity = function(entity, coords, cb) - - Citizen.CreateThread(function() - - RequestCollisionAtCoord(coords.x, coords.y, coords.z) - - while not HasCollisionLoadedAroundEntity(entity) do - RequestCollisionAtCoord(coords.x, coords.y, coords.z) - Citizen.Wait(0) - end - - SetEntityCoords(entity, coords.x, coords.y, coords.z) - - if cb ~= nil then - cb() - end - - end) - -end - ESX.Game.Utils.DrawText3D = function(coords, text, size) local onScreen, x, y = World3dToScreen2d(coords.x, coords.y, coords.z) From 3b45b104417937f48fbda1932f8ed5afd68b3116 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 23 Aug 2017 15:53:01 +0200 Subject: [PATCH 0571/3224] Fix duplicate vehicles in garage --- client/main.lua | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index eda27bcb..0b614c15 100644 --- a/client/main.lua +++ b/client/main.lua @@ -56,8 +56,6 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) ESX.TriggerServerCallback('esx_vehicleshop:getVehiclesInGarage', function(vehicles) - print('') - for i=1, #garage.Parkings, 1 do for j=1, #vehicles, 1 do @@ -65,6 +63,12 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) local spawn = function(j) + local vehicle = GetClosestVehicle(garage.Parkings[i].Pos.x, garage.Parkings[i].Pos.garage.Parkings[i].Pos.y, garage.Parkings[i].Pos.z, 2.0, 0, 71) + + if DoesEntityExist(vehicle) then + ESX.Game.DeleteVehicle(vehicle) + end + ESX.Game.SpawnLocalVehicle(vehicles[j].vehicle.model, { x = garage.Parkings[i].Pos.x, y = garage.Parkings[i].Pos.y, @@ -105,6 +109,12 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) local spawn = function(j) + local vehicle = GetClosestVehicle(garage.Parkings[i].Pos.x, garage.Parkings[i].Pos.garage.Parkings[i].Pos.y, garage.Parkings[i].Pos.z, 2.0, 0, 71) + + if DoesEntityExist(vehicle) then + ESX.Game.DeleteVehicle(vehicle) + end + ESX.Game.SpawnLocalVehicle(vehicles[j].vehicle.model, { x = garage.Parkings[i].Pos.x, y = garage.Parkings[i].Pos.y, @@ -148,6 +158,12 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) local spawn = function(j) + local vehicle = GetClosestVehicle(garage.Parkings[i].Pos.x, garage.Parkings[i].Pos.y, garage.Parkings[i].Pos.z, 2.0, 0, 71) + + if DoesEntityExist(vehicle) then + ESX.Game.DeleteVehicle(vehicle) + end + ESX.Game.SpawnLocalVehicle(vehicles[j].vehicle.model, { x = garage.Parkings[i].Pos.x, y = garage.Parkings[i].Pos.y, From 98b8b38ad29eb039b57b34fa49a188f9f934bbe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 23 Aug 2017 15:58:47 +0200 Subject: [PATCH 0572/3224] Close menu before re-open --- client/main.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/main.lua b/client/main.lua index 7183a639..7bd0d8fc 100644 --- a/client/main.lua +++ b/client/main.lua @@ -41,6 +41,8 @@ function ShowBillsMenu() }, function(data, menu) + menu.close() + local billId = data.current.value ESX.TriggerServerCallback('esx_billing:payBill', function() From e9cea9fe51ab8ee03e888fedcc8f7b75eb4bc04e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 23 Aug 2017 17:12:00 +0200 Subject: [PATCH 0573/3224] Fix menu close bug --- .../es_extended/client/functions.lua | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 1dd6725c..24b68c95 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -134,6 +134,8 @@ ESX.UI.Menu.RegisterType = function(type, open, close) end +local _type = type + ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change, close) local menu = {} @@ -151,9 +153,13 @@ ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change, ESX.UI.Menu.RegisteredTypes[type].close(namespace, name) for i=1, #ESX.UI.Menu.Opened, 1 do - if ESX.UI.Menu.Opened[i].type == type and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then - ESX.UI.Menu.Opened[i] = nil + + if ESX.UI.Menu.Opened[i] ~= nil then + if ESX.UI.Menu.Opened[i].type == type and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then + ESX.UI.Menu.Opened[i] = nil + end end + end if close ~= nil then @@ -203,9 +209,11 @@ end ESX.UI.Menu.Close = function(type, namespace, name) for i=1, #ESX.UI.Menu.Opened, 1 do - if ESX.UI.Menu.Opened[i].type == type and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then - ESX.UI.Menu.Opened[i].close() - ESX.UI.Menu.Opened[i] = nil + if ESX.UI.Menu.Opened[i] ~= nil then + if ESX.UI.Menu.Opened[i].type == type and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then + ESX.UI.Menu.Opened[i].close() + ESX.UI.Menu.Opened[i] = nil + end end end From 7643336246457c7a228334831ad0e7d51caf595b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 23 Aug 2017 17:59:54 +0200 Subject: [PATCH 0574/3224] Change TeleoprtEntity to Teleport --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 8e26fb33..b786afa7 100644 --- a/client/main.lua +++ b/client/main.lua @@ -243,7 +243,7 @@ function TeleportFadeEffect(entity, coords) Citizen.Wait(0) end - ESX.Game.TeleportEntity(entity, coords, function() + ESX.Game.Teleport(entity, coords, function() DoScreenFadeIn(800) end) From e6212deddcfbbb119a33f084408355d92fc45d99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 23 Aug 2017 18:07:55 +0200 Subject: [PATCH 0575/3224] Increase radius for billing --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index b9ccdecb..5f151ab4 100644 --- a/client/main.lua +++ b/client/main.lua @@ -82,7 +82,7 @@ function OpenBankActionsMenu() local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if closestPlayer == -1 or closestDistance > 3.0 then + if closestPlayer == -1 or closestDistance > 5.0 then ESX.ShowNotification(_U('no_player_nearby')) else TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_banker', 'Banque', amount) From 9226d33a5645bf8980422741a491c49922571255 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Wed, 23 Aug 2017 14:52:31 -0400 Subject: [PATCH 0576/3224] Update multi-language support --- locales/en.lua | 2 +- locales/fr.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/en.lua b/locales/en.lua index 4cdf1dba..48d62100 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -6,7 +6,7 @@ Locales['en'] = { ['yes'] = 'yes', ['no'] = 'no', ['shop_menu'] = 'press ~INPUT_CONTEXT~ to access the menu', - ['vehicle_purchase'] = 'you bought a vehicle', + ['vehicle_purchased'] = 'you bought a vehicle', ['broke_company'] = 'you do not have enough money in the company account', ['not_enough_money'] = 'you do not have enough money', ['pop_vehicle'] = 'exit vehicle', diff --git a/locales/fr.lua b/locales/fr.lua index c17c077f..55c7fd8c 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -6,7 +6,7 @@ Locales['fr'] = { ['yes'] = 'Oui', ['no'] = 'Non', ['shop_menu'] = 'Appuez sur ~INPUT_CONTEXT~ pour accéder au menu', - ['vehicle_purchase'] = 'Vous avez acheté un véhicule', + ['vehicle_purchased'] = 'Vous avez acheté un véhicule', ['broke_company'] = 'Vous n\'avez pas assez d\'argent sur votre compte société', ['not_enough_money'] = 'Vous n\'avez pas assez d\'argent', ['pop_vehicle'] = 'Sortir véhicule', From e48388ced32ce0293614843e62ae6ed437cc9185 Mon Sep 17 00:00:00 2001 From: Don <30905704+ddh3@users.noreply.github.com> Date: Wed, 23 Aug 2017 12:17:41 -0700 Subject: [PATCH 0577/3224] Fixed spelling error farbic to fabric line 93 --- jobs/textil.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jobs/textil.lua b/jobs/textil.lua index ec19e3a1..2c26b81e 100644 --- a/jobs/textil.lua +++ b/jobs/textil.lua @@ -90,7 +90,7 @@ Config.Jobs.textil = { max = 40, add = 1, remove = 2, - requires = "farbric", + requires = "fabric", requires_name = _U('dd_fabric'), drop = 100 } From 0534ab38bc5200ab733fd6232fe7478052c7d239 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Wed, 23 Aug 2017 20:04:34 -0400 Subject: [PATCH 0578/3224] Update English UI --- html/scripts/app_en.js | 2 +- html/ui_en.html | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/html/scripts/app_en.js b/html/scripts/app_en.js index cd4ef5c2..3b91ca33 100644 --- a/html/scripts/app_en.js +++ b/html/scripts/app_en.js @@ -293,7 +293,7 @@ $('.phone-icon').unbind('click'); $('#phone .menu .home').html( - '
  • Home
  • ' + + '
  • Contacts
  • ' + '
  • Messages
  • ' ); diff --git a/html/ui_en.html b/html/ui_en.html index b5227c83..9aaacf2b 100644 --- a/html/ui_en.html +++ b/html/ui_en.html @@ -17,14 +17,14 @@
    -
    Phone
    +
    Contacts
    From d26a4594251996543371f34207819cbf08acaaec Mon Sep 17 00:00:00 2001 From: Don Date: Wed, 23 Aug 2017 19:25:02 -0700 Subject: [PATCH 0579/3224] sql multilanguage update Credits to: TehBADger --- esx_policejob_en_full.sql | 83 ++++++++++++++++++++++++++++++++++++ esx_policejob_en_minimal.sql | 76 +++++++++++++++++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 esx_policejob_en_full.sql create mode 100644 esx_policejob_en_minimal.sql diff --git a/esx_policejob_en_full.sql b/esx_policejob_en_full.sql new file mode 100644 index 00000000..be26c653 --- /dev/null +++ b/esx_policejob_en_full.sql @@ -0,0 +1,83 @@ +INSERT INTO `addon_account` (name, label, shared) VALUES + ('society_police','Police',1) +; + +INSERT INTO `datastore` (name, label, shared) VALUES + ('society_police','Police',1) +; + +INSERT INTO `jobs` (name, label) VALUES + ('police','LSPD') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('police',0,'recruit','Recrue',20,'{\"tshirt_1\":57,\"torso_1\":55,\"arms\":0,\"pants_1\":35,\"glasses\":0,\"decals_2\":0,\"hair_color_2\":0,\"helmet_2\":0,\"hair_color_1\":5,\"face\":19,\"glasses_2\":1,\"torso_2\":0,\"shoes\":24,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"pants_2\":0,\"hair_2\":0,\"decals_1\":0,\"tshirt_2\":0,\"helmet_1\":8}','{\"tshirt_1\":34,\"torso_1\":48,\"shoes\":24,\"pants_1\":34,\"torso_2\":0,\"decals_2\":0,\"hair_color_2\":0,\"glasses\":0,\"helmet_2\":0,\"hair_2\":3,\"face\":21,\"decals_1\":0,\"glasses_2\":1,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"pants_2\":0,\"arms\":14,\"hair_color_1\":10,\"tshirt_2\":0,\"helmet_1\":57}'), + ('police',1,'sergeant','Sergent',40,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":1,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"arms\":0,\"decals_1\":8,\"torso_2\":0,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"hair_color_1\":5,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":14,\"pants_1\":34,\"pants_2\":0,\"decals_2\":1,\"hair_color_2\":0,\"shoes\":24,\"helmet_2\":0,\"hair_2\":3,\"decals_1\":7,\"torso_2\":0,\"face\":21,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"glasses_2\":1,\"hair_color_1\":10,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}'), + ('police',2,'lieutenant','Lieutenant',65,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":2,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"glasses\":0,\"decals_1\":8,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"torso_2\":0,\"arms\":41,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"hair_2\":3,\"decals_2\":2,\"hair_color_2\":0,\"hair_color_1\":10,\"helmet_2\":0,\"face\":21,\"shoes\":24,\"torso_2\":0,\"glasses_2\":1,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"pants_2\":0,\"decals_1\":7,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}'), + ('police',3,'boss','Commandant',80,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"arms\":41,\"torso_2\":0,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"decals_1\":8,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":21,\"helmet_2\":0,\"hair_2\":3,\"decals_1\":7,\"torso_2\":0,\"hair_color_1\":10,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"glasses_2\":1,\"shoes\":24,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}') +; + +CREATE TABLE `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`) +); + +INSERT INTO `fine_types` (label, amount, category) VALUES + ('Misuse of a horn', 30, 0), + ('Illegally Crossing a continuous Line', 40, 0), + ('Driving on the wrong side of the road', 250, 0), + ('Illegal U-Turn', 250, 0), + ('Illegally Driving Off-road', 170, 0), + ('Refusing a Lawful Command', 30, 0), + ('Illegally Stoped of a Vehicle', 150, 0), + ('Illegal Parking', 70, 0), + ('Failing to Yield to the right', 70, 0), + ('Failure to comply with Vehicle Information', 90, 0), + ('Failing to stop at a Stop Sign ', 105, 0), + ('Failing to stop at a Red Light', 130, 0), + ('Illegal Passing', 100, 0), + ('Driving an illegal Vehicle', 100, 0), + ('Driving without a License', 1500, 0), + ('Hit and Run', 800, 0), + ('Exceeding Speeds Over < 5 mph', 90, 0), + ('Exceeding Speeds Over 5-15 mph', 120, 0), + ('Exceeding Speeds Over 15-30 mph', 180, 0), + ('Exceeding Speeds Over > 30 mph', 300, 0), + ('Impeding traffic flow', 110, 1), + ('Public Intoxication', 90, 1), + ('Disorderly conduct', 90, 1), + ('Obstruction of Justice', 130, 1), + ('Insults towards Civilans', 75, 1), + ('Disrespecting of an LEO', 110, 1), + ('Verbal Threat towards a Civilan', 90, 1), + ('Verbal Threat towards an LEO', 150, 1), + ('Providing False Information', 250, 1), + ('Attempt of Corruption', 1500, 1), + ('Brandishing a weapon in city Limits', 120, 2), + ('Brandishing a Lethal Weapon in city Limits', 300, 2), + ('No Firearms License', 600, 2), + ('Possession of an Illegal Weapon', 700, 2), + ('Possession of Burglary Tools', 300, 2), + ('Grand Theft Auto', 1800, 2), + ('Intent to Sell/Distrube of an illegal Substance', 1500, 2), + ('Frabrication of an Illegal Substance', 1500, 2), + ('Possession of an Illegal Substance ', 650, 2), + ('Kidnapping of a Civilan', 1500, 2), + ('Kidnapping of an LEO', 2000, 2), + ('Robbery', 650, 2), + ('Armed Robbery of a Store', 650, 2), + ('Armed Robbery of a Bank', 1500, 2), + ('Assault on a Civilian', 2000, 3), + ('Assault of an LEO', 2500, 3), + ('Attempt of Murder of a Civilian', 3000, 3), + ('Attempt of Murder of an LEO', 5000, 3), + ('Murder of a Civilian', 10000, 3), + ('Murder of an LEO', 30000, 3), + ('Involuntary manslaughter', 1800, 3), + ('Fraud', 2000, 2); +; \ No newline at end of file diff --git a/esx_policejob_en_minimal.sql b/esx_policejob_en_minimal.sql new file mode 100644 index 00000000..35fd99df --- /dev/null +++ b/esx_policejob_en_minimal.sql @@ -0,0 +1,76 @@ +INSERT INTO `jobs` (name, label) VALUES + ('police','LSPD') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('police',0,'recruit','Recrue',20,'{\"tshirt_1\":57,\"torso_1\":55,\"arms\":0,\"pants_1\":35,\"glasses\":0,\"decals_2\":0,\"hair_color_2\":0,\"helmet_2\":0,\"hair_color_1\":5,\"face\":19,\"glasses_2\":1,\"torso_2\":0,\"shoes\":24,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"pants_2\":0,\"hair_2\":0,\"decals_1\":0,\"tshirt_2\":0,\"helmet_1\":8}','{\"tshirt_1\":34,\"torso_1\":48,\"shoes\":24,\"pants_1\":34,\"torso_2\":0,\"decals_2\":0,\"hair_color_2\":0,\"glasses\":0,\"helmet_2\":0,\"hair_2\":3,\"face\":21,\"decals_1\":0,\"glasses_2\":1,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"pants_2\":0,\"arms\":14,\"hair_color_1\":10,\"tshirt_2\":0,\"helmet_1\":57}'), + ('police',1,'sergeant','Sergent',40,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":1,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"arms\":0,\"decals_1\":8,\"torso_2\":0,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"hair_color_1\":5,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":14,\"pants_1\":34,\"pants_2\":0,\"decals_2\":1,\"hair_color_2\":0,\"shoes\":24,\"helmet_2\":0,\"hair_2\":3,\"decals_1\":7,\"torso_2\":0,\"face\":21,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"glasses_2\":1,\"hair_color_1\":10,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}'), + ('police',2,'lieutenant','Lieutenant',65,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":2,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"glasses\":0,\"decals_1\":8,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"torso_2\":0,\"arms\":41,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"hair_2\":3,\"decals_2\":2,\"hair_color_2\":0,\"hair_color_1\":10,\"helmet_2\":0,\"face\":21,\"shoes\":24,\"torso_2\":0,\"glasses_2\":1,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"pants_2\":0,\"decals_1\":7,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}'), + ('police',3,'boss','Commandant',80,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"arms\":41,\"torso_2\":0,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"decals_1\":8,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":21,\"helmet_2\":0,\"hair_2\":3,\"decals_1\":7,\"torso_2\":0,\"hair_color_1\":10,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"glasses_2\":1,\"shoes\":24,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}') +; + +CREATE TABLE `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`) +); + + +INSERT INTO `fine_types` (label, amount, category) VALUES + ('Misuse of a horn', 30, 0), + ('Illegally Crossing a continuous Line', 40, 0), + ('Driving on the wrong side of the road', 250, 0), + ('Illegal U-Turn', 250, 0), + ('Illegally Driving Off-road', 170, 0), + ('Refusing a Lawful Command', 30, 0), + ('Illegally Stoped of a Vehicle', 150, 0), + ('Illegal Parking', 70, 0), + ('Failing to Yield to the right', 70, 0), + ('Failure to comply with Vehicle Information', 90, 0), + ('Failing to stop at a Stop Sign ', 105, 0), + ('Failing to stop at a Red Light', 130, 0), + ('Illegal Passing', 100, 0), + ('Driving an illegal Vehicle', 100, 0), + ('Driving without a License', 1500, 0), + ('Hit and Run', 800, 0), + ('Exceeding Speeds Over < 5 mph', 90, 0), + ('Exceeding Speeds Over 5-15 mph', 120, 0), + ('Exceeding Speeds Over 15-30 mph', 180, 0), + ('Exceeding Speeds Over > 30 mph', 300, 0), + ('Impeding traffic flow', 110, 1), + ('Public Intoxication', 90, 1), + ('Disorderly conduct', 90, 1), + ('Obstruction of Justice', 130, 1), + ('Insults towards Civilans', 75, 1), + ('Disrespecting of an LEO', 110, 1), + ('Verbal Threat towards a Civilan', 90, 1), + ('Verbal Threat towards an LEO', 150, 1), + ('Providing False Information', 250, 1), + ('Attempt of Corruption', 1500, 1), + ('Brandishing a weapon in city Limits', 120, 2), + ('Brandishing a Lethal Weapon in city Limits', 300, 2), + ('No Firearms License', 600, 2), + ('Possession of an Illegal Weapon', 700, 2), + ('Possession of Burglary Tools', 300, 2), + ('Grand Theft Auto', 1800, 2), + ('Intent to Sell/Distrube of an illegal Substance', 1500, 2), + ('Frabrication of an Illegal Substance', 1500, 2), + ('Possession of an Illegal Substance ', 650, 2), + ('Kidnapping of a Civilan', 1500, 2), + ('Kidnapping of an LEO', 2000, 2), + ('Robbery', 650, 2), + ('Armed Robbery of a Store', 650, 2), + ('Armed Robbery of a Bank', 1500, 2), + ('Assault on a Civilian', 2000, 3), + ('Assault of an LEO', 2500, 3), + ('Attempt of Murder of a Civilian', 3000, 3), + ('Attempt of Murder of an LEO', 5000, 3), + ('Murder of a Civilian', 10000, 3), + ('Murder of an LEO', 30000, 3), + ('Involuntary manslaughter', 1800, 3), + ('Fraud', 2000, 2); +; \ No newline at end of file From 26110d3dd1e9ea9a42fc59b588a09e0807c252eb Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Wed, 23 Aug 2017 22:58:59 -0400 Subject: [PATCH 0580/3224] Add Job Whitelist Credits "Jager Bom" --- server/esx_joblisting_sv.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/esx_joblisting_sv.lua b/server/esx_joblisting_sv.lua index 79533e40..af73d047 100644 --- a/server/esx_joblisting_sv.lua +++ b/server/esx_joblisting_sv.lua @@ -3,7 +3,7 @@ TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) ESX.RegisterServerCallback('esx_joblisting:getJobsList', function(source, cb) MySQL.Async.fetchAll( - 'SELECT * FROM jobs', + 'SELECT * FROM jobs WHERE whitelisted = false', {}, function(result) local data = {} From 4f0fe5d6faaf3d91506786734bb82c694fac1daa Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Wed, 23 Aug 2017 22:59:22 -0400 Subject: [PATCH 0581/3224] Add Job Whitelist Credits "Jager Bom" --- de_esx_jobs.sql | 2 ++ esx_jobs.sql | 2 ++ 2 files changed, 4 insertions(+) diff --git a/de_esx_jobs.sql b/de_esx_jobs.sql index 6b099cc5..5796899c 100644 --- a/de_esx_jobs.sql +++ b/de_esx_jobs.sql @@ -14,6 +14,8 @@ INSERT INTO `jobs` (name, label) VALUES ('textil', 'Schneiderei') ; +ALTER TABLE jobs ADD whitelisted BOOLEAN NOT NULL DEFAULT FALSE; + INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES ('lumberjack', 0, 'interim', 'Mitarbeiter', 0, '{}', '{}'), ('fisherman', 0, 'interim', 'Mitarbeiter', 0, '{}', '{}'), diff --git a/esx_jobs.sql b/esx_jobs.sql index fb356df6..981f118b 100644 --- a/esx_jobs.sql +++ b/esx_jobs.sql @@ -14,6 +14,8 @@ INSERT INTO `jobs` (name, label) VALUES ('textil', 'Couturier') ; +ALTER TABLE jobs ADD whitelisted BOOLEAN NOT NULL DEFAULT FALSE; + INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES ('lumberjack', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), ('fisherman', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), From 3549c6d7e4f305f636aa33594de6c50514b3cfa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 24 Aug 2017 09:15:13 +0200 Subject: [PATCH 0582/3224] Fix wrong variable name --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 5a57ff0e..e27fdcae 100644 --- a/client/main.lua +++ b/client/main.lua @@ -293,7 +293,7 @@ function OpenCustomersMenu() cols = { customers[i].name, customers[i].propertyName, - (customers[i].rented and _U('rent') or _U('sell')), + (customers[i].propertyRented and _U('rent') or _U('sell')), _U('contract') } }) From c51909fed7bb9ef03320c0235bc77de758bf7143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 24 Aug 2017 10:06:47 +0200 Subject: [PATCH 0583/3224] Fix marker positions --- config.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config.lua b/config.lua index 8fbe526e..43d7bbed 100644 --- a/config.lua +++ b/config.lua @@ -31,9 +31,9 @@ Config.Zones = { {x = -2968.243, y = 390.910, z = 14.043}, {x = 1166.024, y = 2708.930, z = 37.157}, {x = 1392.562, y = 3604.684, z = 33.980}, - {x = 127.830, y = -1284.796, z = 29.280}, --StripClub - {x = -1393.409, y = -606.624, z = 30.319}, --Tequila la - {x = -559.906, y = 287.093, z = 82.176} --Bahamamas + {x = 127.830, y = -1284.796, z = 28.280}, --StripClub + {x = -1393.409, y = -606.624, z = 29.319}, --Tequila la + {x = -559.906, y = 287.093, z = 81.176} --Bahamamas } }, From fe140eec0f0f3d55a424aeec614ffebdd24efe4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 24 Aug 2017 12:05:13 +0200 Subject: [PATCH 0584/3224] Callback even on empty queue --- async.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/async.lua b/async.lua index 3c7ab7c8..5420a306 100644 --- a/async.lua +++ b/async.lua @@ -45,6 +45,7 @@ function Async.parallelLimit(tasks, limit, cb) local function processQueue() if #queue == 0 then + cb(results) return end From caf09a649af7687ec4d6cb028e08325af62eeaea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 24 Aug 2017 12:40:07 +0200 Subject: [PATCH 0585/3224] Add missing manifest version - Fix spawn objects --- __resource.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/__resource.lua b/__resource.lua index 734f0377..403d0d09 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,3 +1,5 @@ +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' + description 'ESX Mecano Job' client_scripts { From 70a48ffe0b72bbb7828380d27fc9c3872f7dd7cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 24 Aug 2017 12:50:14 +0200 Subject: [PATCH 0586/3224] Fix prop_toolchest_01 z pos --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 000797c4..7a7c1809 100644 --- a/client/main.lua +++ b/client/main.lua @@ -504,7 +504,7 @@ function OpenMobileMecanoActionsMenu() if model == 'prop_roadcone02a' then z = z - 2.0 elseif model == 'prop_toolchest_01' then - z = z - 3.0 + z = z - 2.0 end ESX.Game.SpawnObject(model, { From 12cbc52ab9e2dd732cd44c8a57cdf3f4377b74cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 24 Aug 2017 15:28:44 +0200 Subject: [PATCH 0587/3224] Now use entityiter.lua --- .../[essential]/es_extended/__resource.lua | 1 + .../es_extended/client/entityiter.lua | 79 +++++++++++++++++++ .../es_extended/client/functions.lua | 34 ++++---- 3 files changed, 98 insertions(+), 16 deletions(-) create mode 100644 resources/[essential]/es_extended/client/entityiter.lua diff --git a/resources/[essential]/es_extended/__resource.lua b/resources/[essential]/es_extended/__resource.lua index 396a1e69..26eb01ef 100644 --- a/resources/[essential]/es_extended/__resource.lua +++ b/resources/[essential]/es_extended/__resource.lua @@ -26,6 +26,7 @@ client_scripts { 'locales/en.lua', 'config.weapons.lua', 'client/common.lua', + 'client/entityiter.lua', 'client/functions.lua', 'client/main.lua' } diff --git a/resources/[essential]/es_extended/client/entityiter.lua b/resources/[essential]/es_extended/client/entityiter.lua new file mode 100644 index 00000000..71e9ee23 --- /dev/null +++ b/resources/[essential]/es_extended/client/entityiter.lua @@ -0,0 +1,79 @@ +--[[The MIT License (MIT) + +Copyright (c) 2017 IllidanS4 + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. +]] + +local entityEnumerator = { + __gc = function(enum) + if enum.destructor and enum.handle then + enum.destructor(enum.handle) + end + enum.destructor = nil + enum.handle = nil + end +} + +local function EnumerateEntities(initFunc, moveFunc, disposeFunc) + return coroutine.wrap(function() + local iter, id = initFunc() + if not id or id == 0 then + disposeFunc(iter) + return + end + + local enum = {handle = iter, destructor = disposeFunc} + setmetatable(enum, entityEnumerator) + + local next = true + repeat + coroutine.yield(id) + next, id = moveFunc(iter) + until not next + + enum.destructor, enum.handle = nil, nil + disposeFunc(iter) + end) +end + +function EnumerateObjects() + return EnumerateEntities(FindFirstObject, FindNextObject, EndFindObject) +end + +function EnumeratePeds() + return EnumerateEntities(FindFirstPed, FindNextPed, EndFindPed) +end + +function EnumerateVehicles() + return EnumerateEntities(FindFirstVehicle, FindNextVehicle, EndFindVehicle) +end + +function EnumeratePickups() + return EnumerateEntities(FindFirstPickup, FindNextPickup, EndFindPickup) +end + +--[[Usage: +for ped in EnumeratePeds() do + +end +]] \ No newline at end of file diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 24b68c95..0ef5872f 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -409,16 +409,11 @@ end ESX.Game.GetObjects = function() - local objects = {} - local handle, object = FindFirstObject() - local success = nil + local objects = {} - repeat + for object in EnumerateObjects() do table.insert(objects, object) - success, object = FindNextObject(handle) - until not success - - EndFindObject(handle) + end return objects @@ -555,16 +550,11 @@ end ESX.Game.GetVehicles = function() - local vehicles = {} - local handle, vehicle = FindFirstVehicle() - local success = nil + local vehicles = {} - repeat + for vehicle in EnumerateVehicles() do table.insert(vehicles, vehicle) - success, vehicle = FindNextVehicle(handle) - until not success - - EndFindVehicle(handle) + end return vehicles @@ -617,6 +607,18 @@ ESX.Game.GetVehiclesInArea = function(coords, area) return vehiclesInArea end +ESX.Game.GetPeds = function() + + local peds = {} + + for ped in EnumeratePeds() do + table.insert(peds, ped) + end + + return peds + +end + ESX.Game.GetVehicleProperties = function(vehicle) local color1, color2 = GetVehicleColours(vehicle) From 3afa53f394dcd200fc6ce5d25422796d37d3cbd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 24 Aug 2017 15:29:34 +0200 Subject: [PATCH 0588/3224] Fix taxi crashes NEED es_extended UPDATE --- client/main.lua | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/client/main.lua b/client/main.lua index 239bac8b..062788be 100644 --- a/client/main.lua +++ b/client/main.lua @@ -53,21 +53,19 @@ function ShowLoadingPromt(msg, time, type) end) end -function GetRandomPed() +function GetRandomWalkingNPC() - local peds = {} - local handle, ped = FindFirstPed() - local success = nil + local search = {} + local peds = ESX.Game.GetPeds() - repeat - table.insert(peds, ped) - success, ped = FindNextPed(handle) - until not success + for i=1, #peds, 1 do + if IsPedHuman(peds[i]) and IsPedWalking(peds[i]) and not IsPedAPlayer(peds[i]) then + table.insert(search, peds[i]) + end + end - EndFindPed(handle) - - if #peds > 0 then - return peds[GetRandomIntInRange(1, #peds)] + if #search > 0 then + return search[GetRandomIntInRange(1, #search)] end end @@ -480,17 +478,9 @@ Citizen.CreateThread(function() if OnJob and IsPedInAnyVehicle(playerPed, false) and GetEntitySpeed(playerPed) > 0 then - while CurrentCustomer == nil do + CurrentCustomer = GetRandomWalkingNPC() - local ped = GetRandomPed() - - if DoesEntityExist(ped) and IsPedHuman(ped) and IsPedWalking(ped) and not IsPedAPlayer(ped) then - CurrentCustomer = ped - end - - end - - if DoesEntityExist(CurrentCustomer) and IsEntityAPed(CurrentCustomer) then + if CurrentCustomer ~= nil then CurrentCustomerBlip = AddBlipForEntity(CurrentCustomer) @@ -509,8 +499,6 @@ Citizen.CreateThread(function() ESX.ShowNotification(_U('customer_found')) - else - CurrentCustomer = nil end end From dc42a6378b1f9627f06fc592fb649c67a9a727f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 24 Aug 2017 16:53:53 +0200 Subject: [PATCH 0589/3224] Fix DeathFailOut effect + remove debug code --- client/main.lua | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/client/main.lua b/client/main.lua index b786afa7..e5ca39a2 100644 --- a/client/main.lua +++ b/client/main.lua @@ -44,11 +44,9 @@ function RespawnPed(ped, coords) end function StartRespawnToHospitalMenuTimer() - Citizen.Trace('player IsDead') ESX.SetTimeout(Config.MenuRespawnToHospitalDelay, function() - Citizen.Trace('timer started') if IsDead then local elements = {} @@ -127,10 +125,10 @@ end function RespawnTimer() -local timer = Config.RespawnDelayAfterRPDeath -local allowRespawn = Config.RespawnDelayAfterRPDeath/2 -local enoughMoney = false -local money = 0 + local timer = Config.RespawnDelayAfterRPDeath + local allowRespawn = Config.RespawnDelayAfterRPDeath/2 + local enoughMoney = false + local money = 0 if IsDead and Config.ShowDeathTimer then ESX.TriggerServerCallback('esx_ambulancejob:getBankMoney', function(money) @@ -635,19 +633,18 @@ AddEventHandler('baseevents:onPlayerKilled', function(killerId, data) end) AddEventHandler('esx_ambulancejob:onPlayerDeath', function() - Citizen.Trace('player died') + IsDead = true if Config.ShowDeathTimer == true then - Citizen.Trace('player died: true') RespawnTimer() else - Citizen.Trace('player died: false') StartRespawnTimer() StartRespawnToHospitalMenuTimer() - StartScreenEffect('DeathFailOut', 0, false) end + StartScreenEffect('DeathFailOut', 0, false) + end) RegisterNetEvent('esx_ambulancejob:revive') From 5765a030c732f34b035050e6bda9ded6040aa5a0 Mon Sep 17 00:00:00 2001 From: nearbyplayer <3721216+nearbyplayer@users.noreply.github.com> Date: Thu, 24 Aug 2017 12:36:39 -0400 Subject: [PATCH 0590/3224] Update main.lua --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index e5ca39a2..a2372e0c 100644 --- a/client/main.lua +++ b/client/main.lua @@ -222,7 +222,7 @@ function RespawnTimer() TriggerServerEvent('esx:updateLastPosition', Config.Zones.HospitalInteriorInside1.Pos) RespawnPed(GetPlayerPed(-1), Config.Zones.HospitalInteriorInside1.Pos) - --StopScreenEffect('DeathFailOut') + StopScreenEffect('DeathFailOut') DoScreenFadeIn(800) end) end From c1f58d7b6416a34d01b7c5899e9ff4a6f4f7c869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 24 Aug 2017 20:15:44 +0200 Subject: [PATCH 0591/3224] Fix nil value bugs --- .../es_extended/client/functions.lua | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 0ef5872f..4d2f4541 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -222,8 +222,10 @@ end ESX.UI.Menu.CloseAll = function() for i=1, #ESX.UI.Menu.Opened, 1 do - ESX.UI.Menu.Opened[i].close() - ESX.UI.Menu.Opened[i] = nil + if ESX.UI.Menu.Opened[i] ~= nil then + ESX.UI.Menu.Opened[i].close() + ESX.UI.Menu.Opened[i] = nil + end end end @@ -231,8 +233,10 @@ end ESX.UI.Menu.GetOpened = function(type, namespace, name) for i=1, #ESX.UI.Menu.Opened, 1 do - if ESX.UI.Menu.Opened[i].type == type and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then - return ESX.UI.Menu.Opened[i] + if ESX.UI.Menu.Opened[i] ~= nil then + if ESX.UI.Menu.Opened[i].type == type and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then + return ESX.UI.Menu.Opened[i] + end end end @@ -1215,9 +1219,13 @@ Citizen.CreateThread(function() for i=1, #ESX.TimeoutCallbacks, 1 do - if currTime >= ESX.TimeoutCallbacks[i].time then - ESX.TimeoutCallbacks[i].cb() - ESX.TimeoutCallbacks[i] = nil + if ESX.TimeoutCallbacks[i] ~= nil then + + if currTime >= ESX.TimeoutCallbacks[i].time then + ESX.TimeoutCallbacks[i].cb() + ESX.TimeoutCallbacks[i] = nil + end + end end From b172cd630a23b164fbd002773c6cb38f02b2ccf9 Mon Sep 17 00:00:00 2001 From: Don <30905704+ddh3@users.noreply.github.com> Date: Thu, 24 Aug 2017 21:13:31 -0700 Subject: [PATCH 0592/3224] added sql command to readme --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 64d5b689..8f8403dc 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,6 @@ # fxserver-esx_joblisting -FR - Pôle Emploi \ No newline at end of file +FR - Pôle Emploi + +Update SQL database for job whitelist: + +ALTER TABLE jobs add whitelist BOOLEAN NOT NULL DEFAULT FALSE; From 2164ffdec3e26174b048e084ad922636085bac26 Mon Sep 17 00:00:00 2001 From: Don <30905704+ddh3@users.noreply.github.com> Date: Thu, 24 Aug 2017 21:35:30 -0700 Subject: [PATCH 0593/3224] added sql command to readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8f8403dc..c2e84113 100644 --- a/README.md +++ b/README.md @@ -3,4 +3,4 @@ FR - Pôle Emploi Update SQL database for job whitelist: -ALTER TABLE jobs add whitelist BOOLEAN NOT NULL DEFAULT FALSE; +ALTER TABLE jobs add whitelisted BOOLEAN NOT NULL DEFAULT FALSE; From 2795a1985fc5a0781ec464db25b072ee10572cb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 25 Aug 2017 09:35:42 +0200 Subject: [PATCH 0594/3224] Load Slautherer and textil IPLs --- client/esx_jobs_cl.lua | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/client/esx_jobs_cl.lua b/client/esx_jobs_cl.lua index 651aec84..db973daf 100644 --- a/client/esx_jobs_cl.lua +++ b/client/esx_jobs_cl.lua @@ -571,3 +571,18 @@ Citizen.CreateThread(function() end end end) + +Citizen.CreateThread(function() + + -- Slaughterer + RemoveIpl("CS1_02_cf_offmission") + RequestIpl("CS1_02_cf_onmission1") + RequestIpl("CS1_02_cf_onmission2") + RequestIpl("CS1_02_cf_onmission3") + RequestIpl("CS1_02_cf_onmission4") + + -- Textil + RequestIpl("id2_14_during_door") + RequestIpl("id2_14_during1") + +end) \ No newline at end of file From 7b6f83583117c6d725aae1bbdc2d0290a392df74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 25 Aug 2017 10:24:42 +0200 Subject: [PATCH 0595/3224] Add slaughterer and textil skins --- esx_jobs.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esx_jobs.sql b/esx_jobs.sql index 981f118b..f07bbb1f 100644 --- a/esx_jobs.sql +++ b/esx_jobs.sql @@ -21,9 +21,9 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_ ('fisherman', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), ('fuel', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), ('reporter', 0, 'employee', 'Intérimaire', 0, '{}', '{}'), - ('textil', 0, 'interim', 'Intérimaire', 0, '{}', '{}'), + ('textil',0,'interim','Intérimaire',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}'), ('miner', 0, 'interim', 'Intérimaire', 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}', '{}'), - ('slaughterer', 0, 'interim', 'Intérimaire', 0, '{}', '{}') + ('slaughterer',0,'interim','Intérimaire',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}') ; INSERT INTO `items` (`name`, `label`) VALUES From 0f32bbcf9c040d583ded50d695a5f9826433a5a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 25 Aug 2017 10:44:57 +0200 Subject: [PATCH 0596/3224] Add ESX.ClearTimeout --- resources/[essential]/es_extended/client/functions.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 4d2f4541..f2394e18 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -38,6 +38,11 @@ ESX.SetTimeout = function(msec, cb) time = GetGameTimer() + msec, cb = cb }) + return #ESX.TimeoutCallbacks +end + +ESX.ClearTimeout = function(i) + ESX.TimeoutCallbacks[i] = nil end ESX.ShowNotification = function(msg) From 859cfd60b136a3c3803885d3f52088740ec2df44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 25 Aug 2017 10:45:56 +0200 Subject: [PATCH 0597/3224] Add ClearTimeout - NEED ESX UPDATE --- client/main.lua | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index 6b4e3e7f..f9d25d80 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,4 +1,5 @@ -ESX = nil +ESX = nil +local Timeouts = {} Citizen.CreateThread(function() @@ -26,6 +27,10 @@ Citizen.CreateThread(function() local openMenu = function(namespace, name, data) + for i=1, #Timeouts, 1 do + ESX.ClearTimeout(Timeouts[i]) + end + OpenedMenus[namespace .. '_' .. name] = true SendNUIMessage({ @@ -35,10 +40,12 @@ Citizen.CreateThread(function() data = data, }) - ESX.SetTimeout(200, function() + local timeoutId = ESX.SetTimeout(200, function() SetNuiFocus(true, true) end) + table.insert(Timeouts, timeoutId) + end local closeMenu = function(namespace, name) From 70a796e583506d0f34a691148de970e90c9eb290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 25 Aug 2017 10:52:14 +0200 Subject: [PATCH 0598/3224] Add ESX.UI.Menu.CloseAll --- client/main.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/client/main.lua b/client/main.lua index d8bebf5d..b37eeb9a 100644 --- a/client/main.lua +++ b/client/main.lua @@ -999,6 +999,7 @@ AddEventHandler('esx_policejob:hasEnteredMarker', function(station, part, partNu end) AddEventHandler('esx_policejob:hasExitedMarker', function(station, part, partNum) + ESX.UI.Menu.CloseAll() CurrentAction = nil end) From a86520b12949afdb1ba0b59b9066c2b5b90de8f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 25 Aug 2017 10:58:14 +0200 Subject: [PATCH 0599/3224] Fix wrong var name (typo) --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 0b614c15..30bb4c13 100644 --- a/client/main.lua +++ b/client/main.lua @@ -63,7 +63,7 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) local spawn = function(j) - local vehicle = GetClosestVehicle(garage.Parkings[i].Pos.x, garage.Parkings[i].Pos.garage.Parkings[i].Pos.y, garage.Parkings[i].Pos.z, 2.0, 0, 71) + local vehicle = GetClosestVehicle(garage.Parkings[i].Pos.x, garage.Parkings[i].Pos.y, garage.Parkings[i].Pos.z, 2.0, 0, 71) if DoesEntityExist(vehicle) then ESX.Game.DeleteVehicle(vehicle) From fe5b7ba8969bffd46d8f20a4930ec5f951f76b41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 25 Aug 2017 12:42:09 +0200 Subject: [PATCH 0600/3224] Show only job blips + Remove NUI Stuff --- client/esx_jobs_cl.lua | 60 +++++++++++++++--------------------------- 1 file changed, 21 insertions(+), 39 deletions(-) diff --git a/client/esx_jobs_cl.lua b/client/esx_jobs_cl.lua index db973daf..7f65f096 100644 --- a/client/esx_jobs_cl.lua +++ b/client/esx_jobs_cl.lua @@ -232,10 +232,6 @@ AddEventHandler('esx_jobs:hasExitedMarker', function(zone) menuIsShowed = false hintIsShowed = false isInMarker = false - SendNUIMessage({ - showControls = false, - showMenu = false, - }) end) RegisterNetEvent('esx:setJob') @@ -245,15 +241,15 @@ AddEventHandler('esx:setJob', function(job) myPlate = {} -- loosing vehicle caution in case player changes job. isJobVehicleDestroyed = false spawner = 0 - --deleteBlips() - --refreshBlips() + deleteBlips() + refreshBlips() end) function deleteBlips() if JobBlips[1] ~= nil then for i=1, #JobBlips, 1 do RemoveBlip(JobBlips[i]) - table.remove(JobBlips, i) + JobBlips[i] = nil end end end @@ -261,24 +257,30 @@ end function refreshBlips() local zones = {} local blipInfo = {} + if PlayerData.job ~= nil then for jobKey,jobValues in pairs(Config.Jobs) do - for zoneKey,zoneValues in pairs(jobValues.Zones) do - if zoneValues.Blip then - local blip = AddBlipForCoord(zoneValues.Pos.x, zoneValues.Pos.y, zoneValues.Pos.z) - SetBlipSprite (blip, jobValues.BlipInfos.Sprite) - SetBlipDisplay(blip, 4) - SetBlipScale (blip, 1.2) - SetBlipColour (blip, jobValues.BlipInfos.Color) - SetBlipAsShortRange(blip, true) - BeginTextCommandSetBlipName("STRING") - AddTextComponentString(zoneValues.Name) - EndTextCommandSetBlipName(blip) - table.insert(JobBlips, blip) + + if jobKey == PlayerData.job.name then + for zoneKey,zoneValues in pairs(jobValues.Zones) do + if zoneValues.Blip then + local blip = AddBlipForCoord(zoneValues.Pos.x, zoneValues.Pos.y, zoneValues.Pos.z) + SetBlipSprite (blip, jobValues.BlipInfos.Sprite) + SetBlipDisplay(blip, 4) + SetBlipScale (blip, 1.2) + SetBlipColour (blip, jobValues.BlipInfos.Color) + SetBlipAsShortRange(blip, true) + BeginTextCommandSetBlipName("STRING") + AddTextComponentString(zoneValues.Name) + EndTextCommandSetBlipName(blip) + table.insert(JobBlips, blip) + end end end + end end + end function spawncar(spawnPoint, vehicle) @@ -552,26 +554,6 @@ Citizen.CreateThread(function() end end) --- Menu Controls -Citizen.CreateThread(function() - while true do - Wait(0) - if IsControlJustReleased(0, Keys['ENTER']) or IsControlJustReleased(0, Keys['E']) then - SendNUIMessage({ enterPressed = true }) - elseif IsControlJustReleased(0, Keys['BACKSPACE']) then - SendNUIMessage({ backspacePressed = true }) - elseif IsControlJustReleased(0, Keys['LEFT']) then - SendNUIMessage({ move = 'LEFT' }) - elseif IsControlJustReleased(0, Keys['RIGHT']) then - SendNUIMessage({ move = 'RIGHT' }) - elseif IsControlJustReleased(0, Keys['TOP']) then - SendNUIMessage({ move = 'UP' }) - elseif IsControlJustReleased(0, Keys['DOWN']) then - SendNUIMessage({ move = 'DOWN' }) - end - end -end) - Citizen.CreateThread(function() -- Slaughterer From 74247e1238307f43322b4c1b8969290a1ca4151d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 25 Aug 2017 16:48:20 +0200 Subject: [PATCH 0601/3224] Set LastSkin when saving --- client/main.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/main.lua b/client/main.lua index 57d823cf..2086cc10 100644 --- a/client/main.lua +++ b/client/main.lua @@ -264,6 +264,8 @@ function OpenSaveableMenu(submitCb, cancelCb, restrict) TriggerServerEvent('esx_skin:save', skin) + LastSkin = skin + if submitCb ~= nil then submitCb(data, menu) end From 6c66b7a4e6d68a6581ca36eb8559f297d53d4d93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 25 Aug 2017 17:15:03 +0200 Subject: [PATCH 0602/3224] Set LastSkin when submiting --- client/main.lua | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index 2086cc10..f7d44e38 100644 --- a/client/main.lua +++ b/client/main.lua @@ -94,6 +94,11 @@ function OpenMenu(submitCb, cancelCb, restrict) elements = elements }, function(data, menu) + + TriggerEvent('skinchanger:getSkin', function(skin) + LastSkin = skin + end) + submitCb(data, menu) DeleteSkinCam() end, @@ -264,8 +269,6 @@ function OpenSaveableMenu(submitCb, cancelCb, restrict) TriggerServerEvent('esx_skin:save', skin) - LastSkin = skin - if submitCb ~= nil then submitCb(data, menu) end From 93a8db19a08db44de307aaa380524085e4ff0a30 Mon Sep 17 00:00:00 2001 From: TanguyOrtegat Date: Fri, 25 Aug 2017 18:51:12 +0200 Subject: [PATCH 0603/3224] added opium --- README.md | 12 ++- client/esx_drugs_cl.lua | 58 +++++++++++- config.lua | 22 +++-- esx_drugs.sql | 4 +- locales/br.lua | 7 ++ locales/en.lua | 7 ++ locales/fr.lua | 7 ++ server/esx_drugs_sv.lua | 203 +++++++++++++++++++++++++++++++++++++--- 8 files changed, 293 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 97e88e09..e1873b00 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,17 @@ FXserver ESX Drugs * esx_policejob => https://github.com/FXServer-ESX/fxserver-esx_policejob -[INSTALLATION] + + [UPDATE] + to install opium : +``` +INSERT INTO `items` (name, label) VALUES + ('opium', 'Opium'), + ('opium_pooch', 'Pochon de opium') +; +``` + + [INSTALLATION] 1) CD in your resources/[esx] folder 2) Clone the repository diff --git a/client/esx_drugs_cl.lua b/client/esx_drugs_cl.lua index ae97c58c..9e5b8a7d 100644 --- a/client/esx_drugs_cl.lua +++ b/client/esx_drugs_cl.lua @@ -20,6 +20,8 @@ local weedQTE = 0 local weed_poochQTE = 0 local methQTE = 0 local meth_poochQTE = 0 +local opiumQTE = 0 +local opium_poochQTE = 0 local myJob = nil local PlayerData = {} local GUI = {} @@ -39,7 +41,8 @@ end) AddEventHandler('esx_drugs:hasEnteredMarker', function(zone) ESX.UI.Menu.CloseAll() - + + --coke if zone == 'CokeFarm' then if myJob ~= "police" then CurrentAction = 'coke_harvest' @@ -67,7 +70,8 @@ AddEventHandler('esx_drugs:hasEnteredMarker', function(zone) end end end - + + --meth if zone == 'MethFarm' then if myJob ~= "police" then CurrentAction = 'meth_harvest' @@ -95,7 +99,8 @@ AddEventHandler('esx_drugs:hasEnteredMarker', function(zone) end end end - + + --weed if zone == 'WeedFarm' then if myJob ~= "police" then CurrentAction = 'weed_harvest' @@ -123,6 +128,35 @@ AddEventHandler('esx_drugs:hasEnteredMarker', function(zone) end end end + + --opium + if zone == 'OpiumFarm' then + if myJob ~= "police" then + CurrentAction = 'opium_harvest' + CurrentActionMsg = _U('press_collect_opium') + CurrentActionData = {} + end + end + + if zone == 'OpiumTreatment' then + if myJob ~= "police" then + if opiumQTE >= 5 then + CurrentAction = 'opium_treatment' + CurrentActionMsg = _U('press_process_opium') + CurrentActionData = {} + end + end + end + + if zone == 'OpiumResell' then + if myJob ~= "police" then + if opium_poochQTE >= 1 then + CurrentAction = 'opium_resell' + CurrentActionMsg = _U('press_sell_opium') + CurrentActionData = {} + end + end + end end) AddEventHandler('esx_drugs:hasExitedMarker', function(zone) @@ -139,6 +173,9 @@ AddEventHandler('esx_drugs:hasExitedMarker', function(zone) TriggerServerEvent('esx_drugs:stopHarvestWeed') TriggerServerEvent('esx_drugs:stopTransformWeed') TriggerServerEvent('esx_drugs:stopSellWeed') + TriggerServerEvent('esx_drugs:stopHarvestOpium') + TriggerServerEvent('esx_drugs:stopTransformOpium') + TriggerServerEvent('esx_drugs:stopSellOpium') end) -- Weed Effect @@ -188,13 +225,15 @@ end) -- RETURN NUMBER OF ITEMS FROM SERVER RegisterNetEvent('esx_drugs:ReturnInventory') -AddEventHandler('esx_drugs:ReturnInventory', function(cokeNbr, cokepNbr, methNbr, methpNbr, weedNbr, weedpNbr, jobName, currentZone) +AddEventHandler('esx_drugs:ReturnInventory', function(cokeNbr, cokepNbr, methNbr, methpNbr, weedNbr, weedpNbr,opiumNbr, opiumpNbr, jobName, currentZone) cokeQTE = cokeNbr coke_poochQTE = cokepNbr methQTE = methNbr meth_poochQTE = methpNbr weedQTE = weedNbr - weed_poochQTE = weedpNbr + weed_poochQTE = weedpNbr + opiumQTE = opiumbr + opium_poochQTE = opiumpNbr myJob = jobName TriggerEvent('esx_drugs:hasEnteredMarker', currentZone) end) @@ -266,6 +305,15 @@ Citizen.CreateThread(function() if CurrentAction == 'weed_resell' then TriggerServerEvent('esx_drugs:startSellWeed') end + if CurrentAction == 'opium_harvest' then + TriggerServerEvent('esx_drugs:startHarvestOpium') + end + if CurrentAction == 'opium_treatment' then + TriggerServerEvent('esx_drugs:startTransformOpium') + end + if CurrentAction == 'opium_resell' then + TriggerServerEvent('esx_drugs:startSellOpium') + end CurrentAction = nil end end diff --git a/config.lua b/config.lua index f277af23..7d660cd6 100644 --- a/config.lua +++ b/config.lua @@ -6,16 +6,20 @@ Config.ZoneSize = {x = 5.0, y = 5.0, z = 3.0} Config.RequiredCopsCoke = 2 Config.RequiredCopsMeth = 2 Config.RequiredCopsWeed = 0 +Config.RequiredCopsOpium = 3 Config.Locale = 'fr' Config.Zones = { - CokeFarm = {x=2448.9228515625, y=-1836.8076171875, z=51.953701019287}, - CokeTreatment = {x=-458.13967895508, y=-2278.6174316406, z=7.5158290863037}, - CokeResell = {x=-1756.1984863281, y=427.31674194336, z=126.68292999268}, - MethFarm = {x=1525.298828125, y=1710.0217285156, z=109.00956726074}, - MethTreatment = {x=-1001.4151611328, y=4848.0087890625, z=274.00686645508}, - MethResell = {x=-63.592178344727, y=-1224.0709228516, z=27.768648147583}, - WeedFarm = {x=1609.125, y=6663.5942382813, z=20.961572647095}, - WeedTreatment = {x=91.061386108398, y=3750.0380859375, z=39.77326965332}, - WeedResell = {x=-54.249694824219, y=-1443.3666992188, z=31.068626403809} + CokeFarm = {x=2448.9228515625, y=-1836.8076171875, z=51.953701019287}, + CokeTreatment = {x=-458.13967895508, y=-2278.6174316406, z=7.5158290863037}, + CokeResell = {x=-1756.1984863281, y=427.31674194336, z=126.68292999268}, + MethFarm = {x=1525.298828125, y=1710.0217285156, z=109.00956726074}, + MethTreatment = {x=-1001.4151611328, y=4848.0087890625, z=274.00686645508}, + MethResell = {x=-63.592178344727, y=-1224.0709228516, z=27.768648147583}, + WeedFarm = {x=1609.125, y=6663.5942382813, z=20.961572647095}, + WeedTreatment = {x=91.061386108398, y=3750.0380859375, z=39.77326965332}, + WeedResell = {x=-54.249694824219, y=-1443.3666992188, z=31.068626403809}, + OpiumFarm = {x=1972.784790039, y=3819.3999023438, z=33.428722381592}, + OpiumTreatment = {x=971.86499023438,y=-2157.61328125, z=28.475107192994}, + OpiumResell = {x=2331.0881347656,y=2570.2250976562,z=46.681819915772} } \ No newline at end of file diff --git a/esx_drugs.sql b/esx_drugs.sql index 6cad45ce..17d92a2d 100644 --- a/esx_drugs.sql +++ b/esx_drugs.sql @@ -4,5 +4,7 @@ INSERT INTO `items` (name, label) VALUES ('coke', 'Coke'), ('coke_pooch', 'Pochon de coke'), ('meth', 'Meth'), - ('meth_pooch', 'Pochon de meth') + ('meth_pooch', 'Pochon de meth'), + ('opium', 'Opium'), + ('opium_pooch', 'Pochon de opium') ; \ No newline at end of file diff --git a/locales/br.lua b/locales/br.lua index 23afcbb4..fdad1ed5 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -8,6 +8,9 @@ Locales['br'] = { ['press_sell_meth'] = 'Pressione ~INPUT_CONTEXT~ para vender metanfetamina', ['press_collect_weed'] = 'Pressione ~INPUT_CONTEXT~ para coletar erva', ['press_process_weed'] = 'Pressione ~INPUT_CONTEXT~ para processar erva', + ['press_sell_opium'] = 'Pressione ~INPUT_CONTEXT~ para vender ópio', + ['press_collect_opium'] = 'Pressione ~INPUT_CONTEXT~ para coletar ópio', + ['press_process_opium'] = 'Pressione ~INPUT_CONTEXT~ para processar ópio', ['press_sell_weed'] = 'Pressione ~INPUT_CONTEXT~ para vender erva', ['act_imp_police'] = 'Ação ~r~impossivel~s~, ~b~polícia~s~: ', ['inv_full_coke'] = 'Você não pode mais coletar a Cocaína, seu estoque está ~r~cheio~s~', @@ -25,5 +28,9 @@ Locales['br'] = { ['not_enough_weed'] = 'Você não tem erva suficiente para ~r~embalar~s~', ['sold_one_weed'] = 'Você vendeu ~g~x1 Trouxinha de erva~s~', ['used_one_weed'] = 'Você usou 1 trouxinha de ~b~erva', + ['inv_full_opium'] = 'Você não pode mais coletar ópio, seu inventário está ~r~cheio~s~', + ['not_enough_opium'] = 'Você não tem ópio suficiente para ~r~embalar~s~', + ['sold_one_opium'] = 'Você vendeu ~g~x1 Trouxinha de ópio~s~', + ['used_one_opium'] = 'Você usou 1 trouxinha de ~b~ópio', } \ No newline at end of file diff --git a/locales/en.lua b/locales/en.lua index a3013aaa..3852ef36 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -9,6 +9,9 @@ Locales['en'] = { ['press_collect_weed'] = 'press ~INPUT_CONTEXT~ to collect weed', ['press_process_weed'] = 'press ~INPUT_CONTEXT~ to process weed', ['press_sell_weed'] = 'press ~INPUT_CONTEXT~ to sell weed', + ['press_collect_opium'] = 'press ~INPUT_CONTEXT~ to collect opium', + ['press_process_opium'] = 'press ~INPUT_CONTEXT~ to process opium', + ['press_sell_opium'] = 'press ~INPUT_CONTEXT~ to sell opium', ['act_imp_police'] = 'action ~r~impossible~s~, ~b~police~s~: ', ['inv_full_coke'] = 'you can no longer collect Cocaine, your inventory is ~r~full~s~', ['pickup_in_prog'] = '~y~Pickup in progress~s~...', @@ -25,5 +28,9 @@ Locales['en'] = { ['not_enough_weed'] = 'you do not have enough Weed to ~r~pack~s~', ['sold_one_weed'] = 'you\'ve sold ~g~x1 Weed Pouch~s~', ['used_one_weed'] = 'you used 1 pouch of ~b~weed', + ['inv_full_opium'] = 'you can no longer collect opium, your inventory is ~r~full~s~', + ['not_enough_opium'] = 'you do not have enough opium to ~r~pack~s~', + ['sold_one_opium'] = 'you\'ve sold ~g~x1 opium Pouch~s~', + ['used_one_opium'] = 'you used 1 pouch of ~b~opium', } \ No newline at end of file diff --git a/locales/fr.lua b/locales/fr.lua index eeddacb2..55d455e3 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -9,6 +9,9 @@ Locales['fr'] = { ['press_collect_weed'] = 'appuyez sur ~INPUT_CONTEXT~ pour récolter la weed', ['press_process_weed'] = 'appuyez sur ~INPUT_CONTEXT~ pour traiter la weed', ['press_sell_weed'] = 'appuyez sur ~INPUT_CONTEXT~ pour vendre la weed', + ['press_collect_opium'] = "appuyez sur ~INPUT_CONTEXT~ pour récolter l'opium", + ['press_process_opium'] = "appuyez sur ~INPUT_CONTEXT~ pour traiter l'opium", + ['press_sell_opium'] = "appuyez sur ~INPUT_CONTEXT~ pour vendre l'opium", ['act_imp_police'] = 'action ~r~impossible~s~, ~b~policiers~s~: ', ['inv_full_coke'] = 'vous ne pouvez plus ramasser de Cocaine, votre inventaire est ~r~plein~s~', ['pickup_in_prog'] = '~y~Ramassage en cours~s~...', @@ -25,5 +28,9 @@ Locales['fr'] = { ['not_enough_weed'] = 'vous n\'avez pas assez de weed à ~r~conditionner~s~', ['sold_one_weed'] = 'vous avez vendu ~g~x1 Pochon de weed~s~', ['used_one_weed'] = 'Vous avez utilisé 1 Pochon de ~b~weed', + ['inv_full_opium'] = 'vous ne pouvez plus ramasser de weed, votre inventaire est ~r~plein~s~', + ['not_enough_opium'] = 'vous n\'avez pas assez de opium à ~r~conditionner~s~', + ['sold_one_opium'] = 'vous avez vendu ~g~x1 Pochon de opium~s~', + ['used_one_opium'] = 'Vous avez utilisé 1 Pochon de ~b~opium', } \ No newline at end of file diff --git a/server/esx_drugs_sv.lua b/server/esx_drugs_sv.lua index 970e799b..ba8606aa 100644 --- a/server/esx_drugs_sv.lua +++ b/server/esx_drugs_sv.lua @@ -1,14 +1,17 @@ -ESX = nil -local CopsConnected = 0 -local PlayersHarvestingCoke = {} -local PlayersTransformingCoke = {} -local PlayersSellingCoke = {} -local PlayersHarvestingMeth = {} -local PlayersTransformingMeth = {} -local PlayersSellingMeth = {} -local PlayersHarvestingWeed = {} -local PlayersTransformingWeed = {} -local PlayersSellingWeed = {} +ESX = nil +local CopsConnected = 0 +local PlayersHarvestingCoke = {} +local PlayersTransformingCoke = {} +local PlayersSellingCoke = {} +local PlayersHarvestingMeth = {} +local PlayersTransformingMeth = {} +local PlayersSellingMeth = {} +local PlayersHarvestingWeed = {} +local PlayersTransformingWeed = {} +local PlayersSellingWeed = {} +local PlayersHarvestingOpium = {} +local PlayersTransformingOpium = {} +local PlayersSellingOpium = {} TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) @@ -31,6 +34,7 @@ end CountCops() +--coke local function HarvestCoke(source) if CopsConnected < Config.RequiredCopsCoke then @@ -200,6 +204,7 @@ AddEventHandler('esx_drugs:stopSellCoke', function() end) +--meth local function HarvestMeth(source) if CopsConnected < Config.RequiredCopsMeth then @@ -372,6 +377,7 @@ AddEventHandler('esx_drugs:stopSellMeth', function() end) +--weed local function HarvestWeed(source) if CopsConnected < Config.RequiredCopsWeed then @@ -538,6 +544,179 @@ AddEventHandler('esx_drugs:stopSellWeed', function() end) + +--opium + +local function HarvestOpium(source) + + if CopsConnected < Config.RequiredCopsOpium then + TriggerClientEvent('esx:showNotification', source, _U('act_imp_police') .. CopsConnected .. '/' .. Config.RequiredCopsOpium) + return + end + + SetTimeout(5000, function() + + if PlayersHarvestingOpium[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + + local opium = xPlayer.getInventoryItem('opium') + + if opium.limit ~= -1 and opium.count >= opium.limit then + TriggerClientEvent('esx:showNotification', source, _U('inv_full_opium')) + else + xPlayer.addInventoryItem('opium', 1) + HarvestOpium(source) + end + + end + end) +end + +RegisterServerEvent('esx_drugs:startHarvestOpium') +AddEventHandler('esx_drugs:startHarvestOpium', function() + + local _source = source + + PlayersHarvestingOpium[_source] = true + + TriggerClientEvent('esx:showNotification', _source, _U('pickup_in_prog')) + + HarvestOpium(_source) + +end) + +RegisterServerEvent('esx_drugs:stopHarvestOpium') +AddEventHandler('esx_drugs:stopHarvestOpium', function() + + local _source = source + + PlayersHarvestingOpium[_source] = false + +end) + +local function TransformOpium(source) + + if CopsConnected < Config.RequiredCopsOpium then + TriggerClientEvent('esx:showNotification', source, _U('act_imp_police') .. CopsConnected .. '/' .. Config.RequiredCopsOpium) + return + end + + SetTimeout(10000, function() + + if PlayersTransformingOpium[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + + local opiumQuantity = xPlayer.getInventoryItem('opium').count + local poochQuantity = xPlayer.getInventoryItem('opium_pooch').count + + if poochQuantity > 35 then + TriggerClientEvent('esx:showNotification', source, _U('too_many_pouches')) + elseif opiumQuantity < 5 then + TriggerClientEvent('esx:showNotification', source, _U('not_enough_opium')) + else + xPlayer.removeInventoryItem('opium', 5) + xPlayer.addInventoryItem('opium_pooch', 1) + + TransformOpium(source) + end + + end + end) +end + +RegisterServerEvent('esx_drugs:startTransformOpium') +AddEventHandler('esx_drugs:startTransformOpium', function() + + local _source = source + + PlayersTransformingOpium[_source] = true + + TriggerClientEvent('esx:showNotification', _source, _U('packing_in_prog')) + + TransformOpium(_source) + +end) + +RegisterServerEvent('esx_drugs:stopTransformOpium') +AddEventHandler('esx_drugs:stopTransformOpium', function() + + local _source = source + + PlayersTransformingOpium[_source] = false + +end) + +local function SellOpium(source) + + if CopsConnected < Config.RequiredCopsOpium then + TriggerClientEvent('esx:showNotification', source, _U('act_imp_police') .. CopsConnected .. '/' .. Config.RequiredCopsOpium) + return + end + + SetTimeout(7500, function() + + if PlayersSellingOpium[source] == true then + + local xPlayer = ESX.GetPlayerFromId(source) + + local poochQuantity = xPlayer.getInventoryItem('opium_pooch').count + + if poochQuantity == 0 then + TriggerClientEvent('esx:showNotification', source, _U('no_pouches_sale')) + else + xPlayer.removeInventoryItem('opium_pooch', 1) + if CopsConnected == 0 then + xPlayer.addAccountMoney('black_money', 300) + TriggerClientEvent('esx:showNotification', source, _U('sold_one_opium')) + elseif CopsConnected == 1 then + xPlayer.addAccountMoney('black_money', 500) + TriggerClientEvent('esx:showNotification', source, _U('sold_one_opium')) + elseif CopsConnected == 2 then + xPlayer.addAccountMoney('black_money', 700) + TriggerClientEvent('esx:showNotification', source, _U('sold_one_opium')) + elseif CopsConnected == 3 then + xPlayer.addAccountMoney('black_money', 800) + TriggerClientEvent('esx:showNotification', source, _U('sold_one_opium')) + elseif CopsConnected == 4 then + xPlayer.addAccountMoney('black_money', 900) + TriggerClientEvent('esx:showNotification', source, _U('sold_one_opium')) + elseif CopsConnected >= 5 then + xPlayer.addAccountMoney('black_money', 1000) + TriggerClientEvent('esx:showNotification', source, _U('sold_one_opium')) + end + + SellOpium(source) + end + + end + end) +end + +RegisterServerEvent('esx_drugs:startSellOpium') +AddEventHandler('esx_drugs:startSellOpium', function() + + local _source = source + + PlayersSellingOpium[_source] = true + + TriggerClientEvent('esx:showNotification', _source, _U('sale_in_prog')) + + SellOpium(_source) + +end) + +RegisterServerEvent('esx_drugs:stopSellOpium') +AddEventHandler('esx_drugs:stopSellOpium', function() + + local _source = source + + PlayersSellingOpium[_source] = false + +end) + + -- RETURN INVENTORY TO CLIENT RegisterServerEvent('esx_drugs:GetUserInventory') AddEventHandler('esx_drugs:GetUserInventory', function(currentZone) @@ -551,6 +730,8 @@ AddEventHandler('esx_drugs:GetUserInventory', function(currentZone) xPlayer.getInventoryItem('meth_pooch').count, xPlayer.getInventoryItem('weed').count, xPlayer.getInventoryItem('weed_pooch').count, + xPlayer.getInventoryItem('opium').count, + xPlayer.getInventoryItem('opium_pooch').count, xPlayer.job.name, currentZone ) From e6ec608400f4a760c02537b7b11a578e413e9374 Mon Sep 17 00:00:00 2001 From: Moonblaze1995 Date: Fri, 25 Aug 2017 15:52:37 -0500 Subject: [PATCH 0604/3224] Update README.md Added Installation Instructions --- README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7b2d9ed0..5f6a3402 100644 --- a/README.md +++ b/README.md @@ -11,4 +11,16 @@ This addon is an easy way to have farming jobs on your server. There is no player management. -Just take exemple on the files in the jobs folder. \ No newline at end of file +Just take example on the files in the jobs folder. + +[INSTALLATION] +1. CD in your resources/[esx] folder +2. Clone the repository + ``` + git clone https://github.com/FXServer-ESX/fxserver-esx_jobs esx_drugs + ``` +3. Import esx_jobs.sql into your database +4. Add this into your server.cfg +``` +start esx_drugs +``` From adaaa8b67920a39c6f9ccdedcd06de69784da554 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 26 Aug 2017 08:56:22 +0200 Subject: [PATCH 0605/3224] Add Config.EnableOwnedVehicles --- client/main.lua | 16 +++++++++++++--- config.lua | 3 ++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/client/main.lua b/client/main.lua index d2f18d04..f6870d02 100644 --- a/client/main.lua +++ b/client/main.lua @@ -182,7 +182,9 @@ function OpenShopMenu() local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) - TriggerServerEvent('esx_vehicleshop:setVehicleOwned', vehicleProps) + if Config.EnableOwnedVehicles then + TriggerServerEvent('esx_vehicleshop:setVehicleOwned', vehicleProps) + end end) @@ -347,7 +349,11 @@ function OpenResellerMenu() local model = CurrentVehicleData.model TriggerServerEvent('esx_vehicleshop:sellVehicle', model) - TriggerServerEvent('esx_vehicleshop:setVehicleOwnedPlayerId', GetPlayerServerId(closestPlayer), vehicleProps) + + if Config.EnableOwnedVehicles then + TriggerServerEvent('esx_vehicleshop:setVehicleOwnedPlayerId', GetPlayerServerId(closestPlayer), vehicleProps) + end + end end @@ -381,7 +387,11 @@ function OpenResellerMenu() local model = CurrentVehicleData.model TriggerServerEvent('esx_vehicleshop:rentVehicle', model, vehicleProps.plate, GetPlayerName(closestPlayer), CurrentVehicleData.price, amount, GetPlayerServerId(closestPlayer)) - TriggerServerEvent('esx_vehicleshop:setVehicleOwnedPlayerId', GetPlayerServerId(closestPlayer), vehicleProps) + + if Config.EnableOwnedVehicles then + TriggerServerEvent('esx_vehicleshop:setVehicleOwnedPlayerId', GetPlayerServerId(closestPlayer), vehicleProps) + end + TriggerServerEvent('esx_vehicleshop:setVehicleForAllPlayers', vehicleProps, Config.Zones.ShopInside.Pos.x, Config.Zones.ShopInside.Pos.y, Config.Zones.ShopInside.Pos.z, 5.0) end diff --git a/config.lua b/config.lua index 81ea2e7a..c4cb3f43 100644 --- a/config.lua +++ b/config.lua @@ -3,8 +3,9 @@ Config.DrawDistance = 100.0 Config.MarkerColor = {r = 120, g = 120, b = 240} Config.EnablePlayerManagement = false -- If set to true, you need esx_addonaccount, esx_billing and esx_society Config.EnablePvCommand = true +Config.EnableOwnedVehicles = true Config.ResellPercentage = 50 -Config.Locale = 'fr' +Config.Locale = 'fr' Config.Zones = { From 64db46ed649e18e15cba0c0ebc9ed1dbfa160892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 26 Aug 2017 09:01:46 +0200 Subject: [PATCH 0606/3224] Optimization --- server/main.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index eba7d460..d340dde0 100644 --- a/server/main.lua +++ b/server/main.lua @@ -107,7 +107,9 @@ function CalculateBankSavings(d, h, m) local interests = math.floor(account.money / 100 * Config.BankSavingPercentage) bankInterests = bankInterests + interests - account.addMoney(interests) + table.insert(asyncTasks, function(cb) + account.addMoney(interests) + end) end) From 2772576df8e8f339cf7cc7c77493e5b4614f10f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 26 Aug 2017 09:03:48 +0200 Subject: [PATCH 0607/3224] Fix pickup --- resources/[essential]/es_extended/client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index 0fff86b3..caa47ea7 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -270,7 +270,7 @@ AddEventHandler('esx:spawnObject', function(model) end) RegisterNetEvent('esx:pickup') -AddEventHandler('esx:pickup', function(id, label, coords) +AddEventHandler('esx:pickup', function(id, label, player) local ped = GetPlayerPed(GetPlayerFromServerId(player)) local coords = GetEntityCoords(ped) From b415f2d59ddce213d428c3fcc15a40fcc22a43d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 26 Aug 2017 09:20:49 +0200 Subject: [PATCH 0608/3224] Add setLastSkin event --- client/main.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/main.lua b/client/main.lua index f7d44e38..8fef14cf 100644 --- a/client/main.lua +++ b/client/main.lua @@ -316,6 +316,10 @@ AddEventHandler('esx_skin:getLastSkin', function(cb) cb(LastSkin) end) +AddEventHandler('esx_skin:setLastSkin', function(skin) + LastSkin = skin +end) + RegisterNetEvent('esx_skin:openMenu') AddEventHandler('esx_skin:openMenu', function(submitCb, cancelCb) OpenMenu(submitCb, cancelCb, nil) From a5448f891a247af6108e36a79e0076ee23676986 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 26 Aug 2017 09:23:05 +0200 Subject: [PATCH 0609/3224] Set last skin when get outfit --- client/main.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/client/main.lua b/client/main.lua index 7867679a..f76f9bba 100644 --- a/client/main.lua +++ b/client/main.lua @@ -574,6 +574,7 @@ function OpenRoomMenu(property) TriggerEvent('skinchanger:getSkin', function(skin) TriggerEvent('skinchanger:loadClothes', skin, data.current.value) + TriggerEvent('esx_skin:setLastSkin', skin) TriggerEvent('skinchanger:getSkin', function(skin) TriggerServerEvent('esx_skin:save', skin) From 425acbf1b9a8e591b548ad954c0c940526a00aaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 26 Aug 2017 09:24:32 +0200 Subject: [PATCH 0610/3224] Fix typo --- client/main.lua | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/client/main.lua b/client/main.lua index 7a7c1809..527178c1 100644 --- a/client/main.lua +++ b/client/main.lua @@ -286,12 +286,12 @@ function OpenMobileMecanoActionsMenu() { title = 'Mécano', elements = { - {label = 'Facuration', value = 'billing'}, - {label = 'Crocheter', value = 'hijack_vehicle'}, - {label = 'Réparer', value = 'fix_vehicle'}, - {label = 'Netoyer', value = 'clean_vehicle'}, - {label = 'Fourrière', value = 'del_vehicle'}, - {label = 'Plateau', value = 'dep_vehicle'}, + {label = 'Facuration', value = 'billing'}, + {label = 'Crocheter', value = 'hijack_vehicle'}, + {label = 'Réparer', value = 'fix_vehicle'}, + {label = 'Nettoyer', value = 'clean_vehicle'}, + {label = 'Fourrière', value = 'del_vehicle'}, + {label = 'Plateau', value = 'dep_vehicle'}, {label = 'Placer objets', value = 'object_spawner'} } }, @@ -374,6 +374,7 @@ function OpenMobileMecanoActionsMenu() SetVehicleFixed(vehicle) SetVehicleDeformationFixed(vehicle) SetVehicleUndriveable(vehicle, false) + SetVehicleEngineOn(vehicle, true, true) ClearPedTasksImmediately(playerPed) TriggerEvent('esx:showNotification', 'Véhicule ~g~réparé') end) From b3eb5a46715a9ad0caebdee1ceaccf2b53802b16 Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 10:41:02 +0200 Subject: [PATCH 0611/3224] Added German language --- __resource.lua | 2 + de_esx_property.sql | 94 +++++++++++++++++++++++++++++++++++++++++++++ locales/de.lua | 31 +++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 de_esx_property.sql create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index a8c1e5ea..fc295f8e 100644 --- a/__resource.lua +++ b/__resource.lua @@ -4,6 +4,7 @@ description 'ESX Property' server_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', @@ -14,6 +15,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', diff --git a/de_esx_property.sql b/de_esx_property.sql new file mode 100644 index 00000000..cb819d08 --- /dev/null +++ b/de_esx_property.sql @@ -0,0 +1,94 @@ +USE `essentialmode`; + +ALTER TABLE `users` + ADD COLUMN `last_property` VARCHAR(255) NULL +; + +INSERT INTO `addon_account` (name, label, shared) VALUES + ('property_black_money','Schwarzgeld',0) +; + +INSERT INTO `addon_inventory` (name, label, shared) VALUES + ('property','Immobilien',0) +; + +INSERT INTO `datastore` (name, label, shared) VALUES + ('property','Immobilien',0) +; + +CREATE TABLE `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`) +); + +CREATE TABLE `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`) +); + +INSERT INTO `properties` 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) +; + diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..ffc3fdf4 --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,31 @@ +Locales['de'] = { + + ['free_prop'] = 'Kostenlose Immobilie', + ['property'] = 'Immobilie', + ['enter'] = 'Eintreten', + ['leave'] = 'Verlassen', + ['buy'] = 'Kaufen', + ['rent'] = 'Mieten', + ['visit'] = 'Ansehen', + ['press_to_menu'] = 'Drücke ~INPUT_CONTEXT~ um das Menü zu öffnen', + ['owned_properties'] = 'Gekaufte Immobilien', + ['available_properties'] = 'Verfügbare Immobilien', + ['invite_player'] = 'Spieler einladen', + ['you_invited'] = 'Du hast %s eingeladen', + ['player_clothes'] = 'Kleidung', + ['remove_object'] = 'Objekt nehmen', + ['deposit_object'] = 'Objekt deponieren', + ['invite'] = 'Einladen', + ['dirty_money'] = 'Schwarzgeld $', + ['inventory'] = 'Inventar', + ['amount'] = 'Anzahlt?', + ['amount_invalid'] = 'Ungültiger Wert', + ['press_to_exit'] = 'Drücke ~INPUT_CONTEXT~ um die Immobilie zu verlassen', + ['rented_for'] = 'Du hast eine Immobilie gemietet $', + ['purchased_for'] = 'Du hast eine Immobilie gekauft $', + ['made_property'] = 'Du hast eine Immobilie gemacht', + ['not_enough'] = 'du hast nicht genug Geld', + ['invalid_quantity'] = 'Ungültiger Betrag', + ['paid_rent'] = 'du ~g~bezahlst~s~ deine Miete: ~g~$', + +} From a08a1febf059dc1fd01335b9027a80cbb148ccff Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 10:43:41 +0200 Subject: [PATCH 0612/3224] Add German language --- __resource.lua | 2 ++ locales/de.lua | 8 ++++++++ 2 files changed, 10 insertions(+) create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index eff9b223..0ccde16f 100644 --- a/__resource.lua +++ b/__resource.lua @@ -5,6 +5,7 @@ description 'ESX Skin' server_scripts { '@es_extended/locale.lua', 'config.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', @@ -15,6 +16,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', 'config.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..ea5b6bb1 --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,8 @@ +Locales['de'] = { + + ['skin_menu'] = 'Skin Menü', + ['use_rotate_view'] = 'benutze ~INPUT_VEH_FLY_ROLL_LEFT_ONLY~ und ~INPUT_VEH_FLY_ROLL_RIGHT_ONLY~ um die Sicht zu drehen.', + ['skin'] = 'Skin ändern', + ['saveskin'] = 'Skin speichern', + +} From e84541553acdcb1bd64fa12ab0d7e56463ece546 Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 10:47:13 +0200 Subject: [PATCH 0613/3224] Add German Language --- de_es_extended.sql | 69 ++++++++++ .../[essential]/es_extended/__resource.lua | 2 + .../[essential]/es_extended/locales/de.lua | 121 ++++++++++++++++++ 3 files changed, 192 insertions(+) create mode 100644 de_es_extended.sql create mode 100644 resources/[essential]/es_extended/locales/de.lua diff --git a/de_es_extended.sql b/de_es_extended.sql new file mode 100644 index 00000000..9e4add3a --- /dev/null +++ b/de_es_extended.sql @@ -0,0 +1,69 @@ +USE `essentialmode`; + +ALTER TABLE `users` + ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, + ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, + ADD COLUMN `job` varchar(255) NULL DEFAULT 'unemployed' AFTER `skin`, + ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, + ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, + ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout` +; + +CREATE TABLE `items` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `label` varchar(255) NOT NULL, + `limit` int(11) NOT NULL DEFAULT '-1', + `rare` int(11) NOT NULL DEFAULT '0', + `can_remove` int(11) NOT NULL DEFAULT '1', + + PRIMARY KEY (`id`) +); + +CREATE TABLE `job_grades` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `job_name` varchar(255) DEFAULT NULL, + `grade` int(11) NOT NULL, + `name` varchar(255) NOT NULL, + `label` varchar(255) NOT NULL, + `salary` int(11) NOT NULL, + `skin_male` longtext NOT NULL, + `skin_female` longtext NOT NULL, + + PRIMARY KEY (`id`) +); + +INSERT INTO `job_grades` VALUES (1,'unemployed',0,'rsa','Arbeitslos',200,'{}','{}'); + +CREATE TABLE `jobs` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `label` varchar(255) DEFAULT NULL, + + PRIMARY KEY (`id`) +); + +INSERT INTO `jobs` VALUES (1,'unemployed','Suchend'); + +CREATE TABLE `user_accounts` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `identifier` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `money` double NOT NULL DEFAULT '0', + + PRIMARY KEY (`id`) +); + +CREATE TABLE `user_inventory` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `identifier` varchar(255) NOT NULL, + `item` varchar(255) NOT NULL, + `count` int(11) NOT NULL, + + PRIMARY KEY (`id`) +); diff --git a/resources/[essential]/es_extended/__resource.lua b/resources/[essential]/es_extended/__resource.lua index 26eb01ef..225d2734 100644 --- a/resources/[essential]/es_extended/__resource.lua +++ b/resources/[essential]/es_extended/__resource.lua @@ -7,6 +7,7 @@ server_scripts { '@mysql-async/lib/MySQL.lua', 'config.lua', 'locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/fr.lua', 'locales/en.lua', @@ -21,6 +22,7 @@ server_scripts { client_scripts { 'config.lua', 'locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/fr.lua', 'locales/en.lua', diff --git a/resources/[essential]/es_extended/locales/de.lua b/resources/[essential]/es_extended/locales/de.lua new file mode 100644 index 00000000..21ec922b --- /dev/null +++ b/resources/[essential]/es_extended/locales/de.lua @@ -0,0 +1,121 @@ +Locales['de'] = { + ['inventory'] = 'Inventar', + ['use'] = 'benutzen', + ['give'] = 'geben', + ['remove'] = 'entfernen', + ['return'] = 'zurück', + ['amount'] = 'Betrag', + ['amount_invalid'] = 'ungültiger Betrag', + ['players_nearby'] = 'keine Spieler in der Nähe', + ['ex_inv_lim'] = 'Aktion nicht möglich, inventarlimit überschritten für ~b~', + ['yougave'] = 'du gibst', + ['youreceived'] = 'to empfängst', + ['to'] = '~s~ zu ~b~', + ['by'] = '~s~ von ~b~', + ['imp_invalid_quantity'] = 'Aktion nicht möglich, ungültige Anzahl', + ['imp_invalid_amount'] = 'Aktion nicht möglich, ungültiger Betrag', + ['delete_five_min'] = '~r~löschen~s~ in 5 Minuten', + ['threw'] = 'du ~r~wirfst weg~s~', + ['rec_salary'] = 'du hast dein Gehalt erhalten: ', + ['act_imp'] = 'Aktion nicht möglich', + -- Commands + ['setjob'] = 'assign a job to a user', + ['id_param'] = 'the ID of the player', + ['setjob_param2'] = 'the job you wish to assign', + ['setjob_param3'] = 'the job level', + ['load_ipl'] = 'load IPL', + ['unload_ipl'] = 'unload IPL', + ['play_anim'] = 'play animation', + ['play_emote'] = 'play emote', + ['spawn_car'] = 'spawn a car', + ['spawn_car_param'] = 'name of car', + ['givemoney'] = 'give money', + ['money_amount'] = 'amount of money', + ['invalid_account'] = 'invalid account', + ['account'] = 'account', + ['giveaccountmoney'] = 'give account money', + ['invalid_item'] = 'invalid item', + ['item'] = 'item', + ['giveitem'] = 'give item', + ['weapon'] = 'weapon', + ['giveweapon'] = 'give weapon', + -- Weapons + ['weapon_knife'] = 'Messer', + ['weapon_nightstick'] = 'Schlagstock', + ['weapon_hammer'] = 'Hammer', + ['weapon_bat'] = 'Schläger', + ['weapon_golfclub'] = 'Golfschläger', + ['weapon_crowbar'] = 'Brecheisen', + ['weapon_pistol'] = 'Pistole', + ['weapon_combatpistol'] = 'Kampfpistole', + ['weapon_appistol'] = 'AP Pistole', + ['weapon_pistol50'] = 'Pistole .50', + ['weapon_microsmg'] = 'Mikro SMG', + ['weapon_smg'] = 'SMG', + ['weapon_assaultsmg'] = 'Kampf SMG', + ['weapon_assaultrifle'] = 'Kampfgewehr', + ['weapon_carbinerifle'] = 'Karabinergewehr', + ['weapon_advancedrifle'] = 'Advancedgewehr', + ['weapon_mg'] = 'MG', + ['weapon_combatmg'] = 'Kampf MG', + ['weapon_pumpshotgun'] = 'Pumpgun', + ['weapon_sawnoffshotgun'] = 'Abgesägte Schrotflinte', + ['weapon_assaultshotgun'] = 'Kampf Schrotflinte', + ['weapon_bullpupshotgun'] = 'Bullpup Schrotflinte', + ['weapon_stungun'] = 'Tazer', + ['weapon_sniperrifle'] = 'Scharfschützengewehr', + ['weapon_heavysniper'] = 'Schweres Sniper', + ['weapon_remotesniper'] = 'Remote sniper', + ['weapon_grenadelauncher'] = 'Granatwerfer', + ['weapon_rpg'] = 'RPG', + ['weapon_stinger'] = 'Stinger', + ['weapon_minigun'] = 'Minigun', + ['weapon_grenade'] = 'Granate', + ['weapon_stickybomb'] = 'Haftbombe', + ['weapon_smokegrenade'] = 'Rauchgranate', + ['weapon_bzgas'] = 'BZ Gas', + ['weapon_molotov'] = 'Molotov Cocktail', + ['weapon_fireextinguisher'] = 'Feuerlöscher', + ['weapon_petrolcan'] = 'Benzinkanister', + ['weapon_digiscanner'] = 'Digiscanner', + ['weapon_ball'] = 'Ball', + ['weapon_snspistol'] = 'SNS Pistole', + ['weapon_bottle'] = 'Flasche', + ['weapon_gusenberg'] = 'Gusenberg', + ['weapon_specialcarbine'] = 'Spezialkarabiner', + ['weapon_heavypistol'] = 'Schwere Pistole', + ['weapon_bullpuprifle'] = 'Bullpupgewehr', + ['weapon_dagger'] = 'Dolch', + ['weapon_vintagepistol'] = 'Vintage Pistole', + ['weapon_firework'] = 'Feuerwerk', + ['weapon_musket'] = 'Muskete', + ['weapon_heavyshotgun'] = 'Schwere Schrotflinte', + ['weapon_marksmanrifle'] = 'Marksmangewehr', + ['weapon_hominglauncher'] = 'Homing Launcher', + ['weapon_proxmine'] = 'Annäherungsmine', + ['weapon_snowball'] = 'Schneeball', + ['weapon_flaregun'] = 'Leuchtpistole', + ['weapon_garbagebag'] = 'Müllsack', + ['weapon_handcuffs'] = 'Handschellen', + ['weapon_combatpdw'] = 'Kampf PDW', + ['weapon_marksmanpistol'] = 'Marksman Pistole', + ['weapon_knuckle'] = 'Schlagring', + ['weapon_hatchet'] = 'Axt', + ['weapon_railgun'] = 'Railgun', + ['weapon_machete'] = 'Machete', + ['weapon_machinepistol'] = 'Maschinenpistole', + ['weapon_switchblade'] = 'Klappmesser', + ['weapon_revolver'] = 'Schwerer Revolver', + ['weapon_dbshotgun'] = 'Doppelläufige Schrotflinte', + ['weapon_compactrifle'] = 'Kampfgewehr', + ['weapon_autoshotgun'] = 'Auto Shotgun', + ['weapon_battleaxe'] = 'Kampfaxt', + ['weapon_compactlauncher'] = 'Kompakt Launcher', + ['weapon_minismg'] = 'Mini SMG', + ['weapon_pipebomb'] = 'Rohrbombe', + ['weapon_poolcue'] = 'Kö', + ['weapon_wrench'] = 'Rohrzange', + ['weapon_flashlight'] = 'Taschenlampe', + ['gadget_nightvision'] = 'Nachtsichtgerät', + ['gadget_parachute'] = 'Fallschirm', +} \ No newline at end of file From 645ab7583fa7c1bfcc022a1efc6fe1a56643e1e1 Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 10:57:48 +0200 Subject: [PATCH 0614/3224] Add German Language --- __resource.lua | 2 + de_esx_bankerjob.sql | 18 ++ html/de_ui.html | 132 +++++++++++ html/scripts/de_app.js | 512 +++++++++++++++++++++++++++++++++++++++++ locales/de.lua | 22 ++ 5 files changed, 686 insertions(+) create mode 100644 de_esx_bankerjob.sql create mode 100644 html/de_ui.html create mode 100644 html/scripts/de_app.js create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index e6a33645..b6f327dd 100644 --- a/__resource.lua +++ b/__resource.lua @@ -7,6 +7,7 @@ server_scripts { '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', 'config.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', @@ -16,6 +17,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', 'config.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', diff --git a/de_esx_bankerjob.sql b/de_esx_bankerjob.sql new file mode 100644 index 00000000..9b203999 --- /dev/null +++ b/de_esx_bankerjob.sql @@ -0,0 +1,18 @@ +USE `essentialmode`; + +INSERT INTO `addon_account` (name, label, shared) VALUES + ('society_banker','Bank',1), + ('bank_savings','Bank',0) +; + +INSERT INTO `jobs` (name, label) VALUES + ('banker','Banker') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('banker',0,'advisor','Berater',10,'{}','{}'), + ('banker',1,'banker','Banker',20,'{}','{}'), + ('banker',2,'business_banker','Business Banker',30,'{}','{}'), + ('banker',3,'trader','Trader',40,'{}','{}'), + ('banker',4,'boss','Boss',0,'{}','{}') +; diff --git a/html/de_ui.html b/html/de_ui.html new file mode 100644 index 00000000..6fa5aa47 --- /dev/null +++ b/html/de_ui.html @@ -0,0 +1,132 @@ + + + + + + + + + + +
    +
    +

    + + Bank +

    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +

    + + Betrag ? +

    +
    +
    +
    + + + +
    +
    +
    + +
    +
    +

    + + Betrag ? +

    +
    +
    +
    + + + +
    +
    +
    + +
    +
    +

    + + Betrag ? +

    +
    +
    +
    + + +
    +
    +
    + +
    +
    +

    + + Betrag ? +

    +
    +
    +
    + + +
    +
    +
    + +
    +
    +

    + + Betrag ? +

    +
    +
    +
    + + +
    +
    +
    + +
    +
    +

    + + Betrag ? +

    +
    +
    +
    + + +
    +
    +
    + + + + +
    +
     Bank
    +
     Bank
    +
     Zurück
    +
    + + + + + + + + \ No newline at end of file diff --git a/html/scripts/de_app.js b/html/scripts/de_app.js new file mode 100644 index 00000000..35c6795a --- /dev/null +++ b/html/scripts/de_app.js @@ -0,0 +1,512 @@ +(function(){ + + let DefaultTpl = + '
    {{title}}
    ' + + ''+ + '
    ' + ; + + let DefaultWithTypeAndCountTpl = + '
    {{title}}
    ' + + ''+ + '
    ' + ; + + let CustomersTpl = + '' + + '' + + 'Client' + + 'Solde' + + 'Actions' + + '' + + '' + + '' + + '{{#customers}}' + + '' + + '{{name}}' + + '${{bank_savings}}' + + '' + + '' + + '' + + '' + + '' + + '{{/customers}}' + + '' + ; + + let menus = { + + banque : { + title : 'Bank', + visible : false, + current : -1, + hasControl: false, + template : DefaultTpl, + + items: [ + {label: 'Kunden', value: 'customers'}, + {label: 'Geld von Firma abheben', value: 'withdraw_society_money'}, + {label: 'Geld waschen', value: 'wash_money'} + ] + }, + + banque_actions : { + title : 'Bank', + visible : false, + current : 0, + hasControl: true, + template : DefaultTpl, + + items: [] + }, + } + + let renderMenus = function(){ + for(let k in menus){ + + let elem = $('#menu_' + k); + + elem.html(Mustache.render(menus[k].template, menus[k])); + + if(menus[k].visible) + elem.show(); + else + elem.hide(); + + } + } + + let showMenu = function(menu){ + + currentMenu = menu; + + for(let k in menus) + menus[k].visible = false; + + menus[menu].visible = true; + + renderMenus(); + + if(menus[currentMenu].items.length > 0){ + + $('#menu_' + currentMenu + ' .menu-item').removeClass('selected'); + $('#menu_' + currentMenu + ' .menu-item:eq(0)').addClass('selected'); + + menus[currentMenu].current = 0; + currentVal = menus[currentMenu].items[menus[currentMenu].current].value; + currentType = $('#menu_' + currentMenu + ' .menu-item:eq(0)').data('type'); + currentAction = $('#menu_' + currentMenu + ' .menu-item:eq(0)').data('action'); + currentCount = $('#menu_' + currentMenu + ' .menu-item:eq(0)').data('count'); + } + + $('#ctl_return').show(); + + isMenuOpen = true + isShowingControls = false + } + + let hideMenus = function(){ + + for(let k in menus) + menus[k].visible = false; + + renderMenus(); + isMenuOpen = false; + } + + let showControl = function(control){ + + hideControls(); + $('#ctl_' + control).show(); + isShowingControls = true; + currentControl = control; + } + + let hideControls = function(){ + + for(let k in menus) + $('#ctl_' + k).hide(); + + $('#ctl_return').hide(); + + isShowingControls = false; + } + + let showCustomers = function(customers, bankMoney){ + + let view = { + customers: customers + } + + $('#bank-money').text('$' + bankMoney) + $('#customer-list').html(Mustache.render(CustomersTpl, view)); + + $('#customer-list .transfer-btn').click(function(){ + showTransferDialog($(this).data('identifier')) + }); + + $('#customer-list .withdraw-btn').click(function(){ + showWithdrawBankSavingsDialog($(this).data('identifier')) + }); + + $('#customers').show(); + $(cursor).show(); + } + + let hideCustomers = function(){ + $('#customers').hide(); + $(cursor).hide(); + } + + let showTransferDialog = function(identifier){ + $('#transfer-dialog-amount').val(''); + $('#transfer-dialog-identifier').val(identifier); + $('#transfer-dialog').show(); + } + + let hideTransferDialog = function(){ + $('#transfer-dialog').hide(); + } + + let showWithdrawBankSavingsDialog = function(identifier){ + $('#withdraw-bank-savings-dialog-amount').val(''); + $('#withdraw-bank-savings-dialog-identifier').val(identifier); + $('#withdraw-bank-savings-dialog').show(); + } + + let hideWithdrawBankSavingsDialog = function(){ + $('#withdraw-bank-savings-dialog').hide(); + } + + let showBillingDialog = function(){ + $('#billing-dialog-amount').val(''); + $('#billing-dialog').show(); + $(cursor).show(); + } + + let hideBillingDialog = function(){ + $('#billing-dialog').hide(); + $(cursor).hide(); + } + + let showWithdrawDialog = function(){ + $('#withdraw-dialog-amount').val(''); + $('#withdraw-dialog').show(); + $(cursor).show(); + } + + let hideWithdrawDialog = function(){ + $('#withdraw-dialog').hide(); + $(cursor).hide(); + } + + let showWashMoneyDialog = function(){ + $('#washmoney-dialog-amount').val(''); + $('#washmoney-dialog').show(); + $(cursor).show(); + } + + let hideWashMoneyDialog = function(){ + $('#washmoney-dialog').hide(); + $(cursor).hide(); + } + + let showWithdrawSocietyMoneyDialog = function(){ + $('#withdraw-society-money-dialog-amount').val(''); + $('#withdraw-society-money-dialog').show(); + $(cursor).show(); + } + + let hideWithdrawSocietyMoneyDialog = function(){ + $('#withdraw-society-money-dialog').hide(); + $(cursor).hide(); + } + + $('#transfer-dialog-send').click(function(){ + + $.post('http://esx_bankerjob/transfer', JSON.stringify({ + identifier: $('#transfer-dialog-identifier').val(), + amount : parseFloat($('#transfer-dialog-amount').val()) + })) + + hideTransferDialog(); + + }); + + $('#withdraw-bank-savings-dialog-send').click(function(){ + + $.post('http://esx_bankerjob/withdraw_bank_savings', JSON.stringify({ + identifier: $('#withdraw-bank-savings-dialog-identifier').val(), + amount : parseFloat($('#withdraw-bank-savings-dialog-amount').val()) + })) + + hideWithdrawBankSavingsDialog(); + + }); + + $('#billing-dialog-send').click(function(){ + + $.post('http://esx_bankerjob/billing', JSON.stringify({ + amount: parseFloat($('#billing-dialog-amount').val()) + })) + + hideBillingDialog(); + + }); + + $('#withdraw-dialog-send').click(function(){ + + $.post('http://esx_bankerjob/withdraw', JSON.stringify({ + amount: parseFloat($('#withdraw-dialog-amount').val()) + })) + + hideWithdrawDialog(); + + }); + + $('#washmoney-dialog-send').click(function(){ + + $.post('http://esx_bankerjob/wash_money', JSON.stringify({ + amount: parseFloat($('#washmoney-dialog-amount').val()) + })) + + hideWashMoneyDialog(); + + }); + + $('#withdraw-society-money-dialog-send').click(function(){ + $.post('http://esx_bankerjob/withdraw_society_money', JSON.stringify({ + amount: parseFloat($('#withdraw-society-money-dialog-amount').val()) + })) + + hideWithdrawSocietyMoneyDialog(); + }); + + let documentWidth = document.documentElement.clientWidth; + let documentHeight = document.documentElement.clientHeight; + + let cursor = document.getElementById("cursor"); + let cursorX = documentWidth / 2; + let cursorY = documentHeight / 2; + + function UpdateCursorPos() { + cursor.style.left = cursorX; + cursor.style.top = cursorY; + } + + function Click(x, y) { + let element = $(document.elementFromPoint(x, y)); + element.focus().click(); + } + + function scrollCustomers(direction){ + + let element = $('#customers .head-content')[0]; + + if(direction == 'UP') + element.scrollTop -= 32; + + if(direction == 'DOWN') + element.scrollTop += 32; + + } + + $(document).mousemove(function(event) { + cursorX = event.pageX; + cursorY = event.pageY; + UpdateCursorPos(); + }); + + let isMenuOpen = false + let isShowingControls = false; + let currentMenu = null; + let currentControl = null; + let currentVal = null; + let currentType = null; + let currentAction = null; + let currentCount = null; + + renderMenus(); + + window.onData = function(data){ + + if(data.click === true){ + Click(cursorX - 1, cursorY - 1); + } + + if(data.showControls === true){ + currentMenu = data.controls; + showControl(data.controls); + } + + if(data.showControls === false){ + hideControls(); + } + + if(data.showMenu === true){ + hideControls(); + + if(data.items) + menus[data.menu].items = data.items + + showMenu(data.menu); + } + + if(data.showMenu === false){ + hideMenus(); + } + + if(data.showCustomers === true){ + showCustomers(data.customers, data.bankMoney); + } + + if(data.showCustomers === false){ + hideCustomers(); + } + + if(data.showBillingDialog === true){ + showBillingDialog(); + } + + if(data.showBillingDialog === false){ + hideBillingDialog(); + } + + if(data.showWithdrawDialog === true){ + showWithdrawDialog(); + } + + if(data.showWithdrawDialog === false){ + hideWithdrawDialog(); + } + + if(data.showWashMoneyDialog === true){ + showWashMoneyDialog(); + } + + if(data.showWashMoneyDialog === false){ + hideWashMoneyDialog(); + } + + if(data.showWithdrawSocietyMoneyDialog === true){ + showWithdrawSocietyMoneyDialog(); + } + + if(data.showWithdrawSocietyMoneyDialog === false){ + hideWithdrawSocietyMoneyDialog(); + } + + if(data.move && isMenuOpen){ + + if(data.move == 'UP'){ + if(menus[currentMenu].current > 0) + menus[currentMenu].current--; + } + + if(data.move == 'DOWN'){ + + let max = $('#menu_' + currentMenu + ' .menu-item').length; + + if(menus[currentMenu].current < max - 1) + menus[currentMenu].current++; + } + + $('#menu_' + currentMenu + ' .menu-item').removeClass('selected'); + $('#menu_' + currentMenu + ' .menu-item:eq(' + menus[currentMenu].current + ')').addClass('selected'); + + currentVal = menus[currentMenu].items[menus[currentMenu].current].value; + currentType = $('#menu_' + currentMenu + ' .menu-item:eq(' + menus[currentMenu].current + ')').data('type'); + currentAction = $('#menu_' + currentMenu + ' .menu-item:eq(' + menus[currentMenu].current + ')').data('action'); + currentCount = $('#menu_' + currentMenu + ' .menu-item:eq(' + menus[currentMenu].current + ')').data('count'); + } + + if(data.enterPressed){ + + if(isShowingControls){ + + $.post('http://esx_bankerjob/select_control', JSON.stringify({ + control: currentControl, + })) + + hideControls(); + showMenu(currentMenu); + + } else if(isMenuOpen) { + + if(menus[currentMenu].current != -1){ + $.post('http://esx_bankerjob/select', JSON.stringify({ + menu : currentMenu, + val : currentVal, + type : currentType, + action: currentAction, + count : currentCount + })) + } + + let elem = $('#menu_' + currentMenu + ' .menu-item.selected') + + if(elem.data('remove-on-select') == true){ + + elem.remove(); + + menus[currentMenu].items.splice(menus[currentMenu].current, 1) + menus[currentMenu].current = 0; + + $('#menu_' + currentMenu + ' .menu-item').removeClass('selected'); + $('#menu_' + currentMenu + ' .menu-item:eq(0)').addClass('selected'); + + currentVal = menus[currentMenu].items[0].value; + currentType = $('#menu_' + currentMenu + ' .menu-item:eq(0)').data('type'); + currentAction = $('#menu_' + currentMenu + ' .menu-item:eq(0)').data('action'); + currentCount = $('#menu_' + currentMenu + ' .menu-item:eq(0)').data('count'); + } + + } + + } + + if(data.backspacePressed){ + + if(isMenuOpen && currentMenu == 'banque'){ + hideMenus(); + $('#ctl_return').hide(); + showControl('banque'); + } + + if(isMenuOpen && currentMenu == 'banque_actions'){ + hideMenus(); + $('#ctl_return').hide(); + } + + } + } + + document.onkeyup = function (data) { + if (data.which == 27) { + $.post('http://esx_bankerjob/escape', '{}'); + } + }; + + document.onwheel = function (data) { + + if (data.deltaY < 0) { + scrollCustomers('UP'); + } + + if (data.deltaY > 0) { + scrollCustomers('DOWN'); + } + + }; + + $('form').submit(function(){ + return false; + }); + + window.onload = function(e){ window.addEventListener('message', function(event){ onData(event.data) }); } + +})() \ No newline at end of file diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..c5f479bb --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,22 @@ +Locales['de'] = { + ['actions'] = 'Aktionen', + ['amount'] = 'Betrag', + ['balance'] = 'Kontostand', + ['bank'] = 'Bank', + ['bill_amount'] = 'Rechnungsbetrag', + ['billing'] = 'Rechnung', + ['customer'] = 'Kunde', + ['customers'] = 'Client', + ['deposit'] = 'einzahlen', + ['deposit_amount'] = 'Einzahlungsbetrag', + ['deposit_society_money'] = 'Geld in Firma einzahlen', + ['invalid_amount'] = 'ungültiger Betrag', + ['no_player_nearby'] = 'kein Spieler in der Nähe', + ['press_input_context_to_open_menu'] = 'Drücke ~INPUT_CONTEXT~ um das Menü zu öffnen', + ['property'] = 'Immobilie', + ['wash_money'] = 'Geld waschen', + ['withdraw'] = 'Abheben', + ['withdraw_amount'] = 'Abhebebetrag', + ['withdraw_society_money'] = 'Firmengeld abheben', + ['bank_customer'] = 'Bankkunde', +} \ No newline at end of file From 123347c2c030db224b44ec9ba232b85652be1393 Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 11:07:28 +0200 Subject: [PATCH 0615/3224] Add German Language --- __resource.lua | 2 + de_esx_vehicleshop_full.sql | 292 +++++++++++++++++++++++++++++++++ de_esx_vehicleshop_minimal.sql | 288 ++++++++++++++++++++++++++++++++ locales/de.lua | 47 ++++++ 4 files changed, 629 insertions(+) create mode 100644 de_esx_vehicleshop_full.sql create mode 100644 de_esx_vehicleshop_minimal.sql create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index 7ce747e8..37d36fcb 100644 --- a/__resource.lua +++ b/__resource.lua @@ -5,6 +5,7 @@ description 'ESX Vehicle Shop' server_scripts { '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua' , + 'locales/de.lua' , 'locales/en.lua' , 'locales/fr.lua' , 'config.lua', @@ -13,6 +14,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua' , + 'locales/de.lua' , 'locales/en.lua' , 'locales/fr.lua' , 'config.lua', diff --git a/de_esx_vehicleshop_full.sql b/de_esx_vehicleshop_full.sql new file mode 100644 index 00000000..f81f796c --- /dev/null +++ b/de_esx_vehicleshop_full.sql @@ -0,0 +1,292 @@ +USE `essentialmode`; + +INSERT INTO `addon_account` (name, label, shared) VALUES + ('society_cardealer','Händler',1) +; + +INSERT INTO `jobs` (name, label) VALUES + ('cardealer','Händler') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('cardealer',0,'recruit','Neuling',10,'{}','{}'), + ('cardealer',1,'novice','Verkäufer',25,'{}','{}'), + ('cardealer',2,'experienced','Verkaufsleiter',40,'{}','{}'), + ('cardealer',3,'boss','Boss',0,'{}','{}') +; + +CREATE TABLE `cardealer_vehicles` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `vehicle` varchar(255) NOT NULL, + `price` int(11) NOT NULL, + PRIMARY KEY (`id`) +); + +CREATE TABLE `owned_vehicles` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `vehicle` longtext NOT NULL, + `owner` varchar(60) NOT NULL, + + PRIMARY KEY (`id`) +); + +CREATE TABLE `rented_vehicles` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `vehicle` varchar(60) NOT NULL, + `plate` varchar(10) NOT NULL, + `player_name` varchar(255) NOT NULL, + `base_price` int(11) NOT NULL, + `rent_price` int(11) NOT NULL, + `owner` varchar(255) NOT NULL, + + PRIMARY KEY (`id`) +); + +CREATE TABLE `vehicle_categories` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(60) NOT NULL, + `label` varchar(60) NOT NULL, + + PRIMARY KEY (`id`) +); + +INSERT INTO `vehicle_categories` (name, label) VALUES + ('compacts','Compacts'), + ('coupes','Coupés'), + ('sedans','Sedans'), + ('sports','Sports'), + ('sportsclassics','Sports Classics'), + ('super','Super'), + ('muscle','Muscle'), + ('offroad','Off Road'), + ('suvs','SUVs'), + ('vans','Vans'), + ('sedans','Sedans'), + ('motorcycles','Motos') +; + +CREATE TABLE `vehicles` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(60) NOT NULL, + `model` varchar(60) NOT NULL, + `price` int(11) NOT NULL, + `category` varchar(60) DEFAULT NULL, + PRIMARY KEY (`id`) +); + +INSERT INTO `vehicles` (name, model, price, category) VALUES + ('Blade','blade',15000,'muscle'), + ('Buccaneer','buccaneer',18000,'muscle'), + ('Buccaneer Rider','buccaneer2',24000,'muscle'), + ('Chino','chino',15000,'muscle'), + ('Chino Luxe','chino2',19000,'muscle'), + ('Coquette BlackFin','coquette3',55000,'muscle'), + ('Dominator','dominator',35000,'muscle'), + ('Dukes','dukes',28000,'muscle'), + ('Gauntlet','gauntlet',30000,'muscle'), + ('Hotknife','hotknife',125000,'muscle'), + ('Faction','faction',20000,'muscle'), + ('Faction Rider','faction2',30000,'muscle'), + ('Faction XL','faction3',40000,'muscle'), + ('Nightshade','nightshade',65000,'muscle'), + ('Phoenix','phoenix',12500,'muscle'), + ('Picador','picador',18000,'muscle'), + ('Sabre Turbo','sabregt',20000,'muscle'), + ('Sabre GT','sabregt2',25000,'muscle'), + ('Slam Van','slamvan3',11500,'muscle'), + ('Tampa','tampa',16000,'muscle'), + ('Virgo','virgo',14000,'muscle'), + ('Vigero','vigero',12500,'muscle'), + ('Voodoo','voodoo',7200,'muscle'), + ('Blista','blista',8000,'compacts'), + ('Brioso R/A','brioso',18000,'compacts'), + ('Issi','issi2',10000,'compacts'), + ('Panto','panto',10000,'compacts'), + ('Prairie','prairie',12000,'compacts'), + ('Bison','bison',45000,'vans'), + ('Bobcat XL','bobcatxl',32000,'vans'), + ('Burrito','burrito3',19000,'vans'), + ('Burrito','gburrito2',29000,'vans'), + ('Camper','camper',42000,'vans'), + ('Gang Burrito','gburrito',45000,'vans'), + ('Journey','journey',6500,'vans'), + ('Minivan','minivan',13000,'vans'), + ('Moonbeam','moonbeam',18000,'vans'), + ('Moonbeam Rider','moonbeam2',35000,'vans'), + ('Paradise','paradise',19000,'vans'), + ('Rumpo','rumpo',15000,'vans'), + ('Rumpo Trail','rumpo3',19500,'vans'), + ('Surfer','surfer',12000,'vans'), + ('Youga','youga',10800,'vans'), + ('Youga Luxuary','youga2',14500,'vans'), + ('Asea','asea',5500,'sedans'), + ('Cognoscenti','cognoscenti',55000,'sedans'), + ('Emperor','emperor',8500,'sedans'), + ('Fugitive','fugitive',12000,'sedans'), + ('Glendale','glendale',6500,'sedans'), + ('Intruder','intruder',7500,'sedans'), + ('Premier','premier',8000,'sedans'), + ('Primo Custom','primo2',14000,'sedans'), + ('Regina','regina',5000,'sedans'), + ('Schafter','schafter2',25000,'sedans'), + ('Stretch','stretch',90000,'sedans'), + ('Super Diamond','superd',130000,'sedans'), + ('Tailgater','tailgater',30000,'sedans'), + ('Warrener','warrener',4000,'sedans'), + ('Washington','washington',9000,'sedans'), + ('Baller','baller2',40000,'suvs'), + ('Baller Sport','baller3',60000,'suvs'), + ('Cavalcade','cavalcade2',55000,'suvs'), + ('Contender','contender',70000,'suvs'), + ('Dubsta','dubsta',45000,'suvs'), + ('Dubsta Luxuary','dubsta2',60000,'suvs'), + ('Fhantom','fq2',17000,'suvs'), + ('Grabger','granger',50000,'suvs'), + ('Gresley','gresley',47500,'suvs'), + ('Huntley S','huntley',40000,'suvs'), + ('Landstalker','landstalker',35000,'suvs'), + ('Mesa','mesa',16000,'suvs'), + ('Mesa Trail','mesa3',40000,'suvs'), + ('Patriot','patriot',55000,'suvs'), + ('Radius','radi',29000,'suvs'), + ('Rocoto','rocoto',45000,'suvs'), + ('Seminole','seminole',25000,'suvs'), + ('XLS','xls',32000,'suvs'), + ('Btype','btype',62000,'sportsclassics'), + ('Btype Luxe','btype3',85000,'sportsclassics'), + ('Btype Hotroad','btype2',155000,'sportsclassics'), + ('Casco','casco',30000,'sportsclassics'), + ('Coquette Classic','coquette2',40000,'sportsclassics'), + ('Manana','manana',12800,'sportsclassics'), + ('Monroe','monroe',55000,'sportsclassics'), + ('Pigalle','pigalle',20000,'sportsclassics'), + ('Stinger','stinger',80000,'sportsclassics'), + ('Stinger GT','stingergt',75000,'sportsclassics'), + ('Stirling GT','feltzer3',65000,'sportsclassics'), + ('Z-Type','ztype',220000,'sportsclassics'), + ('Bifta','bifta',12000,'offroad'), + ('Bf Injection','bfinjection',16000,'offroad'), + ('Blazer','blazer',6500,'offroad'), + ('Blazer Sport','blazer4',8500,'offroad'), + ('Brawler','brawler',45000,'offroad'), + ('Bubsta 6x6','dubsta3',120000,'offroad'), + ('Dune Buggy','dune',8000,'offroad'), + ('Guardian','guardian',45000,'offroad'), + ('Rebel','rebel2',35000,'offroad'), + ('Sandking','sandking',55000,'offroad'), + ('The Liberator','monster',210000,'offroad'), + ('Trophy Truck','trophytruck',60000,'offroad'), + ('Trophy Truck Limited','trophytruck2',80000,'offroad'), + ('Cognoscenti Cabrio','cogcabrio',55000,'coupes'), + ('Exemplar','exemplar',32000,'coupes'), + ('F620','f620',40000,'coupes'), + ('Felon','felon',42000,'coupes'), + ('Felon GT','felon2',55000,'coupes'), + ('Jackal','jackal',38000,'coupes'), + ('Oracle XS','oracle2',35000,'coupes'), + ('Sentinel','sentinel',32000,'coupes'), + ('Sentinel XS','sentinel2',40000,'coupes'), + ('Windsor','windsor',95000,'coupes'), + ('Windsor Drop','windsor2',125000,'coupes'), + ('Zion','zion',36000,'coupes'), + ('Zion Cabrio','zion2',45000,'coupes'), + ('9F','ninef',65000,'sports'), + ('9F Cabrio','ninef2',80000,'sports'), + ('Alpha','alpha',60000,'sports'), + ('Banshee','banshee',70000,'sports'), + ('Bestia GTS','bestiagts',55000,'sports'), + ('Buffalo','buffalo',12000,'sports'), + ('Buffalo S','buffalo2',20000,'sports'), + ('Carbonizzare','carbonizzare',75000,'sports'), + ('Comet','comet2',65000,'sports'), + ('Coquette','coquette',65000,'sports'), + ('Drift Tampa','tampa2',80000,'sports'), + ('Elegy','elegy2',38500,'sports'), + ('Feltzer','feltzer2',55000,'sports'), + ('Furore GT','furoregt',45000,'sports'), + ('Fusilade','fusilade',40000,'sports'), + ('Jester','jester',65000,'sports'), + ('Jester(Racecar)','jester2',135000,'sports'), + ('Khamelion','khamelion',38000,'sports'), + ('Kuruma','kuruma',30000,'sports'), + ('Lynx','lynx',40000,'sports'), + ('Mamba','mamba',70000,'sports'), + ('Massacro','massacro',65000,'sports'), + ('Massacro(Racecar)','massacro2',130000,'sports'), + ('Omnis','omnis',35000,'sports'), + ('Penumbra','penumbra',28000,'sports'), + ('Rapid GT','rapidgt',35000,'sports'), + ('Rapid GT Convertible','rapidgt2',45000,'sports'), + ('Schafter V12','schafter3',50000,'sports'), + ('Seven 70','seven70',39500,'sports'), + ('Sultan','sultan',15000,'sports'), + ('Surano','surano',50000,'sports'), + ('Tropos','tropos',40000,'sports'), + ('Verlierer','verlierer2',70000,'sports'), + ('Adder','adder',900000,'super'), + ('Banshee 900R','banshee2',255000,'super'), + ('Bullet','bullet',90000,'super'), + ('Cheetah','cheetah',375000,'super'), + ('Entity XF','entityxf',425000,'super'), + ('ETR1','sheava',220000,'super'), + ('FMJ','fmj',185000,'super'), + ('Infernus','infernus',180000,'super'), + ('Osiris','osiris',160000,'super'), + ('Pfister','pfister811',85000,'super'), + ('RE-7B','le7b',325000,'super'), + ('Reaper','reaper',150000,'super'), + ('Sultan RS','sultanrs',65000,'super'), + ('T20','t20',300000,'super'), + ('Turismo R','turismor',350000,'super'), + ('Tyrus','tyrus',600000,'super'), + ('Vacca','vacca',120000,'super'), + ('Voltic','voltic',90000,'super'), + ('X80 Proto','prototipo',2500000,'super'), + ('Zentorno','zentorno',1500000,'super'), + ('Akuma','AKUMA',7500,'motorcycles'), + ('Avarus','avarus',18000,'motorcycles'), + ('Bagger','bagger',13500,'motorcycles'), + ('Bati 801','bati',12000,'motorcycles'), + ('Bati 801RR','bati2',19000,'motorcycles'), + ('BF400','bf400',6500,'motorcycles'), + ('BMX (velo)','bmx',160,'motorcycles'), + ('Carbon RS','carbonrs',18000,'motorcycles'), + ('Chimera','chimera',38000,'motorcycles'), + ('Cliffhanger','cliffhanger',9500,'motorcycles'), + ('Cruiser (velo)','cruiser',510,'motorcycles'), + ('Daemon','daemon',11500,'motorcycles'), + ('Daemon High','daemon2',13500,'motorcycles'), + ('Defiler','defiler',9800,'motorcycles'), + ('Double T','double',28000,'motorcycles'), + ('Enduro','enduro',5500,'motorcycles'), + ('Esskey','esskey',4200,'motorcycles'), + ('Faggio','faggio',1900,'motorcycles'), + ('Vespa','faggio2',2800,'motorcycles'), + ('Fixter (velo)','fixter',225,'motorcycles'), + ('Gargoyle','gargoyle',16500,'motorcycles'), + ('Hakuchou','hakuchou',31000,'motorcycles'), + ('Hakuchou Sport','hakuchou2',55000,'motorcycles'), + ('Hexer','hexer',12000,'motorcycles'), + ('Innovation','innovation',23500,'motorcycles'), + ('Manchez','manchez',5300,'motorcycles'), + ('Nemesis','nemesis',5800,'motorcycles'), + ('Nightblade','nightblade',35000,'motorcycles'), + ('PCJ-600','pcj',6200,'motorcycles'), + ('Ruffian','ruffian',6800,'motorcycles'), + ('Sanchez','sanchez',5300,'motorcycles'), + ('Sanchez Sport','sanchez2',5300,'motorcycles'), + ('Sanctus','sanctus',25000,'motorcycles'), + ('Scorcher (velo)','scorcher',280,'motorcycles'), + ('Sovereign','sovereign',22000,'motorcycles'), + ('Shotaro Concept','shotaro',320000,'motorcycles'), + ('Thrust','thrust',24000,'motorcycles'), + ('Tri bike (velo)','tribike3',520,'motorcycles'), + ('Vader','vader',7200,'motorcycles'), + ('Vortex','vortex',9800,'motorcycles'), + ('Woflsbane','wolfsbane',9000,'motorcycles'), + ('Zombie','zombiea',9500,'motorcycles'), + ('Zombie Luxuary','zombieb',12000,'motorcycles') +; diff --git a/de_esx_vehicleshop_minimal.sql b/de_esx_vehicleshop_minimal.sql new file mode 100644 index 00000000..0368f879 --- /dev/null +++ b/de_esx_vehicleshop_minimal.sql @@ -0,0 +1,288 @@ +USE `essentialmode`; + +INSERT INTO `jobs` (name, label) VALUES + ('cardealer','Händler') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('cardealer',0,'recruit','Neuling',10,'{}','{}'), + ('cardealer',1,'novice','Verkäufer',25,'{}','{}'), + ('cardealer',2,'experienced','Verkaufsleiter',40,'{}','{}'), + ('cardealer',3,'boss','Boss',0,'{}','{}') +; + +CREATE TABLE `cardealer_vehicles` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `vehicle` varchar(255) NOT NULL, + `price` int(11) NOT NULL, + PRIMARY KEY (`id`) +); + +CREATE TABLE `owned_vehicles` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `vehicle` longtext NOT NULL, + `owner` varchar(60) NOT NULL, + + PRIMARY KEY (`id`) +); + +CREATE TABLE `rented_vehicles` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `vehicle` varchar(60) NOT NULL, + `plate` varchar(10) NOT NULL, + `player_name` varchar(255) NOT NULL, + `base_price` int(11) NOT NULL, + `rent_price` int(11) NOT NULL, + `owner` varchar(255) NOT NULL, + + PRIMARY KEY (`id`) +); + +CREATE TABLE `vehicle_categories` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(60) NOT NULL, + `label` varchar(60) NOT NULL, + + PRIMARY KEY (`id`) +); + +INSERT INTO `vehicle_categories` (name, label) VALUES + ('compacts','Compacts'), + ('coupes','Coupés'), + ('sedans','Sedans'), + ('sports','Sports'), + ('sportsclassics','Sports Classics'), + ('super','Super'), + ('muscle','Muscle'), + ('offroad','Off Road'), + ('suvs','SUVs'), + ('vans','Vans'), + ('sedans','Sedans'), + ('motorcycles','Motos') +; + +CREATE TABLE `vehicles` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(60) NOT NULL, + `model` varchar(60) NOT NULL, + `price` int(11) NOT NULL, + `category` varchar(60) DEFAULT NULL, + PRIMARY KEY (`id`) +); + +INSERT INTO `vehicles` (name, model, price, category) VALUES + ('Blade','blade',15000,'muscle'), + ('Buccaneer','buccaneer',18000,'muscle'), + ('Buccaneer Rider','buccaneer2',24000,'muscle'), + ('Chino','chino',15000,'muscle'), + ('Chino Luxe','chino2',19000,'muscle'), + ('Coquette BlackFin','coquette3',55000,'muscle'), + ('Dominator','dominator',35000,'muscle'), + ('Dukes','dukes',28000,'muscle'), + ('Gauntlet','gauntlet',30000,'muscle'), + ('Hotknife','hotknife',125000,'muscle'), + ('Faction','faction',20000,'muscle'), + ('Faction Rider','faction2',30000,'muscle'), + ('Faction XL','faction3',40000,'muscle'), + ('Nightshade','nightshade',65000,'muscle'), + ('Phoenix','phoenix',12500,'muscle'), + ('Picador','picador',18000,'muscle'), + ('Sabre Turbo','sabregt',20000,'muscle'), + ('Sabre GT','sabregt2',25000,'muscle'), + ('Slam Van','slamvan3',11500,'muscle'), + ('Tampa','tampa',16000,'muscle'), + ('Virgo','virgo',14000,'muscle'), + ('Vigero','vigero',12500,'muscle'), + ('Voodoo','voodoo',7200,'muscle'), + ('Blista','blista',8000,'compacts'), + ('Brioso R/A','brioso',18000,'compacts'), + ('Issi','issi2',10000,'compacts'), + ('Panto','panto',10000,'compacts'), + ('Prairie','prairie',12000,'compacts'), + ('Bison','bison',45000,'vans'), + ('Bobcat XL','bobcatxl',32000,'vans'), + ('Burrito','burrito3',19000,'vans'), + ('Burrito','gburrito2',29000,'vans'), + ('Camper','camper',42000,'vans'), + ('Gang Burrito','gburrito',45000,'vans'), + ('Journey','journey',6500,'vans'), + ('Minivan','minivan',13000,'vans'), + ('Moonbeam','moonbeam',18000,'vans'), + ('Moonbeam Rider','moonbeam2',35000,'vans'), + ('Paradise','paradise',19000,'vans'), + ('Rumpo','rumpo',15000,'vans'), + ('Rumpo Trail','rumpo3',19500,'vans'), + ('Surfer','surfer',12000,'vans'), + ('Youga','youga',10800,'vans'), + ('Youga Luxuary','youga2',14500,'vans'), + ('Asea','asea',5500,'sedans'), + ('Cognoscenti','cognoscenti',55000,'sedans'), + ('Emperor','emperor',8500,'sedans'), + ('Fugitive','fugitive',12000,'sedans'), + ('Glendale','glendale',6500,'sedans'), + ('Intruder','intruder',7500,'sedans'), + ('Premier','premier',8000,'sedans'), + ('Primo Custom','primo2',14000,'sedans'), + ('Regina','regina',5000,'sedans'), + ('Schafter','schafter2',25000,'sedans'), + ('Stretch','stretch',90000,'sedans'), + ('Super Diamond','superd',130000,'sedans'), + ('Tailgater','tailgater',30000,'sedans'), + ('Warrener','warrener',4000,'sedans'), + ('Washington','washington',9000,'sedans'), + ('Baller','baller2',40000,'suvs'), + ('Baller Sport','baller3',60000,'suvs'), + ('Cavalcade','cavalcade2',55000,'suvs'), + ('Contender','contender',70000,'suvs'), + ('Dubsta','dubsta',45000,'suvs'), + ('Dubsta Luxuary','dubsta2',60000,'suvs'), + ('Fhantom','fq2',17000,'suvs'), + ('Grabger','granger',50000,'suvs'), + ('Gresley','gresley',47500,'suvs'), + ('Huntley S','huntley',40000,'suvs'), + ('Landstalker','landstalker',35000,'suvs'), + ('Mesa','mesa',16000,'suvs'), + ('Mesa Trail','mesa3',40000,'suvs'), + ('Patriot','patriot',55000,'suvs'), + ('Radius','radi',29000,'suvs'), + ('Rocoto','rocoto',45000,'suvs'), + ('Seminole','seminole',25000,'suvs'), + ('XLS','xls',32000,'suvs'), + ('Btype','btype',62000,'sportsclassics'), + ('Btype Luxe','btype3',85000,'sportsclassics'), + ('Btype Hotroad','btype2',155000,'sportsclassics'), + ('Casco','casco',30000,'sportsclassics'), + ('Coquette Classic','coquette2',40000,'sportsclassics'), + ('Manana','manana',12800,'sportsclassics'), + ('Monroe','monroe',55000,'sportsclassics'), + ('Pigalle','pigalle',20000,'sportsclassics'), + ('Stinger','stinger',80000,'sportsclassics'), + ('Stinger GT','stingergt',75000,'sportsclassics'), + ('Stirling GT','feltzer3',65000,'sportsclassics'), + ('Z-Type','ztype',220000,'sportsclassics'), + ('Bifta','bifta',12000,'offroad'), + ('Bf Injection','bfinjection',16000,'offroad'), + ('Blazer','blazer',6500,'offroad'), + ('Blazer Sport','blazer4',8500,'offroad'), + ('Brawler','brawler',45000,'offroad'), + ('Bubsta 6x6','dubsta3',120000,'offroad'), + ('Dune Buggy','dune',8000,'offroad'), + ('Guardian','guardian',45000,'offroad'), + ('Rebel','rebel2',35000,'offroad'), + ('Sandking','sandking',55000,'offroad'), + ('The Liberator','monster',210000,'offroad'), + ('Trophy Truck','trophytruck',60000,'offroad'), + ('Trophy Truck Limited','trophytruck2',80000,'offroad'), + ('Cognoscenti Cabrio','cogcabrio',55000,'coupes'), + ('Exemplar','exemplar',32000,'coupes'), + ('F620','f620',40000,'coupes'), + ('Felon','felon',42000,'coupes'), + ('Felon GT','felon2',55000,'coupes'), + ('Jackal','jackal',38000,'coupes'), + ('Oracle XS','oracle2',35000,'coupes'), + ('Sentinel','sentinel',32000,'coupes'), + ('Sentinel XS','sentinel2',40000,'coupes'), + ('Windsor','windsor',95000,'coupes'), + ('Windsor Drop','windsor2',125000,'coupes'), + ('Zion','zion',36000,'coupes'), + ('Zion Cabrio','zion2',45000,'coupes'), + ('9F','ninef',65000,'sports'), + ('9F Cabrio','ninef2',80000,'sports'), + ('Alpha','alpha',60000,'sports'), + ('Banshee','banshee',70000,'sports'), + ('Bestia GTS','bestiagts',55000,'sports'), + ('Buffalo','buffalo',12000,'sports'), + ('Buffalo S','buffalo2',20000,'sports'), + ('Carbonizzare','carbonizzare',75000,'sports'), + ('Comet','comet2',65000,'sports'), + ('Coquette','coquette',65000,'sports'), + ('Drift Tampa','tampa2',80000,'sports'), + ('Elegy','elegy2',38500,'sports'), + ('Feltzer','feltzer2',55000,'sports'), + ('Furore GT','furoregt',45000,'sports'), + ('Fusilade','fusilade',40000,'sports'), + ('Jester','jester',65000,'sports'), + ('Jester(Racecar)','jester2',135000,'sports'), + ('Khamelion','khamelion',38000,'sports'), + ('Kuruma','kuruma',30000,'sports'), + ('Lynx','lynx',40000,'sports'), + ('Mamba','mamba',70000,'sports'), + ('Massacro','massacro',65000,'sports'), + ('Massacro(Racecar)','massacro2',130000,'sports'), + ('Omnis','omnis',35000,'sports'), + ('Penumbra','penumbra',28000,'sports'), + ('Rapid GT','rapidgt',35000,'sports'), + ('Rapid GT Convertible','rapidgt2',45000,'sports'), + ('Schafter V12','schafter3',50000,'sports'), + ('Seven 70','seven70',39500,'sports'), + ('Sultan','sultan',15000,'sports'), + ('Surano','surano',50000,'sports'), + ('Tropos','tropos',40000,'sports'), + ('Verlierer','verlierer2',70000,'sports'), + ('Adder','adder',900000,'super'), + ('Banshee 900R','banshee2',255000,'super'), + ('Bullet','bullet',90000,'super'), + ('Cheetah','cheetah',375000,'super'), + ('Entity XF','entityxf',425000,'super'), + ('ETR1','sheava',220000,'super'), + ('FMJ','fmj',185000,'super'), + ('Infernus','infernus',180000,'super'), + ('Osiris','osiris',160000,'super'), + ('Pfister','pfister811',85000,'super'), + ('RE-7B','le7b',325000,'super'), + ('Reaper','reaper',150000,'super'), + ('Sultan RS','sultanrs',65000,'super'), + ('T20','t20',300000,'super'), + ('Turismo R','turismor',350000,'super'), + ('Tyrus','tyrus',600000,'super'), + ('Vacca','vacca',120000,'super'), + ('Voltic','voltic',90000,'super'), + ('X80 Proto','prototipo',2500000,'super'), + ('Zentorno','zentorno',1500000,'super'), + ('Akuma','AKUMA',7500,'motorcycles'), + ('Avarus','avarus',18000,'motorcycles'), + ('Bagger','bagger',13500,'motorcycles'), + ('Bati 801','bati',12000,'motorcycles'), + ('Bati 801RR','bati2',19000,'motorcycles'), + ('BF400','bf400',6500,'motorcycles'), + ('BMX (velo)','bmx',160,'motorcycles'), + ('Carbon RS','carbonrs',18000,'motorcycles'), + ('Chimera','chimera',38000,'motorcycles'), + ('Cliffhanger','cliffhanger',9500,'motorcycles'), + ('Cruiser (velo)','cruiser',510,'motorcycles'), + ('Daemon','daemon',11500,'motorcycles'), + ('Daemon High','daemon2',13500,'motorcycles'), + ('Defiler','defiler',9800,'motorcycles'), + ('Double T','double',28000,'motorcycles'), + ('Enduro','enduro',5500,'motorcycles'), + ('Esskey','esskey',4200,'motorcycles'), + ('Faggio','faggio',1900,'motorcycles'), + ('Vespa','faggio2',2800,'motorcycles'), + ('Fixter (velo)','fixter',225,'motorcycles'), + ('Gargoyle','gargoyle',16500,'motorcycles'), + ('Hakuchou','hakuchou',31000,'motorcycles'), + ('Hakuchou Sport','hakuchou2',55000,'motorcycles'), + ('Hexer','hexer',12000,'motorcycles'), + ('Innovation','innovation',23500,'motorcycles'), + ('Manchez','manchez',5300,'motorcycles'), + ('Nemesis','nemesis',5800,'motorcycles'), + ('Nightblade','nightblade',35000,'motorcycles'), + ('PCJ-600','pcj',6200,'motorcycles'), + ('Ruffian','ruffian',6800,'motorcycles'), + ('Sanchez','sanchez',5300,'motorcycles'), + ('Sanchez Sport','sanchez2',5300,'motorcycles'), + ('Sanctus','sanctus',25000,'motorcycles'), + ('Scorcher (velo)','scorcher',280,'motorcycles'), + ('Sovereign','sovereign',22000,'motorcycles'), + ('Shotaro Concept','shotaro',320000,'motorcycles'), + ('Thrust','thrust',24000,'motorcycles'), + ('Tri bike (velo)','tribike3',520,'motorcycles'), + ('Vader','vader',7200,'motorcycles'), + ('Vortex','vortex',9800,'motorcycles'), + ('Woflsbane','wolfsbane',9000,'motorcycles'), + ('Zombie','zombiea',9500,'motorcycles'), + ('Zombie Luxuary','zombieb',12000,'motorcycles') +; diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..bcf96d8a --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,47 @@ +Locales['de'] = { + --Global menus + ['car_dealer'] = 'Autohändler', + ['buy'] = 'kaufen', + ['for'] = 'für $', + ['yes'] = 'ja', + ['no'] = 'nein', + ['shop_menu'] = 'Drücke ~INPUT_CONTEXT~ um das Menü zu öffnen', + ['vehicle_purchased'] = 'du hast ein Fahrzeug gekauft', + ['broke_company'] = 'du hast nicht genug Geld auf dem Firmenkonto', + ['not_enough_money'] = 'du hast nicht genug Geld', + ['pop_vehicle'] = 'Fahrzeug holen', + ['depop_vehicle'] = 'Fahrzeug zurückholen', + ['create_bill'] = 'Rechnung erstellen', + ['get_rented_vehicles'] = 'Mietwagen', + ['set_vehicle_owner_sell'] = 'Fahrzeuge [Verkauf]', + ['set_vehicle_owner_rent'] = 'Fahrzeug zuweisen [Mieten]', + ['invoice_amount'] = 'Rechnungsbetrag', + ['invalid_amount'] = 'ungültiger Betrag', + ['no_players'] = 'keine Spieler in der Nähe', + ['rental_amount'] = 'Mietbetrag', + ['personal_vehicle'] = 'Persönliches Fahrzeug', + ['vehicle_dealer'] = 'Autohändler', + ['rent_vehicle'] = 'Autohändler - Fahrzeuge zum vermieten', + ['dealer_boss'] = 'Autohändler - Boss', + ['buy_vehicle'] = 'Fahrzeug kaufen', + ['withdraw_money'] = 'Firmengeld abheben', + ['deposit_money'] = 'Geld einzahlen', + ['wash_money'] = 'Geld waschen', + ['withdraw_amount'] = 'Abhebebetrag', + ['deposit_amount'] = 'Einzahlbetrag', + ['bleach amount'] = 'Betrag zum waschen', + ['vehicle_menu'] = 'Drücke ~INPUT_CONTEXT~ um ein Fahrzeug zu übergeben', + ['sell_menu'] = 'Drücke ~INPUT_CONTEXT~ zum verkaufen ', + ['price'] = ' für den Betrag $', + ['delivered'] = 'Fahrzeug zum Händler ~g~gebracht~s~', + ['not_rental'] = 'dies ist kein ~r~Mietwagen~s~', + ['vehicle_sold'] = 'Fahrzeug ~g~verkauft~s~', + ['not_yours'] = 'dieses Fahrzeug gehört dir nicht', + ['vehicle'] = 'Fahrzeug ', + ['belongs'] = ' gehört jetzt dir', + ['leaving'] = 'verlasse persönnliches Fahrzeug', + ['paid_rental'] = 'du ~g~bezahlst~s~ für den Mietwagen : ~g~$', + ['recruit'] = 'Neuling', + ['experianced'] = 'erfahren', + ['the_boss'] = 'boss', +} From 18aab6e401e50fc4d3c15ba10cf886297a8d40f3 Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 11:19:25 +0200 Subject: [PATCH 0616/3224] Add German Language --- __resource.lua | 2 ++ de_esx_drugs.sql | 10 ++++++++++ locales/de.lua | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 de_esx_drugs.sql create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index 53c16c00..ac31d644 100644 --- a/__resource.lua +++ b/__resource.lua @@ -3,6 +3,7 @@ description 'esx_drugs' server_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', @@ -14,6 +15,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', diff --git a/de_esx_drugs.sql b/de_esx_drugs.sql new file mode 100644 index 00000000..5ffb3e66 --- /dev/null +++ b/de_esx_drugs.sql @@ -0,0 +1,10 @@ +INSERT INTO `items` (name, label) VALUES + ('weed', 'Grass'), + ('weed_pooch', 'Portion Grass'), + ('coke', 'Koks'), + ('coke_pooch', 'Portion Koks'), + ('meth', 'Meth'), + ('meth_pooch', 'Portion Meth'), + ('opium', 'Opium'), + ('opium_pooch', 'Portion Opium') +; \ No newline at end of file diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..4cbdbfe6 --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,36 @@ +Locales['de'] = { + + ['press_collect_coke'] = 'drücke ~INPUT_CONTEXT~ um Koks zu sammeln', + ['press_process_coke'] = 'drücke ~INPUT_CONTEXT~ um Koks zu verarbeiten', + ['press_sell_coke'] = 'drücke ~INPUT_CONTEXT~ um Koks zu verkaufen', + ['press_collect_meth'] = 'drücke ~INPUT_CONTEXT~ um Meth zu sammeln', + ['press_process_meth'] = 'drücke ~INPUT_CONTEXT~ um Meth zu verarbeiten', + ['press_sell_meth'] = 'drücke ~INPUT_CONTEXT~ um Meth zu verkaufen', + ['press_collect_weed'] = 'drücke ~INPUT_CONTEXT~ um Grass zu sammeln', + ['press_process_weed'] = 'drücke ~INPUT_CONTEXT~ um Grass zu verarbeiten', + ['press_sell_weed'] = 'drücke ~INPUT_CONTEXT~ um Grass zu verkaufen', + ['press_collect_opium'] = 'drücke ~INPUT_CONTEXT~ um Opium zu sammeln', + ['press_process_opium'] = 'drücke ~INPUT_CONTEXT~ um Opium zu verarbeiten', + ['press_sell_opium'] = 'drücke ~INPUT_CONTEXT~ um Opium zu verkaufen', + ['act_imp_police'] = 'aktion ~r~nihct möglich~s~, ~b~Polizisten~s~: ', + ['inv_full_coke'] = 'Du kannst nicht länger Koks sammeln, dein Inventar ist ~r~VOLL~s~', + ['pickup_in_prog'] = '~y~Sammeln im gange~s~...', + ['too_many_pouches'] = 'du hast zuviele Pakete', + ['not_enough_coke'] = 'du hast nicht genug Koks zum ~r~verpacken~s~', + ['packing_in_prog'] = '~y~Verarbeitung im gange~s~...', + ['no_pouchs_sale'] = 'Du hast nicht genug Portionen zum ~r~verkaufen~s~', + ['sold_one_coke'] = 'du verkaufst ~g~x1 Portion Koks~s~', + ['sale_in_prog'] = '~g~Verkauf im gange~s~...', + ['inv_full_meth'] = 'Du kannst nicht länger Meth sammeln, dein Inventar ist ~r~VOLL~s~', + ['not_enough_meth'] = 'du hast nicht genug Meth zum ~r~verpacken~s~', + ['sold_one_meth'] = 'du verkaufst ~g~x1 Portion Meth~s~', + ['inv_full_weed'] = 'Du kannst nicht länger Grass sammeln, dein Inventar ist ~r~VOLL~s~', + ['not_enough_weed'] = 'du hast nicht genug Grass zum ~r~verarbeiten~s~', + ['sold_one_weed'] = 'du verkaufst ~g~x1 Portion Grass~s~', + ['used_one_weed'] = 'du benutzt 1x ~b~Grass', + ['inv_full_opium'] = 'Du kannst nicht länger Opium sammeln, dein Inventar ist ~r~VOLL~s~', + ['not_enough_opium'] = 'du hast nicht genug Opium zum ~r~verarbeiten~s~', + ['sold_one_opium'] = 'du verkaufst ~g~x1 Portion Opium~s~', + ['used_one_opium'] = 'du benutzt 1x ~b~Opium', + +} \ No newline at end of file From 13b15c4282fbaee7ca06343b6c9315b215f10464 Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 11:22:05 +0200 Subject: [PATCH 0617/3224] Add German Language --- __resource.lua | 2 ++ locales/de.lua | 6 ++++++ 2 files changed, 8 insertions(+) create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index 698b69ec..f85400fa 100644 --- a/__resource.lua +++ b/__resource.lua @@ -4,6 +4,7 @@ description 'ESX Garage' server_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', @@ -14,6 +15,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..929d5eab --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,6 @@ +Locales['de'] = { + + ['veh_released'] = 'Fahrzeug ~g~genommen', + ['veh_stored'] = 'vehicle ~g~geparkt', + +} From 1090d0f663654f84a42de3a6bbcec6f8c19171ec Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 11:29:18 +0200 Subject: [PATCH 0618/3224] Add German Language --- de_config.lua | 78 +++++++++++++++++++++++++++++++ de_esx_policejob_full.sql | 82 ++++++++++++++++++++++++++++++++ de_esx_policejob_minimal.sql | 75 +++++++++++++++++++++++++++++ locales/de.lua | 91 ++++++++++++++++++++++++++++++++++++ 4 files changed, 326 insertions(+) create mode 100644 de_config.lua create mode 100644 de_esx_policejob_full.sql create mode 100644 de_esx_policejob_minimal.sql create mode 100644 locales/de.lua diff --git a/de_config.lua b/de_config.lua new file mode 100644 index 00000000..55ba5522 --- /dev/null +++ b/de_config.lua @@ -0,0 +1,78 @@ +Config = {} +Config.DrawDistance = 100.0 +Config.MarkerType = 1 +Config.MarkerSize = {x = 1.5, y = 1.5, z = 1.0} +Config.MarkerColor = {r = 50, g = 50, b = 204} +Config.EnablePlayerManagement = false +Config.EnableArmoryManagement = false +Config.MaxInService = -1 +Config.Locale = 'de' + +Config.PoliceStations = { + + LSPD = { + + Blip = { + Pos = {x = 425.130, y = -979.558, z = 30.711}, + Color = 29 + }, + + AuthorizedWeapons = { + {name = 'WEAPON_NIGHTSTICK', price = 200}, + {name = 'WEAPON_COMBATPISTOL', price = 300}, + {name = 'WEAPON_ASSAULTSMG', price = 1250}, + {name = 'WEAPON_ASSAULTRIFLE', price = 1500}, + {name = 'WEAPON_PUMPSHOTGUN', price = 600}, + {name = 'WEAPON_STUNGUN', price = 500}, + {name = 'WEAPON_FLASHLIGHT', price = 80}, + {name = 'WEAPON_FIREEXTINGUISHER', price = 120}, + {name = 'WEAPON_FLAREGUN', price = 60}, + {name = 'WEAPON_STICKYBOMB', price = 250}, + {name = 'GADGET_PARACHUTE', price = 300}, + }, + + AuthorizedVehicles = { + {name = 'police' , label = 'Streifenfahrzeug 1'}, + {name = 'police2', label = 'Streifenfahrzeug 2'}, + {name = 'police3', label = 'Streifenfahrzeug 3'}, + {name = 'police4', label = 'Zivilfahrzeug'}, + {name = 'policeb', label = 'Motorrad'}, + {name = 'policet', label = 'Transporter'}, + }, + + Cloakrooms = { + {x = 452.600, y = -993.306, z = 29.750} + }, + + Armories = { + {x = 451.699, y = -980.356, z = 29.689} + }, + + Vehicles = { + { + Spawner = {x = 454.69, y = -1017.4, z = 27.430}, + SpawnPoint = {x = 438.42, y = -1018.3, z = 27.757}, + Heading = 90.0 + } + }, + + Helicopters = { + { + Spawner = {x = 466.477, y = -982.819, z = 42.691}, + SpawnPoint = {x = 450.04, y = -981.14, z = 42.691}, + Heading = 0.0 + } + }, + + VehicleDeleters = { + {x = 462.74, y = -1014.4, z = 27.065}, + {x = 462.40, y = -1019.7, z = 27.104} + }, + + BossActions = { + {x = 448.417, y = -973.208, z = 29.689} + } + + } + +} \ No newline at end of file diff --git a/de_esx_policejob_full.sql b/de_esx_policejob_full.sql new file mode 100644 index 00000000..a13e74fe --- /dev/null +++ b/de_esx_policejob_full.sql @@ -0,0 +1,82 @@ +INSERT INTO `addon_account` (name, label, shared) VALUES + ('society_police','Polizei',1) +; + +INSERT INTO `datastore` (name, label, shared) VALUES + ('society_police','Polizei',1) +; + +INSERT INTO `jobs` (name, label) VALUES + ('police','LSPD') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('police',0,'recruit','Rekrut',20,'{\"tshirt_1\":57,\"torso_1\":55,\"arms\":0,\"pants_1\":35,\"glasses\":0,\"decals_2\":0,\"hair_color_2\":0,\"helmet_2\":0,\"hair_color_1\":5,\"face\":19,\"glasses_2\":1,\"torso_2\":0,\"shoes\":24,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"pants_2\":0,\"hair_2\":0,\"decals_1\":0,\"tshirt_2\":0,\"helmet_1\":8}','{\"tshirt_1\":34,\"torso_1\":48,\"shoes\":24,\"pants_1\":34,\"torso_2\":0,\"decals_2\":0,\"hair_color_2\":0,\"glasses\":0,\"helmet_2\":0,\"hair_2\":3,\"face\":21,\"decals_1\":0,\"glasses_2\":1,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"pants_2\":0,\"arms\":14,\"hair_color_1\":10,\"tshirt_2\":0,\"helmet_1\":57}'), + ('police',1,'sergeant','Sergent',40,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":1,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"arms\":0,\"decals_1\":8,\"torso_2\":0,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"hair_color_1\":5,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":14,\"pants_1\":34,\"pants_2\":0,\"decals_2\":1,\"hair_color_2\":0,\"shoes\":24,\"helmet_2\":0,\"hair_2\":3,\"decals_1\":7,\"torso_2\":0,\"face\":21,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"glasses_2\":1,\"hair_color_1\":10,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}'), + ('police',2,'lieutenant','Lieutenant',65,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":2,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"glasses\":0,\"decals_1\":8,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"torso_2\":0,\"arms\":41,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"hair_2\":3,\"decals_2\":2,\"hair_color_2\":0,\"hair_color_1\":10,\"helmet_2\":0,\"face\":21,\"shoes\":24,\"torso_2\":0,\"glasses_2\":1,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"pants_2\":0,\"decals_1\":7,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}'), + ('police',3,'boss','Commandant',80,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"arms\":41,\"torso_2\":0,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"decals_1\":8,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":21,\"helmet_2\":0,\"hair_2\":3,\"decals_1\":7,\"torso_2\":0,\"hair_color_1\":10,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"glasses_2\":1,\"shoes\":24,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}') +; + +CREATE TABLE `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`) +); + +INSERT INTO `fine_types` VALUES ('1', 'Missbrauchen der Hupe', '30', '0'); +INSERT INTO `fine_types` VALUES ('2', 'Vorfahrtstraße missachtet', '40', '0'); +INSERT INTO `fine_types` VALUES ('3', 'Gegenverkehr', '250', '0'); +INSERT INTO `fine_types` VALUES ('4', 'Unbefugtes Wenden', '250', '0'); +INSERT INTO `fine_types` VALUES ('5', 'Off-Road fahren', '170', '0'); +INSERT INTO `fine_types` VALUES ('6', 'Sicherheitsrichtlinien missachtet', '30', '0'); +INSERT INTO `fine_types` VALUES ('7', 'Gefährliches halten', '150', '0'); +INSERT INTO `fine_types` VALUES ('8', 'Nicht erlaubtes parken', '70', '0'); +INSERT INTO `fine_types` VALUES ('9', 'Nicht respektieren des Rechtsfahrgebotes', '70', '0'); +INSERT INTO `fine_types` VALUES ('10', 'Nicht einhaltender Priorität eines Rettungsfahrzeuges', '90', '0'); +INSERT INTO `fine_types` VALUES ('11', 'Nicht angehalten nach Aufforderung', '105', '0'); +INSERT INTO `fine_types` VALUES ('12', 'Bei Rot über die Ampel', '130', '0'); +INSERT INTO `fine_types` VALUES ('13', 'gefährliches Überholmanöver', '100', '0'); +INSERT INTO `fine_types` VALUES ('14', 'Fahrzeug nicht Verkehrstauglich', '100', '0'); +INSERT INTO `fine_types` VALUES ('15', 'Fahren ohne Lizenz', '1500', '0'); +INSERT INTO `fine_types` VALUES ('16', 'Hit and Run', '800', '0'); +INSERT INTO `fine_types` VALUES ('17', 'zu schnell < 5 kmh', '90', '0'); +INSERT INTO `fine_types` VALUES ('18', 'zu schnell 5-15 kmh', '120', '0'); +INSERT INTO `fine_types` VALUES ('19', 'zu schnell 15-30 kmh', '180', '0'); +INSERT INTO `fine_types` VALUES ('20', 'zu schnell > 30 kmh', '300', '0'); +INSERT INTO `fine_types` VALUES ('21', 'Verkehrsbehinderung', '110', '1'); +INSERT INTO `fine_types` VALUES ('22', 'Nicht Benutzung öffentlicher Straßen', '90', '1'); +INSERT INTO `fine_types` VALUES ('23', 'Störung der öffentlichen Ordnung', '90', '1'); +INSERT INTO `fine_types` VALUES ('24', 'Polizeieinsatz behindern', '130', '1'); +INSERT INTO `fine_types` VALUES ('25', 'Beildigung an Zivilist', '75', '1'); +INSERT INTO `fine_types` VALUES ('26', 'Polizist geringschätzen', '110', '1'); +INSERT INTO `fine_types` VALUES ('27', 'verbale Bedrohung an Zivilist', '90', '1'); +INSERT INTO `fine_types` VALUES ('28', 'verbale Bedrohung an Polizist', '150', '1'); +INSERT INTO `fine_types` VALUES ('29', 'Illegale Demonstration', '250', '1'); +INSERT INTO `fine_types` VALUES ('30', 'versuchte Bestechung', '1500', '1'); +INSERT INTO `fine_types` VALUES ('31', 'Mit Messer in der Stadt bewaffnet', '120', '2'); +INSERT INTO `fine_types` VALUES ('32', 'Mit tötlicher Waffe bewaffnet', '300', '2'); +INSERT INTO `fine_types` VALUES ('33', 'Unbefugter Besitz einer Waffe (Standard-Lizenz)', '600', '2'); +INSERT INTO `fine_types` VALUES ('34', 'Illegale Waffe', '700', '2'); +INSERT INTO `fine_types` VALUES ('35', 'Einbruch/Aufbruch', '300', '2'); +INSERT INTO `fine_types` VALUES ('36', 'Autodiebstahl', '1800', '2'); +INSERT INTO `fine_types` VALUES ('37', 'Drogenverkauf', '1500', '2'); +INSERT INTO `fine_types` VALUES ('38', 'Drogen herstellen', '1500', '2'); +INSERT INTO `fine_types` VALUES ('39', 'Drogenbesitz', '650', '2'); +INSERT INTO `fine_types` VALUES ('40', 'Zivile Geisel genommen', '1500', '2'); +INSERT INTO `fine_types` VALUES ('41', 'Geiselnahme', '2000', '2'); +INSERT INTO `fine_types` VALUES ('42', 'Waghalsiges Lenken', '650', '2'); +INSERT INTO `fine_types` VALUES ('43', 'Ladenraub', '650', '2'); +INSERT INTO `fine_types` VALUES ('44', 'Bankraub', '1500', '2'); +INSERT INTO `fine_types` VALUES ('45', 'Schießen auf Zivilisten', '2000', '3'); +INSERT INTO `fine_types` VALUES ('46', 'Schießen auf Beamten', '2500', '3'); +INSERT INTO `fine_types` VALUES ('47', 'versuchterMord an Zivilisten', '3000', '3'); +INSERT INTO `fine_types` VALUES ('48', 'versuchter Mord an einem Beamten', '5000', '3'); +INSERT INTO `fine_types` VALUES ('49', 'Mord an Zivilisten', '10000', '3'); +INSERT INTO `fine_types` VALUES ('50', 'Mord an Beamten', '30000', '3'); +INSERT INTO `fine_types` VALUES ('51', 'versehentlicher Mord', '1800', '3'); +INSERT INTO `fine_types` VALUES ('52', 'Firmenbetrug', '2000', '2'); +; \ No newline at end of file diff --git a/de_esx_policejob_minimal.sql b/de_esx_policejob_minimal.sql new file mode 100644 index 00000000..d0d67a2b --- /dev/null +++ b/de_esx_policejob_minimal.sql @@ -0,0 +1,75 @@ +INSERT INTO `jobs` (name, label) VALUES + ('police','LSPD') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('police',0,'recruit','Rekrut',20,'{\"tshirt_1\":57,\"torso_1\":55,\"arms\":0,\"pants_1\":35,\"glasses\":0,\"decals_2\":0,\"hair_color_2\":0,\"helmet_2\":0,\"hair_color_1\":5,\"face\":19,\"glasses_2\":1,\"torso_2\":0,\"shoes\":24,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"pants_2\":0,\"hair_2\":0,\"decals_1\":0,\"tshirt_2\":0,\"helmet_1\":8}','{\"tshirt_1\":34,\"torso_1\":48,\"shoes\":24,\"pants_1\":34,\"torso_2\":0,\"decals_2\":0,\"hair_color_2\":0,\"glasses\":0,\"helmet_2\":0,\"hair_2\":3,\"face\":21,\"decals_1\":0,\"glasses_2\":1,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"pants_2\":0,\"arms\":14,\"hair_color_1\":10,\"tshirt_2\":0,\"helmet_1\":57}'), + ('police',1,'sergeant','Sergent',40,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":1,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"arms\":0,\"decals_1\":8,\"torso_2\":0,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"hair_color_1\":5,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":14,\"pants_1\":34,\"pants_2\":0,\"decals_2\":1,\"hair_color_2\":0,\"shoes\":24,\"helmet_2\":0,\"hair_2\":3,\"decals_1\":7,\"torso_2\":0,\"face\":21,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"glasses_2\":1,\"hair_color_1\":10,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}'), + ('police',2,'lieutenant','Lieutenant',65,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":2,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"glasses\":0,\"decals_1\":8,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"torso_2\":0,\"arms\":41,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"hair_2\":3,\"decals_2\":2,\"hair_color_2\":0,\"hair_color_1\":10,\"helmet_2\":0,\"face\":21,\"shoes\":24,\"torso_2\":0,\"glasses_2\":1,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"pants_2\":0,\"decals_1\":7,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}'), + ('police',3,'boss','Commandant',80,'{\"tshirt_1\":58,\"torso_1\":55,\"shoes\":24,\"pants_1\":35,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":19,\"helmet_2\":0,\"hair_2\":0,\"arms\":41,\"torso_2\":0,\"hair_color_1\":5,\"hair_1\":2,\"skin\":34,\"sex\":0,\"glasses_1\":0,\"glasses_2\":1,\"decals_1\":8,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":11}','{\"tshirt_1\":35,\"torso_1\":48,\"arms\":44,\"pants_1\":34,\"pants_2\":0,\"decals_2\":3,\"hair_color_2\":0,\"face\":21,\"helmet_2\":0,\"hair_2\":3,\"decals_1\":7,\"torso_2\":0,\"hair_color_1\":10,\"hair_1\":11,\"skin\":34,\"sex\":1,\"glasses_1\":5,\"glasses_2\":1,\"shoes\":24,\"glasses\":0,\"tshirt_2\":0,\"helmet_1\":57}') +; + +CREATE TABLE `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`) +); + + +INSERT INTO `fine_types` VALUES ('1', 'Missbrauchen der Hupe', '30', '0'); +INSERT INTO `fine_types` VALUES ('2', 'Vorfahrtstraße missachtet', '40', '0'); +INSERT INTO `fine_types` VALUES ('3', 'Gegenverkehr', '250', '0'); +INSERT INTO `fine_types` VALUES ('4', 'Unbefugtes Wenden', '250', '0'); +INSERT INTO `fine_types` VALUES ('5', 'Off-Road fahren', '170', '0'); +INSERT INTO `fine_types` VALUES ('6', 'Sicherheitsrichtlinien missachtet', '30', '0'); +INSERT INTO `fine_types` VALUES ('7', 'Gefährliches halten', '150', '0'); +INSERT INTO `fine_types` VALUES ('8', 'Nicht erlaubtes parken', '70', '0'); +INSERT INTO `fine_types` VALUES ('9', 'Nicht respektieren des Rechtsfahrgebotes', '70', '0'); +INSERT INTO `fine_types` VALUES ('10', 'Nicht einhaltender Priorität eines Rettungsfahrzeuges', '90', '0'); +INSERT INTO `fine_types` VALUES ('11', 'Nicht angehalten nach Aufforderung', '105', '0'); +INSERT INTO `fine_types` VALUES ('12', 'Bei Rot über die Ampel', '130', '0'); +INSERT INTO `fine_types` VALUES ('13', 'gefährliches Überholmanöver', '100', '0'); +INSERT INTO `fine_types` VALUES ('14', 'Fahrzeug nicht Verkehrstauglich', '100', '0'); +INSERT INTO `fine_types` VALUES ('15', 'Fahren ohne Lizenz', '1500', '0'); +INSERT INTO `fine_types` VALUES ('16', 'Hit and Run', '800', '0'); +INSERT INTO `fine_types` VALUES ('17', 'zu schnell < 5 kmh', '90', '0'); +INSERT INTO `fine_types` VALUES ('18', 'zu schnell 5-15 kmh', '120', '0'); +INSERT INTO `fine_types` VALUES ('19', 'zu schnell 15-30 kmh', '180', '0'); +INSERT INTO `fine_types` VALUES ('20', 'zu schnell > 30 kmh', '300', '0'); +INSERT INTO `fine_types` VALUES ('21', 'Verkehrsbehinderung', '110', '1'); +INSERT INTO `fine_types` VALUES ('22', 'Nicht Benutzung öffentlicher Straßen', '90', '1'); +INSERT INTO `fine_types` VALUES ('23', 'Störung der öffentlichen Ordnung', '90', '1'); +INSERT INTO `fine_types` VALUES ('24', 'Polizeieinsatz behindern', '130', '1'); +INSERT INTO `fine_types` VALUES ('25', 'Beildigung an Zivilist', '75', '1'); +INSERT INTO `fine_types` VALUES ('26', 'Polizist geringschätzen', '110', '1'); +INSERT INTO `fine_types` VALUES ('27', 'verbale Bedrohung an Zivilist', '90', '1'); +INSERT INTO `fine_types` VALUES ('28', 'verbale Bedrohung an Polizist', '150', '1'); +INSERT INTO `fine_types` VALUES ('29', 'Illegale Demonstration', '250', '1'); +INSERT INTO `fine_types` VALUES ('30', 'versuchte Bestechung', '1500', '1'); +INSERT INTO `fine_types` VALUES ('31', 'Mit Messer in der Stadt bewaffnet', '120', '2'); +INSERT INTO `fine_types` VALUES ('32', 'Mit tötlicher Waffe bewaffnet', '300', '2'); +INSERT INTO `fine_types` VALUES ('33', 'Unbefugter Besitz einer Waffe (Standard-Lizenz)', '600', '2'); +INSERT INTO `fine_types` VALUES ('34', 'Illegale Waffe', '700', '2'); +INSERT INTO `fine_types` VALUES ('35', 'Einbruch/Aufbruch', '300', '2'); +INSERT INTO `fine_types` VALUES ('36', 'Autodiebstahl', '1800', '2'); +INSERT INTO `fine_types` VALUES ('37', 'Drogenverkauf', '1500', '2'); +INSERT INTO `fine_types` VALUES ('38', 'Drogen herstellen', '1500', '2'); +INSERT INTO `fine_types` VALUES ('39', 'Drogenbesitz', '650', '2'); +INSERT INTO `fine_types` VALUES ('40', 'Zivile Geisel genommen', '1500', '2'); +INSERT INTO `fine_types` VALUES ('41', 'Geiselnahme', '2000', '2'); +INSERT INTO `fine_types` VALUES ('42', 'Waghalsiges Lenken', '650', '2'); +INSERT INTO `fine_types` VALUES ('43', 'Ladenraub', '650', '2'); +INSERT INTO `fine_types` VALUES ('44', 'Bankraub', '1500', '2'); +INSERT INTO `fine_types` VALUES ('45', 'Schießen auf Zivilisten', '2000', '3'); +INSERT INTO `fine_types` VALUES ('46', 'Schießen auf Beamten', '2500', '3'); +INSERT INTO `fine_types` VALUES ('47', 'versuchterMord an Zivilisten', '3000', '3'); +INSERT INTO `fine_types` VALUES ('48', 'versuchter Mord an einem Beamten', '5000', '3'); +INSERT INTO `fine_types` VALUES ('49', 'Mord an Zivilisten', '10000', '3'); +INSERT INTO `fine_types` VALUES ('50', 'Mord an Beamten', '30000', '3'); +INSERT INTO `fine_types` VALUES ('51', 'versehentlicher Mord', '1800', '3'); +INSERT INTO `fine_types` VALUES ('52', 'Firmenbetrug', '2000', '2'); +; \ No newline at end of file diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..2a06348e --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,91 @@ +Locales['de'] = { + --Cloackroom + ['cloakroom'] = 'Garderobe', + ['citizen_wear'] = 'Zivilkleidung', + ['police_wear'] = 'Arbeitskleidung', + ['open_cloackroom'] = 'Drücke ~INPUT_CONTEXT~ um dich umzuziehen', + --Armory + ['get_weapon'] = 'Waffen holen', + ['put_weapon'] = 'Waffen bringen', + ['buy_weapons'] = 'Waffen kaufen', + ['armory'] = 'Waffenkammer', + ['open_armory'] = 'Drücke ~INPUT_CONTEXT~ um die Waffenkammer zu öffnen', + --Vehicles + ['vehicle_menu'] = 'Fahrzeug', + ['vehicle_out'] = 'es ist bereits ein Fahrzeug draussen', + ['vehicle_spawner'] = 'Drücke ~INPUT_CONTEXT~ um ein Fahrzeug zu holen', + ['store_vehicle'] = 'Drücke ~INPUT_CONTEXT~ um das Fahrzeug zu parken', + ['service_max'] = 'Max Polizisten im Dienst : ', + --Action Menu + ['citizen_interaction'] = 'Zivilistenaktionen', + ['vehicle_interaction'] = 'Fahrzeuginteraktionen', + ['object_spawner'] = 'Objekt Spawner', + + ['id_card'] = 'ID Karte', + ['search'] = 'Suche', + ['handcuff'] = 'Festnehmen / Freilassen', + ['put_in_vehicle'] = 'In Fahrzeug setzen', + ['fine'] = 'Strafe', + ['no_players_nearby'] = 'Keine Spieler in der Nähe', + + ['vehicle_info'] = 'Fahrzeug Info', + ['pick_lock'] = 'Fahrzeug öffnen', + ['vehicle_unlocked'] = 'Fahrzeug ~g~offen~s~', + ['no_vehicles_nearby'] = 'Keine Fahrzeuge in der Nähe', + ['traffic_interaction'] = 'Straßeninteraktionen', + ['cone'] = 'Hütchen', + ['barrier'] = 'Barriere', + ['spikestrips'] = 'Nagelband', + ['box'] = 'Box', + ['cash'] = 'Box mit Geld', + --ID Card Menu + ['name'] = 'name : ', + ['bac'] = 'bAC : ', + --Body Search Menu + ['confiscate_dirty'] = 'Schwarzgeld konfesziert : $', + ['guns_label'] = '--- Waffen ---', + ['confiscate'] = 'konfeszieren ', + ['inventory_label'] = '--- Inventar ---', + ['confiscate_inv'] = 'konfeziere x', + + ['traffic_offense'] = 'Verkehrs vergehen', + ['minor_offense'] = 'Geringes vergehen', + ['average_offense'] = 'Normales vergehen', + ['major_offense'] = 'Hohes vergehen', + ['fine_total'] = 'Strafe : ', + --Vehicle Info Menu + ['plate'] = 'Plate: ', + ['owner_unknown'] = 'Besitzer : Unbekannt', + ['owner'] = 'Besitzer : ', + --Weapons Menus + ['get_weapon_menu'] = 'Waffenkammer - Waffen nehmen', + ['put_weapon_menu'] = 'Waffenkammer - Waffen bringen', + ['buy_weapon_menu'] = 'Waffenkammer - Waffen kaufen', + ['not_enough_money'] = 'Du hast nicht genug Geld', + --Boss Menu + ['take_company_money'] = 'Firmengeld abheben', + ['deposit_money'] = 'Geld einzahlen', + ['amount_of_withdrawal'] = 'Betrag zum abheben', + ['invalid_amount'] = 'ungültiger Betrag', + ['amount_of_deposit'] = 'Betrag zum einzahlen', + ['open_bossmenu'] = 'Drücke ~INPUT_CONTEXT~ um das Menü zu öffnen', + --Misc + ['remove_object'] = 'Drücke ~INPUT_CONTEXT~ um das Objekt zu entfernen', + ['map_blip'] = 'Polizeistation', + --Notifications + ['from'] = '~s~ von ~b~', + ['you_have_confinv'] = 'du hast ~y~x konfesziert', + ['confinv'] = '~s~ hat von dir ~y~x konfesziert', + ['you_have_confdm'] = 'du hast ~y~$ konfesziert', + ['confdm'] = '~s~ hat von dir ~y~$ konfesziert', + ['you_have_confweapon'] = 'du hast ~y~x1 konfesziert', + ['confweapon'] = '~s~ hat von dir ~y~x1 konfesziert', + ['alert_police'] = 'Polizei alamieren', + --Authorized Vehicles + ['police'] = 'Streifenfahrzeug 1', + ['police2'] = 'Streifenfahrzeug 2', + ['police3'] = 'Streifenfahrzeug 3', + ['police4'] = 'Zivilfahrzeug', + ['policeb'] = 'Motorrad', + ['policet'] = 'Transporter', +} \ No newline at end of file From 9ed46165f5e18ec06031bec68c10e335f8d7e624 Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 11:31:41 +0200 Subject: [PATCH 0619/3224] Add German Language --- __resource.lua | 2 ++ locales/de.lua | 7 +++++++ 2 files changed, 9 insertions(+) create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index 4c7f041d..afa1e3f5 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,6 +2,7 @@ server_scripts { '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', 'config.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', @@ -11,6 +12,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', 'config.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..19032e2f --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,7 @@ +Locales['de'] = { + + ['new_job'] = 'Du hast einen neuen Job!', + ['access_job_center'] = 'Drücke ~INPUT_PICKUP~ um das ~b~Arbeitsamt~s~ zu öffnen.', + ['job_center'] = 'Arbeitsamt', + +} From 773094631484b9d8f664ba54a35a009b700c0c17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 26 Aug 2017 11:37:19 +0200 Subject: [PATCH 0620/3224] Enable moving down-top and top-down in menu --- html/js/app.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/html/js/app.js b/html/js/app.js index 2ca0f6de..36fdb28f 100644 --- a/html/js/app.js +++ b/html/js/app.js @@ -209,6 +209,8 @@ if(pos > 0) ESX_MENU.pos[focused.namespace][focused.name]--; + else + ESX_MENU.pos[focused.namespace][focused.name] = menu.elements.length - 1; let elem = menu.elements[ESX_MENU.pos[focused.namespace][focused.name]]; @@ -237,6 +239,8 @@ if(pos < length - 1) ESX_MENU.pos[focused.namespace][focused.name]++; + else + ESX_MENU.pos[focused.namespace][focused.name] = 0; let elem = menu.elements[ESX_MENU.pos[focused.namespace][focused.name]]; From 99125452b44052bad1aa8653566d51b12163adcf Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 11:38:36 +0200 Subject: [PATCH 0621/3224] Add German Language --- __resource.lua | 2 ++ de_esx_ambulancejob_full.sql | 16 ++++++++++++ de_esx_ambulancejob_minimal.sql | 12 +++++++++ locales/de.lua | 46 +++++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+) create mode 100644 de_esx_ambulancejob_full.sql create mode 100644 de_esx_ambulancejob_minimal.sql create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index 1a7000ed..9a9710d6 100644 --- a/__resource.lua +++ b/__resource.lua @@ -5,6 +5,7 @@ description 'ESX Ambulance Job' server_scripts { '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', @@ -14,6 +15,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', diff --git a/de_esx_ambulancejob_full.sql b/de_esx_ambulancejob_full.sql new file mode 100644 index 00000000..cd81e976 --- /dev/null +++ b/de_esx_ambulancejob_full.sql @@ -0,0 +1,16 @@ +USE `essentialmode`; + +INSERT INTO `addon_account` (name, label, shared) VALUES + ('society_ambulance', 'Notdienst', 1) +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('ambulance',0,'ambulance','Sanitäter',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}'), + ('ambulance',1,'doctor','Arzt',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}'), + ('ambulance',2,'chief_doctor','Chefarzt',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}'), + ('ambulance',3,'boss','Chirurg',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}') +; + +INSERT INTO `jobs` (name, label) VALUES + ('ambulance','Notdienst') +; diff --git a/de_esx_ambulancejob_minimal.sql b/de_esx_ambulancejob_minimal.sql new file mode 100644 index 00000000..04e27ffc --- /dev/null +++ b/de_esx_ambulancejob_minimal.sql @@ -0,0 +1,12 @@ +USE `essentialmode`; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('ambulance',0,'ambulance','Sanitäter',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}'), + ('ambulance',1,'doctor','Arzt',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}'), + ('ambulance',2,'chief_doctor','Chefarzt',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}'), + ('ambulance',3,'boss','Chirurg',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}') +; + +INSERT INTO `jobs` (name, label) VALUES + ('ambulance','Notdienst') +; diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..41a263cc --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,46 @@ +Locales['de'] = { + --Cloakroom + ['cloakroom'] = 'Umkleide', + ['ems_clothes_civil'] = 'Zivilkleidung', + ['ems_clothes_ems'] = 'Arbeitskleidung', + --Vehicles + ['veh_menu'] = 'Fahrzeuge', + ['veh_spawn'] = 'Drücke ~INPUT_CONTEXT~ um ein Fahrzeug zu bekommen', + ['store_veh'] = 'Drücke ~INPUT_CONTEXT~ um das Fahrzeug zu parken', + ['ambulance'] = 'Krankenwagen', + ['helicopter'] = 'Helicopter', + --Action Menu + ['hospital'] = 'Krankenhaus', + ['revive_inprogress'] = 'wiederbeleben im Gange', + ['revive_complete'] = 'du wurdest wiederbelebt ', + ['no_players'] = 'keine Spieler in der Nähe', + ['no_vehicles'] = 'keine Fahrzeuge in der Nähe', + ['isdead'] = 'ist gestorben', + ['unconscious'] = 'ist nicht im Koma', + --Boss Menu + ['deposit_society'] = 'Notdienst einzahlen', + ['withdraw_society'] = 'Notdienst abheben', + --Misc + ['invalid_amount'] = '~r~ungültiger Betrag', + ['open_menu'] = 'Drücke ~INPUT_CONTEXT~ um das Menü zu öffnen', + ['deposit_amount'] = 'Betrag zum einzahlen', + ['money_withdraw'] = 'Betrag zum abheben', + -- F6 Menu + ['ems_menu'] = 'Notdienst - Menü', + ['ems_menu_title'] = 'Notdienst - Menü', + ['ems_menu_revive'] = 'Spieler wiederbeleben', + ['ems_menu_putincar'] = 'in Fahrzeug setzen', + -- Phone + ['alert_ambulance'] = 'Notdienst anrufen', + -- Death + ['respawn_at_hospital'] = 'Willst du ins Krankenhaus gebracht werden?', + ['yes'] = 'ja', + ['please_wait'] = 'bitte warte ~b~', + ['minutes'] = ' minuten ', + ['seconds_fine'] = ' sekunden ~w~zum respawnen\nRespawn jetzt für ~g~$', + ['seconds'] = ' sekunden ~w~bis zum respawn.', + ['press_respawn_fine'] = '~w~ [Drücke ~b~E~w~]', + ['press_respawn'] = 'Drücke [~b~E~w~] zum respawnen.', + -- Revive + ['revive_help'] = 'Spieler wiederbeleben', +} From 26c2a684b2ad8ad16ad9b290b0cbe75dae284ad7 Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 12:16:45 +0200 Subject: [PATCH 0622/3224] Add German Language --- __resource.lua | 2 ++ locales/de.lua | 9 +++++++++ 2 files changed, 11 insertions(+) create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index def8a634..c38cbe63 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,6 +2,7 @@ description 'ESX Shops' client_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', @@ -11,6 +12,7 @@ client_scripts { server_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..c34fd81c --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,9 @@ +Locales['de'] = { + + ['shop'] = 'Geschäft', + ['shops'] = 'Geschäfte', + ['press_menu'] = 'Drücke ~INPUT_CONTEXT~ um auf das Geschäft zuzugreifen.', + ['bought'] = 'du kaufst ~b~1x ', + ['not_enough'] = 'du ~r~hast nicht~s~ genug Geld.' + +} From 7b2e5ea87cae33b33fc02d87a58d77144e382ad6 Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 12:21:28 +0200 Subject: [PATCH 0623/3224] Add German Language --- __resource.lua | 2 ++ de_esx_realestateagentjob.sql | 16 ++++++++++++++++ esx_realestateagentjob.sql | 12 ++++++------ locales/de.lua | 23 +++++++++++++++++++++++ 4 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 de_esx_realestateagentjob.sql create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index 37b6b8ba..6d127e77 100644 --- a/__resource.lua +++ b/__resource.lua @@ -4,6 +4,7 @@ description 'ESX RealestateAgentJob' server_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', @@ -14,6 +15,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', diff --git a/de_esx_realestateagentjob.sql b/de_esx_realestateagentjob.sql new file mode 100644 index 00000000..0b6de025 --- /dev/null +++ b/de_esx_realestateagentjob.sql @@ -0,0 +1,16 @@ +USE `essentialmode`; + +INSERT INTO `addon_account` (name, label, shared) VALUES + ('society_realestateagent','Immobilienverkauf',1) +; + +INSERT INTO `jobs` (name, label) VALUES + ('realestateagent','Immobilienverkauf') +; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('realestateagent',0,'location','Vermieter',10,'{}','{}'), + ('realestateagent',1,'vendeur','Verkäufer',25,'{}','{}'), + ('realestateagent',2,'gestion','Manager',40,'{}','{}'), + ('realestateagent',3,'boss','Boss',0,'{}','{}') +; diff --git a/esx_realestateagentjob.sql b/esx_realestateagentjob.sql index 947ff9bc..0b6de025 100644 --- a/esx_realestateagentjob.sql +++ b/esx_realestateagentjob.sql @@ -1,16 +1,16 @@ USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES - ('society_realestateagent','Agent Immobilier',1) + ('society_realestateagent','Immobilienverkauf',1) ; INSERT INTO `jobs` (name, label) VALUES - ('realestateagent','Agent immobilier') + ('realestateagent','Immobilienverkauf') ; INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES - ('realestateagent',0,'location','Location',10,'{}','{}'), - ('realestateagent',1,'vendeur','Vendeur',25,'{}','{}'), - ('realestateagent',2,'gestion','Gestion',40,'{}','{}'), - ('realestateagent',3,'boss','Patron',0,'{}','{}') + ('realestateagent',0,'location','Vermieter',10,'{}','{}'), + ('realestateagent',1,'vendeur','Verkäufer',25,'{}','{}'), + ('realestateagent',2,'gestion','Manager',40,'{}','{}'), + ('realestateagent',3,'boss','Boss',0,'{}','{}') ; diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..2614f948 --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,23 @@ +Locales['en'] = { + + ['properties'] = 'Immobilien', + ['property'] = 'Immobilie', + ['clients'] = 'Kunden', + ['remove_comp_money'] = 'Firmengeld abheben', + ['dep_money'] = 'Geld einzahlen', + ['wash_money'] = 'Geld waschen', + ['realtor'] = 'Makler', + ['amount_withdraw'] = 'Betrag zun abheben', + ['invalid_amount'] = 'ungültiger Betrag', + ['amount_deposit'] = 'Betrag zum einzahlen', + ['amount_launder'] = 'Betrag zum waschen', + ['press_to_access'] = 'Drücke ~INPUT_CONTEXT~ um das Menü zu öffnen', + ['property_actions'] = '{{Zuweisen [Verkaufen]|sell}} {{Zuweisen [Vermieten]|rent}} {{GPS|gps}}', + ['amount'] = 'Betrag', + ['no_play_near'] = 'Kein Spieler in der Nähe', + ['contract'] = '{{Revoke contract|revoke}} {{GPS|gps}}', + ['rent'] = 'Mieten', + ['sell'] = 'Verkaufen', + ['realtors'] = 'Makler', + +} \ No newline at end of file From bc8d30e6586ca817c19b2dd790442e32e11f5f13 Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 12:25:12 +0200 Subject: [PATCH 0624/3224] Add German Language --- __resource.lua | 4 ++++ locales/de.lua | 13 +++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index 4f737ba0..5eb22590 100644 --- a/__resource.lua +++ b/__resource.lua @@ -6,6 +6,8 @@ server_scripts { '@mysql-async/lib/MySQL.lua', 'config.lua', '@es_extended/locale.lua', + 'locales/de.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'server/main.lua' @@ -14,6 +16,8 @@ server_scripts { client_scripts { '@es_extended/locale.lua', 'config.lua', + 'locales/de.lua', + 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', 'client/main.lua' diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..e69dae2e --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,13 @@ +Locales['de'] = { + + ['new_message'] = '~b~Neue Nachricht', + ['press_take_call'] = ' - Drücke ~INPUT_CONTEXT~ um den Anruf anzunehmen', + ['taken_call'] = ' hat den Anruf angenommen', + ['gps_position'] = 'Ziel in GPS eingegeben', + ['message_sent'] = 'nachricht gesendet', + ['cannot_add_self'] = 'du kannst dich nicht selbst hinzufügen', + ['number_in_contacts'] = 'diese Nummer ist bereits in deinen Kontakten', + ['contact_added'] = 'Kontakt hinzugefügt', + ['number_not_assigned'] = 'diese Nummer ist nicht vergeben...', + +} From 32ae7a000ba572fcc38ecf17d926c7e851eb5759 Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 12:27:59 +0200 Subject: [PATCH 0625/3224] Add German ui.html --- html/ui_de.html | 82 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 html/ui_de.html diff --git a/html/ui_de.html b/html/ui_de.html new file mode 100644 index 00000000..55d92593 --- /dev/null +++ b/html/ui_de.html @@ -0,0 +1,82 @@ + + + + + + + + +
    + +
    + +
    + + #123456 +
    + + + +
    + +
    Kontakte
    +
    +
    +
    +

    Keine Kontakte

    +
    +
    +
    +
    + +
    +
    Nachrichten
    +
    +
    +
    +

    Keine Nachrichten

    +
    +
    +
    +
    + +
    +
    +
    +
    + + + + + +
    +
    +
    + +
    +
    Kontakt hinzufügen
    +
    +
    + + + + +
    +
    +
    + +
    +
    + + + + + + + + From 39ae3e9d01cdfd3506c2114580c8b5138ea8bce9 Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 12:31:40 +0200 Subject: [PATCH 0626/3224] Add German Language --- __resource.lua | 2 ++ locales/de.lua | 9 +++++++++ 2 files changed, 11 insertions(+) create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index bfc3d345..543399a8 100644 --- a/__resource.lua +++ b/__resource.lua @@ -5,6 +5,7 @@ description 'ESX Billing' server_scripts { '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', @@ -14,6 +15,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..f1c54612 --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,9 @@ +Locales['de'] = { + + ['invoices'] = 'Rechnungen', + ['received_invoice'] = 'you hast eine Rechnung ~r~erhlaten~s~', + ['paid_invoice'] = 'du ~g~bezahlst~s~ eine Rechnung von ~r~$', + ['received_payment'] = 'du ~g~erhältst~s~ eine Zahlung von ~r~$', + ['player_not_logged'] = 'der Spieler ist nicht online', + +} From bcfb6c2adbd6624269ef889d1b768a6af3555a00 Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 12:33:40 +0200 Subject: [PATCH 0627/3224] Add German app_de.js --- html/scripts/app_de.js | 489 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 489 insertions(+) create mode 100644 html/scripts/app_de.js diff --git a/html/scripts/app_de.js b/html/scripts/app_de.js new file mode 100644 index 00000000..bdc0e71f --- /dev/null +++ b/html/scripts/app_de.js @@ -0,0 +1,489 @@ +(function(){ + + let ContactTpl = + '
    ' + + '
    ' + + '
    ' + + '{{sender}}
    #{{phoneNumber}}' + + '
    ' + + '
    ' + + '
    ' + + '
    ' + ; + + let MessageTpl = + '
    ' + + '
    ' + + '
    ' + + '{{sender}}
    #{{phoneNumber}}' + + '
    ' + + '
    ' + + '
    {{message}}
    ' + + '
    ' + + '
    ' + ; + + let SpecialContactTpl = '
  • {{name}}
  • '; + + let contacts = []; + let specialContacts = []; + let menu = []; + let currentItem = 0; + let currentVal = null; + let isMessageEditorOpen = false; + let isMessagesOpen = false; + let isPhoneShowed = false; + + let showMain = function() { + $('.screen').removeClass('active'); + } + + let showRepertoire = function() { + $('#repertoire').addClass('active'); + } + + let hideRepertoire = function() { + $('#repertoire').removeClass('active'); + } + + let showMessages = function(){ + $('#messages').addClass('active'); + isMessagesOpen = true; + } + + let hideMessages = function(){ + $('#messages').removeClass('active'); + isMessagesOpen = false; + } + + let showAddContact = function() { + $('#contact').addClass('active'); + } + + let hideAddContact = function() { + $('#contact').removeClass('active'); + $('#contact_name').val(''); + $('#contact_number').val(''); + } + + let showNewMessage = function(cnum, cname) { + $('#writer').addClass('active'); + $('#writer_number').val(cnum); + $('#writer .header-title').html(cname); + } + + let hideNewMessage = function() { + $('#writer').removeClass('active'); + $('#writer_number').val(''); + $('#writer_message').val(''); + $('#writer .header-title').html(''); + } + + let showGPS = function(xPos, yPos) { + $.post('http://esx_phone/setGPS', JSON.stringify({ + x: parseFloat(xPos), + y: parseFloat(yPos) + } + )); + } + + let renderContacts = function(){ + + let contactHTML = ''; + + if(contacts.length > 0) { + + for(let i=0; i 0) { + + for(let i=0; i { + return a.name.localeCompare(b.name); + }); + + renderSpecialContacts(); + + } + + } + + let removeSpecialContact = function(number){ + + for(let i=0; iKontakte' + + '
  • Nachrichten
  • ' + ); + + for(let i=0; i Date: Sat, 26 Aug 2017 12:36:15 +0200 Subject: [PATCH 0628/3224] Add German Language --- __resource.lua | 2 ++ de_esx_basicneeds.sql | 6 ++++++ locales/de.lua | 6 ++++++ 3 files changed, 14 insertions(+) create mode 100644 de_esx_basicneeds.sql create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index f0e0b5b1..fa44d3e9 100644 --- a/__resource.lua +++ b/__resource.lua @@ -4,6 +4,7 @@ description 'ESX Basic Needs' server_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', @@ -13,6 +14,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', diff --git a/de_esx_basicneeds.sql b/de_esx_basicneeds.sql new file mode 100644 index 00000000..2863dde8 --- /dev/null +++ b/de_esx_basicneeds.sql @@ -0,0 +1,6 @@ +USE `essentialmode`; + +INSERT INTO `items` (name, label) VALUES + ('bread', 'Brot'), + ('water', 'Wasser') +; diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..9ee67348 --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,6 @@ +Locales['de'] = { + + ['used_bread'] = 'Du hast 1x Brot gegessen', + ['used_water'] = 'Du hast 1x Wasser getrunken', + +} From 87743aa5a279b4c26ecca93ef486644f77ec5d11 Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 12:40:40 +0200 Subject: [PATCH 0629/3224] Add German Language --- __resource.lua | 2 + locales/de.lua | 182 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 184 insertions(+) create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index 58616817..88f56ca1 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,5 +1,6 @@ server_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', @@ -8,6 +9,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..75567f0b --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,182 @@ +Locales['de'] = { + + ['by_default'] = 'default', + ['installed'] = 'installiert', + ['already_own'] = 'du besitzt bereits: ~b~', + ['not_enough_money'] = 'du hast nicht genug Geld!', + ['purchased'] = 'gekauft!', + ['press_custom'] = 'Drücke ~INPUT_PICKUP~ um dein Fahrzeug zu modifizieren.', +-- Paint Colors + -- Black + ['black'] = 'black', + ['graphite'] = 'graphite', + ['black_metallic'] = 'black Metallic', + ['caststeel'] = 'cast Steel', + ['black_anth'] = 'black Anthracite', + ['matteblack'] = 'matte Black', + ['darknight'] = 'dark Night', + ['deepblack'] = 'deep Black', + ['oil'] = 'oil', + ['carbon'] = 'carbon', + -- White + ['white'] = 'white', + ['vanilla'] = 'vanilla', + ['creme'] = 'creme', + ['polarwhite'] = 'polar White', + ['beige'] = 'beige', + ['mattewhite'] = 'matte White', + ['snow'] = 'snow', + ['cotton'] = 'cotton', + ['alabaster'] = 'alabaster', + ['purewhite'] = 'pure White', + -- Grey + ['grey'] = 'grey', + ['silver'] = 'silver', + ['metallicgrey'] = 'metallic Grey', + ['laminatedsteel'] = 'laminated Steel', + ['darkgray'] = 'dark Grey', + ['rockygray'] = 'rocky Grey', + ['graynight'] = 'gray Night', + ['aluminum'] = 'aluminum', + ['graymat'] = 'matte Grey', + ['lightgrey'] = 'light Grey', + ['asphaltgray'] = 'asphalt Grey', + ['grayconcrete'] = 'concrete Grey', + ['darksilver'] = 'dark Silver', + ['magnesite'] = 'magnesite', + ['nickel'] = 'nickel', + ['zinc'] = 'zinc', + ['dolomite'] = 'dolomite', + ['bluesilver'] = 'blue Silver', + ['titanium'] = 'titanium', + ['steelblue'] = 'steel Blue', + ['champagne'] = 'champagne', + ['grayhunter'] = 'grey Hunter', + -- Red + ['red'] = 'red', + -- Pink + ['pink'] = 'pink', + ['electricpink'] = 'electric Pink', + ['brightpink'] = 'bright Pink', + ['salmon'] = 'salmon', + ['sugarplum'] = 'sugar Plum', + -- Blue + ['blue'] = 'blue', + -- Yellow + ['yellow'] = 'yellow', + ['wheat'] = 'wheat', + ['raceyellow'] = 'race Yellow', + ['paleyellow'] = 'pale Yellow', + ['lightyellow'] = 'light Yellow', + -- Green + ['green'] = 'green', + -- Orange + ['orange'] = 'orange', + ['tangerine'] = 'Tangerine', + ['matteorange'] = 'Matte Orange', + ['lightorange'] = 'Light Orange', + ['peach'] = 'Peach', + ['pumpkin'] = 'Pumpkin', + ['orangelambo'] = 'Orange Lambo', + -- Brown + ['brown'] = 'brown', + ['copper'] = 'Copper', + ['lightbrown'] = 'Light Brown', + ['darkbrown'] = 'Dark Brown', + ['bronze'] = 'Bronze', + ['brownmetallic'] = 'Brown Metallic', + ['espresso'] = 'Espresso', + ['chocolate'] = 'Chocolate', + ['terracotta'] = 'Terracotta', + ['marble'] = 'Marble', + ['sand'] = 'Sand', + ['sepia'] = 'Sepia', + ['bison'] = 'Bison', + ['palm'] = 'Palm', + ['caramel'] = 'Caramel', + ['rust'] = 'Rust', + ['chestnut'] = 'Chestnut', + ['hazelnut'] = 'Hazelnut', + ['shell'] = 'Shell', + ['mahogany'] = 'Mahogany', + ['cauldron'] = 'Cauldron', + ['blond'] = 'Blond', + ['gravel'] = 'Gravel', + ['darkearth'] = 'Dark Earth', + ['desert'] = 'Desert', + -- Purple + ['purple'] = 'purple', + ['indigo'] = 'Indigo', + ['deeppurple'] = 'Deep Purple', + ['darkviolet'] = 'Dark Violet', + ['amethyst'] = 'Amethyst', + ['mysticalviolet'] = 'Mystic Violet', + ['purplemetallic'] = 'Purple Metallic', + ['matteviolet'] = 'Matte Violet', + ['mattedeeppurple'] = 'Matte Deep Purple', + -- Chrome + ['chrome'] = 'chrome', + ['brushedchrome'] = 'brushed Chrome', + ['blackchrome'] = 'black Chrome', + ['brushedaluminum'] = 'brushed Aluminum', + -- Metal + ['gold'] = 'gold', + ['puregold'] = 'pure Gold', + ['brushedgold'] = 'brushed Gold', + ['lightgold'] = 'light Gold', +-- License Plates + ['blue_on_white_1'] = 'blue on white 1', + ['yellow_on_black'] = 'yellow on black', + ['yellow_blue'] = 'yellow on blue', + ['blue_on_white_2'] = 'blue on white 2', + ['blue_on_white_3'] = 'blue on white 3', +-- Upgrades + ['upgrades'] = 'upgrades', + ['engine'] = 'engine', + ['brakes'] = 'brakes', + ['transmission'] = 'transmission', + ['suspension'] = 'suspension', + ['armor'] = 'armor', + ['turbo'] = 'turbo', +-- Cosmetics + ['cosmetics'] = 'cosmetics', + -- Body Parts + ['bodyparts'] = 'body Parts', + ['leftfender'] = 'left fender', + ['rightfender'] = 'right fender', + ['spoilers'] = 'spoilers', + ['sideskirt'] = 'side skirts', + ['frame'] = 'cage', + ['hood'] = 'hood', + ['grille'] = 'grille', + ['rearbumper'] = 'rear bumper', + ['frontbumper'] = 'front bumper', + ['exhaust'] = 'exhaust', + ['roof'] = 'roof', + -- Paint + ['respray'] = 'respray', + ['primary'] = 'primary', + ['secondary'] = 'secondary', + ['pearlescent'] = 'pearlescent', + -- Misc + ['headlights'] = 'headlights', + ['licenseplates'] = 'license Plate', + ['windowtint'] = 'window Tint', + ['horns'] = 'horns', + -- Neon + ['neons'] = 'neons', + -- Wheels + ['wheels'] = 'wheels', + ['tiresmoke'] = 'tire smoke', + ['wheel_type'] = 'wheel type', + ['wheel_color'] = 'wheel color', + ['sport'] = 'sport', + ['muscle'] = 'muscle', + ['lowrider'] = 'lowrider', + ['suv'] = 'sUV', + ['allterrain'] = 'all terrain', + ['tuning'] = 'tuning', + ['motorcycle'] = 'motorcycle', + ['highend'] = 'high end', + +} From 081e07887b27dbb5de5dc8cee8e8ee668f001921 Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 12:43:20 +0200 Subject: [PATCH 0630/3224] Add German Language --- __resource.lua | 2 ++ html/ui_de.html | 28 ++++++++++++++++++++++++++++ locales/de.lua | 6 ++++++ 3 files changed, 36 insertions(+) create mode 100644 html/ui_de.html create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index 43e598eb..bf960960 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,5 +1,6 @@ server_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', @@ -9,6 +10,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', diff --git a/html/ui_de.html b/html/ui_de.html new file mode 100644 index 00000000..9057d83e --- /dev/null +++ b/html/ui_de.html @@ -0,0 +1,28 @@ + + + + + + + + +
    + +
    + + + + + + + \ No newline at end of file diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..bc70b179 --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,6 @@ +Locales['de'] = { + ['invalid_amount'] = '~r~ungültiger Betrag', + ['deposit_money'] = 'eingezahlt ~g~$', + ['withdraw_money'] = 'abgehoben ~g~$', + ['press_e_atm'] = 'Drücke ~INPUT_PICKUP~ um auf den ~g~ATM~s~ zuzugreifen.', +} From 56b341aa032e58746ea068aa1108e56f6cc258ef Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 12:48:43 +0200 Subject: [PATCH 0631/3224] Add German Language --- __resource.lua | 2 ++ locales/de.lua | 12 ++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index afef484e..79524ba4 100644 --- a/__resource.lua +++ b/__resource.lua @@ -5,6 +5,7 @@ description 'ESX ClotheShop' server_scripts { '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', + 'locales/de.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', @@ -13,6 +14,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..700a986b --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,12 @@ +Locales['de'] = { + + ['valid_this_purchase'] = 'Einkauf bestätigen?', + ['yes'] = 'ja', + ['no'] = 'nein', + ['name_outfit'] = 'Name des Outfits?', + ['not_enough_money'] = 'du hast nicht genug Geld', + ['press_menu'] = 'Drücke ~INPUT_CONTEXT~ um das Menü zu öffnen', + ['clothes'] = 'Kleidung', + ['you_paid'] = 'du bezahlst $', + +} From 017a2d8733d5ae09218bbc02ffdd88e72cae9f63 Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 12:50:44 +0200 Subject: [PATCH 0632/3224] Add German Language --- __resource.lua | 2 ++ locales/de.lua | 10 ++++++++++ 2 files changed, 12 insertions(+) create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index a04ea924..32ac26c4 100644 --- a/__resource.lua +++ b/__resource.lua @@ -4,6 +4,7 @@ description 'ESX BarberShop' server_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/en.lua', 'locales/fr.lua', '@mysql-async/lib/MySQL.lua', @@ -13,6 +14,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..e5c26ff2 --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,10 @@ +Locales['de'] = { + + ['valid_purchase'] = 'Einkauf bestätigen?', + ['yes'] = 'ja', + ['no'] = 'nein', + ['not_enough_money'] = 'du hast nicht genug Geld', + ['press_access'] = 'Drücke ~INPUT_CONTEXT~ um das Menü zu öffnen', + ['barber_blip'] = 'Friseur', + ['you_paid'] = 'du bezahlst ', +} \ No newline at end of file From cca9c70de6fbfd18109c1b22898f32f6d930e34b Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 12:55:32 +0200 Subject: [PATCH 0633/3224] Add German Language --- __resource.lua | 2 ++ locales/de.lua | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index 87810e29..1eb7a203 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,6 +2,7 @@ dependency 'essentialmode' client_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', @@ -11,6 +12,7 @@ client_scripts { server_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..900f6d53 --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,23 @@ +Locales['de'] = { + + ['robbery_cancelled'] = 'der Raub wurde abgebrochen, du bekommst nichts!', + ['robbery_successful'] = 'Raub erfolgreich du erbeutest ~g~$', + ['shop_robbery'] = 'Ladenraub', + ['press_to_rob'] = 'Drücke ~INPUT_CONTEXT~ zum ausrauben ~b~', + ['robbery_of'] = 'Ladenraub: ~r~', + ['seconds_remaining'] = '~w~ sekunden übrig', + ['robbery_cancelled_at'] = '~r~ Raub abgebrochen bei: ~b~', + ['robbery_has_cancelled'] = '~r~ Raub wurde abgebrochen: ~b~', + ['already_robbed'] = 'dieser Laden wurde bereits ausgeraubt. Bitte warte: ', + ['seconds'] = 'sekunden.', + ['rob_in_prog'] = '~r~ Raub im gange bei: ~b~', + ['started_to_rob'] = 'du hast einen Raub gestartet ', + ['do_not_move'] = ', laufe nicht weg!', + ['alarm_triggered'] = 'der Alarm wurde ausgelöst', + ['hold_pos'] = 'halte 5 Minuten lang durch, und die Beute gehört dir!', + ['robbery_complete'] = '~r~ Raub erfolgreich.~s~ ~h~ LAUF!', + ['robbery_complete_at'] = '~r~ Raub erfolgreich bei: ~b~', + ['min_two_police'] = 'es müssen mindestens ~b~2 Polizisten~s~ im Dienst sein um einen Raub starten zu können.', + ['robbery_already'] = '~r~Ein Raub ist bereits im gange.', + +} From 1e7a4bc9e2fa31e56e97051f6c5df996809f1b14 Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 12:57:49 +0200 Subject: [PATCH 0634/3224] Add German Language --- __resource.lua | 2 ++ locales/de.lua | 9 +++++++++ 2 files changed, 11 insertions(+) create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index ec0d70a4..78593c6c 100644 --- a/__resource.lua +++ b/__resource.lua @@ -5,6 +5,7 @@ description 'ESX Society' server_scripts { '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', @@ -14,6 +15,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..e5e45b05 --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,9 @@ +Locales['de'] = { + + ['have_withdrawn'] = 'abgehoben ~g~$', + ['invalid_amount'] = 'ungültiger Betrag', + ['have_deposited'] = 'eingezahlt ~r~$', + ['you_have'] = 'du hast ~g~$', + ['you_have_laundered'] = 'du hast dein Geld ~r~gewaschen~s~: ~g~$', + +} From 3dc731f2e55a6aeacdf8f030fe98a992ec7a68f0 Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 12:59:44 +0200 Subject: [PATCH 0635/3224] Add German Language --- __resource.lua | 1 + locales/de.lua | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index 472826ea..be3c0c0c 100644 --- a/__resource.lua +++ b/__resource.lua @@ -4,6 +4,7 @@ description 'SkinChanger' client_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/en.lua', 'locales/fr.lua', 'config.lua', diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..7353cec9 --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,53 @@ +Locales['de'] = { + + ['sex'] = 'Geschlecht', + ['face'] = 'Gesicht', + ['skin'] = 'Skin', + ['wrinkles'] = 'Falten', + ['wrinkle_thickness'] = 'Faltendicke', + ['beard_type'] = 'Bart Typ', + ['beard_size'] = 'Bartdichte', + ['beard_color_1'] = 'Bartfarbe 1', + ['beard_color_2'] = 'Bartfarbe 2', + ['hair_1'] = 'Haare 1', + ['hair_2'] = 'Haare 2', + ['hair_color_1'] = 'Haarfarbe 1', + ['hair_color_2'] = 'Haarfarbe 2', + ['eyebrow_type'] = 'Augenbrauen Typ', + ['eyebrow_size'] = 'Augenbrauen Größe', + ['eyebrow_color_1'] = 'Augenbrauenfarbe 1', + ['eyebrow_color_2'] = 'Augenbrauenfarbe 2', + ['makeup_type'] = 'Makeup Typ', + ['makeup_thickness'] = 'Makeup dicke', + ['makeup_color_1'] = 'Makeupfarbe 1', + ['makeup_color_2'] = 'Makeupfarbe 2', + ['lipstick_type'] = 'Lippenstift Typ', + ['lipstick_thickness'] = 'Lippenstift dicke', + ['lipstick_color_1'] = 'Lippenstiffarbe 1', + ['lipstick_color_2'] = 'Lippenstiftfarbe 2', + ['ear_accessories'] = 'Ohr Accessories', + ['ear_accessories_color'] = 'Ohr Accessories Farbe', + ['tshirt_1'] = 'T-Shirt 1', + ['tshirt_2'] = 'T-Shirt 2', + ['torso_1'] = 'Torso 1', + ['torso_2'] = 'Torso 2', + ['decals_1'] = 'Tattoos 1', + ['decals_2'] = 'Tattoos 2', + ['arms'] = 'Arme', + ['pants_1'] = 'Hosen 1', + ['pants_2'] = 'Hosen 2', + ['shoes_1'] = 'Schuhe 1', + ['shoes_2'] = 'Schuhe 2', + ['mask_1'] = 'Maske 1', + ['mask_2'] = 'Maske 2', + ['bproof_1'] = 'Schusssichere Weste 1', + ['bproof_2'] = 'Schusssichere Weste 2', + ['chain_1'] = 'Kette 1', + ['chain_2'] = 'Kette 2', + ['helmet_1'] = 'Helm 1', + ['helmet_2'] = 'Helm 2', + ['glasses_1'] = 'Brille 1', + ['glasses_2'] = 'Brille 2', + ['bag'] = 'Rucksack', + ['bag_color'] = 'Rucksackfarbe', +} From a52c27eb8b88c31eb4e7ef45de37019aecb28fb2 Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 13:04:20 +0200 Subject: [PATCH 0636/3224] Add German Language --- __resource.lua | 2 ++ locales/de.lua | 10 ++++++++++ 2 files changed, 12 insertions(+) create mode 100644 locales/de.lua diff --git a/__resource.lua b/__resource.lua index 239daaed..5f926927 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,6 +2,7 @@ description 'ESX Mecano Job' client_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', @@ -11,6 +12,7 @@ client_scripts { server_scripts { '@es_extended/locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/en.lua', 'locales/fr.lua', diff --git a/locales/de.lua b/locales/de.lua new file mode 100644 index 00000000..7415e576 --- /dev/null +++ b/locales/de.lua @@ -0,0 +1,10 @@ +Locales ['de'] = { + + ['buy'] = 'du kaufst', + ['not_enough_black'] = 'du hast nicht genug Schwarzgeld', + ['not_enough'] = 'du hast nicht genug Geld', + ['shop'] = 'Geschäft', + ['shop_menu'] = 'Drücke ~INPUT_CONTEXT~ um auf das Geschäft zuzugreifen.', + ['map_blip'] = 'Waffenladen', + +} \ No newline at end of file From 5491654979a8977030c7aa7b8bbc000e8b24bd10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 26 Aug 2017 17:33:04 +0200 Subject: [PATCH 0637/3224] Add /spawnped command --- .../[essential]/es_extended/client/main.lua | 27 +++++++++++++++++++ .../es_extended/server/commands.lua | 6 +++++ 2 files changed, 33 insertions(+) diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index caa47ea7..f594f8ac 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -319,6 +319,33 @@ AddEventHandler('esx:pickupWeapon', function(weaponPickup, weaponName) end) +RegisterNetEvent('esx:spawnPed') +AddEventHandler('esx:spawnPed', function(model) + + model = (tonumber(model) ~= nil and tonumber(model) or GetHashKey(model)) + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + local forward = GetEntityForwardVector(playerPed) + local x, y, z = table.unpack(coords + forward * 1.0) + + Citizen.CreateThread(function() + + print(model) + + RequestModel(model) + + while not HasModelLoaded(model) do + Citizen.Wait(0) + end + + print('LOADED') + + CreatePed(5, model, x, y, z, 0.0, true, false) + + end) + +end) + -- Pause menu disable HUD display Citizen.CreateThread(function() while true do diff --git a/resources/[essential]/es_extended/server/commands.lua b/resources/[essential]/es_extended/server/commands.lua index e4102452..d21f081c 100644 --- a/resources/[essential]/es_extended/server/commands.lua +++ b/resources/[essential]/es_extended/server/commands.lua @@ -47,6 +47,12 @@ end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('spawn_car'), params = {{name = "car", help = _U('spawn_car_param')}}}) +TriggerEvent('es:addGroupCommand', 'spawnped', 'admin', function(source, args, user) + TriggerClientEvent('esx:spawnPed', source, args[2]) +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end) + TriggerEvent('es:addGroupCommand', 'spawnobject', 'admin', function(source, args, user) TriggerClientEvent('esx:spawnObject', source, args[2]) end, function(source, args, user) From dcfe4f62366ddad7c3a74a841db358d244783630 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 26 Aug 2017 18:36:49 +0200 Subject: [PATCH 0638/3224] Add NPC jobs --- client/main.lua | 253 +++++++++++++++++++++++++++++++++++++++++------- config.lua | 82 +++++++++++++++- server/main.lua | 21 ++++ 3 files changed, 318 insertions(+), 38 deletions(-) diff --git a/client/main.lua b/client/main.lua index 527178c1..2fa62033 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,14 +1,34 @@ -ESX = nil -local PlayerData = {} -local GUI = {} -GUI.Time = 0 -local HasAlreadyEnteredMarker = false -local LastZone = nil -local CurrentAction = nil -local CurrentActionMsg = '' -local CurrentActionData = {} -local OnJob = false -local TargetCoords = nil +local Keys = { + ["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57, + ["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177, + ["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18, + ["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182, + ["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81, + ["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70, + ["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178, + ["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173, + ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 +} + +ESX = nil +local PlayerData = {} +local GUI = {} +GUI.Time = 0 +local HasAlreadyEnteredMarker = false +local LastZone = nil +local CurrentAction = nil +local CurrentActionMsg = '' +local CurrentActionData = {} +local OnJob = false +local TargetCoords = nil +local CurrentlyTowedVehicle = nil +local Blips = {} +local NPCOnJob = false +local NPCTargetTowable = nil +local NPCTargetTowableZone = nil +local NPCHasSpawnedTowable = false +local NPCLastCancel = GetGameTimer() - 5 * 60000 +local NPCHasBeenNextToTowable = false Citizen.CreateThread(function() while ESX == nil do @@ -17,6 +37,60 @@ Citizen.CreateThread(function() end end) +function SelectRandomTowable() + + local index = GetRandomIntInRange(1, #Config.Towables) + + for k,v in pairs(Config.Zones) do + if v.Pos.x == Config.Towables[index].x and v.Pos.y == Config.Towables[index].y and v.Pos.z == Config.Towables[index].z then + return k + end + end + +end + +function StartNPCJob() + + NPCOnJob = true + + NPCTargetTowableZone = SelectRandomTowable() + local zone = Config.Zones[NPCTargetTowableZone] + + Blips['NPCTargetTowableZone'] = AddBlipForCoord(zone.Pos.x, zone.Pos.y, zone.Pos.z) + SetBlipRoute(Blips['NPCTargetTowableZone'], true) + + ESX.ShowNotification('~y~Conduisez~s~ jusqu\'à l\'endroit indiqué') +end + +function StopNPCJob(cancel) + + if Blips['NPCTargetTowableZone'] ~= nil then + RemoveBlip(Blips['NPCTargetTowableZone']) + Blips['NPCTargetTowableZone'] = nil + end + + if Blips['NPCDelivery'] ~= nil then + RemoveBlip(Blips['NPCDelivery']) + Blips['NPCDelivery'] = nil + end + + + Config.Zones.VehicleDelivery.Type = -1 + + NPCOnJob = false + NPCTargetTowable = nil + NPCTargetTowableZone = nil + NPCHasSpawnedTowable = false + NPCHasBeenNextToTowable = false + + if cancel then + ESX.ShowNotification('Mission ~r~annulée~s~') + else + TriggerServerEvent('esx_mecanojob:onNPCJobCompleted') + end + +end + function OpenMecanoActionsMenu() local elements = { @@ -344,7 +418,7 @@ function OpenMobileMecanoActionsMenu() SetVehicleDoorsLocked(vehicle, 1) SetVehicleDoorsLockedForAllPlayers(vehicle, false) ClearPedTasksImmediately(playerPed) - TriggerEvent('esx:showNotification', 'Véhicule ~g~déverouillé') + ESX.ShowNotification('Véhicule ~g~déverouillé') end) end @@ -376,7 +450,7 @@ function OpenMobileMecanoActionsMenu() SetVehicleUndriveable(vehicle, false) SetVehicleEngineOn(vehicle, true, true) ClearPedTasksImmediately(playerPed) - TriggerEvent('esx:showNotification', 'Véhicule ~g~réparé') + ESX.ShowNotification('Véhicule ~g~réparé') end) end end @@ -403,7 +477,7 @@ function OpenMobileMecanoActionsMenu() Citizen.Wait(10000) SetVehicleDirtLevel(vehicle, 0) ClearPedTasksImmediately(playerPed) - TriggerEvent('esx:showNotification', 'Véhicule ~g~néttoyé') + ESX.ShowNotification('Véhicule ~g~néttoyé') end) end end @@ -420,11 +494,11 @@ function OpenMobileMecanoActionsMenu() local vehicle = GetVehiclePedIsIn( ped, false ) if ( GetPedInVehicleSeat( vehicle, -1 ) == ped ) then - TriggerEvent('esx:showNotification', 'Vehicule ~r~mis en fourrière') + ESX.ShowNotification('Vehicule ~r~mis en fourrière') SetEntityAsMissionEntity( vehicle, true, true ) deleteCar( vehicle ) else - TriggerEvent('esx:showNotification', 'Vous devez être assis du ~r~côté conducteur!') + ESX.ShowNotification('Vous devez être assis du ~r~côté conducteur!') end else local playerPos = GetEntityCoords( ped, 1 ) @@ -432,11 +506,11 @@ function OpenMobileMecanoActionsMenu() local vehicle = GetVehicleInDirection( playerPos, inFrontOfPlayer ) if ( DoesEntityExist( vehicle ) ) then - TriggerEvent('esx:showNotification', 'Vehicule ~r~mis en fourrière') + ESX.ShowNotification('Vehicule ~r~mis en fourrière') SetEntityAsMissionEntity( vehicle, true, true ) deleteCar( vehicle ) else - TriggerEvent('esx:showNotification', 'Vous devez être ~r~près d\'un véhicule~s~ pour le mettre en fourrière') + ESX.ShowNotification('Vous devez être ~r~près d\'un véhicule~s~ pour le mettre en fourrière') end end end @@ -456,28 +530,65 @@ function OpenMobileMecanoActionsMenu() local coordB = GetOffsetFromEntityInWorldCoords(playerped, 0.0, 5.0, 0.0) local targetVehicle = getVehicleInDirection(coordA, coordB) - if currentlyTowedVehicle == nil then + if CurrentlyTowedVehicle == nil then if targetVehicle ~= 0 then if not IsPedInAnyVehicle(playerped, true) then if vehicle ~= targetVehicle then AttachEntityToEntity(targetVehicle, vehicle, 20, -0.5, -5.0, 1.0, 0.0, 0.0, 0.0, false, false, false, false, 20, true) - currentlyTowedVehicle = targetVehicle - TriggerEvent('esx:showNotification', 'Vehicule ~b~attaché~s~ avec succès!') + CurrentlyTowedVehicle = targetVehicle + ESX.ShowNotification('Vehicule ~b~attaché~s~ avec succès!') + + if NPCOnJob then + + if NPCTargetTowable == targetVehicle then + ESX.ShowNotification('Veuillez déposer le véhicule à la concession') + + Config.Zones.VehicleDelivery.Type = 1 + + if Blips['NPCTargetTowableZone'] ~= nil then + RemoveBlip(Blips['NPCTargetTowableZone']) + Blips['NPCTargetTowableZone'] = nil + end + + Blips['NPCDelivery'] = AddBlipForCoord(Config.Zones.VehicleDelivery.Pos.x, Config.Zones.VehicleDelivery.Pos.y, Config.Zones.VehicleDelivery.Pos.z) + + SetBlipRoute(Blips['NPCDelivery'], true) + + end + + end + else - TriggerEvent('esx:showNotification', '~r~Impossible~s~ d\'attacher votre propre dépanneuse') + ESX.ShowNotification('~r~Impossible~s~ d\'attacher votre propre dépanneuse') end end else - TriggerEvent('esx:showNotification', 'Il n\'y a ~r~pas de véhicule~s~ à attacher') + ESX.ShowNotification('Il n\'y a ~r~pas de véhicule~s~ à attacher') end else - AttachEntityToEntity(currentlyTowedVehicle, vehicle, 20, -0.5, -12.0, 1.0, 0.0, 0.0, 0.0, false, false, false, false, 20, true) - DetachEntity(currentlyTowedVehicle, true, true) - currentlyTowedVehicle = nil - TriggerEvent('esx:showNotification', 'Vehicule ~b~détattaché~s~ avec succès!') + + AttachEntityToEntity(CurrentlyTowedVehicle, vehicle, 20, -0.5, -12.0, 1.0, 0.0, 0.0, 0.0, false, false, false, false, 20, true) + DetachEntity(CurrentlyTowedVehicle, true, true) + + if NPCOnJob then + + if CurrentlyTowedVehicle == NPCTargetTowable then + ESX.Game.DeleteVehicle(NPCTargetTowable) + TriggerServerEvent('esx_mecanojob:onNPCJobMissionCompleted') + StopNPCJob() + + else + ESX.ShowNotification('Ce n\'est pas le bon véhicule') + end + + end + + CurrentlyTowedVehicle = nil + + ESX.ShowNotification('Vehicule ~b~détattaché~s~ avec succès!') end else - TriggerEvent('esx:showNotification', '~r~Impossible! ~s~Vous devez avoir un ~b~Flatbed ~s~pour ça') + ESX.ShowNotification('~r~Impossible! ~s~Vous devez avoir un ~b~Flatbed ~s~pour ça') end end @@ -562,9 +673,9 @@ AddEventHandler('esx_mecanojob:onHijack', function() SetVehicleDoorsLocked(vehicle, 1) SetVehicleDoorsLockedForAllPlayers(vehicle, false) ClearPedTasksImmediately(playerPed) - TriggerEvent('esx:showNotification', '~g~Véhicule déverouillé') + ESX.ShowNotification('~g~Véhicule déverouillé') else - TriggerEvent('esx:showNotification', '~r~Crochetage raté') + ESX.ShowNotification('~r~Crochetage raté') ClearPedTasksImmediately(playerPed) end end) @@ -595,7 +706,7 @@ AddEventHandler('esx_mecanojob:onCarokit', function() SetVehicleFixed(vehicle) SetVehicleDeformationFixed(vehicle) ClearPedTasksImmediately(playerPed) - TriggerEvent('esx:showNotification', '~g~Carosserie réparée') + ESX.ShowNotification('~g~Carosserie réparée') end) end end @@ -624,7 +735,7 @@ AddEventHandler('esx_mecanojob:onFixkit', function() SetVehicleDeformationFixed(vehicle) SetVehicleUndriveable(vehicle, false) ClearPedTasksImmediately(playerPed) - TriggerEvent('esx:showNotification', '~g~Véhicule réparé') + ESX.ShowNotification('~g~Véhicule réparé') end) end end @@ -656,21 +767,29 @@ AddEventHandler('esx:setJob', function(job) end) AddEventHandler('esx_mecanojob:hasEnteredMarker', function(zone) + + if zone == NPCJobTargetTowable then + + end + if zone == 'MecanoActions' then CurrentAction = 'mecano_actions_menu' CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au menu.' CurrentActionData = {} end + if zone == 'Garage' then CurrentAction = 'mecano_harvest_menu' CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au menu de récolte.' CurrentActionData = {} end + if zone == 'Craft' then CurrentAction = 'mecano_craft_menu' CurrentActionMsg = 'Appuyez sur ~INPUT_CONTEXT~ pour accéder au menu établi.' CurrentActionData = {} end + if zone == 'VehicleDeleter' then local playerPed = GetPlayerPed(-1) if IsPedInAnyVehicle(playerPed, false) then @@ -679,6 +798,7 @@ AddEventHandler('esx_mecanojob:hasEnteredMarker', function(zone) CurrentActionData = {} end end + end) AddEventHandler('esx_mecanojob:hasExitedMarker', function(zone) @@ -729,6 +849,46 @@ AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) end) +-- Pop NPC mission vehicle when inside area +Citizen.CreateThread(function() + while true do + + Wait(0) + + if NPCTargetTowableZone ~= nil and not NPCHasSpawnedTowable then + + local coords = GetEntityCoords(GetPlayerPed(-1)) + local zone = Config.Zones[NPCTargetTowableZone] + + if GetDistanceBetweenCoords(coords, zone.Pos.x, zone.Pos.y, zone.Pos.z, true) < Config.NPCSpawnDistance then + + local model = Config.Vehicles[GetRandomIntInRange(1, #Config.Vehicles)] + + ESX.Game.SpawnVehicle(model, zone.Pos, 0, function(vehicle) + NPCTargetTowable = vehicle + end) + + NPCHasSpawnedTowable = true + + end + + end + + if NPCTargetTowableZone ~= nil and NPCHasSpawnedTowable and not NPCHasBeenNextToTowable then + + local coords = GetEntityCoords(GetPlayerPed(-1)) + local zone = Config.Zones[NPCTargetTowableZone] + + if(GetDistanceBetweenCoords(coords, zone.Pos.x, zone.Pos.y, zone.Pos.z, true) < Config.NPCNextToDistance) then + ESX.ShowNotification('Veuillez ~y~remorquer~s~ le véhicule') + NPCHasBeenNextToTowable = true + end + + end + + end +end) + -- Create Blips Citizen.CreateThread(function() local blip = AddBlipForCoord(Config.Zones.MecanoActions.Pos.x, Config.Zones.MecanoActions.Pos.y, Config.Zones.MecanoActions.Pos.z) @@ -823,6 +983,7 @@ end) Citizen.CreateThread(function() while true do Citizen.Wait(0) + if CurrentAction ~= nil then SetTextComponentFormat('STRING') AddTextComponentString(CurrentActionMsg) @@ -857,8 +1018,34 @@ Citizen.CreateThread(function() end end - if IsControlJustReleased(0, 167) and PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then + if IsControlJustReleased(0, Keys['F6']) and PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then OpenMobileMecanoActionsMenu() end + + if IsControlJustReleased(0, Keys['DELETE']) and PlayerData.job ~= nil and PlayerData.job.name == 'mecano' then + + if NPCOnJob then + + if GetGameTimer() - NPCLastCancel > 5 * 60000 then + StopNPCJob(true) + -- NPCLastCancel = GetGameTimer() + else + ESX.ShowNotification('Vous devez ~r~attendre~s~ 5 minutes') + end + + else + + local playerPed = GetPlayerPed(-1) + + if IsPedInAnyVehicle(playerPed, false) and IsVehicleModel(GetVehiclePedIsIn(playerPed, false), GetHashKey("flatbed")) then + StartNPCJob() + else + ESX.ShowNotification('Vous devez être en flatbed pour commencer la mission') + end + + end + + end + end end) \ No newline at end of file diff --git a/config.lua b/config.lua index ffb65d2b..96d25931 100644 --- a/config.lua +++ b/config.lua @@ -2,11 +2,14 @@ Config = {} Config.DrawDistance = 100.0 Config.MaxInService = -1 Config.EnablePlayerManagement = true +Config.NPCSpawnDistance = 500.0 +Config.NPCNextToDistance = 25.0 +Config.NPCJobEarnings = {min = 15, max = 40} Config.Zones = { MecanoActions = { - Pos = {x = -205.90548706055, y = -1327.7248535156, z = 29.89040184021}, + Pos = {x = -347.291, y = -133.370, z = 38.009}, Size = {x = 1.5, y = 1.5, z = 1.0}, Color = {r = 204, g = 204, b = 0}, Type = 1 @@ -20,23 +23,92 @@ Config.Zones = { }, Craft = { - Pos = {x = -196.51593017578, y = -1318.4403076172, z = 30.089345932007}, + Pos = {x = -323.140, y = -129.882, z = 37.999}, Size = {x = 1.5, y = 1.5, z = 1.0}, Color = {r = 204, g = 204, b = 0}, Type = 1 }, VehicleSpawnPoint = { - Pos = {x = -157.7899017334, y = -1305.8979492188, z = 30.348382949829}, + Pos = {x = -366.354, y = -110.766, z = 37.696}, Size = {x = 1.5, y = 1.5, z = 1.0}, Type = -1 }, VehicleDeleter = { - Pos = {x = -182.78112792969, y = -1330.5368652344, z = 30.194892883301}, + Pos = {x = -386.899, y = -105.675, z = 37.683}, Size = {x = 3.0, y = 3.0, z = 1.0}, Color = {r = 204, g = 204, b = 0}, Type = 1 - } + }, + + VehicleDelivery = { + Pos = {x = -382.925, y = -133.748, z = 37.685}, + Size = {x = 20.0, y = 20.0, z = 3.0}, + Color = {r = 204, g = 204, b = 0}, + Type = -1 + }, } + +Config.Towables = { + { ['x'] = -2480.8720703125, ['y'] = -211.96409606934, ['z'] = 17.397672653198 }, + { ['x'] = -2723.392578125, ['y'] = 13.207388877869, ['z'] = 15.12806892395 }, + { ['x'] = -3169.6235351563, ['y'] = 976.18127441406, ['z'] = 15.038360595703 }, + { ['x'] = -3139.7568359375, ['y'] = 1078.7182617188, ['z'] = 20.189767837524 }, + { ['x'] = -1656.9357910156, ['y'] = -246.16479492188, ['z'] = 54.510955810547 }, + { ['x'] = -1586.6560058594, ['y'] = -647.56115722656, ['z'] = 29.441320419312 }, + { ['x'] = -1036.1470947266, ['y'] = -491.05856323242, ['z'] = 36.214912414551 }, + { ['x'] = -1029.1884765625, ['y'] = -475.53167724609, ['z'] = 36.416831970215 }, + { ['x'] = 75.212287902832, ['y'] = 164.8522644043, ['z'] = 104.69123077393 }, + { ['x'] = -534.60491943359, ['y'] = -756.71801757813, ['z'] = 31.599143981934 }, + { ['x'] = 487.24212646484, ['y'] = -30.827201843262, ['z'] = 88.856712341309 }, + { ['x'] = -772.20111083984, ['y'] = -1281.8114013672, ['z'] = 4.5642876625061 }, + { ['x'] = -663.84173583984, ['y'] = -1206.9936523438, ['z'] = 10.171216011047 }, + { ['x'] = 719.12451171875, ['y'] = -767.77545166016, ['z'] = 24.892364501953 }, + { ['x'] = -970.95465087891, ['y'] = -2410.4453125, ['z'] = 13.344270706177 }, + { ['x'] = -1067.5234375, ['y'] = -2571.4064941406, ['z'] = 13.211874008179 }, + { ['x'] = -619.23968505859, ['y'] = -2207.2927246094, ['z'] = 5.5659561157227 }, + { ['x'] = 1192.0831298828, ['y'] = -1336.9086914063, ['z'] = 35.106426239014 }, + { ['x'] = -432.81033325195, ['y'] = -2166.0505371094, ['z'] = 9.8885231018066 }, + { ['x'] = -451.82403564453, ['y'] = -2269.34765625, ['z'] = 7.1719741821289 }, + { ['x'] = 939.26702880859, ['y'] = -2197.5390625, ['z'] = 30.546691894531 }, + { ['x'] = -556.11486816406, ['y'] = -1794.7312011719, ['z'] = 22.043060302734 }, + { ['x'] = 591.73504638672, ['y'] = -2628.2197265625, ['z'] = 5.5735430717468 }, + { ['x'] = 1654.515625, ['y'] = -2535.8325195313, ['z'] = 74.491394042969 }, + { ['x'] = 1642.6146240234, ['y'] = -2413.3159179688, ['z'] = 93.139915466309 }, + { ['x'] = 1371.3223876953, ['y'] = -2549.525390625, ['z'] = 47.575256347656 }, + { ['x'] = 383.83779907227, ['y'] = -1652.8695068359, ['z'] = 37.278503417969 }, + { ['x'] = 27.219129562378, ['y'] = -1030.8818359375, ['z'] = 29.414621353149 }, + { ['x'] = 229.26435852051, ['y'] = -365.91101074219, ['z'] = 43.750762939453 }, + { ['x'] = -85.809432983398, ['y'] = -51.665500640869, ['z'] = 61.10591506958 }, + { ['x'] = -4.5967531204224, ['y'] = -670.27124023438, ['z'] = 31.85863494873 }, + { ['x'] = -111.89884185791, ['y'] = 91.96940612793, ['z'] = 71.080169677734 }, + { ['x'] = -314.26129150391, ['y'] = -698.23309326172, ['z'] = 32.545776367188 }, + { ['x'] = -366.90979003906, ['y'] = 115.53963470459, ['z'] = 65.575706481934 }, + { ['x'] = -592.06726074219, ['y'] = 138.20733642578, ['z'] = 60.074813842773 }, + { ['x'] = -1613.8572998047, ['y'] = 18.759860992432, ['z'] = 61.799819946289 }, + { ['x'] = -1709.7995605469, ['y'] = 55.105819702148, ['z'] = 65.706237792969 }, + { ['x'] = -521.88830566406, ['y'] = -266.7805480957, ['z'] = 34.940990447998 }, + { ['x'] = -451.08666992188, ['y'] = -333.52026367188, ['z'] = 34.021533966064 }, + { ['x'] = 322.36480712891, ['y'] = -1900.4990234375, ['z'] = 25.773607254028 }, +} + +for i=1, #Config.Towables, 1 do + + Config.Zones['Towable' .. i] = { + Pos = Config.Towables[i], + Size = {x = 1.5, y = 1.5, z = 1.0}, + Color = {r = 204, g = 204, b = 0}, + Type = -1 + } + +end + +Config.Vehicles = { + 'adder', + 'asea', + 'asterope', + 'banshee', + 'buffalo' +} diff --git a/server/main.lua b/server/main.lua index 3edee613..0e2ffb1d 100644 --- a/server/main.lua +++ b/server/main.lua @@ -233,6 +233,27 @@ AddEventHandler('esx_mecanojob:stopCraft3', function() PlayersCrafting3[_source] = false end) +---------------------------- NPC Job Earnings ------------------------------------------------------ + +RegisterServerEvent('esx_mecanojob:onNPCJobMissionCompleted') +AddEventHandler('esx_mecanojob:onNPCJobMissionCompleted', function() + + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) + local total = math.random(Config.NPCJobEarnings.min, Config.NPCJobEarnings.max); + + if xPlayer.job.grade >= 3 then + total = total * 2 + end + + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_mecano', function(account) + account.addMoney(total) + end) + + TriggerClientEvent("esx:showNotification", _source, "Votre société a ~g~gagné~s~ ~g~$".. total) + +end) + ---------------------------- register usable item -------------------------------------------------- ESX.RegisterUsableItem('blowpipe', function(source) From 79c8dce15d05368bcc458f78fe7fdbcca48a3c46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 26 Aug 2017 18:44:30 +0200 Subject: [PATCH 0639/3224] Remove debug comment --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 2fa62033..13f156a3 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1028,7 +1028,7 @@ Citizen.CreateThread(function() if GetGameTimer() - NPCLastCancel > 5 * 60000 then StopNPCJob(true) - -- NPCLastCancel = GetGameTimer() + NPCLastCancel = GetGameTimer() else ESX.ShowNotification('Vous devez ~r~attendre~s~ 5 minutes') end From 859c118ccf2b0c4e310ef2f02b14a147ab5407e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 26 Aug 2017 18:55:05 +0200 Subject: [PATCH 0640/3224] Add dv --- .../[essential]/es_extended/client/main.lua | 21 +++++++++++++++++++ .../es_extended/server/commands.lua | 7 +++++++ 2 files changed, 28 insertions(+) diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index f594f8ac..efd451d2 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -346,6 +346,27 @@ AddEventHandler('esx:spawnPed', function(model) end) +RegisterNetEvent('esx:deleteVehicle') +AddEventHandler('esx:deleteVehicle', function() + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + if IsPedInAnyVehicle(playerPed, false) then + + local vehicle = GetVehiclePedIsIn(playerPed, false) + ESX.Game.DeleteVehicle(vehicle) + + elseif IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + + local vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) + ESX.Game.DeleteVehicle(vehicle) + + end + +end) + + -- Pause menu disable HUD display Citizen.CreateThread(function() while true do diff --git a/resources/[essential]/es_extended/server/commands.lua b/resources/[essential]/es_extended/server/commands.lua index d21f081c..5d0800e7 100644 --- a/resources/[essential]/es_extended/server/commands.lua +++ b/resources/[essential]/es_extended/server/commands.lua @@ -47,6 +47,13 @@ end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('spawn_car'), params = {{name = "car", help = _U('spawn_car_param')}}}) +TriggerEvent('es:addGroupCommand', 'dv', 'admin', function(source, args, user) + TriggerClientEvent('esx:deleteVehicle', source) +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end) + + TriggerEvent('es:addGroupCommand', 'spawnped', 'admin', function(source, args, user) TriggerClientEvent('esx:spawnPed', source, args[2]) end, function(source, args, user) From 5346661d88c72adb11f1443a4f1cbd66c2408362 Mon Sep 17 00:00:00 2001 From: SrPapani Date: Sat, 26 Aug 2017 15:04:02 -0300 Subject: [PATCH 0641/3224] Create br_esx_jobs.sql --- br_esx_jobs.sql | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 br_esx_jobs.sql diff --git a/br_esx_jobs.sql b/br_esx_jobs.sql new file mode 100644 index 00000000..b56b96f9 --- /dev/null +++ b/br_esx_jobs.sql @@ -0,0 +1,49 @@ +USE `essentialmode`; + +INSERT INTO `addon_account` (name, label, shared) VALUES + ('caution', 'Deposito', 0) +; + +INSERT INTO `jobs` (name, label) VALUES + ('slaughterer', 'Abatedor'), + ('fisherman', 'Pescador'), + ('miner', 'Minerador'), + ('lumberjack', 'Lenhador'), + ('fuel', 'Refinador'), + ('reporter', 'Jornalista'), + ('textil', 'Costureiro') +; + +ALTER TABLE jobs ADD whitelisted BOOLEAN NOT NULL DEFAULT FALSE; + +INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES + ('lumberjack', 0, 'interim', 'Temporario', 0, '{}', '{}'), + ('fisherman', 0, 'interim', 'Temporario', 0, '{}', '{}'), + ('fuel', 0, 'interim', 'Temporario', 0, '{}', '{}'), + ('reporter', 0, 'employee', 'Temporario', 0, '{}', '{}'), + ('textil',0,'interim','Temporario',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}'), + ('miner', 0, 'interim', 'Temporario', 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}', '{}'), + ('slaughterer',0,'interim','Temporario',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}') +; + +INSERT INTO `items` (`name`, `label`) VALUES + ('alive_chicken', 'Frango Vivo'), + ('slaughtered_chicken', 'Frango Abatido'), + ('packaged_chicken', 'Frango na Bandeja'), + ('fish', 'Peixe'), + ('stone', 'Pedra'), + ('washed_stone', 'Pedra Limpa'), + ('copper', 'Cobre'), + ('iron', 'Ferro'), + ('gold', 'Ouro'), + ('diamond', 'Diamante'), + ('wood', 'Madeira'), + ('cutted_wood', 'Madeira Cortada'), + ('packaged_plank', 'Tábua Embalada'), + ('petrol', 'Petroleo'), + ('petrol_raffin', 'Petroleo Refinado'), + ('essence', 'Gasolina'), + ('whool', 'Lã'), + ('fabric', 'Tecido'), + ('clothe', 'Roupa') +; From a3e5e5bc90ba0ba14bc5779b737921e1fce6195a Mon Sep 17 00:00:00 2001 From: SrPapani Date: Sat, 26 Aug 2017 15:05:05 -0300 Subject: [PATCH 0642/3224] Create br_config.lua --- br_config.lua | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 br_config.lua diff --git a/br_config.lua b/br_config.lua new file mode 100644 index 00000000..5425e477 --- /dev/null +++ b/br_config.lua @@ -0,0 +1,45 @@ +Config = {} +Config.DrawDistance = 1000.0 +Config.Locale = 'br' + +Config.Plates = { + taxi = "TAXI", + fisherman = "PESCA", + cop = "LSPD", + ambulance = "SAMU", + depanneur = "MECA", + fuel = "REFINA", + lumberjack = "LENHA", + miner = "MINE", + reporter = "JORN", + slaughterer = "ABAT", + textil = "COST" +} + +Config.Jobs = {} + +Config.PublicZones = { + EnterBuilding = { + Pos = { x = -118.21381378174, y = -607.14227294922, z = 35.280723571777 }, + Size = {x = 3.0, y = 3.0, z = 0.2}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = false, + Name = "Globo News", + Type = "teleport", + Hint = "Pressione ~INPUT_PICKUP~ para entrar no prédio.", + Teleport = { x = -139.09838867188, y = -620.74865722656, z = 167.82052612305 } + }, + + ExitBuilding = { + Pos = { x = -139.45831298828, y = -617.32312011719, z = 167.82052612305 }, + Size = {x = 3.0, y = 3.0, z = 0.2}, + Color = {r = 204, g = 204, b = 0}, + Marker= 1, + Blip = false, + Name = "Globo News", + Type = "teleport", + Hint = "pressione ~INPUT_PICKUP~ para ir à entrada do edifício.", + Teleport = { x = -113.07, y = -604.93, z = 35.28 }, + }, +} From 863ba1d1851b3188405e9f663c978d908d0609dd Mon Sep 17 00:00:00 2001 From: SrPapani Date: Sat, 26 Aug 2017 15:05:53 -0300 Subject: [PATCH 0643/3224] Create br.lua --- locales/br.lua | 117 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 locales/br.lua diff --git a/locales/br.lua b/locales/br.lua new file mode 100644 index 00000000..6e1772af --- /dev/null +++ b/locales/br.lua @@ -0,0 +1,117 @@ +Locales['br'] = { + --Menus Geral + ['cloakroom'] = 'Vestiário', + ['cloak_change'] = 'pressione ~INPUT_PICKUP~ mudar de roupa.', + ['citizen_wear'] = 'retirar uniforme', + ['job_wear'] = 'colocar uniforme', + ['bank_deposit'] = 'um depósito de segurança de ~g~', + ['bank_deposit_r'] = 'um depósito de segurança de ~g~$', + ['bank_deposit2'] = '$ ~s~foi feito para você depois do seu desmaio.', + ['bank_nodeposit'] = "você não tinha um depósito de segurança", + ['foot_work'] = 'você deve estar a pé para poder trabalhar.', + ['next_point'] = 'vá para o próximo passo depois de completar este.', + ['security_deposit'] = 'a segurança dada será ~g~$', + ['not_your_vehicle'] = "este não é o seu veículo ou você deve ser um motorista.", + ['in_vehicle'] = 'você deve estar em um veículo.', + ['wrong_point'] = "você não está no ponto certo de entrega.", + ['max_limit'] = 'você tem o máximo: ', + ['not_enough'] = "você não tem o suficiente", + ['not_enough2'] = ' Para continuar esta tarefa.', + ['caution_taken'] = ' ~s~foi tirado de você.', + ['caution_returned'] = ' ~s~foi devolvido a você.', + ['spawn_veh'] = 'Veiculo Spawnado', + ['spawn_veh_button'] = 'pressione ~INPUT_PICKUP~ chamar o veículo de entrega.', + ['spawn_truck_button'] = 'pressione ~INPUT_PICKUP~ spawnar o caminhão.', + ['service_vh'] = 'veículo de serviço', + ['return_vh'] = 'veiculo devolvido', + ['return_vh_button'] = 'pressione ~INPUT_PICKUP~ para devolver o veiculo.', + ['delivery_point'] = 'ponto de entrega', + ['delivery'] = 'Entrega', + + --Trabalho de Lenhador + ['lj_locker_room'] = "Vestiario Lenhador", + ['lj_mapblip'] = 'pilha de madeira', + ['lj_wood'] = 'madeira', + ['lj_pickup'] = 'pressione ~INPUT_PICKUP~ para recuperar madeira.', + ['lj_cutwood'] = 'Corte de Madeira', + ['lj_cutwood_button'] = 'pressione ~INPUT_PICKUP~ para cortar madeira.', + ['lj_board'] = 'tábua', + ['lj_planks'] = 'tábua embalada', + ['lj_cutwood'] = 'madeira cortada', + ['lj_pick_boards'] = 'pressione ~INPUT_PICKUP~ para recuperar tábuas.', + ['lj_deliver_button'] = 'pressione ~INPUT_PICKUP~ para entregar as tábuas.', + + --Pescador + ['fm_fish_locker'] = "Vestiario Pescador", + ['fm_fish'] = 'peixe', + ['fm_fish_area'] = 'area de pesca', + ['fm_fish_button'] = 'pressione ~INPUT_PICKUP~ para pescar.', + ['fm_spawnboat_title'] = 'Spawnar Barco', + ['fm_spawnboat'] = 'pressione ~INPUT_PICKUP~ para chamar um barco.', + ['fm_boat_title'] = 'Barco', + ['fm_boat_return_title'] = 'devolver barco', + ['fm_boat_return_button'] = 'Pressione ~INPUT_PICKUP~ para devolver o barco.', + ['fm_deliver_fish'] = 'pressione ~INPUT_PICKUP~ para entregar os peixes.', + + --Refinador + ['f_oil_refiner'] = 'Vestiario Refinador', + ['f_drill_oil'] = 'Broca de óleo', + ['f_fuel'] = 'óleo', + ['f_drillbutton'] = 'pressione ~INPUT_PICKUP~ para perfurar.', + ['f_fuel_refine'] = 'refinar óleo', + ['f_refine_fuel_button'] = 'pressione ~INPUT_PICKUP~ para refinar.', + ['f_fuel_mixture'] = 'Misturar o óleo refinado', + ['f_gas'] = 'gasolina', + ['f_fuel_mixture_button'] = 'pressione ~INPUT_PICKUP~ para misturar.', + ['f_deliver_gas'] = 'Entregar Gasolina', + ['f_deliver_gas_button'] = "pressione ~INPUT_PICKUP~ para entregar a gasolina.", + + --Minerador + ['m_miner_locker'] = "Vestiario Minerador", + ['m_rock'] = ' Pedregulho', + ['m_pickrocks'] = 'pressione ~INPUT_PICKUP~ para obter pedras.', + ['m_washrock'] = ' pedras limpas ', + ['m_rock_button'] = 'pressione ~INPUT_PICKUP~ para lavar as pedras.', + ['m_rock_smelting'] = 'Fundição', + ['m_copper'] = ' cobre', + ['m_sell_copper'] = 'vender cobre', + ['m_deliver_copper'] = 'Pressione ~INPUT_PICKUP~ para entregar cobre.', + ['m_iron'] = ' ferro', + ['m_sell_iron'] = 'vender ferro', + ['m_deliver_iron'] = 'pressione ~INPUT_PICKUP~ para entregar ferro.', + ['m_gold'] = ' ouro', + ['m_sell_gold'] = "vender ouro", + ['m_deliver_gold'] = 'pressione ~INPUT_PICKUP~ para entregar ouro.', + ['m_diamond'] = ' diamante', + ['m_sell_diamond'] = 'vender diamante', + ['m_deliver_diamond'] = 'pressione ~INPUT_PICKUP~ para entregar diamantes.', + ['m_melt_button'] = 'pressione ~INPUT_PICKUP~ para derreter as pedras.', + + --Jornalista + ['reporter_name'] = 'Globo News', + ['reporter_garage'] = 'Pressione ~INPUT_PICKUP~ para descer à garagem.', + + --Abatedor + ['s_slaughter_locker'] = "Vestiario Abatedor", + ['s_hen'] = 'galinheiro', + ['s_alive_chicken'] = 'galinha viva', + ['s_catch_hen'] = 'pressione ~INPUT_PICKUP~ para pegar galinha viva.', + ['s_slaughtered_chicken'] = 'frango para ser embalado', + ['s_chop_animal'] = 'pressione ~INPUT_PICKUP~ para cortar as galinhas.', + ['s_slaughtered'] = 'matadouro', + ['s_package'] = 'embalamento', + ['s_packagechicken'] = 'frango na bandeija', + ['s_unpackaged'] = 'frango para ser embalado', + ['s_unpackaged_button'] = 'pressione ~INPUT_PICKUP~ para colocar o frango em uma bandeja.', + ['s_deliver'] = 'pressione ~INPUT_PICKUP~ para entregar as bandejas de frango.', + + --Costureiro + ['dd_dress_locker'] = "Vestiario Costureiro", + ['dd_wool'] = 'lã', + ['dd_pickup'] = 'pressione ~INPUT_PICKUP~ para obter lã.', + ['dd_fabric'] = 'tecido', + ['dd_makefabric'] = 'Pressione ~INPUT_PICKUP~ para fazer tecido.', + ['dd_clothing'] = 'roupas', + ['dd_makeclothing'] = 'pressione ~INPUT_PICKUP~ para obter roupas.', + ['dd_deliver_clothes'] = 'pressione ~INPUT_PICKUP~ para entregar roupas.', + } From 52e47bcff4924e10b9cdac93e35a2a4076013b8c Mon Sep 17 00:00:00 2001 From: "[D]ouglas PpN" Date: Sat, 26 Aug 2017 15:15:27 -0300 Subject: [PATCH 0644/3224] Update __resource.lua for br linguage --- __resource.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/__resource.lua b/__resource.lua index 49121d1a..c69bbb9c 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,6 +1,7 @@ server_scripts { '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', + 'locales/br.lua', 'locales/de.lua', 'locales/en.lua', 'locales/fr.lua', @@ -10,6 +11,7 @@ server_scripts { client_scripts { '@es_extended/locale.lua', + 'locales/br.lua', 'locales/de.lua', 'locales/en.lua', 'locales/fr.lua', From 3e3a6ccccd69c2df253931ee2a3ae4c7f927b164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 27 Aug 2017 10:02:44 +0200 Subject: [PATCH 0645/3224] Remove config --- config.lua | 75 ------------------------------------------------------ 1 file changed, 75 deletions(-) delete mode 100644 config.lua diff --git a/config.lua b/config.lua deleted file mode 100644 index 547c835e..00000000 --- a/config.lua +++ /dev/null @@ -1,75 +0,0 @@ -Config = {} - -Config.accounts = {'bank', 'black_money'} -Config.accountLabels = {'Banque', 'Argent Sale'} -- FR ---Config.accountLabels = {'Bank', 'Dirty Money'} -- EN -Config.PaycheckInterval = 7 * 60000 -Config.ShowDotAbovePlayer = false -Config.RemoveInventoryItemDelay = 5 * 60000 - -Config.Weapons = { - - {name = 'WEAPON_UNARMED'}, - {name = 'WEAPON_ANIMAL'}, - {name = 'WEAPON_COUGAR'}, - {name = 'WEAPON_KNIFE'}, - {name = 'WEAPON_NIGHTSTICK'}, - {name = 'WEAPON_HAMMER'}, - {name = 'WEAPON_BAT'}, - {name = 'WEAPON_GOLFCLUB'}, - {name = 'WEAPON_CROWBAR'}, - {name = 'WEAPON_PISTOL'}, - {name = 'WEAPON_COMBATPISTOL'}, - {name = 'WEAPON_APPISTOL'}, - {name = 'WEAPON_PISTOL50'}, - {name = 'WEAPON_MICROSMG'}, - {name = 'WEAPON_SMG'}, - {name = 'WEAPON_ASSAULTSMG'}, - {name = 'WEAPON_ASSAULTRIFLE'}, - {name = 'WEAPON_CARBINERIFLE'}, - {name = 'WEAPON_ADVANCEDRIFLE'}, - {name = 'WEAPON_MG'}, - {name = 'WEAPON_COMBATMG'}, - {name = 'WEAPON_PUMPSHOTGUN'}, - {name = 'WEAPON_SAWNOFFSHOTGUN'}, - {name = 'WEAPON_ASSAULTSHOTGUN'}, - {name = 'WEAPON_BULLPUPSHOTGUN'}, - {name = 'WEAPON_STUNGUN'}, - {name = 'WEAPON_SNIPERRIFLE'}, - {name = 'WEAPON_HEAVYSNIPER'}, - {name = 'WEAPON_REMOTESNIPER'}, - {name = 'WEAPON_GRENADELAUNCHER'}, - {name = 'WEAPON_GRENADELAUNCHER_SMOKE'}, - {name = 'WEAPON_RPG'}, - {name = 'WEAPON_PASSENGER_ROCKET'}, - {name = 'WEAPON_AIRSTRIKE_ROCKET'}, - {name = 'WEAPON_STINGER'}, - {name = 'WEAPON_MINIGUN'}, - {name = 'WEAPON_GRENADE'}, - {name = 'WEAPON_STICKYBOMB'}, - {name = 'WEAPON_SMOKEGRENADE'}, - {name = 'WEAPON_BZGAS'}, - {name = 'WEAPON_MOLOTOV'}, - {name = 'WEAPON_FIREEXTINGUISHER'}, - {name = 'WEAPON_PETROLCAN'}, - {name = 'WEAPON_DIGISCANNER'}, - {name = 'WEAPON_BRIEFCASE'}, - {name = 'WEAPON_BRIEFCASE_02'}, - {name = 'WEAPON_BALL'}, - {name = 'WEAPON_FLARE'}, - {name = 'WEAPON_VEHICLE_ROCKET'}, - {name = 'WEAPON_BARBED_WIRE'}, - {name = 'WEAPON_DROWNING'}, - {name = 'WEAPON_DROWNING_IN_VEHICLE'}, - {name = 'WEAPON_BLEEDING'}, - {name = 'WEAPON_ELECTRIC_FENCE'}, - {name = 'WEAPON_EXPLOSION'}, - {name = 'WEAPON_FALL'}, - {name = 'WEAPON_EXHAUSTION'}, - {name = 'WEAPON_HIT_BY_WATER_CANNON'}, - {name = 'WEAPON_RAMMED_BY_CAR'}, - {name = 'WEAPON_RUN_OVER_BY_CAR'}, - {name = 'WEAPON_HELI_CRASH'}, - {name = 'WEAPON_FIRE'} - -} \ No newline at end of file From d60322b044529923b4c904b43f2fd1c93ea02ffa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 27 Aug 2017 10:03:02 +0200 Subject: [PATCH 0646/3224] Remove config --- config.lua | 75 ------------------------------------------------------ 1 file changed, 75 deletions(-) delete mode 100644 config.lua diff --git a/config.lua b/config.lua deleted file mode 100644 index 547c835e..00000000 --- a/config.lua +++ /dev/null @@ -1,75 +0,0 @@ -Config = {} - -Config.accounts = {'bank', 'black_money'} -Config.accountLabels = {'Banque', 'Argent Sale'} -- FR ---Config.accountLabels = {'Bank', 'Dirty Money'} -- EN -Config.PaycheckInterval = 7 * 60000 -Config.ShowDotAbovePlayer = false -Config.RemoveInventoryItemDelay = 5 * 60000 - -Config.Weapons = { - - {name = 'WEAPON_UNARMED'}, - {name = 'WEAPON_ANIMAL'}, - {name = 'WEAPON_COUGAR'}, - {name = 'WEAPON_KNIFE'}, - {name = 'WEAPON_NIGHTSTICK'}, - {name = 'WEAPON_HAMMER'}, - {name = 'WEAPON_BAT'}, - {name = 'WEAPON_GOLFCLUB'}, - {name = 'WEAPON_CROWBAR'}, - {name = 'WEAPON_PISTOL'}, - {name = 'WEAPON_COMBATPISTOL'}, - {name = 'WEAPON_APPISTOL'}, - {name = 'WEAPON_PISTOL50'}, - {name = 'WEAPON_MICROSMG'}, - {name = 'WEAPON_SMG'}, - {name = 'WEAPON_ASSAULTSMG'}, - {name = 'WEAPON_ASSAULTRIFLE'}, - {name = 'WEAPON_CARBINERIFLE'}, - {name = 'WEAPON_ADVANCEDRIFLE'}, - {name = 'WEAPON_MG'}, - {name = 'WEAPON_COMBATMG'}, - {name = 'WEAPON_PUMPSHOTGUN'}, - {name = 'WEAPON_SAWNOFFSHOTGUN'}, - {name = 'WEAPON_ASSAULTSHOTGUN'}, - {name = 'WEAPON_BULLPUPSHOTGUN'}, - {name = 'WEAPON_STUNGUN'}, - {name = 'WEAPON_SNIPERRIFLE'}, - {name = 'WEAPON_HEAVYSNIPER'}, - {name = 'WEAPON_REMOTESNIPER'}, - {name = 'WEAPON_GRENADELAUNCHER'}, - {name = 'WEAPON_GRENADELAUNCHER_SMOKE'}, - {name = 'WEAPON_RPG'}, - {name = 'WEAPON_PASSENGER_ROCKET'}, - {name = 'WEAPON_AIRSTRIKE_ROCKET'}, - {name = 'WEAPON_STINGER'}, - {name = 'WEAPON_MINIGUN'}, - {name = 'WEAPON_GRENADE'}, - {name = 'WEAPON_STICKYBOMB'}, - {name = 'WEAPON_SMOKEGRENADE'}, - {name = 'WEAPON_BZGAS'}, - {name = 'WEAPON_MOLOTOV'}, - {name = 'WEAPON_FIREEXTINGUISHER'}, - {name = 'WEAPON_PETROLCAN'}, - {name = 'WEAPON_DIGISCANNER'}, - {name = 'WEAPON_BRIEFCASE'}, - {name = 'WEAPON_BRIEFCASE_02'}, - {name = 'WEAPON_BALL'}, - {name = 'WEAPON_FLARE'}, - {name = 'WEAPON_VEHICLE_ROCKET'}, - {name = 'WEAPON_BARBED_WIRE'}, - {name = 'WEAPON_DROWNING'}, - {name = 'WEAPON_DROWNING_IN_VEHICLE'}, - {name = 'WEAPON_BLEEDING'}, - {name = 'WEAPON_ELECTRIC_FENCE'}, - {name = 'WEAPON_EXPLOSION'}, - {name = 'WEAPON_FALL'}, - {name = 'WEAPON_EXHAUSTION'}, - {name = 'WEAPON_HIT_BY_WATER_CANNON'}, - {name = 'WEAPON_RAMMED_BY_CAR'}, - {name = 'WEAPON_RUN_OVER_BY_CAR'}, - {name = 'WEAPON_HELI_CRASH'}, - {name = 'WEAPON_FIRE'} - -} \ No newline at end of file From 11f85e81897079261e9f87c8f6f8b200445db0c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 27 Aug 2017 10:03:20 +0200 Subject: [PATCH 0647/3224] Remove config --- config.lua | 75 ------------------------------------------------------ 1 file changed, 75 deletions(-) delete mode 100644 config.lua diff --git a/config.lua b/config.lua deleted file mode 100644 index 547c835e..00000000 --- a/config.lua +++ /dev/null @@ -1,75 +0,0 @@ -Config = {} - -Config.accounts = {'bank', 'black_money'} -Config.accountLabels = {'Banque', 'Argent Sale'} -- FR ---Config.accountLabels = {'Bank', 'Dirty Money'} -- EN -Config.PaycheckInterval = 7 * 60000 -Config.ShowDotAbovePlayer = false -Config.RemoveInventoryItemDelay = 5 * 60000 - -Config.Weapons = { - - {name = 'WEAPON_UNARMED'}, - {name = 'WEAPON_ANIMAL'}, - {name = 'WEAPON_COUGAR'}, - {name = 'WEAPON_KNIFE'}, - {name = 'WEAPON_NIGHTSTICK'}, - {name = 'WEAPON_HAMMER'}, - {name = 'WEAPON_BAT'}, - {name = 'WEAPON_GOLFCLUB'}, - {name = 'WEAPON_CROWBAR'}, - {name = 'WEAPON_PISTOL'}, - {name = 'WEAPON_COMBATPISTOL'}, - {name = 'WEAPON_APPISTOL'}, - {name = 'WEAPON_PISTOL50'}, - {name = 'WEAPON_MICROSMG'}, - {name = 'WEAPON_SMG'}, - {name = 'WEAPON_ASSAULTSMG'}, - {name = 'WEAPON_ASSAULTRIFLE'}, - {name = 'WEAPON_CARBINERIFLE'}, - {name = 'WEAPON_ADVANCEDRIFLE'}, - {name = 'WEAPON_MG'}, - {name = 'WEAPON_COMBATMG'}, - {name = 'WEAPON_PUMPSHOTGUN'}, - {name = 'WEAPON_SAWNOFFSHOTGUN'}, - {name = 'WEAPON_ASSAULTSHOTGUN'}, - {name = 'WEAPON_BULLPUPSHOTGUN'}, - {name = 'WEAPON_STUNGUN'}, - {name = 'WEAPON_SNIPERRIFLE'}, - {name = 'WEAPON_HEAVYSNIPER'}, - {name = 'WEAPON_REMOTESNIPER'}, - {name = 'WEAPON_GRENADELAUNCHER'}, - {name = 'WEAPON_GRENADELAUNCHER_SMOKE'}, - {name = 'WEAPON_RPG'}, - {name = 'WEAPON_PASSENGER_ROCKET'}, - {name = 'WEAPON_AIRSTRIKE_ROCKET'}, - {name = 'WEAPON_STINGER'}, - {name = 'WEAPON_MINIGUN'}, - {name = 'WEAPON_GRENADE'}, - {name = 'WEAPON_STICKYBOMB'}, - {name = 'WEAPON_SMOKEGRENADE'}, - {name = 'WEAPON_BZGAS'}, - {name = 'WEAPON_MOLOTOV'}, - {name = 'WEAPON_FIREEXTINGUISHER'}, - {name = 'WEAPON_PETROLCAN'}, - {name = 'WEAPON_DIGISCANNER'}, - {name = 'WEAPON_BRIEFCASE'}, - {name = 'WEAPON_BRIEFCASE_02'}, - {name = 'WEAPON_BALL'}, - {name = 'WEAPON_FLARE'}, - {name = 'WEAPON_VEHICLE_ROCKET'}, - {name = 'WEAPON_BARBED_WIRE'}, - {name = 'WEAPON_DROWNING'}, - {name = 'WEAPON_DROWNING_IN_VEHICLE'}, - {name = 'WEAPON_BLEEDING'}, - {name = 'WEAPON_ELECTRIC_FENCE'}, - {name = 'WEAPON_EXPLOSION'}, - {name = 'WEAPON_FALL'}, - {name = 'WEAPON_EXHAUSTION'}, - {name = 'WEAPON_HIT_BY_WATER_CANNON'}, - {name = 'WEAPON_RAMMED_BY_CAR'}, - {name = 'WEAPON_RUN_OVER_BY_CAR'}, - {name = 'WEAPON_HELI_CRASH'}, - {name = 'WEAPON_FIRE'} - -} \ No newline at end of file From 983be68c996a72d39c549c416df2e30b4296f9f9 Mon Sep 17 00:00:00 2001 From: Romain Lanz Date: Sun, 27 Aug 2017 10:48:18 +0200 Subject: [PATCH 0648/3224] fix(menu): add align property --- client/main.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 7bd0d8fc..0fc8eb5c 100644 --- a/client/main.lua +++ b/client/main.lua @@ -37,6 +37,7 @@ function ShowBillsMenu() 'default', GetCurrentResourceName(), 'billing', { title = _U('invoices'), + align = 'top-left', elements = elements }, function(data, menu) @@ -71,4 +72,4 @@ Citizen.CreateThread(function() end end -end) \ No newline at end of file +end) From 7255dcab2742dd0e50a41493ee4a9d3609fb3ee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 27 Aug 2017 11:04:30 +0200 Subject: [PATCH 0649/3224] Fix mistake --- client/main.lua | 4 ++++ config.lua | 17 +++++++++-------- server/main.lua | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 8 deletions(-) diff --git a/client/main.lua b/client/main.lua index 30bb4c13..e594e2cb 100644 --- a/client/main.lua +++ b/client/main.lua @@ -257,6 +257,10 @@ AddEventHandler('esx_property:hasEnteredMarker', function(name, part, parking) TriggerServerEvent('esx_garage:setParking', name, parking, vehicleProps) + if Config.EnableOwnedVehicles then + TriggerServerEvent('esx_garage:updateOwnedVehicle', vehicleProps) + end + end end diff --git a/config.lua b/config.lua index f53456ad..6bce9fc5 100644 --- a/config.lua +++ b/config.lua @@ -1,11 +1,12 @@ -Config = {} -Config.DrawDistance = 100.0 -Config.MarkerType = 1 -Config.MarkerSize = {x = 2.0, y = 2.0, z = 1.0} -Config.MarkerColor = {r = 204, g = 204, b = 0} -Config.ParkingMarkerSize = {x = 3.0, y = 3.0, z = 2.0} -Config.ParkingMarkerColor = {r = 102, g = 102, b = 204} -Config.ZDiff = 0.5 +Config = {} +Config.DrawDistance = 100.0 +Config.MarkerType = 1 +Config.MarkerSize = {x = 2.0, y = 2.0, z = 1.0} +Config.MarkerColor = {r = 204, g = 204, b = 0} +Config.ParkingMarkerSize = {x = 3.0, y = 3.0, z = 2.0} +Config.ParkingMarkerColor = {r = 102, g = 102, b = 204} +Config.ZDiff = 0.5 +Config.EnableOwnedVehicles = true Config.Locale = 'fr' diff --git a/server/main.lua b/server/main.lua index 458539bb..1a07fd5a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -38,6 +38,49 @@ AddEventHandler('esx_garage:setParking', function(garage, zone, vehicleProps) end) +RegisterServerEvent('esx_vehicleshop:updateOwnedVehicle') +AddEventHandler('esx_vehicleshop:updateOwnedVehicle', function(vehicleProps) + + local _source = source + local xPlayer = ESX.GetPlayerFromId(source) + + MySQL.Async.fetchAll( + 'SELECT * FROM owned_vehicles WHERE owner = @owner', + { + ['@owner'] = xPlayer.identifier + }, + function(results) + + local foundVehicleId = nil + + for i=1, #result, 1 do + + local vehicle = json.decode(result[i].vehicle) + + if vehicle.plate == vehicleProps.plate then + foundVehicleId = result[i].id + break + end + + end + + if foundVehicleId ~= nil then + + MySQL.Async.execute( + 'UPDATE owned_vehicles SET vehicle = @vehicle WHERE id = @id', + { + ['@vehicle'] = json.encode(vehicleProps), + ['@id'] = foundVehicleId + } + ) + + end + + end + ) + +end) + ESX.RegisterServerCallback('esx_vehicleshop:getVehiclesInGarage', function(source, cb, garage) local xPlayer = ESX.GetPlayerFromId(source) From 772df8c70b3c01044169879772f990367d092967 Mon Sep 17 00:00:00 2001 From: Moonblaze1995 Date: Sun, 27 Aug 2017 09:56:03 -0500 Subject: [PATCH 0650/3224] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5f6a3402..73d442e3 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,10 @@ Just take example on the files in the jobs folder. 1. CD in your resources/[esx] folder 2. Clone the repository ``` - git clone https://github.com/FXServer-ESX/fxserver-esx_jobs esx_drugs + git clone https://github.com/FXServer-ESX/fxserver-esx_jobs esx_jobs ``` 3. Import esx_jobs.sql into your database 4. Add this into your server.cfg ``` -start esx_drugs +start esx_jobs ``` From e6f11d56c2a046fc4e686f18bd1b5aeee1907b1a Mon Sep 17 00:00:00 2001 From: Pgmbru Date: Sun, 27 Aug 2017 23:06:50 +0200 Subject: [PATCH 0651/3224] Fix trad --- locales/fr.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/fr.lua b/locales/fr.lua index 433c1ab3..746e5154 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -8,5 +8,6 @@ Locales['fr'] = { ['press_menu'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder au menu', ['clothes'] = 'vêtements', ['you_paid'] = 'vous avez payé $', + ['save_in_dressing'] = 'voulez-vous donnez un nom à votre tenue ?', } From 152c447325185be3d5caf8e50a124b0697504a16 Mon Sep 17 00:00:00 2001 From: Pgmbru Date: Sun, 27 Aug 2017 23:07:38 +0200 Subject: [PATCH 0652/3224] Fix trad --- locales/en.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/en.lua b/locales/en.lua index a70acc6b..302e5754 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -8,5 +8,6 @@ Locales['en'] = { ['press_menu'] = 'press ~INPUT_CONTEXT~ to access the menu', ['clothes'] = 'clothes', ['you_paid'] = 'you paid $', + ['save_in_dressing'] = 'Do you want to give a name to your outfit ?', } From b4fb9f1523125d1979209f4bb4d7e6127735777e Mon Sep 17 00:00:00 2001 From: Wesley Moura <14825927+wesleymoura@users.noreply.github.com> Date: Sun, 27 Aug 2017 19:06:43 -0300 Subject: [PATCH 0653/3224] Add Brazilian Language --- __resource.lua | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/__resource.lua b/__resource.lua index 79524ba4..5c8af3ab 100644 --- a/__resource.lua +++ b/__resource.lua @@ -3,20 +3,23 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ESX ClotheShop' server_scripts { - '@mysql-async/lib/MySQL.lua', - '@es_extended/locale.lua', - 'locales/de.lua', - 'locales/en.lua', - 'locales/fr.lua', - 'config.lua', - 'server/main.lua' + '@mysql-async/lib/MySQL.lua', + '@es_extended/locale.lua', + 'locales/br.lua', + 'locales/de.lua', + 'locales/en.lua', + 'locales/fr.lua', + 'config.lua', + 'server/main.lua' } client_scripts { - '@es_extended/locale.lua', - 'locales/de.lua', - 'locales/en.lua', - 'locales/fr.lua', - 'config.lua', - 'client/main.lua' + '@es_extended/locale.lua', + 'locales/br.lua', + 'locales/de.lua', + 'locales/en.lua', + 'locales/fr.lua', + 'config.lua', + 'client/main.lua' } + From e05a0fb6b5e0fbe32c2fe492ee8af51042c3dcef Mon Sep 17 00:00:00 2001 From: Wesley Moura <14825927+wesleymoura@users.noreply.github.com> Date: Sun, 27 Aug 2017 19:06:59 -0300 Subject: [PATCH 0654/3224] Add Brazilian Language --- __resource.lua | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/__resource.lua b/__resource.lua index 32ac26c4..281b21ec 100644 --- a/__resource.lua +++ b/__resource.lua @@ -3,20 +3,22 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ESX BarberShop' server_scripts { - '@es_extended/locale.lua', - 'locales/de.lua', + '@mysql-async/lib/MySQL.lua', + '@es_extended/locale.lua', + 'locales/br.lua', + 'locales/de.lua', 'locales/en.lua', 'locales/fr.lua', - '@mysql-async/lib/MySQL.lua', - 'config.lua', - 'server/main.lua' + 'config.lua', + 'server/main.lua' } client_scripts { '@es_extended/locale.lua', - 'locales/de.lua', + 'locales/br.lua', + 'locales/de.lua', 'locales/en.lua', 'locales/fr.lua', - 'config.lua', - 'client/main.lua' + 'config.lua', + 'client/main.lua' } From b726da03cc47fb3152e54de9c8c95bd61b53215a Mon Sep 17 00:00:00 2001 From: Wesley Moura <14825927+wesleymoura@users.noreply.github.com> Date: Sun, 27 Aug 2017 19:07:39 -0300 Subject: [PATCH 0655/3224] Add Brazilian Language --- locales/br.lua | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 locales/br.lua diff --git a/locales/br.lua b/locales/br.lua new file mode 100644 index 00000000..a2e39b47 --- /dev/null +++ b/locales/br.lua @@ -0,0 +1,14 @@ +Locales['br'] = { + + ['valid_this_purchase'] = 'validar esta compra?', + ['yes'] = 'sim', + ['no'] = 'não', + ['save_in_dressing'] = 'você quer salvar essa roupa??', + ['name_outfit'] = 'nome da roupa?', + ['saved_outfit'] = 'roupa salva', + ['not_enough_money'] = 'você não tem dinheiro suficiente', + ['press_menu'] = 'pressione ~INPUT_CONTEXT~ para acessar o menu', + ['clothes'] = 'roupas', + ['you_paid'] = 'você pagou $', + +} From 93f49924b62127e7e9bab4f459028652ff27c28e Mon Sep 17 00:00:00 2001 From: Wesley Moura <14825927+wesleymoura@users.noreply.github.com> Date: Sun, 27 Aug 2017 19:07:59 -0300 Subject: [PATCH 0656/3224] Add Brazilian Language --- locales/br.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 locales/br.lua diff --git a/locales/br.lua b/locales/br.lua new file mode 100644 index 00000000..0cc4e13a --- /dev/null +++ b/locales/br.lua @@ -0,0 +1,10 @@ +Locales['br'] = { + + ['valid_purchase'] = 'validar esta compra?', + ['yes'] = 'sim', + ['no'] = 'não', + ['not_enough_money'] = 'você não tem dinheiro suficiente', + ['press_access'] = 'pressione ~INPUT_CONTEXT~ para acessar o menu', + ['barber_blip'] = 'Barbearia', + ['you_paid'] = 'você pagou ', +} \ No newline at end of file From 9a89f27a847dd0767c8bde8aebf74539694d4b3f Mon Sep 17 00:00:00 2001 From: Wesley Moura <14825927+wesleymoura@users.noreply.github.com> Date: Sun, 27 Aug 2017 20:52:24 -0300 Subject: [PATCH 0657/3224] Add Brazilian Language --- locales/br.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/br.lua b/locales/br.lua index a2e39b47..18c6faa1 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -3,7 +3,7 @@ Locales['br'] = { ['valid_this_purchase'] = 'validar esta compra?', ['yes'] = 'sim', ['no'] = 'não', - ['save_in_dressing'] = 'você quer salvar essa roupa??', + ['save_in_dressing'] = 'você quer salvar essa roupa?', ['name_outfit'] = 'nome da roupa?', ['saved_outfit'] = 'roupa salva', ['not_enough_money'] = 'você não tem dinheiro suficiente', From 70904e7faf79642098ddea415880bf1fc6af69b4 Mon Sep 17 00:00:00 2001 From: AdrineX Date: Mon, 28 Aug 2017 02:58:00 +0300 Subject: [PATCH 0658/3224] Save modifications to car + get modified car from /pv menu --- server/main.lua | 78 ++++++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/server/main.lua b/server/main.lua index 1a07fd5a..cc60d34a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -38,48 +38,48 @@ AddEventHandler('esx_garage:setParking', function(garage, zone, vehicleProps) end) -RegisterServerEvent('esx_vehicleshop:updateOwnedVehicle') -AddEventHandler('esx_vehicleshop:updateOwnedVehicle', function(vehicleProps) +RegisterServerEvent('esx_garage:updateOwnedVehicle') + AddEventHandler('esx_garage:updateOwnedVehicle', function(vehicleProps) + + local _source = source + local xPlayer = ESX.GetPlayerFromId(source) + + MySQL.Async.fetchAll( + 'SELECT * FROM owned_vehicles WHERE owner = @owner', + { + ['@owner'] = xPlayer.identifier + }, + function(result) + + local foundVehicleId = nil + + for i=1, #result, 1 do + + local vehicle = json.decode(result[i].vehicle) + + if vehicle.plate == vehicleProps.plate then + foundVehicleId = result[i].id + break + end + + end + + if foundVehicleId ~= nil then - local _source = source - local xPlayer = ESX.GetPlayerFromId(source) - - MySQL.Async.fetchAll( - 'SELECT * FROM owned_vehicles WHERE owner = @owner', - { - ['@owner'] = xPlayer.identifier - }, - function(results) - - local foundVehicleId = nil - - for i=1, #result, 1 do - - local vehicle = json.decode(result[i].vehicle) - - if vehicle.plate == vehicleProps.plate then - foundVehicleId = result[i].id - break - end - - end - - if foundVehicleId ~= nil then - - MySQL.Async.execute( - 'UPDATE owned_vehicles SET vehicle = @vehicle WHERE id = @id', - { + MySQL.Async.execute( + 'UPDATE owned_vehicles SET vehicle = @vehicle WHERE id = @id', + { ['@vehicle'] = json.encode(vehicleProps), ['@id'] = foundVehicleId - } - ) - - end - - end - ) - -end) + } + ) + + end + + end + ) + + end) ESX.RegisterServerCallback('esx_vehicleshop:getVehiclesInGarage', function(source, cb, garage) From fd37b71ab1989318de265cdf27b0c9c5e957fc85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 28 Aug 2017 12:51:10 +0200 Subject: [PATCH 0659/3224] Move callback to top of functio --- async.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/async.lua b/async.lua index 5420a306..3c7ab7c8 100644 --- a/async.lua +++ b/async.lua @@ -45,7 +45,6 @@ function Async.parallelLimit(tasks, limit, cb) local function processQueue() if #queue == 0 then - cb(results) return end From 99ac3427209d56c787b7a2c39ce4f55559b1466c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 28 Aug 2017 12:52:20 +0200 Subject: [PATCH 0660/3224] Move callback to top of function --- async.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/async.lua b/async.lua index 3c7ab7c8..378dec29 100644 --- a/async.lua +++ b/async.lua @@ -33,6 +33,10 @@ end function Async.parallelLimit(tasks, limit, cb) + if #tasks = 0 then + cb(results) + end + local remaining = #tasks local running = 0 local queue = {} From 749bf802e3056a35932a3993bb897d5d464d34fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 28 Aug 2017 12:53:01 +0200 Subject: [PATCH 0661/3224] Fix error --- async.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/async.lua b/async.lua index 378dec29..ba2783f9 100644 --- a/async.lua +++ b/async.lua @@ -34,7 +34,7 @@ end function Async.parallelLimit(tasks, limit, cb) if #tasks = 0 then - cb(results) + cb({}) end local remaining = #tasks From 94082664fc2898a577893ff67039339a0375a12a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 28 Aug 2017 12:54:16 +0200 Subject: [PATCH 0662/3224] Fix error --- async.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/async.lua b/async.lua index ba2783f9..9a9f59ed 100644 --- a/async.lua +++ b/async.lua @@ -33,7 +33,7 @@ end function Async.parallelLimit(tasks, limit, cb) - if #tasks = 0 then + if #tasks == 0 then cb({}) end From ec2c7cd6a9f9aea47e0e4ba75633fe8c8364705f Mon Sep 17 00:00:00 2001 From: Charly Date: Tue, 29 Aug 2017 21:26:18 +0200 Subject: [PATCH 0663/3224] correction --- locales/fr.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/fr.lua b/locales/fr.lua index 746e5154..44ae4f02 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -8,6 +8,6 @@ Locales['fr'] = { ['press_menu'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder au menu', ['clothes'] = 'vêtements', ['you_paid'] = 'vous avez payé $', - ['save_in_dressing'] = 'voulez-vous donnez un nom à votre tenue ?', + ['save_in_dressing'] = 'voulez-vous donner un nom à votre tenue ?', } From e58dc08318bd21ae3ad1e71a5888e6a8cb66bf26 Mon Sep 17 00:00:00 2001 From: Aleweadan Date: Wed, 30 Aug 2017 00:26:24 +0200 Subject: [PATCH 0664/3224] Update esx_realestateagentjob.sql --- esx_realestateagentjob.sql | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/esx_realestateagentjob.sql b/esx_realestateagentjob.sql index 0b6de025..f7fc3ffb 100644 --- a/esx_realestateagentjob.sql +++ b/esx_realestateagentjob.sql @@ -1,16 +1,16 @@ USE `essentialmode`; INSERT INTO `addon_account` (name, label, shared) VALUES - ('society_realestateagent','Immobilienverkauf',1) + ('society_realestateagent','Agent immobilier',1) ; INSERT INTO `jobs` (name, label) VALUES - ('realestateagent','Immobilienverkauf') + ('realestateagent','Agent immobilier') ; INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES - ('realestateagent',0,'location','Vermieter',10,'{}','{}'), - ('realestateagent',1,'vendeur','Verkäufer',25,'{}','{}'), - ('realestateagent',2,'gestion','Manager',40,'{}','{}'), - ('realestateagent',3,'boss','Boss',0,'{}','{}') + ('realestateagent',0,'location','Location',10,'{}','{}'), + ('realestateagent',1,'vendeur','Vendeur',25,'{}','{}'), + ('realestateagent',2,'gestion','Gestion',40,'{}','{}'), + ('realestateagent',3,'boss','Patron',0,'{}','{}') ; From ee242c0b92d140c5e18f1e569a844298e69f649f Mon Sep 17 00:00:00 2001 From: Aleweadan Date: Wed, 30 Aug 2017 00:27:57 +0200 Subject: [PATCH 0665/3224] Update fr.lua --- locales/fr.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/fr.lua b/locales/fr.lua index 60217531..e89be8a6 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,6 +1,6 @@ Locales['fr'] = { - ['new_job'] = 'vous avez nouveau job !', + ['new_job'] = 'vous avez un nouveau job !', ['access_job_center'] = 'appuyez sur ~INPUT_PICKUP~ pour \naccéder au ~b~Pôle Emploi~s~.', ['job_center'] = 'pôle-Emploi', From a2e53dd64e2054ffa8a8285983820a40e4de8b8a Mon Sep 17 00:00:00 2001 From: renaiku Date: Wed, 30 Aug 2017 12:57:48 +0200 Subject: [PATCH 0666/3224] paint colors and return bugfixes --- client/main.lua | 6 ++++-- config.lua | 22 ++++++++++++++++------ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/client/main.lua b/client/main.lua index 3938d12b..1178ce49 100644 --- a/client/main.lua +++ b/client/main.lua @@ -110,8 +110,7 @@ function GetAction(data) local vehicle = GetVehiclePedIsIn(playerPed, false) local currentMods = ESX.Game.GetVehicleProperties(vehicle) - for k,v in pairs(Config - .Menus) do + for k,v in pairs(Config.Menus) do if data.value == k then @@ -123,6 +122,9 @@ function GetAction(data) if v.modType == 22 then table.insert(elements, {label = " " .. _U('by_default'), modType = k, modNum = false}) + elseif v.modType == 'color1' or v.modType == 'color2' or v.modType == 'pearlescentColor' or v.modType == 'wheelColor' then + local num = myCar[v.modType] + table.insert(elements, {label = " " .. _U('by_default'), modType = k, modNum = num}) else table.insert(elements, {label = " " .. _U('by_default'), modType = k, modNum = -1}) end diff --git a/config.lua b/config.lua index aef63381..67cfa883 100644 --- a/config.lua +++ b/config.lua @@ -418,37 +418,37 @@ Config.Menus = { }, modEngine = { label = _U('engine'), - parent = 'modEngine', + parent = 'upgrades', modType = 11, price = 500 }, modBrakes = { label = _U('brakes'), - parent = 'modBrakes', + parent = 'upgrades', modType = 12, price = 500 }, modTransmission = { label = _U('transmission'), - parent = 'modTransmission', + parent = 'upgrades', modType = 13, price = 500 }, modSuspension = { label = _U('suspension'), - parent = 'modSuspension', + parent = 'upgrades', modType = 15, price = 500 }, modArmor = { label = _U('armor'), - parent = 'modArmor', + parent = 'upgrades', modType = 16, price = 500 }, modTurbo = { label = _U('turbo'), - parent = 'modTurbo', + parent = 'upgrades', modType = 18, price = 500 }, @@ -621,51 +621,61 @@ Config.Menus = { }, modFrontBumper = { label = _U('frontbumper'), + parent = 'bodyparts', modType = 1, price = 500 }, modRearBumper = { label = _U('rearbumper'), + parent = 'bodyparts', modType = 2, price = 500 }, modSideSkirt = { label = _U('sideskirt'), + parent = 'bodyparts', modType = 3, price = 500 }, modExhaust = { label = _U('exhaust'), + parent = 'bodyparts', modType = 4, price = 500 }, modFrame = { label = _U('cage'), + parent = 'bodyparts', modType = 5, price = 500 }, modGrille = { label = _U('grille'), + parent = 'bodyparts', modType = 6, price = 500 }, modHood = { label = _U('hood'), + parent = 'bodyparts', modType = 7, price = 500 }, modFender = { label = _U('leftfender'), + parent = 'bodyparts', modType = 8, price = 500 }, modRightFender = { label = _U('rightfender'), + parent = 'bodyparts', modType = 9, price = 500 }, modRoof = { label = _U('roof'), + parent = 'bodyparts', modType = 10, price = 500 }, From 04eda375973d5cc76151bed1d232912f9350c083 Mon Sep 17 00:00:00 2001 From: renaiku Date: Wed, 30 Aug 2017 13:18:23 +0200 Subject: [PATCH 0667/3224] vehicle is saved each time you buy something (pressing enter) --- client/main.lua | 1 + server/main.lua | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/client/main.lua b/client/main.lua index 1178ce49..8767cde6 100644 --- a/client/main.lua +++ b/client/main.lua @@ -15,6 +15,7 @@ RegisterNetEvent('esx_lscustom:installMod') AddEventHandler('esx_lscustom:installMod', function() local vehicle = GetVehiclePedIsIn(GetPlayerPed(-1), false) myCar = ESX.Game.GetVehicleProperties(vehicle) + TriggerServerEvent('esx_lscustom:refreshOwnedVehicle', myCar) end) RegisterNetEvent('esx_lscustom:cancelInstallMod') diff --git a/server/main.lua b/server/main.lua index 26ebe2a7..de331d01 100644 --- a/server/main.lua +++ b/server/main.lua @@ -15,3 +15,14 @@ AddEventHandler('esx_lscustom:buyMod', function(price) TriggerClientEvent('esx:showNotification', _source, _U('purchased')) end end) + +RegisterServerEvent('esx_lscustom:refreshOwnedVehicle') +AddEventHandler('esx_lscustom:refreshOwnedVehicle', function(myCar) + + MySQL.Async.execute( + 'UPDATE `owned_vehicles` SET `vehicle` = @vehicle WHERE `vehicle` LIKE "%' .. myCar['plate'] .. '%"', + { + ['@vehicle'] = json.encode(myCar) + } + ) +end) \ No newline at end of file From b7a7f77c324778de2bdd35f4e07b1827e03156da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 30 Aug 2017 17:22:07 +0200 Subject: [PATCH 0668/3224] Bandwith optimization + Add ESX.SetTimeout / ESX.ClearTimeout serverside --- .../es_extended/client/functions.lua | 325 +++++++++--------- .../[essential]/es_extended/client/main.lua | 74 ++-- resources/[essential]/es_extended/config.lua | 2 +- .../[essential]/es_extended/server/common.lua | 27 +- .../es_extended/server/functions.lua | 15 +- 5 files changed, 251 insertions(+), 192 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index f2394e18..87e53b3b 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -5,6 +5,7 @@ for i = 65, 90 do table.insert(Charset, string.char(i)) end for i = 97, 122 do table.insert(Charset, string.char(i)) end ESX = {} +ESX.PlayerData = {} ESX.CurrentRequestId = 0 ESX.ServerCallbacks = {} ESX.TimeoutCallbacks = {} @@ -996,210 +997,206 @@ ESX.Game.Utils.DrawText3D = function(coords, text, size) end ESX.ShowInventory = function() - - ESX.TriggerServerCallback('esx:getPlayerData', function(data) - local playerPed = GetPlayerPed(-1) - local elements = {} + local playerPed = GetPlayerPed(-1) + local elements = {} + table.insert(elements, { + label = '[Cash] $' .. ESX.PlayerData.money, + count = ESX.PlayerData.money, + type = 'item_money', + value = 'money', + usable = false, + rare = false, + canRemove = true + }) + + for i=1, #ESX.PlayerData.accounts, 1 do table.insert(elements, { - label = '[Cash] $' .. data.money, - count = data.money, - type = 'item_money', - value = 'money', + label = '[' .. ESX.PlayerData.accounts[i].label .. '] $' .. ESX.PlayerData.accounts[i].money, + count = ESX.PlayerData.accounts[i].money, + type = 'item_account', + value = ESX.PlayerData.accounts[i].name, usable = false, rare = false, canRemove = true }) + end - for i=1, #data.accounts, 1 do + for i=1, #ESX.PlayerData.inventory, 1 do + + if ESX.PlayerData.inventory[i].count > 0 then table.insert(elements, { - label = '[' .. data.accounts[i].label .. '] $' .. data.accounts[i].money, - count = data.accounts[i].money, - type = 'item_account', - value = data.accounts[i].name, + label = ESX.PlayerData.inventory[i].label .. ' x' .. ESX.PlayerData.inventory[i].count, + count = ESX.PlayerData.inventory[i].count, + type = 'item_standard', + value = ESX.PlayerData.inventory[i].name, + usable = ESX.PlayerData.inventory[i].usable, + rare = ESX.PlayerData.inventory[i].rare, + canRemove = ESX.PlayerData.inventory[i].canRemove, + }) + end + + end + + for i=1, #Config.Weapons, 1 do + + local weaponHash = GetHashKey(Config.Weapons[i].name) + + if HasPedGotWeapon(playerPed, weaponHash, false) and Config.Weapons[i].name ~= 'WEAPON_UNARMED' then + + local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) + + table.insert(elements, { + label = Config.Weapons[i].label .. ' x1 [' .. ammo .. ']', + count = 1, + type = 'item_weapon', + value = Config.Weapons[i].name, usable = false, rare = false, canRemove = true }) + end + end - for i=1, #data.inventory, 1 do + ESX.UI.Menu.CloseAll() - if data.inventory[i].count > 0 then - table.insert(elements, { - label = data.inventory[i].label .. ' x' .. data.inventory[i].count, - count = data.inventory[i].count, - type = 'item_standard', - value = data.inventory[i].name, - usable = data.inventory[i].usable, - rare = data.inventory[i].rare, - canRemove = data.inventory[i].canRemove, - }) + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'inventory', + { + title = _U('inventory'), + align = 'bottom-right', + elements = elements, + }, + function(data, menu) + + menu.close() + + local elements = {} + + if data.current.usable then + table.insert(elements, {label = _U('use'), action = 'use', type = data.current.type, value = data.current.value}) end - end - - for i=1, #Config.Weapons, 1 do - - local weaponHash = GetHashKey(Config.Weapons[i].name) - - if HasPedGotWeapon(playerPed, weaponHash, false) and Config.Weapons[i].name ~= 'WEAPON_UNARMED' then - - local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) - - table.insert(elements, { - label = Config.Weapons[i].label .. ' x1 [' .. ammo .. ']', - count = 1, - type = 'item_weapon', - value = Config.Weapons[i].name, - usable = false, - rare = false, - canRemove = true - }) - + if data.current.canRemove then + table.insert(elements, {label = _U('give'), action = 'give', type = data.current.type, value = data.current.value}) + table.insert(elements, {label = _U('remove'), action = 'remove', type = data.current.type, value = data.current.value}) end - end - ESX.UI.Menu.CloseAll() + table.insert(elements, {label = _U('return'), action = 'return'}) - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'inventory', - { - title = _U('inventory'), - align = 'bottom-right', - elements = elements, - }, - function(data, menu) + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'inventory_item', + { + title = _U('inventory'), + align = 'bottom-right', + elements = elements, + }, + function(data, menu) - menu.close() + local item = data.current.value + local type = data.current.type - local elements = {} + if data.current.action == 'give' then - if data.current.usable then - table.insert(elements, {label = _U('use'), action = 'use', type = data.current.type, value = data.current.value}) - end + if type == 'item_weapon' then - if data.current.canRemove then - table.insert(elements, {label = _U('give'), action = 'give', type = data.current.type, value = data.current.value}) - table.insert(elements, {label = _U('remove'), action = 'remove', type = data.current.type, value = data.current.value}) - end + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - table.insert(elements, {label = _U('return'), action = 'return'}) + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(_U('players_nearby')) + else + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 1) + end - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'inventory_item', - { - title = _U('inventory'), - align = 'bottom-right', - elements = elements, - }, - function(data, menu) + else - local item = data.current.value - local type = data.current.type + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'inventory_item_count_give', + { + title = _U('amount') + }, + function(data2, menu2) - if data.current.action == 'give' then + local quantity = tonumber(data2.value) + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if type == 'item_weapon' then + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(_U('players_nearby')) + else + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) + end - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + menu2.close() + menu.close() - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(_U('players_nearby')) - else - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 1) + end, + function(data2, menu2) + menu2.close() end + ) - else - - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'inventory_item_count_give', - { - title = _U('amount') - }, - function(data2, menu2) - - local quantity = tonumber(data2.value) - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(_U('players_nearby')) - else - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) - end - - menu2.close() - menu.close() - - end, - function(data2, menu2) - menu2.close() - end - ) - - end - - elseif data.current.action == 'remove' then - - if type == 'item_weapon' then - - TriggerServerEvent('esx:removeInventoryItem', type, item, 1) - menu.close() - - else - - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'inventory_item_count_remove', - { - title = _U('amount') - }, - function(data2, menu2) - - local quantity = tonumber(data2.value) - - if quantity == nil then - ESX.ShowNotification(_U('amount_invalid')) - else - TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) - end - - menu2.close() - menu.close() - - end, - function(data2, menu2) - menu2.close() - end - ) - - end - - elseif data.current.action == 'use' then - - TriggerServerEvent('esx:useItem', data.current.value) - - elseif data.current.action == 'return' then - - ESX.UI.Menu.CloseAll() - ESX.ShowInventory() - end + + elseif data.current.action == 'remove' then + + if type == 'item_weapon' then + + TriggerServerEvent('esx:removeInventoryItem', type, item, 1) + menu.close() + + else + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'inventory_item_count_remove', + { + title = _U('amount') + }, + function(data2, menu2) + + local quantity = tonumber(data2.value) + + if quantity == nil then + ESX.ShowNotification(_U('amount_invalid')) + else + TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) + end + + menu2.close() + menu.close() + + end, + function(data2, menu2) + menu2.close() + end + ) + + end + + elseif data.current.action == 'use' then + + TriggerServerEvent('esx:useItem', data.current.value) + + elseif data.current.action == 'return' then - end, - function(data, menu) ESX.UI.Menu.CloseAll() ESX.ShowInventory() + end - ) + + end, + function(data, menu) + ESX.UI.Menu.CloseAll() + ESX.ShowInventory() + end + ) - end, - function(data, menu) - menu.close() - end - ) - - end) + end, + function(data, menu) + menu.close() + end + ) end diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index efd451d2..45387806 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -21,7 +21,8 @@ local Pickups = {} RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) - PlayerLoaded = true + PlayerLoaded = true + ESX.PlayerData = xPlayer for i=1, #xPlayer.accounts, 1 do @@ -63,24 +64,20 @@ AddEventHandler('playerSpawned', function() Citizen.Wait(0) end - ESX.TriggerServerCallback('esx:getPlayerData', function(data) - - local playerPed = GetPlayerPed(-1) + local playerPed = GetPlayerPed(-1) - -- Restore position - if data.lastPosition ~= nil then - SetEntityCoords(playerPed, data.lastPosition.x, data.lastPosition.y, data.lastPosition.z) - end + -- Restore position + if ESX.PlayerData.lastPosition ~= nil then + SetEntityCoords(playerPed, ESX.PlayerData.lastPosition.x, ESX.PlayerData.lastPosition.y, ESX.PlayerData.lastPosition.z) + end - -- Restore loadout - for i=1, #data.loadout, 1 do - local weaponHash = GetHashKey(data.loadout[i].name) - GiveWeaponToPed(playerPed, weaponHash, data.loadout[i].ammo, false, false) - end + -- Restore loadout + for i=1, #ESX.PlayerData.loadout, 1 do + local weaponHash = GetHashKey(ESX.PlayerData.loadout[i].name) + GiveWeaponToPed(playerPed, weaponHash, ESX.PlayerData.loadout[i].ammo, false, false) + end - LoadoutLoaded = true - - end) + LoadoutLoaded = true end) @@ -97,31 +94,46 @@ AddEventHandler('skinchanger:modelLoaded', function() end -- Restore loadout - ESX.TriggerServerCallback('esx:getPlayerData', function(data) - local playerPed = GetPlayerPed(-1) + local playerPed = GetPlayerPed(-1) - for i=1, #data.loadout, 1 do - local weaponHash = GetHashKey(data.loadout[i].name) - GiveWeaponToPed(playerPed, weaponHash, data.loadout[i].ammo, false, false) - end + for i=1, #ESX.PlayerData.loadout, 1 do + local weaponHash = GetHashKey(ESX.PlayerData.loadout[i].name) + GiveWeaponToPed(playerPed, weaponHash, ESX.PlayerData.loadout[i].ammo, false, false) + end - LoadoutLoaded = true - - end) + LoadoutLoaded = true end) RegisterNetEvent('esx:setAccountMoney') AddEventHandler('esx:setAccountMoney', function(account) + + for i=1, #ESX.PlayerData.accounts, 1 do + if ESX.PlayerData.accounts[i].name == account.name then + ESX.PlayerData.accounts[i] = account + end + end + ESX.UI.HUD.UpdateElement('account_' .. account.name, { money = account.money }) end) +RegisterNetEvent('es:activateMoney') +AddEventHandler('es:activateMoney', function(money) + ESX.PlayerData.money = money +end) + RegisterNetEvent('esx:addInventoryItem') AddEventHandler('esx:addInventoryItem', function(item, count) + for i=1, #ESX.PlayerData.inventory, 1 do + if ESX.PlayerData.inventory[i].name == item.name then + ESX.PlayerData.inventory[i] = item + end + end + ESX.UI.ShowInventoryItemNotification(true, item, count) if ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then @@ -133,6 +145,12 @@ end) RegisterNetEvent('esx:removeInventoryItem') AddEventHandler('esx:removeInventoryItem', function(item, count) + for i=1, #ESX.PlayerData.inventory, 1 do + if ESX.PlayerData.inventory[i].name == item.name then + ESX.PlayerData.inventory[i] = item + end + end + ESX.UI.ShowInventoryItemNotification(false, item, count) if ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then @@ -141,6 +159,11 @@ AddEventHandler('esx:removeInventoryItem', function(item, count) end) +RegisterNetEvent('esx:setJob') +AddEventHandler('esx:setJob', function(job) + ESX.PlayerData.job = job +end) + RegisterNetEvent('esx:addWeapon') AddEventHandler('esx:addWeapon', function(weaponName, ammo) local playerPed = GetPlayerPed(-1) @@ -431,6 +454,7 @@ Citizen.CreateThread(function() end if loadoutChanged and LoadoutLoaded then + ESX.PlayerData.loadout = loadout TriggerServerEvent('esx:updateLoadout', loadout) end diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua index 8b280075..02da4807 100644 --- a/resources/[essential]/es_extended/config.lua +++ b/resources/[essential]/es_extended/config.lua @@ -7,5 +7,5 @@ Config.PaycheckInterval = 7 * 60000 Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true Config.RemoveInventoryItemDelay = 5 * 60000 -Config.EnableWeaponPickup = false +Config.EnableWeaponPickup = true Config.Locale = 'fr' diff --git a/resources/[essential]/es_extended/server/common.lua b/resources/[essential]/es_extended/server/common.lua index 6676db37..f8b1c72d 100644 --- a/resources/[essential]/es_extended/server/common.lua +++ b/resources/[essential]/es_extended/server/common.lua @@ -3,6 +3,7 @@ ESX.Players = {} ESX.UsableItemsCallbacks = {} ESX.Items = {} ESX.ServerCallbacks = {} +ESX.TimeoutCallbacks = {} ESX.LastPlayerData = {} ESX.Pickups = {} ESX.PickupId = 0 @@ -73,4 +74,28 @@ AddEventHandler('esx:triggerServerCallback', function(name, requestId, ...) TriggerClientEvent('esx:serverCallback', _source, requestId, ...) end, ...) -end) \ No newline at end of file +end) + +-- SetTimeout +CreateThread(function() + while true do + + Wait(0) + + local currTime = os.clock() * 1000 + + for i=1, #ESX.TimeoutCallbacks, 1 do + + if ESX.TimeoutCallbacks[i] ~= nil then + + if currTime >= ESX.TimeoutCallbacks[i].time then + ESX.TimeoutCallbacks[i].cb() + ESX.TimeoutCallbacks[i] = nil + end + + end + + end + + end +end) diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index 4c6ee6b3..1ac85f8e 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -20,6 +20,18 @@ ESX.GetRandomString = function(length) end +ESX.SetTimeout = function(msec, cb) + table.insert(ESX.TimeoutCallbacks, { + time = os.clock() * 1000 + msec, + cb = cb + }) + return #ESX.TimeoutCallbacks +end + +ESX.ClearTimeout = function(i) + ESX.TimeoutCallbacks[i] = nil +end + ESX.RegisterServerCallback = function(name, cb) ESX.ServerCallbacks[name] = cb end @@ -249,4 +261,5 @@ ESX.CreatePickup = function(type, name, count, label, player) ESX.PickupId = pickupId -end \ No newline at end of file +end + From 2fa1b2b4c3ae8f2a51fed97fb20542f1c42270b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 30 Aug 2017 17:22:57 +0200 Subject: [PATCH 0669/3224] Add timeouts to save data --- server/classes/datastore.lua | 47 +++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/server/classes/datastore.lua b/server/classes/datastore.lua index 482c493c..cfab64d6 100644 --- a/server/classes/datastore.lua +++ b/server/classes/datastore.lua @@ -6,6 +6,8 @@ function CreateDataStore(name, owner, data) self.owner = owner self.data = data + local timeoutCallbacks = {} + self.set = function(key, val) data[key] = val self.save() @@ -17,25 +19,36 @@ function CreateDataStore(name, owner, data) self.save = 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, - } - ) - 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, - } - ) + for i=1, #timeoutCallbacks, 1 do + ESX.ClearTimeout(timeoutCallbacks[i]) + timeoutCallbacks[i] = nil end + 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, + } + ) + 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, + } + ) + end + + end) + + table.insert(timeoutCallbacks, timeoutCallback) + end return self From 10a903c9e0e97d89866ee952502a221d95c1576d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 30 Aug 2017 18:04:22 +0200 Subject: [PATCH 0670/3224] Add ESX.GetClosestPed --- .../es_extended/client/functions.lua | 44 +++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 87e53b3b..6857bae5 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -617,18 +617,54 @@ ESX.Game.GetVehiclesInArea = function(coords, area) return vehiclesInArea end -ESX.Game.GetPeds = function() - - local peds = {} +ESX.Game.GetPeds = function(ignoreList) + + local ignoreList = ignoreList or {} + local peds = {} for ped in EnumeratePeds() do - table.insert(peds, ped) + + local found = false + + for j=1, #ignoreList, 1 do + if ignoreList[j] == ped then + found = true + end + end + + if not found then + table.insert(peds, ped) + end + end return peds end +ESX.Game.GetClosestPed = function(coords, ignoreList) + + local ignoreList = ignoreList or {} + local peds = ESX.Game.GetPeds(ignoreList) + local closestDistance = -1 + local closestPed = -1 + + for i=1, #peds, 1 do + + local pedCoords = GetEntityCoords(peds[i]) + local distance = GetDistanceBetweenCoords(pedCoords.x, pedCoords.y, pedCoords.z, coords.x, coords.y, coords.z, true) + + if closestDistance == -1 or closestDistance > distance then + closestPed = peds[i] + closestDistance = distance + end + + end + + return closestPed, closestDistance + +end + ESX.Game.GetVehicleProperties = function(vehicle) local color1, color2 = GetVehicleColours(vehicle) From 9c849044d588e0c7f430de856b4ec81c06cf4d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 30 Aug 2017 18:07:18 +0200 Subject: [PATCH 0671/3224] Add ESX.PlayerLoaded --- resources/[essential]/es_extended/client/functions.lua | 1 + resources/[essential]/es_extended/client/main.lua | 9 ++++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 6857bae5..6cc0363c 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -6,6 +6,7 @@ for i = 97, 122 do table.insert(Charset, string.char(i)) end ESX = {} ESX.PlayerData = {} +ESX.PlayerLoaded = false ESX.CurrentRequestId = 0 ESX.ServerCallbacks = {} ESX.TimeoutCallbacks = {} diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index 45387806..309e8cda 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -12,7 +12,6 @@ local Keys = { local GUI = {} GUI.Time = 0 -local PlayerLoaded = false local LoadoutLoaded = false local IsPaused = false local LastLoadout = {} @@ -21,8 +20,8 @@ local Pickups = {} RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) - PlayerLoaded = true - ESX.PlayerData = xPlayer + ESX.PlayerLoaded = true + ESX.PlayerData = xPlayer for i=1, #xPlayer.accounts, 1 do @@ -60,7 +59,7 @@ AddEventHandler('playerSpawned', function() Citizen.CreateThread(function() - while not PlayerLoaded do + while not ESX.PlayerLoaded do Citizen.Wait(0) end @@ -89,7 +88,7 @@ end) AddEventHandler('skinchanger:modelLoaded', function() - while not PlayerLoaded do + while not ESX.PlayerLoaded do Citizen.Wait(0) end From 4f63c141b9adef6fe6a487a84a0a40bed3650b04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 30 Aug 2017 19:40:49 +0200 Subject: [PATCH 0672/3224] Fix position with new system --- .../[essential]/es_extended/client/main.lua | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index 309e8cda..66ed6b61 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -546,5 +546,25 @@ Citizen.CreateThread(function() end + end +end) + +-- Last position +Citizen.CreateThread(function() + while true do + + Citizen.Wait(1000) + + if ESX ~= nil and ESX.PlayerLoaded then + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + if not IsEntityDead(playerPed) then + ESX.PlayerData.lastPosition = {x = coords.x, y = coords.y, z = coords.z} + end + + end + end end) \ No newline at end of file From 7f33a1549dd6c1f9bf05066260fdbc421f376f36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 30 Aug 2017 19:42:33 +0200 Subject: [PATCH 0673/3224] Fix position --- client/main.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/client/main.lua b/client/main.lua index a2372e0c..2c1fb9bf 100644 --- a/client/main.lua +++ b/client/main.lua @@ -74,6 +74,7 @@ function StartRespawnToHospitalMenuTimer() ESX.TriggerServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function() + ESX.PlayerData.lastPosition = Config.Zones.HospitalInteriorInside1.Pos TriggerServerEvent('esx:updateLastPosition', Config.Zones.HospitalInteriorInside1.Pos) RespawnPed(GetPlayerPed(-1), Config.Zones.HospitalInteriorInside1.Pos) From 2bc7caef0e159a59de2d8feb8c29ec7635b680ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 30 Aug 2017 23:29:01 +0200 Subject: [PATCH 0674/3224] Add ESX.IsPlayerLoaded --- resources/[essential]/es_extended/client/functions.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 6cc0363c..e8a8028e 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -47,6 +47,10 @@ ESX.ClearTimeout = function(i) ESX.TimeoutCallbacks[i] = nil end +ESX.IsPlayerLoaded = function() + return ESX.PlayerLoaded +end + ESX.ShowNotification = function(msg) SetNotificationTextEntry('STRING') AddTextComponentString(msg) From 7e4838fb6e9af6f9f631170f14e7f9fe4755b6b1 Mon Sep 17 00:00:00 2001 From: renaiku Date: Wed, 30 Aug 2017 23:29:05 +0200 Subject: [PATCH 0675/3224] MYSQL fix --- __resource.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/__resource.lua b/__resource.lua index 88f56ca1..699b368a 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,4 +1,5 @@ server_scripts { + '@mysql-async/lib/MySQL.lua', '@es_extended/locale.lua', 'locales/de.lua', 'locales/en.lua', From b285ae9c8935a45c95a06c17413a4c40a8bff7a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 30 Aug 2017 23:45:19 +0200 Subject: [PATCH 0676/3224] Add ESX.GetPlayerData() --- resources/[essential]/es_extended/client/functions.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index e8a8028e..81142ee2 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -51,6 +51,10 @@ ESX.IsPlayerLoaded = function() return ESX.PlayerLoaded end +ESX.GetPlayerData = function() + return ESX.PlayerData +end + ESX.ShowNotification = function(msg) SetNotificationTextEntry('STRING') AddTextComponentString(msg) From 4c88c72b50c36177939ce6685b7839a434f502b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 31 Aug 2017 00:59:34 +0200 Subject: [PATCH 0677/3224] Add ESX.SetPlayerData --- resources/[essential]/es_extended/client/functions.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 81142ee2..7c6eb4b8 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -55,6 +55,10 @@ ESX.GetPlayerData = function() return ESX.PlayerData end +ESX.SetPlayerData = function(key, val) + ESX.PlayerData[key] = val +end + ESX.ShowNotification = function(msg) SetNotificationTextEntry('STRING') AddTextComponentString(msg) From dd389b53f73468d526c1c1ea874e5129ef594000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 31 Aug 2017 01:01:35 +0200 Subject: [PATCH 0678/3224] Fix respawn position --- client/main.lua | 6 +++++- config.lua | 10 +++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/client/main.lua b/client/main.lua index 2c1fb9bf..3424420f 100644 --- a/client/main.lua +++ b/client/main.lua @@ -74,7 +74,7 @@ function StartRespawnToHospitalMenuTimer() ESX.TriggerServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function() - ESX.PlayerData.lastPosition = Config.Zones.HospitalInteriorInside1.Pos + ESX.SetPlayerData('lastPosition', Config.Zones.HospitalInteriorInside1.Pos) TriggerServerEvent('esx:updateLastPosition', Config.Zones.HospitalInteriorInside1.Pos) RespawnPed(GetPlayerPed(-1), Config.Zones.HospitalInteriorInside1.Pos) @@ -113,6 +113,7 @@ function StartRespawnTimer() ESX.TriggerServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function() + ESX.SetPlayerData('lastPosition', Config.Zones.HospitalInteriorInside1.Pos) TriggerServerEvent('esx:updateLastPosition', Config.Zones.HospitalInteriorInside1.Pos) RespawnPed(GetPlayerPed(-1), Config.Zones.HospitalInteriorInside1.Pos) @@ -172,6 +173,7 @@ function RespawnTimer() ESX.TriggerServerCallback('esx_ambulancejob:removeItemsAfterRPDeathRemoveMoney', function() TriggerServerEvent('esx_ambulancejob:removeAccountMoney', source) + ESX.SetPlayerData('lastPosition', Config.Zones.HospitalInteriorInside1.Pos) TriggerServerEvent('esx:updateLastPosition', Config.Zones.HospitalInteriorInside1.Pos) RespawnPed(GetPlayerPed(-1), Config.Zones.HospitalInteriorInside1.Pos) @@ -220,6 +222,7 @@ function RespawnTimer() ESX.TriggerServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function() + ESX.SetPlayerData('lastPosition', Config.Zones.HospitalInteriorInside1.Pos) TriggerServerEvent('esx:updateLastPosition', Config.Zones.HospitalInteriorInside1.Pos) RespawnPed(GetPlayerPed(-1), Config.Zones.HospitalInteriorInside1.Pos) @@ -662,6 +665,7 @@ AddEventHandler('esx_ambulancejob:revive', function() Citizen.Wait(0) end + ESX.SetPlayerData('lastPosition', Config.Zones.HospitalInteriorInside1.Pos) TriggerServerEvent('esx:updateLastPosition', { x = coords.x, y = coords.y, diff --git a/config.lua b/config.lua index 6331f291..02206d7b 100644 --- a/config.lua +++ b/config.lua @@ -7,11 +7,11 @@ Config.RemoveWeaponsAfterRPDeath = true Config.RemoveCashAfterRPDeath = true Config.RemoveItemsAfterRPDeath = true Config.EnablePlayerManagement = false -Config.ShowDeathTimer = false -Config.EarlyRespawn = false -Config.EarlyRespawnFine = false -Config.EarlyRespawnFineAmount = 500 -Config.Locale = 'fr' +Config.ShowDeathTimer = true +Config.EarlyRespawn = true +Config.EarlyRespawnFine = true +Config.EarlyRespawnFineAmount = 500 +Config.Locale = 'fr' Config.Zones = { From a10f4df910f2e81554e5e78b9b360df777811ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 31 Aug 2017 09:50:19 +0200 Subject: [PATCH 0679/3224] Fix player spawn --- .../[essential]/es_extended/client/main.lua | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index 66ed6b61..82664623 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -14,6 +14,7 @@ local GUI = {} GUI.Time = 0 local LoadoutLoaded = false local IsPaused = false +local PlayerSpawned = false local LastLoadout = {} local Pickups = {} @@ -77,6 +78,7 @@ AddEventHandler('playerSpawned', function() end LoadoutLoaded = true + PlayerSpawned = true end) @@ -352,16 +354,12 @@ AddEventHandler('esx:spawnPed', function(model) Citizen.CreateThread(function() - print(model) - RequestModel(model) while not HasModelLoaded(model) do Citizen.Wait(0) end - print('LOADED') - CreatePed(5, model, x, y, z, 0.0, true, false) end) @@ -551,11 +549,12 @@ end) -- Last position Citizen.CreateThread(function() + while true do Citizen.Wait(1000) - if ESX ~= nil and ESX.PlayerLoaded then + if ESX ~= nil and ESX.PlayerLoaded and PlayerSpawned then local playerPed = GetPlayerPed(-1) local coords = GetEntityCoords(playerPed) @@ -567,4 +566,20 @@ Citizen.CreateThread(function() end end + +end) + +Citizen.CreateThread(function() + + while true do + + Citizen.Wait(0) + + local playerPed = GetPlayerPed(-1) + + if IsEntityDead(playerPed) and PlayerSpawned then + PlayerSpawned = false + end + end + end) \ No newline at end of file From a6390d1038a4cd9f93cfa136ba8e0fdf253dd028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 31 Aug 2017 09:51:01 +0200 Subject: [PATCH 0680/3224] Fix revive --- client/main.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 3424420f..0f85f2d1 100644 --- a/client/main.lua +++ b/client/main.lua @@ -665,7 +665,12 @@ AddEventHandler('esx_ambulancejob:revive', function() Citizen.Wait(0) end - ESX.SetPlayerData('lastPosition', Config.Zones.HospitalInteriorInside1.Pos) + ESX.SetPlayerData('lastPosition', { + x = coords.x, + y = coords.y, + z = coords.z + ) + TriggerServerEvent('esx:updateLastPosition', { x = coords.x, y = coords.y, From 1bfefc2931067d6835af39fc16cecc4634082c77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 31 Aug 2017 09:51:33 +0200 Subject: [PATCH 0681/3224] Fix revive --- client/main.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index 0f85f2d1..605e2c1c 100644 --- a/client/main.lua +++ b/client/main.lua @@ -669,8 +669,8 @@ AddEventHandler('esx_ambulancejob:revive', function() x = coords.x, y = coords.y, z = coords.z - ) - + }) + TriggerServerEvent('esx:updateLastPosition', { x = coords.x, y = coords.y, From 755d11b8920745b5917f054d356b038b444fecfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 31 Aug 2017 11:08:29 +0200 Subject: [PATCH 0682/3224] Fix helicpoter spawn --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index b37eeb9a..b5a05f3c 100644 --- a/client/main.lua +++ b/client/main.lua @@ -956,7 +956,7 @@ AddEventHandler('esx_policejob:hasEnteredMarker', function(station, part, partNu local helicopters = Config.PoliceStations[station].Helicopters local vehicle = GetClosestVehicle(helicopters[partNum].SpawnPoint.x, helicopters[partNum].SpawnPoint.y, helicopters[partNum].SpawnPoint.z, 3.0, 0, 71) - if DoesEntityExist(vehicle) then + if not DoesEntityExist(vehicle) then ESX.Game.SpawnVehicle('polmav', { x = helicopters[partNum].SpawnPoint.x, From 0c33748f9dbd810a4c604e470b94d32ea9afeaf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 31 Aug 2017 13:28:25 +0200 Subject: [PATCH 0683/3224] Helicopter fix #2 --- client/main.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index b5a05f3c..8df0062b 100644 --- a/client/main.lua +++ b/client/main.lua @@ -954,9 +954,8 @@ AddEventHandler('esx_policejob:hasEnteredMarker', function(station, part, partNu if part == 'HelicopterSpawner' then local helicopters = Config.PoliceStations[station].Helicopters - local vehicle = GetClosestVehicle(helicopters[partNum].SpawnPoint.x, helicopters[partNum].SpawnPoint.y, helicopters[partNum].SpawnPoint.z, 3.0, 0, 71) - if not DoesEntityExist(vehicle) then + if not IsAnyVehicleNearPoint(helicopters[partNum].SpawnPoint.x, helicopters[partNum].SpawnPoint.y, helicopters[partNum].SpawnPoint.z, 3.0) then ESX.Game.SpawnVehicle('polmav', { x = helicopters[partNum].SpawnPoint.x, From 9ac17cf76d3c5845dbe606e3dfb9016ff2d13dd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 2 Sep 2017 00:21:58 +0200 Subject: [PATCH 0684/3224] Add esx:setJob server event + ESX.Trace + increase save timeout --- resources/[essential]/es_extended/config.lua | 2 ++ .../es_extended/server/classes/player.lua | 3 +++ .../[essential]/es_extended/server/functions.lua | 14 ++++++++++---- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua index 02da4807..b6714cc6 100644 --- a/resources/[essential]/es_extended/config.lua +++ b/resources/[essential]/es_extended/config.lua @@ -9,3 +9,5 @@ Config.DisableWantedLevel = true Config.RemoveInventoryItemDelay = 5 * 60000 Config.EnableWeaponPickup = true Config.Locale = 'fr' +Config.EnableDebug = false + diff --git a/resources/[essential]/es_extended/server/classes/player.lua b/resources/[essential]/es_extended/server/classes/player.lua index 107960e7..6a29f4f1 100644 --- a/resources/[essential]/es_extended/server/classes/player.lua +++ b/resources/[essential]/es_extended/server/classes/player.lua @@ -318,6 +318,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.setJob = function(name, grade) + local lastJob = json.decode(json.encode(self.job)) + MySQL.Async.fetchAll( 'SELECT * FROM `jobs` WHERE `name` = @name', { @@ -353,6 +355,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.job['skin_female'] = json.decode(result[1].skin_female) end + TriggerEvent("esx:setJob", self.source, self.job, lastJob) TriggerClientEvent("esx:setJob", self.source, self.job) end diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index 1ac85f8e..fad63172 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -4,6 +4,12 @@ for i = 48, 57 do table.insert(Charset, string.char(i)) end for i = 65, 90 do table.insert(Charset, string.char(i)) end for i = 97, 122 do table.insert(Charset, string.char(i)) end +ESX.Trace = function(str) + if Config.EnableDebug then + print('ESX> ' .. str) + end +end + ESX.GetConfig = function() return Config end @@ -148,7 +154,7 @@ ESX.SavePlayers = function(cb) end) end - Async.parallelLimit(asyncTasks, 15, function(results) + Async.parallelLimit(asyncTasks, 8, function(results) RconPrint('[SAVED] All players' .. "\n") @@ -164,15 +170,15 @@ ESX.StartDBSync = function() function saveData() ESX.SavePlayers() - SetTimeout(60000, saveData) + SetTimeout(10 * 60 * 1000, saveData) end - SetTimeout(60000, saveData) + SetTimeout(10 * 60 * 1000, saveData) end ESX.StartPayCheck = function() - + function payCheck() local xPlayers = ESX.GetPlayers() From 3b9973fa9acfee8b977785aa7ce72f31bf22bbff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 2 Sep 2017 00:35:35 +0200 Subject: [PATCH 0685/3224] Rewrite phone => No more server lags --- client/main.lua | 26 ++++- html/scripts/app.js | 6 ++ html/scripts/app_de.js | 104 ++++++++++---------- html/scripts/app_en.js | 104 ++++++++++---------- locales/br.lua | 2 +- locales/en.lua | 2 +- locales/fr.lua | 2 +- server/main.lua | 215 ++++++++++++++++++++++++----------------- 8 files changed, 266 insertions(+), 195 deletions(-) diff --git a/client/main.lua b/client/main.lua index 5ba395b5..ed69f73c 100644 --- a/client/main.lua +++ b/client/main.lua @@ -23,6 +23,7 @@ local CurrentAction = nil local CurrentActionMsg = '' local CurrentActionData = {} local CurrentDispatchRequestId = -1 +local PhoneNumberSources = {} Citizen.CreateThread(function() @@ -71,6 +72,7 @@ AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) PhoneData.contacts = {} for i=1, #contacts, 1 do + contacts[i].online = (PhoneNumberSources[contacts[i].number] == nil and false or NetworkIsPlayerActive(GetPlayerFromServerId(PhoneNumberSources[contacts[i].number]))), table.insert(PhoneData.contacts, contacts[i]) end @@ -82,12 +84,12 @@ AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) end) RegisterNetEvent('esx_phone:addContact') -AddEventHandler('esx_phone:addContact', function(name, phoneNumber, isOnline) +AddEventHandler('esx_phone:addContact', function(name, phoneNumber) table.insert(PhoneData.contacts, { name = name, number = phoneNumber, - online = isOnline + online = (PhoneNumberSources[contacts[i].number] == nil and false or NetworkIsPlayerActive(GetPlayerFromServerId(PhoneNumberSources[contacts[i].number]))), }) -- CALL HERE RELOADCONTACT SendNUIMessage({ @@ -133,7 +135,7 @@ end) RegisterNetEvent('esx_phone:onMessage') AddEventHandler('esx_phone:onMessage', function(phoneNumber, message, position, anon, job, dispatchRequestId) - ESX.ShowNotification(_U('new_message')) + ESX.ShowNotification(_U('new_message', message)) SendNUIMessage({ newMessage = true, @@ -177,6 +179,16 @@ AddEventHandler('esx_phone:stopDispatch', function(dispatchRequestId, playerName end) +RegisterNetEvent('esx_phone:setPhoneNumberSource') +AddEventHandler('esx_phone:setPhoneNumberSource', function(phoneNumber, source) + + if source == -1 then + PhoneNumberSources[phoneNumber] = nil + else + PhoneNumberSources[phoneNumber] = source + end +end) + RegisterNUICallback('setGPS', function(data) SetNewWaypoint(data.x, data.y) ESX.ShowNotification(_U('gps_position')) @@ -185,12 +197,18 @@ end) RegisterNUICallback('send', function(data) local phoneNumber = data.number + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) if tonumber(phoneNumber) ~= nil then phoneNumber = tonumber(phoneNumber) end - TriggerServerEvent('esx_phone:send', phoneNumber, data.message, data.anonyme) + TriggerServerEvent('esx_phone:send', phoneNumber, data.message, data.anonyme, { + x = coords.x, + y = coords.y, + z = coords.z + }) SendNUIMessage({ showMessageEditor = false diff --git a/html/scripts/app.js b/html/scripts/app.js index a4f64f5a..3afebe53 100644 --- a/html/scripts/app.js +++ b/html/scripts/app.js @@ -36,6 +36,7 @@ let showMain = function() { $('.screen').removeClass('active'); + $('.screen *').attr('disabled', 'disabled'); } let showRepertoire = function() { @@ -58,6 +59,8 @@ let showAddContact = function() { $('#contact').addClass('active'); + $('.screen *').attr('disabled', 'disabled'); + $('.screen.active *').removeAttr('disabled'); } let hideAddContact = function() { @@ -70,6 +73,8 @@ $('#writer').addClass('active'); $('#writer_number').val(cnum); $('#writer .header-title').html(cname); + $('.screen *').attr('disabled', 'disabled'); + $('.screen.active *').removeAttr('disabled'); } let hideNewMessage = function() { @@ -145,6 +150,7 @@ let showPhone = function(phoneData){ reloadPhone(phoneData); $('#phone').show(); + showMain(); isPhoneShowed = true; } diff --git a/html/scripts/app_de.js b/html/scripts/app_de.js index bdc0e71f..fa6bb6a7 100644 --- a/html/scripts/app_de.js +++ b/html/scripts/app_de.js @@ -1,6 +1,6 @@ (function(){ - - let ContactTpl = + + let ContactTpl = '
    ' + '
    ' + '
    ' + @@ -10,15 +10,15 @@ '
    ' + '
    ' ; - - let MessageTpl = + + let MessageTpl = '
    ' + '
    ' + '
    ' + '{{sender}}
    #{{phoneNumber}}' + - '
    ' + - '
    ' + - '
    {{message}}
    ' + + '
    ' + + '
    ' + + '
    {{message}}
    ' + '
    ' + '
    ' ; @@ -33,52 +33,57 @@ let isMessageEditorOpen = false; let isMessagesOpen = false; let isPhoneShowed = false; - + let showMain = function() { $('.screen').removeClass('active'); + $('.screen *').attr('disabled', 'disabled'); } - + let showRepertoire = function() { $('#repertoire').addClass('active'); } - + let hideRepertoire = function() { $('#repertoire').removeClass('active'); } - - let showMessages = function(){ + + let showMessages = function(){ $('#messages').addClass('active'); isMessagesOpen = true; } - let hideMessages = function(){ + let hideMessages = function(){ $('#messages').removeClass('active'); isMessagesOpen = false; } - + let showAddContact = function() { $('#contact').addClass('active'); + $('.screen *').attr('disabled', 'disabled'); + $('.screen.active *').removeAttr('disabled'); } - + let hideAddContact = function() { $('#contact').removeClass('active'); $('#contact_name').val(''); $('#contact_number').val(''); } - + let showNewMessage = function(cnum, cname) { $('#writer').addClass('active'); $('#writer_number').val(cnum); $('#writer .header-title').html(cname); + $('.screen *').attr('disabled', 'disabled'); + $('.screen.active *').removeAttr('disabled'); } - let hideNewMessage = function() { + let hideNewMessage = function() { $('#writer').removeClass('active'); $('#writer_number').val(''); $('#writer_message').val(''); $('#writer .header-title').html(''); } - + let showGPS = function(xPos, yPos) { $.post('http://esx_phone/setGPS', JSON.stringify({ x: parseFloat(xPos), @@ -88,13 +93,13 @@ } let renderContacts = function(){ - + let contactHTML = ''; - + if(contacts.length > 0) { for(let i=0; i 0) { - + for(let i=0; i' + '
    ' + @@ -10,15 +10,15 @@ '
    ' + '
    ' ; - - let MessageTpl = + + let MessageTpl = '
    ' + '
    ' + '
    ' + '{{sender}}
    #{{phoneNumber}}' + - '
    ' + - '
    ' + - '
    {{message}}
    ' + + '
    ' + + '
    ' + + '
    {{message}}
    ' + '
    ' + '
    ' ; @@ -33,52 +33,57 @@ let isMessageEditorOpen = false; let isMessagesOpen = false; let isPhoneShowed = false; - + let showMain = function() { $('.screen').removeClass('active'); + $('.screen *').attr('disabled', 'disabled'); } - + let showRepertoire = function() { $('#repertoire').addClass('active'); } - + let hideRepertoire = function() { $('#repertoire').removeClass('active'); } - - let showMessages = function(){ + + let showMessages = function(){ $('#messages').addClass('active'); isMessagesOpen = true; } - let hideMessages = function(){ + let hideMessages = function(){ $('#messages').removeClass('active'); isMessagesOpen = false; } - + let showAddContact = function() { $('#contact').addClass('active'); + $('.screen *').attr('disabled', 'disabled'); + $('.screen.active *').removeAttr('disabled'); } - + let hideAddContact = function() { $('#contact').removeClass('active'); $('#contact_name').val(''); $('#contact_number').val(''); } - + let showNewMessage = function(cnum, cname) { $('#writer').addClass('active'); $('#writer_number').val(cnum); $('#writer .header-title').html(cname); + $('.screen *').attr('disabled', 'disabled'); + $('.screen.active *').removeAttr('disabled'); } - let hideNewMessage = function() { + let hideNewMessage = function() { $('#writer').removeClass('active'); $('#writer_number').val(''); $('#writer_message').val(''); $('#writer .header-title').html(''); } - + let showGPS = function(xPos, yPos) { $.post('http://esx_phone/setGPS', JSON.stringify({ x: parseFloat(xPos), @@ -88,13 +93,13 @@ } let renderContacts = function(){ - + let contactHTML = ''; - + if(contacts.length > 0) { for(let i=0; i 0) { - + for(let i=0; i ' .. xPlayer.name .. '@' .. phoneNumber .. ' : ' .. message) - local xPlayer2 = ESX.GetPlayerFromId(xPlayers[j]) - - if xPlayer2.get('phoneNumber') == contacts[i].number then - contacts[i].online = true - end + if PhoneNumbers[phoneNumber] ~= nil then + + for i=1, #PhoneNumbers[phoneNumber].sources, 1 do + + if PhoneNumbers[phoneNumber].sources[i] ~= nil then + + local numType = PhoneNumbers[phoneNumber].type + local numHasDispatch = PhoneNumbers[phoneNumber].hasDispatch + local numHide = PhoneNumbers[phoneNumber].hideNumber + local numHidePosIfAnon = PhoneNumbers[phoneNumber].hidePosIfAnon + local numPosition = (PhoneNumbers[phoneNumber].sharePos and position or false) + local numSource = PhoneNumbers[phoneNumber].sources[i] + + if numHidePosIfAnon and anon then + numPosition = false + end + + if numHasDispatch then + TriggerClientEvent('esx_phone:onMessage', numSource, xPlayer.get('phoneNumber'), message, numPosition, (numHide and true or anon), numType, GetDistpatchRequestId()) + else + TriggerClientEvent('esx_phone:onMessage', numSource, xPlayer.get('phoneNumber'), message, numPosition, (numHide and true or anon), numType, false) end end - xPlayer.set('contacts', contacts) - - TriggerClientEvent('esx_phone:loaded', _source, phoneNumber, contacts) - end - ) -end) - -RegisterServerEvent('esx_phone:registerCallback') -AddEventHandler('esx_phone:registerCallback', function(cb) - table.insert(RegisteredCallbacks, cb) -end) - -RegisterServerEvent('esx_phone:send') -AddEventHandler('esx_phone:send', function(phoneNumber, message, anon) - - local _source = source - - for i=1, #RegisteredCallbacks, 1 do - RegisteredCallbacks[i](_source, phoneNumber, message, anon) end + +end) + +AddEventHandler('esx_phone:registerNumber', function(number, type, sharePos, hasDispatch, hideNumber, hidePosIfAnon) + + local hideNumber = hideNumber or false + local hidePosIfAnon = hidePosIfAnon or false + + PhoneNumbers[number] = { + type = type, + sharePos = sharePos, + hasDispatch = (hasDispatch or false), + hideNumber = hideNumber, + hidePosIfAnon = hidePosIfAnon, + sources = {} + } + +end) + +AddEventHandler('esx_phone:addSource', function(number, source) + + local found = false + + for i=1, #PhoneNumbers[number].sources, 1 do + if PhoneNumbers[number].sources[i] == source then + found = true + break + end + end + + if not found then + table.insert(PhoneNumbers[number].sources, source) + end + +end) + +AddEventHandler('esx_phone:removeSource', function(number, source) + + for i=1, #PhoneNumbers[number].sources, 1 do + if PhoneNumbers[number].sources[i] == source then + PhoneNumbers[number].sources[i] = nil + end + end + end) RegisterServerEvent('esx_phone:addPlayerContact') @@ -244,20 +312,7 @@ AddEventHandler('esx_phone:addPlayerContact', function(phoneNumber, contactName) TriggerClientEvent('esx:showNotification', _source, _U('contact_added')) - local xPlayers = ESX.GetPlayers() - local isOnline = false - - for i=1, #xPlayers, 1 do - - local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) - - if xPlayer2.get('phoneNumber') == phoneNumber then - isOnline = true - break - end - end - - TriggerClientEvent('esx_phone:addContact', _source, contactName, phoneNumber, isOnline) + TriggerClientEvent('esx_phone:addContact', _source, contactName, phoneNumber) end ) @@ -273,26 +328,6 @@ AddEventHandler('esx_phone:addPlayerContact', function(phoneNumber, contactName) end) -AddEventHandler('esx_phone:ready', function() - TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) - - local xPlayer = ESX.GetPlayerFromId(source) - local xPlayers = ESX.GetPlayers() - - print('MESSAGE => ' .. xPlayer.name .. '@' .. phoneNumber .. ' : ' .. message) - - for i=1, #xPlayers, 1 do - - local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) - - if xPlayer2.get('phoneNumber') == phoneNumber then - TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, false, anon, 'player', false) - end - end - - end) -end) - RegisterServerEvent('esx_phone:stopDispatch') AddEventHandler('esx_phone:stopDispatch', function(dispatchRequestId) TriggerClientEvent('esx_phone:stopDispatch', -1, dispatchRequestId, GetPlayerName(source)) From 885af6d46291f313a033642a5b76284f0396f92f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 2 Sep 2017 00:36:55 +0200 Subject: [PATCH 0686/3224] Use new phone --- server/main.lua | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/server/main.lua b/server/main.lua index 7063b953..d8e72d27 100644 --- a/server/main.lua +++ b/server/main.lua @@ -7,6 +7,8 @@ AddEventHandler('esx_ambulancejob:revive', function(target) TriggerClientEvent('esx_ambulancejob:revive', target) end) +TriggerEvent('esx_phone:registerNumber', 'ambulance', _('alert_ambulance'), true, true) + ESX.RegisterServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) @@ -73,26 +75,6 @@ ESX.RegisterServerCallback('esx_ambulancejob:getBankMoney', function(source, cb) cb(money) end) -TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) - - local xPlayer = ESX.GetPlayerFromId(source) - local xPlayers = ESX.GetPlayers() - - if phoneNumber == 'ambulance' then - for i=1, #xPlayers, 1 do - - local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) - - if xPlayer2.job.name == 'ambulance' then - TriggerEvent('esx_phone:getDistpatchRequestId', function(requestId) - TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, _U('alert_ambulance'), requestId) - end) - end - end - end - -end) - TriggerEvent('es:addGroupCommand', 'revive', 'admin', function(source, args, user) if args[2] ~= nil then From 810278523fc5bfc4258fc29341970fc053b4d9d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 2 Sep 2017 00:38:07 +0200 Subject: [PATCH 0687/3224] Use new phone --- server/main.lua | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/server/main.lua b/server/main.lua index d340dde0..dd0d4127 100644 --- a/server/main.lua +++ b/server/main.lua @@ -2,6 +2,8 @@ ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) +TriggerEvent('esx_phone:registerNumber', 'banker', _('bank_customer'), false, false) + RegisterServerEvent('esx_bankerjob:customerDeposit') AddEventHandler('esx_bankerjob:customerDeposit', function(target, amount) @@ -55,24 +57,6 @@ ESX.RegisterServerCallback('esx_bankerjob:getCustomers', function(source, cb) end) -TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) - - local xPlayer = ESX.GetPlayerFromId(source) - local xPlayers = ESX.GetPlayers() - - if phoneNumber == 'banker' then - for i=1, #xPlayers, 1 do - local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) - if xPlayer2.job.name == 'banker' then - TriggerEvent('esx_phone:getDistpatchRequestId', function(requestId) - TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, _U('bank_customer'), false) - end) - end - end - end - -end) - function CalculateBankSavings(d, h, m) local asyncTasks = {} From 563fd1f7c1740b7099a87260140069acc6b5a0f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 2 Sep 2017 00:39:58 +0200 Subject: [PATCH 0688/3224] Use new phone --- server/main.lua | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/server/main.lua b/server/main.lua index 0e2ffb1d..cb98646d 100644 --- a/server/main.lua +++ b/server/main.lua @@ -12,22 +12,8 @@ if Config.MaxInService ~= -1 then TriggerEvent('esx_service:activateService', 'mecano', Config.MaxInService) end -TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) - local xPlayers = ESX.GetPlayers() - - if phoneNumber == 'mecano' then - for i=1, #xPlayers, 1 do - - local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) +TriggerEvent('esx_phone:registerNumber', 'mecano', 'Client mecano', true, true) - if xPlayer2.job.name == 'mecano' then - TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'Appel Mécano') - end - end - end -end) -------------- Récupération bouteille de gaz ------------- ---- Sqlut je teste ------ local function Harvest(source) From 0f9436bc6d5591f0fbb84e6f149fd5b789c50c7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 2 Sep 2017 00:42:05 +0200 Subject: [PATCH 0689/3224] Use new phone --- server/main.lua | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/server/main.lua b/server/main.lua index ed21ebd2..b97d9624 100644 --- a/server/main.lua +++ b/server/main.lua @@ -6,6 +6,8 @@ if Config.MaxInService ~= -1 then TriggerEvent('esx_service:activateService', 'police', Config.MaxInService) end +TriggerEvent('esx_phone:registerNumber', 'police', _('alert_police'), true, true) + RegisterServerEvent('esx_policejob:giveWeapon') AddEventHandler('esx_policejob:giveWeapon', function(weapon, ammo) local xPlayer = ESX.GetPlayerFromId(source) @@ -265,21 +267,3 @@ ESX.RegisterServerCallback('esx_policejob:buy', function(source, cb, amount) end) end) - -TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) - - local xPlayer = ESX.GetPlayerFromId(source) - local xPlayers = ESX.GetPlayers() - - if phoneNumber == 'police' then - for i=1, #xPlayers, 1 do - local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) - if xPlayer2.job.name == 'police' then - TriggerEvent('esx_phone:getDistpatchRequestId', function(requestId) - TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, _('alert_police'), requestId) - end) - end - end - end - -end) \ No newline at end of file From d33b38516fc37771be981bc30050f36868ec6609 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 2 Sep 2017 00:44:34 +0200 Subject: [PATCH 0690/3224] Use new phone --- server/main.lua | 45 ++------------------------------------------- 1 file changed, 2 insertions(+), 43 deletions(-) diff --git a/server/main.lua b/server/main.lua index 2fc0dae8..54d1cd7d 100644 --- a/server/main.lua +++ b/server/main.lua @@ -4,36 +4,13 @@ TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) +TriggerEvent('esx_phone:registerNumber', 'realestateagent', 'Client immo', false, false) + RegisterServerEvent('esx_realestateagentjob:revoke') AddEventHandler('esx_realestateagentjob:revoke', function(property, owner) TriggerEvent('esx_property:removeOwnedPropertyIdentifier', property, owner) end) -AddEventHandler('esx_phone:ready', function() - - TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) - - local xPlayer = ESX.GetPlayerFromId(source) - local xPlayers = ESX.GetPlayers() - local job = 'Client immobilier' - - if phoneNumber == "realestateagent" then - - for i=1, #xPlayers, 1 do - - local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) - - if xPlayer2.job.name == 'realestateagent' then - TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, job, false) - end - end - - end - - end) - -end) - RegisterServerEvent('esx_realestateagentjob:sell') AddEventHandler('esx_realestateagentjob:sell', function(target, property, price) @@ -56,24 +33,6 @@ AddEventHandler('esx_realestateagentjob:rent', function(target, property, price) TriggerEvent('esx_property:setPropertyOwned', property, price, true, xPlayer.identifier) end) -TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) - - local xPlayer = ESX.GetPlayerFromId(source) - local xPlayers = ESX.GetPlayers() - - if phoneNumber == 'realestateagent' then - for i=1, #xPlayers, 1 do - - local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) - - if xPlayer2.job.name == 'realestateagent' then - TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'player') - end - end - end - -end) - ESX.RegisterServerCallback('esx_realestateagentjob:getCustomers', function(source, cb) TriggerEvent('esx_ownedproperty:getOwnedProperties', function(properties) From 4946fd170c14c3d538a58bac4ec6ce6f90ab69aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 2 Sep 2017 00:46:20 +0200 Subject: [PATCH 0691/3224] Use new phone --- server/main.lua | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/server/main.lua b/server/main.lua index 33eca25e..59c7aa30 100644 --- a/server/main.lua +++ b/server/main.lua @@ -6,6 +6,8 @@ if Config.MaxInService ~= -1 then TriggerEvent('esx_service:activateService', 'taxi', Config.MaxInService) end +TriggerEvent('esx_phone:registerNumber', 'taxi', 'Client taxi', true, true) + RegisterServerEvent('esx_taxijob:success') AddEventHandler('esx_taxijob:success', function() @@ -42,21 +44,3 @@ AddEventHandler('esx_taxijob:success', function() end end) - -TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) - - local xPlayer = ESX.GetPlayerFromId(source) - local xPlayers = ESX.GetPlayers() - - if phoneNumber == 'taxi' then - for i=1, #xPlayers, 1 do - local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) - if xPlayer2.job.name == 'taxi' then - TriggerEvent('esx_phone:getDistpatchRequestId', function(requestId) - TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'Appel Taxi', requestId) - end) - end - end - end - -end) From 470045f7925f6e806619467be5b0641c007052c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 2 Sep 2017 00:47:27 +0200 Subject: [PATCH 0692/3224] Use new phone --- server/main.lua | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/server/main.lua b/server/main.lua index c564c4e2..910d5721 100644 --- a/server/main.lua +++ b/server/main.lua @@ -4,6 +4,8 @@ local Vehicles = {} TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) +TriggerEvent('esx_phone:registerNumber', 'cardealer', 'Client concession', false, false) + function RemoveOwnedVehicle(plate) MySQL.Async.fetchAll( @@ -395,22 +397,6 @@ ESX.RegisterServerCallback('esx_vehicleshop:resellVehicle', function(source, cb, end) -TriggerEvent('esx_phone:registerCallback', function(source, phoneNumber, message, anon) - - local xPlayer = ESX.GetPlayerFromId(source) - local xPlayers = ESX.GetPlayers() - - if phoneNumber == 'cardealer' then - for i=1, #xPlayers, 1 do - local xPlayer2 = ESX.GetPlayerFromId(xPlayers[i]) - if xPlayer2.job.name == 'cardealer' then - TriggerClientEvent('esx_phone:onMessage', xPlayer2.source, xPlayer.get('phoneNumber'), message, xPlayer.get('coords'), anon, 'player') - end - end - end - -end) - if Config.EnablePvCommand then TriggerEvent('es:addCommand', 'pv', function(source, args, user) From 58ab6be31e51320eaa099e54c657356d6736feb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 2 Sep 2017 12:15:18 +0200 Subject: [PATCH 0693/3224] Fix lags --- __resource.lua | 2 +- client/classes/status.lua | 50 +++++++++++ client/main.lua | 176 +++++++++++++++++++++++++++----------- config.lua | 7 +- server/main.lua | 129 +++------------------------- 5 files changed, 194 insertions(+), 170 deletions(-) create mode 100644 client/classes/status.lua diff --git a/__resource.lua b/__resource.lua index f3fe55e6..6db3c800 100644 --- a/__resource.lua +++ b/__resource.lua @@ -5,12 +5,12 @@ description 'ESX Status' server_scripts { '@mysql-async/lib/MySQL.lua', 'config.lua', - 'server/classes/status.lua', 'server/main.lua' } client_scripts { 'config.lua', + 'client/classes/status.lua', 'client/main.lua' } diff --git a/client/classes/status.lua b/client/classes/status.lua new file mode 100644 index 00000000..c478a98d --- /dev/null +++ b/client/classes/status.lua @@ -0,0 +1,50 @@ +function CreateStatus(name, default, color, visible, tickCallback) + + local self = {} + + self.val = default + self.name = name + self.default = default + self.color = color + self.visible = visible + self.tickCallback = tickCallback + + self._set = function(k, v) + self[k] = v + end + + self._get = function(k) + return self[k] + end + + self.onTick = function() + self.tickCallback(self) + end + + self.set = function(val) + self.val = val + end + + self.add = function(val) + if self.val + val > Config.StatusMax then + self.val = Config.StatusMax + else + self.val = self.val + val + end + end + + self.remove = function(val) + if self.val - val < 0 then + self.val = 0 + else + self.val = self.val - val + end + end + + self.getPercent = function() + return (self.val / Config.StatusMax) * 100 + end + + return self + +end diff --git a/client/main.lua b/client/main.lua index 4db12de3..140d79ed 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,21 +1,126 @@ local Status = {} -local loaded = false -RegisterNetEvent('esx_status:update') -AddEventHandler('esx_status:update', function(status) +function GetStatusData(minimal) + + local status = {} + + for i=1, #Status, 1 do + + if minimal then + + table.insert(status, { + name = Status[i].name, + val = Status[i].val, + }) + + else + + table.insert(status, { + name = Status[i].name, + val = Status[i].val, + color = Status[i].color, + visible = Status[i].visible(Status[i]), + max = Status[i].max, + }) + + end + + end + + return status + +end + +AddEventHandler('esx_status:registerStatus', function(name, default, color, visible, tickCallback) + local s = CreateStatus(name, default, color, visible, tickCallback) + table.insert(Status, s) +end) + +RegisterNetEvent('esx_status:load') +AddEventHandler('esx_status:load', function(status) + + for i=1, #Status, 1 do + for j=1, #status, 1 do + if Status[i].name == status[j].name then + Status[i].set(status[j].val) + end + end + end + + Citizen.CreateThread(function() + while true do + + for i=1, #Status, 1 do + Status[i].onTick() + end + + SendNUIMessage({ + update = true, + status = GetStatusData() + }) + + Citizen.Wait(Config.TickTime) + + end + end) + +end) + +RegisterNetEvent('esx_status:set') +AddEventHandler('esx_status:set', function(name, val) - Status = status + for i=1, #Status, 1 do + if Status[i].name == name then + Status[i].set(val) + break + end + end SendNUIMessage({ update = true, - status = Status + status = GetStatusData() }) - if not loaded then - TriggerEvent('esx_status:loaded') - loaded = true + TriggerServerEvent('esx_status:update', GetStatusData(true)) + +end) + +RegisterNetEvent('esx_status:add') +AddEventHandler('esx_status:add', function(name, val) + + for i=1, #Status, 1 do + if Status[i].name == name then + Status[i].add(val) + break + end end + SendNUIMessage({ + update = true, + status = GetStatusData() + }) + + TriggerServerEvent('esx_status:update', GetStatusData(true)) + +end) + +RegisterNetEvent('esx_status:remove') +AddEventHandler('esx_status:remove', function(name, val) + + for i=1, #Status, 1 do + if Status[i].name == name then + Status[i].remove(val) + break + end + end + + SendNUIMessage({ + update = true, + status = GetStatusData() + }) + + TriggerServerEvent('esx_status:update', GetStatusData(true)) + end) AddEventHandler('esx_status:getStatus', function(name, cb) @@ -38,48 +143,6 @@ AddEventHandler('esx_status:setDisplay', function(val) end) --- Calculate status -Citizen.CreateThread(function() - while true do - - for i=1, #Status, 1 do - - if Status[i].clientAction.add ~= nil then - - local val = math.floor(Status[i].clientAction.add / (Config.TickTime / Config.ClientTickTime)) - - if Status[i].val + val > Config.StatusMax then - Status[i].val = StatusMax - else - Status[i].val = Status[i].val + val - end - - end - - if Status[i].clientAction.remove ~= nil then - - local val = math.floor(Status[i].clientAction.remove / (Config.TickTime / Config.ClientTickTime)) - - if Status[i].val - val < 0 then - Status[i].val = 0 - else - Status[i].val = Status[i].val - val - end - - end - - end - - SendNUIMessage({ - update = true, - status = Status - }) - - Citizen.Wait(Config.ClientqTickTime) - - end -end) - -- Pause menu disable hud display local isPaused = false @@ -94,4 +157,17 @@ Citizen.CreateThread(function() TriggerEvent('esx_status:setDisplay', 0.5) end end +end) + +-- Loaded event +Citizen.CreateThread(function() + TriggerEvent('esx_status:loaded') +end) + +-- Update server +Citizen.CreateThread(function() + while true do + Citizen.Wait(Config.UpdateInterval) + TriggerServerEvent('esx_status:update', GetStatusData(true)) + end end) \ No newline at end of file diff --git a/config.lua b/config.lua index 1baf3075..3b444340 100644 --- a/config.lua +++ b/config.lua @@ -1,6 +1,5 @@ Config = {} -Config.StatusMax = 1000000 -Config.TickTime = 30000 -Config.ClientTickTime = 1000 -Config.UpdateClientTime = 65000 \ No newline at end of file +Config.StatusMax = 1000000 +Config.TickTime = 1000 +Config.UpdateInterval = 10000 \ No newline at end of file diff --git a/server/main.lua b/server/main.lua index 493065cd..29d75b17 100644 --- a/server/main.lua +++ b/server/main.lua @@ -3,19 +3,6 @@ local RegisteredStatus = {} TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) -AddEventHandler('esx_status:registerStatus', function(name, default, color, visible, tickCallback, clientAction) - - table.insert(RegisteredStatus, { - name = name, - default = default, - color = color, - visible = visible, - tickCallback = tickCallback, - clientAction = clientAction - }) - -end) - AddEventHandler('esx:playerLoaded', function(source) local _source = source @@ -28,36 +15,15 @@ AddEventHandler('esx:playerLoaded', function(source) }, function(result) - local data = {} - local savedStatus = {} + local data = {} if result[1].status ~= nil then data = json.decode(result[1].status) end - for i=1, #data, 1 do - savedStatus[data[i].name] = data[i] - end + xPlayer.set('status', data) - local status = {} - - for i=1, #RegisteredStatus, 1 do - - local s = RegisteredStatus[i] - local default = nil - - if savedStatus[s.name] ~= nil then - default = savedStatus[s.name].val - else - default = s.default - end - - table.insert(status, CreateStatus(xPlayer, s.name, default, s.color, s.visible, s.tickCallback, s.clientAction)) - end - - xPlayer.set('status', status) - - TriggerEvent('esx_status:updateClient', _source) + TriggerClientEvent('esx_status:load', _source, data) end ) @@ -71,20 +37,10 @@ AddEventHandler('esx:playerDropped', function(source) local data = {} local status = xPlayer.get('status') - for i=1, #status, 1 do - - local s = status[i] - - table.insert(data, { - name = s._get('name'), - val = s._get('val') - }) - end - MySQL.Async.execute( 'UPDATE users SET status = @status WHERE identifier = @identifier', { - ['@status'] = json.encode(data), + ['@status'] = json.encode(status), ['@identifier'] = xPlayer.identifier } ) @@ -97,7 +53,7 @@ AddEventHandler('esx_status:getStatus', function(playerId, statusName, cb) local status = xPlayer.get('status') for i=1, #status, 1 do - if status[i]._get('name') == statusName then + if status[i].name == statusName then cb(status[i]) break end @@ -105,61 +61,16 @@ AddEventHandler('esx_status:getStatus', function(playerId, statusName, cb) end) -AddEventHandler('esx_status:updateClient', function(playerId) - - local xPlayer = ESX.GetPlayerFromId(playerId) - local data = {} - local status = xPlayer.get('status') - - for i=1, #status, 1 do - table.insert(data, { - name = status[i]._get('name'), - val = status[i]._get('val'), - color = status[i]._get('color'), - visible = status[i]._get('visible')(status[i]), - clientAction = status[i]._get('clientAction'), - max = Config.StatusMax - }) - end - - TriggerClientEvent('esx_status:update', playerId, data) +RegisterServerEvent('esx_status:update') +AddEventHandler('esx_status:update', function(status) + + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) + + xPlayer.set('status', status) end) -function TickStatus() - - local xPlayers = ESX.GetPlayers() - - for i=1, #xPlayers, 1 do - - local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) - local status = xPlayer.get('status') - - if status ~= nil then - for i=1, #status, 1 do - status[i]._get('onTick')() - end - end - - end - - SetTimeout(Config.TickTime, TickStatus) - -end - -function UpdateClients() - - local xPlayers = ESX.GetPlayers() - - for i=1, #xPlayers, 1 do - local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) - TriggerEvent('esx_status:updateClient', xPlayer.source) - end - - SetTimeout(Config.UpdateClientTime, UpdateClients) - -end - function SaveData() local xPlayers = ESX.GetPlayers() @@ -170,30 +81,18 @@ function SaveData() local data = {} local status = xPlayer.get('status') - for i=1, #status, 1 do - - local s = status[i] - - table.insert(data, { - name = s._get('name'), - val = s._get('val') - }) - end - MySQL.Async.execute( 'UPDATE users SET status = @status WHERE identifier = @identifier', { - ['@status'] = json.encode(data), + ['@status'] = json.encode(status), ['@identifier'] = xPlayer.identifier } ) end - SetTimeout(60000, SaveData) + SetTimeout(10 * 60 * 1000, SaveData) end -TickStatus() -UpdateClients() SaveData() \ No newline at end of file From c0c5fbba0002f901776391046b891385400426d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 2 Sep 2017 12:15:59 +0200 Subject: [PATCH 0694/3224] Use new esx_status --- client/main.lua | 26 ++++++++++++++++++- server/main.lua | 67 ++++++------------------------------------------- 2 files changed, 33 insertions(+), 60 deletions(-) diff --git a/client/main.lua b/client/main.lua index 1ea6d25e..18eea3ff 100644 --- a/client/main.lua +++ b/client/main.lua @@ -8,10 +8,16 @@ Citizen.CreateThread(function() end end) +AddEventHandler('esx_basicneeds:resetStatus', function() + TriggerEvent('esx_status:set', 'hunger', 500000) + TriggerEvent('esx_status:set', 'thirst', 500000) + +end) + AddEventHandler('playerSpawned', function() if IsDead then - TriggerServerEvent('esx_basicneeds:resetStatus') + TriggerEvent('esx_basicneeds:resetStatus') end IsDead = false @@ -19,6 +25,24 @@ end) AddEventHandler('esx_status:loaded', function(status) + TriggerEvent('esx_status:registerStatus', 'hunger', 1000000, '#CFAD0F', + function(status) + return true + end, + function(status) + status.remove(200) + end + ) + + TriggerEvent('esx_status:registerStatus', 'thirst', 1000000, '#0C98F1', + function(status) + return true + end, + function(status) + status.remove(250) + end + ) + Citizen.CreateThread(function() while true do diff --git a/server/main.lua b/server/main.lua index 626cb07e..ced6dbf9 100644 --- a/server/main.lua +++ b/server/main.lua @@ -2,77 +2,26 @@ ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) -TriggerEvent('esx_status:registerStatus', 'hunger', 1000000, '#CFAD0F', - function(status) - return true - end, - function(status) - status.remove(6000) - end, - {remove = 6000} -) - -TriggerEvent('esx_status:registerStatus', 'thirst', 1000000, '#0C98F1', - function(status) - return true - end, - function(status) - status.remove(7500) - end, - {remove = 7500} -) - -RegisterServerEvent('esx_basicneeds:resetStatus') -AddEventHandler('esx_basicneeds:resetStatus', function() - - local _source = source - - TriggerEvent('esx_status:getStatus', _source, 'hunger', function(status) - status.set(500000) - status.updateClient() - end) - - TriggerEvent('esx_status:getStatus', _source, 'thirst', function(status) - status.set(500000) - status.updateClient() - end) - -end) - ESX.RegisterUsableItem('bread', function(source) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) + local xPlayer = ESX.GetPlayerFromId(source) xPlayer.removeInventoryItem('bread', 1) - TriggerEvent('esx_status:getStatus', _source, 'hunger', function(status) - - status.add(200000) - status.updateClient() - - TriggerClientEvent('esx_basicneeds:onEat', _source) - TriggerClientEvent('esx:showNotification', _source, _U('used_bread')) - - end) + TriggerClientEvent('esx_status:add', source, 'hunger', 200000) + TriggerClientEvent('esx_basicneeds:onEat', source) + TriggerClientEvent('esx:showNotification', source, _U('used_bread')) end) ESX.RegisterUsableItem('water', function(source) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) + local xPlayer = ESX.GetPlayerFromId(source) xPlayer.removeInventoryItem('water', 1) - TriggerEvent('esx_status:getStatus', _source, 'thirst', function(status) - - status.add(200000) - status.updateClient() - - TriggerClientEvent('esx_basicneeds:onDrink', _source) - TriggerClientEvent('esx:showNotification', _source, _U('used_water')) - - end) + TriggerClientEvent('esx_status:add', source, 'thirst', 200000) + TriggerClientEvent('esx_basicneeds:onDrink', source) + TriggerClientEvent('esx:showNotification', source, _U('used_water')) end) From f6229f51c46f58cf76a853960be6179efc42949e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 2 Sep 2017 13:17:37 +0200 Subject: [PATCH 0695/3224] Fix inventory limit + move paycheck in separate file --- .../[essential]/es_extended/__resource.lua | 1 + .../es_extended/server/functions.lua | 25 ------------------- .../[essential]/es_extended/server/main.lua | 2 +- .../es_extended/server/paycheck.lua | 24 ++++++++++++++++++ 4 files changed, 26 insertions(+), 26 deletions(-) create mode 100644 resources/[essential]/es_extended/server/paycheck.lua diff --git a/resources/[essential]/es_extended/__resource.lua b/resources/[essential]/es_extended/__resource.lua index 225d2734..9557254a 100644 --- a/resources/[essential]/es_extended/__resource.lua +++ b/resources/[essential]/es_extended/__resource.lua @@ -15,6 +15,7 @@ server_scripts { 'server/common.lua', 'server/classes/player.lua', 'server/functions.lua', + 'server/paycheck.lua', 'server/main.lua', 'server/commands.lua' } diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index fad63172..ffbbe1dd 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -177,31 +177,6 @@ ESX.StartDBSync = function() end -ESX.StartPayCheck = function() - - function payCheck() - - local xPlayers = ESX.GetPlayers() - - for i=1, #xPlayers, 1 do - - local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) - - if xPlayer.job.grade_salary > 0 then - xPlayer.addMoney(xPlayer.job.grade_salary) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('rec_salary') .. '~g~$' .. xPlayer.job.grade_salary) - end - - end - - SetTimeout(Config.PaycheckInterval, payCheck) - - end - - SetTimeout(Config.PaycheckInterval, payCheck) - -end - ESX.GetPlayers = function() local sources = {} diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index e634c744..7985851a 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -305,7 +305,7 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo if itemCount > 0 and sourceItem.count >= itemCount then - if targetItem.limit ~= -1 and (targetItem.count + sourceItem.count) > targetItem.limit then + if targetItem.limit ~= -1 and (targetItem.count + itemCount) > targetItem.limit then TriggerClientEvent('esx:showNotification', target, _U('ex_inv_lim') .. targetXPlayer.name) else sourceXPlayer.removeInventoryItem(itemName, itemCount) diff --git a/resources/[essential]/es_extended/server/paycheck.lua b/resources/[essential]/es_extended/server/paycheck.lua new file mode 100644 index 00000000..f68818a4 --- /dev/null +++ b/resources/[essential]/es_extended/server/paycheck.lua @@ -0,0 +1,24 @@ +ESX.StartPayCheck = function() + + function payCheck() + + local xPlayers = ESX.GetPlayers() + + for i=1, #xPlayers, 1 do + + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + + if xPlayer.job.grade_salary > 0 then + xPlayer.addMoney(xPlayer.job.grade_salary) + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('rec_salary') .. '~g~$' .. xPlayer.job.grade_salary) + end + + end + + SetTimeout(Config.PaycheckInterval, payCheck) + + end + + SetTimeout(Config.PaycheckInterval, payCheck) + +end \ No newline at end of file From 699c5a820c2e4eba73ca463f3406a071404408b2 Mon Sep 17 00:00:00 2001 From: Don <30905704+ddh3@users.noreply.github.com> Date: Sat, 2 Sep 2017 10:13:12 -0700 Subject: [PATCH 0696/3224] added chat help dv, spawn ped Updated en.lua locale for dv, spawn ped --- resources/[essential]/es_extended/locales/en.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/locales/en.lua b/resources/[essential]/es_extended/locales/en.lua index def2cc5e..6f1c10b4 100644 --- a/resources/[essential]/es_extended/locales/en.lua +++ b/resources/[essential]/es_extended/locales/en.lua @@ -29,7 +29,11 @@ Locales['en'] = { ['play_emote'] = 'play emote', ['spawn_car'] = 'spawn a car', ['spawn_car_param'] = 'name of car', + ['delete_vehicle'] = 'deletes Vehicle', + ['delete_veh_param'] = 'press enter', ['spawn_object'] = 'spawn object', + ['spawn_ped'] = 'spawn ped', + ['spawn_ped_param'] = 'example a_m_m_hillbilly_01', ['givemoney'] = 'give money', ['money_amount'] = 'amount of money', ['invalid_account'] = 'invalid account', @@ -119,4 +123,4 @@ Locales['en'] = { ['weapon_flashlight'] = 'flashlight', ['gadget_nightvision'] = 'night vision', ['gadget_parachute'] = 'parachute', -} \ No newline at end of file +} From abb2d8c828c50e1053d43508857f20f832af7c63 Mon Sep 17 00:00:00 2001 From: Don <30905704+ddh3@users.noreply.github.com> Date: Sat, 2 Sep 2017 10:15:07 -0700 Subject: [PATCH 0697/3224] Add chat help dv and spawn ped --- resources/[essential]/es_extended/server/commands.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/[essential]/es_extended/server/commands.lua b/resources/[essential]/es_extended/server/commands.lua index 5d0800e7..461af225 100644 --- a/resources/[essential]/es_extended/server/commands.lua +++ b/resources/[essential]/es_extended/server/commands.lua @@ -51,14 +51,14 @@ TriggerEvent('es:addGroupCommand', 'dv', 'admin', function(source, args, user) TriggerClientEvent('esx:deleteVehicle', source) end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end) +end, {help = _U('delete_vehicle'), params = {{name = "car", help = _U('delete_veh_param')}}}) TriggerEvent('es:addGroupCommand', 'spawnped', 'admin', function(source, args, user) TriggerClientEvent('esx:spawnPed', source, args[2]) end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end) +end, {help = _U('spawn_ped'), params = {{name = "name", help = _U('spawn_ped_param')}}}) TriggerEvent('es:addGroupCommand', 'spawnobject', 'admin', function(source, args, user) TriggerClientEvent('esx:spawnObject', source, args[2]) @@ -133,4 +133,4 @@ TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end, {help = _U('giveweapon'), params = {{name = "id", help = _U('id_param')}, {name = "weapon", help = _U('weapon')}}}) \ No newline at end of file +end, {help = _U('giveweapon'), params = {{name = "id", help = _U('id_param')}, {name = "weapon", help = _U('weapon')}}}) From e05ff4beb0058658dd781beeda5ff1ee2f3d7026 Mon Sep 17 00:00:00 2001 From: Don <30905704+ddh3@users.noreply.github.com> Date: Sat, 2 Sep 2017 10:19:31 -0700 Subject: [PATCH 0698/3224] Update fr.lua --- resources/[essential]/es_extended/locales/fr.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/resources/[essential]/es_extended/locales/fr.lua b/resources/[essential]/es_extended/locales/fr.lua index 02bf1c10..1fb41d49 100644 --- a/resources/[essential]/es_extended/locales/fr.lua +++ b/resources/[essential]/es_extended/locales/fr.lua @@ -29,7 +29,11 @@ Locales['fr'] = { ['play_emote'] = 'jouer emote', ['spawn_car'] = 'spawn un véhicule', ['spawn_car_param'] = 'nom de la voiture', - ['spawn_object'] = 'spawn un objet', + ['delete_vehicle'] = 'supprimer le véhicule', + ['delete_veh_param'] = 'appuyez sur Entrée', + ['spawn_object'] = 'engendre un objet', + ['spawn_ped'] = 'spawn ped', + ['spawn_ped_param'] = 'example a_m_m_hillbilly_01', ['givemoney'] = 'donner de l\'argent', ['money_amount'] = 'somme d\'argent', ['invalid_account'] = 'compete invalide', @@ -119,4 +123,4 @@ Locales['fr'] = { ['weapon_flashlight'] = 'lampe torche', ['gadget_nightvision'] = 'vision nocturne', ['gadget_parachute'] = 'parachute', -} \ No newline at end of file +} From 431a4bba9abd68e40f4dba74ecc84e817e58bc7e Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Sat, 2 Sep 2017 18:00:02 -0400 Subject: [PATCH 0699/3224] Add English JS File --- html/js/app_en.js | 167 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 html/js/app_en.js diff --git a/html/js/app_en.js b/html/js/app_en.js new file mode 100644 index 00000000..9992857c --- /dev/null +++ b/html/js/app_en.js @@ -0,0 +1,167 @@ +(function(){ + + let MenuTpl = + ' +
    +