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

209 lines
7.4 KiB
Lua

local decorationsByGarage = {}
local decorationUsedBy = {}
local ALLOWED_UPDATE_KEYS = {
coords = true,
rotation = true,
inStash = true,
lightData = true,
}
lib.callback.register("garages:decorate:saveObject", function(sourcePlayer, garageId, objectData)
local playerIdentifier = GetPlayerIdentifier(sourcePlayer)
objectData.created = os.time()
local newId = db.saveObject(playerIdentifier, objectData)
objectData.id = newId
if not decorationsByGarage[garageId] then
decorationsByGarage[garageId] = {}
end
decorationsByGarage[garageId][#decorationsByGarage[garageId] + 1] = objectData
objectData.uniq = tostring("garage_" .. newId)
TriggerClientEvent("garages:decorate:addObject", -1, garageId, objectData)
Debug("garages:decorate:saveObject", "Saved", garageId, "Id", newId, "Data", objectData)
return true
end)
RegisterNetEvent("garages:decorate:updateObject")
AddEventHandler("garages:decorate:updateObject", function(garageId, objectId, updateData)
local playerSource = source
if not updateData then
return Notification(playerSource, i18n.t("decorate.invalid_data"), "error")
end
Debug("data", updateData)
local hasInvalidKey = table.find(updateData, function(value, key)
return not ALLOWED_UPDATE_KEYS[key]
end)
if hasInvalidKey then
Notification(playerSource, i18n.t("decorate.invalid_data"), "error")
Debug("unsecured", updateData)
Debug("garages:decorate:updateObject", "User trying to exploit update profile event", playerSource, updateData)
return
end
local foundObject = table.find(decorationsByGarage[garageId], function(obj)
return obj.id == objectId
end)
if not foundObject then
return Notification(playerSource, i18n.t("decorate.invalid_object"), "error")
end
local success = db.updateObject(objectId, updateData)
if not success then
Notification(playerSource, i18n.t("decorate.failed_update"), "error")
return
end
for key, value in pairs(updateData) do
if value and (key == "coords" or key == "rotation" or key == "lightData") then
Debug("garages:decorate:updateObject", "Decoding", key, value)
updateData[key] = json.decode(value)
end
foundObject[key] = updateData[key]
end
TriggerClientEvent("garages:decorate:updateObject", -1, garageId, objectId, updateData)
Debug("garages:decorate:updateObject", "Updated", garageId, "Id", objectId, "data", updateData)
end)
local function GetFurniturePriceByObject(modelName)
for categoryKey, category in pairs(Config.Furniture) do
if categoryKey ~= "navigation" then
for _, item in pairs(category.items) do
if item.object == modelName then
return item.price
end
if item.colors then
for _, colorVariant in pairs(item.colors) do
if colorVariant.object == modelName then
return item.price
end
end
end
end
end
end
end
RegisterNetEvent("garages:decorate:sellFurniture")
AddEventHandler("garages:decorate:sellFurniture", function(garageId, objectId)
local playerSource = source
local foundObject = table.find(decorationsByGarage[garageId], function(obj)
return obj.id == objectId
end)
if not foundObject then
return Notification(playerSource, i18n.t("decorate.invalid_object"), "error")
end
local success = db.deleteObject(objectId)
if not success then
Notification(playerSource, i18n.t("decorate.failed_sell"), "error")
return
end
local price = GetFurniturePriceByObject(foundObject.modelName)
local sellGain = price * Config.SellObjectCommision
AddAccountMoney(playerSource, Config.MoneyType, sellGain)
decorationsByGarage[garageId] = table.filter(decorationsByGarage[garageId], function(obj)
return obj.id ~= objectId
end)
TriggerClientEvent("garages:decorate:sellFurniture", -1, garageId, objectId)
Notification(playerSource, i18n.t("decorate.sold_furniture", { price = sellGain }), "success")
end)
local function GetDecorations(garageId)
if not decorationsByGarage[garageId] then
local dbObjects = db.getObjects(garageId)
decorationsByGarage[garageId] = dbObjects or {}
end
for key, value in pairs(decorationsByGarage) do
if key == "coords" and type(value) == "string" then
decorationsByGarage[key] = json.decode(value)
Error("If you see this error please report this ERROR TO THE QUASAR. It will not affect the server but it will help us to improve the script. Thank you!")
elseif key == "rotation" and type(value) == "string" then
decorationsByGarage[key] = json.decode(value)
Error("If you see this error please report this ERROR TO THE QUASAR. It will not affect the server but it will help us to improve the script. Thank you!")
elseif key == "lightData" and type(value) == "string" then
decorationsByGarage[key] = json.decode(value)
Error("If you see this error please report this ERROR TO THE QUASAR. It will not affect the server but it will help us to improve the script. Thank you!")
end
end
return decorationsByGarage[garageId] or {}
end
function ClearDecorations(garageId)
decorationsByGarage[garageId] = nil
Debug("ClearDecorations", garageId)
end
lib.callback.register("garages:decorate:getDecorations", function(sourcePlayer, garageId)
return GetDecorations(garageId)
end)
lib.callback.register("garages:decorate:buyDecorationObject", function(sourcePlayer, price)
local balance = GetAccountMoney(sourcePlayer, Config.MoneyType)
if not price then
Error("Price is nil", price)
return false
end
if price > balance then
Notification(sourcePlayer, i18n.t("decorate.no_money", { price = price }), "error")
return false
end
RemoveAccountMoney(sourcePlayer, Config.MoneyType, price)
return true
end)
lib.callback.register("garages:decorate:getDecorationAvailable", function(sourcePlayer, garageId)
local usedBy = decorationUsedBy[garageId]
Debug("garages:decorate:getDecorationAvailable", garageId, "UsedBy", usedBy)
if not usedBy then
return true
end
return usedBy
end)
RegisterNetEvent("garages:decorate:updateDecorationUsedBy")
AddEventHandler("garages:decorate:updateDecorationUsedBy", function(garageId, isUsing)
local playerSource = source
decorationUsedBy[garageId] = (isUsing and playerSource) and playerSource or nil
Debug("garages:decorate:updateDecorationUsedBy", garageId, "UsedBy", isUsing)
end)
AddEventHandler("playerDropped", function(reason)
local playerSource = source
for garageId, usedByPlayer in pairs(decorationUsedBy) do
if usedByPlayer == playerSource then
decorationUsedBy[garageId] = nil
end
end
end)
RegisterNetEvent("garages:fiveguard:freecam")
AddEventHandler("garages:fiveguard:freecam", function(isActive)
local playerSource = source
if not Config.FiveGuard then return end
local fiveGuard = exports[Config.FiveGuard]
fiveGuard:SetTempPermission(playerSource, "Client", "BypassFreecam", isActive, isActive, false)
fiveGuard:SetTempPermission(playerSource, "Client", "BypassNoclip", isActive, isActive, false)
end)