pack: KubeJS tidying + admin commands, bump to 0.20.0
Tidying pass on the KubeJS suite before plot system V1 lands. Sets up
the file structure + conventions + diagnostics so the larger plot
system has a clean foundation.
Changes:
1. NEW kubejs/README.md
File layout doc + conventions: logging prefix [bns/<module>],
persistent-data key naming (bns* prefix), one concern per file,
performance discipline (O(1) lookups, no polling).
2. Split economy_policy.js -> recipes_waystones.js + recipes_numismatics.js
Single-concern files. recipes_waystones removes ALL waystones
crafting (welcome.js distributes the only allowed waystone instead).
recipes_numismatics removes the 5 coin-denomination crafts.
3. NEW kubejs/server_scripts/bns_admin.js
/bns admin subcommands for OP diagnostics:
- info calling player's flags+counts
- waystone-count <player> read stored count
- waystone-set <player> <n> override stored count
- reset-welcome <player> clear bnsWelcomeGranted -- replays
the welcome grant on next login
Registered via ServerEvents.commandRegistry with Brigadier tree,
permission level 2 (OP). No performance cost (operator-triggered only).
4. Logging added to waystones_policy.js + welcome.js
Every action prints `[bns/<module>] ...` so server logs can be
filtered with `journalctl ... | grep '\[bns/'`.
Performance discipline applied:
- All event-handler lookups use Set.has (O(1)), not Array.includes
- No periodic tick polling anywhere
- No network calls in event handlers
- console.info is cheap (no string format unless logged)
Bumps to 0.20.0. Plot system V1 follows in v0.21.x as a separate
multi-file submodule under server_scripts/plots/.
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
// 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 <player> read stored count
|
||||
// /bns admin waystone-set <player> <n> override stored count
|
||||
// /bns admin reset-welcome <player> 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 <player>
|
||||
.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 <player> <n>
|
||||
.then(Commands.literal('waystone-set')
|
||||
.then(Commands.argument('target', Arguments.PLAYER.create(event))
|
||||
.then(Commands.argument('count', Arguments.INTEGER.create(event, 0, 1000))
|
||||
.executes(ctx => {
|
||||
const target = Arguments.PLAYER.getResult(ctx, 'target');
|
||||
const count = Arguments.INTEGER.getResult(ctx, 'count');
|
||||
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 <player>
|
||||
.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);
|
||||
});
|
||||
Reference in New Issue
Block a user