alle
This commit is contained in:
		
							parent
							
								
									f9b8f9ccad
								
							
						
					
					
						commit
						495d74e4dc
					
				
					 3 changed files with 113 additions and 59 deletions
				
			
		| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue