@crowdedkingdoms/crowdyjs 8.7.0 → 8.9.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/MIGRATION.md +85 -0
- package/README.md +2 -2
- package/dist/domains/compute.d.ts +12 -1
- package/dist/domains/compute.d.ts.map +1 -1
- package/dist/domains/compute.js +18 -1
- package/dist/generated/graphql.d.ts +60 -0
- package/dist/generated/graphql.d.ts.map +1 -1
- package/dist/generated/graphql.js +2 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/kit/abilities.d.ts +66 -0
- package/dist/kit/abilities.d.ts.map +1 -0
- package/dist/kit/abilities.js +71 -0
- package/dist/kit/blueprints/index.d.ts +2 -0
- package/dist/kit/blueprints/index.d.ts.map +1 -1
- package/dist/kit/blueprints/index.js +2 -0
- package/dist/kit/blueprints/liveops.d.ts +42 -0
- package/dist/kit/blueprints/liveops.d.ts.map +1 -0
- package/dist/kit/blueprints/liveops.js +170 -0
- package/dist/kit/blueprints/moderation.d.ts +32 -0
- package/dist/kit/blueprints/moderation.d.ts.map +1 -0
- package/dist/kit/blueprints/moderation.js +140 -0
- package/dist/kit/decks.d.ts +33 -1
- package/dist/kit/decks.d.ts.map +1 -1
- package/dist/kit/decks.js +49 -1
- package/dist/kit/director.d.ts +88 -0
- package/dist/kit/director.d.ts.map +1 -0
- package/dist/kit/director.js +86 -0
- package/dist/kit/economy.d.ts +46 -1
- package/dist/kit/economy.d.ts.map +1 -1
- package/dist/kit/economy.js +63 -1
- package/dist/kit/index.d.ts +14 -3
- package/dist/kit/index.d.ts.map +1 -1
- package/dist/kit/index.js +14 -3
- package/dist/kit/instances.d.ts +52 -0
- package/dist/kit/instances.d.ts.map +1 -0
- package/dist/kit/instances.js +60 -0
- package/dist/kit/kit.d.ts +60 -0
- package/dist/kit/kit.d.ts.map +1 -1
- package/dist/kit/kit.js +47 -5
- package/dist/kit/leaderboards.d.ts +21 -1
- package/dist/kit/leaderboards.d.ts.map +1 -1
- package/dist/kit/leaderboards.js +40 -1
- package/dist/kit/liveops.d.ts +112 -0
- package/dist/kit/liveops.d.ts.map +1 -0
- package/dist/kit/liveops.js +183 -0
- package/dist/kit/loot.d.ts +22 -1
- package/dist/kit/loot.d.ts.map +1 -1
- package/dist/kit/loot.js +41 -1
- package/dist/kit/matches.d.ts +33 -1
- package/dist/kit/matches.d.ts.map +1 -1
- package/dist/kit/matches.js +56 -1
- package/dist/kit/matchmaking.d.ts +57 -0
- package/dist/kit/matchmaking.d.ts.map +1 -0
- package/dist/kit/matchmaking.js +59 -0
- package/dist/kit/minigames.d.ts +30 -0
- package/dist/kit/minigames.d.ts.map +1 -0
- package/dist/kit/minigames.js +38 -0
- package/dist/kit/moderation.d.ts +73 -0
- package/dist/kit/moderation.d.ts.map +1 -0
- package/dist/kit/moderation.js +103 -0
- package/dist/kit/movement.d.ts +78 -0
- package/dist/kit/movement.d.ts.map +1 -0
- package/dist/kit/movement.js +103 -0
- package/dist/kit/npcs.d.ts.map +1 -1
- package/dist/kit/quests.d.ts +57 -0
- package/dist/kit/quests.d.ts.map +1 -1
- package/dist/kit/quests.js +72 -0
- package/dist/kit/racing.d.ts +85 -0
- package/dist/kit/racing.d.ts.map +1 -0
- package/dist/kit/racing.js +99 -0
- package/dist/kit/social.d.ts.map +1 -1
- package/dist/kit/telemetry.d.ts +66 -0
- package/dist/kit/telemetry.d.ts.map +1 -0
- package/dist/kit/telemetry.js +133 -0
- package/dist/kit/territory.d.ts +97 -0
- package/dist/kit/territory.d.ts.map +1 -0
- package/dist/kit/territory.js +114 -0
- package/dist/kit/wire.d.ts +88 -0
- package/dist/kit/wire.d.ts.map +1 -1
- package/dist/kit/wire.js +110 -0
- package/package.json +1 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime helpers for the matchmaking engine (Wave 2): rating-bucketed
|
|
3
|
+
* queues with widening windows, party blocks, and accept-gated proposals
|
|
4
|
+
* that hand off to the match layer over compute events. After everyone
|
|
5
|
+
* accepts, resolve the created match with `kit.matches.findByProposal`.
|
|
6
|
+
*
|
|
7
|
+
* Obtained via `client.kit(appId).matchmaking`.
|
|
8
|
+
*/
|
|
9
|
+
export class MatchmakingKit {
|
|
10
|
+
constructor(_appId, engines, options = {}) {
|
|
11
|
+
this.engines = engines;
|
|
12
|
+
this.moduleName = options.moduleName ?? 'matchmaking';
|
|
13
|
+
}
|
|
14
|
+
/** Is the matchmaking engine deployed + enabled (cached per session)? */
|
|
15
|
+
engineAvailable() {
|
|
16
|
+
return this.engines.has(this.moduleName);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Join a queue (optionally with a party block that must match together,
|
|
20
|
+
* and an explicit rating for games that keep rating on the progression
|
|
21
|
+
* layer).
|
|
22
|
+
*/
|
|
23
|
+
async queueJoin(input = {}) {
|
|
24
|
+
return this.invoke('queue_join', input);
|
|
25
|
+
}
|
|
26
|
+
/** Leave your queue (all modes, or one with `mode`). */
|
|
27
|
+
async queueLeave(mode) {
|
|
28
|
+
return this.invoke('queue_leave', mode ? { mode } : {});
|
|
29
|
+
}
|
|
30
|
+
/** Your queue/proposal status. */
|
|
31
|
+
async queueStatus(mode) {
|
|
32
|
+
const body = await this.invoke('queue_status', mode ? { mode } : {});
|
|
33
|
+
return {
|
|
34
|
+
queuedIn: body.queuedIn != null ? String(body.queuedIn) : null,
|
|
35
|
+
proposal: body.proposal ?? null,
|
|
36
|
+
queueDepth: Number(body.queueDepth ?? 0),
|
|
37
|
+
rating: Number(body.rating ?? 0),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/** Accept a proposal; when everyone has, the match handoff fires. */
|
|
41
|
+
async accept(proposalId) {
|
|
42
|
+
return this.invoke('accept', { proposalId });
|
|
43
|
+
}
|
|
44
|
+
/** Report the decided result (Elo-lite rating update + proposal close). */
|
|
45
|
+
async reportResult(proposalId, winnerUserId) {
|
|
46
|
+
return this.invoke('report_result', { proposalId, winnerUserId });
|
|
47
|
+
}
|
|
48
|
+
/** Engine totals (queues/proposals/rated players). */
|
|
49
|
+
async status() {
|
|
50
|
+
return this.invoke('status', {});
|
|
51
|
+
}
|
|
52
|
+
async invoke(exportName, params) {
|
|
53
|
+
const result = await this.engines.invoke(this.moduleName, exportName, params);
|
|
54
|
+
if (!result.success) {
|
|
55
|
+
throw new Error(`matchmaking.${exportName} failed: ${result.reason ?? 'unknown'}`);
|
|
56
|
+
}
|
|
57
|
+
return result.body;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Scalars } from '../generated/graphql.js';
|
|
2
|
+
import type { EngineDetector, EngineInvokeResult } from './engine.js';
|
|
3
|
+
/** Options for {@link MinigamesKit}. */
|
|
4
|
+
export interface MinigamesKitOptions {
|
|
5
|
+
/** Default module when calls omit one (e.g. your scaffolded game). */
|
|
6
|
+
defaultModuleName?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* A thin invoke wrapper for invoke-loop minigames (the Wave 2 `minigame`
|
|
10
|
+
* scaffold pattern): synchronous `play` RPCs with server-bound caller
|
|
11
|
+
* identity, server-held secrets, and per-caller records. Every method
|
|
12
|
+
* resolves the engine envelope — denials come back as
|
|
13
|
+
* `{success: false, reason}` rather than throwing.
|
|
14
|
+
*
|
|
15
|
+
* Obtained via `client.kit(appId).minigames`.
|
|
16
|
+
*/
|
|
17
|
+
export declare class MinigamesKit {
|
|
18
|
+
private readonly engines;
|
|
19
|
+
private readonly defaultModuleName?;
|
|
20
|
+
constructor(_appId: Scalars['BigInt']['input'], engines: EngineDetector, options?: MinigamesKitOptions);
|
|
21
|
+
/** Is a minigame module deployed + enabled (cached per session)? */
|
|
22
|
+
engineAvailable(moduleName?: string): Promise<boolean>;
|
|
23
|
+
/** One round: invoke the game's `play` export with your move. */
|
|
24
|
+
play(params: Record<string, unknown>, moduleName?: string): Promise<EngineInvokeResult>;
|
|
25
|
+
/** Your per-caller record. */
|
|
26
|
+
record(moduleName?: string): Promise<EngineInvokeResult>;
|
|
27
|
+
/** Any other export the game defines (typed result envelope). */
|
|
28
|
+
invoke(exportName: string, params?: Record<string, unknown>, moduleName?: string): Promise<EngineInvokeResult>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=minigames.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"minigames.d.ts","sourceRoot":"","sources":["../../src/kit/minigames.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtE,wCAAwC;AACxC,MAAM,WAAW,mBAAmB;IAClC,sEAAsE;IACtE,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;GAQG;AACH,qBAAa,YAAY;IAKrB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAS;gBAG1C,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EACjB,OAAO,EAAE,cAAc,EACxC,OAAO,GAAE,mBAAwB;IAKnC,oEAAoE;IACpE,eAAe,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMtD,iEAAiE;IAC3D,IAAI,CACR,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,kBAAkB,CAAC;IAI9B,8BAA8B;IACxB,MAAM,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAI9D,iEAAiE;IAC3D,MAAM,CACV,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACpC,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,kBAAkB,CAAC;CAO/B"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A thin invoke wrapper for invoke-loop minigames (the Wave 2 `minigame`
|
|
3
|
+
* scaffold pattern): synchronous `play` RPCs with server-bound caller
|
|
4
|
+
* identity, server-held secrets, and per-caller records. Every method
|
|
5
|
+
* resolves the engine envelope — denials come back as
|
|
6
|
+
* `{success: false, reason}` rather than throwing.
|
|
7
|
+
*
|
|
8
|
+
* Obtained via `client.kit(appId).minigames`.
|
|
9
|
+
*/
|
|
10
|
+
export class MinigamesKit {
|
|
11
|
+
constructor(_appId, engines, options = {}) {
|
|
12
|
+
this.engines = engines;
|
|
13
|
+
this.defaultModuleName = options.defaultModuleName;
|
|
14
|
+
}
|
|
15
|
+
/** Is a minigame module deployed + enabled (cached per session)? */
|
|
16
|
+
engineAvailable(moduleName) {
|
|
17
|
+
const name = moduleName ?? this.defaultModuleName;
|
|
18
|
+
if (!name)
|
|
19
|
+
return Promise.resolve(false);
|
|
20
|
+
return this.engines.has(name);
|
|
21
|
+
}
|
|
22
|
+
/** One round: invoke the game's `play` export with your move. */
|
|
23
|
+
async play(params, moduleName) {
|
|
24
|
+
return this.invoke('play', params, moduleName);
|
|
25
|
+
}
|
|
26
|
+
/** Your per-caller record. */
|
|
27
|
+
async record(moduleName) {
|
|
28
|
+
return this.invoke('record', {}, moduleName);
|
|
29
|
+
}
|
|
30
|
+
/** Any other export the game defines (typed result envelope). */
|
|
31
|
+
async invoke(exportName, params = {}, moduleName) {
|
|
32
|
+
const name = moduleName ?? this.defaultModuleName;
|
|
33
|
+
if (!name) {
|
|
34
|
+
return { success: false, reason: 'no minigame module configured', body: {} };
|
|
35
|
+
}
|
|
36
|
+
return this.engines.invoke(name, exportName, params);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { GameModelAPI } from '../domains/gameModel.js';
|
|
2
|
+
import type { Scalars } from '../generated/graphql.js';
|
|
3
|
+
/** Options for {@link ModerationKit}. */
|
|
4
|
+
export interface ModerationKitOptions {
|
|
5
|
+
/** The `typePrefix` the moderation blueprint was deployed with. */
|
|
6
|
+
typePrefix?: string;
|
|
7
|
+
}
|
|
8
|
+
/** A parsed report row. */
|
|
9
|
+
export interface KitModReport {
|
|
10
|
+
containerId: string;
|
|
11
|
+
reporterUserId: string;
|
|
12
|
+
subjectUserId: string;
|
|
13
|
+
reason: string;
|
|
14
|
+
detail: string;
|
|
15
|
+
status: string;
|
|
16
|
+
resolution: string;
|
|
17
|
+
filedAtMs: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Runtime helpers for the moderation blueprint: file reports, read the
|
|
21
|
+
* admin escalation queue, resolve reports, and manage the caller's personal
|
|
22
|
+
* mute list (client-enforced chat filtering). Enforcement stays on platform
|
|
23
|
+
* surfaces — tier revocation and grid permissions.
|
|
24
|
+
*
|
|
25
|
+
* Obtained via `client.kit(appId).moderation`.
|
|
26
|
+
*/
|
|
27
|
+
export declare class ModerationKit {
|
|
28
|
+
private readonly appId;
|
|
29
|
+
private readonly gameModel;
|
|
30
|
+
private readonly names;
|
|
31
|
+
constructor(appId: Scalars['BigInt']['input'], gameModel: GameModelAPI, options?: ModerationKitOptions);
|
|
32
|
+
/** File a report (creates the caller's report row in the queue). */
|
|
33
|
+
report(input: {
|
|
34
|
+
reporterUserId: string;
|
|
35
|
+
subjectUserId: string;
|
|
36
|
+
reason: string;
|
|
37
|
+
detail?: string;
|
|
38
|
+
}): Promise<{
|
|
39
|
+
__typename?: "GmContainer";
|
|
40
|
+
containerId: string;
|
|
41
|
+
appId: string;
|
|
42
|
+
sessionId: string | null;
|
|
43
|
+
typeName: string;
|
|
44
|
+
displayName: string;
|
|
45
|
+
description: string | null;
|
|
46
|
+
ownerUserId: string | null;
|
|
47
|
+
metadataJson: string;
|
|
48
|
+
}>;
|
|
49
|
+
/** The escalation queue (admins; filter by status, default `'open'`). */
|
|
50
|
+
queue(status?: string): Promise<KitModReport[]>;
|
|
51
|
+
/** ADMIN — resolve a report with a disposition. */
|
|
52
|
+
resolve(reportContainerId: string, status: 'actioned' | 'dismissed', resolution: string): Promise<import("./shared.js").KitInvokeResult<string>>;
|
|
53
|
+
/** Mute a player (adds to YOUR client-enforced mute list). */
|
|
54
|
+
mute(ownerUserId: string, mutedUserId: string): Promise<{
|
|
55
|
+
__typename?: "GmContainer";
|
|
56
|
+
containerId: string;
|
|
57
|
+
appId: string;
|
|
58
|
+
sessionId: string | null;
|
|
59
|
+
typeName: string;
|
|
60
|
+
displayName: string;
|
|
61
|
+
description: string | null;
|
|
62
|
+
ownerUserId: string | null;
|
|
63
|
+
metadataJson: string;
|
|
64
|
+
}>;
|
|
65
|
+
/** Unmute: delete the matching mute row. */
|
|
66
|
+
unmute(ownerUserId: string, mutedUserId: string): Promise<boolean>;
|
|
67
|
+
/** The caller's mute list (feed it to your chat renderer). */
|
|
68
|
+
mutes(ownerUserId: string): Promise<Array<{
|
|
69
|
+
containerId: string;
|
|
70
|
+
mutedUserId: string;
|
|
71
|
+
}>>;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=moderation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"moderation.d.ts","sourceRoot":"","sources":["../../src/kit/moderation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAIvD,yCAAyC;AACzC,MAAM,WAAW,oBAAoB;IACnC,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,2BAA2B;AAC3B,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,qBAAa,aAAa;IAItB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAJ5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkB;gBAGrB,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EACjC,SAAS,EAAE,YAAY,EACxC,OAAO,GAAE,oBAAyB;IAKpC,oEAAoE;IAC9D,MAAM,CAAC,KAAK,EAAE;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC;QACtB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB;;;;;;;;;;;IAeD,yEAAyE;IACnE,KAAK,CAAC,MAAM,SAAS,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAyBrD,mDAAmD;IAC7C,OAAO,CAAC,iBAAiB,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,WAAW,EAAE,UAAU,EAAE,MAAM;IAS7F,8DAA8D;IACxD,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;;;;;;;;;;;IAYnD,4CAA4C;IACtC,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQxE,8DAA8D;IACxD,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAmB/F"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { moderationNames } from './blueprints/moderation.js';
|
|
2
|
+
import { kitContainerProperties, kitInvoke } from './shared.js';
|
|
3
|
+
/**
|
|
4
|
+
* Runtime helpers for the moderation blueprint: file reports, read the
|
|
5
|
+
* admin escalation queue, resolve reports, and manage the caller's personal
|
|
6
|
+
* mute list (client-enforced chat filtering). Enforcement stays on platform
|
|
7
|
+
* surfaces — tier revocation and grid permissions.
|
|
8
|
+
*
|
|
9
|
+
* Obtained via `client.kit(appId).moderation`.
|
|
10
|
+
*/
|
|
11
|
+
export class ModerationKit {
|
|
12
|
+
constructor(appId, gameModel, options = {}) {
|
|
13
|
+
this.appId = appId;
|
|
14
|
+
this.gameModel = gameModel;
|
|
15
|
+
this.names = moderationNames(options.typePrefix ?? '');
|
|
16
|
+
}
|
|
17
|
+
/** File a report (creates the caller's report row in the queue). */
|
|
18
|
+
async report(input) {
|
|
19
|
+
return this.gameModel.createContainer({
|
|
20
|
+
appId: this.appId,
|
|
21
|
+
typeName: this.names.reportType,
|
|
22
|
+
displayName: `report ${input.reason} vs ${input.subjectUserId}`,
|
|
23
|
+
properties: [
|
|
24
|
+
{ key: 'reporter_user_id', valueType: 'string', valueJson: JSON.stringify(input.reporterUserId) },
|
|
25
|
+
{ key: 'subject_user_id', valueType: 'string', valueJson: JSON.stringify(input.subjectUserId) },
|
|
26
|
+
{ key: 'reason', valueType: 'string', valueJson: JSON.stringify(input.reason) },
|
|
27
|
+
{ key: 'detail', valueType: 'string', valueJson: JSON.stringify((input.detail ?? '').slice(0, 500)) },
|
|
28
|
+
{ key: 'filed_at_ms', valueType: 'int', valueJson: String(Date.now()) },
|
|
29
|
+
],
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/** The escalation queue (admins; filter by status, default `'open'`). */
|
|
33
|
+
async queue(status = 'open') {
|
|
34
|
+
const containers = await this.gameModel.containers({
|
|
35
|
+
appId: this.appId,
|
|
36
|
+
typeName: this.names.reportType,
|
|
37
|
+
});
|
|
38
|
+
const rows = await Promise.all(containers.map(async (c) => {
|
|
39
|
+
const props = await kitContainerProperties(this.gameModel, String(this.appId), c.containerId);
|
|
40
|
+
return {
|
|
41
|
+
containerId: c.containerId,
|
|
42
|
+
reporterUserId: String(props.reporter_user_id ?? ''),
|
|
43
|
+
subjectUserId: String(props.subject_user_id ?? ''),
|
|
44
|
+
reason: String(props.reason ?? ''),
|
|
45
|
+
detail: String(props.detail ?? ''),
|
|
46
|
+
status: String(props.status ?? 'open'),
|
|
47
|
+
resolution: String(props.resolution ?? ''),
|
|
48
|
+
filedAtMs: Number(props.filed_at_ms ?? 0),
|
|
49
|
+
};
|
|
50
|
+
}));
|
|
51
|
+
return rows
|
|
52
|
+
.filter((r) => !status || r.status === status)
|
|
53
|
+
.sort((a, b) => a.filedAtMs - b.filedAtMs);
|
|
54
|
+
}
|
|
55
|
+
/** ADMIN — resolve a report with a disposition. */
|
|
56
|
+
async resolve(reportContainerId, status, resolution) {
|
|
57
|
+
return kitInvoke(this.gameModel, {
|
|
58
|
+
appId: String(this.appId),
|
|
59
|
+
functionName: this.names.resolveReportFn,
|
|
60
|
+
selfContainerId: reportContainerId,
|
|
61
|
+
params: { status, resolution },
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/** Mute a player (adds to YOUR client-enforced mute list). */
|
|
65
|
+
async mute(ownerUserId, mutedUserId) {
|
|
66
|
+
return this.gameModel.createContainer({
|
|
67
|
+
appId: this.appId,
|
|
68
|
+
typeName: this.names.muteType,
|
|
69
|
+
displayName: `mute ${mutedUserId}`,
|
|
70
|
+
properties: [
|
|
71
|
+
{ key: 'owner_user_id', valueType: 'string', valueJson: JSON.stringify(ownerUserId) },
|
|
72
|
+
{ key: 'muted_user_id', valueType: 'string', valueJson: JSON.stringify(mutedUserId) },
|
|
73
|
+
],
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
/** Unmute: delete the matching mute row. */
|
|
77
|
+
async unmute(ownerUserId, mutedUserId) {
|
|
78
|
+
const mutes = await this.mutes(ownerUserId);
|
|
79
|
+
const row = mutes.find((m) => m.mutedUserId === mutedUserId);
|
|
80
|
+
if (!row)
|
|
81
|
+
return false;
|
|
82
|
+
await this.gameModel.deleteContainer({ appId: this.appId, containerId: row.containerId });
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
/** The caller's mute list (feed it to your chat renderer). */
|
|
86
|
+
async mutes(ownerUserId) {
|
|
87
|
+
const containers = await this.gameModel.containers({
|
|
88
|
+
appId: this.appId,
|
|
89
|
+
typeName: this.names.muteType,
|
|
90
|
+
});
|
|
91
|
+
const rows = await Promise.all(containers.map(async (c) => {
|
|
92
|
+
const props = await kitContainerProperties(this.gameModel, String(this.appId), c.containerId);
|
|
93
|
+
return {
|
|
94
|
+
containerId: c.containerId,
|
|
95
|
+
ownerUserId: String(props.owner_user_id ?? ''),
|
|
96
|
+
mutedUserId: String(props.muted_user_id ?? ''),
|
|
97
|
+
};
|
|
98
|
+
}));
|
|
99
|
+
return rows
|
|
100
|
+
.filter((r) => r.ownerUserId === String(ownerUserId))
|
|
101
|
+
.map(({ containerId, mutedUserId }) => ({ containerId, mutedUserId }));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { GameModelAPI } from '../domains/gameModel.js';
|
|
2
|
+
import type { Scalars } from '../generated/graphql.js';
|
|
3
|
+
import type { EngineDetector } from './engine.js';
|
|
4
|
+
import { type MovementViolationEvent } from './wire.js';
|
|
5
|
+
/** Options for {@link MovementKit}. */
|
|
6
|
+
export interface MovementKitOptions {
|
|
7
|
+
/** The warden module name. Defaults to `'movement-warden'`. */
|
|
8
|
+
moduleName?: string;
|
|
9
|
+
/** The warden-config container type. Defaults to `'WardenConfig'`. */
|
|
10
|
+
configTypeName?: string;
|
|
11
|
+
}
|
|
12
|
+
/** A user's violation book as the warden reports it. */
|
|
13
|
+
export interface KitViolations {
|
|
14
|
+
userId: string;
|
|
15
|
+
speed: number;
|
|
16
|
+
teleport: number;
|
|
17
|
+
bounds: number;
|
|
18
|
+
log: Array<{
|
|
19
|
+
atMs: number;
|
|
20
|
+
kind: string;
|
|
21
|
+
detail: string;
|
|
22
|
+
}>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Runtime helpers for the movement-warden (Wave 3, observe/flag posture):
|
|
26
|
+
* read violation books, inspect the live envelope config, and parse type-95
|
|
27
|
+
* violation events. The warden never corrects or kicks — client prediction
|
|
28
|
+
* stays exactly as it is; games decide what flags mean (scoreboard shame,
|
|
29
|
+
* moderation reports, tournament DQs).
|
|
30
|
+
*
|
|
31
|
+
* Client-prediction guidance: keep your movement client-authoritative and
|
|
32
|
+
* SMOOTH — the envelopes are generous (speed tolerance + one-sample jitter
|
|
33
|
+
* forgiveness) so honest clients never flag; teleports (fast travel,
|
|
34
|
+
* respawns) should be paired with game-known context you can correlate
|
|
35
|
+
* against the violation log.
|
|
36
|
+
*
|
|
37
|
+
* Obtained via `client.kit(appId).movement`.
|
|
38
|
+
*/
|
|
39
|
+
export declare class MovementKit {
|
|
40
|
+
private readonly appId;
|
|
41
|
+
private readonly gameModel;
|
|
42
|
+
private readonly engines;
|
|
43
|
+
private readonly moduleName;
|
|
44
|
+
private readonly configTypeName;
|
|
45
|
+
constructor(appId: Scalars['BigInt']['input'], gameModel: GameModelAPI, engines: EngineDetector, options?: MovementKitOptions);
|
|
46
|
+
/** Is the warden deployed + enabled (cached per session)? */
|
|
47
|
+
engineAvailable(): Promise<boolean>;
|
|
48
|
+
/** A user's violation book (your own without an argument). */
|
|
49
|
+
violations(userId?: string): Promise<KitViolations>;
|
|
50
|
+
/** The live envelope configuration (posture is always `'observe'` v1). */
|
|
51
|
+
config(): Promise<Record<string, unknown>>;
|
|
52
|
+
/** Warden totals (watched actors, flagged users, samples). */
|
|
53
|
+
status(): Promise<Record<string, unknown>>;
|
|
54
|
+
/** STUDIO (admin) — create/adjust the WardenConfig container. */
|
|
55
|
+
defineConfig(input: {
|
|
56
|
+
displayName?: string;
|
|
57
|
+
chunk?: [number, number, number];
|
|
58
|
+
radiusXz?: number;
|
|
59
|
+
maxSpeed?: number;
|
|
60
|
+
maxTeleport?: number;
|
|
61
|
+
bounds?: [number, number, number, number];
|
|
62
|
+
tolerancePct?: number;
|
|
63
|
+
}): Promise<{
|
|
64
|
+
__typename?: "GmContainer";
|
|
65
|
+
containerId: string;
|
|
66
|
+
appId: string;
|
|
67
|
+
sessionId: string | null;
|
|
68
|
+
typeName: string;
|
|
69
|
+
displayName: string;
|
|
70
|
+
description: string | null;
|
|
71
|
+
ownerUserId: string | null;
|
|
72
|
+
metadataJson: string;
|
|
73
|
+
}>;
|
|
74
|
+
/** Parse a type-95 movement-violation server event. */
|
|
75
|
+
parseViolation(bytes: Uint8Array): MovementViolationEvent | null;
|
|
76
|
+
private invoke;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=movement.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"movement.d.ts","sourceRoot":"","sources":["../../src/kit/movement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAA0B,KAAK,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAEhF,uCAAuC;AACvC,MAAM,WAAW,kBAAkB;IACjC,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wDAAwD;AACxD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC5D;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,WAAW;IAKpB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAN1B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;gBAGrB,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EACjC,SAAS,EAAE,YAAY,EACvB,OAAO,EAAE,cAAc,EACxC,OAAO,GAAE,kBAAuB;IAMlC,6DAA6D;IAC7D,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAInC,8DAA8D;IACxD,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAiBzD,0EAA0E;IACpE,MAAM;IAIZ,8DAA8D;IACxD,MAAM;IAIZ,iEAAiE;IAC3D,YAAY,CAAC,KAAK,EAAE;QACxB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAC1C,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB;;;;;;;;;;;IAsCD,uDAAuD;IACvD,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,sBAAsB,GAAG,IAAI;YAIlD,MAAM;CAOrB"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { parseMovementViolation } from './wire.js';
|
|
2
|
+
/**
|
|
3
|
+
* Runtime helpers for the movement-warden (Wave 3, observe/flag posture):
|
|
4
|
+
* read violation books, inspect the live envelope config, and parse type-95
|
|
5
|
+
* violation events. The warden never corrects or kicks — client prediction
|
|
6
|
+
* stays exactly as it is; games decide what flags mean (scoreboard shame,
|
|
7
|
+
* moderation reports, tournament DQs).
|
|
8
|
+
*
|
|
9
|
+
* Client-prediction guidance: keep your movement client-authoritative and
|
|
10
|
+
* SMOOTH — the envelopes are generous (speed tolerance + one-sample jitter
|
|
11
|
+
* forgiveness) so honest clients never flag; teleports (fast travel,
|
|
12
|
+
* respawns) should be paired with game-known context you can correlate
|
|
13
|
+
* against the violation log.
|
|
14
|
+
*
|
|
15
|
+
* Obtained via `client.kit(appId).movement`.
|
|
16
|
+
*/
|
|
17
|
+
export class MovementKit {
|
|
18
|
+
constructor(appId, gameModel, engines, options = {}) {
|
|
19
|
+
this.appId = appId;
|
|
20
|
+
this.gameModel = gameModel;
|
|
21
|
+
this.engines = engines;
|
|
22
|
+
this.moduleName = options.moduleName ?? 'movement-warden';
|
|
23
|
+
this.configTypeName = options.configTypeName ?? 'WardenConfig';
|
|
24
|
+
}
|
|
25
|
+
/** Is the warden deployed + enabled (cached per session)? */
|
|
26
|
+
engineAvailable() {
|
|
27
|
+
return this.engines.has(this.moduleName);
|
|
28
|
+
}
|
|
29
|
+
/** A user's violation book (your own without an argument). */
|
|
30
|
+
async violations(userId) {
|
|
31
|
+
const body = await this.invoke('violations', userId ? { userId } : {});
|
|
32
|
+
return {
|
|
33
|
+
userId: String(body.userId ?? ''),
|
|
34
|
+
speed: Number(body.speed ?? 0),
|
|
35
|
+
teleport: Number(body.teleport ?? 0),
|
|
36
|
+
bounds: Number(body.bounds ?? 0),
|
|
37
|
+
log: Array.isArray(body.log)
|
|
38
|
+
? body.log.map((entry) => ({
|
|
39
|
+
atMs: Number(entry.atMs ?? 0),
|
|
40
|
+
kind: String(entry.kind ?? ''),
|
|
41
|
+
detail: String(entry.detail ?? ''),
|
|
42
|
+
}))
|
|
43
|
+
: [],
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/** The live envelope configuration (posture is always `'observe'` v1). */
|
|
47
|
+
async config() {
|
|
48
|
+
return this.invoke('config', {});
|
|
49
|
+
}
|
|
50
|
+
/** Warden totals (watched actors, flagged users, samples). */
|
|
51
|
+
async status() {
|
|
52
|
+
return this.invoke('status', {});
|
|
53
|
+
}
|
|
54
|
+
/** STUDIO (admin) — create/adjust the WardenConfig container. */
|
|
55
|
+
async defineConfig(input) {
|
|
56
|
+
const properties = [
|
|
57
|
+
...(input.chunk
|
|
58
|
+
? [
|
|
59
|
+
{ key: 'chunk_x', valueType: 'int', valueJson: String(input.chunk[0]) },
|
|
60
|
+
{ key: 'chunk_y', valueType: 'int', valueJson: String(input.chunk[1]) },
|
|
61
|
+
{ key: 'chunk_z', valueType: 'int', valueJson: String(input.chunk[2]) },
|
|
62
|
+
]
|
|
63
|
+
: []),
|
|
64
|
+
...(input.radiusXz !== undefined
|
|
65
|
+
? [{ key: 'radius_xz', valueType: 'int', valueJson: String(input.radiusXz) }]
|
|
66
|
+
: []),
|
|
67
|
+
...(input.maxSpeed !== undefined
|
|
68
|
+
? [{ key: 'max_speed', valueType: 'int', valueJson: String(input.maxSpeed) }]
|
|
69
|
+
: []),
|
|
70
|
+
...(input.maxTeleport !== undefined
|
|
71
|
+
? [{ key: 'max_teleport', valueType: 'int', valueJson: String(input.maxTeleport) }]
|
|
72
|
+
: []),
|
|
73
|
+
...(input.bounds
|
|
74
|
+
? [
|
|
75
|
+
{ key: 'min_x', valueType: 'int', valueJson: String(input.bounds[0]) },
|
|
76
|
+
{ key: 'max_x', valueType: 'int', valueJson: String(input.bounds[1]) },
|
|
77
|
+
{ key: 'min_z', valueType: 'int', valueJson: String(input.bounds[2]) },
|
|
78
|
+
{ key: 'max_z', valueType: 'int', valueJson: String(input.bounds[3]) },
|
|
79
|
+
]
|
|
80
|
+
: []),
|
|
81
|
+
...(input.tolerancePct !== undefined
|
|
82
|
+
? [{ key: 'tolerance_pct', valueType: 'int', valueJson: String(input.tolerancePct) }]
|
|
83
|
+
: []),
|
|
84
|
+
];
|
|
85
|
+
return this.gameModel.createContainer({
|
|
86
|
+
appId: this.appId,
|
|
87
|
+
typeName: this.configTypeName,
|
|
88
|
+
displayName: input.displayName ?? 'warden-config',
|
|
89
|
+
properties,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/** Parse a type-95 movement-violation server event. */
|
|
93
|
+
parseViolation(bytes) {
|
|
94
|
+
return parseMovementViolation(bytes);
|
|
95
|
+
}
|
|
96
|
+
async invoke(exportName, params) {
|
|
97
|
+
const result = await this.engines.invoke(this.moduleName, exportName, params);
|
|
98
|
+
if (!result.success) {
|
|
99
|
+
throw new Error(`movement.${exportName} failed: ${result.reason ?? 'unknown'}`);
|
|
100
|
+
}
|
|
101
|
+
return result.body;
|
|
102
|
+
}
|
|
103
|
+
}
|
package/dist/kit/npcs.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"npcs.d.ts","sourceRoot":"","sources":["../../src/kit/npcs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5C,0EAA0E;AAC1E,MAAM,WAAW,cAAc;IAC7B,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;IACzC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qCAAqC;AACrC,MAAM,WAAW,MAAM;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED;;;;;;;;;;GAUG;AACH,qBAAa,OAAO;IAKhB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAE1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAP3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAGjB,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EACjC,SAAS,EAAE,YAAY,EACxC,OAAO,GAAE,cAAmB,EACX,OAAO,CAAC,EAAE,cAAc,YAAA;IAM3C;;;;;OAKG;IACH,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAKnC;;;;;;;;;OASG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,MAAM,EAAE;IAW/D,0EAA0E;IACpE,KAAK,CAAC,KAAK,EAAE;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAC/C,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAC;QACjC,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB;;;;;;;;;;;IAuBD;;;;OAIG;IACG,IAAI,CAAC,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAclF,gDAAgD;IAC1C,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQ3C,8EAA8E;IACxE,MAAM,CAAC,cAAc,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;IAInC;;;OAGG;IACG,UAAU,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAQzD,6EAA6E;IACvE,KAAK,CAAC,aAAa,CAAC,EAAE,MAAM;;;;;;;;;;;;sBA+
|
|
1
|
+
{"version":3,"file":"npcs.d.ts","sourceRoot":"","sources":["../../src/kit/npcs.ts"],"names":[],"mappings":"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"}
|
package/dist/kit/quests.d.ts
CHANGED
|
@@ -87,6 +87,63 @@ export declare class QuestsKit {
|
|
|
87
87
|
}>;
|
|
88
88
|
/** List a player's quest progress rows. */
|
|
89
89
|
mine(ownerUserId: Scalars['BigInt']['input']): Promise<KitQuestProgress[]>;
|
|
90
|
+
/**
|
|
91
|
+
* STUDIO (admin) — define an ordered tutorial chain as quest defs. Steps
|
|
92
|
+
* are plain quests whose `questId` encodes the chain + index
|
|
93
|
+
* (`"<chain>:<i>"`), so no new server surface is involved: the sequencing
|
|
94
|
+
* is a read-side convention enforced by {@link tutorial} /
|
|
95
|
+
* {@link acceptNextTutorialStep} (a step is `locked` until every earlier
|
|
96
|
+
* step completes).
|
|
97
|
+
*/
|
|
98
|
+
defineTutorial(input: {
|
|
99
|
+
/** Chain id (one app can ship several tutorials). Defaults to `'ftue'`. */
|
|
100
|
+
chain?: string;
|
|
101
|
+
steps: Array<{
|
|
102
|
+
displayName: string;
|
|
103
|
+
targetCount?: number;
|
|
104
|
+
rewardItemId?: string;
|
|
105
|
+
rewardQty?: number;
|
|
106
|
+
rewardGold?: number;
|
|
107
|
+
}>;
|
|
108
|
+
}): Promise<{
|
|
109
|
+
__typename?: "GmContainer";
|
|
110
|
+
containerId: string;
|
|
111
|
+
appId: string;
|
|
112
|
+
sessionId: string | null;
|
|
113
|
+
typeName: string;
|
|
114
|
+
displayName: string;
|
|
115
|
+
description: string | null;
|
|
116
|
+
ownerUserId: string | null;
|
|
117
|
+
metadataJson: string;
|
|
118
|
+
}[]>;
|
|
119
|
+
/** One tutorial step joined with the player's progress. */
|
|
120
|
+
/**
|
|
121
|
+
* A player's view of a tutorial chain: steps in order, each `locked`
|
|
122
|
+
* (an earlier step is incomplete), `active` (the first incomplete step),
|
|
123
|
+
* or `complete`. The client shows/drives only the `active` step; the
|
|
124
|
+
* trusted advance authority is unchanged (players still cannot complete
|
|
125
|
+
* their own quests).
|
|
126
|
+
*/
|
|
127
|
+
tutorial(ownerUserId: Scalars['BigInt']['input'], chain?: string): Promise<Array<{
|
|
128
|
+
stepIndex: number;
|
|
129
|
+
def: KitQuestDef;
|
|
130
|
+
progress: KitQuestProgress | null;
|
|
131
|
+
status: 'locked' | 'active' | 'complete';
|
|
132
|
+
}>>;
|
|
133
|
+
/**
|
|
134
|
+
* Ensure the player's ACTIVE tutorial step has a progress row (accepting
|
|
135
|
+
* it when missing) and return the step. Returns null when the chain is
|
|
136
|
+
* complete. Calling this for a locked step is impossible by construction —
|
|
137
|
+
* it always targets the first incomplete step.
|
|
138
|
+
*/
|
|
139
|
+
acceptNextTutorialStep(ownerUserId: Scalars['BigInt']['input'], chain?: string, options?: {
|
|
140
|
+
sessionId?: string;
|
|
141
|
+
}): Promise<{
|
|
142
|
+
stepIndex: number;
|
|
143
|
+
def: KitQuestDef;
|
|
144
|
+
progress: KitQuestProgress | null;
|
|
145
|
+
status: "locked" | "active" | "complete";
|
|
146
|
+
} | null>;
|
|
90
147
|
/** Read one progress row. */
|
|
91
148
|
state(progressId: string): Promise<KitQuestProgress>;
|
|
92
149
|
/**
|
package/dist/kit/quests.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quests.d.ts","sourceRoot":"","sources":["../../src/kit/quests.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE1E,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,aAAa,CAAC;AAErB,+EAA+E;AAC/E,MAAM,WAAW,gBAAgB;IAC/B,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,8CAA8C;AAC9C,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,oDAAoD;AACpD,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,qBAAa,SAAS;IAIlB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAJ5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;gBAGjB,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EACjC,SAAS,EAAE,YAAY,EACxC,OAAO,GAAE,gBAAqB;IAKhC,iEAAiE;IAC3D,OAAO,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IA2BvC,uEAAuE;IACjE,WAAW,CAAC,KAAK,EAAE;QACvB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAC;KAClC;;;;;;;;;;;IAkCD;;;OAGG;IACG,MAAM,CACV,WAAW,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EACvC,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO;;;;;;;;;;;IA8B5D,2CAA2C;IACrC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"quests.d.ts","sourceRoot":"","sources":["../../src/kit/quests.ts"],"names":[],"mappings":"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"}
|