feat: skin update

This commit is contained in:
2026-04-20 19:32:52 +08:00
parent b492dc99b6
commit f2e14f20f3
28 changed files with 1396 additions and 113 deletions
+62 -20
View File
@@ -18,6 +18,7 @@ function InitModule(ctx, logger, nk, initializer) {
initializer.registerRpc("admin_set_user_role", rpcAdminSetUserRole);
initializer.registerRpc("admin_list_users", rpcAdminListUsers);
initializer.registerRpc("admin_delete_users", rpcAdminDeleteUsers);
initializer.registerRpc("admin_topup_gold", rpcAdminTopupGold);
// User management RPCs
initializer.registerRpc("get_user_profile", rpcGetUserProfile);
@@ -52,6 +53,54 @@ function InitModule(ctx, logger, nk, initializer) {
var ADMIN_ROLES = ["admin", "moderator", "owner"];
// =============================================================================
// Shop Catalog Definitions
// =============================================================================
// To add a new item: append ONE entry to SHOP_CATALOG_DEFS.
// Fields:
// id (String) — must match item_id in game inventory + SkinManager
// name (String) — display name shown in shop
// category (String) — "head" | "costume" | "glove" | "accessory"
// gold (Number) — gold price (0 = not sold for gold)
// star (Number) — star price (0 = not sold for star)
// rarity (String) — "Common" | "Rare" | "Epic" | "Legendary"
// character (String) — (optional) which character the skin targets, e.g. "Oldpop"
// [BEGIN_SHOP_CATALOG_DEFS]
var SHOP_CATALOG_DEFS = [
// ── HEAD ────────────────────────────────────────────────────────────
{ id: "example-hat", name: "Example Hat", category: "head", gold: 0, star: 0, rarity: "Common", character: "Oldpop" },
// ── COSTUME ────────────────────────────────────────────────────────────
{ id: "oldpop-grey-pant", name: "Copper Grey Pant", category: "costume", gold: 200, star: 0, rarity: "Common", character: "Oldpop" },
{ id: "oldpop-clothing-original", name: "Copper Original Pants", category: "costume", gold: 0, star: 0, rarity: "Common", character: "Oldpop" },
// ── GLOVE ────────────────────────────────────────────────────────────
{ id: "example-gloves", name: "Example Gloves", category: "glove", gold: 150, star: 0, rarity: "Common", character: "Oldpop" },
// ── COSTUME ────────────────────────────────────────────────────────────
{ id: "oldpop-red-pant", name: "Copper Red Pant", category: "costume", gold: 200, star: 0, rarity: "Rare", character: "Oldpop" },
];
// [END_SHOP_CATALOG_DEFS]
/** Groups SHOP_CATALOG_DEFS by category for the shop RPC response. */
function buildShopCatalog() {
var catalog = {};
for (var i = 0; i < SHOP_CATALOG_DEFS.length; i++) {
var def = SHOP_CATALOG_DEFS[i];
var cat = def.category;
if (!catalog[cat]) catalog[cat] = [];
var entry = {
id: def.id,
name: def.name,
gold: def.gold || 0,
star: def.star || 0,
rarity: def.rarity || "Common"
};
if (def.character) entry.character = def.character;
catalog[cat].push(entry);
}
return catalog;
}
function isAdmin(ctx, nk) {
if (!ctx.userId) return false;
@@ -388,26 +437,19 @@ function rpcAdminSetUserRole(ctx, logger, nk, payload) {
function rpcGetShopCatalog(ctx, logger, nk, payload) {
if (!ctx.userId) throw new Error("Not authenticated");
// We could read this from storage, but for now we hardcode it to keep it simple and authoritative
var catalog = {
"head": [
{"id": "head_hat1", "name": "Cap", "gold": 100, "star": 0},
{"id": "head_crown", "name": "Crown", "gold": 0, "star": 50}
],
"costume": [
{"id": "costume_red", "name": "Red Suit", "gold": 200, "star": 0},
{"id": "costume_gold", "name": "Gold Suit", "gold": 0, "star": 100}
],
"glove": [
{"id": "glove_leather", "name": "Leather Gloves", "gold": 50, "star": 0}
],
"accessory": [
{"id": "acc_glasses", "name": "Sunglasses", "gold": 80, "star": 0}
]
};
return JSON.stringify({ catalog: catalog });
return JSON.stringify({ catalog: buildShopCatalog() });
}
function rpcAdminTopupGold(ctx, logger, nk, payload) {
requireAdmin(ctx, nk);
try {
nk.walletUpdate(ctx.userId, { "gold": 999999 }, {}, true);
logger.info("Admin gold top-up applied for user " + ctx.userId);
return JSON.stringify({ success: true, gold_added: 999999 });
} catch (e) {
logger.error("Top-up failed: " + e);
throw new Error("Top-up failed: " + e);
}
}
function rpcBuyCurrency(ctx, logger, nk, payload) {