diff --git a/server-data/resources/[esx]/es_extended/client/functions.lua b/server-data/resources/[esx]/es_extended/client/functions.lua index 6a055277c..ac5482076 100644 --- a/server-data/resources/[esx]/es_extended/client/functions.lua +++ b/server-data/resources/[esx]/es_extended/client/functions.lua @@ -24,38 +24,19 @@ 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) - local item - if type(items) == "string" then - item, items = items, { items } - end + items = type(items) == "string" and { items } or items local data = {} - 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 + 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] end end - if #items == 0 then - break - end end - return not item and data or data[item] + return #items == 1 and data[items[1]] or data end function ESX.SetPlayerData(key, val) @@ -68,30 +49,49 @@ function ESX.SetPlayerData(key, val) end end -function ESX.Progressbar(...) - return IsResourceFound("esx_progressbar") and exports["esx_progressbar"]:Progressbar(...) +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!") end function ESX.ShowNotification(message, notifyType, length) - return IsResourceFound("esx_notify") and exports["esx_notify"]:Notify(notifyType, length, message) + if GetResourceState("esx_notify") ~= "missing" then + return exports["esx_notify"]:Notify(notifyType, length, message) + end + + print("[^1ERROR^7] ^5ESX Notify^7 is Missing!") end -function ESX.TextUI(...) - return IsResourceFound("esx_textui") and exports["esx_textui"]:TextUI(...) +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!") end function ESX.HideUI() - return IsResourceFound("esx_textui") and exports["esx_textui"]:HideUI() + if GetResourceState("esx_textui") ~= "missing" then + return exports["esx_textui"]:HideUI() + end + + print("[^1ERROR^7] ^5ESX TextUI^7 is Missing!") 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, saveToBrief == nil or saveToBrief) + EndTextCommandThefeedPostTicker(flash or false, saveToBrief) end function ESX.ShowHelpNotification(msg, thisFrame, beep, duration) @@ -100,8 +100,11 @@ function ESX.ShowHelpNotification(msg, thisFrame, beep, duration) if thisFrame then DisplayHelpTextThisFrame("esxHelpNotification", false) else + if beep == nil then + beep = true + end BeginTextCommandDisplayHelp("esxHelpNotification") - EndTextCommandDisplayHelp(0, false, beep == nil or beep, duration or -1) + EndTextCommandDisplayHelp(0, false, beep, duration or -1) end end @@ -113,40 +116,42 @@ function ESX.ShowFloatingHelpNotification(msg, coords) EndTextCommandDisplayHelp(2, false, false, -1) end -function ESX.DrawMissionText(msg, time) - ClearPrints() - BeginTextCommandPrint("STRING") - AddTextComponentSubstringPlayerName(msg) - EndTextCommandPrint(time, true) -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", "") -function ESX.HashString(str) - return ("~INPUT_%s~"):format(("%x"):format(joaat(str)):upper()) + return input_map end +local contextAvailable = GetResourceState("esx_context") ~= "missing" + function ESX.OpenContext(...) - return IsResourceFound("esx_context") and exports["esx_context"]:Open(...) + 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!") end function ESX.PreviewContext(...) - return IsResourceFound("esx_context") and exports["esx_context"]:Preview(...) + 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!") end function ESX.CloseContext(...) - return IsResourceFound("esx_context") and exports["esx_context"]:Close(...) + 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!") end function ESX.RefreshContext(...) - return IsResourceFound("esx_context") and exports["esx_context"]:Refresh(...) + 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!") end -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) +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) if on_release then RegisterCommand("-" .. command_name, on_release) end - RegisterKeyMapping("+" .. command_name, label or "", input_group or "keyboard", key or "") + RegisterKeyMapping(on_release ~= nil and "+" .. command_name or command_name, label, input_group, key) end function ESX.UI.Menu.RegisterType(menuType, open, close) @@ -271,7 +276,9 @@ function ESX.UI.Menu.GetOpenedMenus() return ESX.UI.Menu.Opened end -ESX.UI.Menu.IsOpen = ESX.UI.Menu.GetOpened +function ESX.UI.Menu.IsOpen(menuType, namespace, name) + return ESX.UI.Menu.GetOpened(menuType, namespace, name) ~= nil +end function ESX.UI.ShowInventoryItemNotification(add, item, count) SendNUIMessage({ @@ -314,8 +321,18 @@ function ESX.Game.Teleport(entity, coords, cb) end function ESX.Game.SpawnObject(object, coords, cb, networked) - 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 + 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) end function ESX.Game.SpawnLocalObject(object, coords, cb) @@ -379,7 +396,10 @@ function ESX.Game.SpawnLocalVehicle(vehicle, coords, heading, cb) end function ESX.Game.IsVehicleEmpty(vehicle) - return GetVehicleNumberOfPassengers(vehicle) == 0 and IsVehicleSeatFree(vehicle, -1) + local passengers = GetVehicleNumberOfPassengers(vehicle) + local driverSeatFree = IsVehicleSeatFree(vehicle, -1) + + return passengers == 0 and driverSeatFree end function ESX.Game.GetObjects() -- Leave the function for compatibility @@ -475,20 +495,6 @@ 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(0.5, 0.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 @@ -521,10 +527,18 @@ function ESX.Game.GetClosestEntity(entities, isPlayerEntities, coords, modelFilt end function ESX.Game.GetVehicleInDirection() - local _, hit, coords, _, _, entity = ESX.Game.RaycastScreen(5, 10, ESX.PlayerData.ped) - if hit and IsEntityAVehicle(entity) then - return entity, coords + 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 end + + return nil end function ESX.Game.GetVehicleProperties(vehicle) @@ -563,19 +577,10 @@ function ESX.Game.GetVehicleProperties(vehicle) local doorsBroken, windowsBroken, tyreBurst = {}, {}, {} - local numWheels = tostring(GetVehicleNumberOfWheels(vehicle)) + local wheel_count = 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. - } - - if TyresIndex[numWheels] then - for _, idx in pairs(TyresIndex[numWheels]) do - tyreBurst[tostring(idx)] = IsVehicleTyreBurst(vehicle, idx, false) - end + for wheel_index = 0, wheel_count - 1 do + tyreBurst[tostring(wheel_index)] = IsVehicleTyreBurst(vehicle, wheel_index, false) end for windowId = 0, 7 do -- 13 @@ -1249,11 +1254,20 @@ function ESX.ShowInventory() end) end -RegisterNetEvent("esx:showNotification", ESX.ShowNotification) +RegisterNetEvent("esx:showNotification") +AddEventHandler("esx:showNotification", function(msg, notifyType, length) + ESX.ShowNotification(msg, notifyType, length) +end) -RegisterNetEvent("esx:showAdvancedNotification", ESX.ShowAdvancedNotification) +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:showHelpNotification", ESX.ShowHelpNotification) +RegisterNetEvent("esx:showHelpNotification") +AddEventHandler("esx:showHelpNotification", function(msg, thisFrame, beep, duration) + ESX.ShowHelpNotification(msg, thisFrame, beep, duration) +end) AddEventHandler("onResourceStop", function(resourceName) for i = 1, #ESX.UI.Menu.Opened, 1 do diff --git a/server-data/resources/[esx]/es_extended/client/main.lua b/server-data/resources/[esx]/es_extended/client/main.lua index 001b068ba..bbfde96c0 100644 --- a/server-data/resources/[esx]/es_extended/client/main.lua +++ b/server-data/resources/[esx]/es_extended/client/main.lua @@ -25,19 +25,14 @@ 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) and (GetGameTimer() - timer) < 5000 do + while not HasCollisionLoadedAroundEntity(playerPed) do Wait(0) end - + FreezeEntityPosition(playerPed, false) NetworkResurrectLocalPlayer(coords.x, coords.y, coords.z, coords.heading, true, true, false) TriggerEvent("playerSpawned", coords) cb() @@ -145,7 +140,6 @@ AddEventHandler("esx:playerLoaded", function(xPlayer, _, skin) for i = 1, 15 do EnableDispatchService(i, false) end - SetAudioFlag("PoliceScannerDisabled", true) end -- Disable Scenarios @@ -209,10 +203,6 @@ 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 diff --git a/server-data/resources/[esx]/es_extended/client/modules/actions.lua b/server-data/resources/[esx]/es_extended/client/modules/actions.lua index ec0f06d31..f762e0c84 100644 --- a/server-data/resources/[esx]/es_extended/client/modules/actions.lua +++ b/server-data/resources/[esx]/es_extended/client/modules/actions.lua @@ -91,7 +91,7 @@ CreateThread(function() ToggleVehicleStatus(current.vehicle, current.seat) end elseif isInVehicle then - if (current.vehicle ~= GetVehiclePedIsUsing(playerPed)) or IsPlayerDead(PlayerId()) then + if not IsPedInAnyVehicle(playerPed, false) 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) diff --git a/server-data/resources/[esx]/es_extended/client/modules/streaming.lua b/server-data/resources/[esx]/es_extended/client/modules/streaming.lua index 231806167..958509783 100644 --- a/server-data/resources/[esx]/es_extended/client/modules/streaming.lua +++ b/server-data/resources/[esx]/es_extended/client/modules/streaming.lua @@ -1,51 +1,85 @@ function ESX.Streaming.RequestModel(modelHash, cb) - modelHash = type(modelHash) == "number" and modelHash or joaat(modelHash) - if not IsModelInCdimage(modelHash) then - return + modelHash = (type(modelHash) == "number" and modelHash or joaat(modelHash)) + + if not HasModelLoaded(modelHash) and IsModelInCdimage(modelHash) then + RequestModel(modelHash) + + while not HasModelLoaded(modelHash) do + Wait(0) + end end - RequestModel(modelHash) - while not HasModelLoaded(modelHash) do - Wait(0) + + if cb ~= nil then + cb() end - return cb and cb(modelHash) or modelHash end function ESX.Streaming.RequestStreamedTextureDict(textureDict, cb) - RequestStreamedTextureDict(textureDict) - while not HasStreamedTextureDictLoaded(textureDict) do - Wait(0) + if not HasStreamedTextureDictLoaded(textureDict) then + RequestStreamedTextureDict(textureDict) + + while not HasStreamedTextureDictLoaded(textureDict) do + Wait(0) + end + end + + if cb ~= nil then + cb() end - return cb and cb(textureDict) or textureDict end function ESX.Streaming.RequestNamedPtfxAsset(assetName, cb) - RequestNamedPtfxAsset(assetName) - while not HasNamedPtfxAssetLoaded(assetName) do - Wait(0) + if not HasNamedPtfxAssetLoaded(assetName) then + RequestNamedPtfxAsset(assetName) + + while not HasNamedPtfxAssetLoaded(assetName) do + Wait(0) + end + end + + if cb ~= nil then + cb() end - return cb and cb(assetName) or assetName end function ESX.Streaming.RequestAnimSet(animSet, cb) - RequestAnimSet(animSet) - while not HasAnimSetLoaded(animSet) do - Wait(0) + if not HasAnimSetLoaded(animSet) then + RequestAnimSet(animSet) + + while not HasAnimSetLoaded(animSet) do + Wait(0) + end + end + + if cb ~= nil then + cb() end - return cb and cb(animSet) or animSet end function ESX.Streaming.RequestAnimDict(animDict, cb) - RequestAnimDict(animDict) - while not HasAnimDictLoaded(animDict) do - Wait(0) + if not HasAnimDictLoaded(animDict) then + RequestAnimDict(animDict) + + while not HasAnimDictLoaded(animDict) do + Wait(0) + end + end + + if cb ~= nil then + cb() end - return cb and cb(animDict) or animDict end function ESX.Streaming.RequestWeaponAsset(weaponHash, cb) - RequestWeaponAsset(weaponHash) - while not HasWeaponAssetLoaded(weaponHash) do - Wait(0) + if not HasWeaponAssetLoaded(weaponHash) then + RequestWeaponAsset(weaponHash) + + while not HasWeaponAssetLoaded(weaponHash) do + Wait(0) + end + end + + if cb ~= nil then + cb() end - return cb and cb(weaponHash) or weaponHash end diff --git a/server-data/resources/[esx]/es_extended/fxmanifest.lua b/server-data/resources/[esx]/es_extended/fxmanifest.lua index 29883ecf1..db651f165 100644 --- a/server-data/resources/[esx]/es_extended/fxmanifest.lua +++ b/server-data/resources/[esx]/es_extended/fxmanifest.lua @@ -3,7 +3,7 @@ fx_version("cerulean") game("gta5") description("The Core resource that provides the functionalities for all other resources.") lua54("yes") -version("1.0.2") +version("1.0.1") shared_scripts({ "locale.lua", diff --git a/server-data/resources/[esx]/es_extended/server/classes/player.lua b/server-data/resources/[esx]/es_extended/server/classes/player.lua index e1fa0e06c..d9ba79001 100644 --- a/server-data/resources/[esx]/es_extended/server/classes/player.lua +++ b/server-data/resources/[esx]/es_extended/server/classes/player.lua @@ -191,10 +191,8 @@ 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 - local accountName = string.lower(self.accounts[i].name) - if accountName == account then + if self.accounts[i].name == account then return self.accounts[i] end end diff --git a/server-data/resources/[esx]/es_extended/server/main.lua b/server-data/resources/[esx]/es_extended/server/main.lua index 5d5179f37..b28bd5cdb 100644 --- a/server-data/resources/[esx]/es_extended/server/main.lua +++ b/server-data/resources/[esx]/es_extended/server/main.lua @@ -28,9 +28,9 @@ if Config.Multichar then if not ESX.Players[src] then local identifier = char .. ":" .. ESX.GetIdentifier(src) if data then - CreateESXPlayer(identifier, src, data) + createESXPlayer(identifier, src, data) else - LoadESXPlayer(identifier, src, false) + loadESXPlayer(identifier, src, false) end end end) @@ -43,12 +43,12 @@ else end if not ESX.Players[_source] then - OnPlayerJoined(_source) + onPlayerJoined(_source) end end) end -function OnPlayerJoined(playerId) +function onPlayerJoined(playerId) local identifier = ESX.GetIdentifier(playerId) if identifier then if ESX.GetPlayerFromIdentifier(identifier) then @@ -61,9 +61,9 @@ function OnPlayerJoined(playerId) else local result = MySQL.scalar.await("SELECT 1 FROM users WHERE identifier = ?", { identifier }) if result then - LoadESXPlayer(identifier, playerId, false) + loadESXPlayer(identifier, playerId, false) else - CreateESXPlayer(identifier, playerId) + createESXPlayer(identifier, playerId) end end else @@ -71,7 +71,7 @@ function OnPlayerJoined(playerId) end end -function CreateESXPlayer(identifier, playerId, data) +function createESXPlayer(identifier, playerId, data) local accounts = {} for account, money in pairs(Config.StartingAccountMoney) do @@ -91,7 +91,7 @@ function CreateESXPlayer(identifier, playerId, data) end MySQL.prepare(newPlayer, parameters, function() - LoadESXPlayer(identifier, playerId, true) + loadESXPlayer(identifier, playerId, true) end) end @@ -123,7 +123,7 @@ if not Config.Multichar then end) end -function LoadESXPlayer(identifier, playerId, isNew) +function loadESXPlayer(identifier, playerId, isNew) local userData = { accounts = {}, inventory = {}, @@ -306,7 +306,7 @@ end AddEventHandler("chatMessage", function(playerId, _, message) local xPlayer = ESX.GetPlayerFromId(playerId) - if xPlayer and message:sub(1, 1) == "/" and playerId > 0 then + if message:sub(1, 1) == "/" and playerId > 0 then CancelEvent() local commandName = message:sub(1):gmatch("%w+")() xPlayer.showNotification(TranslateCap("commanderror_invalidcommand", commandName))