209 lines
7.4 KiB
Lua
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)
|