2026-04-14 17:41:39 +02:00

235 lines
7.1 KiB
Lua

--- Desencrypted By PrejuicioX
-- Framework validation
if Config.esxSettings.enabled then
if Config.qbSettings.enabled then
print("^1BOTH FRAMEWORKS ENABLED!! MAKE SURE TO ONLY ENABLE ONE FRAMEWORK IN THE CONFIG FILE!")
end
end
-- Global tables (preserve for cross-file usage)
DB_TAG = "kq_outfitbag:outfit"
OUTFITS = {}
PLAYER_BAGS = {}
DELETE_QUEUE = {}
-- Bag despawning system
if Config.bagDespawning and Config.bagDespawning.enabled then
Citizen.CreateThread(function()
while true do
Citizen.Wait(60000)
local queueCopy = json.decode(json.encode(DELETE_QUEUE))
for index, bagData in pairs(DELETE_QUEUE) do
if not DoesEntityExist(bagData.entity) then
queueCopy[index] = nil
else
local currentTime = GetGameTimer()
local despawnTime = bagData.time + (Config.bagDespawning.time * 1000 * 60)
if currentTime > despawnTime then
DeleteEntity(bagData.entity)
queueCopy[index] = nil
end
end
end
DELETE_QUEUE = queueCopy
end
end)
end
function GetOrFetchOutfits(playerId, bagTag)
local identifier = _GetPlayerIdentifier(playerId)
if OUTFITS[identifier] and OUTFITS[identifier][bagTag] then
return OUTFITS[identifier][bagTag]
end
return FetchPlayerOutfits(playerId, bagTag)
end
function FetchPlayerOutfits(playerId, bagTag)
local identifier = _GetPlayerIdentifier(playerId)
OUTFITS[identifier] = {}
OUTFITS[identifier][bagTag] = nil
if not OUTFITS[identifier][bagTag] then
local savedOutfits = GetSavedPlayerOutfits(playerId)
if savedOutfits then
OUTFITS[identifier][bagTag] = {}
for _, outfitRecord in ipairs(savedOutfits) do
local outfitData = json.decode(outfitRecord.data)
-- Filter outfits by bag tag
if outfitData.bagItem == bagTag or (Config.bagTag == bagTag and not outfitData.bagItem) then
outfitData.id = outfitRecord.id
table.insert(OUTFITS[identifier][bagTag], outfitData)
end
end
end
end
return OUTFITS[identifier][bagTag]
end
function RefreshBagOutfits(playerId, bagTag, bagEntity)
local outfits = GetOrFetchOutfits(playerId, bagTag)
local entityState = Entity(bagEntity).state
entityState:set("kq_ob_outfits", outfits, true)
-- Fallback for non-networked entities
if not bagEntity or bagEntity <= 0 then
TriggerClientEvent("kq_outfitbag2:client:set_bags", playerId, nil, {
kq_ob_outfits = outfits
})
end
end
function GetBagTagFromNetId(networkId)
local entity = NetworkGetEntityFromNetworkId(networkId)
return Entity(entity).state.kq_ob_bag
end
-- Command registration
if Config.command.enabled then
RegisterCommand(Config.command.command, function(source)
TriggerClientEvent("kq_outfitbag2:client:place", source, "kq_outfitbag", false)
end)
RegisterCommand(Config.command.shortCommand, function(source)
TriggerClientEvent("kq_outfitbag2:client:place", source, "kq_outfitbag", false)
end)
end
-- Event: Place bag
RegisterServerEvent("kq_outfitbag2:server:place")
AddEventHandler("kq_outfitbag2:server:place", function(bagTag, networkId, propEntity, itemName)
local playerId = source
PlaceBag(playerId, bagTag, networkId, propEntity, itemName)
end)
function PlaceBag(playerId, bagTag, networkId, propEntity, itemName)
local identifier = _GetPlayerIdentifier(playerId)
-- Handle existing bag on ground
if PLAYER_BAGS[identifier] and DoesEntityExist(PLAYER_BAGS[identifier]) then
if Config.onlyAllowOneBagOnGround then
DeleteEntity(PLAYER_BAGS[identifier])
PLAYER_BAGS[identifier] = nil
end
end
local bagEntity = NetworkGetEntityFromNetworkId(networkId)
-- Fallback for non-networked entities
if not bagEntity or bagEntity <= 0 then
Debug("Could not detect the bag as networked")
TriggerClientEvent("kq_outfitbag2:client:set_bags", playerId, propEntity, {
kq_ob = true,
kq_ob_item = itemName or false,
kq_ob_bag = bagTag,
kq_ob_public = false,
kq_ob_owner = playerId,
kq_ob_outfits = GetOrFetchOutfits(playerId, bagTag)
})
return
end
Debug("Created bag entity", bagEntity)
Citizen.Wait(500)
PLAYER_BAGS[identifier] = bagEntity
FreezeEntityPosition(bagEntity, true)
Debug("500ms since created bag entity", bagEntity, DoesEntityExist(bagEntity), GetEntityCoords(bagEntity))
if bagEntity and bagEntity > 0 then
Debug("object detected, setting state")
EnsureEntityStateBag(bagEntity)
local entityState = Entity(bagEntity).state
entityState:set("kq_ob", true, true)
entityState:set("kq_ob_item", itemName or false, true)
entityState:set("kq_ob_bag", bagTag, true)
entityState:set("kq_ob_public", false, true)
entityState:set("kq_ob_owner", playerId, true)
RefreshBagOutfits(playerId, bagTag, bagEntity)
table.insert(DELETE_QUEUE, {
time = GetGameTimer(),
entity = bagEntity
})
end
if itemName then
RemoveBagItem(playerId, itemName)
end
end
-- Event: Delete outfit
RegisterServerEvent("kq_outfitbag2:server:deleteOutfit")
AddEventHandler("kq_outfitbag2:server:deleteOutfit", function(outfitId, bagNetworkId, fallbackBagTag)
local bagTag = GetBagTagFromNetId(bagNetworkId) or fallbackBagTag
local playerId = source
DeleteOutfit(playerId, outfitId)
FetchPlayerOutfits(playerId, bagTag)
RefreshBagOutfits(playerId, bagTag, NetworkGetEntityFromNetworkId(bagNetworkId))
end)
-- Event: Pickup bag
RegisterServerEvent("kq_outfitbag2:server:pickup")
AddEventHandler("kq_outfitbag2:server:pickup", function(bagNetworkId, itemName)
PickupBag(source, bagNetworkId, itemName)
end)
function PickupBag(playerId, bagNetworkId, itemName)
local bagEntity = NetworkGetEntityFromNetworkId(bagNetworkId)
local bagItemName = Entity(bagEntity).state.kq_ob_item
if bagItemName or itemName then
AddPlayerItem(playerId, bagItemName or itemName, 1)
end
DeleteEntity(bagEntity)
local identifier = _GetPlayerIdentifier(playerId)
PLAYER_BAGS[identifier] = nil
end
-- Event: Save outfit
RegisterServerEvent("kq_outfitbag2:server:saveOutfit")
AddEventHandler("kq_outfitbag2:server:saveOutfit", function(outfitData, bagNetworkId, fallbackBagTag)
local bagTag = GetBagTagFromNetId(bagNetworkId) or fallbackBagTag
local playerId = tonumber(source)
local identifier = _GetPlayerIdentifier(playerId)
-- Check outfit limit
if OUTFITS[identifier] and OUTFITS[identifier][bagTag] then
if #OUTFITS[identifier][bagTag] >= Config.maxOutfits then
return
end
end
outfitData.bagItem = bagTag
SaveOutfit(playerId, outfitData)
FetchPlayerOutfits(playerId, bagTag)
RefreshBagOutfits(playerId, bagTag, NetworkGetEntityFromNetworkId(bagNetworkId))
end)
function Debug(...)
if Config.debug then
print(...)
end
end
--- Desencrypted By PrejuicioX