local positions = {} local presets = {} local positionsFile = 'positions.json' local presetsFile = 'presets.json' -- Load saved positions from JSON file local function LoadPositions() local file = LoadResourceFile(GetCurrentResourceName(), 'json/' .. positionsFile) if file then positions = json.decode(file) or {} end end -- Load saved presets from JSON file local function LoadPresets() local file = LoadResourceFile(GetCurrentResourceName(), 'json/' .. presetsFile) if file then presets = json.decode(file) or {} end end -- Save positions to JSON file local function SavePositions() SaveResourceFile(GetCurrentResourceName(), 'json/' .. positionsFile, json.encode(positions), -1) end -- Save presets to JSON file local function SavePresets() SaveResourceFile(GetCurrentResourceName(), 'json/' .. presetsFile, json.encode(presets), -1) end -- Load data when resource starts CreateThread(function() LoadPositions() LoadPresets() end) -- Weapon sync local attachedWeapons = {} RegisterNetEvent('force-sling:server:syncWeapons') AddEventHandler('force-sling:server:syncWeapons', function(weaponData, action) local src = source if action == 'attach' then attachedWeapons[src] = attachedWeapons[src] or {} attachedWeapons[src][weaponData.weaponName] = weaponData elseif action == 'detach' then if attachedWeapons[src] then attachedWeapons[src][weaponData.weaponName] = nil end end TriggerClientEvent('force-sling:client:syncWeapons', -1, src, weaponData, action) end) -- Callbacks lib.callback.register('force-sling:callback:getCachedPositions', function(source) return positions end) lib.callback.register('force-sling:callback:getCachedPresets', function(source) return presets 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} end) lib.callback.register('force-sling:callback:resetWeaponPositions', function(source, weapon) local src = source if weapon then positions[weapon] = nil else positions = {} end SavePositions() return positions end) RegisterNetEvent('force-sling:server:saveWeaponPosition') AddEventHandler('force-sling:server:saveWeaponPosition', function(position, rotation, weapon, weaponName, boneId, isPreset) local src = source local data = { coords = position, rot = rotation, boneId = boneId } if isPreset then presets[weaponName] = data SavePresets() else positions[weaponName] = data SavePositions() end end) -- Cleanup on player drop AddEventHandler('playerDropped', function() local src = source if attachedWeapons[src] then TriggerClientEvent('force-sling:client:cleanupPlayerWeapons', -1, src) attachedWeapons[src] = nil end end)