@kradle/challenges-sdk 0.25.0 → 0.26.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -1
- package/LLM_README.md +36 -0
- package/README.md +30 -0
- package/dist/engine.d.ts +1 -0
- package/dist/engine.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/runtime/builder.d.ts.map +1 -1
- package/dist/runtime/builder.js +17 -0
- package/dist/runtime/builder.js.map +1 -1
- package/dist/runtime/commands.d.ts +70 -0
- package/dist/runtime/commands.d.ts.map +1 -0
- package/dist/runtime/commands.js +121 -0
- package/dist/runtime/commands.js.map +1 -0
- package/dist/runtime/reducer.d.ts +8 -0
- package/dist/runtime/reducer.d.ts.map +1 -1
- package/dist/runtime/reducer.js +75 -0
- package/dist/runtime/reducer.js.map +1 -1
- package/dist/runtime/types.d.ts +17 -0
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/runtime/wire.d.ts +40 -3
- package/dist/runtime/wire.d.ts.map +1 -1
- package/dist/runtime/wire.js +2 -0
- package/dist/runtime/wire.js.map +1 -1
- package/dist/test/harness.d.ts +4 -0
- package/dist/test/harness.d.ts.map +1 -1
- package/dist/test/harness.js +15 -0
- package/dist/test/harness.js.map +1 -1
- package/package.json +1 -1
package/dist/runtime/reducer.js
CHANGED
|
@@ -6,6 +6,7 @@ exports.parseBlockState = parseBlockState;
|
|
|
6
6
|
exports.blockSpecString = blockSpecString;
|
|
7
7
|
exports.splitBatches = splitBatches;
|
|
8
8
|
exports.createReducer = createReducer;
|
|
9
|
+
const commands_js_1 = require("./commands.js");
|
|
9
10
|
const dimensions_js_1 = require("./dimensions.js");
|
|
10
11
|
// The reducer: one locked definition, one `init()` per run, one `reduce(state,
|
|
11
12
|
// event)` per engine event. Everything a rule sees comes through a context
|
|
@@ -375,6 +376,7 @@ function createReducer(def) {
|
|
|
375
376
|
every: {},
|
|
376
377
|
timers: {},
|
|
377
378
|
nextGen: 0,
|
|
379
|
+
commandAccess: {},
|
|
378
380
|
players: {},
|
|
379
381
|
game: {},
|
|
380
382
|
votes: Object.fromEntries(voteIds.map((id) => [id, { open: false, round: 0, cast: {} }])),
|
|
@@ -1887,6 +1889,10 @@ function createReducer(def) {
|
|
|
1887
1889
|
return;
|
|
1888
1890
|
}
|
|
1889
1891
|
const missing = missingCapabilities(e.capabilities);
|
|
1892
|
+
if (def.customCommands.length)
|
|
1893
|
+
for (const c of ["custom_commands_v1", "agent_commands_v1"])
|
|
1894
|
+
if (!e.capabilities.includes(c))
|
|
1895
|
+
missing.push(c);
|
|
1890
1896
|
if (dimensions.length > 1 && !e.capabilities.includes("dimensions"))
|
|
1891
1897
|
missing.push("dimensions");
|
|
1892
1898
|
if (def.setup && !e.capabilities.includes("batch"))
|
|
@@ -2349,6 +2355,9 @@ function createReducer(def) {
|
|
|
2349
2355
|
});
|
|
2350
2356
|
break;
|
|
2351
2357
|
}
|
|
2358
|
+
case "challenge_command":
|
|
2359
|
+
customCommand(r, e);
|
|
2360
|
+
break;
|
|
2352
2361
|
case "custom": {
|
|
2353
2362
|
if (!playing())
|
|
2354
2363
|
return;
|
|
@@ -2357,6 +2366,67 @@ function createReducer(def) {
|
|
|
2357
2366
|
}
|
|
2358
2367
|
}
|
|
2359
2368
|
}
|
|
2369
|
+
function commandAvailable(r, command, player) {
|
|
2370
|
+
return (r.s.status === "PLAYING" &&
|
|
2371
|
+
player.connected &&
|
|
2372
|
+
(!command.available ||
|
|
2373
|
+
run(r, "pure", command.available, ctxOf(r, "read"), playerView(r, player, false)) === true));
|
|
2374
|
+
}
|
|
2375
|
+
function publishCommandAccess(r) {
|
|
2376
|
+
if (!def.customCommands.length)
|
|
2377
|
+
return;
|
|
2378
|
+
const access = {};
|
|
2379
|
+
if (r.s.status === "PLAYING")
|
|
2380
|
+
for (const p of Object.values(r.s.players)) {
|
|
2381
|
+
if (p.connected)
|
|
2382
|
+
access[p.name] = def.customCommands.filter((c) => commandAvailable(r, c, p)).map((c) => c.schema.name);
|
|
2383
|
+
}
|
|
2384
|
+
if (JSON.stringify(access) !== JSON.stringify(r.s.commandAccess)) {
|
|
2385
|
+
r.s.commandAccess = access;
|
|
2386
|
+
r.actions.push({ type: "command_access", players: snapshot(access) });
|
|
2387
|
+
}
|
|
2388
|
+
}
|
|
2389
|
+
function customCommand(r, e) {
|
|
2390
|
+
const reject = (reason) => r.actions.push({ type: "command_decision", requestId: e.requestId, origin: e.origin, accepted: false, reason });
|
|
2391
|
+
const p = r.s.players[e.player];
|
|
2392
|
+
const command = def.customCommands.find((c) => c.schema.name === e.command);
|
|
2393
|
+
if (!p || (e.uuid !== undefined && e.uuid !== p.uuid) || !command || !commandAvailable(r, command, p)) {
|
|
2394
|
+
reject("The command is not available.");
|
|
2395
|
+
return;
|
|
2396
|
+
}
|
|
2397
|
+
if (!e.args ||
|
|
2398
|
+
typeof e.args !== "object" ||
|
|
2399
|
+
Array.isArray(e.args) ||
|
|
2400
|
+
Object.keys(e.args).some((k) => !command.schema.args.some((a) => a.name === k))) {
|
|
2401
|
+
reject("Invalid command arguments.");
|
|
2402
|
+
return;
|
|
2403
|
+
}
|
|
2404
|
+
const args = {};
|
|
2405
|
+
for (const a of command.schema.args) {
|
|
2406
|
+
const value = Object.hasOwn(e.args, a.name) ? e.args[a.name] : a.default;
|
|
2407
|
+
if (value === undefined && a.optional) {
|
|
2408
|
+
args[a.name] = undefined;
|
|
2409
|
+
continue;
|
|
2410
|
+
}
|
|
2411
|
+
if (!(0, commands_js_1.validCommandValue)(a, value)) {
|
|
2412
|
+
reject("Invalid command arguments.");
|
|
2413
|
+
return;
|
|
2414
|
+
}
|
|
2415
|
+
if (a.type === "player") {
|
|
2416
|
+
const target = r.s.players[value];
|
|
2417
|
+
if (!target?.connected) {
|
|
2418
|
+
reject("Select a connected participant.");
|
|
2419
|
+
return;
|
|
2420
|
+
}
|
|
2421
|
+
args[a.name] = viewOf(r, target);
|
|
2422
|
+
}
|
|
2423
|
+
else
|
|
2424
|
+
args[a.name] = value;
|
|
2425
|
+
}
|
|
2426
|
+
run(r, "handler", command.run, ctxOf(r, "full"), { player: viewOf(r, p), args: Object.freeze(args) });
|
|
2427
|
+
resolvePhaseRequest(r);
|
|
2428
|
+
r.actions.push({ type: "command_decision", requestId: e.requestId, origin: e.origin, accepted: true });
|
|
2429
|
+
}
|
|
2360
2430
|
function voteAttempt(r, e) {
|
|
2361
2431
|
const s = r.s;
|
|
2362
2432
|
const p = s.players[e.name];
|
|
@@ -2450,6 +2520,7 @@ function createReducer(def) {
|
|
|
2450
2520
|
checkpoint(r);
|
|
2451
2521
|
if (r.req.end)
|
|
2452
2522
|
finalize(r);
|
|
2523
|
+
publishCommandAccess(r);
|
|
2453
2524
|
assertJson({ game: r.s.game, players: Object.fromEntries(Object.values(r.s.players).map((p) => [p.name, p.state])) }, "state");
|
|
2454
2525
|
}
|
|
2455
2526
|
catch (err) {
|
|
@@ -2459,6 +2530,10 @@ function createReducer(def) {
|
|
|
2459
2530
|
r = { ...r, s: clone(input), actions: [], batch: null, req: { phase: null, end: null, budget: 0 } };
|
|
2460
2531
|
if (event.type === "tick")
|
|
2461
2532
|
r.s.tick = event.serverTick;
|
|
2533
|
+
if (def.customCommands.length) {
|
|
2534
|
+
r.s.commandAccess = {};
|
|
2535
|
+
r.actions.push({ type: "command_access", players: {} });
|
|
2536
|
+
}
|
|
2462
2537
|
const detail = err instanceof errors_js_1.ChallengeError ? err.toJSON() : { message: String(err?.message ?? err) };
|
|
2463
2538
|
failRun(r.s, r.actions, "error_challenge", `challenge error on ${event.type}: ${err.message}`, {
|
|
2464
2539
|
event: event,
|