1
0
Fork 0
forked from Simnation/Main
This commit is contained in:
Nordi98 2025-06-12 22:21:39 +02:00
parent f9b8f9ccad
commit 495d74e4dc
3 changed files with 113 additions and 59 deletions

View file

@ -74,29 +74,30 @@ end)
RegisterNetEvent('force-sling:client:syncWeapons') RegisterNetEvent('force-sling:client:syncWeapons')
AddEventHandler('force-sling:client:syncWeapons', function(playerId, weaponData, action) AddEventHandler('force-sling:client:syncWeapons', function(playerId, weaponData, action)
if not Sling then return end 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 if action == 'attach' then
local targetPed = GetPlayerPed(GetPlayerFromServerId(playerId)) local targetPed = GetPlayerPed(GetPlayerFromServerId(playerId))
if not targetPed or not DoesEntityExist(targetPed) then return end if not targetPed or not DoesEntityExist(targetPed) then return end
-- Erstelle einen eindeutigen Key für die Waffe des anderen Spielers -- 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 {} otherPlayersWeapons[playerId] = otherPlayersWeapons[playerId] or {}
-- Verwende den eindeutigen Key für die Waffe if not otherPlayersWeapons[playerId][uniqueWeaponKey] then
Utils:CreateAndAttachWeapon( Utils:CreateAndAttachWeapon(
uniqueWeaponKey, -- Eindeutiger Key uniqueWeaponKey,
weaponData.weaponVal, weaponData.weaponVal,
weaponData.coords, weaponData.coords,
targetPed, targetPed,
true -- Flag für andere Spieler true -- Flag für andere Spieler
) )
otherPlayersWeapons[playerId][uniqueWeaponKey] = true otherPlayersWeapons[playerId][uniqueWeaponKey] = true
end
elseif action == 'detach' then elseif action == 'detach' then
local uniqueWeaponKey = playerId .. '_' .. weaponData.weaponName local uniqueWeaponKey = 'player_' .. playerId .. '_' .. weaponData.weaponName
if otherPlayersWeapons[playerId] and otherPlayersWeapons[playerId][uniqueWeaponKey] then if otherPlayersWeapons[playerId] and otherPlayersWeapons[playerId][uniqueWeaponKey] then
Utils:DeleteWeapon(uniqueWeaponKey) Utils:DeleteWeapon(uniqueWeaponKey)
otherPlayersWeapons[playerId][uniqueWeaponKey] = nil otherPlayersWeapons[playerId][uniqueWeaponKey] = nil
@ -104,6 +105,7 @@ AddEventHandler('force-sling:client:syncWeapons', function(playerId, weaponData,
end end
end) end)
RegisterNetEvent('force-sling:client:cleanupPlayerWeapons') RegisterNetEvent('force-sling:client:cleanupPlayerWeapons')
AddEventHandler('force-sling:client:cleanupPlayerWeapons', function(playerId) AddEventHandler('force-sling:client:cleanupPlayerWeapons', function(playerId)
if not Sling then return end if not Sling then return end

View file

@ -106,7 +106,6 @@ function Sling:WeaponThread()
Sling.cachedAttachments[weaponName] = {} Sling.cachedAttachments[weaponName] = {}
end end
-- Erweiterte Checks für Spielerzustände
local isInVehicle = IsPedInAnyVehicle(playerPed, false) local isInVehicle = IsPedInAnyVehicle(playerPed, false)
local isSitting = IsPedUsingScenario(playerPed, "PROP_HUMAN_SEAT_CHAIR") local isSitting = IsPedUsingScenario(playerPed, "PROP_HUMAN_SEAT_CHAIR")
local isRagdoll = IsPedRagdoll(playerPed) local isRagdoll = IsPedRagdoll(playerPed)
@ -115,23 +114,14 @@ function Sling:WeaponThread()
if weapon == weaponVal.name or shouldHideWeapons then if weapon == weaponVal.name or shouldHideWeapons then
if DoesEntityExist(Sling.cachedAttachments[weaponName].obj) then if DoesEntityExist(Sling.cachedAttachments[weaponName].obj) then
Utils:DeleteWeapon(weaponName) Utils:DeleteWeapon(weaponName)
if shouldHideWeapons then Sling:SyncWeaponAttachment(weaponName, nil, nil, 'detach')
Sling:SyncWeaponAttachment(weaponName, nil, nil, 'detach')
end
end end
else else
if not DoesEntityExist(Sling.cachedAttachments[weaponName].obj) then if not DoesEntityExist(Sling.cachedAttachments[weaponName].obj) then
local coords = Sling.cachedPositions[weaponName] or Sling.cachedPresets[weaponName] or 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 } { 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)
if not shouldHideWeapons then Sling:SyncWeaponAttachment(weaponName, weaponVal, coords, 'attach')
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
end end
end end
end end
@ -152,43 +142,34 @@ function Sling:WeaponThread()
ragdoll = IsPedRagdoll(playerPed) ragdoll = IsPedRagdoll(playerPed)
} }
-- Überprüfe, ob sich der Zustand geändert hat
local stateChanged = lastState.inVehicle ~= currentState.inVehicle or local stateChanged = lastState.inVehicle ~= currentState.inVehicle or
lastState.sitting ~= currentState.sitting or lastState.sitting ~= currentState.sitting or
lastState.ragdoll ~= currentState.ragdoll lastState.ragdoll ~= currentState.ragdoll
if stateChanged then if stateChanged then
-- Aktualisiere den letzten Status
lastState = Utils:DeepCopy(currentState) lastState = Utils:DeepCopy(currentState)
local shouldHideWeapons = currentState.inVehicle or currentState.sitting or currentState.ragdoll local shouldHideWeapons = currentState.inVehicle or currentState.sitting or currentState.ragdoll
if shouldHideWeapons then -- Nur eigene Waffen verarbeiten
-- Entferne alle Waffen for weaponName, weaponVal in pairs(Sling.cachedWeapons) do
for weaponName, _ in pairs(Sling.cachedAttachments) do if shouldHideWeapons then
if DoesEntityExist(Sling.cachedAttachments[weaponName].obj) then if DoesEntityExist(Sling.cachedAttachments[weaponName]?.obj) then
Utils:DeleteWeapon(weaponName) Utils:DeleteWeapon(weaponName)
Sling:SyncWeaponAttachment(weaponName, nil, nil, 'detach') Sling:SyncWeaponAttachment(weaponName, nil, nil, 'detach')
end end
end else
else
-- Füge Waffen wieder hinzu
for weaponName, weaponVal in pairs(Sling.cachedWeapons) do
if not DoesEntityExist(Sling.cachedAttachments[weaponName]?.obj) then if not DoesEntityExist(Sling.cachedAttachments[weaponName]?.obj) then
local coords = Sling.cachedPositions[weaponName] or Sling.cachedPresets[weaponName] or 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 } { 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') Sling:SyncWeaponAttachment(weaponName, weaponVal, coords, 'attach')
end end
end end
end end
end end
while Sling.inPositioning do
Wait(1000)
end
if not (currentState.inVehicle or currentState.sitting or currentState.ragdoll) then if not (currentState.inVehicle or currentState.sitting or currentState.ragdoll) then
-- Nur eigene Waffen verarbeiten
for weaponName, weaponVal in pairs(Sling.cachedWeapons) do for weaponName, weaponVal in pairs(Sling.cachedWeapons) do
handleWeaponAttachment(weaponName, weaponVal, playerPed, weapon) handleWeaponAttachment(weaponName, weaponVal, playerPed, weapon)
end end

View file

@ -2,6 +2,7 @@ local positions = {}
local presets = {} local presets = {}
local positionsFile = 'positions.json' local positionsFile = 'positions.json'
local presetsFile = 'presets.json' local presetsFile = 'presets.json'
local attachedWeapons = {}
-- Load saved positions from JSON file -- Load saved positions from JSON file
local function LoadPositions() local function LoadPositions()
@ -29,19 +30,44 @@ local function SavePresets()
SaveResourceFile(GetCurrentResourceName(), 'json/' .. presetsFile, json.encode(presets), -1) SaveResourceFile(GetCurrentResourceName(), 'json/' .. presetsFile, json.encode(presets), -1)
end 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 -- Load data when resource starts
CreateThread(function() CreateThread(function()
LoadPositions() LoadPositions()
LoadPresets() LoadPresets()
end) end)
-- Weapon sync -- Weapon sync with verification
local attachedWeapons = {}
RegisterNetEvent('force-sling:server:syncWeapons') RegisterNetEvent('force-sling:server:syncWeapons')
AddEventHandler('force-sling:server:syncWeapons', function(weaponData, action) AddEventHandler('force-sling:server:syncWeapons', function(weaponData, action)
local src = source local src = source
if action == 'attach' then 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] = attachedWeapons[src] or {}
attachedWeapons[src][weaponData.weaponName] = weaponData attachedWeapons[src][weaponData.weaponName] = weaponData
elseif action == 'detach' then elseif action == 'detach' then
@ -55,7 +81,17 @@ end)
-- Callbacks -- Callbacks
lib.callback.register('force-sling:callback:getCachedPositions', function(source) 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) end)
lib.callback.register('force-sling:callback:getCachedPresets', function(source) lib.callback.register('force-sling:callback:getCachedPresets', function(source)
@ -64,23 +100,34 @@ end)
lib.callback.register('force-sling:callback:isPlayerAdmin', function(source) lib.callback.register('force-sling:callback:isPlayerAdmin', function(source)
local src = source local src = source
-- Add your admin check logic here if Config.Framework.name == "qbcore" then
-- Example for QBCore: local Player = QBCore.Functions.GetPlayer(src)
-- local Player = QBCore.Functions.GetPlayer(src) return Player and Player.PlayerData.admin or false
-- return Player.PlayerData.admin or false elseif Config.Framework.name == "esx" then
local xPlayer = ESX.GetPlayerFromId(src)
-- For testing, returning true return xPlayer and xPlayer.getGroup() == 'admin' or false
return {isAdmin = true} end
return false
end) end)
lib.callback.register('force-sling:callback:resetWeaponPositions', function(source, weapon) lib.callback.register('force-sling:callback:resetWeaponPositions', function(source, weapon)
local src = source local src = source
if weapon then if weapon then
positions[weapon] = nil if DoesPlayerHaveWeapon(src, weapon) then
positions[weapon] = nil
SavePositions()
end
else 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 end
SavePositions()
return positions return positions
end) end)
@ -94,11 +141,18 @@ AddEventHandler('force-sling:server:saveWeaponPosition', function(position, rota
} }
if isPreset then if isPreset then
presets[weaponName] = data -- Nur Admins können Presets speichern
SavePresets() local isAdmin = lib.callback.await('force-sling:callback:isPlayerAdmin', src)
if isAdmin then
presets[weaponName] = data
SavePresets()
end
else else
positions[weaponName] = data -- Überprüfe ob der Spieler die Waffe besitzt
SavePositions() if DoesPlayerHaveWeapon(src, weaponName) then
positions[weaponName] = data
SavePositions()
end
end end
end) end)
@ -110,3 +164,20 @@ AddEventHandler('playerDropped', function()
attachedWeapons[src] = nil attachedWeapons[src] = nil
end end
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)