Removed the 'unique_active_skin' database trigger from setupDatabase and updated setSkin in userRepository to handle skin selection logic in application code. This change centralizes the logic for ensuring only one active skin per user, improving maintainability and error handling.
784 lines
24 KiB
JavaScript
784 lines
24 KiB
JavaScript
const utils = require("../modules/utils")
|
|
const crypto = require("node:crypto")
|
|
const database = require("../modules/database")
|
|
const { DefaultError } = require("../errors/errors")
|
|
|
|
async function getSkins(uuid) {
|
|
try {
|
|
const sql = `
|
|
SELECT t.uuid as textureUuid, t.hash, t.url, ps.variant, ps.isSelected
|
|
FROM playersSkins ps
|
|
JOIN textures t ON ps.assetHash = t.hash
|
|
WHERE ps.playerUuid = ?
|
|
`
|
|
const rows = await database.query(sql, [uuid])
|
|
return rows
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function getCapes(uuid) {
|
|
try {
|
|
const sql = `
|
|
SELECT t.uuid as textureUuid, t.hash, t.url, t.alias, pc.isSelected
|
|
FROM playersCapes pc
|
|
JOIN textures t ON pc.assetHash = t.hash
|
|
WHERE pc.playerUuid = ?
|
|
`
|
|
const rows = await database.query(sql, [uuid])
|
|
return rows
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function addPropertyToPlayer(key, value, uuid) {
|
|
try {
|
|
const sql = `
|
|
INSERT INTO playersProperties (name, value, uuid)
|
|
VALUES (?, ?, ?)
|
|
ON DUPLICATE KEY UPDATE value = VALUES(value)
|
|
`
|
|
const result = await database.query(sql, [key, value, uuid])
|
|
|
|
if (result.affectedRows > 0) {
|
|
return { code: 200, key, value, uuid }
|
|
} else {
|
|
throw new DefaultError(500, "Please contact an administrator.", "InternalServerError")
|
|
}
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function deletePropertyToPlayer(key, uuid) {
|
|
try {
|
|
const sql = `DELETE FROM playersProperties WHERE name = ? AND uuid = ?`
|
|
const result = await database.query(sql, [key, uuid])
|
|
|
|
if (result.affectedRows > 0) {
|
|
return { code: 200, key, uuid }
|
|
} else {
|
|
throw new DefaultError(500, "Property not found for this user/key combination.")
|
|
}
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function updatePropertyToPlayer(key, value, uuid) {
|
|
try {
|
|
const sql = `UPDATE playersProperties SET value = ? WHERE name = ? AND uuid = ?`
|
|
const result = await database.query(sql, [value, key, uuid])
|
|
if (result.affectedRows > 0) {
|
|
return { code: 200, key, value, uuid }
|
|
} else {
|
|
throw new DefaultError(404, "Property not found for this user/key combination")
|
|
}
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function getPlayerProperties(uuid) {
|
|
try {
|
|
const sql = `SELECT * FROM playersProperties WHERE uuid = ?`
|
|
const rows = await database.query(sql, [uuid])
|
|
if (rows.length === 0) {
|
|
throw new DefaultError(404, "Properties not found for this user")
|
|
}
|
|
return {
|
|
code: 200,
|
|
properties: rows.map(property => ({ name: property.name, value: property.value }))
|
|
}
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function getPlayerProperty(key, uuid) {
|
|
try {
|
|
const sql = `SELECT * FROM playersProperties WHERE name = ? AND uuid = ?`
|
|
const rows = await database.query(sql, [key, uuid])
|
|
const property = rows[0]
|
|
if (!property) {
|
|
throw new DefaultError(404, "Property not found for this user/key combination")
|
|
}
|
|
return { code: 200, property }
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function getPlayerPropertyByValue(key, value) {
|
|
try {
|
|
const sql = `SELECT * FROM playersProperties WHERE name = ? AND value = ?`
|
|
const rows = await database.query(sql, [key, value])
|
|
const property = rows[0]
|
|
|
|
if (!property) {
|
|
throw new DefaultError(404, "No property found with this value for the specified key")
|
|
}
|
|
|
|
return {
|
|
code: 200,
|
|
property: {
|
|
name: property.name,
|
|
value: property.value,
|
|
uuid: property.uuid
|
|
}
|
|
}
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function getPlayerSettingsSchema() {
|
|
const RAW_SCHEMA_CACHE = {
|
|
privileges: {},
|
|
preferences: {}
|
|
}
|
|
try {
|
|
const privilegesRows = await database.query("DESCRIBE playersPrivileges")
|
|
const preferencesRows = await database.query("DESCRIBE playersPreferences")
|
|
RAW_SCHEMA_CACHE.privileges = privilegesRows.map(c => c.Field).filter(n => n !== "uuid")
|
|
RAW_SCHEMA_CACHE.preferences = preferencesRows.map(c => c.Field).filter(n => n !== "uuid")
|
|
return RAW_SCHEMA_CACHE
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function updatePlayerPreferences(uuid, updates) {
|
|
try {
|
|
const keys = Object.keys(updates)
|
|
if (keys.length === 0) {
|
|
throw new DefaultError(400, "No fields provided for update.")
|
|
}
|
|
const setClause = keys.map(key => `\`${key}\` = ?`).join(', ')
|
|
const sql = `UPDATE playersPreferences SET ${setClause} WHERE uuid = ?`
|
|
const values = keys.map(key => updates[key])
|
|
values.push(uuid)
|
|
const result = await database.query(sql, values)
|
|
if (result.affectedRows > 0) {
|
|
return {
|
|
code: 200,
|
|
message: "Preferences updated successfully."
|
|
}
|
|
} else {
|
|
throw new DefaultError(404, "Player preferences not found or no changes made.")
|
|
}
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function getPlayerPreferences(uuid) {
|
|
try {
|
|
const sql = `SELECT profanityFilter FROM playersPreferences WHERE uuid = ?`
|
|
const rows = await database.query(sql, [uuid])
|
|
const data = rows[0]
|
|
|
|
if (data) {
|
|
return {
|
|
code: 200,
|
|
message: "Preferences retrieved successfully.",
|
|
data: data
|
|
}
|
|
} else {
|
|
throw new DefaultError(404, "Preferences not found for this UUID.")
|
|
}
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function getPlayerPrivileges(uuid) {
|
|
try {
|
|
const sql = `
|
|
SELECT onlineChat, multiplayerServer, multiplayerRealms, telemetry
|
|
FROM playersPrivileges
|
|
WHERE uuid = ?
|
|
`
|
|
const rows = await database.query(sql, [uuid])
|
|
const data = rows[0]
|
|
if (data) {
|
|
return {
|
|
code: 200,
|
|
message: "Privileges retrieved successfully.",
|
|
data: data
|
|
}
|
|
} else {
|
|
throw new DefaultError(404, "Privileges not found for this UUID.")
|
|
}
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function updatePlayerPrivileges(uuid, updates) {
|
|
try {
|
|
const keys = Object.keys(updates)
|
|
if (keys.length === 0) {
|
|
throw new DefaultError(404, "No fields provided for update.")
|
|
}
|
|
const setClause = keys.map(key => `\`${key}\` = ?`).join(', ')
|
|
const sql = `UPDATE playersPrivileges SET ${setClause} WHERE uuid = ?`
|
|
const values = keys.map(key => updates[key])
|
|
values.push(uuid)
|
|
const result = await database.query(sql, values)
|
|
if (result.affectedRows > 0) {
|
|
return {
|
|
code: 200,
|
|
message: "Privileges updated successfully."
|
|
}
|
|
} else {
|
|
throw new DefaultError(404, "Player privileges not found or no changes made.")
|
|
}
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function banUser(uuid, { reasonKey, reasonMessage, expires = null }) {
|
|
try {
|
|
if (!uuid || !reasonKey) {
|
|
throw new DefaultError(400, "Missing uuid or reasonKey.")
|
|
}
|
|
|
|
let reasonId
|
|
const reasonRows = await database.query("SELECT id FROM banReasons WHERE reasonKey = ?", [reasonKey])
|
|
if (reasonRows.length > 0) {
|
|
reasonId = reasonRows[0].id
|
|
} else {
|
|
const insertReason = await database.query("INSERT INTO banReasons (reasonKey) VALUES (?)", [reasonKey])
|
|
reasonId = insertReason.insertId
|
|
}
|
|
|
|
const banId = crypto.randomUUID()
|
|
const insertSql = `
|
|
INSERT INTO bans (banId, uuid, reason, reasonMessage, expires)
|
|
VALUES (?, ?, ?, ?, ?)
|
|
`
|
|
const result = await database.query(insertSql, [banId, uuid, reasonId, reasonMessage || "Banned by operator", expires])
|
|
|
|
if (result.affectedRows > 0) {
|
|
return {
|
|
code: 200,
|
|
message: "User successfully banned.",
|
|
banId: banId
|
|
}
|
|
} else {
|
|
throw new DefaultError(500, "Failed to ban user.")
|
|
}
|
|
|
|
} catch (error) {
|
|
if (error instanceof DefaultError) throw error
|
|
if (error.code === "ER_NO_REFERENCED_ROW_2" || error.toString().includes("foreign key constraint")) {
|
|
throw new DefaultError(404, "User not found (cannot ban a ghost).")
|
|
}
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function unbanUser(uuid) {
|
|
try {
|
|
if (!uuid) {
|
|
throw new DefaultError(400, "Missing uuid.")
|
|
}
|
|
const sql = "DELETE FROM bans WHERE uuid = ?"
|
|
const result = await database.query(sql, [uuid])
|
|
if (result.affectedRows > 0) {
|
|
return {
|
|
code: 200,
|
|
message: "User successfully unbanned.",
|
|
count: result.affectedRows
|
|
}
|
|
} else {
|
|
throw new DefaultError(404, "User was not banned.")
|
|
}
|
|
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function getPlayerBans(uuid) {
|
|
try {
|
|
const sql = `
|
|
SELECT
|
|
b.banId,
|
|
b.expires,
|
|
b.reasonMessage,
|
|
r.reasonKey as reason
|
|
FROM bans b
|
|
JOIN banReasons r ON b.reason = r.id
|
|
WHERE b.uuid = ?
|
|
ORDER BY b.expires ASC
|
|
`
|
|
const rows = await database.query(sql, [uuid])
|
|
|
|
if (rows.length > 0) {
|
|
return { code: 200, bans: rows }
|
|
} else {
|
|
return { code: 204 }
|
|
}
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function changeUsername(uuid, newName) {
|
|
try {
|
|
const sql = "UPDATE players SET username = ? WHERE uuid = ?"
|
|
const result = await database.query(sql, [newName, uuid])
|
|
if (result.affectedRows > 0) {
|
|
return { code: 200, message: "Username changed successfully" }
|
|
} else {
|
|
throw new DefaultError(404, "User not found")
|
|
}
|
|
} catch (error) {
|
|
if (error instanceof DefaultError) throw error
|
|
if (error.code === "ER_DUP_ENTRY" || error.errno === 1062) {
|
|
throw new DefaultError(409, "Username already taken", "ForbiddenOperationException")
|
|
}
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function createTexture(uuid, hash, type, url, alias) {
|
|
try {
|
|
const sql = `
|
|
INSERT INTO textures (uuid, hash, type, url, alias)
|
|
VALUES (?, ?, ?, ?, ?)
|
|
`
|
|
await database.query(sql, [uuid, hash, type, url, alias])
|
|
return true
|
|
} catch (error) {
|
|
if (error.code === 'ER_DUP_ENTRY') {
|
|
return false
|
|
}
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
|
|
async function getTextureByUuid(textureUuid) {
|
|
try {
|
|
const sql = "SELECT hash FROM textures WHERE uuid = ?"
|
|
const rows = await database.query(sql, [textureUuid])
|
|
return rows[0] || null
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function getTextureByHash(hash) {
|
|
try {
|
|
const sql = "SELECT uuid FROM textures WHERE hash = ?"
|
|
const rows = await database.query(sql, [hash])
|
|
return rows[0]
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function resetSkin(uuid, hash, variant) {
|
|
try {
|
|
const insertSql = `
|
|
INSERT IGNORE INTO playersSkins (playerUuid, assetHash, variant, isSelected)
|
|
VALUES (?, ?, ?, 0)
|
|
`
|
|
await database.query(insertSql, [uuid, hash, variant])
|
|
const updateSql = `
|
|
UPDATE playersSkins
|
|
SET isSelected = (assetHash = ?)
|
|
WHERE playerUuid = ?
|
|
`
|
|
await database.query(updateSql, [hash, uuid])
|
|
return { code: 200 }
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function hideCape(uuid) {
|
|
try {
|
|
const sql = "UPDATE playersCapes SET isSelected = 0 WHERE playerUuid = ?"
|
|
await database.query(sql, [uuid])
|
|
return { code: 200 }
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function showCape(uuid, hash) {
|
|
try {
|
|
await database.query(
|
|
"UPDATE playersCapes SET isSelected = 0 WHERE playerUuid = ?",
|
|
[uuid]
|
|
)
|
|
|
|
const result = await database.query(
|
|
"UPDATE playersCapes SET isSelected = 1 WHERE playerUuid = ? AND assetHash = ?",
|
|
[uuid, hash]
|
|
)
|
|
|
|
const affectedRows = Array.isArray(result) ? result[0].affectedRows : result.affectedRows
|
|
|
|
return { code: 200, changed: affectedRows > 0 }
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function checkCapeOwnership(uuid, hash) {
|
|
try {
|
|
const sql = "SELECT 1 FROM playersCapes WHERE playerUuid = ? AND assetHash = ?"
|
|
const rows = await database.query(sql, [uuid, hash])
|
|
return rows.length > 0
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function getPlayerMeta(uuid) {
|
|
try {
|
|
const sql = `SELECT createdAt, nameChangeAllowed FROM players WHERE uuid = ?`
|
|
const rows = await database.query(sql, [uuid])
|
|
return rows[0]
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function getLastNameChange(uuid) {
|
|
try {
|
|
const sql = `
|
|
SELECT changedAt
|
|
FROM uuidToNameHistory
|
|
WHERE uuid = ? AND changedAt IS NOT NULL
|
|
ORDER BY changedAt DESC
|
|
LIMIT 1
|
|
`
|
|
const rows = await database.query(sql, [uuid])
|
|
return rows[0]
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function getPlayerCertificate(uuid) {
|
|
try {
|
|
const sql = "SELECT * FROM playerCertificates WHERE uuid = ?"
|
|
const rows = await database.query(sql, [uuid])
|
|
return rows[0]
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function savePlayerCertificate(uuid, privateKey, publicKey, signatureV2, expiresAt, refreshedAfter) {
|
|
try {
|
|
const sql = `
|
|
REPLACE INTO playerCertificates
|
|
(uuid, privateKey, publicKey, publicKeySignatureV2, expiresAt, refreshedAfter)
|
|
VALUES (?, ?, ?, ?, ?, ?)
|
|
`
|
|
const result = await database.query(sql, [uuid, privateKey, publicKey, signatureV2, expiresAt, refreshedAfter])
|
|
return result.affectedRows > 0
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function deleteExpiredCertificates(isoDate) {
|
|
try {
|
|
const sql = "DELETE FROM playerCertificates WHERE expiresAt < ?"
|
|
const result = await database.query(sql, [isoDate])
|
|
return result.affectedRows
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function addProfileAction(uuid, actionCode) {
|
|
try {
|
|
const cleanUuid = uuid.replace(/-/g, "")
|
|
const sql = "INSERT IGNORE INTO playerProfileActions (uuid, action) VALUES (?, ?)"
|
|
const result = await database.query(sql, [cleanUuid, actionCode])
|
|
return result.affectedRows > 0
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function removeProfileAction(uuid, actionCode) {
|
|
try {
|
|
const cleanUuid = uuid.replace(/-/g, "")
|
|
const sql = "DELETE FROM playerProfileActions WHERE uuid = ? AND action = ?"
|
|
const result = await database.query(sql, [cleanUuid, actionCode])
|
|
return result.affectedRows
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function getPlayerActions(uuid) {
|
|
try {
|
|
const cleanUuid = uuid.replace(/-/g, "")
|
|
const sql = "SELECT action FROM playerProfileActions WHERE uuid = ?"
|
|
const rows = await database.query(sql, [cleanUuid])
|
|
return rows.map(r => r.action)
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function clearAllPlayerActions(uuid) {
|
|
try {
|
|
const cleanUuid = uuid.replace(/-/g, "")
|
|
const sql = "DELETE FROM playerProfileActions WHERE uuid = ?"
|
|
const result = await database.query(sql, [cleanUuid])
|
|
return result.affectedRows
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function blockPlayer(blockerUuid, blockedUuid) {
|
|
try {
|
|
const sql = `INSERT IGNORE INTO playersBlockslist (blockerUuid, blockedUuid) VALUES (?, ?)`
|
|
const result = await database.query(sql, [blockerUuid, blockedUuid])
|
|
return result.affectedRows > 0
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function unblockPlayer(blockerUuid, blockedUuid) {
|
|
try {
|
|
const sql = `DELETE FROM playersBlockslist WHERE blockerUuid = ? AND blockedUuid = ?`
|
|
const result = await database.query(sql, [blockerUuid, blockedUuid])
|
|
return result.affectedRows > 0
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function getBlockedUuids(blockerUuid) {
|
|
try {
|
|
const sql = `SELECT blockedUuid FROM playersBlockslist WHERE blockerUuid = ?`
|
|
const rows = await database.query(sql, [blockerUuid])
|
|
return rows.map(r => r.blockedUuid)
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function isBlocked(blockerUuid, targetUuid) {
|
|
try {
|
|
const sql = `SELECT 1 FROM playersBlockslist WHERE blockerUuid = ? AND blockedUuid = ? LIMIT 1`
|
|
const rows = await database.query(sql, [blockerUuid, targetUuid])
|
|
return rows.length > 0
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function getUsersByNames(usernames) {
|
|
try {
|
|
if (!usernames || usernames.length === 0) return []
|
|
const uniqueNames = [...new Set(usernames)]
|
|
|
|
const placeholders = uniqueNames.map(() => "?").join(", ")
|
|
const sql = `SELECT uuid, username FROM players WHERE username IN (${placeholders})`
|
|
|
|
const rows = await database.query(sql, uniqueNames)
|
|
return rows
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function getUuidAndUsername(username) {
|
|
try {
|
|
const sql = "SELECT uuid, username FROM players WHERE username = ?"
|
|
const rows = await database.query(sql, [username])
|
|
|
|
return rows[0] || null
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function getProfileByUsername(username) {
|
|
try {
|
|
const sql = "SELECT uuid, username FROM players WHERE username = ?"
|
|
const rows = await database.query(sql, [username])
|
|
return rows[0] || null
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function getProfileByHistory(username, isoDate) {
|
|
try {
|
|
const sql = `
|
|
SELECT uuid, username
|
|
FROM uuidToNameHistory
|
|
WHERE username = ?
|
|
AND (changedAt <= ? OR changedAt IS NULL)
|
|
ORDER BY changedAt DESC
|
|
LIMIT 1
|
|
`
|
|
const rows = await database.query(sql, [username, isoDate])
|
|
return rows[0] || null
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function getNameHistory(uuid) {
|
|
try {
|
|
const sql = `
|
|
SELECT username, changedAt
|
|
FROM uuidToNameHistory
|
|
WHERE uuid = ?
|
|
ORDER BY changedAt ASC
|
|
`
|
|
const rows = await database.query(sql, [uuid])
|
|
return rows
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function setSkin(uuid, hash, variant) {
|
|
try {
|
|
const resetSql = `UPDATE playersSkins SET isSelected = 0 WHERE playerUuid = ?`
|
|
await database.query(resetSql, [uuid])
|
|
|
|
const upsertSql = `
|
|
INSERT INTO playersSkins (playerUuid, assetHash, variant, isSelected)
|
|
VALUES (?, ?, ?, 1)
|
|
ON DUPLICATE KEY UPDATE isSelected = 1, variant = VALUES(variant)
|
|
`
|
|
await database.query(upsertSql, [uuid, hash, variant.toLowerCase()])
|
|
|
|
return true
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function updatePassword(uuid, hashedPassword) {
|
|
try {
|
|
const sql = "UPDATE players SET password = ? WHERE uuid = ?"
|
|
const result = await database.query(sql, [hashedPassword, uuid])
|
|
|
|
if (result.affectedRows > 0) {
|
|
return { code: 200, message: "Password updated successfully" }
|
|
} else {
|
|
throw new DefaultError(404, "User not found")
|
|
}
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function addCapeToPlayer(uuid, hash) {
|
|
try {
|
|
const sql = `
|
|
INSERT INTO playersCapes (playerUuid, assetHash, isSelected)
|
|
VALUES (?, ?, 0)
|
|
`
|
|
const result = await database.query(sql, [uuid, hash])
|
|
|
|
if (result.affectedRows > 0) {
|
|
return { code: 200, message: "Cape granted to the player." }
|
|
}
|
|
throw new DefaultError(500, "Error when assigning the cape.")
|
|
} catch (error) {
|
|
if (error.code === "ER_DUP_ENTRY") {
|
|
throw new DefaultError(409, "The player already possesses this cloak.")
|
|
}
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function removeCapeFromPlayer(uuid, hash) {
|
|
try {
|
|
const sql = "DELETE FROM playersCapes WHERE playerUuid = ? AND assetHash = ?"
|
|
const result = await database.query(sql, [uuid, hash])
|
|
|
|
if (result.affectedRows > 0) {
|
|
return { code: 200, message: "Cape removed from player." }
|
|
} else {
|
|
throw new DefaultError(404, "The player does not own this cloak.")
|
|
}
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function deleteTexture(hash) {
|
|
try {
|
|
const sql = "DELETE FROM textures WHERE hash = ?"
|
|
const result = await database.query(sql, [hash])
|
|
return result.affectedRows > 0
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
setSkin,
|
|
banUser,
|
|
getSkins,
|
|
getCapes,
|
|
showCape,
|
|
hideCape,
|
|
resetSkin,
|
|
isBlocked,
|
|
unbanUser,
|
|
blockPlayer,
|
|
deleteTexture,
|
|
createTexture,
|
|
getPlayerBans,
|
|
getPlayerMeta,
|
|
unblockPlayer,
|
|
changeUsername,
|
|
getNameHistory,
|
|
updatePassword,
|
|
getBlockedUuids,
|
|
getUsersByNames,
|
|
addCapeToPlayer,
|
|
getPlayerActions,
|
|
getTextureByUuid,
|
|
getTextureByHash,
|
|
addProfileAction,
|
|
getLastNameChange,
|
|
getPlayerProperty,
|
|
getUuidAndUsername,
|
|
checkCapeOwnership,
|
|
getProfileByHistory,
|
|
getPlayerPrivileges,
|
|
getPlayerProperties,
|
|
removeProfileAction,
|
|
addPropertyToPlayer,
|
|
removeCapeFromPlayer,
|
|
getProfileByUsername,
|
|
getPlayerPreferences,
|
|
getPlayerCertificate,
|
|
clearAllPlayerActions,
|
|
savePlayerCertificate,
|
|
updatePlayerPrivileges,
|
|
deletePropertyToPlayer,
|
|
updatePropertyToPlayer,
|
|
getPlayerSettingsSchema,
|
|
updatePlayerPreferences,
|
|
getPlayerPropertyByValue,
|
|
deleteExpiredCertificates,
|
|
} |