From f254c911281c53972f46fb3b3a04ec268d81db24 Mon Sep 17 00:00:00 2001 From: Kasey FItton Date: Sun, 15 Dec 2024 22:48:53 +0000 Subject: [PATCH 1/4] refactor(es_extended/client): rename common.lua and main.lua --- [core]/es_extended/client/common.lua | 30 -- [core]/es_extended/client/events.lua | 594 ++++++++++++++++++++++++++ [core]/es_extended/client/main.lua | 604 +-------------------------- [core]/es_extended/fxmanifest.lua | 4 +- 4 files changed, 616 insertions(+), 616 deletions(-) delete mode 100644 [core]/es_extended/client/common.lua create mode 100644 [core]/es_extended/client/events.lua diff --git a/[core]/es_extended/client/common.lua b/[core]/es_extended/client/common.lua deleted file mode 100644 index 441af7662..000000000 --- a/[core]/es_extended/client/common.lua +++ /dev/null @@ -1,30 +0,0 @@ -Core = {} -Core.Input = {} -Core.Events = {} - -ESX.PlayerData = {} -ESX.PlayerLoaded = false -ESX.playerId = PlayerId() -ESX.serverId = GetPlayerServerId(ESX.playerId) - -ESX.UI = {} -ESX.UI.Menu = {} -ESX.UI.Menu.RegisteredTypes = {} -ESX.UI.Menu.Opened = {} - -ESX.Game = {} -ESX.Game.Utils = {} - -CreateThread(function() - while not Config.Multichar do - Wait(100) - - if NetworkIsPlayerActive(ESX.playerId) then - ESX.DisableSpawnManager() - DoScreenFadeOut(0) - Wait(500) - TriggerServerEvent("esx:onPlayerJoined") - break - end - end -end) diff --git a/[core]/es_extended/client/events.lua b/[core]/es_extended/client/events.lua new file mode 100644 index 000000000..08d85b78b --- /dev/null +++ b/[core]/es_extended/client/events.lua @@ -0,0 +1,594 @@ +local pickups = {} + +ESX.SecureNetEvent("esx:requestModel", function(model) + ESX.Streaming.RequestModel(model) +end) + +RegisterNetEvent("esx:playerLoaded", function(xPlayer, _, skin) + ESX.PlayerData = xPlayer + + if not Config.Multichar then + ESX.SpawnPlayer(skin, ESX.PlayerData.coords, function() + TriggerEvent("esx:onPlayerSpawn") + TriggerEvent("esx:restoreLoadout") + TriggerServerEvent("esx:onPlayerSpawn") + TriggerEvent("esx:loadingScreenOff") + ShutdownLoadingScreen() + ShutdownLoadingScreenNui() + end) + end + + while not DoesEntityExist(ESX.PlayerData.ped) do + Wait(20) + end + + ESX.PlayerLoaded = true + + local timer = GetGameTimer() + while not HaveAllStreamingRequestsCompleted(ESX.PlayerData.ped) and (GetGameTimer() - timer) < 2000 do + Wait(0) + end + + Adjustments:Load() + + ClearPedTasksImmediately(ESX.PlayerData.ped) + + if not Config.Multichar then + Core.FreezePlayer(false) + end + + if IsScreenFadedOut() then + DoScreenFadeIn(500) + end + + Actions:Init() + StartPointsLoop() + StartServerSyncLoops() + NetworkSetLocalPlayerSyncLookAt(true) +end) + +local isFirstSpawn = true +ESX.SecureNetEvent("esx:onPlayerLogout", function() + ESX.PlayerLoaded = false + isFirstSpawn = true +end) + +ESX.SecureNetEvent("esx:setMaxWeight", function(newMaxWeight) + ESX.SetPlayerData("maxWeight", newMaxWeight) +end) + +local function onPlayerSpawn() + ESX.SetPlayerData("ped", PlayerPedId()) + ESX.SetPlayerData("dead", false) +end + +AddEventHandler("playerSpawned", onPlayerSpawn) +AddEventHandler("esx:onPlayerSpawn", function() + onPlayerSpawn() + + if isFirstSpawn then + isFirstSpawn = false + + if ESX.PlayerData.metadata.health and (ESX.PlayerData.metadata.health > 0 or Config.SaveDeathStatus) then + SetEntityHealth(ESX.PlayerData.ped, ESX.PlayerData.metadata.health) + end + + if ESX.PlayerData.metadata.armor and ESX.PlayerData.metadata.armor > 0 then + SetPedArmour(ESX.PlayerData.ped, ESX.PlayerData.metadata.armor) + end + end +end) + +AddEventHandler("esx:onPlayerDeath", function() + ESX.SetPlayerData("ped", PlayerPedId()) + ESX.SetPlayerData("dead", true) +end) + +AddEventHandler("skinchanger:modelLoaded", function() + while not ESX.PlayerLoaded do + Wait(100) + end + TriggerEvent("esx:restoreLoadout") +end) + +AddEventHandler("esx:restoreLoadout", function() + ESX.SetPlayerData("ped", PlayerPedId()) + + if not Config.CustomInventory then + local ammoTypes = {} + RemoveAllPedWeapons(ESX.PlayerData.ped, true) + + for _, v in ipairs(ESX.PlayerData.loadout) do + local weaponName = v.name + local weaponHash = joaat(weaponName) + + GiveWeaponToPed(ESX.PlayerData.ped, weaponHash, 0, false, false) + SetPedWeaponTintIndex(ESX.PlayerData.ped, weaponHash, v.tintIndex) + + local ammoType = GetPedAmmoTypeFromWeapon(ESX.PlayerData.ped, weaponHash) + + for _, v2 in ipairs(v.components) do + local componentHash = ESX.GetWeaponComponent(weaponName, v2).hash + GiveWeaponComponentToPed(ESX.PlayerData.ped, weaponHash, componentHash) + end + + if not ammoTypes[ammoType] then + AddAmmoToPed(ESX.PlayerData.ped, weaponHash, v.ammo) + ammoTypes[ammoType] = true + end + end + end +end) + +---@diagnostic disable-next-line: param-type-mismatch +AddStateBagChangeHandler("VehicleProperties", nil, function(bagName, _, value) + if not value then + return + end + + bagName = bagName:gsub("entity:", "") + local netId = tonumber(bagName) + if not netId then + error("Tried to set vehicle properties with invalid netId") + return + end + + local vehicle = NetToVeh(netId) + + local tries = 0 + while not NetworkDoesEntityExistWithNetworkId(netId) do + Wait(200) + tries = tries + 1 + if tries > 20 then + return error(("Invalid entity - ^5%s^7!"):format(netId)) + end + end + + if NetworkGetEntityOwner(vehicle) ~= ESX.playerId then + return + end + + ESX.Game.SetVehicleProperties(vehicle, value) +end) + +ESX.SecureNetEvent("esx:setAccountMoney", function(account) + for i = 1, #ESX.PlayerData.accounts do + if ESX.PlayerData.accounts[i].name == account.name then + ESX.PlayerData.accounts[i] = account + break + end + end + + ESX.SetPlayerData("accounts", ESX.PlayerData.accounts) +end) + +if not Config.CustomInventory then + ESX.SecureNetEvent("esx:addInventoryItem", function(item, count, showNotification) + 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 + break + end + end + + if showNotification then + ESX.UI.ShowInventoryItemNotification(true, item, count) + end + end) + + ESX.SecureNetEvent("esx:removeInventoryItem", function(item, count, showNotification) + for i = 1, #ESX.PlayerData.inventory do + if ESX.PlayerData.inventory[i].name == item then + ESX.UI.ShowInventoryItemNotification(false, ESX.PlayerData.inventory[i].label, ESX.PlayerData.inventory[i].count - count) + ESX.PlayerData.inventory[i].count = count + break + end + end + + if showNotification then + ESX.UI.ShowInventoryItemNotification(false, item, count) + end + end) + + RegisterNetEvent("esx:addWeapon", function() + error("event ^5'esx:addWeapon'^1 Has Been Removed. Please use ^5xPlayer.addWeapon^1 Instead!") + end) + + + RegisterNetEvent("esx:addWeaponComponent", function() + error("event ^5'esx:addWeaponComponent'^1 Has Been Removed. Please use ^5xPlayer.addWeaponComponent^1 Instead!") + end) + + RegisterNetEvent("esx:setWeaponAmmo", function() + error("event ^5'esx:setWeaponAmmo'^1 Has Been Removed. Please use ^5xPlayer.addWeaponAmmo^1 Instead!") + end) + + ESX.SecureNetEvent("esx:setWeaponTint", function(weapon, weaponTintIndex) + SetPedWeaponTintIndex(ESX.PlayerData.ped, joaat(weapon), weaponTintIndex) + end) + + RegisterNetEvent("esx:removeWeapon", function() + error("event ^5'esx:removeWeapon'^1 Has Been Removed. Please use ^5xPlayer.removeWeapon^1 Instead!") + end) + + ESX.SecureNetEvent("esx:removeWeaponComponent", function(weapon, weaponComponent) + local componentHash = ESX.GetWeaponComponent(weapon, weaponComponent).hash + RemoveWeaponComponentFromPed(ESX.PlayerData.ped, joaat(weapon), componentHash) + end) +end + +ESX.SecureNetEvent("esx:setJob", function(Job) + ESX.SetPlayerData("job", Job) +end) + +ESX.SecureNetEvent("esx:setGroup", function(group) + ESX.SetPlayerData("group", group) +end) + +if not Config.CustomInventory then + ESX.SecureNetEvent("esx:createPickup", function(pickupId, label, coords, itemType, name, components, tintIndex) + local function setObjectProperties(object) + SetEntityAsMissionEntity(object, true, false) + PlaceObjectOnGroundProperly(object) + FreezeEntityPosition(object, true) + SetEntityCollision(object, false, true) + + pickups[pickupId] = { + obj = object, + label = label, + inRange = false, + coords = coords, + } + end + + if itemType == "item_weapon" then + local weaponHash = joaat(name) + ESX.Streaming.RequestWeaponAsset(weaponHash) + local pickupObject = CreateWeaponObject(weaponHash, 50, coords.x, coords.y, coords.z, true, 1.0, 0) + SetWeaponObjectTintIndex(pickupObject, tintIndex) + + for _, v in ipairs(components) do + local component = ESX.GetWeaponComponent(name, v) + if component then + GiveWeaponComponentToWeaponObject(pickupObject, component.hash) + end + end + + setObjectProperties(pickupObject) + else + ESX.Game.SpawnLocalObject("prop_money_bag_01", coords, setObjectProperties) + end + end) + + ESX.SecureNetEvent("esx:createMissingPickups", function(missingPickups) + for pickupId, pickup in pairs(missingPickups) do + TriggerEvent("esx:createPickup", pickupId, pickup.label, vector3(pickup.coords.x, pickup.coords.y, pickup.coords.z - 1.0), pickup.type, pickup.name, pickup.components, pickup.tintIndex) + end + end) +end + +ESX.SecureNetEvent("esx:registerSuggestions", function(registeredCommands) + for name, command in pairs(registeredCommands) do + if command.suggestion then + TriggerEvent("chat:addSuggestion", ("/%s"):format(name), command.suggestion.help, command.suggestion.arguments) + end + end +end) + +if not Config.CustomInventory then + ESX.SecureNetEvent("esx:removePickup", function(pickupId) + if pickups[pickupId] and pickups[pickupId].obj then + ESX.Game.DeleteObject(pickups[pickupId].obj) + pickups[pickupId] = nil + end + end) +end + +function StartServerSyncLoops() + if Config.CustomInventory then return end + + local currentWeapon = { + ---@type number + ---@diagnostic disable-next-line: assign-type-mismatch + hash = `WEAPON_UNARMED`, + ammo = 0, + } + + local function updateCurrentWeaponAmmo(weaponName) + local newAmmo = GetAmmoInPedWeapon(ESX.PlayerData.ped, currentWeapon.hash) + + if newAmmo ~= currentWeapon.ammo then + currentWeapon.ammo = newAmmo + TriggerServerEvent("esx:updateWeaponAmmo", weaponName, newAmmo) + end + end + + CreateThread(function() + while ESX.PlayerLoaded do + currentWeapon.hash = GetSelectedPedWeapon(ESX.PlayerData.ped) + + if currentWeapon.hash ~= `WEAPON_UNARMED` then + local weaponConfig = ESX.GetWeaponFromHash(currentWeapon.hash) + + if weaponConfig then + currentWeapon.ammo = GetAmmoInPedWeapon(ESX.PlayerData.ped, currentWeapon.hash) + + while GetSelectedPedWeapon(ESX.PlayerData.ped) == currentWeapon.hash do + updateCurrentWeaponAmmo(weaponConfig.name) + Wait(1000) + end + + updateCurrentWeaponAmmo(weaponConfig.name) + end + end + Wait(250) + end + end) + + CreateThread(function() + local PARACHUTE_OPENING = 1 + local PARACHUTE_OPEN = 2 + + while ESX.PlayerLoaded do + local parachuteState = GetPedParachuteState(ESX.PlayerData.ped) + + if parachuteState == PARACHUTE_OPENING or parachuteState == PARACHUTE_OPEN then + TriggerServerEvent("esx:updateWeaponAmmo", "GADGET_PARACHUTE", 0) + + while GetPedParachuteState(ESX.PlayerData.ped) ~= -1 do Wait(1000) end + end + Wait(500) + end + end) +end + +if not Config.CustomInventory and Config.EnableDefaultInventory then + ESX.RegisterInput("showinv", TranslateCap("keymap_showinventory"), "keyboard", "F2", function() + if not ESX.PlayerData.dead then + ESX.ShowInventory() + end + end) +end + +if not Config.CustomInventory then + CreateThread(function() + while true do + local Sleep = 1500 + local playerCoords = GetEntityCoords(ESX.PlayerData.ped) + local _, closestDistance = ESX.Game.GetClosestPlayer(playerCoords) + + for pickupId, pickup in pairs(pickups) do + local distance = #(playerCoords - pickup.coords) + + if distance < 5 then + Sleep = 0 + local label = pickup.label + + if distance < 1 then + if IsControlJustReleased(0, 38) then + if IsPedOnFoot(ESX.PlayerData.ped) and (closestDistance == -1 or closestDistance > 3) and not pickup.inRange then + pickup.inRange = true + + local dict, anim = "weapons@first_person@aim_rng@generic@projectile@sticky_bomb@", "plant_floor" + ESX.Streaming.RequestAnimDict(dict) + TaskPlayAnim(ESX.PlayerData.ped, dict, anim, 8.0, 1.0, 1000, 16, 0.0, false, false, false) + RemoveAnimDict(dict) + Wait(1000) + + TriggerServerEvent("esx:onPickup", pickupId) + PlaySoundFrontend(-1, "PICK_UP", "HUD_FRONTEND_DEFAULT_SOUNDSET", false) + end + end + + label = ("%s~n~%s"):format(label, TranslateCap("threw_pickup_prompt")) + end + + local textCoords = pickup.coords + vector3(0.0, 0.0, 0.25) + ESX.Game.Utils.DrawText3D(textCoords, label, 1.2, 1) + elseif pickup.inRange then + pickup.inRange = false + end + end + Wait(Sleep) + end + end) +end + +----- Admin commands from esx_adminplus +ESX.SecureNetEvent("esx:tpm", function() + local GetEntityCoords = GetEntityCoords + local GetGroundZFor_3dCoord = GetGroundZFor_3dCoord + local GetFirstBlipInfoId = GetFirstBlipInfoId + local DoesBlipExist = DoesBlipExist + local DoScreenFadeOut = DoScreenFadeOut + local GetBlipInfoIdCoord = GetBlipInfoIdCoord + local GetVehiclePedIsIn = GetVehiclePedIsIn + + ESX.TriggerServerCallback("esx:isUserAdmin", function(admin) + if not admin then + return + end + local blipMarker = GetFirstBlipInfoId(8) + if not DoesBlipExist(blipMarker) then + ESX.ShowNotification(TranslateCap("tpm_nowaypoint"), "error") + return "marker" + end + + -- Fade screen to hide how clients get teleported. + DoScreenFadeOut(650) + while not IsScreenFadedOut() do + Wait(0) + end + + local ped, coords = ESX.PlayerData.ped, GetBlipInfoIdCoord(blipMarker) + local vehicle = GetVehiclePedIsIn(ped, false) + local oldCoords = GetEntityCoords(ped) + + -- Unpack coords instead of having to unpack them while iterating. + -- 825.0 seems to be the max a player can reach while 0.0 being the lowest. + local x, y, groundZ, Z_START = coords["x"], coords["y"], 850.0, 950.0 + local found = false + FreezeEntityPosition(vehicle > 0 and vehicle or ped, true) + + for i = Z_START, 0, -25.0 do + local z = i + if (i % 2) ~= 0 then + z = Z_START - i + end + + NewLoadSceneStart(x, y, z, x, y, z, 50.0, 0) + local curTime = GetGameTimer() + while IsNetworkLoadingScene() do + if GetGameTimer() - curTime > 1000 then + break + end + Wait(0) + end + NewLoadSceneStop() + SetPedCoordsKeepVehicle(ped, x, y, z) + + while not HasCollisionLoadedAroundEntity(ped) do + RequestCollisionAtCoord(x, y, z) + if GetGameTimer() - curTime > 1000 then + break + end + Wait(0) + end + + -- Get ground coord. As mentioned in the natives, this only works if the client is in render distance. + found, groundZ = GetGroundZFor_3dCoord(x, y, z, false) + if found then + Wait(0) + SetPedCoordsKeepVehicle(ped, x, y, groundZ) + break + end + Wait(0) + end + + -- Remove black screen once the loop has ended. + DoScreenFadeIn(650) + FreezeEntityPosition(vehicle > 0 and vehicle or ped, false) + + if not found then + -- If we can't find the coords, set the coords to the old ones. + -- We don't unpack them before since they aren't in a loop and only called once. + SetPedCoordsKeepVehicle(ped, oldCoords["x"], oldCoords["y"], oldCoords["z"] - 1.0) + ESX.ShowNotification(TranslateCap("tpm_success"), "success") + end + + -- If Z coord was found, set coords in found coords. + SetPedCoordsKeepVehicle(ped, x, y, groundZ) + ESX.ShowNotification(TranslateCap("tpm_success"), "success") + end) +end) + +local noclip = false +local noclip_pos = vector3(0, 0, 70) +local heading = 0 + +local function noclipThread() + while noclip do + SetEntityCoordsNoOffset(ESX.PlayerData.ped, noclip_pos.x, noclip_pos.y, noclip_pos.z, false, false, true) + + if IsControlPressed(1, 34) then + heading = heading + 1.5 + if heading > 360 then + heading = 0 + end + + SetEntityHeading(ESX.PlayerData.ped, heading) + end + + if IsControlPressed(1, 9) then + heading = heading - 1.5 + if heading < 0 then + heading = 360 + end + + SetEntityHeading(ESX.PlayerData.ped, heading) + end + + if IsControlPressed(1, 8) then + noclip_pos = GetOffsetFromEntityInWorldCoords(ESX.PlayerData.ped, 0.0, 1.0, 0.0) + end + + if IsControlPressed(1, 32) then + noclip_pos = GetOffsetFromEntityInWorldCoords(ESX.PlayerData.ped, 0.0, -1.0, 0.0) + end + + if IsControlPressed(1, 27) then + noclip_pos = GetOffsetFromEntityInWorldCoords(ESX.PlayerData.ped, 0.0, 0.0, 1.0) + end + + if IsControlPressed(1, 173) then + noclip_pos = GetOffsetFromEntityInWorldCoords(ESX.PlayerData.ped, 0.0, 0.0, -1.0) + end + Wait(0) + end +end + +ESX.SecureNetEvent("esx:noclip", function() + ESX.TriggerServerCallback("esx:isUserAdmin", function(admin) + if not admin then + return + end + + if not noclip then + noclip_pos = GetEntityCoords(ESX.PlayerData.ped, false) + heading = GetEntityHeading(ESX.PlayerData.ped) + end + + noclip = not noclip + if noclip then + CreateThread(noclipThread) + end + + if noclip then + ESX.ShowNotification(TranslateCap("noclip_message", Translate("enabled")), "success") + else + ESX.ShowNotification(TranslateCap("noclip_message", Translate("disabled")), "error") + end + end) +end) + +ESX.SecureNetEvent("esx:killPlayer", function() + SetEntityHealth(ESX.PlayerData.ped, 0) +end) + +ESX.SecureNetEvent("esx:repairPedVehicle", function() + local ped = ESX.PlayerData.ped + local vehicle = GetVehiclePedIsIn(ped, false) + SetVehicleEngineHealth(vehicle, 1000) + SetVehicleEngineOn(vehicle, true, true, false) + SetVehicleFixed(vehicle) + SetVehicleDirtLevel(vehicle, 0) +end) + +ESX.SecureNetEvent("esx:freezePlayer", function(input) + if input == "freeze" then + SetEntityCollision(ESX.PlayerData.ped, false, false) + FreezeEntityPosition(ESX.PlayerData.ped, true) + SetPlayerInvincible(ESX.playerId, true) + elseif input == "unfreeze" then + SetEntityCollision(ESX.PlayerData.ped, true, true) + FreezeEntityPosition(ESX.PlayerData.ped, false) + SetPlayerInvincible(ESX.playerId, false) + end +end) + +ESX.RegisterClientCallback("esx:GetVehicleType", function(cb, model) + cb(ESX.GetVehicleTypeClient(model)) +end) + +ESX.SecureNetEvent('esx:updatePlayerData', function(key, val) + ESX.SetPlayerData(key, val) +end) + +AddEventHandler("onResourceStop", function(resource) + if Core.Events[resource] then + for i = 1, #Core.Events[resource] do + RemoveEventHandler(Core.Events[resource][i]) + end + end +end) diff --git a/[core]/es_extended/client/main.lua b/[core]/es_extended/client/main.lua index 08d85b78b..441af7662 100644 --- a/[core]/es_extended/client/main.lua +++ b/[core]/es_extended/client/main.lua @@ -1,594 +1,30 @@ -local pickups = {} +Core = {} +Core.Input = {} +Core.Events = {} -ESX.SecureNetEvent("esx:requestModel", function(model) - ESX.Streaming.RequestModel(model) -end) - -RegisterNetEvent("esx:playerLoaded", function(xPlayer, _, skin) - ESX.PlayerData = xPlayer - - if not Config.Multichar then - ESX.SpawnPlayer(skin, ESX.PlayerData.coords, function() - TriggerEvent("esx:onPlayerSpawn") - TriggerEvent("esx:restoreLoadout") - TriggerServerEvent("esx:onPlayerSpawn") - TriggerEvent("esx:loadingScreenOff") - ShutdownLoadingScreen() - ShutdownLoadingScreenNui() - end) - end - - while not DoesEntityExist(ESX.PlayerData.ped) do - Wait(20) - end +ESX.PlayerData = {} +ESX.PlayerLoaded = false +ESX.playerId = PlayerId() +ESX.serverId = GetPlayerServerId(ESX.playerId) - ESX.PlayerLoaded = true +ESX.UI = {} +ESX.UI.Menu = {} +ESX.UI.Menu.RegisteredTypes = {} +ESX.UI.Menu.Opened = {} - local timer = GetGameTimer() - while not HaveAllStreamingRequestsCompleted(ESX.PlayerData.ped) and (GetGameTimer() - timer) < 2000 do - Wait(0) - end - - Adjustments:Load() - - ClearPedTasksImmediately(ESX.PlayerData.ped) +ESX.Game = {} +ESX.Game.Utils = {} - if not Config.Multichar then - Core.FreezePlayer(false) - end - - if IsScreenFadedOut() then - DoScreenFadeIn(500) - end - - Actions:Init() - StartPointsLoop() - StartServerSyncLoops() - NetworkSetLocalPlayerSyncLookAt(true) -end) - -local isFirstSpawn = true -ESX.SecureNetEvent("esx:onPlayerLogout", function() - ESX.PlayerLoaded = false - isFirstSpawn = true -end) - -ESX.SecureNetEvent("esx:setMaxWeight", function(newMaxWeight) - ESX.SetPlayerData("maxWeight", newMaxWeight) -end) - -local function onPlayerSpawn() - ESX.SetPlayerData("ped", PlayerPedId()) - ESX.SetPlayerData("dead", false) -end - -AddEventHandler("playerSpawned", onPlayerSpawn) -AddEventHandler("esx:onPlayerSpawn", function() - onPlayerSpawn() - - if isFirstSpawn then - isFirstSpawn = false - - if ESX.PlayerData.metadata.health and (ESX.PlayerData.metadata.health > 0 or Config.SaveDeathStatus) then - SetEntityHealth(ESX.PlayerData.ped, ESX.PlayerData.metadata.health) - end - - if ESX.PlayerData.metadata.armor and ESX.PlayerData.metadata.armor > 0 then - SetPedArmour(ESX.PlayerData.ped, ESX.PlayerData.metadata.armor) - end - end -end) - -AddEventHandler("esx:onPlayerDeath", function() - ESX.SetPlayerData("ped", PlayerPedId()) - ESX.SetPlayerData("dead", true) -end) - -AddEventHandler("skinchanger:modelLoaded", function() - while not ESX.PlayerLoaded do +CreateThread(function() + while not Config.Multichar do Wait(100) - end - TriggerEvent("esx:restoreLoadout") -end) - -AddEventHandler("esx:restoreLoadout", function() - ESX.SetPlayerData("ped", PlayerPedId()) - - if not Config.CustomInventory then - local ammoTypes = {} - RemoveAllPedWeapons(ESX.PlayerData.ped, true) - - for _, v in ipairs(ESX.PlayerData.loadout) do - local weaponName = v.name - local weaponHash = joaat(weaponName) - - GiveWeaponToPed(ESX.PlayerData.ped, weaponHash, 0, false, false) - SetPedWeaponTintIndex(ESX.PlayerData.ped, weaponHash, v.tintIndex) - - local ammoType = GetPedAmmoTypeFromWeapon(ESX.PlayerData.ped, weaponHash) - - for _, v2 in ipairs(v.components) do - local componentHash = ESX.GetWeaponComponent(weaponName, v2).hash - GiveWeaponComponentToPed(ESX.PlayerData.ped, weaponHash, componentHash) - end - - if not ammoTypes[ammoType] then - AddAmmoToPed(ESX.PlayerData.ped, weaponHash, v.ammo) - ammoTypes[ammoType] = true - end - end - end -end) - ----@diagnostic disable-next-line: param-type-mismatch -AddStateBagChangeHandler("VehicleProperties", nil, function(bagName, _, value) - if not value then - return - end - - bagName = bagName:gsub("entity:", "") - local netId = tonumber(bagName) - if not netId then - error("Tried to set vehicle properties with invalid netId") - return - end - - local vehicle = NetToVeh(netId) - - local tries = 0 - while not NetworkDoesEntityExistWithNetworkId(netId) do - Wait(200) - tries = tries + 1 - if tries > 20 then - return error(("Invalid entity - ^5%s^7!"):format(netId)) - end - end - - if NetworkGetEntityOwner(vehicle) ~= ESX.playerId then - return - end - - ESX.Game.SetVehicleProperties(vehicle, value) -end) - -ESX.SecureNetEvent("esx:setAccountMoney", function(account) - for i = 1, #ESX.PlayerData.accounts do - if ESX.PlayerData.accounts[i].name == account.name then - ESX.PlayerData.accounts[i] = account - break - end - end - - ESX.SetPlayerData("accounts", ESX.PlayerData.accounts) -end) - -if not Config.CustomInventory then - ESX.SecureNetEvent("esx:addInventoryItem", function(item, count, showNotification) - 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 - break - end - end - - if showNotification then - ESX.UI.ShowInventoryItemNotification(true, item, count) - end - end) - - ESX.SecureNetEvent("esx:removeInventoryItem", function(item, count, showNotification) - for i = 1, #ESX.PlayerData.inventory do - if ESX.PlayerData.inventory[i].name == item then - ESX.UI.ShowInventoryItemNotification(false, ESX.PlayerData.inventory[i].label, ESX.PlayerData.inventory[i].count - count) - ESX.PlayerData.inventory[i].count = count - break - end - end - - if showNotification then - ESX.UI.ShowInventoryItemNotification(false, item, count) - end - end) - - RegisterNetEvent("esx:addWeapon", function() - error("event ^5'esx:addWeapon'^1 Has Been Removed. Please use ^5xPlayer.addWeapon^1 Instead!") - end) - - - RegisterNetEvent("esx:addWeaponComponent", function() - error("event ^5'esx:addWeaponComponent'^1 Has Been Removed. Please use ^5xPlayer.addWeaponComponent^1 Instead!") - end) - - RegisterNetEvent("esx:setWeaponAmmo", function() - error("event ^5'esx:setWeaponAmmo'^1 Has Been Removed. Please use ^5xPlayer.addWeaponAmmo^1 Instead!") - end) - - ESX.SecureNetEvent("esx:setWeaponTint", function(weapon, weaponTintIndex) - SetPedWeaponTintIndex(ESX.PlayerData.ped, joaat(weapon), weaponTintIndex) - end) - - RegisterNetEvent("esx:removeWeapon", function() - error("event ^5'esx:removeWeapon'^1 Has Been Removed. Please use ^5xPlayer.removeWeapon^1 Instead!") - end) - - ESX.SecureNetEvent("esx:removeWeaponComponent", function(weapon, weaponComponent) - local componentHash = ESX.GetWeaponComponent(weapon, weaponComponent).hash - RemoveWeaponComponentFromPed(ESX.PlayerData.ped, joaat(weapon), componentHash) - end) -end - -ESX.SecureNetEvent("esx:setJob", function(Job) - ESX.SetPlayerData("job", Job) -end) - -ESX.SecureNetEvent("esx:setGroup", function(group) - ESX.SetPlayerData("group", group) -end) - -if not Config.CustomInventory then - ESX.SecureNetEvent("esx:createPickup", function(pickupId, label, coords, itemType, name, components, tintIndex) - local function setObjectProperties(object) - SetEntityAsMissionEntity(object, true, false) - PlaceObjectOnGroundProperly(object) - FreezeEntityPosition(object, true) - SetEntityCollision(object, false, true) - - pickups[pickupId] = { - obj = object, - label = label, - inRange = false, - coords = coords, - } - end - - if itemType == "item_weapon" then - local weaponHash = joaat(name) - ESX.Streaming.RequestWeaponAsset(weaponHash) - local pickupObject = CreateWeaponObject(weaponHash, 50, coords.x, coords.y, coords.z, true, 1.0, 0) - SetWeaponObjectTintIndex(pickupObject, tintIndex) - - for _, v in ipairs(components) do - local component = ESX.GetWeaponComponent(name, v) - if component then - GiveWeaponComponentToWeaponObject(pickupObject, component.hash) - end - end - - setObjectProperties(pickupObject) - else - ESX.Game.SpawnLocalObject("prop_money_bag_01", coords, setObjectProperties) - end - end) - - ESX.SecureNetEvent("esx:createMissingPickups", function(missingPickups) - for pickupId, pickup in pairs(missingPickups) do - TriggerEvent("esx:createPickup", pickupId, pickup.label, vector3(pickup.coords.x, pickup.coords.y, pickup.coords.z - 1.0), pickup.type, pickup.name, pickup.components, pickup.tintIndex) - end - end) -end - -ESX.SecureNetEvent("esx:registerSuggestions", function(registeredCommands) - for name, command in pairs(registeredCommands) do - if command.suggestion then - TriggerEvent("chat:addSuggestion", ("/%s"):format(name), command.suggestion.help, command.suggestion.arguments) - end - end -end) - -if not Config.CustomInventory then - ESX.SecureNetEvent("esx:removePickup", function(pickupId) - if pickups[pickupId] and pickups[pickupId].obj then - ESX.Game.DeleteObject(pickups[pickupId].obj) - pickups[pickupId] = nil - end - end) -end - -function StartServerSyncLoops() - if Config.CustomInventory then return end - - local currentWeapon = { - ---@type number - ---@diagnostic disable-next-line: assign-type-mismatch - hash = `WEAPON_UNARMED`, - ammo = 0, - } - - local function updateCurrentWeaponAmmo(weaponName) - local newAmmo = GetAmmoInPedWeapon(ESX.PlayerData.ped, currentWeapon.hash) - - if newAmmo ~= currentWeapon.ammo then - currentWeapon.ammo = newAmmo - TriggerServerEvent("esx:updateWeaponAmmo", weaponName, newAmmo) - end - end - - CreateThread(function() - while ESX.PlayerLoaded do - currentWeapon.hash = GetSelectedPedWeapon(ESX.PlayerData.ped) - if currentWeapon.hash ~= `WEAPON_UNARMED` then - local weaponConfig = ESX.GetWeaponFromHash(currentWeapon.hash) - - if weaponConfig then - currentWeapon.ammo = GetAmmoInPedWeapon(ESX.PlayerData.ped, currentWeapon.hash) - - while GetSelectedPedWeapon(ESX.PlayerData.ped) == currentWeapon.hash do - updateCurrentWeaponAmmo(weaponConfig.name) - Wait(1000) - end - - updateCurrentWeaponAmmo(weaponConfig.name) - end - end - Wait(250) - end - end) - - CreateThread(function() - local PARACHUTE_OPENING = 1 - local PARACHUTE_OPEN = 2 - - while ESX.PlayerLoaded do - local parachuteState = GetPedParachuteState(ESX.PlayerData.ped) - - if parachuteState == PARACHUTE_OPENING or parachuteState == PARACHUTE_OPEN then - TriggerServerEvent("esx:updateWeaponAmmo", "GADGET_PARACHUTE", 0) - - while GetPedParachuteState(ESX.PlayerData.ped) ~= -1 do Wait(1000) end - end + if NetworkIsPlayerActive(ESX.playerId) then + ESX.DisableSpawnManager() + DoScreenFadeOut(0) Wait(500) - end - end) -end - -if not Config.CustomInventory and Config.EnableDefaultInventory then - ESX.RegisterInput("showinv", TranslateCap("keymap_showinventory"), "keyboard", "F2", function() - if not ESX.PlayerData.dead then - ESX.ShowInventory() - end - end) -end - -if not Config.CustomInventory then - CreateThread(function() - while true do - local Sleep = 1500 - local playerCoords = GetEntityCoords(ESX.PlayerData.ped) - local _, closestDistance = ESX.Game.GetClosestPlayer(playerCoords) - - for pickupId, pickup in pairs(pickups) do - local distance = #(playerCoords - pickup.coords) - - if distance < 5 then - Sleep = 0 - local label = pickup.label - - if distance < 1 then - if IsControlJustReleased(0, 38) then - if IsPedOnFoot(ESX.PlayerData.ped) and (closestDistance == -1 or closestDistance > 3) and not pickup.inRange then - pickup.inRange = true - - local dict, anim = "weapons@first_person@aim_rng@generic@projectile@sticky_bomb@", "plant_floor" - ESX.Streaming.RequestAnimDict(dict) - TaskPlayAnim(ESX.PlayerData.ped, dict, anim, 8.0, 1.0, 1000, 16, 0.0, false, false, false) - RemoveAnimDict(dict) - Wait(1000) - - TriggerServerEvent("esx:onPickup", pickupId) - PlaySoundFrontend(-1, "PICK_UP", "HUD_FRONTEND_DEFAULT_SOUNDSET", false) - end - end - - label = ("%s~n~%s"):format(label, TranslateCap("threw_pickup_prompt")) - end - - local textCoords = pickup.coords + vector3(0.0, 0.0, 0.25) - ESX.Game.Utils.DrawText3D(textCoords, label, 1.2, 1) - elseif pickup.inRange then - pickup.inRange = false - end - end - Wait(Sleep) - end - end) -end - ------ Admin commands from esx_adminplus -ESX.SecureNetEvent("esx:tpm", function() - local GetEntityCoords = GetEntityCoords - local GetGroundZFor_3dCoord = GetGroundZFor_3dCoord - local GetFirstBlipInfoId = GetFirstBlipInfoId - local DoesBlipExist = DoesBlipExist - local DoScreenFadeOut = DoScreenFadeOut - local GetBlipInfoIdCoord = GetBlipInfoIdCoord - local GetVehiclePedIsIn = GetVehiclePedIsIn - - ESX.TriggerServerCallback("esx:isUserAdmin", function(admin) - if not admin then - return - end - local blipMarker = GetFirstBlipInfoId(8) - if not DoesBlipExist(blipMarker) then - ESX.ShowNotification(TranslateCap("tpm_nowaypoint"), "error") - return "marker" - end - - -- Fade screen to hide how clients get teleported. - DoScreenFadeOut(650) - while not IsScreenFadedOut() do - Wait(0) - end - - local ped, coords = ESX.PlayerData.ped, GetBlipInfoIdCoord(blipMarker) - local vehicle = GetVehiclePedIsIn(ped, false) - local oldCoords = GetEntityCoords(ped) - - -- Unpack coords instead of having to unpack them while iterating. - -- 825.0 seems to be the max a player can reach while 0.0 being the lowest. - local x, y, groundZ, Z_START = coords["x"], coords["y"], 850.0, 950.0 - local found = false - FreezeEntityPosition(vehicle > 0 and vehicle or ped, true) - - for i = Z_START, 0, -25.0 do - local z = i - if (i % 2) ~= 0 then - z = Z_START - i - end - - NewLoadSceneStart(x, y, z, x, y, z, 50.0, 0) - local curTime = GetGameTimer() - while IsNetworkLoadingScene() do - if GetGameTimer() - curTime > 1000 then - break - end - Wait(0) - end - NewLoadSceneStop() - SetPedCoordsKeepVehicle(ped, x, y, z) - - while not HasCollisionLoadedAroundEntity(ped) do - RequestCollisionAtCoord(x, y, z) - if GetGameTimer() - curTime > 1000 then - break - end - Wait(0) - end - - -- Get ground coord. As mentioned in the natives, this only works if the client is in render distance. - found, groundZ = GetGroundZFor_3dCoord(x, y, z, false) - if found then - Wait(0) - SetPedCoordsKeepVehicle(ped, x, y, groundZ) - break - end - Wait(0) - end - - -- Remove black screen once the loop has ended. - DoScreenFadeIn(650) - FreezeEntityPosition(vehicle > 0 and vehicle or ped, false) - - if not found then - -- If we can't find the coords, set the coords to the old ones. - -- We don't unpack them before since they aren't in a loop and only called once. - SetPedCoordsKeepVehicle(ped, oldCoords["x"], oldCoords["y"], oldCoords["z"] - 1.0) - ESX.ShowNotification(TranslateCap("tpm_success"), "success") - end - - -- If Z coord was found, set coords in found coords. - SetPedCoordsKeepVehicle(ped, x, y, groundZ) - ESX.ShowNotification(TranslateCap("tpm_success"), "success") - end) -end) - -local noclip = false -local noclip_pos = vector3(0, 0, 70) -local heading = 0 - -local function noclipThread() - while noclip do - SetEntityCoordsNoOffset(ESX.PlayerData.ped, noclip_pos.x, noclip_pos.y, noclip_pos.z, false, false, true) - - if IsControlPressed(1, 34) then - heading = heading + 1.5 - if heading > 360 then - heading = 0 - end - - SetEntityHeading(ESX.PlayerData.ped, heading) - end - - if IsControlPressed(1, 9) then - heading = heading - 1.5 - if heading < 0 then - heading = 360 - end - - SetEntityHeading(ESX.PlayerData.ped, heading) - end - - if IsControlPressed(1, 8) then - noclip_pos = GetOffsetFromEntityInWorldCoords(ESX.PlayerData.ped, 0.0, 1.0, 0.0) - end - - if IsControlPressed(1, 32) then - noclip_pos = GetOffsetFromEntityInWorldCoords(ESX.PlayerData.ped, 0.0, -1.0, 0.0) - end - - if IsControlPressed(1, 27) then - noclip_pos = GetOffsetFromEntityInWorldCoords(ESX.PlayerData.ped, 0.0, 0.0, 1.0) - end - - if IsControlPressed(1, 173) then - noclip_pos = GetOffsetFromEntityInWorldCoords(ESX.PlayerData.ped, 0.0, 0.0, -1.0) - end - Wait(0) - end -end - -ESX.SecureNetEvent("esx:noclip", function() - ESX.TriggerServerCallback("esx:isUserAdmin", function(admin) - if not admin then - return - end - - if not noclip then - noclip_pos = GetEntityCoords(ESX.PlayerData.ped, false) - heading = GetEntityHeading(ESX.PlayerData.ped) - end - - noclip = not noclip - if noclip then - CreateThread(noclipThread) - end - - if noclip then - ESX.ShowNotification(TranslateCap("noclip_message", Translate("enabled")), "success") - else - ESX.ShowNotification(TranslateCap("noclip_message", Translate("disabled")), "error") - end - end) -end) - -ESX.SecureNetEvent("esx:killPlayer", function() - SetEntityHealth(ESX.PlayerData.ped, 0) -end) - -ESX.SecureNetEvent("esx:repairPedVehicle", function() - local ped = ESX.PlayerData.ped - local vehicle = GetVehiclePedIsIn(ped, false) - SetVehicleEngineHealth(vehicle, 1000) - SetVehicleEngineOn(vehicle, true, true, false) - SetVehicleFixed(vehicle) - SetVehicleDirtLevel(vehicle, 0) -end) - -ESX.SecureNetEvent("esx:freezePlayer", function(input) - if input == "freeze" then - SetEntityCollision(ESX.PlayerData.ped, false, false) - FreezeEntityPosition(ESX.PlayerData.ped, true) - SetPlayerInvincible(ESX.playerId, true) - elseif input == "unfreeze" then - SetEntityCollision(ESX.PlayerData.ped, true, true) - FreezeEntityPosition(ESX.PlayerData.ped, false) - SetPlayerInvincible(ESX.playerId, false) - end -end) - -ESX.RegisterClientCallback("esx:GetVehicleType", function(cb, model) - cb(ESX.GetVehicleTypeClient(model)) -end) - -ESX.SecureNetEvent('esx:updatePlayerData', function(key, val) - ESX.SetPlayerData(key, val) -end) - -AddEventHandler("onResourceStop", function(resource) - if Core.Events[resource] then - for i = 1, #Core.Events[resource] do - RemoveEventHandler(Core.Events[resource][i]) + TriggerServerEvent("esx:onPlayerJoined") + break end end end) diff --git a/[core]/es_extended/fxmanifest.lua b/[core]/es_extended/fxmanifest.lua index 848289bf8..1e51f401b 100644 --- a/[core]/es_extended/fxmanifest.lua +++ b/[core]/es_extended/fxmanifest.lua @@ -40,14 +40,14 @@ server_scripts { } client_scripts { - 'client/common.lua', + 'client/main.lua', 'client/functions.lua', 'client/modules/wrapper.lua', 'client/modules/callback.lua', 'client/modules/adjustments.lua', 'client/modules/points.lua', - 'client/main.lua', + 'client/events.lua', 'client/modules/actions.lua', 'client/modules/death.lua', From c00a9b6ab7985ce17f00f65e3f9e3e297232e8fb Mon Sep 17 00:00:00 2001 From: Kasey FItton Date: Sun, 15 Dec 2024 22:50:31 +0000 Subject: [PATCH 2/4] refactor(es_extended/client): move events.lua to modules --- [core]/es_extended/client/{ => modules}/events.lua | 0 [core]/es_extended/fxmanifest.lua | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename [core]/es_extended/client/{ => modules}/events.lua (100%) diff --git a/[core]/es_extended/client/events.lua b/[core]/es_extended/client/modules/events.lua similarity index 100% rename from [core]/es_extended/client/events.lua rename to [core]/es_extended/client/modules/events.lua diff --git a/[core]/es_extended/fxmanifest.lua b/[core]/es_extended/fxmanifest.lua index 1e51f401b..b6726c248 100644 --- a/[core]/es_extended/fxmanifest.lua +++ b/[core]/es_extended/fxmanifest.lua @@ -47,7 +47,7 @@ client_scripts { 'client/modules/adjustments.lua', 'client/modules/points.lua', - 'client/events.lua', + 'client/modules/events.lua', 'client/modules/actions.lua', 'client/modules/death.lua', From 10ee1b9ac1f069a1a3ef4be0c539113d87f4fa40 Mon Sep 17 00:00:00 2001 From: Kasey FItton Date: Sun, 15 Dec 2024 22:55:21 +0000 Subject: [PATCH 3/4] refactor(es_extended): move core definition into shared --- [core]/es_extended/client/main.lua | 1 - [core]/es_extended/server/common.lua | 1 - [core]/es_extended/shared/main.lua | 5 +++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/[core]/es_extended/client/main.lua b/[core]/es_extended/client/main.lua index 441af7662..33677a740 100644 --- a/[core]/es_extended/client/main.lua +++ b/[core]/es_extended/client/main.lua @@ -1,4 +1,3 @@ -Core = {} Core.Input = {} Core.Events = {} diff --git a/[core]/es_extended/server/common.lua b/[core]/es_extended/server/common.lua index edbc39529..cbc921b79 100644 --- a/[core]/es_extended/server/common.lua +++ b/[core]/es_extended/server/common.lua @@ -2,7 +2,6 @@ ESX.Players = {} ESX.Jobs = {} ESX.JobsPlayerCount = {} ESX.Items = {} -Core = {} Core.UsableItemsCallbacks = {} Core.RegisteredCommands = {} Core.Pickups = {} diff --git a/[core]/es_extended/shared/main.lua b/[core]/es_extended/shared/main.lua index 00f775b46..b88f8afc4 100644 --- a/[core]/es_extended/shared/main.lua +++ b/[core]/es_extended/shared/main.lua @@ -1,4 +1,5 @@ ESX = {} +Core = {} exports("getSharedObject", function() return ESX @@ -12,5 +13,5 @@ AddEventHandler("esx:getSharedObject", function(cb) print(("^3[WARNING]^0 Resource ^5%s^0 used the ^5getSharedObject^0 event. This is not the recommended way to import ESX. Visit https://documentation.esx-framework.org/tutorials/tutorials-esx/sharedevent to find out why."):format(invokingResource)) end) --- backwards compatibility (DO NOT TOUCH !) -Config.OxInventory = Config.CustomInventory == "ox" \ No newline at end of file +-- backwards compatibility (DO NOT TOUCH !) +Config.OxInventory = Config.CustomInventory == "ox" From a1d99786dba7a2fc6bde63e0b86a98fa39c88da7 Mon Sep 17 00:00:00 2001 From: Kasey FItton Date: Sun, 15 Dec 2024 22:56:48 +0000 Subject: [PATCH 4/4] refactor(es_extended/client): move core tables to their respective modules --- [core]/es_extended/client/main.lua | 3 --- [core]/es_extended/client/modules/events.lua | 2 ++ [core]/es_extended/client/modules/interactions.lua | 4 +++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/[core]/es_extended/client/main.lua b/[core]/es_extended/client/main.lua index 33677a740..d46cc3ce0 100644 --- a/[core]/es_extended/client/main.lua +++ b/[core]/es_extended/client/main.lua @@ -1,6 +1,3 @@ -Core.Input = {} -Core.Events = {} - ESX.PlayerData = {} ESX.PlayerLoaded = false ESX.playerId = PlayerId() diff --git a/[core]/es_extended/client/modules/events.lua b/[core]/es_extended/client/modules/events.lua index 08d85b78b..68907d95d 100644 --- a/[core]/es_extended/client/modules/events.lua +++ b/[core]/es_extended/client/modules/events.lua @@ -1,3 +1,5 @@ +Core.Events = {} + local pickups = {} ESX.SecureNetEvent("esx:requestModel", function(model) diff --git a/[core]/es_extended/client/modules/interactions.lua b/[core]/es_extended/client/modules/interactions.lua index 0a1a31fe2..08bb437d9 100644 --- a/[core]/es_extended/client/modules/interactions.lua +++ b/[core]/es_extended/client/modules/interactions.lua @@ -1,3 +1,5 @@ +Core.Input = {} + local interactions = {} local pressedInteractions = {} @@ -35,4 +37,4 @@ AddEventHandler("onResourceStop", function(resource) interactions[name] = nil end end -end) \ No newline at end of file +end)