@kradle/challenges-sdk 0.25.0 → 0.26.0
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 +9 -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 +74 -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,66 @@ 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
|
+
r.actions.push({ type: "command_decision", requestId: e.requestId, origin: e.origin, accepted: true });
|
|
2428
|
+
}
|
|
2360
2429
|
function voteAttempt(r, e) {
|
|
2361
2430
|
const s = r.s;
|
|
2362
2431
|
const p = s.players[e.name];
|
|
@@ -2450,6 +2519,7 @@ function createReducer(def) {
|
|
|
2450
2519
|
checkpoint(r);
|
|
2451
2520
|
if (r.req.end)
|
|
2452
2521
|
finalize(r);
|
|
2522
|
+
publishCommandAccess(r);
|
|
2453
2523
|
assertJson({ game: r.s.game, players: Object.fromEntries(Object.values(r.s.players).map((p) => [p.name, p.state])) }, "state");
|
|
2454
2524
|
}
|
|
2455
2525
|
catch (err) {
|
|
@@ -2459,6 +2529,10 @@ function createReducer(def) {
|
|
|
2459
2529
|
r = { ...r, s: clone(input), actions: [], batch: null, req: { phase: null, end: null, budget: 0 } };
|
|
2460
2530
|
if (event.type === "tick")
|
|
2461
2531
|
r.s.tick = event.serverTick;
|
|
2532
|
+
if (def.customCommands.length) {
|
|
2533
|
+
r.s.commandAccess = {};
|
|
2534
|
+
r.actions.push({ type: "command_access", players: {} });
|
|
2535
|
+
}
|
|
2462
2536
|
const detail = err instanceof errors_js_1.ChallengeError ? err.toJSON() : { message: String(err?.message ?? err) };
|
|
2463
2537
|
failRun(r.s, r.actions, "error_challenge", `challenge error on ${event.type}: ${err.message}`, {
|
|
2464
2538
|
event: event,
|