Merge pull request #1398 from esx-framework/dev

📦 1.10.8 Release package
This commit is contained in:
Gellipapa
2024-10-10 18:11:28 +02:00
committed by GitHub
23 changed files with 901 additions and 965 deletions
+1 -1
View File
@@ -28,7 +28,7 @@ TriggerEvent('cron:runAt', 18, 30, CronTask)
cron - run tasks at specific intervals!
Copyright (C) 2015-2023 Jérémie N'gadi
Copyright (C) 2015-2024 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.
+13
View File
@@ -0,0 +1,13 @@
<h1 align='center'>es_extended</a></h1><p align='center'><b><a href='https://discord.esx-framework.org/'>Discord</a> - <a href='https://documentation.esx-framework.org/legacy/installation'>Documentation</a></b></h5>
## Legal
es_extended
Copyright (C) 2015-2024 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/>.
+84 -103
View File
@@ -24,19 +24,38 @@ function ESX.GetPlayerData()
return ESX.PlayerData
end
local addonResourcesState = {
['esx_progressbar'] = GetResourceState('esx_progressbar') ~= 'missing',
['esx_notify'] = GetResourceState('esx_notify') ~= 'missing',
['esx_textui'] = GetResourceState('esx_textui') ~= 'missing',
['esx_context'] = GetResourceState('esx_context') ~= 'missing'
}
local function IsResourceFound(resource)
return addonResourcesState[resource] or print(('[^1ERROR^7] ^5%s^7 is Missing!'):format(resource))
end
function ESX.SearchInventory(items, count)
items = type(items) == "string" and { items } or items
local item
if type(items) == 'string' then
item, items = items, {items}
end
local data = {}
for i = 1, #items do
for c = 1, #ESX.PlayerData.inventory do
if ESX.PlayerData.inventory[c].name == items[i] then
data[items[i]] = (count and ESX.PlayerData.inventory[c].count) or ESX.PlayerData.inventory[c]
for i = 1, #ESX.PlayerData.inventory do
local e = ESX.PlayerData.inventory[i]
for ii = 1, #items do
if e.name == items[ii] then
data[table.remove(items, ii)] = count and e.count or e
break
end
end
if #items == 0 then
break
end
end
return #items == 1 and data[items[1]] or data
return not item and data or data[item]
end
function ESX.SetPlayerData(key, val)
@@ -49,62 +68,39 @@ function ESX.SetPlayerData(key, val)
end
end
function ESX.Progressbar(message, length, Options)
if GetResourceState("esx_progressbar") ~= "missing" then
return exports["esx_progressbar"]:Progressbar(message, length, Options)
end
print("[^1ERROR^7] ^5ESX Progressbar^7 is Missing!")
function ESX.Progressbar(...)
return IsResourceFound('esx_progressbar') and exports['esx_progressbar']:Progressbar(...)
end
function ESX.ShowNotification(message, notifyType, length)
if GetResourceState("esx_notify") ~= "missing" then
return exports["esx_notify"]:Notify(notifyType, length, message)
end
print("[^1ERROR^7] ^5ESX Notify^7 is Missing!")
return IsResourceFound('esx_notify') and exports['esx_notify']:Notify(notifyType, length, message)
end
function ESX.TextUI(message, notifyType)
if GetResourceState("esx_textui") ~= "missing" then
return exports["esx_textui"]:TextUI(message, notifyType)
end
print("[^1ERROR^7] ^5ESX TextUI^7 is Missing!")
function ESX.TextUI(...)
return IsResourceFound('esx_textui') and exports['esx_textui']:TextUI(...)
end
function ESX.HideUI()
if GetResourceState("esx_textui") ~= "missing" then
return exports["esx_textui"]:HideUI()
end
print("[^1ERROR^7] ^5ESX TextUI^7 is Missing!")
return IsResourceFound('esx_textui') and exports['esx_textui']:HideUI()
end
function ESX.ShowAdvancedNotification(sender, subject, msg, textureDict, iconType, flash, saveToBrief, hudColorIndex)
if saveToBrief == nil then
saveToBrief = true
end
AddTextEntry("esxAdvancedNotification", msg)
BeginTextCommandThefeedPost("esxAdvancedNotification")
if hudColorIndex then
ThefeedSetNextPostBackgroundColor(hudColorIndex)
end
EndTextCommandThefeedPostMessagetext(textureDict, textureDict, false, iconType, sender, subject)
EndTextCommandThefeedPostTicker(flash or false, saveToBrief)
EndTextCommandThefeedPostTicker(flash, saveToBrief == nil or saveToBrief)
end
function ESX.ShowHelpNotification(msg, thisFrame, beep, duration)
AddTextEntry("esxHelpNotification", msg)
if thisFrame then
DisplayHelpTextThisFrame("esxHelpNotification", false)
DisplayHelpTextThisFrame("esxHelpNotification")
else
if beep == nil then
beep = true
end
BeginTextCommandDisplayHelp("esxHelpNotification")
EndTextCommandDisplayHelp(0, false, beep, duration or -1)
EndTextCommandDisplayHelp(0, false, beep == nil or beep, duration or -1)
end
end
@@ -116,42 +112,40 @@ function ESX.ShowFloatingHelpNotification(msg, coords)
EndTextCommandDisplayHelp(2, false, false, -1)
end
ESX.HashString = function(str)
local format = string.format
local upper = string.upper
local gsub = string.gsub
local hash = joaat(str)
local input_map = format("~INPUT_%s~", upper(format("%x", hash)))
input_map = gsub(input_map, "FFFFFFFF", "")
return input_map
function ESX.DrawMissionText(msg, time)
ClearPrints()
BeginTextCommandPrint('STRING')
AddTextComponentSubstringPlayerName(msg)
EndTextCommandPrint(time, true)
end
local contextAvailable = GetResourceState("esx_context") ~= "missing"
function ESX.HashString(str)
return ('~INPUT_%s~'):format(('%x'):format(joaat(str)):upper())
end
function ESX.OpenContext(...)
return contextAvailable and exports["esx_context"]:Open(...) or not contextAvailable and print("[^1ERROR^7] Tried to ^5open^7 context menu, but ^5esx_context^7 is missing!")
return IsResourceFound('esx_context') and exports['esx_context']:Open(...)
end
function ESX.PreviewContext(...)
return contextAvailable and exports["esx_context"]:Preview(...) or not contextAvailable and print("[^1ERROR^7] Tried to ^5preview^7 context menu, but ^5esx_context^7 is missing!")
return IsResourceFound('esx_context') and exports['esx_context']:Preview(...)
end
function ESX.CloseContext(...)
return contextAvailable and exports["esx_context"]:Close(...) or not contextAvailable and print("[^1ERROR^7] Tried to ^5close^7 context menu, but ^5esx_context^7 is missing!")
return IsResourceFound('esx_context') and exports['esx_context']:Close(...)
end
function ESX.RefreshContext(...)
return contextAvailable and exports["esx_context"]:Refresh(...) or not contextAvailable and print("[^1ERROR^7] Tried to ^5Refresh^7 context menu, but ^5esx_context^7 is missing!")
return IsResourceFound('esx_context') and exports['esx_context']:Refresh(...)
end
ESX.RegisterInput = function(command_name, label, input_group, key, on_press, on_release)
RegisterCommand(on_release ~= nil and "+" .. command_name or command_name, on_press)
Core.Input[command_name] = on_release ~= nil and ESX.HashString("+" .. command_name) or ESX.HashString(command_name)
function ESX.RegisterInput(command_name, label, input_group, key, on_press, on_release)
RegisterCommand("+" .. command_name, on_press)
Core.Input[command_name] = ESX.HashString("+" .. command_name)
if on_release then
RegisterCommand("-" .. command_name, on_release)
end
RegisterKeyMapping(on_release ~= nil and "+" .. command_name or command_name, label, input_group, key)
RegisterKeyMapping("+" .. command_name, label or '', input_group or 'keyboard', key or '')
end
function ESX.UI.Menu.RegisterType(menuType, open, close)
@@ -276,9 +270,7 @@ function ESX.UI.Menu.GetOpenedMenus()
return ESX.UI.Menu.Opened
end
function ESX.UI.Menu.IsOpen(menuType, namespace, name)
return ESX.UI.Menu.GetOpened(menuType, namespace, name) ~= nil
end
ESX.UI.Menu.IsOpen = ESX.UI.Menu.GetOpened
function ESX.UI.ShowInventoryItemNotification(add, item, count)
SendNUIMessage({
@@ -321,18 +313,8 @@ function ESX.Game.Teleport(entity, coords, cb)
end
function ESX.Game.SpawnObject(object, coords, cb, networked)
networked = networked == nil and true or networked
local model = type(object) == "number" and object or joaat(object)
local vector = type(coords) == "vector3" and coords or vec(coords.x, coords.y, coords.z)
CreateThread(function()
ESX.Streaming.RequestModel(model)
local obj = CreateObject(model, vector.xyz, networked, false, true)
if cb then
cb(obj)
end
end)
local obj = CreateObject(ESX.Streaming.RequestModel(object), coords.x, coords.y. coords.z, networked == nil or networked, false, true)
return cb and cb(obj) or obj
end
function ESX.Game.SpawnLocalObject(object, coords, cb)
@@ -396,10 +378,7 @@ function ESX.Game.SpawnLocalVehicle(vehicle, coords, heading, cb)
end
function ESX.Game.IsVehicleEmpty(vehicle)
local passengers = GetVehicleNumberOfPassengers(vehicle)
local driverSeatFree = IsVehicleSeatFree(vehicle, -1)
return passengers == 0 and driverSeatFree
return GetVehicleNumberOfPassengers(vehicle) == 0 and IsVehicleSeatFree(vehicle, -1)
end
function ESX.Game.GetObjects() -- Leave the function for compatibility
@@ -495,6 +474,19 @@ function ESX.Game.IsSpawnPointClear(coords, maxDistance)
return #ESX.Game.GetVehiclesInArea(coords, maxDistance) == 0
end
function ESX.Game.GetShapeTestResultSync(shape)
local handle, hit, coords, normal, material, entity
repeat handle, hit, coords, normal, material, entity = GetShapeTestResultIncludingMaterial(shape)
until handle ~= 1 or Wait()
return hit, coords, normal, material, entity
end
function ESX.Game.RaycastScreen(depth, ...)
local world, normal = GetWorldCoordFromScreenCoord(.5, .5)
local target = world + normal * depth
return target, ESX.Game.GetShapeTestResultAsync(StartShapeTestLosProbe(world + normal, target, ...))
end
function ESX.Game.GetClosestEntity(entities, isPlayerEntities, coords, modelFilter)
local closestEntity, closestEntityDistance, filteredEntities = -1, -1, nil
@@ -527,18 +519,10 @@ function ESX.Game.GetClosestEntity(entities, isPlayerEntities, coords, modelFilt
end
function ESX.Game.GetVehicleInDirection()
local playerPed = ESX.PlayerData.ped
local playerCoords = GetEntityCoords(playerPed)
local inDirection = GetOffsetFromEntityInWorldCoords(playerPed, 0.0, 5.0, 0.0)
local rayHandle = StartExpensiveSynchronousShapeTestLosProbe(playerCoords, inDirection, 10, playerPed, 0)
local _, hit, _, _, entityHit = GetShapeTestResult(rayHandle)
if hit == 1 and GetEntityType(entityHit) == 2 then
local entityCoords = GetEntityCoords(entityHit)
return entityHit, entityCoords
local _, hit, coords, _, _, entity = ESX.Game.RaycastScreen(5, 10, ESX.PlayerData.ped)
if hit and IsEntityAVehicle(entity) then
return entity, coords
end
return nil
end
function ESX.Game.GetVehicleProperties(vehicle)
@@ -576,14 +560,20 @@ function ESX.Game.GetVehicleProperties(vehicle)
end
local doorsBroken, windowsBroken, tyreBurst = {}, {}, {}
local numWheels = tostring(GetVehicleNumberOfWheels(vehicle))
local TyresIndex = { -- Wheel index list according to the number of vehicle wheels.
["2"] = { 0, 4 }, -- Bike and cycle.
["3"] = { 0, 1, 4, 5 }, -- Vehicle with 3 wheels (get for wheels because some 3 wheels vehicles have 2 wheels on front and one rear or the reverse).
["4"] = { 0, 1, 4, 5 }, -- Vehicle with 4 wheels.
["6"] = { 0, 1, 2, 3, 4, 5 }, -- Vehicle with 6 wheels.
}
local wheel_count = GetVehicleNumberOfWheels(vehicle);
for wheel_index = 0, wheel_count - 1 do
tyreBurst[tostring(wheel_index)] = IsVehicleTyreBurst(vehicle, wheel_index, false)
if TyresIndex[numWheels] then
for _, idx in pairs(TyresIndex[numWheels]) do
tyreBurst[tostring(idx)] = IsVehicleTyreBurst(vehicle, idx, false)
end
end
for windowId = 0, 7 do -- 13
RollUpWindow(vehicle, windowId) --fix when you put the car away with the window down
@@ -1256,20 +1246,11 @@ function ESX.ShowInventory()
end)
end
RegisterNetEvent("esx:showNotification")
AddEventHandler("esx:showNotification", function(msg, notifyType, length)
ESX.ShowNotification(msg, notifyType, length)
end)
RegisterNetEvent('esx:showNotification', ESX.ShowNotification)
RegisterNetEvent("esx:showAdvancedNotification")
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:showAdvancedNotification', ESX.ShowAdvancedNotification)
RegisterNetEvent("esx:showHelpNotification")
AddEventHandler("esx:showHelpNotification", function(msg, thisFrame, beep, duration)
ESX.ShowHelpNotification(msg, thisFrame, beep, duration)
end)
RegisterNetEvent('esx:showHelpNotification', ESX.ShowHelpNotification)
AddEventHandler("onResourceStop", function(resourceName)
for i = 1, #ESX.UI.Menu.Opened, 1 do
+13 -3
View File
@@ -25,14 +25,19 @@ function ESX.SpawnPlayer(skin, coords, cb)
end)
Citizen.Await(p)
RequestCollisionAtCoord(coords.x, coords.y, coords.z)
local playerPed = PlayerPedId()
local timer = GetGameTimer()
FreezeEntityPosition(playerPed, true)
SetEntityCoordsNoOffset(playerPed, coords.x, coords.y, coords.z, false, false, false, true)
SetEntityHeading(playerPed, coords.heading)
while not HasCollisionLoadedAroundEntity(playerPed) do
while not HasCollisionLoadedAroundEntity(playerPed) and (GetGameTimer() - timer) < 5000 do
Wait(0)
end
FreezeEntityPosition(playerPed, false)
NetworkResurrectLocalPlayer(coords.x, coords.y, coords.z, coords.heading, true, true, false)
TriggerEvent('playerSpawned', coords)
cb()
@@ -140,6 +145,7 @@ AddEventHandler("esx:playerLoaded", function(xPlayer, _, skin)
for i = 1, 15 do
EnableDispatchService(i, false)
end
SetAudioFlag('PoliceScannerDisabled', true)
end
-- Disable Scenarios
@@ -203,6 +209,10 @@ AddEventHandler("esx:playerLoaded", function(xPlayer, _, skin)
end
end
if not Config.Multichar then
FreezeEntityPosition(ESX.PlayerData.ped, false)
end
if IsScreenFadedOut() then
DoScreenFadeIn(500)
end
@@ -709,6 +719,6 @@ ESX.RegisterClientCallback("esx:GetVehicleType", function(cb, model)
cb(ESX.GetVehicleType(model))
end)
AddStateBagChangeHandler("metadata", "player:" .. tostring(GetPlayerServerId(PlayerId())), function(_, key, val)
RegisterNetEvent('esx:updatePlayerData', function(key, val)
ESX.SetPlayerData(key, val)
end)
@@ -89,7 +89,7 @@ CreateThread(function()
ToggleVehicleStatus(current.vehicle, current.seat)
end
elseif isInVehicle then
if not IsPedInAnyVehicle(playerPed, false) or IsPlayerDead(PlayerId()) then
if (current.vehicle ~= GetVehiclePedIsUsing(playerPed)) or IsPlayerDead(PlayerId()) then
-- bye, vehicle
TriggerEvent("esx:exitedVehicle", current.vehicle, current.plate, current.seat, current.displayName, current.netId)
TriggerServerEvent("esx:exitedVehicle", current.plate, current.seat, current.displayName, current.netId)
+14 -62
View File
@@ -1,85 +1,37 @@
function ESX.Streaming.RequestModel(modelHash, cb)
modelHash = (type(modelHash) == "number" and modelHash or joaat(modelHash))
if not HasModelLoaded(modelHash) and IsModelInCdimage(modelHash) then
modelHash = type(modelHash) == "number" and modelHash or joaat(modelHash)
if not IsModelInCdimage(modelHash) then return end
RequestModel(modelHash)
while not HasModelLoaded(modelHash) do
Wait(0)
end
end
if cb ~= nil then
cb()
end
while not HasModelLoaded(modelHash) do Wait() end
return cb and cb(modelHash) or modelHash
end
function ESX.Streaming.RequestStreamedTextureDict(textureDict, cb)
if not HasStreamedTextureDictLoaded(textureDict) then
RequestStreamedTextureDict(textureDict)
while not HasStreamedTextureDictLoaded(textureDict) do
Wait(0)
end
end
if cb ~= nil then
cb()
end
while not HasStreamedTextureDictLoaded(textureDict) do Wait() end
return cb and cb(textureDict) or textureDict
end
function ESX.Streaming.RequestNamedPtfxAsset(assetName, cb)
if not HasNamedPtfxAssetLoaded(assetName) then
RequestNamedPtfxAsset(assetName)
while not HasNamedPtfxAssetLoaded(assetName) do
Wait(0)
end
end
if cb ~= nil then
cb()
end
while not HasNamedPtfxAssetLoaded(assetName) do Wait() end
return cb and cb(assetName) or assetName
end
function ESX.Streaming.RequestAnimSet(animSet, cb)
if not HasAnimSetLoaded(animSet) then
RequestAnimSet(animSet)
while not HasAnimSetLoaded(animSet) do
Wait(0)
end
end
if cb ~= nil then
cb()
end
while not HasAnimSetLoaded(animSet) do Wait() end
return cb and cb(animSet) or animSet
end
function ESX.Streaming.RequestAnimDict(animDict, cb)
if not HasAnimDictLoaded(animDict) then
RequestAnimDict(animDict)
while not HasAnimDictLoaded(animDict) do
Wait(0)
end
end
if cb ~= nil then
cb()
end
while not HasAnimDictLoaded(animDict) do Wait() end
return cb and cb(animDict) or animDict
end
function ESX.Streaming.RequestWeaponAsset(weaponHash, cb)
if not HasWeaponAssetLoaded(weaponHash) then
RequestWeaponAsset(weaponHash)
while not HasWeaponAssetLoaded(weaponHash) do
Wait(0)
end
end
if cb ~= nil then
cb()
end
while not HasWeaponAssetLoaded(weaponHash) do Wait() end
return cb and cb(weaponHash) or weaponHash
end
+1 -1
View File
@@ -305,7 +305,7 @@ Locales["de"] = {
["component_camo_slide_finish10"] = "BOOM Rutschen Camouflage",
["component_camo_slide_finish11"] = "Patriotisch Rutschen Camouflage",
["component_clip_default"] = "Standart Magazin",
["component_clip_default"] = "Standard Magazin",
["component_clip_extended"] = "Erweiterters Magazin",
["component_clip_drum"] = "Trommelmagazin",
["component_clip_box"] = "Kastenmagazin",
+8 -10
View File
@@ -52,12 +52,11 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory,
_ExecuteCommand(("add_principal identifier.%s group.%s"):format(self.license, self.group))
local stateBag = Player(self.source).state
stateBag:set("identifier", self.identifier, true)
stateBag:set("license", self.license, true)
stateBag:set("identifier", self.identifier, false)
stateBag:set("license", self.license, false)
stateBag:set("job", self.job, true)
stateBag:set("group", self.group, true)
stateBag:set("name", self.name, true)
stateBag:set("metadata", self.metadata, true)
---@param eventName string
---@param ... any
@@ -163,7 +162,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory,
---@return void
function self.set(k, v)
self.variables[k] = v
Player(self.source).state:set(k, v, true)
end
---@param k string
@@ -191,8 +189,10 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory,
---@param account string
---@return table | nil
function self.getAccount(account)
account = string.lower(account)
for i = 1, #self.accounts do
if self.accounts[i].name == account then
local accountName = string.lower(self.accounts[i].name)
if accountName == account then
return self.accounts[i]
end
end
@@ -476,7 +476,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory,
local lastJob = self.job
if not ESX.DoesJobExist(newJob, grade) then
return print(("[es_extended] [^3WARNING^7] Ignoring invalid ^5.setJob()^7 usage for ID: ^5%s^7, Job: ^5%s^7"):format(self.source, job))
return print(("[es_extended] [^3WARNING^7] Ignoring invalid ^5.setJob()^7 usage for ID: ^5%s^7, Job: ^5%s^7"):format(self.source, newJob))
end
local jobObject, gradeObject = ESX.Jobs[newJob], ESX.Jobs[newJob].grades[grade]
@@ -829,8 +829,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory,
self.metadata[index] = type(self.metadata[index]) == "table" and self.metadata[index] or {}
self.metadata[index][value] = subValue
end
Player(self.source).state:set("metadata", self.metadata, true)
self.triggerEvent('esx:updatePlayerData', 'metadata', self.metadata)
end
function self.clearMeta(index, subValues)
@@ -874,8 +873,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory,
else
return print(("[^1ERROR^7] xPlayer.clearMeta ^5subValues^7 should be ^5string^7 or ^5table^7, received ^5%s^7!"):format(type(subValues)))
end
Player(self.source).state:set("metadata", self.metadata, true)
self.triggerEvent('esx:updatePlayerData', 'metadata', self.metadata)
end
for fnName, fn in pairs(targetOverrides) do
+6 -2
View File
@@ -129,6 +129,7 @@ function loadESXPlayer(identifier, playerId, isNew)
inventory = {},
loadout = {},
weight = 0,
name = GetPlayerName(playerId),
identifier = identifier,
firstName = "John",
lastName = "Doe",
@@ -257,9 +258,12 @@ function loadESXPlayer(identifier, playerId, isNew)
userData.firstName = result.firstname
userData.lastName = result.lastname
local name = ("%s %s"):format(result.firstname, result.lastname)
userData.name = name
xPlayer.set("firstName", result.firstname)
xPlayer.set("lastName", result.lastname)
xPlayer.setName(("%s %s"):format(result.firstname, result.lastname))
xPlayer.setName(name)
if result.dateofbirth then
userData.dateofbirth = result.dateofbirth
@@ -302,7 +306,7 @@ end
AddEventHandler("chatMessage", function(playerId, _, message)
local xPlayer = ESX.GetPlayerFromId(playerId)
if message:sub(1, 1) == "/" and playerId > 0 then
if xPlayer and message:sub(1, 1) == "/" and playerId > 0 then
CancelEvent()
local commandName = message:sub(1):gmatch("%w+")()
xPlayer.showNotification(TranslateCap("commanderror_invalidcommand", commandName))
+22 -30
View File
@@ -19,18 +19,6 @@ local function doesJobAndGradesExist(name, grades)
return true
end
local function generateTransactionQueries(name,grades)
local queries = {}
for _, grade in ipairs(grades) do
queries[#queries+1] = {
query = 'INSERT INTO job_grades (job_name, grade, name, label, salary, skin_male, skin_female) VALUES (?, ?, ?, ?, ?, ?, ?)',
values = {name, grade.grade, grade.name, grade.label, grade.salary, '{}', '{}'}
}
end
return queries
end
local function generateNewJobTable(name, label, grades)
local job = { name = name, label = label, grades = {} }
for _, v in pairs(grades) do
@@ -60,43 +48,47 @@ function ESX.CreateJob(name, label, grades)
if not name or name == '' then
notify("ERROR",currentResourceName, 'Missing argument `name`')
return
return success
end
if not label or label == '' then
notify("ERROR",currentResourceName, 'Missing argument `label`')
return
return success
end
if not grades or not next(grades) then
notify("ERROR",currentResourceName, 'Missing argument `grades`')
return
return success
end
local currentJobExist = doesJobAndGradesExist(name, grades)
if currentJobExist then
notify("ERROR",currentResourceName, 'Job or grades already exists: `%s`', name)
return
return success
end
MySQL.insert('INSERT IGNORE INTO jobs (name, label) VALUES (?, ?)', {name, label}, function(jobId)
if jobId == nil or jobId == 0 then
notify("ERROR",currentResourceName, 'Failed to insert job: `%s`', name)
return
local queries = {
{ query = 'INSERT INTO jobs (name, label) VALUES (?, ?)', values = { name, label } }
}
for _, grade in ipairs(grades) do
queries[#queries + 1] = {
query = 'INSERT INTO job_grades (job_name, grade, name, label, salary, skin_male, skin_female) VALUES (?, ?, ?, ?, ?, ?, ?)',
values = { name, grade.grade, grade.name, grade.label, grade.salary, '{}', '{}' }
}
end
local queries = generateTransactionQueries(name, grades)
success = exports.oxmysql:transaction_async(queries)
MySQL.transaction(queries, function(results)
success = results
if not results then
notify("ERROR",currentResourceName, 'Failed to insert one or more grades for job: `%s`', name)
return
if not success then
notify("ERROR", currentResourceName, 'Failed to insert one or more grades for job: `%s`', name)
return success
end
ESX.Jobs[name] = generateNewJobTable(name,label,grades)
notify("SUCCESS",currentResourceName, 'Job created successfully: `%s`', name)
end)
end)
ESX.Jobs[name] = generateNewJobTable(name, label, grades)
notify("SUCCESS", currentResourceName, 'Job created successfully: `%s`', name)
return success
end
+1 -1
View File
@@ -21,7 +21,7 @@ A Core Resource that Allows the player to Pick their characters, Name, Gender, H
esx_identity - Make your Character a Person!
Copyright (C) 2015-2023 Jérémie N'gadi
Copyright (C) 2015-2024 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.
+27 -30
View File
@@ -12,20 +12,34 @@ local function deleteIdentityFromDatabase(xPlayer)
end
end
function SetPlayerData(xPlayer, data)
local name = ("%s %s"):format(data.firstName, data.lastName)
xPlayer.setName(name)
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)
local state = Player(xPlayer.source).state
state:set("name", name, true)
state:set("firstName", data.firstName, true)
state:set("lastName", data.lastName, true)
state:set("dateofbirth", data.dateOfBirth, true)
state:set("sex", data.sex, true)
state:set("height", data.height, true)
end
local function deleteIdentity(xPlayer)
if not alreadyRegistered[xPlayer.identifier] then
return
end
xPlayer.setName(("%s %s"):format(nil, nil))
xPlayer.set("firstName", nil)
xPlayer.set("lastName", nil)
xPlayer.set("dateofbirth", nil)
xPlayer.set("sex", nil)
xPlayer.set("height", nil)
SetPlayerData(xPlayer, {firstName = nil, lastName = nil, dateOfBirth = nil, sex = nil, height = nil})
deleteIdentityFromDatabase(xPlayer)
end
local function saveIdentityToDatabase(identifier, identity)
MySQL.update.await("UPDATE users SET firstname = ?, lastname = ?, dateofbirth = ?, sex = ?, height = ? WHERE identifier = ?", { identity.firstName, identity.lastName, identity.dateOfBirth, identity.sex, identity.height, identifier })
end
@@ -222,12 +236,8 @@ if Config.UseDeferrals then
end
local currentIdentity = playerIdentity[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)
SetPlayerData(xPlayer, currentIdentity)
if currentIdentity.saveToDatabase then
saveIdentityToDatabase(xPlayer.identifier, currentIdentity)
end
@@ -243,13 +253,8 @@ else
return
end
local currentIdentity = playerIdentity[xPlayer.identifier]
SetPlayerData(xPlayer, currentIdentity)
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)
TriggerClientEvent("esx_identity:setPlayerData", xPlayer.source, currentIdentity)
if currentIdentity.saveToDatabase then
saveIdentityToDatabase(xPlayer.identifier, currentIdentity)
@@ -340,12 +345,8 @@ else
local currentIdentity = playerIdentity[xPlayer.identifier]
if currentIdentity and alreadyRegistered[xPlayer.identifier] then
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)
SetPlayerData(xPlayer, currentIdentity)
TriggerClientEvent("esx_identity:setPlayerData", xPlayer.source, currentIdentity)
if currentIdentity.saveToDatabase then
saveIdentityToDatabase(xPlayer.identifier, currentIdentity)
@@ -400,12 +401,8 @@ else
local currentIdentity = playerIdentity[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)
SetPlayerData(xPlayer, currentIdentity)
TriggerClientEvent("esx_identity:setPlayerData", xPlayer.source, currentIdentity)
saveIdentityToDatabase(xPlayer.identifier, currentIdentity)
alreadyRegistered[xPlayer.identifier] = true
+1 -1
View File
@@ -9,7 +9,7 @@ A default List type menu for ESX.
esx_menu_default - Default Menu!
Copyright (C) 2015-2023 Jérémie N'gadi
Copyright (C) 2015-2024 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.
+1 -1
View File
@@ -12,7 +12,7 @@ start esx_menu_dialog
### License
esx_menu_dialog - input dialog for ESX
Copyright (C) 2015-2024 ESX-Framework
Copyright (C) 2015-2024 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.
+1 -1
View File
@@ -5,7 +5,7 @@ Advanced menu inputs for ESX
### License
esx_menu_list - advanced menu inputs for ESX
Copyright (C) 2015-2024 ESX-Framework
Copyright (C) 2015-2024 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.
+2 -1
View File
@@ -1,6 +1,6 @@
local Debug = ESX.GetConfig().EnableDebug
---@param type string the notification type
---@param notificatonType string the notification type
---@param length number the length of the notification
---@param message any the message :D
local function Notify(notificatonType, length, message)
@@ -36,6 +36,7 @@ RegisterNetEvent("ESX:Notify", Notify)
if Debug then
RegisterCommand("oldnotify", function()
---@diagnostic disable-next-line
ESX.ShowNotification("No Waypoint Set.", true, false, 140)
end)
+1 -1
View File
@@ -60,7 +60,7 @@ notification = (data) => {
const notification = $(`
<div class="notify ${data.type}">
<div class="innerText">
<span class="material-symbols-outlined icon">${types[data.type]["icon"]}</span>
<span class="material-symbols-outlined icon">${types[data.type] ? types[data.type]["icon"] : types["info"]["icon"]}</span>
<p class="text">${data["message"]}</p>
</div>
</div>
+7 -7
View File
@@ -1,7 +1,7 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -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-legacy
Copyright (C) 2015-2024 Jérémie N'gadi
esx_notify
Copyright (C) 2022-2024 ESX Framework
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
@@ -645,14 +645,14 @@ the "copyright" line and a pointer to where the full notice is found.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
along with this program. If not, see <http://www.gnu.org/licenses/>.
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-legacy Copyright (C) 2015-2024 Jérémie N'gadi
esx_notify Copyright (C) 2022-2024 ESX Framework
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.
@@ -664,11 +664,11 @@ 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
<https://www.gnu.org/licenses/>.
<http://www.gnu.org/licenses/>.
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
<https://www.gnu.org/licenses/why-not-lgpl.html>.
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+3 -3
View File
@@ -16,7 +16,7 @@ local function Progressbar(message, length, Options)
end
end
if CurrentProgress.FreezePlayer then
FreezeEntityPosition(PlayerPedId(), CurrentProgress.FreezePlayer)
FreezeEntityPosition(ESX.PlayerData.ped, CurrentProgress.FreezePlayer)
end
SendNUIMessage({
type = "Progressbar",
@@ -30,7 +30,7 @@ local function Progressbar(message, length, Options)
else
ClearPedTasks(ESX.PlayerData.ped)
if CurrentProgress.FreezePlayer then
FreezeEntityPosition(PlayerPedId(), false)
FreezeEntityPosition(ESX.PlayerData.ped, false)
end
if CurrentProgress.onFinish then
CurrentProgress.onFinish()
@@ -50,7 +50,7 @@ local function CancelProgressbar()
})
ClearPedTasks(ESX.PlayerData.ped)
if CurrentProgress.FreezePlayer then
FreezeEntityPosition(PlayerPedId(), false)
FreezeEntityPosition(ESX.PlayerData.ped, false)
end
if CurrentProgress.onCancel then
CurrentProgress.onCancel()
+12
View File
@@ -64,3 +64,15 @@
end
})
```
## Legal
esx_progressbar
Copyright (C) 2022-2024 ESX-Framework
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/>.
+1 -1
View File
@@ -32,7 +32,7 @@ start esx_skin
### License
esx_skin - skin selector for ESX
Copyright (C) 2015-2023 Jérémie N'gadi
Copyright (C) 2015-2024 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.
+1 -1
View File
@@ -73,7 +73,7 @@ end)
skinchanger - Own your skin!
Copyright (C) 2015-2023 Jérémie N'gadi
Copyright (C) 2015-2024 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.
-24
View File
@@ -18,29 +18,5 @@ Interested in helping us? [Take a look at our patreon](https://www.patreon.com/e
| CONGRESS KW - Michael Hein - Smery sitbon - daZepelin - CMF Community |
------
<br>
<table><tr><td><h4 align='center'>Legal Notices</h4></tr></td>
<tr><td>
ESX Core (ESX-legacy)
Copyright (C) 2015-2024 [ESX-Framework](https://github.com/esx-framework)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.
If not, see <https://www.gnu.org/licenses/>
</td></tr></table>
Powered by [Oxygenserv](https://www.oxygenserv.com/en/)