// Brass & Sigil — admin commands (/bns admin ...) // // Diagnostic + maintenance commands for OPs. Players without OP level // (>= 2) get a permission-denied response from the command framework. // // Subcommand summary: // /bns admin info state of the calling player // /bns admin waystone-count read stored count // /bns admin waystone-set override stored count // /bns admin reset-welcome clear bnsWelcomeGranted flag // so the welcome grant fires again // // Adding new subcommands: follow the same `Commands.literal(...) // .then(...)` pattern below. Keep handlers cheap -- these are only run // on operator action so performance isn't critical, but make them // readable. ServerEvents.commandRegistry(event => { const { commands: Commands, arguments: Arguments } = event; const bnsAdmin = Commands.literal('bns') .then(Commands.literal('admin') .requires(src => src.hasPermission(2)) // /bns admin info .then(Commands.literal('info').executes(ctx => { const player = ctx.source.player; if (!player) { ctx.source.sendSystemMessage(Text.red('Run from a player context.')); return 0; } const data = player.persistentData; const lines = [ `Player: ${player.username} (${player.uuid})`, `bnsWaystoneCount = ${data.getInt('bnsWaystoneCount')}`, `bnsWelcomeGranted = ${data.getBoolean('bnsWelcomeGranted')}`, ]; lines.forEach(line => ctx.source.sendSystemMessage(Text.aqua(line))); console.info(`[bns/admin] info: ${player.username} -> ${JSON.stringify({ waystones: data.getInt('bnsWaystoneCount'), welcomed: data.getBoolean('bnsWelcomeGranted'), })}`); return 1; })) // /bns admin waystone-count .then(Commands.literal('waystone-count') .then(Commands.argument('target', Arguments.PLAYER.create(event)) .executes(ctx => { const target = Arguments.PLAYER.getResult(ctx, 'target'); const count = target.persistentData.getInt('bnsWaystoneCount'); ctx.source.sendSystemMessage(Text.aqua( `${target.username} has bnsWaystoneCount = ${count}` )); return 1; }))) // /bns admin waystone-set // (Argument-bounds aren't exposed via KubeJS's wrapper, so we // validate the range inside the handler instead.) .then(Commands.literal('waystone-set') .then(Commands.argument('target', Arguments.PLAYER.create(event)) .then(Commands.argument('count', Arguments.INTEGER.create(event)) .executes(ctx => { const target = Arguments.PLAYER.getResult(ctx, 'target'); const count = Arguments.INTEGER.getResult(ctx, 'count'); if (count < 0 || count > 1000) { ctx.source.sendSystemMessage(Text.red( `count must be 0..1000 (got ${count})` )); return 0; } target.persistentData.putInt('bnsWaystoneCount', count); ctx.source.sendSystemMessage(Text.gold( `Set ${target.username}'s bnsWaystoneCount = ${count}` )); console.info(`[bns/admin] waystone-set: ${target.username} -> ${count}`); return 1; })))) // /bns admin reset-welcome .then(Commands.literal('reset-welcome') .then(Commands.argument('target', Arguments.PLAYER.create(event)) .executes(ctx => { const target = Arguments.PLAYER.getResult(ctx, 'target'); target.persistentData.putBoolean('bnsWelcomeGranted', false); ctx.source.sendSystemMessage(Text.gold( `Cleared bnsWelcomeGranted for ${target.username}. ` + `They'll get the welcome packet again on next login.` )); console.info(`[bns/admin] reset-welcome: ${target.username}`); return 1; }))) ); event.register(bnsAdmin); });