Add player names and account deletion

This commit is contained in:
Emporex committed 2026-10-04 08:09:52 +02:00
1 parent 32594c7f81
commit 1b5b8dc0a4
10 files changed
+299 -11

No files matched your search

+32 -2
View File
@@ -1,4 +1,4 @@
var GAME_VERSION = "0.21";
var GAME_VERSION = "0.22";
var MAP_COUNT = 3;
var DIFFICULTY_COUNT = 3;
var VALID_MODES = ["mission", "endless", "coop_ai", "coop_online"];
@@ -48,6 +48,33 @@ function rpcSubmitRun(ctx, logger, nk, payload) {
return JSON.stringify({accepted:true,leaderboard_id:id,rank:record.rank,score:Number(record.score),wave:wave});
}
function normalizeDisplayName(value) {
return String(value || "").trim().replace(/\s+/g, " ").substring(0, 20);
}
function validateDisplayName(value) {
var name = normalizeDisplayName(value);
if (name.length < 3) return "name_too_short";
if (name.length > 20) return "name_too_long";
if (!/^[A-Za-z0-9 ÄÖÜäöüß_-]+$/.test(name)) return "invalid_characters";
var reserved = ["ADMIN","ADMINISTRATOR","GERGAMES","MODERATOR","SUPPORT","SYSTEM"];
if (reserved.indexOf(name.toUpperCase()) >= 0) return "reserved_name";
return "";
}
function rpcUpdateDisplayName(ctx, logger, nk, payload) {
if (!ctx.userId) throw new Error("authentication required");
var request;
try { request = JSON.parse(payload || "{}"); } catch (error) { return JSON.stringify({accepted:false,error:"invalid_json"}); }
var name = normalizeDisplayName(request.display_name), errorCode = validateDisplayName(name);
if (errorCode) return JSON.stringify({accepted:false,error:errorCode});
nk.accountUpdateId(ctx.userId, null, name, null, null, null, null, null);
return JSON.stringify({accepted:true,display_name:name});
}
function rpcDeleteAccount(ctx, logger, nk, payload) {
if (!ctx.userId) throw new Error("authentication required");
nk.accountDeleteId(ctx.userId, false);
return JSON.stringify({accepted:true});
}
function normalizeRoomCode(value) {
return String(value || "").toUpperCase().replace(/[^A-Z0-9]/g, "").slice(0, 6);
}
@@ -232,7 +259,8 @@ function handleCommand(nk,dispatcher,state,message) {
else if (message.opCode===OP_START_WAVE) changed=startWave(state);
else if (message.opCode===OP_READY&&!state.started) {
state.ready[message.sender.userId]=payload.ready!==false;
var name=String(payload.name||message.sender.username||"PILOT").trim().substring(0,24);
var requestedName=normalizeDisplayName(payload.name||message.sender.username||"PILOT");
var name=validateDisplayName(requestedName) ? "PILOT" : requestedName;
state.players[message.sender.userId]={name:name||"PILOT"};
var ids=Object.keys(state.slots),allReady=ids.length===2&&Object.keys(state.presences).length===2;
for (var i=0;i<ids.length;i++) if (!state.ready[ids[i]]||state.presences[ids[i]]===undefined) allReady=false;
@@ -259,6 +287,8 @@ function InitModule(ctx,logger,nk,initializer) {
for (var mode=0;mode<VALID_MODES.length;mode++) for (var map=0;map<MAP_COUNT;map++) for (var difficulty=0;difficulty<DIFFICULTY_COUNT;difficulty++) nk.leaderboardCreate(leaderboardId(map,difficulty,VALID_MODES[mode]),true,"desc","best",null,{game:"void_bastion"});
initializer.registerRpc("server_info",rpcServerInfo);
initializer.registerRpc("submit_run",rpcSubmitRun);
initializer.registerRpc("update_display_name",rpcUpdateDisplayName);
initializer.registerRpc("delete_account",rpcDeleteAccount);
initializer.registerRpc("create_private_room",rpcCreatePrivateRoom);
initializer.registerRpc("join_private_room",rpcJoinPrivateRoom);
initializer.registerMatchmakerMatched(matchmakerMatched);
+14
View File
@@ -24,6 +24,20 @@ const logger = { info() {} };
const presenceA = { userId: "pilot-a", sessionId: "a", username: "Pilot A" };
const presenceB = { userId: "pilot-b", sessionId: "b", username: "Pilot B" };
let updatedAccount = null;
let deletedAccount = null;
const accountNk = {
accountUpdateId(...args) { updatedAccount = args; },
accountDeleteId(...args) { deletedAccount = args; }
};
assert.deepStrictEqual(JSON.parse(context.rpcUpdateDisplayName({ userId: "pilot-a" }, logger, accountNk, JSON.stringify({ display_name: " Kommandant Ägir " }))), { accepted: true, display_name: "Kommandant Ägir" });
assert.strictEqual(updatedAccount[0], "pilot-a");
assert.strictEqual(updatedAccount[2], "Kommandant Ägir");
assert.strictEqual(JSON.parse(context.rpcUpdateDisplayName({ userId: "pilot-a" }, logger, accountNk, JSON.stringify({ display_name: "ADMIN" }))).accepted, false);
assert.strictEqual(JSON.parse(context.rpcUpdateDisplayName({ userId: "pilot-a" }, logger, accountNk, JSON.stringify({ display_name: "A!" }))).accepted, false);
assert.deepStrictEqual(JSON.parse(context.rpcDeleteAccount({ userId: "pilot-a" }, logger, accountNk, "{}")), { accepted: true });
assert.deepStrictEqual(deletedAccount, ["pilot-a", false]);
let state = context.matchInit({}, logger, nk, { difficulty: 1 }).state;
state = context.matchJoin({}, logger, nk, dispatcher, 1, state, [presenceA]).state;
state = context.matchJoin({}, logger, nk, dispatcher, 2, state, [presenceB]).state;