366 lines
12 KiB
Lua
366 lines
12 KiB
Lua
|
local outfitCache = {}
|
||
|
local uniformCache = {}
|
||
|
|
||
|
local function getMoneyForShop(shopType)
|
||
|
local money = 0
|
||
|
if shopType == "clothing" then
|
||
|
money = Config.ClothingCost
|
||
|
elseif shopType == "barber" then
|
||
|
money = Config.BarberCost
|
||
|
elseif shopType == "tattoo" then
|
||
|
money = Config.TattooCost
|
||
|
elseif shopType == "surgeon" then
|
||
|
money = Config.SurgeonCost
|
||
|
end
|
||
|
|
||
|
return money
|
||
|
end
|
||
|
|
||
|
local function getOutfitsForPlayer(citizenid)
|
||
|
outfitCache[citizenid] = {}
|
||
|
local result = Database.PlayerOutfits.GetAllByCitizenID(citizenid)
|
||
|
for i = 1, #result, 1 do
|
||
|
outfitCache[citizenid][#outfitCache[citizenid] + 1] = {
|
||
|
id = result[i].id,
|
||
|
name = result[i].outfitname,
|
||
|
model = result[i].model,
|
||
|
components = json.decode(result[i].components),
|
||
|
props = json.decode(result[i].props)
|
||
|
}
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function GenerateUniqueCode()
|
||
|
local code, exists
|
||
|
repeat
|
||
|
code = GenerateNanoID(Config.OutfitCodeLength)
|
||
|
exists = Database.PlayerOutfitCodes.GetByCode(code)
|
||
|
until not exists
|
||
|
return code
|
||
|
end
|
||
|
|
||
|
-- Callback(s)
|
||
|
|
||
|
lib.callback.register("illenium-appearance:server:generateOutfitCode", function(_, outfitID)
|
||
|
local existingOutfitCode = Database.PlayerOutfitCodes.GetByOutfitID(outfitID)
|
||
|
if not existingOutfitCode then
|
||
|
local code = GenerateUniqueCode()
|
||
|
local id = Database.PlayerOutfitCodes.Add(outfitID, code)
|
||
|
if not id then
|
||
|
print("Something went wrong while generating outfit code")
|
||
|
return
|
||
|
end
|
||
|
return code
|
||
|
end
|
||
|
return existingOutfitCode.code
|
||
|
end)
|
||
|
|
||
|
lib.callback.register("illenium-appearance:server:importOutfitCode", function(source, outfitName, outfitCode)
|
||
|
local citizenID = Framework.GetPlayerID(source)
|
||
|
local existingOutfitCode = Database.PlayerOutfitCodes.GetByCode(outfitCode)
|
||
|
if not existingOutfitCode then
|
||
|
return nil
|
||
|
end
|
||
|
|
||
|
local playerOutfit = Database.PlayerOutfits.GetByID(existingOutfitCode.outfitid)
|
||
|
if not playerOutfit then
|
||
|
return
|
||
|
end
|
||
|
|
||
|
if playerOutfit.citizenid == citizenID then return end -- Validation when someone tried to duplicate own outfit
|
||
|
if Database.PlayerOutfits.GetByOutfit(outfitName, citizenID) then return end -- Validation duplicate outfit name, if validate on local id, someone can "spam error" server-sided
|
||
|
|
||
|
local id = Database.PlayerOutfits.Add(citizenID, outfitName, playerOutfit.model, playerOutfit.components, playerOutfit.props)
|
||
|
|
||
|
if not id then
|
||
|
print("Something went wrong while importing the outfit")
|
||
|
return
|
||
|
end
|
||
|
|
||
|
outfitCache[citizenID][#outfitCache[citizenID] + 1] = {
|
||
|
id = id,
|
||
|
name = outfitName,
|
||
|
model = playerOutfit.model,
|
||
|
components = json.decode(playerOutfit.components),
|
||
|
props = json.decode(playerOutfit.props)
|
||
|
}
|
||
|
|
||
|
return true
|
||
|
end)
|
||
|
|
||
|
lib.callback.register("illenium-appearance:server:getAppearance", function(source, model)
|
||
|
local citizenID = Framework.GetPlayerID(source)
|
||
|
return Framework.GetAppearance(citizenID, model)
|
||
|
end)
|
||
|
|
||
|
lib.callback.register("illenium-appearance:server:hasMoney", function(source, shopType)
|
||
|
local money = getMoneyForShop(shopType)
|
||
|
if Framework.HasMoney(source, "cash", money) or Framework.HasMoney(source, "bank", money) then
|
||
|
return true, money
|
||
|
else
|
||
|
return false, money
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
lib.callback.register("illenium-appearance:server:payForTattoo", function(source, tattoo)
|
||
|
local src = source
|
||
|
local cost = tattoo.cost or Config.TattooCost
|
||
|
|
||
|
if Framework.RemoveMoney(src, "cash", cost) or Framework.RemoveMoney(src, "bank", cost) then
|
||
|
lib.notify(src, {
|
||
|
title = _L("purchase.tattoo.success.title"),
|
||
|
description = string.format(_L("purchase.tattoo.success.description"), tattoo.label, cost),
|
||
|
type = "success",
|
||
|
position = Config.NotifyOptions.position
|
||
|
})
|
||
|
return true
|
||
|
else
|
||
|
lib.notify(src, {
|
||
|
title = _L("purchase.tattoo.failure.title"),
|
||
|
description = _L("purchase.tattoo.failure.description"),
|
||
|
type = "error",
|
||
|
position = Config.NotifyOptions.position
|
||
|
})
|
||
|
return false
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
lib.callback.register("illenium-appearance:server:getOutfits", function(source)
|
||
|
local citizenID = Framework.GetPlayerID(source)
|
||
|
if outfitCache[citizenID] == nil then
|
||
|
getOutfitsForPlayer(citizenID)
|
||
|
end
|
||
|
return outfitCache[citizenID]
|
||
|
end)
|
||
|
|
||
|
lib.callback.register("illenium-appearance:server:getManagementOutfits", function(source, mType, gender)
|
||
|
local job = Framework.GetJob(source)
|
||
|
if mType == "Gang" then
|
||
|
job = Framework.GetGang(source)
|
||
|
end
|
||
|
|
||
|
local grade = tonumber(job.grade.level)
|
||
|
local managementOutfits = {}
|
||
|
local result = Database.ManagementOutfits.GetAllByJob(mType, job.name, gender)
|
||
|
|
||
|
for i = 1, #result, 1 do
|
||
|
if grade >= result[i].minrank then
|
||
|
managementOutfits[#managementOutfits + 1] = {
|
||
|
id = result[i].id,
|
||
|
name = result[i].name,
|
||
|
model = result[i].model,
|
||
|
gender = result[i].gender,
|
||
|
components = json.decode(result[i].components),
|
||
|
props = json.decode(result[i].props)
|
||
|
}
|
||
|
end
|
||
|
end
|
||
|
return managementOutfits
|
||
|
end)
|
||
|
|
||
|
lib.callback.register("illenium-appearance:server:getUniform", function(source)
|
||
|
return uniformCache[Framework.GetPlayerID(source)]
|
||
|
end)
|
||
|
|
||
|
RegisterServerEvent("illenium-appearance:server:saveAppearance", function(appearance)
|
||
|
local src = source
|
||
|
local citizenID = Framework.GetPlayerID(src)
|
||
|
if appearance ~= nil then
|
||
|
Framework.SaveAppearance(appearance, citizenID)
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
RegisterServerEvent("illenium-appearance:server:chargeCustomer", function(shopType)
|
||
|
local label
|
||
|
local src = source
|
||
|
local money = getMoneyForShop(shopType)
|
||
|
if Framework.RemoveMoney(src, "cash", money) or Framework.RemoveMoney(src, "bank", money) then
|
||
|
if shopType == "clothing" then
|
||
|
label = "tøj"
|
||
|
elseif shopType == "barber" then
|
||
|
label = "hårklipning"
|
||
|
elseif shopType == "tattoo" then
|
||
|
label = "tatovering"
|
||
|
elseif shopType == "surgeon" then
|
||
|
label = "kirurgi"
|
||
|
end
|
||
|
|
||
|
lib.notify(src, {
|
||
|
title = _L("purchase.store.success.title"),
|
||
|
description = string.format(_L("purchase.store.success.description"), label, money),
|
||
|
type = "success",
|
||
|
position = Config.NotifyOptions.position
|
||
|
})
|
||
|
else
|
||
|
lib.notify(src, {
|
||
|
title = _L("purchase.store.failure.title"),
|
||
|
description = _L("purchase.store.failure.description"),
|
||
|
type = "error",
|
||
|
position = Config.NotifyOptions.position
|
||
|
})
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent("illenium-appearance:server:saveOutfit", function(name, model, components, props)
|
||
|
local src = source
|
||
|
local citizenID = Framework.GetPlayerID(src)
|
||
|
if outfitCache[citizenID] == nil then
|
||
|
getOutfitsForPlayer(citizenID)
|
||
|
end
|
||
|
if model and components and props then
|
||
|
local id = Database.PlayerOutfits.Add(citizenID, name, model, json.encode(components), json.encode(props))
|
||
|
if not id then
|
||
|
return
|
||
|
end
|
||
|
outfitCache[citizenID][#outfitCache[citizenID] + 1] = {
|
||
|
id = id,
|
||
|
name = name,
|
||
|
model = model,
|
||
|
components = components,
|
||
|
props = props
|
||
|
}
|
||
|
lib.notify(src, {
|
||
|
title = _L("outfits.save.success.title"),
|
||
|
description = string.format(_L("outfits.save.success.description"), name),
|
||
|
type = "success",
|
||
|
position = Config.NotifyOptions.position
|
||
|
})
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent("illenium-appearance:server:updateOutfit", function(id, model, components, props)
|
||
|
local src = source
|
||
|
local citizenID = Framework.GetPlayerID(src)
|
||
|
if outfitCache[citizenID] == nil then
|
||
|
getOutfitsForPlayer(citizenID)
|
||
|
end
|
||
|
if model and components and props then
|
||
|
if not Database.PlayerOutfits.Update(id, model, json.encode(components), json.encode(props)) then return end
|
||
|
local outfitName = ""
|
||
|
for i = 1, #outfitCache[citizenID], 1 do
|
||
|
local outfit = outfitCache[citizenID][i]
|
||
|
if outfit.id == id then
|
||
|
outfit.model = model
|
||
|
outfit.components = components
|
||
|
outfit.props = props
|
||
|
outfitName = outfit.name
|
||
|
break
|
||
|
end
|
||
|
end
|
||
|
lib.notify(src, {
|
||
|
title = _L("outfits.update.success.title"),
|
||
|
description = string.format(_L("outfits.update.success.description"), outfitName),
|
||
|
type = "success",
|
||
|
position = Config.NotifyOptions.position
|
||
|
})
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent("illenium-appearance:server:saveManagementOutfit", function(outfitData)
|
||
|
local src = source
|
||
|
local id = Database.ManagementOutfits.Add(outfitData)
|
||
|
if not id then
|
||
|
return
|
||
|
end
|
||
|
|
||
|
lib.notify(src, {
|
||
|
title = _L("outfits.save.success.title"),
|
||
|
description = string.format(_L("outfits.save.success.description"), outfitData.Name),
|
||
|
type = "success",
|
||
|
position = Config.NotifyOptions.position
|
||
|
})
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent("illenium-appearance:server:deleteManagementOutfit", function(id)
|
||
|
Database.ManagementOutfits.DeleteByID(id)
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent("illenium-appearance:server:syncUniform", function(uniform)
|
||
|
local src = source
|
||
|
uniformCache[Framework.GetPlayerID(src)] = uniform
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent("illenium-appearance:server:deleteOutfit", function(id)
|
||
|
local src = source
|
||
|
local citizenID = Framework.GetPlayerID(src)
|
||
|
Database.PlayerOutfitCodes.DeleteByOutfitID(id)
|
||
|
Database.PlayerOutfits.DeleteByID(id)
|
||
|
|
||
|
for k, v in ipairs(outfitCache[citizenID]) do
|
||
|
if v.id == id then
|
||
|
table.remove(outfitCache[citizenID], k)
|
||
|
break
|
||
|
end
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent("illenium-appearance:server:resetOutfitCache", function()
|
||
|
local src = source
|
||
|
local citizenID = Framework.GetPlayerID(src)
|
||
|
if citizenID then
|
||
|
outfitCache[citizenID] = nil
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent("illenium-appearance:server:ChangeRoutingBucket", function()
|
||
|
local src = source
|
||
|
SetPlayerRoutingBucket(src, src)
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent("illenium-appearance:server:ResetRoutingBucket", function()
|
||
|
local src = source
|
||
|
SetPlayerRoutingBucket(src, 0)
|
||
|
end)
|
||
|
|
||
|
if Config.EnablePedMenu then
|
||
|
lib.addCommand("pedmenu", {
|
||
|
help = _L("commands.pedmenu.title"),
|
||
|
params = {
|
||
|
{
|
||
|
name = "playerID",
|
||
|
type = "number",
|
||
|
help = "Target player's server id",
|
||
|
optional = true
|
||
|
},
|
||
|
},
|
||
|
restricted = Config.PedMenuGroup
|
||
|
}, function(source, args)
|
||
|
local target = source
|
||
|
if args.playerID then
|
||
|
local citizenID = Framework.GetPlayerID(args.playerID)
|
||
|
if citizenID then
|
||
|
target = args.playerID
|
||
|
else
|
||
|
lib.notify(source, {
|
||
|
title = _L("commands.pedmenu.failure.title"),
|
||
|
description = _L("commands.pedmenu.failure.description"),
|
||
|
type = "error",
|
||
|
position = Config.NotifyOptions.position
|
||
|
})
|
||
|
return
|
||
|
end
|
||
|
end
|
||
|
TriggerClientEvent("illenium-appearance:client:openClothingShopMenu", target, true)
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
if Config.EnableJobOutfitsCommand then
|
||
|
lib.addCommand("joboutfits", { help = _L("commands.joboutfits.title"), }, function(source)
|
||
|
TriggerClientEvent("illenium-apearance:client:outfitsCommand", source, true)
|
||
|
end)
|
||
|
|
||
|
lib.addCommand("gangoutfits", { help = _L("commands.gangoutfits.title"), }, function(source)
|
||
|
TriggerClientEvent("illenium-apearance:client:outfitsCommand", source)
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
lib.addCommand("reloadskin", { help = _L("commands.reloadskin.title") }, function(source)
|
||
|
TriggerClientEvent("illenium-appearance:client:reloadSkin", source)
|
||
|
end)
|
||
|
|
||
|
lib.addCommand("clearstuckprops", { help = _L("commands.clearstuckprops.title") }, function(source)
|
||
|
TriggerClientEvent("illenium-appearance:client:ClearStuckProps", source)
|
||
|
end)
|
||
|
|
||
|
lib.versionCheck("iLLeniumStudios/illenium-appearance")
|