functions/properties.lua
Adapter de propriedades — casas, apartamentos, cofres e moradores.
Globals esperadas
getUserProperties(userId)getAvailableProperties()tryRemoveProperty(userId, propertyId)addProperty(userId, propertyId)getPropertyChest(propertyId)tryRemovePropertyChestItem(propertyId, item, amount, slot)getPropertyResidents(propertyId)tryRemovePropertyResident(propertyId, userId)resolveUserName(userId)— helper interno
Tabelas
core_homes—(user_id, name AS propertyId, owner BOOLEAN, residents JSON|CSV, vault, tax)core_residences—(name AS propertyId, intPrice AS price, interiorType AS type)mtg_containers— cofre da propriedade, key =propertyId.mtg_home_residents(opcional) —(home, user_id, role)quando o servidor separa moradores em tabela própria.
getUserProperties(userId)
functions/properties.lua·lua
function getUserProperties(userId)
local rows = exports.oxmysql:query_async([[
SELECT
ch.name AS propertyId,
cr.name AS label,
cr.intPrice AS preco,
cr.interiorType AS tipo,
ch.residents
FROM core_homes ch
JOIN core_residences cr ON cr.name = ch.name
WHERE ch.user_id = ? AND ch.owner = 1
]], { userId })
local out = {}
for _, p in ipairs(rows or {}) do
out[#out+1] = {
propertyId = p.propertyId,
label = p.label,
preco = p.preco,
tipo = p.tipo,
residentes = p.residents, -- chave extra: pode ser JSON inline
image = (Config.PropertyImageBaseUrl or "")..p.propertyId..".png"
}
end
return out
endgetAvailableProperties()
lua
function getAvailableProperties()
return exports.oxmysql:query_async([[
SELECT cr.name AS propertyId, cr.name AS label,
cr.intPrice AS price, cr.interiorType AS type
FROM core_residences cr
LEFT JOIN core_homes ch ON ch.name = cr.name AND ch.owner = 1
WHERE ch.name IS NULL
LIMIT 1500
]], {}) or {}
endgetPropertyResidents(propertyId)
Une o owner (de core_homes) com os residents extras (de mtg_home_residents se existir). Resolve nomes via vrp_user_identities.
lua
local function resolveUserName(userId)
local row = exports.oxmysql:query_async(
"SELECT firstname, name FROM vrp_user_identities WHERE user_id = ? LIMIT 1",
{ userId }
)
if not row or #row == 0 then return "user:"..userId end
return (row[1].name or "")..' '..(row[1].firstname or "")
end
function getPropertyResidents(propertyId)
local out = {}
local owner = exports.oxmysql:query_async(
"SELECT user_id FROM core_homes WHERE name = ? AND owner = 1 LIMIT 1",
{ propertyId }
)
if owner and owner[1] then
out[#out+1] = {
userId = owner[1].user_id,
name = resolveUserName(owner[1].user_id),
role = "owner"
}
end
local extras = exports.oxmysql:query_async(
"SELECT user_id FROM mtg_home_residents WHERE home = ?",
{ propertyId }
)
for _, r in ipairs(extras or {}) do
out[#out+1] = {
userId = r.user_id,
name = resolveUserName(r.user_id),
role = "resident"
}
end
return out
endCofre
A leitura é idêntica ao trunk da garagem — JSON dentro de mtg_containers.inventory. A remoção também usa o mesmo exports['mtg_inventory']:withdrawContainer().