Merge branch 'esx-framework:main' into production

This commit is contained in:
thefourCraft
2023-02-21 11:24:30 +02:00
committed by GitHub
46 changed files with 1183 additions and 750 deletions
+1 -1
View File
@@ -391,7 +391,7 @@ CREATE TABLE `users` (
`job` varchar(20) DEFAULT 'unemployed',
`job_grade` int(11) DEFAULT 0,
`loadout` longtext DEFAULT NULL,
`position` varchar(255) DEFAULT '{"x":-269.4,"y":-955.3,"z":31.2,"heading":205.8}',
`position` longtext NULL DEFAULT NULL,
`firstname` varchar(16) DEFAULT NULL,
`lastname` varchar(16) DEFAULT NULL,
`dateofbirth` varchar(10) DEFAULT NULL,
@@ -631,8 +631,8 @@ 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.
esx_example
Copyright (C) 2015-2023 Jérémie N'gadi
async
Copyright (C) 2015-2022 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
@@ -652,7 +652,7 @@ 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:
esx_example Copyright (C) 2015-2023 Jérémie N'gadi
async Copyright (C) 2015-2022 Jérémie N'gadi
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.
+15
View File
@@ -0,0 +1,15 @@
<h1 align='center'>[ESX] Async</a></h1><p align='center'><b><a href='https://discord.esx-framework.org/'>Discord</a> - <a href='https://esx-framework.org/'>Website</a> - <a href='https://docs.esx-framework.org/legacy/installation'>Documentation</a></b></h5>
A very Simple resource that allows resources to run tasks asynchronously.
## Legal
async - asynchronous tasks.
Copyright (C) 2015-2022 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/>.
+71
View File
@@ -0,0 +1,71 @@
Async = {}
function Async.parallel(tasks, cb)
if #tasks == 0 then
cb({})
return
end
local remaining = #tasks
local results = {}
for i = 1, #tasks, 1 do
CreateThread(function()
tasks[i](function(result)
results[#results+ 1] = result
remaining = remaining - 1;
if remaining == 0 then
cb(results)
end
end)
end)
end
end
function Async.parallelLimit(tasks, limit, cb)
if #tasks == 0 then
cb({})
return
end
local remaining = #tasks
local running = 0
local queue, results = {}, {}
for i=1, #tasks, 1 do
queue[#queue + 1] = 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)
results[#results+ 1] = 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
+7
View File
@@ -0,0 +1,7 @@
fx_version 'cerulean'
game 'gta5'
author 'ESX-Framework'
description 'asynchronous Tasks'
lua54 'yes'
shared_script 'async.lua'
+1 -1
View File
@@ -4,6 +4,6 @@ game 'gta5'
author 'ESX-Framework'
description 'cron'
lua54 'yes'
version '1.9.0'
version '1.9.2'
server_script 'server/main.lua'
+22 -34
View File
@@ -4,7 +4,6 @@ ESX.PlayerData = {}
ESX.PlayerLoaded = false
Core.CurrentRequestId = 0
Core.ServerCallbacks = {}
Core.TimeoutCallbacks = {}
Core.Input = {}
ESX.UI = {}
ESX.UI.Menu = {}
@@ -19,18 +18,6 @@ ESX.Scaleform.Utils = {}
ESX.Streaming = {}
function ESX.SetTimeout(msec, cb)
table.insert(Core.TimeoutCallbacks, {
time = GetGameTimer() + msec,
cb = cb
})
return #Core.TimeoutCallbacks
end
function ESX.ClearTimeout(i)
Core.TimeoutCallbacks[i] = nil
end
function ESX.IsPlayerLoaded()
return ESX.PlayerLoaded
end
@@ -471,10 +458,15 @@ function ESX.Game.GetObjects() -- Leave the function for compatibility
end
function ESX.Game.GetPeds(onlyOtherPeds)
local peds, myPed, pool = {}, ESX.PlayerData.ped, GetGamePool('CPed')
local myPed, pool = ESX.PlayerData.ped, GetGamePool('CPed')
if not onlyOtherPeds then
return pool
end
local peds = {}
for i = 1, #pool do
if ((onlyOtherPeds and pool[i] ~= myPed) or not onlyOtherPeds) then
if pool[i] ~= myPed then
peds[#peds + 1] = pool[i]
end
end
@@ -608,6 +600,8 @@ function ESX.Game.GetVehicleProperties(vehicle)
local colorPrimary, colorSecondary = GetVehicleColours(vehicle)
local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle)
local hasCustomPrimaryColor = GetIsVehiclePrimaryColourCustom(vehicle)
local dashboardColor = GetVehicleDashboardColor(vehicle)
local interiorColor = GetVehicleInteriorColour(vehicle)
local customPrimaryColor = nil
if hasCustomPrimaryColor then
customPrimaryColor = {GetVehicleCustomPrimaryColour(vehicle)}
@@ -680,6 +674,9 @@ function ESX.Game.GetVehicleProperties(vehicle)
pearlescentColor = pearlescentColor,
wheelColor = wheelColor,
dashboardColor = dashboardColor,
interiorColor = interiorColor,
wheels = GetVehicleWheelType(vehicle),
windowTint = GetVehicleWindowTint(vehicle),
@@ -792,6 +789,15 @@ function ESX.Game.SetVehicleProperties(vehicle, props)
if props.pearlescentColor ~= nil then
SetVehicleExtraColours(vehicle, props.pearlescentColor, wheelColor)
end
if props.interiorColor ~= nil then
SetVehicleInteriorColor(vehicle, props.interiorColor)
end
if props.dashboardColor ~= nil then
SetVehicleDashboardColor(vehicle, props.dashboardColor)
end
if props.wheelColor ~= nil then
SetVehicleExtraColours(vehicle, props.pearlescentColor or pearlescentColor, props.wheelColor)
end
@@ -1321,22 +1327,4 @@ AddEventHandler('esx:showAdvancedNotification',
RegisterNetEvent('esx:showHelpNotification')
AddEventHandler('esx:showHelpNotification', function(msg, thisFrame, beep, duration)
ESX.ShowHelpNotification(msg, thisFrame, beep, duration)
end)
-- SetTimeout
CreateThread(function()
while true do
local sleep = 100
if #Core.TimeoutCallbacks > 0 then
local currTime = GetGameTimer()
sleep = 0
for i = 1, #Core.TimeoutCallbacks, 1 do
if currTime >= Core.TimeoutCallbacks[i].time then
Core.TimeoutCallbacks[i].cb()
Core.TimeoutCallbacks[i] = nil
end
end
end
Wait(sleep)
end
end)
end)
+102 -118
View File
@@ -14,7 +14,7 @@ CreateThread(function()
end)
RegisterNetEvent("esx:requestModel", function(model)
ESX.Streaming.RequestModel(model)
ESX.Streaming.RequestModel(model)
end)
RegisterNetEvent('esx:playerLoaded')
@@ -57,66 +57,49 @@ AddEventHandler('esx:playerLoaded', function(xPlayer, isNew, skin)
NetworkSetFriendlyFireOption(true)
end
CreateThread(function()
local SetPlayerHealthRechargeMultiplier = SetPlayerHealthRechargeMultiplier
local BlockWeaponWheelThisFrame = BlockWeaponWheelThisFrame
local DisableControlAction = DisableControlAction
local IsPedArmed = IsPedArmed
local SetPlayerLockonRangeOverride = SetPlayerLockonRangeOverride
local DisablePlayerVehicleRewards = DisablePlayerVehicleRewards
local RemoveAllPickupsOfType = RemoveAllPickupsOfType
local HideHudComponentThisFrame = HideHudComponentThisFrame
local PlayerId = PlayerId()
local DisabledComps = {}
for i=1, #(Config.RemoveHudCommonents) do
if Config.RemoveHudCommonents[i] then
DisabledComps[#DisabledComps + 1] = i
end
local playerId = PlayerId()
-- RemoveHudCommonents
for i = 1, #(Config.RemoveHudCommonents) do
if Config.RemoveHudCommonents[i] then
SetHudComponentPosition(i, 999999.0, 999999.0)
end
end
while true do
local Sleep = true
-- DisableNPCDrops
if Config.DisableNPCDrops then
local weaponPickups = { `PICKUP_WEAPON_CARBINERIFLE`, `PICKUP_WEAPON_PISTOL`, `PICKUP_WEAPON_PUMPSHOTGUN` }
for i = 1, #weaponPickups do
ToggleUsePickupsForPlayer(playerId, weaponPickups[i], false)
end
end
if Config.DisableHealthRegeneration then
Sleep = false
SetPlayerHealthRechargeMultiplier(PlayerId, 0.0)
end
if Config.DisableWeaponWheel then
Sleep = false
BlockWeaponWheelThisFrame()
DisableControlAction(0, 37,true)
end
if Config.DisableAimAssist then
Sleep = false
if IsPedArmed(ESX.PlayerData.ped, 4) then
SetPlayerLockonRangeOverride(PlayerId, 2.0)
if Config.DisableHealthRegeneration or Config.DisableWeaponWheel or Config.DisableAimAssist or Config.DisableVehicleRewards then
CreateThread(function()
while true do
if Config.DisableHealthRegeneration then
SetPlayerHealthRechargeMultiplier(playerId, 0.0)
end
end
if Config.DisableVehicleRewards then
Sleep = false
DisablePlayerVehicleRewards(PlayerId)
end
if Config.DisableNPCDrops then
Sleep = false
RemoveAllPickupsOfType(0xDF711959)
RemoveAllPickupsOfType(0xF9AFB48F)
RemoveAllPickupsOfType(0xA9355DCD)
end
if #DisabledComps > 0 then
Sleep = false
for i=1, #(DisabledComps) do
HideHudComponentThisFrame(DisabledComps[i])
if Config.DisableWeaponWheel then
BlockWeaponWheelThisFrame()
DisableControlAction(0, 37, true)
end
if Config.DisableAimAssist then
if IsPedArmed(ESX.PlayerData.ped, 4) then
SetPlayerLockonRangeOverride(playerId, 2.0)
end
end
end
Wait(Sleep and 1500 or 0)
end
end)
if Config.DisableVehicleRewards then
DisablePlayerVehicleRewards(playerId)
end
Wait(0)
end
end)
end
SetDefaultVehicleNumberPlateTextPattern(-1, Config.CustomAIPlates)
StartServerSyncLoops()
@@ -131,8 +114,8 @@ RegisterNetEvent('esx:setMaxWeight')
AddEventHandler('esx:setMaxWeight', function(newMaxWeight) ESX.SetPlayerData("maxWeight", newMaxWeight) end)
local function onPlayerSpawn()
ESX.SetPlayerData('ped', PlayerPedId())
ESX.SetPlayerData('dead', false)
ESX.SetPlayerData('ped', PlayerPedId())
ESX.SetPlayerData('dead', false)
end
AddEventHandler('playerSpawned', onPlayerSpawn)
@@ -157,7 +140,7 @@ AddEventHandler('esx:restoreLoadout', function()
local ammoTypes = {}
RemoveAllPedWeapons(ESX.PlayerData.ped, true)
for k,v in ipairs(ESX.PlayerData.loadout) do
for k, v in ipairs(ESX.PlayerData.loadout) do
local weaponName = v.name
local weaponHash = joaat(weaponName)
@@ -166,7 +149,7 @@ AddEventHandler('esx:restoreLoadout', function()
local ammoType = GetPedAmmoTypeFromWeapon(ESX.PlayerData.ped, weaponHash)
for k2,v2 in ipairs(v.components) do
for k2, v2 in ipairs(v.components) do
local componentHash = ESX.GetWeaponComponent(weaponName, v2).hash
GiveWeaponComponentToPed(ESX.PlayerData.ped, weaponHash, componentHash)
end
@@ -181,27 +164,27 @@ end)
AddStateBagChangeHandler('VehicleProperties', nil, function(bagName, key, value)
if value then
Wait(0)
local NetId = value.NetId
local Vehicle = NetworkGetEntityFromNetworkId(NetId)
local Tries = 0
while Vehicle == 0 do
Vehicle = NetworkGetEntityFromNetworkId(NetId)
Wait(100)
Tries = Tries + 1
if Tries > 300 then
break
end
end
if NetworkGetEntityOwner(Vehicle) == PlayerId() then
ESX.Game.SetVehicleProperties(Vehicle, value)
Wait(0)
local NetId = value.NetId
local Vehicle = NetworkGetEntityFromNetworkId(NetId)
local Tries = 0
while Vehicle == 0 do
Vehicle = NetworkGetEntityFromNetworkId(NetId)
Wait(100)
Tries = Tries + 1
if Tries > 300 then
break
end
end
if NetworkGetEntityOwner(Vehicle) == PlayerId() then
ESX.Game.SetVehicleProperties(Vehicle, value)
end
end
end)
RegisterNetEvent('esx:setAccountMoney')
AddEventHandler('esx:setAccountMoney', function(account)
for i=1, #(ESX.PlayerData.accounts) do
for i = 1, #(ESX.PlayerData.accounts) do
if ESX.PlayerData.accounts[i].name == account.name then
ESX.PlayerData.accounts[i] = account
break
@@ -214,7 +197,7 @@ end)
if not Config.OxInventory then
RegisterNetEvent('esx:addInventoryItem')
AddEventHandler('esx:addInventoryItem', function(item, count, showNotification)
for k,v in ipairs(ESX.PlayerData.inventory) do
for k, v in ipairs(ESX.PlayerData.inventory) do
if v.name == item then
ESX.UI.ShowInventoryItemNotification(true, v.label, count - v.count)
ESX.PlayerData.inventory[k].count = count
@@ -231,7 +214,7 @@ if not Config.OxInventory then
RegisterNetEvent('esx:removeInventoryItem')
AddEventHandler('esx:removeInventoryItem', function(item, count, showNotification)
for k,v in ipairs(ESX.PlayerData.inventory) do
for k, v in ipairs(ESX.PlayerData.inventory) do
if v.name == item then
ESX.UI.ShowInventoryItemNotification(false, v.label, v.count - count)
ESX.PlayerData.inventory[k].count = count
@@ -264,7 +247,7 @@ if not Config.OxInventory then
RegisterNetEvent('esx:setWeaponTint')
AddEventHandler('esx:setWeaponTint', function(weapon, weaponTintIndex)
SetPedWeaponTintIndex(ESX.PlayerData.ped, joaat(weapon), weaponTintIndex)
end)
RegisterNetEvent('esx:removeWeapon')
@@ -309,7 +292,7 @@ if not Config.OxInventory then
local pickupObject = CreateWeaponObject(weaponHash, 50, coords.x, coords.y, coords.z, true, 1.0, 0)
SetWeaponObjectTintIndex(pickupObject, tintIndex)
for k,v in ipairs(components) do
for k, v in ipairs(components) do
local component = ESX.GetWeaponComponent(name, v)
GiveWeaponComponentToWeaponObject(pickupObject, component.hash)
end
@@ -323,14 +306,15 @@ if not Config.OxInventory then
RegisterNetEvent('esx:createMissingPickups')
AddEventHandler('esx:createMissingPickups', function(missingPickups)
for pickupId, pickup in pairs(missingPickups) do
TriggerEvent('esx:createPickup', pickupId, pickup.label, pickup.coords - vector3(0,0, 1.0), pickup.type, pickup.name, pickup.components, pickup.tintIndex)
TriggerEvent('esx:createPickup', pickupId, pickup.label, pickup.coords - vector3(0, 0, 1.0), pickup.type, pickup.name
, pickup.components, pickup.tintIndex)
end
end)
end
RegisterNetEvent('esx:registerSuggestions')
AddEventHandler('esx:registerSuggestions', function(registeredCommands)
for name,command in pairs(registeredCommands) do
for name, command in pairs(registeredCommands) do
if command.suggestion then
TriggerEvent('chat:addSuggestion', ('/%s'):format(name), command.suggestion.help, command.suggestion.arguments)
end
@@ -349,32 +333,32 @@ end
function StartServerSyncLoops()
if not Config.OxInventory then
-- keep track of ammo
-- keep track of ammo
CreateThread(function()
local currentWeapon = {Ammo = 0}
while ESX.PlayerLoaded do
local sleep = 1500
if GetSelectedPedWeapon(ESX.PlayerData.ped) ~= -1569615261 then
sleep = 1000
local _,weaponHash = GetCurrentPedWeapon(ESX.PlayerData.ped, true)
local weapon = ESX.GetWeaponFromHash(weaponHash)
if weapon then
local ammoCount = GetAmmoInPedWeapon(ESX.PlayerData.ped, weaponHash)
if weapon.name ~= currentWeapon.name then
currentWeapon.Ammo = ammoCount
currentWeapon.name = weapon.name
else
if ammoCount ~= currentWeapon.Ammo then
currentWeapon.Ammo = ammoCount
TriggerServerEvent('esx:updateWeaponAmmo', weapon.name, ammoCount)
end
end
CreateThread(function()
local currentWeapon = { Ammo = 0 }
while ESX.PlayerLoaded do
local sleep = 1500
if GetSelectedPedWeapon(ESX.PlayerData.ped) ~= -1569615261 then
sleep = 1000
local _, weaponHash = GetCurrentPedWeapon(ESX.PlayerData.ped, true)
local weapon = ESX.GetWeaponFromHash(weaponHash)
if weapon then
local ammoCount = GetAmmoInPedWeapon(ESX.PlayerData.ped, weaponHash)
if weapon.name ~= currentWeapon.name then
currentWeapon.Ammo = ammoCount
currentWeapon.name = weapon.name
else
if ammoCount ~= currentWeapon.Ammo then
currentWeapon.Ammo = ammoCount
TriggerServerEvent('esx:updateWeaponAmmo', weapon.name, ammoCount)
end
end
Wait(sleep)
end
end
end)
end
Wait(sleep)
end
end)
end
end
@@ -401,7 +385,7 @@ if not Config.OxInventory then
local playerCoords = GetEntityCoords(ESX.PlayerData.ped)
local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer(playerCoords)
for pickupId,pickup in pairs(pickups) do
for pickupId, pickup in pairs(pickups) do
local distance = #(playerCoords - pickup.coords)
if distance < 5 then
@@ -599,30 +583,30 @@ end)
RegisterNetEvent("esx:killPlayer")
AddEventHandler("esx:killPlayer", function()
SetEntityHealth(ESX.PlayerData.ped, 0)
SetEntityHealth(ESX.PlayerData.ped, 0)
end)
RegisterNetEvent("esx:freezePlayer")
AddEventHandler("esx:freezePlayer", function(input)
local player = PlayerId()
if input == 'freeze' then
SetEntityCollision(ESX.PlayerData.ped, false)
FreezeEntityPosition(ESX.PlayerData.ped, true)
SetPlayerInvincible(player, true)
elseif input == 'unfreeze' then
SetEntityCollision(ESX.PlayerData.ped, true)
local player = PlayerId()
if input == 'freeze' then
SetEntityCollision(ESX.PlayerData.ped, false)
FreezeEntityPosition(ESX.PlayerData.ped, true)
SetPlayerInvincible(player, true)
elseif input == 'unfreeze' then
SetEntityCollision(ESX.PlayerData.ped, true)
FreezeEntityPosition(ESX.PlayerData.ped, false)
SetPlayerInvincible(player, false)
end
SetPlayerInvincible(player, false)
end
end)
RegisterNetEvent("esx:GetVehicleType", function(Model, Request)
if not IsModelInCdimage(Model) then
return TriggerServerEvent("esx:ReturnVehicleType", false, Request)
end
return TriggerServerEvent("esx:ReturnVehicleType", false, Request)
end
if Model == `submersible` or Model == `submersible2` then
return TriggerServerEvent("esx:ReturnVehicleType", "submarine", Request)
return TriggerServerEvent("esx:ReturnVehicleType", "submarine", Request)
end
local VehicleType = GetVehicleClassFromName(Model)
@@ -650,8 +634,8 @@ local DoNotUse = {
'default_spawnpoint',
}
for i=1, #DoNotUse do
for i = 1, #DoNotUse do
if GetResourceState(DoNotUse[i]) == 'started' or GetResourceState(DoNotUse[i]) == 'starting' then
print("[^1ERROR^7] YOU ARE USING A RESOURCE THAT WILL BREAK ^1ESX^7, PLEASE REMOVE ^5"..DoNotUse[i].."^7")
print("[^1ERROR^7] YOU ARE USING A RESOURCE THAT WILL BREAK ^1ESX^7, PLEASE REMOVE ^5" .. DoNotUse[i] .. "^7")
end
end
+15 -15
View File
@@ -1,6 +1,6 @@
local isInVehicle, isEnteringVehicle, isJumping, inPauseMenu = false, false, false, false
local currentVehicle, currentSeat, currentPlate = nil, nil, nil
local playerPed = PlayerPedId()
local current = {}
local function GetPedVehicleSeat(ped, vehicle)
for i = -1, 16 do
@@ -10,7 +10,10 @@ local function GetPedVehicleSeat(ped, vehicle)
end
local function GetData(vehicle)
local model = GetEntityModel(currentVehicle)
if not DoesEntityExist(vehicle) then
return
end
local model = GetEntityModel(vehicle)
local displayName = GetDisplayNameFromVehicleModel(model)
local netId = VehToNet(vehicle)
return displayName, netId
@@ -51,7 +54,7 @@ CreateThread(function()
local displayName, netId = GetData(vehicle)
isEnteringVehicle = true
TriggerEvent('esx:enteringVehicle', vehicle, plate, seat, netId)
TriggerServerEvent('esx:enteringVehicle', vehicle, plate, seat, netId)
TriggerServerEvent('esx:enteringVehicle', plate, seat, netId)
elseif not DoesEntityExist(GetVehiclePedIsTryingToEnter(playerPed)) and
not IsPedInAnyVehicle(playerPed, true) and isEnteringVehicle then
-- vehicle entering aborted
@@ -62,23 +65,20 @@ CreateThread(function()
-- suddenly appeared in a vehicle, possible teleport
isEnteringVehicle = false
isInVehicle = true
currentVehicle = GetVehiclePedIsUsing(playerPed)
currentSeat = GetPedVehicleSeat(playerPed, currentVehicle)
currentPlate = GetVehicleNumberPlateText(currentVehicle)
local displayName, netId = GetData(currentVehicle)
TriggerEvent('esx:enteredVehicle', currentVehicle, currentPlate, currentSeat, displayName, netId)
TriggerServerEvent('esx:enteredVehicle', currentVehicle, currentPlate, currentSeat, displayName, netId)
current.vehicle = GetVehiclePedIsUsing(playerPed)
current.seat = GetPedVehicleSeat(playerPed, current.vehicle)
current.plate = GetVehicleNumberPlateText(current.vehicle)
current.displayName, current.netId = GetData(current.vehicle)
TriggerEvent('esx:enteredVehicle', current.vehicle, current.plate, current.seat, current.displayName, current.netId)
TriggerServerEvent('esx:enteredVehicle', current.plate, current.seat, current.displayName, current.netId)
end
elseif isInVehicle then
if not IsPedInAnyVehicle(playerPed, false) or IsPlayerDead(PlayerId()) then
-- bye, vehicle
local displayName, netId = GetData(currentVehicle)
TriggerEvent('esx:exitedVehicle', currentVehicle, currentPlate, currentSeat, displayName, netId)
TriggerServerEvent('esx:exitedVehicle', currentVehicle, currentPlate, currentSeat, displayName, netId)
TriggerEvent('esx:exitedVehicle', current.vehicle, current.plate, current.seat, current.displayName, current.netId)
TriggerServerEvent('esx:exitedVehicle', current.plate, current.seat, current.displayName, current.netId)
isInVehicle = false
currentVehicle = nil
currentSeat = nil
currentPlate = nil
current = {}
end
end
Wait(200)
+2 -1
View File
@@ -5,7 +5,8 @@ local function checkPhone()
return
end
npwd:setPhoneDisabled((ESX.SearchInventory('phone').count or 0) <= 0)
local phoneItem <const> = ESX.SearchInventory('phone')
npwd:setPhoneDisabled((phoneItem and phoneItem.count or 0) <= 0)
end
RegisterNetEvent('esx:playerLoaded', checkPhone)
@@ -0,0 +1,23 @@
local TimeoutCount = 0
local CancelledTimeouts = {}
ESX.SetTimeout = function(msec, cb)
local id <const> = TimeoutCount + 1
SetTimeout(msec, function()
if CancelledTimeouts[id] then
CancelledTimeouts[id] = nil
return
end
cb()
end)
TimeoutCount = id
return id
end
ESX.ClearTimeout = function(id)
CancelledTimeouts[id] = true
end
+4
View File
@@ -18,6 +18,9 @@ Config.Accounts = {
Config.StartingAccountMoney = {bank = 50000}
Config.DefaultSpawn = {x = -269.4, y = -955.3, z = 31.2, heading = 205.8}
Config.EnablePaycheck = true -- enable paycheck
Config.EnableSocietyPayouts = false -- pay from the society account that the player is employed at? Requirement: esx_society
Config.MaxWeight = 24 -- the max inventory weight without backpack
Config.PaycheckInterval = 7 * 60000 -- how often to recieve pay checks in milliseconds
@@ -29,6 +32,7 @@ Config.EnablePVP = true -- Allow Player to player combat
Config.Multichar = true -- Enable support for esx_multicharacter
Config.Identity = true -- Select a characters identity data before they have loaded in (this happens by default with multichar)
Config.DistanceGive = 4.0 -- Max distance when giving items, weapons etc.
Config.DisableHealthRegeneration = false -- Player will no longer regenerate health
Config.DisableVehicleRewards = false -- Disables Player Recieving weapons from vehicles
Config.DisableNPCDrops = false -- stops NPCs from dropping weapons on death
+1 -1
View File
@@ -15,7 +15,7 @@ CREATE TABLE `users` (
`job` VARCHAR(20) NULL DEFAULT 'unemployed',
`job_grade` INT NULL DEFAULT 0,
`loadout` LONGTEXT NULL DEFAULT NULL,
`position` VARCHAR(255) NULL DEFAULT '{"x":-269.4,"y":-955.3,"z":31.2,"heading":205.8}',
`position` longtext NULL DEFAULT NULL,
PRIMARY KEY (`identifier`)
) ENGINE=InnoDB;
+2 -1
View File
@@ -5,7 +5,7 @@ game 'gta5'
description 'ES Extended'
lua54 'yes'
version '1.9.1'
version '1.9.2'
shared_scripts {
'locale.lua',
@@ -41,6 +41,7 @@ client_scripts {
'common/modules/*.lua',
'common/functions.lua',
'common/functions.lua',
'client/modules/*.lua'
}
+366
View File
@@ -0,0 +1,366 @@
Locales['da'] = {
-- Inventory
['inventory'] = 'Inventar ( Vægt %s / %s )',
['use'] = 'Brug',
['give'] = 'Giv',
['remove'] = 'Smid',
['return'] = 'Tilbage',
['give_to'] = 'Giv til',
['amount'] = 'Beløb',
['giveammo'] = 'Giv ammunition',
['amountammo'] = 'Ammunition beløb',
['noammo'] = 'Ikke nok!',
['gave_item'] = 'Giver %sx %s til %s',
['received_item'] = 'Modtog %sx %s fra %s',
['gave_weapon'] = 'Giver %s til %s',
['gave_weapon_ammo'] = 'Giver ~o~%sx %s for %s til %s',
['gave_weapon_withammo'] = 'Giver %s med ~o~%sx %s til %s',
['gave_weapon_hasalready'] = '%s har allerede en %s',
['gave_weapon_noweapon'] = '%s har ikke det våben',
['received_weapon'] = 'Modtog %s fra %s',
['received_weapon_ammo'] = 'Modtog ~o~%sx %s for din %s fra %s',
['received_weapon_withammo'] = 'Modtog %s med ~o~%sx %s fra %s',
['received_weapon_hasalready'] = '%s har forsøgt at give dig en %s, men du allerede dette våben',
['received_weapon_noweapon'] = '%s har forsøgt at give dig ammunition for en %s, men du har ikke dette våben',
['gave_account_money'] = 'Giver %s kr. (%s) til %s',
['received_account_money'] = 'Modtog %s kr. (%s) fra %s',
['amount_invalid'] = 'Ugyldig mængde',
['players_nearby'] = 'Ingen spillere i nærheden',
['ex_inv_lim'] = 'Kan ikke udføre handling, overskrider maks. vægt på %s',
['imp_invalid_quantity'] = 'Handlingen kan ikke udføres, mængden er ugyldig',
['imp_invalid_amount'] = 'Handlingen kan ikke udføres, beløbet er ugyldigt',
['threw_standard'] = 'Smider %sx %s',
['threw_account'] = 'Smider %s kr. %s',
['threw_weapon'] = 'Smider %s',
['threw_weapon_ammo'] = 'Smider %s med ~o~%sx %s',
['threw_weapon_already'] = 'Du har allerede dette våben',
['threw_cannot_pickup'] = 'Inventory er fyldt, Kan ikke tages!',
['threw_pickup_prompt'] = 'Tryk på E for at tage genstand',
-- Key mapping
['keymap_showinventory'] = 'Vis Inventory',
-- Salary related
['received_salary'] = 'Du er blevet betalt: %s kr.',
['received_help'] = 'Du har fået udbetalt din velfærdscheck: %s kr.',
['company_nomoney'] = 'den virksomhed, du er ansat i, er for fattig til at udbetale din løn',
['received_paycheck'] = 'modtaget lønseddel',
['bank'] = 'Maze Bank',
['account_bank'] = 'Bank',
['account_black_money'] = 'Beskidte penge',
['account_money'] = 'Penge',
['act_imp'] = 'Kan ikke udføre handling',
['in_vehicle'] = 'Kan ikke udføre handling, spilleren er i et køretøj',
-- Commands
['command_bring'] = 'Tag en spiller til dig',
['command_car'] = 'Spawn et køretøj',
['command_car_car'] = 'Køretøjsmodel eller hash',
['command_cardel'] = 'Fjern køretøjer i nærheden',
['command_cardel_radius'] = 'Fjerner alle køretøjer inden for den specificerede radius',
['command_clear'] = 'Ryd chatten',
['command_clearall'] = 'Ryd chatten for alle spillere',
['command_clearinventory'] = 'Fjern alle elementer fra spillernes inventar',
['command_clearloadout'] = 'Fjern alle våben fra Players Loadout',
['command_freeze'] = 'Frys en spiller',
['command_unfreeze'] = 'Frigør en spiller',
['command_giveaccountmoney'] = 'Giv penge til en bestemt konto',
['command_giveaccountmoney_account'] = 'Konto at tilføje til',
['command_giveaccountmoney_amount'] = 'Beløb at tilføje',
['command_giveaccountmoney_invalid'] = 'Kontonavn ugyldigt',
['command_giveitem'] = 'Giv spilleren en genstand',
['command_giveitem_item'] = 'Genstands navn',
['command_giveitem_count'] = 'Antal',
['command_giveweapon'] = 'Giv spilleren et våben',
['command_giveweapon_weapon'] = 'Navn på våben',
['command_giveweapon_ammo'] = 'Ammunitions mængde',
['command_giveweapon_hasalready'] = 'Spilleren har allerede dette våben',
['command_giveweaponcomponent'] = 'Giv en våbenkomponent til spilleren',
['command_giveweaponcomponent_component'] = 'Komponent navn',
['command_giveweaponcomponent_invalid'] = 'Ugyldig våben-komponent',
['command_giveweaponcomponent_hasalready'] = 'Spilleren har allerede denne våben-komponent',
['command_giveweaponcomponent_missingweapon'] = 'Spilleren har ikke dette våben',
['command_goto'] = 'Teleporter dig selv til en spiller',
['command_kill'] = 'Dræb en spiller',
['command_save'] = 'Force save en spillers data',
['command_saveall'] = 'Force save alle spillers data',
['command_setaccountmoney'] = 'Indstil pengene på en bestemt konto',
['command_setaccountmoney_amount'] = 'Beløb',
['command_setcoords'] = 'Teleporter til specificerede koordinater',
['command_setcoords_x'] = 'X værdi',
['command_setcoords_y'] = 'Y værdi',
['command_setcoords_z'] = 'Z værdi',
['command_setjob'] = 'Sæt en spillers job',
['command_setjob_job'] = 'Navn',
['command_setjob_grade'] = 'Job karakter',
['command_setjob_invalid'] = 'jobbet, karakteren eller begge dele er ugyldige',
['command_setgroup'] = 'Indstil en spillers tilladelsesgruppe',
['command_setgroup_group'] = 'Navn på gruppe',
['commanderror_argumentmismatch'] = 'Antal ugyldige argumenter (bestået %s, ønsket %s)',
['commanderror_argumentmismatch_number'] = 'Ugyldigt argument #%s datatype (bestået streng, ønsket nummer)',
['commanderror_invaliditem'] = 'Ugyldig genstand',
['commanderror_invalidweapon'] = 'Ugyldigt våben',
['commanderror_console'] = 'Kommandoen kan ikke udføres fra konsollen',
['commanderror_invalidcommand'] = 'Ugyldig kommando - /%s',
['commanderror_invalidplayerid'] = 'Den angivne spiller er ikke online',
['commandgeneric_playerid'] = 'Spillerens server-id',
['command_giveammo_noweapon_found'] = '%s har ikke det våben',
['command_giveammo_weapon'] = 'Våben navn',
['command_giveammo_ammo'] = 'Ammunitions mængde',
['tpm_nowaypoint'] = 'Ingen waypoint indstillet.',
['tpm_success'] = 'Teleporteret med succes',
['noclip_message'] = 'Noclip er blevet %s',
['enabled'] = '~g~aktiveret~s~',
['disabled'] = '~r~deaktiveret~s~',
-- Locale settings
['locale_digit_grouping_symbol'] = ',',
['locale_currency'] = 'DKK%s',
-- Weapons
-- Melee
['weapon_dagger'] = 'Dagger',
['weapon_bat'] = 'Bat',
['weapon_battleaxe'] = 'Battle Axe',
['weapon_bottle'] = 'Bottle',
['weapon_crowbar'] = 'Crowbar',
['weapon_flashlight'] = 'Flashlight',
['weapon_golfclub'] = 'Golf Club',
['weapon_hammer'] = 'Hammer',
['weapon_hatchet'] = 'Hatchet',
['weapon_knife'] = 'Knife',
['weapon_knuckle'] = 'Knuckledusters',
['weapon_machete'] = 'Machete',
['weapon_nightstick'] = 'Nightstick',
['weapon_wrench'] = 'Pipe Wrench',
['weapon_poolcue'] = 'Pool Cue',
['weapon_stone_hatchet'] = 'Stone Hatchet',
['weapon_switchblade'] = 'Switchblade',
-- Handguns
['weapon_appistol'] = 'AP Pistol',
['weapon_ceramicpistol'] = 'Ceramic Pistol',
['weapon_combatpistol'] = 'Combat Pistol',
['weapon_doubleaction'] = 'Double-Action Revolver',
['weapon_navyrevolver'] = 'Navy Revolver',
['weapon_flaregun'] = 'Flaregun',
['weapon_gadgetpistol'] = 'Gadget Pistol',
['weapon_heavypistol'] = 'Heavy Pistol',
['weapon_revolver'] = 'Heavy Revolver',
['weapon_revolver_mk2'] = 'Heavy Revolver MK2',
['weapon_marksmanpistol'] = 'Marksman Pistol',
['weapon_pistol'] = 'Pistol',
['weapon_pistol_mk2'] = 'Pistol MK2',
['weapon_pistol50'] = 'Pistol .50',
['weapon_snspistol'] = 'SNS Pistol',
['weapon_snspistol_mk2'] = 'SNS Pistol MK2',
['weapon_stungun'] = 'Taser',
['weapon_raypistol'] = 'Up-N-Atomizer',
['weapon_vintagepistol'] = 'Vintage Pistol',
-- Shotguns
['weapon_assaultshotgun'] = 'Assault Shotgun',
['weapon_autoshotgun'] = 'Auto Shotgun',
['weapon_bullpupshotgun'] = 'Bullpup Shotgun',
['weapon_combatshotgun'] = 'Combat Shotgun',
['weapon_dbshotgun'] = 'Double Barrel Shotgun',
['weapon_heavyshotgun'] = 'Heavy Shotgun',
['weapon_musket'] = 'Musket',
['weapon_pumpshotgun'] = 'Pump Shotgun',
['weapon_pumpshotgun_mk2'] = 'Pump Shotgun MK2',
['weapon_sawnoffshotgun'] = 'Sawed Off Shotgun',
-- SMG & LMG
['weapon_assaultsmg'] = 'Assault SMG',
['weapon_combatmg'] = 'Combat MG',
['weapon_combatmg_mk2'] = 'Combat MG MK2',
['weapon_combatpdw'] = 'Combat PDW',
['weapon_gusenberg'] = 'Gusenberg Sweeper',
['weapon_machinepistol'] = 'Machine Pistol',
['weapon_mg'] = 'MG',
['weapon_microsmg'] = 'Micro SMG',
['weapon_minismg'] = 'Mini SMG',
['weapon_smg'] = 'SMG',
['weapon_smg_mk2'] = 'SMG MK2',
['weapon_raycarbine'] = 'Unholy Hellbringer',
-- Rifles
['weapon_advancedrifle'] = 'Advanced Rifle',
['weapon_assaultrifle'] = 'Assault Rifle',
['weapon_assaultrifle_mk2'] = 'Assault Rifle MK2',
['weapon_bullpuprifle'] = 'Bullpup Rifle',
['weapon_bullpuprifle_mk2'] = 'Bullpup Rifle MK2',
['weapon_carbinerifle'] = 'Carbine Rifle',
['weapon_carbinerifle_mk2'] = 'Carbine Rifle MK2',
['weapon_compactrifle'] = 'Compact Rifle',
['weapon_militaryrifle'] = 'Military Rifle',
['weapon_specialcarbine'] = 'Special Carbine',
['weapon_specialcarbine_mk2'] = 'Special Carbine MK2',
-- Sniper
['weapon_heavysniper'] = 'Heavy Sniper',
['weapon_heavysniper_mk2'] = 'Heavy Sniper MK2',
['weapon_marksmanrifle'] = 'Marksman Rifle',
['weapon_marksmanrifle_mk2'] = 'Marksman Rifle MK2',
['weapon_sniperrifle'] = 'Sniper Rifle',
-- Heavy / Launchers
['weapon_compactlauncher'] = 'Compact Launcher',
['weapon_firework'] = 'Firework Launcher',
['weapon_grenadelauncher'] = 'Grenade Launcher',
['weapon_hominglauncher'] = 'Homing Launcher',
['weapon_minigun'] = 'Minigun',
['weapon_railgun'] = 'Railgun',
['weapon_rpg'] = 'Rocket Launcher',
['weapon_rayminigun'] = 'Widowmaker',
-- Criminal Enterprises DLC
['weapon_metaldetector'] = 'Metal Detector',
['weapon_precisionrifle'] = 'Precision Rifle',
['weapon_tactilerifle'] = 'Service Carbine',
-- Thrown
['weapon_ball'] = 'Baseball',
['weapon_bzgas'] = 'BZ Gas',
['weapon_flare'] = 'Flare',
['weapon_grenade'] = 'Grenade',
['weapon_petrolcan'] = 'Jerrycan',
['weapon_hazardcan'] = 'Hazardous Jerrycan',
['weapon_molotov'] = 'Molotov Cocktail',
['weapon_proxmine'] = 'Proximity Mine',
['weapon_pipebomb'] = 'Pipe Bomb',
['weapon_snowball'] = 'Snowball',
['weapon_stickybomb'] = 'Sticky Bomb',
['weapon_smokegrenade'] = 'Tear Gas',
-- Special
['weapon_fireextinguisher'] = 'Fire Extinguisher',
['weapon_digiscanner'] = 'Digital Scanner',
['weapon_garbagebag'] = 'Garbage Bag',
['weapon_handcuffs'] = 'Handcuffs',
['gadget_nightvision'] = 'Night Vision',
['gadget_parachute'] = 'parachute',
-- Weapon Components
['component_knuckle_base'] = 'base Model',
['component_knuckle_pimp'] = 'the Pimp',
['component_knuckle_ballas'] = 'the Ballas',
['component_knuckle_dollar'] = 'the Hustler',
['component_knuckle_diamond'] = 'the Rock',
['component_knuckle_hate'] = 'the Hater',
['component_knuckle_love'] = 'the Lover',
['component_knuckle_player'] = 'the Player',
['component_knuckle_king'] = 'the King',
['component_knuckle_vagos'] = 'the Vagos',
['component_luxary_finish'] = 'luxary Weapon Finish',
['component_handle_default'] = 'default Handle',
['component_handle_vip'] = 'vIP Handle',
['component_handle_bodyguard'] = 'bodyguard Handle',
['component_vip_finish'] = 'vIP Finish',
['component_bodyguard_finish'] = 'bodyguard Finish',
['component_camo_finish'] = 'digital Camo',
['component_camo_finish2'] = 'brushstroke Camo',
['component_camo_finish3'] = 'woodland Camo',
['component_camo_finish4'] = 'skull Camo',
['component_camo_finish5'] = 'sessanta Nove Camo',
['component_camo_finish6'] = 'perseus Camo',
['component_camo_finish7'] = 'leopard Camo',
['component_camo_finish8'] = 'zebra Camo',
['component_camo_finish9'] = 'geometric Camo',
['component_camo_finish10'] = 'boom Camo',
['component_camo_finish11'] = 'patriotic Camo',
['component_camo_slide_finish'] = 'digital Slide Camo',
['component_camo_slide_finish2'] = 'brushstroke Slide Camo',
['component_camo_slide_finish3'] = 'woodland Slide Camo',
['component_camo_slide_finish4'] = 'skull Slide Camo',
['component_camo_slide_finish5'] = 'sessanta Nove Slide Camo',
['component_camo_slide_finish6'] = 'perseus Slide Camo',
['component_camo_slide_finish7'] = 'leopard Slide Camo',
['component_camo_slide_finish8'] = 'zebra Slide Camo',
['component_camo_slide_finish9'] = 'geometric Slide Camo',
['component_camo_slide_finish10'] = 'boom Slide Camo',
['component_camo_slide_finish11'] = 'patriotic Slide Camo',
['component_clip_default'] = 'default Magazine',
['component_clip_extended'] = 'extended Magazine',
['component_clip_drum'] = 'drum Magazine',
['component_clip_box'] = 'box Magazine',
['component_scope_holo'] = 'holographic Scope',
['component_scope_small'] = 'small Scope',
['component_scope_medium'] = 'medium Scope',
['component_scope_large'] = 'large Scope',
['component_scope'] = 'mounted Scope',
['component_scope_advanced'] = 'advanced Scope',
['component_ironsights'] = 'ironsights',
['component_suppressor'] = 'suppressor',
['component_compensator'] = 'compensator',
['component_muzzle_flat'] = 'flat Muzzle Brake',
['component_muzzle_tactical'] = 'tactical Muzzle Brake',
['component_muzzle_fat'] = 'fat-End Muzzle Brake',
['component_muzzle_precision'] = 'precision Muzzle Brake',
['component_muzzle_heavy'] = 'heavy Duty Muzzle Brake',
['component_muzzle_slanted'] = 'slanted Muzzle Brake',
['component_muzzle_split'] = 'split-End Muzzle Brake',
['component_muzzle_squared'] = 'squared Muzzle Brake',
['component_flashlight'] = 'flashlight',
['component_grip'] = 'grip',
['component_barrel_default'] = 'default Barrel',
['component_barrel_heavy'] = 'heavy Barrel',
['component_ammo_tracer'] = 'tracer Ammo',
['component_ammo_incendiary'] = 'incendiary Ammo',
['component_ammo_hollowpoint'] = 'hollowpoint Ammo',
['component_ammo_fmj'] = 'fMJ Ammo',
['component_ammo_armor'] = 'armor Piercing Ammo',
['component_ammo_explosive'] = 'armor Piercing Incendiary Ammo',
['component_shells_default'] = 'default Shells',
['component_shells_incendiary'] = 'dragons Breath Shells',
['component_shells_armor'] = 'steel Buckshot Shells',
['component_shells_hollowpoint'] = 'flechette Shells',
['component_shells_explosive'] = 'explosive Slug Shells',
-- 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 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',
}
+224 -87
View File
@@ -54,6 +54,7 @@ Locales['tc'] = {
['in_vehicle'] = '請離開載具',
-- Commands
['command_bring'] = '傳送玩家到你旁邊',
['command_car'] = '生成載具',
['command_car_car'] = '生成載具的模型名稱或希哈值',
['command_cardel'] = '刪除附近的載具',
@@ -61,7 +62,9 @@ Locales['tc'] = {
['command_clear'] = '清除聊天紀錄',
['command_clearall'] = '清除所有玩家的聊天紀錄',
['command_clearinventory'] = '清除玩家背包',
['command_clearloadout'] = '清除玩家人物造型',
['command_clearloadout'] = '清除玩家武器配置',
['command_freeze'] = '凍結玩家',
['command_unfreeze'] = '解凍玩家',
['command_giveaccountmoney'] = '給予帳戶錢',
['command_giveaccountmoney_account'] = '有效的帳戶名稱',
['command_giveaccountmoney_amount'] = '添加的數量',
@@ -78,6 +81,8 @@ Locales['tc'] = {
['command_giveweaponcomponent_invalid'] = '無效的武器配件',
['command_giveweaponcomponent_hasalready'] = '該玩家已經擁有了武器配件',
['command_giveweaponcomponent_missingweapon'] = '該玩家沒有那把武器',
['command_goto'] = '傳送到一名玩家旁邊',
['command_kill'] = '殺死一名玩家',
['command_save'] = '保存玩家數據至資料庫',
['command_saveall'] = '保存所有玩家數據至資料庫',
['command_setaccountmoney'] = '為玩家設置賬戶資金',
@@ -100,108 +105,240 @@ Locales['tc'] = {
['commanderror_invalidcommand'] = '/%s 不是有效的指令!',
['commanderror_invalidplayerid'] = '無效的玩家ID',
['commandgeneric_playerid'] = '玩家id',
['command_giveammo_noweapon_found'] = '%s does not have that weapon',
['command_giveammo_weapon'] = 'Weapon name',
['command_giveammo_ammo'] = 'Ammo Quantity',
['command_giveammo_noweapon_found'] = '%s 沒有找到這個武器',
['command_giveammo_weapon'] = '武器名稱',
['command_giveammo_ammo'] = '彈藥數量',
['tpm_nowaypoint'] = '沒有設定導航點',
['tpm_success'] = '成功傳送',
['noclip_message'] = 'Noclip 已被開啟 %s',
['enabled'] = '~g~開啟~s~',
['disabled'] = '~r~關閉~s~',
-- 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'] = '扳手',
-- Melee
['weapon_dagger'] = '古董騎兵匕首',
['weapon_bat'] = '',
['weapon_battleaxe'] = '戰鬥斧頭',
['weapon_bottle'] = '瓶子',
['weapon_crowbar'] = '鐵撬',
['weapon_flashlight'] = '手電筒',
['weapon_golfclub'] = '高爾夫球桿',
['weapon_hammer'] = '鐵鎚',
['weapon_hatchet'] = '斧頭',
['weapon_knife'] = '小刀',
['weapon_knuckle'] = '手指虎',
['weapon_machete'] = '開山刀',
['weapon_nightstick'] = '警棍',
['weapon_wrench'] = '管鉗扳手',
['weapon_poolcue'] = '桌球桿',
['weapon_stone_hatchet'] = '石斧',
['weapon_switchblade'] = '彈簧刀',
-- Handguns
['weapon_appistol'] = '穿甲手槍',
['weapon_ceramicpistol'] = '陶瓷手槍',
['weapon_combatpistol'] = '戰鬥手槍',
['weapon_doubleaction'] = '雙動式左輪手槍',
['weapon_navyrevolver'] = '海軍左輪手槍',
['weapon_flaregun'] = '信號槍',
['weapon_gadgetpistol'] = '佩里克手槍',
['weapon_heavypistol'] = '重型手槍',
['weapon_revolver'] = '重型左輪手槍',
['weapon_revolver_mk2'] = '重型左輪手槍 MK2',
['weapon_marksmanpistol'] = '射手手槍',
['weapon_pistol'] = '手槍',
['weapon_pistol_mk2'] = '手槍 MK2',
['weapon_pistol50'] = '50 口徑手槍',
['weapon_snspistol'] = '劣質手槍',
['weapon_snspistol_mk2'] = '劣質手槍 MK2',
['weapon_stungun'] = '電擊槍',
['weapon_raypistol'] = '原子堡手槍',
['weapon_vintagepistol'] = '復古手槍',
-- Shotguns
['weapon_assaultshotgun'] = '突擊霰彈槍',
['weapon_autoshotgun'] = '衝鋒霰彈槍',
['weapon_bullpupshotgun'] = '犢牛式霰彈槍',
['weapon_combatshotgun'] = '戰鬥霰彈槍',
['weapon_dbshotgun'] = '雙管霰彈槍',
['weapon_heavyshotgun'] = '重型霰彈槍',
['weapon_musket'] = '老式火槍',
['weapon_pumpshotgun'] = '泵動式霰彈槍',
['weapon_pumpshotgun_mk2'] = '泵動式霰彈槍 MK2',
['weapon_sawnoffshotgun'] = '削短型霰彈槍',
-- SMG & LMG
['weapon_assaultsmg'] = '突擊衝鋒槍',
['weapon_combatmg'] = '戰鬥機關槍',
['weapon_combatmg_mk2'] = '戰鬥機關槍 MK2',
['weapon_combatpdw'] = '戰鬥自衛衝鋒槍',
['weapon_gusenberg'] = '古森柏衝鋒槍',
['weapon_machinepistol'] = '衝鋒手槍',
['weapon_mg'] = '機關槍',
['weapon_microsmg'] = '小型衝鋒槍',
['weapon_minismg'] = '迷你衝鋒槍',
['weapon_smg'] = '衝鋒槍',
['weapon_smg_mk2'] = '衝鋒槍',
['weapon_raycarbine'] = '不潔使者',
-- Rifles
['weapon_advancedrifle'] = '高階步槍',
['weapon_assaultrifle'] = '突擊步槍',
['weapon_assaultrifle_mk2'] = '突擊步槍 MK2',
['weapon_bullpuprifle'] = '犢牛式步槍',
['weapon_bullpuprifle_mk2'] = '犢牛式步槍 MK2',
['weapon_carbinerifle'] = '卡賓步槍',
['weapon_carbinerifle_mk2'] = '卡賓步槍 MK2',
['weapon_compactrifle'] = '精簡型步槍',
['weapon_militaryrifle'] = '軍用步槍',
['weapon_specialcarbine'] = '特製卡賓步槍',
['weapon_specialcarbine_mk2'] = '特製卡賓步槍 MK2',
-- Sniper
['weapon_heavysniper'] = '重型狙擊槍',
['weapon_heavysniper_mk2'] = '重型狙擊槍 MK2',
['weapon_marksmanrifle'] = '射手步槍',
['weapon_marksmanrifle_mk2'] = '射手步槍 MK2',
['weapon_sniperrifle'] = '狙擊槍',
-- Heavy / Launchers
['weapon_compactlauncher'] = '精簡榴彈發射器',
['weapon_firework'] = '煙火發射器',
['weapon_grenadelauncher'] = '榴彈發射器',
['weapon_hominglauncher'] = '追蹤彈發射器',
['weapon_minigun'] = '火神機槍',
['weapon_railgun'] = '雷射槍',
['weapon_rpg'] = '火箭砲',
['weapon_rayminigun'] = '寡婦製造者',
-- Criminal Enterprises DLC
['weapon_metaldetector'] = '金屬探測器',
['weapon_precisionrifle'] = '精準步槍',
['weapon_tactilerifle'] = '制式卡賓步槍',
-- Thrown
['weapon_ball'] = '',
['weapon_bzgas'] = '毒氣彈',
['weapon_flare'] = '信號彈',
['weapon_grenade'] = '手榴彈',
['weapon_petrolcan'] = '汽油桶',
['weapon_hazardcan'] = '有害汽油桶',
['weapon_molotov'] = '汽油彈',
['weapon_proxmine'] = '感應式地雷',
['weapon_pipebomb'] = '土製炸彈',
['weapon_snowball'] = '雪球',
['weapon_stickybomb'] = '黏彈',
['weapon_smokegrenade'] = '催淚瓦斯',
-- Special
['weapon_fireextinguisher'] = '滅火器',
['weapon_digiscanner'] = '數位掃描儀',
['weapon_garbagebag'] = '垃圾袋',
['weapon_handcuffs'] = '手銬',
['gadget_nightvision'] = '夜視鏡',
['gadget_parachute'] = '降落傘',
['weapon_flare'] = '信號棒',
['weapon_doubleaction'] = '左輪手槍',
-- Weapon Components
['component_clip_default'] = '默認彈夾',
['component_clip_extended'] = '延伸彈夾',
['component_clip_drum'] = '彈鼓式彈匣',
['component_clip_box'] = '盒式彈匣',
['component_flashlight'] = '手電筒',
['component_knuckle_base'] = '基本款',
['component_knuckle_pimp'] = '皮條客',
['component_knuckle_ballas'] = '巴勒幫',
['component_knuckle_dollar'] = '江湖騙子',
['component_knuckle_diamond'] = '搖滾龐克',
['component_knuckle_hate'] = '仇恨份子',
['component_knuckle_love'] = '甜蜜情人',
['component_knuckle_player'] = '花花公子',
['component_knuckle_king'] = '王者無敵',
['component_knuckle_vagos'] = '維戈斯幫',
['component_luxary_finish'] = '尤瑟夫·阿米爾富豪塗裝',
['component_handle_default'] = '原裝刀柄',
['component_handle_vip'] = '老大款式',
['component_handle_bodyguard'] = '保鑣款式',
['component_vip_finish'] = '老大款式',
['component_bodyguard_finish'] = '保鑣款式',
['component_camo_finish'] = '數碼迷彩',
['component_camo_finish2'] = '筆刷迷彩',
['component_camo_finish3'] = '林地迷彩',
['component_camo_finish4'] = '骷髏頭',
['component_camo_finish5'] = '希斯提·耐',
['component_camo_finish6'] = '神之子',
['component_camo_finish7'] = '豹紋',
['component_camo_finish8'] = '斑馬紋',
['component_camo_finish9'] = '幾何',
['component_camo_finish10'] = 'BOOM!',
['component_camo_finish11'] = '愛國者',
['component_camo_slide_finish'] = '數碼迷彩塗裝',
['component_camo_slide_finish2'] = '筆刷迷彩塗裝',
['component_camo_slide_finish3'] = '林地迷彩塗裝',
['component_camo_slide_finish4'] = '骷髏頭塗裝',
['component_camo_slide_finish5'] = '希斯提·耐塗裝',
['component_camo_slide_finish6'] = '神之子塗裝',
['component_camo_slide_finish7'] = '豹紋塗裝',
['component_camo_slide_finish8'] = '斑馬紋塗裝',
['component_camo_slide_finish9'] = '幾何塗裝',
['component_camo_slide_finish10'] = 'BOOM塗裝',
['component_camo_slide_finish11'] = '愛國者塗裝',
['component_clip_default'] = '預設彈匣',
['component_clip_extended'] = '擴充彈匣',
['component_clip_drum'] = '彈鼓',
['component_clip_box'] = '盒型彈匣',
['component_scope_holo'] = '全像式瞄準鏡',
['component_scope_small'] = '小型瞄準鏡',
['component_scope_medium'] = '中型瞄準鏡',
['component_scope_large'] = '大型瞄準鏡',
['component_scope'] = '瞄準鏡',
['component_scope_advanced'] = '高級瞄準鏡',
['component_suppressor'] = '消音管',
['component_scope_advanced'] = '先進瞄準鏡',
['component_ironsights'] = '鐵瞄具',
['component_suppressor'] = '消音器',
['component_compensator'] = '補償器',
['component_muzzle_flat'] = '扁型槍口制動器',
['component_muzzle_tactical'] = '戰術槍口制動器',
['component_muzzle_fat'] = '寬尾型槍口制動器',
['component_muzzle_precision'] = '精準槍口制動器',
['component_muzzle_heavy'] = '耐用型槍口制動器',
['component_muzzle_slanted'] = '傾斜型槍口制動器',
['component_muzzle_split'] = '分岔型槍口制動器',
['component_muzzle_squared'] = '方形槍口制動器',
['component_flashlight'] = '手電筒',
['component_grip'] = '握把',
['component_luxary_finish'] = '豪華塗裝',
['component_barrel_default'] = '預設槍管',
['component_barrel_heavy'] = '重型槍管',
['component_ammo_tracer'] = '曳光彈',
['component_ammo_incendiary'] = '燃燒彈',
['component_ammo_hollowpoint'] = '空包彈',
['component_ammo_fmj'] = '全金屬外殼彈',
['component_ammo_armor'] = '穿甲彈',
['component_ammo_explosive'] = '爆裂彈',
['component_shells_default'] = '預設彈藥',
['component_shells_incendiary'] = '龍息彈',
['component_shells_armor'] = '鋼製獵鹿彈',
['component_shells_hollowpoint'] = '飛鏢彈',
['component_shells_explosive'] = '爆裂彈',
-- Weapon Ammo
['ammo_rounds'] = '發(子彈)',
['ammo_shells'] = '發(子彈)',
['ammo_charge'] = '',
['ammo_petrol'] = '加崙(燃料)',
['ammo_firework'] = '發(煙火子彈)',
['ammo_firework'] = '發(煙火)',
['ammo_rockets'] = '枚(火箭彈)',
['ammo_grenadelauncher'] = '發(榴彈)',
['ammo_grenade'] = '枚(手榴彈)',
@@ -217,12 +354,12 @@ Locales['tc'] = {
['ammo_flaregun'] = '發(信號彈)',
-- Weapon Tints
['tint_default'] = '默認色調',
['tint_default'] = '預設色調',
['tint_green'] = '綠色調',
['tint_gold'] = '金色調',
['tint_pink'] = '粉色調',
['tint_army'] = '軍用色調',
['tint_lspd'] = '洛聖都警察局色調',
['tint_orange'] = '橘色調',
['tint_platinum'] = '金色調',
['tint_platinum'] = '金色調',
}
+38 -38
View File
@@ -26,11 +26,12 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory,
ExecuteCommand(('add_principal identifier.%s group.%s'):format(self.license, self.group))
Player(self.source).state:set("identifier", self.identifier, true)
Player(self.source).state:set("license", self.license, true)
Player(self.source).state:set("job", self.job, true)
Player(self.source).state:set("group", self.group, true)
Player(self.source).state:set("name", self.name, true)
local stateBag = Player(self.source).state
stateBag:set("identifier", self.identifier, true)
stateBag:set("license", self.license, true)
stateBag:set("job", self.job, true)
stateBag:set("group", self.group, true)
stateBag:set("name", self.name, true)
function self.triggerEvent(eventName, ...)
TriggerClientEvent(eventName, self.source, ...)
@@ -120,17 +121,17 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory,
end
function self.getAccounts(minimal)
if minimal then
local minimalAccounts = {}
for i=1, #self.accounts do
minimalAccounts[self.accounts[i].name] = self.accounts[i].money
end
return minimalAccounts
else
if not minimal then
return self.accounts
end
local minimalAccounts = {}
for i=1, #self.accounts do
minimalAccounts[self.accounts[i].name] = self.accounts[i].money
end
return minimalAccounts
end
function self.getAccount(account)
@@ -162,32 +163,31 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory,
end
function self.getLoadout(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
components[#components + 1] = component
end
end
if #components > 0 then
minimalLoadout[v.name].components = components
end
end
end
return minimalLoadout
else
if not minimal then
return self.loadout
end
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
components[#components + 1] = component
end
end
if #components > 0 then
minimalLoadout[v.name].components = components
end
end
end
return minimalLoadout
end
function self.getName()
+8 -36
View File
@@ -7,13 +7,13 @@ Core.UsableItemsCallbacks = {}
Core.ServerCallbacks = {}
Core.ClientCallbacks = {}
Core.CurrentRequestId = 0
Core.TimeoutCount = -1
Core.CancelledTimeouts = {}
Core.RegisteredCommands = {}
Core.Pickups = {}
Core.PickupId = 0
Core.PlayerFunctionOverrides = {}
Core.playersByIdentifier = {}
AddEventHandler("esx:getSharedObject", function()
local Invoke = GetInvokingResource()
print(("[^1ERROR^7] Resource ^5%s^7 Used the ^5getSharedObject^7 Event, this event ^1no longer exists!^7 Visit https://documentation.esx-framework.org/tutorials/sharedevent for how to fix!"):format(Invoke))
@@ -61,42 +61,14 @@ MySQL.ready(function()
end
end
local Jobs = {}
local jobs = MySQL.query.await('SELECT * FROM jobs')
ESX.RefreshJobs()
for _, v in ipairs(jobs) do
Jobs[v.name] = v
Jobs[v.name].grades = {}
end
local jobGrades = MySQL.query.await('SELECT * FROM job_grades')
for _, v in ipairs(jobGrades) do
if Jobs[v.job_name] then
Jobs[v.job_name].grades[tostring(v.grade)] = v
else
print(('[^3WARNING^7] Ignoring job grades for ^5%s^0 due to missing job'):format(v.job_name))
end
end
for _, v in pairs(Jobs) do
if ESX.Table.SizeOf(v.grades) == 0 then
Jobs[v.name] = nil
print(('[^3WARNING^7] Ignoring job ^5%s^0 due to no job grades found'):format(v.name))
end
end
if not Jobs then
-- Fallback data, if no jobs exist
ESX.Jobs['unemployed'] = {label = 'Unemployed',
grades = {['0'] = {grade = 0, label = 'Unemployed', salary = 200, skin_male = {}, skin_female = {}}}}
else
ESX.Jobs = Jobs
end
print('[^2INFO^7] ESX ^5Legacy 1.9.1^0 initialized!')
print(('[^2INFO^7] ESX ^5Legacy %s^0 initialized!'):format(GetResourceMetadata(GetCurrentResourceName(), "version", 0)))
StartDBSync()
StartPayCheck()
if Config.EnablePaycheck then
StartPayCheck()
end
end)
RegisterServerEvent('esx:clientLog')
+52 -59
View File
@@ -4,22 +4,6 @@ function ESX.Trace(msg)
end
end
function ESX.SetTimeout(msec, cb)
local id = Core.TimeoutCount + 1
SetTimeout(msec, function()
if Core.CancelledTimeouts[id] then
Core.CancelledTimeouts[id] = nil
else
cb()
end
end)
Core.TimeoutCount = id
return id
end
function ESX.RegisterCommand(name, group, cb, allowConsole, suggestion)
if type(name) == 'table' then
for k, v in ipairs(name) do
@@ -159,10 +143,6 @@ function ESX.RegisterCommand(name, group, cb, allowConsole, suggestion)
end
end
function ESX.ClearTimeout(id)
Core.CancelledTimeouts[id] = true
end
function ESX.RegisterServerCallback(name, cb)
Core.ServerCallbacks[name] = cb
end
@@ -176,10 +156,21 @@ function ESX.TriggerServerCallback(name, requestId, source,Invoke, cb, ...)
end
function Core.SavePlayer(xPlayer, cb)
local parameters <const> = {
json.encode(xPlayer.getAccounts(true)),
xPlayer.job.name,
xPlayer.job.grade,
xPlayer.group,
json.encode(xPlayer.getCoords()),
json.encode(xPlayer.getInventory(true)),
json.encode(xPlayer.getLoadout(true)),
xPlayer.identifier
}
MySQL.prepare(
'UPDATE `users` SET `accounts` = ?, `job` = ?, `job_grade` = ?, `group` = ?, `position` = ?, `inventory` = ?, `loadout` = ? WHERE `identifier` = ?',
{json.encode(xPlayer.getAccounts(true)), xPlayer.job.name, xPlayer.job.grade, xPlayer.group, json.encode(xPlayer.getCoords()),
json.encode(xPlayer.getInventory(true)), json.encode(xPlayer.getLoadout(true)), xPlayer.identifier}, function(affectedRows)
parameters,
function(affectedRows)
if affectedRows == 1 then
print(('[^2INFO^7] Saved player ^5"%s^7"'):format(xPlayer.name))
TriggerEvent('esx:playerSaved', xPlayer.playerId, xPlayer)
@@ -187,44 +178,50 @@ function Core.SavePlayer(xPlayer, cb)
if cb then
cb()
end
end)
end
)
end
function Core.SavePlayers(cb)
local xPlayers = ESX.GetExtendedPlayers()
local count = #xPlayers
if count > 0 then
local parameters = {}
local time = os.time()
for i = 1, count do
local xPlayer = xPlayers[i]
parameters[#parameters + 1] = {json.encode(xPlayer.getAccounts(true)), xPlayer.job.name, xPlayer.job.grade, xPlayer.group,
json.encode(xPlayer.getCoords()), json.encode(xPlayer.getInventory(true)), json.encode(xPlayer.getLoadout(true)),
xPlayer.identifier}
local xPlayers <const> = ESX.Players
if not next(xPlayers) then
return
end
local startTime <const> = os.time()
local parameters = {}
for _, xPlayer in pairs(ESX.Players) do
parameters[#parameters + 1] = {
json.encode(xPlayer.getAccounts(true)),
xPlayer.job.name,
xPlayer.job.grade,
xPlayer.group,
json.encode(xPlayer.getCoords()),
json.encode(xPlayer.getInventory(true)),
json.encode(xPlayer.getLoadout(true)),
xPlayer.identifier
}
end
MySQL.prepare(
"UPDATE `users` SET `accounts` = ?, `job` = ?, `job_grade` = ?, `group` = ?, `position` = ?, `inventory` = ?, `loadout` = ? WHERE `identifier` = ?",
parameters,
function(results)
if not results then
return
end
if type(cb) == 'function' then
return cb()
end
print(('[^2INFO^7] Saved ^5%s^7 %s over ^5%s^7 ms'):format(#parameters, #parameters > 1 and 'players' or 'player', ESX.Math.Round((os.time() - startTime) / 1000000, 2)))
end
MySQL.prepare(
"UPDATE `users` SET `accounts` = ?, `job` = ?, `job_grade` = ?, `group` = ?, `position` = ?, `inventory` = ?, `loadout` = ? WHERE `identifier` = ?",
parameters, function(results)
if results then
if type(cb) == 'function' then
cb()
else
print(('[^2INFO^7] Saved ^5%s^7 %s over ^5%s^7 ms'):format(count, count > 1 and 'players' or 'player', ESX.Math.Round((os.time() - time) / 1000000, 2)))
end
end
end)
end
)
end
function ESX.GetPlayers()
local sources = {}
for k, v in pairs(ESX.Players) do
sources[#sources + 1] = k
end
return sources
end
ESX.GetPlayers = GetPlayers
function ESX.GetExtendedPlayers(key, val)
local xPlayers = {}
@@ -245,11 +242,7 @@ function ESX.GetPlayerFromId(source)
end
function ESX.GetPlayerFromIdentifier(identifier)
for k, v in pairs(ESX.Players) do
if v.identifier == identifier then
return v
end
end
return Core.playersByIdentifier[identifier]
end
function ESX.GetIdentifier(playerId)
+9 -12
View File
@@ -71,11 +71,10 @@ function createESXPlayer(identifier, playerId, data)
accounts[account] = money
end
local defaultGroup = "user"
if Core.IsPlayerAdmin(playerId) then
print(('[^2INFO^0] Player ^5%s^0 Has been granted admin permissions via ^5Ace Perms^7.'):format(playerId))
defaultGroup = "admin"
else
defaultGroup = "user"
end
if not Config.Multichar then
@@ -243,12 +242,7 @@ function loadESXPlayer(identifier, playerId, isNew)
end
-- Position
if result.position and result.position ~= '' then
userData.coords = json.decode(result.position)
else
print('[^3WARNING^7] Column ^5"position"^0 in ^5"users"^0 table is missing required default value. Using backup coords, fix your database.')
userData.coords = {x = -269.4, y = -955.3, z = 31.2, heading = 205.8}
end
userData.coords = json.decode(result.position) or Config.DefaultSpawn
-- Skin
if result.skin and result.skin ~= '' then
@@ -280,6 +274,7 @@ function loadESXPlayer(identifier, playerId, isNew)
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
Core.playersByIdentifier[identifier] = xPlayer
if userData.firstname then
xPlayer.set('firstName', userData.firstname)
@@ -308,10 +303,10 @@ function loadESXPlayer(identifier, playerId, isNew)
maxWeight = xPlayer.getMaxWeight(),
money = xPlayer.getMoney(),
sex = xPlayer.get("sex") or "m",
firstName = xPlayer.get("firstName") or "John",
lastName = xPlayer.get("lastName") or "Doe",
dateofbirth = xPlayer.get("dateofbirth") or "01/01/2000",
height = xPlayer.get("height") or 120,
firstName = xPlayer.get("firstName") or "John",
lastName = xPlayer.get("lastName") or "Doe",
dateofbirth = xPlayer.get("dateofbirth") or "01/01/2000",
height = xPlayer.get("height") or 120,
dead = false
}, isNew,
userData.skin)
@@ -342,6 +337,7 @@ AddEventHandler('playerDropped', function(reason)
if xPlayer then
TriggerEvent('esx:playerDropped', playerId, reason)
Core.playersByIdentifier[xPlayer.identifier] = nil
Core.SavePlayer(xPlayer, function()
ESX.Players[playerId] = nil
end)
@@ -353,6 +349,7 @@ AddEventHandler('esx:playerLogout', function(playerId, cb)
if xPlayer then
TriggerEvent('esx:playerDropped', playerId)
Core.playersByIdentifier[xPlayer.identifier] = nil
Core.SavePlayer(xPlayer, function()
ESX.Players[playerId] = nil
if cb then
@@ -15,20 +15,20 @@ if Config.EnableDebug then
print('esx:playerJumping', source)
end)
AddEventHandler('esx:enteringVehicle', function(vehicle, plate, seat, netId)
print('esx:enteringVehicle', 'source', source, 'vehicle', vehicle, 'plate', plate, 'seat', seat, 'netId', netId)
AddEventHandler('esx:enteringVehicle', function(plate, seat, netId)
print('esx:enteringVehicle', 'source', source, 'plate', plate, 'seat', seat, 'netId', netId)
end)
AddEventHandler('esx:enteringVehicleAborted', function()
print('esx:enteringVehicleAborted', source)
end)
AddEventHandler('esx:enteredVehicle', function(vehicle, plate, seat, displayName, netId)
print('esx:enteredVehicle', 'source', source, 'vehicle', vehicle, 'plate', plate, 'seat', seat, 'displayName', displayName, 'netId', netId)
AddEventHandler('esx:enteredVehicle', function(plate, seat, displayName, netId)
print('esx:enteredVehicle', 'source', source, 'plate', plate, 'seat', seat, 'displayName', displayName, 'netId', netId)
end)
AddEventHandler('esx:exitedVehicle', function(vehicle, plate, seat, displayName, netId)
print('esx:exitedVehicle', 'source', source, 'vehicle', vehicle, 'plate', plate, 'seat', seat, 'displayName', displayName, 'netId', netId)
AddEventHandler('esx:exitedVehicle', function(plate, seat, displayName, netId)
print('esx:exitedVehicle', 'source', source, 'plate', plate, 'seat', seat, 'displayName', displayName, 'netId', netId)
end)
end
+17 -18
View File
@@ -1,10 +1,9 @@
ESX.OneSync = {}
---@class vector3
---@field x number
---@field y number
---@field z number
---@param source number|vector3
---@param closest boolean
---@param distance? number
---@param ignore? table
local function getNearbyPlayers(source, closest, distance, ignore)
local result = {}
local count = 0
@@ -44,14 +43,14 @@ end
---@param source vector3|number playerId or vector3 coordinates
---@param maxDistance number
---@param ignore table playerIds to ignore, where the key is playerId and value is true
---@param ignore? table playerIds to ignore, where the key is playerId and value is true
function ESX.OneSync.GetPlayersInArea(source, maxDistance, ignore)
return getNearbyPlayers(source, false, maxDistance, ignore)
end
---@param source vector3|number playerId or vector3 coordinates
---@param maxDistance number
---@param ignore table playerIds to ignore, where the key is playerId and value is true
---@param ignore? table playerIds to ignore, where the key is playerId and value is true
function ESX.OneSync.GetClosestPlayer(source, maxDistance, ignore)
return getNearbyPlayers(source, true, maxDistance, ignore)
end
@@ -59,7 +58,7 @@ end
---@param model number|string
---@param coords vector3|table
---@param heading number
---@param Properties table
---@param properties table
---@param cb function
function ESX.OneSync.SpawnVehicle(model, coords, heading, properties, cb)
local vehicleModel = joaat(model)
@@ -70,14 +69,14 @@ function ESX.OneSync.SpawnVehicle(model, coords, heading, properties, cb)
ESX.GetVehicleType(vehicleModel, xPlayer.id, function(vehicleType)
if vehicleType then
local createdVehicle = CreateVehicleServerSetter(vehicleModel, vehicleType, coords, heading)
if DoesEntityExist(createdVehicle) then
local networkId = NetworkGetNetworkIdFromEntity(createdVehicle)
vehicleProperties.NetId = networkId
Entity(createdVehicle).state:set('VehicleProperties', vehicleProperties, true)
cb(networkId)
else
print('[^1ERROR^7] Unfortunately, this vehicle has not spawned')
if not DoesEntityExist(createdVehicle) then
return print('[^1ERROR^7] Unfortunately, this vehicle has not spawned')
end
local networkId = NetworkGetNetworkIdFromEntity(createdVehicle)
vehicleProperties.NetId = networkId
Entity(createdVehicle).state:set('VehicleProperties', vehicleProperties, true)
cb(networkId)
else
print(('[^1ERROR^7] Tried to spawn invalid vehicle - ^5%s^7!'):format(model))
end
@@ -110,7 +109,7 @@ function ESX.OneSync.SpawnPed(model, coords, heading, cb)
CreateThread(function()
local entity = CreatePed(0, model, coords.x, coords.y, coords.z, heading, true, true)
while not DoesEntityExist(entity) do Wait(50) end
return entity
cb(NetworkGetNetworkIdFromEntity(entity))
end)
end
@@ -123,7 +122,7 @@ function ESX.OneSync.SpawnPedInVehicle(model, vehicle, seat, cb)
CreateThread(function()
local entity = CreatePedInsideVehicle(vehicle, 1, model, seat, true, true)
while not DoesEntityExist(entity) do Wait(50) end
return entity
cb(NetworkGetNetworkIdFromEntity(entity))
end)
end
@@ -164,7 +163,7 @@ end
---@param maxDistance number
---@param modelFilter table models to ignore, where the key is the model hash and the value is true
---@return table
function ESX.OneSync.GetVehiclesInArea(coords, maxDistance, modelFilter, cb)
function ESX.OneSync.GetVehiclesInArea(coords, maxDistance, modelFilter)
return getNearbyEntities(GetAllVehicles(), coords, modelFilter, maxDistance)
end
+7 -8
View File
@@ -2,16 +2,15 @@ function StartPayCheck()
CreateThread(function()
while true do
Wait(Config.PaycheckInterval)
local xPlayers = ESX.GetExtendedPlayers()
for i = 1, #(xPlayers) do
local xPlayer = xPlayers[i]
for player, xPlayer in pairs(ESX.Players) do
local job = xPlayer.job.grade_name
local salary = xPlayer.job.grade_salary
if salary > 0 then
if job == 'unemployed' then -- unemployed
xPlayer.addAccountMoney('bank', salary, "Welfare Check")
TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, TranslateCap('bank'), TranslateCap('received_paycheck'), TranslateCap('received_help', salary),
TriggerClientEvent('esx:showAdvancedNotification', player, TranslateCap('bank'), TranslateCap('received_paycheck'), TranslateCap('received_help', salary),
'CHAR_BANK_MAZE', 9)
elseif Config.EnableSocietyPayouts then -- possibly a society
TriggerEvent('esx_society:getSociety', xPlayer.job.name, function(society)
@@ -21,21 +20,21 @@ function StartPayCheck()
xPlayer.addAccountMoney('bank', salary, "Paycheck")
account.removeMoney(salary)
TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, TranslateCap('bank'), TranslateCap('received_paycheck'),
TriggerClientEvent('esx:showAdvancedNotification', player, TranslateCap('bank'), TranslateCap('received_paycheck'),
TranslateCap('received_salary', salary), 'CHAR_BANK_MAZE', 9)
else
TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, TranslateCap('bank'), '', TranslateCap('company_nomoney'), 'CHAR_BANK_MAZE', 1)
TriggerClientEvent('esx:showAdvancedNotification', player, TranslateCap('bank'), '', TranslateCap('company_nomoney'), 'CHAR_BANK_MAZE', 1)
end
end)
else -- not a society
xPlayer.addAccountMoney('bank', salary, "Paycheck")
TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, TranslateCap('bank'), TranslateCap('received_paycheck'), TranslateCap('received_salary', salary),
TriggerClientEvent('esx:showAdvancedNotification', player, TranslateCap('bank'), TranslateCap('received_paycheck'), TranslateCap('received_salary', salary),
'CHAR_BANK_MAZE', 9)
end
end)
else -- generic job
xPlayer.addAccountMoney('bank', salary, "Paycheck")
TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, TranslateCap('bank'), TranslateCap('received_paycheck'), TranslateCap('received_salary', salary),
TriggerClientEvent('esx:showAdvancedNotification', player, TranslateCap('bank'), TranslateCap('received_paycheck'), TranslateCap('received_salary', salary),
'CHAR_BANK_MAZE', 9)
end
end
+1 -1
View File
@@ -4,7 +4,7 @@ game 'gta5'
author 'ESX-Framework & Brayden'
description 'Offical ESX Legacy Context Menu'
lua54 'yes'
version '1.9.0'
version '1.9.2'
ui_page 'index.html'
+4 -2
View File
@@ -84,7 +84,7 @@ RegisterNUICallback("closed",function(data,cb)
Closed()
end)
RegisterNUICallback("selected",function(data)
RegisterNUICallback("selected",function(data,cb)
if not activeMenu
or not activeMenu.onSelect
or not data.index
@@ -102,9 +102,10 @@ RegisterNUICallback("selected",function(data)
end
activeMenu:onSelect(ele)
if cb then cb('ok') end
end)
RegisterNUICallback("changed",function(data)
RegisterNUICallback("changed",function(data,cb)
if not activeMenu
or not data.index
or not data.value
@@ -136,6 +137,7 @@ RegisterNUICallback("changed",function(data)
elseif ele.inputType == "radio" then
ele.inputValue = data.value
end
if cb then cb('ok') end
end)
-- Keybind
-51
View File
@@ -1,51 +0,0 @@
### ESX Imports
##### Similar to importing the ESX locale functions or MySQL-Async, there is now an import for ESX
- Define `shared_script '@es_extended/imports.lua'` above all other scripts in your fxmanifest
- This will define the ESX object for both the client and server
##### The following event handler will also be created on the client
```lua
AddEventHandler('esx:setPlayerData', function(key, val)
if GetInvokingResource() == 'es_extended' then
ESX.PlayerData[key] = val
if OnPlayerData ~= nil then OnPlayerData(key, val) end
end
end)
```
- You will now receive updated ESX.PlayerData values whenever they change
- This does not include inventory or loadout data and it should still be retrieved with `ESX.GetPlayerData()`
- You can add your own functions to the import if you believe they will be useful in your resources
- You can trigger certain events or functions based on the key and value received (example in client.lua)
- The idea of this function is ensuring up-to-date values for `job, accounts, ped, and dead`
- You can set any data this way if you want to share it between resources
- Using `ESX.SetPlayerData('cuffed', true)` will create and set a new value that you can now reference anywhere
- If you are using OneSync you could set certain values to set a state bag (useful for other players to reference)
### Replacement for ESX.GetPlayers()
##### Old resources would utilise the ESX.GetPlayers() function in a loop with ESX.GetPlayerFromId() to retrieve xPlayer data
- This can be referred to as an xPlayer loop, and has been the cause for server hitches in resources such as esx_society and esx_status
- It is commonly used in robbery scripts to get the active number of cops, or for determining the number of EMS in other places
##### This method is outdated and should be replaced if you are using ESX Legacy
```lua
local xPlayers = ESX.GetPlayers()
for i=1, #xPlayers, 1 do
local xPlayer = ESX.GetPlayerFromId(xPlayers[i])
if xPlayer.job.name == 'police' then
TriggerClientEvent('esx:showNotification', xPlayers[i], 'You are a cop!')
end
end
```
##### This new method retrieves all xPlayer data at once, reducing the number of function references being called
```lua
local xPlayers = ESX.GetExtendedPlayers() -- Returns all xPlayers
for _, xPlayer in pairs(xPlayers) do
if xPlayer.job.name == 'police' then
TriggerClientEvent('esx:showNotification', xPlayer.source, 'You are a cop!')
end
end
local xPlayers = ESX.GetExtendedPlayers('job', 'police') -- Returns xPlayers with the police job
for _, xPlayer in pairs(xPlayers) do
TriggerClientEvent('esx:showNotification', xPlayer.source, 'You are a cop!')
end
```
-72
View File
@@ -1,72 +0,0 @@
RegisterNetEvent('esx:playerLoaded') -- Store the players data
AddEventHandler('esx:playerLoaded', function(xPlayer, isNew)
print(('Player Loaded. New | %s'):format(isNew))
ESX.PlayerData = xPlayer
ESX.PlayerLoaded = true
end)
RegisterNetEvent('esx:playerLogout') -- When a player logs out (multicharacter), reset their data
AddEventHandler('esx:playerLogout', function()
ESX.PlayerLoaded = false
ESX.PlayerData = {}
end)
-- These two functions can perform the same task
RegisterNetEvent('esx:setJob')
AddEventHandler('esx:setJob', function(job)
print('PlayerData.job was set to '..job)
if ESX.PlayerData.job.name ~= job.name then
print('You are now in a different job')
end
ESX.PlayerData.job = job
end)
function OnPlayerData(key, val, last)
if type(val) == 'table' then val = json.encode(val) end
print(('PlayerData.%s was set to %s'):format(key, val))
if key == 'job' then
if last.name ~= val.name then
print('You are now in a different job')
end
elseif key == 'dead' then -- However, this function can be used for other PlayerData
if val == true then
print('You die too easily')
SetTimeout(2000, function()
if ESX.PlayerData.dead then
print('Why are you still dead?')
end
end)
end
end
end
-----------------------------------------------
RegisterCommand('closestobject', function()
local result = ESX.Game.GetClosestObject(GetEntityCoords(PlayerPedId()))
print(result)
end)
RegisterCommand('closestped', function()
local result = ESX.Game.GetClosestPed(GetEntityCoords(PlayerPedId()))
print(result)
end)
RegisterCommand('closestplayer', function()
local result = ESX.Game.GetClosestPlayer(GetEntityCoords(PlayerPedId()))
print(result)
end)
RegisterCommand('closestvehicle', function()
local result = ESX.Game.GetClosestVehicle(GetEntityCoords(PlayerPedId()))
print(result)
end)
RegisterCommand('areaplayer', function()
local result = ESX.Game.GetPlayersInArea(GetEntityCoords(PlayerPedId()), 20)
print(json.encode(result))
end)
RegisterCommand('areavehicle', function()
local result = ESX.Game.GetVehiclesInArea(GetEntityCoords(PlayerPedId()), 20)
print(json.encode(result))
end)
-15
View File
@@ -1,15 +0,0 @@
fx_version 'adamant'
game 'gta5'
description 'ESX Boilerplate'
shared_script '@es_extended/imports.lua'
server_scripts {
'server/main.lua'
}
client_scripts {
'client/main.lua'
}
-43
View File
@@ -1,43 +0,0 @@
CreateThread(function()
Wait(3000)
print('^1Do not run this resource in a live environment, it is solely intended for showcasing ESX functions^0')
end)
RegisterNetEvent('esx:playerLoaded') -- When a player loads in, we can store some basic information about them locally
AddEventHandler('esx:playerLoaded', function(playerId, xPlayer)
print("Player | ".. playerId .. "spawned in")
ESX.Players[playerId] = xPlayer.job.name
end)
RegisterNetEvent('esx:setJob') -- The stored data does not sync with the framework unless we tell it to
AddEventHandler('esx:setJob', function(playerId, job)
print("Player | ".. playerId .. " | Changed Job. Job |".. job.label)
ESX.Players[playerId] = job.name
end)
AddEventHandler('esx:playerDropped', function(playerId, reason) -- Remove any cached data once the player no longer exists
print("Player | ".. playerId .. "Dropped. Reason | ".. reason)
ESX.Players[playerId] = nil
end)
AddEventHandler('onResourceStart', function(resourceName) -- The resource just restarted so we actually have a fresh copy of ESX.Players from the framework
if (GetCurrentResourceName() == resourceName) then -- Useful if we need to run functions or send events after a restart
local players = {}
for _, xPlayer in pairs(ESX.Players) do
players[xPlayer.source] = xPlayer.job.name
print( ('%s %s is online with player id %s'):format(xPlayer.job.grade_label, xPlayer.name, xPlayer.source) )
end
ESX.Players = players -- Replace the data as it is a waste of memory
end
end)
ESX.RegisterCommand('get', 'user', function(xPlayer, args)
print("Player |".. xPlayer.source.. "| Fetching all users.")
local xPlayers = ESX.GetExtendedPlayers(args.key, args.val) -- New hitchless xPlayer loop, with the ability to only return players with specific data
for _, xTarget in pairs(xPlayers) do -- Job and any non-table variable will work, ie. name, group, identifier, source
print("ID - ".. xTarget.source.." | Name - "..xTarget.getName().." | Job - ".. xTarget.job.label)
end
end, true, {help = 'Display all online players with specific player data', validate = false, arguments = {
{name = 'key', help = 'Variable to check (ie. job)', type = 'string'},
{name = 'val', help = 'Value required (ie. police)', type = 'any'}
}})
+1 -1
View File
@@ -4,7 +4,7 @@ game 'gta5'
description 'ESX Identity'
lua54 'yes'
version '1.9.0'
version '1.9.2'
shared_scripts {
'@es_extended/imports.lua',
+39
View File
@@ -0,0 +1,39 @@
Locales['da'] = {
['show_active_character'] = 'Vis aktiv karakter',
['active_character'] = 'Aktiv karakter: %s',
['error_active_character'] = 'Der opstod en fejl under indhentning af dine data.',
['delete_character'] = 'Slet din nuværende karakter.',
['deleted_character'] = 'Karakter slettet',
['error_delete_character'] = 'Der opstod et problem med at slette din karakter.',
['thank_you_for_registering'] = 'Registreringen lykkedes. God fornøjelse!',
['debug_xPlayer_get_first_name'] = 'Returnerer dit fornavn',
['debug_xPlayer_get_last_name'] = 'Returnerer dit efternavn',
['debug_xPlayer_get_full_name'] = 'Returnerer dit fulde navn',
['debug_xPlayer_get_sex'] = 'Returnerer dit køn',
['debug_xPlayer_get_dob'] = 'Returnerer din fødselsdato',
['debug_xPlayer_get_height'] = 'Giver din højde tilbage',
['error_debug_xPlayer_get_first_name'] = 'Der opstod et problem med at få dit fornavn.',
['error_debug_xPlayer_get_last_name'] = 'Der opstod et problem med at få dit efternavn.',
['error_debug_xPlayer_get_full_name'] = 'Der opstod et problem under indhentning af dit fulde navn.',
['error_debug_xPlayer_get_sex'] = 'Der var et problem med at få dit sex.',
['error_debug_xPlayer_get_dob'] = 'Der var et problem med at få din fødselsdato.',
['error_debug_xPlayer_get_height'] = 'Der var et problem med at få din højde.',
['return_debug_xPlayer_get_first_name'] = 'Fornavn: %s',
['return_debug_xPlayer_get_last_name'] = 'Efternavn: %s',
['return_debug_xPlayer_get_full_name'] = 'Fulde Navn: %s',
['return_debug_xPlayer_get_sex'] = 'Køn: %s',
['return_debug_xPlayer_get_dob'] = 'Fødselsdato: %s',
['return_debug_xPlayer_get_height'] = 'Højde: %s Tommer',
['data_incorrect'] = 'Ugyldige data. Prøv venligst igen.',
['invalid_format'] = 'Ugyldigt dataformat. Prøv venligst igen.',
['no_identifier'] = '[ESX Identitet]\nDer var et problem under indlæsning af din karakter!\nFejlkode: identifikator mangler\n\nDette skyldes, at din identifikator mangler. Venligst vend tilbage senere eller rapporter dette problem til serverejeren.',
['missing_identity'] = '[ESX Identitet]\nDer var et problem med at indlæse din karakter!\nFejlkode: identitet mangler\n\nDet ser ud til, at din identitet mangler, prøv at oprette forbindelse igen.',
['deleted_identity'] = 'Tegn slettet. Tilmeld dig igen for at oprette en ny karakter.',
['already_registered'] = 'Du har allerede tilmeldt dig.',
['invalid_firstname_format'] = 'Ugyldigt format (fornavn): Prøv venligst igen.',
['invalid_lastname_format'] = 'Ugyldigt format (efternavn): Prøv igen.',
['invalid_dob_format'] = 'Ugyldigt format (DOB): Prøv venligst igen.',
['invalid_sex_format'] = 'Ugyldigt format (køn): Prøv venligst igen.',
['invalid_height_format'] = 'Ugyldigt format (højde): Prøv venligst igen.'
}
+1 -1
View File
@@ -1,5 +1,5 @@
game 'common'
version '1.9.0'
version '1.9.2'
fx_version 'cerulean'
author 'ESX-Framework'
lua54 'yes'
+1 -1
View File
@@ -4,7 +4,7 @@ game 'gta5'
description 'ESX Menu Default'
lua54 'yes'
version '1.9.0'
version '1.9.2'
client_scripts {'@es_extended/imports.lua', 'client/main.lua'}
+1 -22
View File
@@ -30,10 +30,9 @@ local function closeMenu(namespace, name)
name = name,
})
if ESX.Table.SizeOf(OpenedMenus) == 0 then
if not next(OpenedMenus) then
SetNuiFocus(false)
end
end
ESX.UI.Menu.RegisterType(MenuType, openMenu, closeMenu)
@@ -78,24 +77,4 @@ AddEventHandler('esx_menu_dialog:message:menu_change', function(data)
if menu.change ~= nil then
menu.change(data, menu)
end
end)
CreateThread(function()
while true do
Wait(0)
if ESX.Table.SizeOf(OpenedMenus) > 0 then
DisableControlAction(0, 1, true) -- LookLeftRight
DisableControlAction(0, 2, true) -- LookUpDown
DisableControlAction(0, 142, true) -- MeleeAttackAlternate
DisableControlAction(0, 106, true) -- VehicleMouseControlOverride
DisableControlAction(0, 12, true) -- WeaponWheelUpDown
DisableControlAction(0, 14, true) -- WeaponWheelNext
DisableControlAction(0, 15, true) -- WeaponWheelPrev
DisableControlAction(0, 16, true) -- SelectNextWeapon
DisableControlAction(0, 17, true) -- SelectPrevWeapon
else
Wait(500)
end
end
end)
+1 -1
View File
@@ -4,7 +4,7 @@ game 'gta5'
description 'ESX Menu Dialog'
lua54 'yes'
version '1.9.0'
version '1.9.2'
client_scripts {
'@es_extended/imports.lua',
+1 -1
View File
@@ -4,7 +4,7 @@ game 'gta5'
description 'ESX Menu List'
lua54 'yes'
version '1.9.0'
version '1.9.2'
client_scripts {
'@es_extended/imports.lua',
+1 -1
View File
@@ -2,7 +2,7 @@ fx_version 'cerulean'
game 'gta5'
author 'ESX-Framework - Linden - KASH'
description 'Official Multicharacter System For ESX Legacy'
version '1.9.0'
version '1.9.2'
lua54 'yes'
dependencies {'es_extended', 'esx_context', 'esx_identity', 'esx_skin'}
+33
View File
@@ -0,0 +1,33 @@
Locales["da"] = {
["male"] = "Mand",
["female"] = "Kvinde",
["select_char"] = "Vælg karakter",
["select_char_description"] = "Vælg en karakter at spille som.",
["create_char"] = "Ny Karakter",
["char_play"] = "Spil",
["char_play_description"] = "Fortsæt ind i byen.",
["char_disabled"] = "Deaktiveret",
["char_disabled_description"] = "Denne karakter er ubrugelig.",
["char_delete"] = "Slet",
["char_delete_description"] = "Fjern denne karakter permanent.",
["char_delete_confirmation"] = "Slet bekræftelse",
["char_delete_confirmation_description"] = "Er du sikker på at fjerne det valgte karakter?",
["char_delete_yes_description"] = "Ja, jeg er sikker på at fjerne det valgte karakter",
["char_delete_no_description"] = "Nej, vend tilbage til karakter-indstillinger",
["character"] = "Karakter: %s",
["return"] = "Tilbage",
["return_description"] = "Vend tilbage til valg af karaktere.",
["command_setslots"] = "Indstil flerkarakters slotsnummer for en spiller",
["command_remslots"] = "Fjern flerkarakters slotsnummer for en spiller",
["command_enablechar"] = "Aktiver en valgt karakter af en spiller",
["command_disablechar"] = "Deaktiver en valgt karakter af en spiller",
["command_charslot"] = "Karakterens plads nummer",
["command_identifier"] = "Spiller-id",
["command_slots"] = "# af slots",
["slotsadd"] = "Du føjede %s slots til %s",
["slotsedit"] = "Du indstillerde %s slots til %s",
["slotsrem"] = "Du fjernede slots til %s",
["charenabled"] = "Du aktiverede karakter #%s af %s",
["chardisabled"] = "Du deaktiverede tegn #%s af %s",
["charnotfound"] = "Karakter #%s af %s eksisterer ikke",
}
+6 -2
View File
@@ -94,8 +94,12 @@ elseif ESX.GetConfig().Multichar == true then
local identifier = GetIdentifier(source)
if identifier then
if ESX.Players[identifier] then
deferrals.done(('A player is already connected to the server with this identifier.\nYour identifier: %s:%s'):format(PRIMARY_IDENTIFIER, identifier))
if not ESX.GetConfig().EnableDebug then
if ESX.Players[identifier] then
deferrals.done(('A player is already connected to the server with this identifier.\nYour identifier: %s:%s'):format(PRIMARY_IDENTIFIER, identifier))
else
deferrals.done()
end
else
deferrals.done()
end
+1 -1
View File
@@ -1,7 +1,7 @@
fx_version 'adamant'
lua54 'yes'
game 'gta5'
version '1.9.0'
version '1.9.2'
author 'ESX-Framework'
description 'Official NUI Notification system for ESX'
+38 -38
View File
@@ -1,50 +1,50 @@
local CurrentProgress = nil
local function Progressbar(message,length,Options)
local Canceled = false
if not CurrentProgress then
CurrentProgress = Options or {}
if CurrentProgress.animation then
if CurrentProgress.animation.type == "anim" then
ESX.Streaming.RequestAnimDict(CurrentProgress.animation.dict, function()
TaskPlayAnim(ESX.PlayerData.ped, CurrentProgress.animation.dict, CurrentProgress.animation.lib, 1.0, 1.0, length, 1, 1.0, false,false,false)
RemoveAnimDict(CurrentProgress.animation.dict)
end)
elseif CurrentProgress.animation.type == "Scenario" then
TaskStartScenarioInPlace(ESX.PlayerData.ped, CurrentProgress.animation.Scenario, 0, true)
end
if CurrentProgress then
return false
end
CurrentProgress = Options or {}
if CurrentProgress.animation then
if CurrentProgress.animation.type == "anim" then
ESX.Streaming.RequestAnimDict(CurrentProgress.animation.dict, function()
TaskPlayAnim(ESX.PlayerData.ped, CurrentProgress.animation.dict, CurrentProgress.animation.lib, 1.0, 1.0, length, 1, 1.0, false,false,false)
RemoveAnimDict(CurrentProgress.animation.dict)
end)
elseif CurrentProgress.animation.type == "Scenario" then
TaskStartScenarioInPlace(ESX.PlayerData.ped, CurrentProgress.animation.Scenario, 0, true)
end
if CurrentProgress.FreezePlayer then FreezeEntityPosition(PlayerPedId(),CurrentProgress.FreezePlayer) end
SendNuiMessage(json.encode({
type = "Progressbar",
length = length or 3000,
message = message or "ESX-Framework"
}))
CurrentProgress.length = length or 3000
while CurrentProgress ~= nil do
if CurrentProgress.length > 0 then
CurrentProgress.length -= 1000
else
ClearPedTasks(ESX.PlayerData.ped)
if CurrentProgress.FreezePlayer then FreezeEntityPosition(PlayerPedId(), false) end
if CurrentProgress.onFinish then CurrentProgress.onFinish() end
CurrentProgress = nil
end
Wait(1000)
end
if CurrentProgress.FreezePlayer then FreezeEntityPosition(PlayerPedId(), CurrentProgress.FreezePlayer) end
SendNUIMessage({
type = "Progressbar",
length = length or 3000,
message = message or "ESX-Framework"
})
CurrentProgress.length = length or 3000
while CurrentProgress ~= nil do
if CurrentProgress.length > 0 then
CurrentProgress.length -= 1000
else
ClearPedTasks(ESX.PlayerData.ped)
if CurrentProgress.FreezePlayer then FreezeEntityPosition(PlayerPedId(), false) end
if CurrentProgress.onFinish then CurrentProgress.onFinish() end
CurrentProgress = nil
end
Wait(1000)
end
end
ESX.RegisterInput("cancelprog", "[ProgressBar] Cancel Progressbar", "keyboard", "BACK", function()
if not CurrentProgress then return end
if not CurrentProgress.onCancel then return end
SendNuiMessage(json.encode({
SendNUIMessage({
type = "Close"
}))
ClearPedTasks(ESX.PlayerData.ped)
if CurrentProgress.FreezePlayer then FreezeEntityPosition(PlayerPedId(), false) end
CurrentProgress.canceled = true
CurrentProgress.length = 0
CurrentProgress.onCancel()
CurrentProgress = nil
})
ClearPedTasks(ESX.PlayerData.ped)
if CurrentProgress.FreezePlayer then FreezeEntityPosition(PlayerPedId(), false) end
CurrentProgress.canceled = true
CurrentProgress.length = 0
CurrentProgress.onCancel()
CurrentProgress = nil
end)
exports('Progressbar', Progressbar)
exports('Progressbar', Progressbar)
+2 -2
View File
@@ -1,10 +1,8 @@
<!DOCTYPE html>
<html lang="en">
<head>
<script src="nui://game/ui/jquery.js" type="text/javascript"></script>
<script src="https://kit.fontawesome.com/a81368914c.js"></script>
<link rel="stylesheet" href="css/style.css">
<script src="js/script.js"></script>
</head>
<body>
<div id="notifyInfo" class="notify">
@@ -13,8 +11,10 @@
<p class="text" id="infoMessage"></p>
</div>
<div id="progline" class="progline">
</div>
</div>
</body>
<script src="js/script.js"></script>
</html>
<style>
+53 -53
View File
@@ -1,6 +1,3 @@
const w = window
const doc = document
const codes = {
"~r~": "red",
"~b~": "#378cbf",
@@ -13,57 +10,60 @@ const codes = {
"~o~": "orange"
}
$(function () {
w.addEventListener('message', function(e) {
if (e.data.type === "Progressbar") {
var message = e.data.message
const replaceColors = (str, obj) => {
let strToReplace = str;
for (let id in obj) {
strToReplace = strToReplace.replace(new RegExp(id, "g"), obj[id]);
}
return strToReplace
}
for (color in codes) {
if (message.includes(color)) {
let objArr = {};
objArr[color] = `<span style="color: ${codes[color]}">`;
objArr["~s~"] = "</span>";
let newStr = replaceColors(message, objArr);
message = newStr
}
}
$(".text").html(`<p class="text">${message}</p>`)
doc.getElementById("notifyInfo").style.display = "block";
const start = new Date();
const maxTime = e.data.length;
const timeoutValue = Math.floor(maxTime/100);
animUpdate();
const elems = {
infoMessage: document.getElementById('infoMessage'),
notifyInfo: document.getElementById("notifyInfo"),
progline: document.getElementById('progline')
}
function updateProg(prc) {
$("#progline").css("width", prc + "%");
}
function animUpdate() {
const now = new Date();
const timeoutDiff = now.getTime() - start.getTime();
const prc = Math.round((timeoutDiff/maxTime)*100);
if (prc <= 100) {
updateProg(prc);
this.timeoutID = setTimeout(animUpdate, timeoutValue);
} else {
doc.getElementById('notifyInfo').style.display = "none";
}
}
} else {
doc.getElementById("notifyInfo").style.display = "none"
clearTimeout(this.timeoutID);
timeoutValue = 0;
const replaceColors = (str, obj) => {
let strToReplace = str;
for (let id in obj) {
strToReplace = strToReplace.replace(new RegExp(id, "g"), obj[id]);
}
return strToReplace
}
window.addEventListener('message', function({data}) {
if (data.type === "Progressbar") {
let { message } = data
for (color in codes) {
if (message.includes(color)) {
let objArr = {};
objArr[color] = `<span style="color: ${codes[color]}">`;
objArr["~s~"] = "</span>";
let newStr = replaceColors(message, objArr);
message = newStr
}
}
})
elems.infoMessage.innerHTML = message
elems.notifyInfo.style.display = "block";
const start = new Date();
const maxTime = data.length;
const timeoutValue = Math.floor(maxTime / 100);
animUpdate();
function animUpdate() {
const now = new Date();
const timeoutDiff = now.getTime() - start.getTime();
const prc = Math.round((timeoutDiff/maxTime)*100);
if (prc <= 100) {
elems.progline.style.width = prc + "%"
this.timeoutID = setTimeout(animUpdate, timeoutValue);
} else {
elems.notifyInfo.style.display = "none";
}
}
} else {
elems.notifyInfo.style.display = 'none'
clearTimeout(this.timeoutID);
timeoutValue = 0;
}
})
+1 -1
View File
@@ -4,7 +4,7 @@ game 'gta5'
description 'ESX Skin'
version '1.9.0'
version '1.9.2'
lua54 'yes'
shared_script '@es_extended/imports.lua'
+1 -1
View File
@@ -1,7 +1,7 @@
fx_version 'adamant'
game 'gta5'
author 'ESX-Framework'
version '1.9.0'
version '1.9.2'
description 'ESX TextUI'
lua54 'yes'
client_scripts { 'TextUI.lua' }
+1 -1
View File
@@ -6,7 +6,7 @@ lua54 'yes'
description 'Official ESX-Legacy resource for handling the Player`s Skin'
version '1.9.0'
version '1.9.2'
client_scripts {
'@es_extended/locale.lua',