From 495d74e4dc70af7ad3e591b2962cbadb40fe1e95 Mon Sep 17 00:00:00 2001 From: Nordi98 Date: Thu, 12 Jun 2025 22:21:39 +0200 Subject: [PATCH] alle --- .../[weapons]/force-sling/client/events.lua | 26 +++-- .../force-sling/client/functions.lua | 39 ++----- .../[weapons]/force-sling/server/main.lua | 107 +++++++++++++++--- 3 files changed, 113 insertions(+), 59 deletions(-) diff --git a/resources/[jobs]/[weapons]/force-sling/client/events.lua b/resources/[jobs]/[weapons]/force-sling/client/events.lua index 7266660b8..2856ccc85 100644 --- a/resources/[jobs]/[weapons]/force-sling/client/events.lua +++ b/resources/[jobs]/[weapons]/force-sling/client/events.lua @@ -74,29 +74,30 @@ end) RegisterNetEvent('force-sling:client:syncWeapons') AddEventHandler('force-sling:client:syncWeapons', function(playerId, weaponData, action) if not Sling then return end - if playerId == cache.serverId then return end -- Ignoriere eigene Events + if playerId == cache.serverId then return end if action == 'attach' then local targetPed = GetPlayerPed(GetPlayerFromServerId(playerId)) if not targetPed or not DoesEntityExist(targetPed) then return end -- Erstelle einen eindeutigen Key für die Waffe des anderen Spielers - local uniqueWeaponKey = playerId .. '_' .. weaponData.weaponName + local uniqueWeaponKey = 'player_' .. playerId .. '_' .. weaponData.weaponName otherPlayersWeapons[playerId] = otherPlayersWeapons[playerId] or {} - -- Verwende den eindeutigen Key für die Waffe - Utils:CreateAndAttachWeapon( - uniqueWeaponKey, -- Eindeutiger Key - weaponData.weaponVal, - weaponData.coords, - targetPed, - true -- Flag für andere Spieler - ) - otherPlayersWeapons[playerId][uniqueWeaponKey] = true + if not otherPlayersWeapons[playerId][uniqueWeaponKey] then + Utils:CreateAndAttachWeapon( + uniqueWeaponKey, + weaponData.weaponVal, + weaponData.coords, + targetPed, + true -- Flag für andere Spieler + ) + otherPlayersWeapons[playerId][uniqueWeaponKey] = true + end elseif action == 'detach' then - local uniqueWeaponKey = playerId .. '_' .. weaponData.weaponName + local uniqueWeaponKey = 'player_' .. playerId .. '_' .. weaponData.weaponName if otherPlayersWeapons[playerId] and otherPlayersWeapons[playerId][uniqueWeaponKey] then Utils:DeleteWeapon(uniqueWeaponKey) otherPlayersWeapons[playerId][uniqueWeaponKey] = nil @@ -104,6 +105,7 @@ AddEventHandler('force-sling:client:syncWeapons', function(playerId, weaponData, end end) + RegisterNetEvent('force-sling:client:cleanupPlayerWeapons') AddEventHandler('force-sling:client:cleanupPlayerWeapons', function(playerId) if not Sling then return end diff --git a/resources/[jobs]/[weapons]/force-sling/client/functions.lua b/resources/[jobs]/[weapons]/force-sling/client/functions.lua index 81ee2db72..c2a16e5e3 100644 --- a/resources/[jobs]/[weapons]/force-sling/client/functions.lua +++ b/resources/[jobs]/[weapons]/force-sling/client/functions.lua @@ -106,7 +106,6 @@ function Sling:WeaponThread() Sling.cachedAttachments[weaponName] = {} end - -- Erweiterte Checks für Spielerzustände local isInVehicle = IsPedInAnyVehicle(playerPed, false) local isSitting = IsPedUsingScenario(playerPed, "PROP_HUMAN_SEAT_CHAIR") local isRagdoll = IsPedRagdoll(playerPed) @@ -115,23 +114,14 @@ function Sling:WeaponThread() if weapon == weaponVal.name or shouldHideWeapons then if DoesEntityExist(Sling.cachedAttachments[weaponName].obj) then Utils:DeleteWeapon(weaponName) - if shouldHideWeapons then - Sling:SyncWeaponAttachment(weaponName, nil, nil, 'detach') - end + Sling:SyncWeaponAttachment(weaponName, nil, nil, 'detach') end else if not DoesEntityExist(Sling.cachedAttachments[weaponName].obj) then local coords = Sling.cachedPositions[weaponName] or Sling.cachedPresets[weaponName] or { coords = { x = 0.0, y = -0.15, z = 0.0 }, rot = { x = 0.0, y = 0.0, z = 0.0 }, boneId = DEFAULT_BONE } - Utils:CreateAndAttachWeapon(weaponName, weaponVal, coords, playerPed) - if not shouldHideWeapons then - Sling:SyncWeaponAttachment(weaponName, weaponVal, coords, 'attach') - end - else - if not IsEntityAttachedToEntity(Sling.cachedAttachments[weaponName].placeholder, playerPed) then - Utils:DeleteWeapon(weaponName) - Sling:SyncWeaponAttachment(weaponName, nil, nil, 'detach') - end + Utils:CreateAndAttachWeapon(weaponName, weaponVal, coords, playerPed, false) + Sling:SyncWeaponAttachment(weaponName, weaponVal, coords, 'attach') end end end @@ -152,43 +142,34 @@ function Sling:WeaponThread() ragdoll = IsPedRagdoll(playerPed) } - -- Überprüfe, ob sich der Zustand geändert hat local stateChanged = lastState.inVehicle ~= currentState.inVehicle or lastState.sitting ~= currentState.sitting or lastState.ragdoll ~= currentState.ragdoll if stateChanged then - -- Aktualisiere den letzten Status lastState = Utils:DeepCopy(currentState) - local shouldHideWeapons = currentState.inVehicle or currentState.sitting or currentState.ragdoll - if shouldHideWeapons then - -- Entferne alle Waffen - for weaponName, _ in pairs(Sling.cachedAttachments) do - if DoesEntityExist(Sling.cachedAttachments[weaponName].obj) then + -- Nur eigene Waffen verarbeiten + for weaponName, weaponVal in pairs(Sling.cachedWeapons) do + if shouldHideWeapons then + if DoesEntityExist(Sling.cachedAttachments[weaponName]?.obj) then Utils:DeleteWeapon(weaponName) Sling:SyncWeaponAttachment(weaponName, nil, nil, 'detach') end - end - else - -- Füge Waffen wieder hinzu - for weaponName, weaponVal in pairs(Sling.cachedWeapons) do + else if not DoesEntityExist(Sling.cachedAttachments[weaponName]?.obj) then local coords = Sling.cachedPositions[weaponName] or Sling.cachedPresets[weaponName] or { coords = { x = 0.0, y = -0.15, z = 0.0 }, rot = { x = 0.0, y = 0.0, z = 0.0 }, boneId = DEFAULT_BONE } - Utils:CreateAndAttachWeapon(weaponName, weaponVal, coords, playerPed) + Utils:CreateAndAttachWeapon(weaponName, weaponVal, coords, playerPed, false) Sling:SyncWeaponAttachment(weaponName, weaponVal, coords, 'attach') end end end end - while Sling.inPositioning do - Wait(1000) - end - if not (currentState.inVehicle or currentState.sitting or currentState.ragdoll) then + -- Nur eigene Waffen verarbeiten for weaponName, weaponVal in pairs(Sling.cachedWeapons) do handleWeaponAttachment(weaponName, weaponVal, playerPed, weapon) end diff --git a/resources/[jobs]/[weapons]/force-sling/server/main.lua b/resources/[jobs]/[weapons]/force-sling/server/main.lua index 073eda6b5..5163680c4 100644 --- a/resources/[jobs]/[weapons]/force-sling/server/main.lua +++ b/resources/[jobs]/[weapons]/force-sling/server/main.lua @@ -2,6 +2,7 @@ local positions = {} local presets = {} local positionsFile = 'positions.json' local presetsFile = 'presets.json' +local attachedWeapons = {} -- Load saved positions from JSON file local function LoadPositions() @@ -29,19 +30,44 @@ local function SavePresets() SaveResourceFile(GetCurrentResourceName(), 'json/' .. presetsFile, json.encode(presets), -1) end +-- Überprüfe ob ein Spieler eine Waffe besitzt +local function DoesPlayerHaveWeapon(source, weaponName) + if Config.Framework.name == "qbcore" then + local Player = QBCore.Functions.GetPlayer(source) + if Player then + for _, item in pairs(Player.PlayerData.items) do + if item.name == weaponName then + return true + end + end + end + elseif Config.Framework.name == "esx" then + local xPlayer = ESX.GetPlayerFromId(source) + if xPlayer then + local hasWeapon = xPlayer.hasWeapon(weaponName) + return hasWeapon + end + end + return false +end + -- Load data when resource starts CreateThread(function() LoadPositions() LoadPresets() end) --- Weapon sync -local attachedWeapons = {} - +-- Weapon sync with verification RegisterNetEvent('force-sling:server:syncWeapons') AddEventHandler('force-sling:server:syncWeapons', function(weaponData, action) local src = source + if action == 'attach' then + -- Überprüfe ob der Spieler die Waffe besitzt + if not DoesPlayerHaveWeapon(src, weaponData.weaponName) then + return + end + attachedWeapons[src] = attachedWeapons[src] or {} attachedWeapons[src][weaponData.weaponName] = weaponData elseif action == 'detach' then @@ -55,7 +81,17 @@ end) -- Callbacks lib.callback.register('force-sling:callback:getCachedPositions', function(source) - return positions + local src = source + local playerPositions = {} + + -- Filtere nur die Positionen für Waffen, die der Spieler besitzt + for weaponName, posData in pairs(positions) do + if DoesPlayerHaveWeapon(src, weaponName) then + playerPositions[weaponName] = posData + end + end + + return playerPositions end) lib.callback.register('force-sling:callback:getCachedPresets', function(source) @@ -64,23 +100,34 @@ end) lib.callback.register('force-sling:callback:isPlayerAdmin', function(source) local src = source - -- Add your admin check logic here - -- Example for QBCore: - -- local Player = QBCore.Functions.GetPlayer(src) - -- return Player.PlayerData.admin or false - - -- For testing, returning true - return {isAdmin = true} + if Config.Framework.name == "qbcore" then + local Player = QBCore.Functions.GetPlayer(src) + return Player and Player.PlayerData.admin or false + elseif Config.Framework.name == "esx" then + local xPlayer = ESX.GetPlayerFromId(src) + return xPlayer and xPlayer.getGroup() == 'admin' or false + end + return false end) lib.callback.register('force-sling:callback:resetWeaponPositions', function(source, weapon) local src = source if weapon then - positions[weapon] = nil + if DoesPlayerHaveWeapon(src, weapon) then + positions[weapon] = nil + SavePositions() + end else - positions = {} + -- Beim kompletten Reset nur die Positionen der Waffen löschen, die der Spieler besitzt + local newPositions = {} + for weaponName, posData in pairs(positions) do + if not DoesPlayerHaveWeapon(src, weaponName) then + newPositions[weaponName] = posData + end + end + positions = newPositions + SavePositions() end - SavePositions() return positions end) @@ -94,11 +141,18 @@ AddEventHandler('force-sling:server:saveWeaponPosition', function(position, rota } if isPreset then - presets[weaponName] = data - SavePresets() + -- Nur Admins können Presets speichern + local isAdmin = lib.callback.await('force-sling:callback:isPlayerAdmin', src) + if isAdmin then + presets[weaponName] = data + SavePresets() + end else - positions[weaponName] = data - SavePositions() + -- Überprüfe ob der Spieler die Waffe besitzt + if DoesPlayerHaveWeapon(src, weaponName) then + positions[weaponName] = data + SavePositions() + end end end) @@ -110,3 +164,20 @@ AddEventHandler('playerDropped', function() attachedWeapons[src] = nil end end) + +-- Periodische Überprüfung der angehängten Waffen +CreateThread(function() + while true do + for playerId, weapons in pairs(attachedWeapons) do + for weaponName, _ in pairs(weapons) do + if not DoesPlayerHaveWeapon(playerId, weaponName) then + -- Spieler hat die Waffe nicht mehr, entferne sie + TriggerClientEvent('force-sling:client:syncWeapons', -1, playerId, {weaponName = weaponName}, 'detach') + attachedWeapons[playerId][weaponName] = nil + end + end + end + Wait(5000) -- Alle 5 Sekunden überprüfen + end +end) +