@zhin.js/plugin-idiom-chain 1.0.4 → 1.0.5

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.
@@ -0,0 +1,16 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineCommand } from '@zhin.js/command';
3
+ import { messageFromCommandInput, normalizeChainAction } from '@zhin.js/game-kit';
4
+ import { CHAIN_HELP, runChainCommand } from "../../lib/chain-command.js";
5
+ import { resolveGameServices } from "../../lib/runtime-store.js";
6
+ export default defineCommand({
7
+ description: 'Idiom Chain',
8
+ async execute({ params, input, use, owner }) {
9
+ const action = normalizeChainAction(String(params.action ?? ''));
10
+ if (!action || action === 'help')
11
+ return CHAIN_HELP;
12
+ const services = resolveGameServices({ use, owner });
13
+ const message = messageFromCommandInput(input);
14
+ return runChainCommand(services, message, action);
15
+ },
16
+ });
@@ -1,4 +1,4 @@
1
- import { type GameMessageLike } from '@zhin.js/game-kit';
1
+ import { type GameMessageLike, type GameReply } from '@zhin.js/game-kit';
2
2
  import type { SessionService } from './session-service.js';
3
3
  export declare const CHAIN_HELP: string;
4
- export declare function runChainCommand(services: SessionService, message: GameMessageLike, action: string): Promise<string>;
4
+ export declare function runChainCommand(services: SessionService, message: GameMessageLike, action: string): Promise<GameReply>;
@@ -1,4 +1,4 @@
1
- import { channelKey } from '@zhin.js/game-kit';
1
+ import { channelKey, } from '@zhin.js/game-kit';
2
2
  import { continueGame, startGame } from './game-flow.js';
3
3
  import { idiomCount, modeLabel, promptLine } from './engine.js';
4
4
  export const CHAIN_HELP = [
@@ -1 +1 @@
1
- {"version":3,"file":"chain-command.js","sourceRoot":"","sources":["../src/chain-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAwB,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAkB,MAAM,aAAa,CAAC;AAIhF,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,sBAAsB;IACtB,QAAQ,UAAU,EAAE,eAAe;IACnC,iBAAiB;IACjB,8BAA8B;IAC9B,gBAAgB;IAChB,cAAc;IACd,cAAc;IACd,EAAE;IACF,cAAc;IACd,2BAA2B;CAC5B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAwB,EACxB,OAAwB,EACxB,MAAc;IAEd,MAAM,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;IAElC,IAAI,CAAC,MAAM,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAC/B,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,IAAI,GAAc,MAAM,CAAC,UAAU,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;YACzE,KAAK,CAAC,IAAI,CACR,OAAO,MAAM,CAAC,WAAW,MAAM,SAAS,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,CACvH,CAAC;YACF,IAAI,MAAM,CAAC,UAAU;gBAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;QACzE,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,IAAI,MAAM,KAAK,cAAc;QAAE,OAAO,CAAC,MAAM,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3F,IAAI,MAAM,KAAK,YAAY;QAAE,OAAO,CAAC,MAAM,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IACvF,IAAI,MAAM,KAAK,UAAU;QAAE,OAAO,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAElE,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,gBAAgB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACxD,IAAI,CAAC,GAAG;YAAE,OAAO,YAAY,CAAC;QAC9B,MAAM,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;QAC5D,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,OAAO,SAAS,MAAM,OAAO,UAAU,EAAE,CAAC;AAC5C,CAAC"}
1
+ {"version":3,"file":"chain-command.js","sourceRoot":"","sources":["../src/chain-command.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,GAGX,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAkB,MAAM,aAAa,CAAC;AAIhF,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,sBAAsB;IACtB,QAAQ,UAAU,EAAE,eAAe;IACnC,iBAAiB;IACjB,8BAA8B;IAC9B,gBAAgB;IAChB,cAAc;IACd,cAAc;IACd,EAAE;IACF,cAAc;IACd,2BAA2B;CAC5B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAwB,EACxB,OAAwB,EACxB,MAAc;IAEd,MAAM,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;IAElC,IAAI,CAAC,MAAM,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAC/B,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,IAAI,GAAc,MAAM,CAAC,UAAU,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;YACzE,KAAK,CAAC,IAAI,CACR,OAAO,MAAM,CAAC,WAAW,MAAM,SAAS,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,CACvH,CAAC;YACF,IAAI,MAAM,CAAC,UAAU;gBAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;QACzE,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,IAAI,MAAM,KAAK,cAAc;QAAE,OAAO,CAAC,MAAM,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3F,IAAI,MAAM,KAAK,YAAY;QAAE,OAAO,CAAC,MAAM,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IACvF,IAAI,MAAM,KAAK,UAAU;QAAE,OAAO,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAElE,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,gBAAgB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACxD,IAAI,CAAC,GAAG;YAAE,OAAO,YAAY,CAAC;QAC9B,MAAM,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;QAC5D,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,OAAO,SAAS,MAAM,OAAO,UAAU,EAAE,CAAC;AAC5C,CAAC"}
@@ -1,10 +1,10 @@
1
- import { type GameMessageLike } from '@zhin.js/game-kit';
1
+ import type { GameMessageLike, GameReply } from '@zhin.js/game-kit';
2
2
  import { CHAIN_PREFIX, type MatchMode } from './engine.js';
3
3
  import type { ChainSessionRow } from './models.js';
4
4
  import { type SessionService } from './session-service.js';
5
- export declare function sendOrEditView(services: SessionService, message: GameMessageLike, session: ChainSessionRow, eventLines?: string[]): Promise<string>;
6
- export declare function startGame(services: SessionService, message: GameMessageLike, matchMode?: MatchMode): Promise<string | undefined>;
7
- export declare function continueGame(services: SessionService, message: GameMessageLike): Promise<string>;
8
- export declare function processIdiomText(services: SessionService, message: GameMessageLike, raw: string): Promise<string | null>;
9
- export declare function handleChoice(services: SessionService, message: GameMessageLike, sessionId: string, choiceId: string): Promise<string | null>;
5
+ export declare function sendOrEditView(services: SessionService, message: GameMessageLike, session: ChainSessionRow, eventLines?: string[]): Promise<GameReply>;
6
+ export declare function startGame(services: SessionService, message: GameMessageLike, matchMode?: MatchMode): Promise<GameReply | undefined>;
7
+ export declare function continueGame(services: SessionService, message: GameMessageLike): Promise<GameReply>;
8
+ export declare function processIdiomText(services: SessionService, message: GameMessageLike, raw: string): Promise<GameReply | null>;
9
+ export declare function handleChoice(services: SessionService, message: GameMessageLike, sessionId: string, choiceId: string): Promise<GameReply | null>;
10
10
  export { CHAIN_PREFIX };
package/lib/game-flow.js CHANGED
@@ -1,4 +1,3 @@
1
- import { plainTextFromSendContent } from '@zhin.js/game-kit';
2
1
  import { CHAIN_PREFIX, getGloss, lastChar, modeLabel, normalizeInput, pickBotIdiom, pickHintIdiom, pickStarterIdiom, promptLine, validatePlayerIdiom, } from './engine.js';
3
2
  import { parseUsed } from './session-service.js';
4
3
  import { buildChainView, MAX_WRONG } from './view.js';
@@ -7,7 +6,7 @@ function sessionMode(session) {
7
6
  }
8
7
  export async function sendOrEditView(services, message, session, eventLines = []) {
9
8
  const content = buildChainView(session, eventLines, message.$channel.type);
10
- return plainTextFromSendContent(content);
9
+ return content;
11
10
  }
12
11
  async function botTurn(services, session, used) {
13
12
  const mode = sessionMode(session);
@@ -55,20 +54,16 @@ export async function startGame(services, message, matchMode = 'pinyin') {
55
54
  matchMode,
56
55
  });
57
56
  const gloss = starter.gloss ?? getGloss(starter.text);
58
- const text = await sendOrEditView(services, message, session, [
57
+ return sendOrEditView(services, message, session, [
59
58
  `🎬 ${modeLabel(matchMode)}开局!我先出:**${starter.text}**${gloss ? `(${gloss})` : ''}`,
60
59
  promptLine(starter.text, matchMode),
61
60
  ]);
62
- return typeof text === 'string' ? text : undefined;
63
61
  }
64
62
  export async function continueGame(services, message) {
65
63
  const session = await services.getActiveForUser(`${message.$adapter}-${message.$endpoint}-${message.$channel.type}:${message.$channel.id}`, message.$sender.id);
66
64
  if (!session)
67
65
  return '你没有进行中的接龙,发送「接龙 开始」。';
68
- const text = await sendOrEditView(services, message, session);
69
- if (typeof text === 'string')
70
- return text;
71
- return '已刷新接龙界面。';
66
+ return sendOrEditView(services, message, session);
72
67
  }
73
68
  export async function processIdiomText(services, message, raw) {
74
69
  const ch = `${message.$adapter}-${message.$endpoint}-${message.$channel.type}:${message.$channel.id}`;
@@ -142,7 +137,6 @@ export async function handleChoice(services, message, sessionId, choiceId) {
142
137
  wrong_count: 0,
143
138
  turn: 'player',
144
139
  status: 'active',
145
- board_message_id: '',
146
140
  });
147
141
  const updated = (await services.getById(session.id));
148
142
  const gloss = starter.gloss ?? getGloss(starter.text);
@@ -1 +1 @@
1
- {"version":3,"file":"game-flow.js","sourceRoot":"","sources":["../src/game-flow.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"game-flow.js","sourceRoot":"","sources":["../src/game-flow.ts"],"names":[],"mappings":"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"}
package/lib/index.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  export { CHAIN_HELP } from './chain-command.js';
2
2
  export { gameServicesToken, resolveGameServices } from './runtime-store.js';
3
- export { createInMemoryChainDb, mountChainMemoryServices } from './memory-db.js';
4
3
  /**
5
4
  * 已由 plugin.ts 接线:commands/ 命令、middlewares/ 文本与选项中间件、
6
5
  * 游戏大厅注册(registerRuntimeGame)、过期会话 cron(scheduleHostToken)、
package/lib/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  export { CHAIN_HELP } from './chain-command.js';
2
2
  export { gameServicesToken, resolveGameServices } from './runtime-store.js';
3
- export { createInMemoryChainDb, mountChainMemoryServices } from './memory-db.js';
4
3
  /**
5
4
  * 已由 plugin.ts 接线:commands/ 命令、middlewares/ 文本与选项中间件、
6
5
  * 游戏大厅注册(registerRuntimeGame)、过期会话 cron(scheduleHostToken)、
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAEjF;;;;GAIG"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE5E;;;;GAIG"}
package/lib/models.d.ts CHANGED
@@ -24,7 +24,6 @@ declare module '@zhin.js/core' {
24
24
  hints_used: number;
25
25
  turn: string;
26
26
  status: ChainSessionStatus;
27
- board_message_id: string;
28
27
  updated_at: number;
29
28
  created_at: number;
30
29
  };
package/lib/models.js CHANGED
@@ -20,7 +20,6 @@ export function defineHostTables(db) {
20
20
  hints_used: { type: 'integer', default: 0 },
21
21
  turn: { type: 'text', default: 'player' },
22
22
  status: { type: 'text', default: 'active' },
23
- board_message_id: { type: 'text', default: '' },
24
23
  updated_at: { type: 'integer', default: 0 },
25
24
  created_at: { type: 'integer', default: 0 },
26
25
  });
package/lib/models.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"models.js","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAsCA,MAAM,UAAU,gBAAgB,CAC9B,EAA2E;IAE3E,EAAE,CAAC,MAAM,CAAC,sBAAsB,EAAE;QAChC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;QACnC,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;QAC1C,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;QAC3C,YAAY,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;QAC/C,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;QAC7C,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;QAC9C,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;QAC5C,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QAC1C,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QACzC,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QACxC,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE;QAC/C,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;QAC5C,YAAY,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QAC7C,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QAC1C,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QACvC,WAAW,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QAC5C,WAAW,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QAC5C,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QAC3C,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE;QACzC,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE;QAC3C,gBAAgB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QAC/C,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QAC3C,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;KAC5C,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"models.js","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAqCA,MAAM,UAAU,gBAAgB,CAC9B,EAA2E;IAE3E,EAAE,CAAC,MAAM,CAAC,sBAAsB,EAAE;QAChC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;QACnC,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;QAC1C,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;QAC3C,YAAY,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;QAC/C,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;QAC7C,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;QAC9C,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;QAC5C,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QAC1C,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QACzC,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QACxC,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE;QAC/C,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;QAC5C,YAAY,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QAC7C,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QAC1C,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QACvC,WAAW,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QAC5C,WAAW,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QAC5C,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QAC3C,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE;QACzC,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE;QAC3C,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QAC3C,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;KAC5C,CAAC,CAAC;AACL,CAAC"}
@@ -1,24 +1,17 @@
1
1
  import type { Database, Models } from '@zhin.js/core';
2
- import { type GameMessageLike } from '@zhin.js/game-kit';
2
+ import { BaseSessionService, type GameMessageLike } from '@zhin.js/game-kit';
3
3
  import type { MatchMode } from './engine.js';
4
4
  import type { ChainSessionRow } from './models.js';
5
5
  export type ChainDatabase = Database<unknown, Models, string>;
6
6
  export declare function parseUsed(value: string | string[] | unknown): Set<string>;
7
7
  export declare function serializeUsed(set: Set<string>): string;
8
- export declare class SessionService {
9
- private readonly db;
8
+ export declare class SessionService extends BaseSessionService<ChainSessionRow> {
10
9
  constructor(db: ChainDatabase);
11
- getActiveByChannel(channel: string): Promise<ChainSessionRow | null>;
12
- getActiveForUser(channel: string, userId: string): Promise<ChainSessionRow | null>;
13
- getById(id: string): Promise<ChainSessionRow | null>;
14
- getActiveByBoardMessageId(messageId: string): Promise<ChainSessionRow | null>;
15
10
  createSession(message: GameMessageLike, starter: {
16
11
  text: string;
17
12
  nextChar: string;
18
13
  used: string[];
19
14
  matchMode: MatchMode;
20
15
  }): Promise<ChainSessionRow>;
21
- updateSession(id: string, patch: Partial<ChainSessionRow>): Promise<void>;
22
- abortStale(idleMs: number): Promise<number>;
23
16
  }
24
17
  export declare function createServices(db: ChainDatabase): SessionService;
@@ -1,10 +1,4 @@
1
- import { channelKey, generateSessionId, boardMessageMatches } from '@zhin.js/game-kit';
2
- function getModel(db) {
3
- const model = db.models.get('idiom_chain_sessions');
4
- if (!model)
5
- throw new Error('idiom_chain_sessions not registered');
6
- return model;
7
- }
1
+ import { BaseSessionService, channelKey, generateSessionId, } from '@zhin.js/game-kit';
8
2
  export function parseUsed(value) {
9
3
  if (Array.isArray(value))
10
4
  return new Set(value.filter((x) => typeof x === 'string'));
@@ -21,33 +15,13 @@ export function parseUsed(value) {
21
15
  export function serializeUsed(set) {
22
16
  return JSON.stringify([...set]);
23
17
  }
24
- export class SessionService {
25
- db;
18
+ export class SessionService extends BaseSessionService {
26
19
  constructor(db) {
27
- this.db = db;
28
- }
29
- async getActiveByChannel(channel) {
30
- const rows = await getModel(this.db).findAll({ channel_key: channel, status: 'active' });
31
- return rows[0] ?? null;
32
- }
33
- async getActiveForUser(channel, userId) {
34
- const row = await this.getActiveByChannel(channel);
35
- if (!row || row.player_id !== userId)
36
- return null;
37
- return row;
38
- }
39
- async getById(id) {
40
- return getModel(this.db).findOne({ id });
41
- }
42
- async getActiveByBoardMessageId(messageId) {
43
- if (!messageId)
44
- return null;
45
- const rows = await getModel(this.db).findAll({});
46
- for (const row of rows) {
47
- if (boardMessageMatches(row.board_message_id ?? '', messageId))
48
- return row;
49
- }
50
- return null;
20
+ super(db, {
21
+ gameId: 'chain',
22
+ table: 'idiom_chain_sessions',
23
+ userFields: ['player_id'],
24
+ });
51
25
  }
52
26
  async createSession(message, starter) {
53
27
  const now = Date.now();
@@ -72,28 +46,10 @@ export class SessionService {
72
46
  hints_used: 0,
73
47
  turn: 'player',
74
48
  status: 'active',
75
- board_message_id: '',
76
49
  updated_at: now,
77
50
  created_at: now,
78
51
  };
79
- await getModel(this.db).create(row);
80
- return row;
81
- }
82
- async updateSession(id, patch) {
83
- await getModel(this.db).updateWhere({ id }, { ...patch, updated_at: Date.now() });
84
- }
85
- async abortStale(idleMs) {
86
- const cutoff = Date.now() - idleMs;
87
- const model = getModel(this.db);
88
- const rows = await model.findAll({ status: 'active' });
89
- let n = 0;
90
- for (const row of rows) {
91
- if (row.updated_at < cutoff) {
92
- await model.updateWhere({ id: row.id }, { status: 'aborted', updated_at: Date.now() });
93
- n++;
94
- }
95
- }
96
- return n;
52
+ return this.createRow(row);
97
53
  }
98
54
  }
99
55
  export function createServices(db) {
@@ -1 +1 @@
1
- {"version":3,"file":"session-service.js","sourceRoot":"","sources":["../src/session-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-service.js","sourceRoot":"","sources":["../src/session-service.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAClB,UAAU,EACV,iBAAiB,GAGlB,MAAM,mBAAmB,CAAC;AAM3B,MAAM,UAAU,SAAS,CAAC,KAAkC;IAC1D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC;IAClG,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,GAAG,EAAE,CAAC;IAC1D,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC5B,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;IACrG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,GAAG,EAAE,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAgB;IAC5C,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,OAAO,cAAe,SAAQ,kBAAmC;IACrE,YAAY,EAAiB;QAC3B,KAAK,CAAC,EAAqD,EAAE;YAC3D,MAAM,EAAE,OAAO;YACf,KAAK,EAAE,sBAAsB;YAC7B,UAAU,EAAE,CAAC,WAAW,CAAC;SAC1B,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,aAAa,CACjB,OAAwB,EACxB,OAAiF;QAEjF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,GAAG,GAAoB;YAC3B,EAAE,EAAE,iBAAiB,EAAE;YACvB,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;YACjC,QAAQ,EAAE,OAAO,CAAC,SAAS;YAC3B,YAAY,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI;YACnC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,EAAE;YAC/B,WAAW,EAAE,UAAU,CAAC,OAAO,CAAC;YAChC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE;YAC7B,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;YAC/D,UAAU,EAAE,OAAO,CAAC,IAAI;YACxB,SAAS,EAAE,OAAO,CAAC,QAAQ;YAC3B,UAAU,EAAE,OAAO,CAAC,SAAS;YAC7B,WAAW,EAAE,aAAa,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACjD,YAAY,EAAE,CAAC;YACf,SAAS,EAAE,CAAC;YACZ,MAAM,EAAE,CAAC;YACT,WAAW,EAAE,CAAC;YACd,WAAW,EAAE,CAAC;YACd,UAAU,EAAE,CAAC;YACb,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,QAAQ;YAChB,UAAU,EAAE,GAAG;YACf,UAAU,EAAE,GAAG;SAChB,CAAC;QACF,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;CACF;AAED,MAAM,UAAU,cAAc,CAAC,EAAiB;IAC9C,OAAO,IAAI,cAAc,CAAC,EAAE,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,18 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineGameCommandAliasMiddleware, isChainAction, messageFromCommandInput, normalizeChainAction, } from '@zhin.js/game-kit';
3
+ import { CHAIN_HELP, runChainCommand } from "../lib/chain-command.js";
4
+ import { resolveGameServices } from "../lib/runtime-store.js";
5
+ export default defineGameCommandAliasMiddleware({
6
+ aliases: ['接龙', 'chain'],
7
+ async run(action, input, context) {
8
+ const normalized = normalizeChainAction(String(action ?? ''));
9
+ if (normalized === 'help')
10
+ return CHAIN_HELP;
11
+ // action 无法识别:放行给后续中间件,避免劫持普通聊天
12
+ if (!isChainAction(normalized))
13
+ return null;
14
+ const services = resolveGameServices(context);
15
+ const message = messageFromCommandInput(input);
16
+ return runChainCommand(services, message, normalized);
17
+ },
18
+ });
@@ -0,0 +1,66 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineMiddleware } from '@zhin.js/middleware';
3
+ import { buildChoiceFallbackMap, channelKey, messageFromCommandInput, parseChoicePayload, resolveGameTextPayload, } from '@zhin.js/game-kit';
4
+ import { resolveGameServices } from "../lib/runtime-store.js";
5
+ import { CHAIN_PREFIX, handleChoice, processIdiomText } from "../lib/game-flow.js";
6
+ /**
7
+ * 文本入口:按钮 payload(`chain:session:choiceId`)、数字 fallback
8
+ * (『1提示 2跳过 3认输』,对应 view 的 fallbackHint),其余按成语接龙作答。
9
+ */
10
+ export default defineMiddleware({
11
+ target: 'inbound',
12
+ async handle(context, next) {
13
+ const raw = context.input.content?.trim() ?? '';
14
+ if (!raw) {
15
+ await next();
16
+ return;
17
+ }
18
+ const services = resolveGameServices(context);
19
+ const message = messageFromCommandInput(context.input);
20
+ const ch = channelKey(message);
21
+ // 直接 payload(QQ 指令预填 / Sandbox action→text)
22
+ const payloadFromText = resolveGameTextPayload(raw);
23
+ if (payloadFromText?.startsWith(`${CHAIN_PREFIX}:`)) {
24
+ const parsed = parseChoicePayload(payloadFromText, CHAIN_PREFIX);
25
+ if (parsed) {
26
+ const session = await services.getById(parsed.sessionId);
27
+ if (session?.channel_key === ch) {
28
+ const reply = await handleChoice(services, message, parsed.sessionId, parsed.choiceId);
29
+ if (reply)
30
+ await context.input.$reply(reply);
31
+ return;
32
+ }
33
+ }
34
+ await next();
35
+ return;
36
+ }
37
+ const session = await services.getActiveForUser(ch, message.$sender.id);
38
+ if (!session) {
39
+ await next();
40
+ return;
41
+ }
42
+ if (session.status === 'active') {
43
+ const map = buildChoiceFallbackMap(CHAIN_PREFIX, session.id, [
44
+ { id: 'hint', label: '提示' },
45
+ { id: 'skip', label: '跳过' },
46
+ { id: 'quit', label: '认输' },
47
+ ]);
48
+ const payload = resolveGameTextPayload(raw, map);
49
+ const parsed = payload ? parseChoicePayload(payload, CHAIN_PREFIX) : null;
50
+ if (parsed?.sessionId === session.id) {
51
+ const reply = await handleChoice(services, message, session.id, parsed.choiceId);
52
+ if (reply)
53
+ await context.input.$reply(reply);
54
+ return;
55
+ }
56
+ }
57
+ // 仅把 2-8 个汉字的纯文本当成语作答,其余放行
58
+ if (/^[\u4e00-\u9fff]{2,8}$/.test(raw)) {
59
+ const reply = await processIdiomText(services, message, raw);
60
+ if (reply)
61
+ await context.input.$reply(reply);
62
+ return;
63
+ }
64
+ await next();
65
+ },
66
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/plugin-idiom-chain",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "Zhin.js 成语接龙 — 四字成语文字接龙 (Plugin Runtime)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -14,7 +14,7 @@
14
14
  "./package.json": "./package.json"
15
15
  },
16
16
  "files": [
17
- "plugin.ts",
17
+ "plugin.js",
18
18
  "schema.json",
19
19
  "commands",
20
20
  "middlewares",
@@ -25,10 +25,10 @@
25
25
  "license": "MIT",
26
26
  "dependencies": {
27
27
  "chinese-idiom-chengyu": "^1.1.0",
28
- "@zhin.js/command": "1.0.3",
29
- "@zhin.js/core": "1.4.1",
30
- "@zhin.js/game-kit": "2.0.1",
31
- "@zhin.js/middleware": "1.0.3",
28
+ "@zhin.js/command": "1.0.4",
29
+ "@zhin.js/core": "1.4.2",
30
+ "@zhin.js/game-kit": "2.0.2",
31
+ "@zhin.js/middleware": "1.0.4",
32
32
  "@zhin.js/plugin-runtime": "1.1.1"
33
33
  },
34
34
  "devDependencies": {
@@ -50,7 +50,7 @@
50
50
  "zhin": {
51
51
  "protocol": 1,
52
52
  "type": "plugin",
53
- "entry": "./plugin.ts",
53
+ "entry": "./plugin.js",
54
54
  "engine": "^1.0.0",
55
55
  "runtime": "trusted",
56
56
  "features": [
package/plugin.js ADDED
@@ -0,0 +1,37 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineGamePlugin } from '@zhin.js/game-kit';
3
+ import { defineHostTables } from "./lib/models.js";
4
+ import { gameServicesToken } from "./lib/runtime-store.js";
5
+ import { createServices, } from "./lib/session-service.js";
6
+ /**
7
+ * Plugin Runtime:
8
+ * - Commands under `commands/` are authoritative (help + start/continue/quit via in-memory DB).
9
+ * - DB: prefer databaseHostToken; else in-memory SessionService.
10
+ * - Text middleware under `middlewares/` handles idiom answer payloads.
11
+ */
12
+ export default defineGamePlugin({
13
+ name: 'idiom-chain',
14
+ metadata: {
15
+ displayName: 'Idiom Chain',
16
+ },
17
+ game: {
18
+ id: 'chain',
19
+ title: '成语接龙',
20
+ icon: '📜',
21
+ description: '四字成语接龙(同音/同字)',
22
+ commandPrefix: '/接龙',
23
+ quickStart: 'start_pinyin',
24
+ aliases: ['chain'],
25
+ menus: [
26
+ { id: 'start_pinyin', label: '🎮 同音接龙' },
27
+ { id: 'start_char', label: '📝 同字接龙' },
28
+ { id: 'continue', label: '🔄 继续' },
29
+ { id: 'help', label: '📖 玩法说明' },
30
+ ],
31
+ },
32
+ tables: ['idiom_chain_sessions'],
33
+ servicesToken: gameServicesToken,
34
+ defineHostTables,
35
+ createServices: (database) => createServices(database),
36
+ session: (services) => services,
37
+ });
@@ -1,4 +1,8 @@
1
- import { channelKey, type GameMessageLike } from '@zhin.js/game-kit';
1
+ import {
2
+ channelKey,
3
+ type GameMessageLike,
4
+ type GameReply,
5
+ } from '@zhin.js/game-kit';
2
6
  import { continueGame, startGame } from './game-flow.js';
3
7
  import { idiomCount, modeLabel, promptLine, type MatchMode } from './engine.js';
4
8
 
@@ -21,7 +25,7 @@ export async function runChainCommand(
21
25
  services: SessionService,
22
26
  message: GameMessageLike,
23
27
  action: string,
24
- ): Promise<string> {
28
+ ): Promise<GameReply> {
25
29
  const ch = channelKey(message);
26
30
  const userId = message.$sender.id;
27
31
 
package/src/game-flow.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { plainTextFromSendContent, type GameMessageLike } from '@zhin.js/game-kit';
1
+ import type { GameMessageLike, GameReply } from '@zhin.js/game-kit';
2
2
  import {
3
3
  CHAIN_PREFIX,
4
4
  getGloss,
@@ -25,9 +25,9 @@ export async function sendOrEditView(
25
25
  message: GameMessageLike,
26
26
  session: ChainSessionRow,
27
27
  eventLines: string[] = [],
28
- ): Promise<string> {
28
+ ): Promise<GameReply> {
29
29
  const content = buildChainView(session, eventLines, message.$channel.type);
30
- return plainTextFromSendContent(content);
30
+ return content;
31
31
  }
32
32
 
33
33
  async function botTurn(
@@ -67,7 +67,7 @@ export async function startGame(
67
67
  services: SessionService,
68
68
  message: GameMessageLike,
69
69
  matchMode: MatchMode = 'pinyin',
70
- ): Promise<string | undefined> {
70
+ ): Promise<GameReply | undefined> {
71
71
  const ch = `${message.$adapter}-${message.$endpoint}-${message.$channel.type}:${message.$channel.id}`;
72
72
  const active = await services.getActiveByChannel(ch);
73
73
  if (active) {
@@ -88,32 +88,29 @@ export async function startGame(
88
88
  });
89
89
 
90
90
  const gloss = starter.gloss ?? getGloss(starter.text);
91
- const text = await sendOrEditView(services, message, session, [
91
+ return sendOrEditView(services, message, session, [
92
92
  `🎬 ${modeLabel(matchMode)}开局!我先出:**${starter.text}**${gloss ? `(${gloss})` : ''}`,
93
93
  promptLine(starter.text, matchMode),
94
94
  ]);
95
- return typeof text === 'string' ? text : undefined;
96
95
  }
97
96
 
98
97
  export async function continueGame(
99
98
  services: SessionService,
100
99
  message: GameMessageLike,
101
- ): Promise<string> {
100
+ ): Promise<GameReply> {
102
101
  const session = await services.getActiveForUser(
103
102
  `${message.$adapter}-${message.$endpoint}-${message.$channel.type}:${message.$channel.id}`,
104
103
  message.$sender.id,
105
104
  );
106
105
  if (!session) return '你没有进行中的接龙,发送「接龙 开始」。';
107
- const text = await sendOrEditView(services, message, session);
108
- if (typeof text === 'string') return text;
109
- return '已刷新接龙界面。';
106
+ return sendOrEditView(services, message, session);
110
107
  }
111
108
 
112
109
  export async function processIdiomText(
113
110
  services: SessionService,
114
111
  message: GameMessageLike,
115
112
  raw: string,
116
- ): Promise<string | null> {
113
+ ): Promise<GameReply | null> {
117
114
  const ch = `${message.$adapter}-${message.$endpoint}-${message.$channel.type}:${message.$channel.id}`;
118
115
  const session = await services.getActiveForUser(ch, message.$sender.id);
119
116
  if (!session || session.status !== 'active') return null;
@@ -176,7 +173,7 @@ export async function handleChoice(
176
173
  message: GameMessageLike,
177
174
  sessionId: string,
178
175
  choiceId: string,
179
- ): Promise<string | null> {
176
+ ): Promise<GameReply | null> {
180
177
  const session = await services.getById(sessionId);
181
178
  if (!session) return '对局不存在。';
182
179
  if (session.player_id !== message.$sender.id) return '这是别人的接龙。';
@@ -195,7 +192,6 @@ export async function handleChoice(
195
192
  wrong_count: 0,
196
193
  turn: 'player',
197
194
  status: 'active',
198
- board_message_id: '',
199
195
  });
200
196
  const updated = (await services.getById(session.id))!;
201
197
  const gloss = starter.gloss ?? getGloss(starter.text);
package/src/index.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  export { CHAIN_HELP } from './chain-command.js';
2
2
  export { gameServicesToken, resolveGameServices } from './runtime-store.js';
3
- export { createInMemoryChainDb, mountChainMemoryServices } from './memory-db.js';
4
3
 
5
4
  /**
6
5
  * 已由 plugin.ts 接线:commands/ 命令、middlewares/ 文本与选项中间件、
package/src/models.ts CHANGED
@@ -26,7 +26,6 @@ declare module '@zhin.js/core' {
26
26
  hints_used: number;
27
27
  turn: string;
28
28
  status: ChainSessionStatus;
29
- board_message_id: string;
30
29
  updated_at: number;
31
30
  created_at: number;
32
31
  };
@@ -60,7 +59,6 @@ export function defineHostTables(
60
59
  hints_used: { type: 'integer', default: 0 },
61
60
  turn: { type: 'text', default: 'player' },
62
61
  status: { type: 'text', default: 'active' },
63
- board_message_id: { type: 'text', default: '' },
64
62
  updated_at: { type: 'integer', default: 0 },
65
63
  created_at: { type: 'integer', default: 0 },
66
64
  });
@@ -1,16 +1,16 @@
1
- import type { Database, Models, RelatedModel } from '@zhin.js/core';
2
- import { channelKey, generateSessionId, boardMessageMatches , type GameMessageLike } from '@zhin.js/game-kit';
1
+ import type { Database, Models } from '@zhin.js/core';
2
+ import {
3
+ BaseSessionService,
4
+ channelKey,
5
+ generateSessionId,
6
+ type GameMessageLike,
7
+ type GameSessionDatabase,
8
+ } from '@zhin.js/game-kit';
3
9
  import type { MatchMode } from './engine.js';
4
10
  import type { ChainSessionRow } from './models.js';
5
11
 
6
12
  export type ChainDatabase = Database<unknown, Models, string>;
7
13
 
8
- function getModel(db: ChainDatabase) {
9
- const model = db.models.get('idiom_chain_sessions');
10
- if (!model) throw new Error('idiom_chain_sessions not registered');
11
- return model as RelatedModel<unknown, Models, 'idiom_chain_sessions'>;
12
- }
13
-
14
14
  export function parseUsed(value: string | string[] | unknown): Set<string> {
15
15
  if (Array.isArray(value)) return new Set(value.filter((x): x is string => typeof x === 'string'));
16
16
  if (typeof value !== 'string' || !value) return new Set();
@@ -26,31 +26,13 @@ export function serializeUsed(set: Set<string>): string {
26
26
  return JSON.stringify([...set]);
27
27
  }
28
28
 
29
- export class SessionService {
30
- constructor(private readonly db: ChainDatabase) {}
31
-
32
- async getActiveByChannel(channel: string): Promise<ChainSessionRow | null> {
33
- const rows = await getModel(this.db).findAll({ channel_key: channel, status: 'active' });
34
- return rows[0] ?? null;
35
- }
36
-
37
- async getActiveForUser(channel: string, userId: string): Promise<ChainSessionRow | null> {
38
- const row = await this.getActiveByChannel(channel);
39
- if (!row || row.player_id !== userId) return null;
40
- return row;
41
- }
42
-
43
- async getById(id: string): Promise<ChainSessionRow | null> {
44
- return getModel(this.db).findOne({ id });
45
- }
46
-
47
- async getActiveByBoardMessageId(messageId: string): Promise<ChainSessionRow | null> {
48
- if (!messageId) return null;
49
- const rows = await getModel(this.db).findAll({});
50
- for (const row of rows) {
51
- if (boardMessageMatches(row.board_message_id ?? '', messageId)) return row;
52
- }
53
- return null;
29
+ export class SessionService extends BaseSessionService<ChainSessionRow> {
30
+ constructor(db: ChainDatabase) {
31
+ super(db as unknown as GameSessionDatabase<ChainSessionRow>, {
32
+ gameId: 'chain',
33
+ table: 'idiom_chain_sessions',
34
+ userFields: ['player_id'],
35
+ });
54
36
  }
55
37
 
56
38
  async createSession(
@@ -79,34 +61,13 @@ export class SessionService {
79
61
  hints_used: 0,
80
62
  turn: 'player',
81
63
  status: 'active',
82
- board_message_id: '',
83
64
  updated_at: now,
84
65
  created_at: now,
85
66
  };
86
- await getModel(this.db).create(row);
87
- return row;
88
- }
89
-
90
- async updateSession(id: string, patch: Partial<ChainSessionRow>): Promise<void> {
91
- await getModel(this.db).updateWhere({ id }, { ...patch, updated_at: Date.now() });
92
- }
93
-
94
- async abortStale(idleMs: number): Promise<number> {
95
- const cutoff = Date.now() - idleMs;
96
- const model = getModel(this.db);
97
- const rows = await model.findAll({ status: 'active' });
98
- let n = 0;
99
- for (const row of rows) {
100
- if (row.updated_at < cutoff) {
101
- await model.updateWhere({ id: row.id }, { status: 'aborted', updated_at: Date.now() });
102
- n++;
103
- }
104
- }
105
- return n;
67
+ return this.createRow(row);
106
68
  }
107
69
  }
108
70
 
109
71
  export function createServices(db: ChainDatabase): SessionService {
110
72
  return new SessionService(db);
111
73
  }
112
-
@@ -1,6 +0,0 @@
1
- import type { DatabaseHost } from '@zhin.js/plugin-runtime';
2
- import { type ChainDatabase, type SessionService } from './session-service.js';
3
- /** In-memory idiom_chain_sessions for Plugin Runtime slice-2 (no DatabaseFeature). */
4
- export declare function createInMemoryChainDb(): ChainDatabase;
5
- export declare function mountChainMemoryServices(): SessionService;
6
- export declare function mountChainHostServices(host: DatabaseHost): SessionService;
package/lib/memory-db.js DELETED
@@ -1,18 +0,0 @@
1
- import { createHostGameDb, createInMemoryGameDb } from '@zhin.js/game-kit';
2
- import { defineHostTables } from './models.js';
3
- import { createServices } from './session-service.js';
4
- const CHAIN_TABLES = ['idiom_chain_sessions'];
5
- /** In-memory idiom_chain_sessions for Plugin Runtime slice-2 (no DatabaseFeature). */
6
- export function createInMemoryChainDb() {
7
- return createInMemoryGameDb(CHAIN_TABLES);
8
- }
9
- export function mountChainMemoryServices() {
10
- const services = createServices(createInMemoryChainDb());
11
- return services;
12
- }
13
- export function mountChainHostServices(host) {
14
- defineHostTables(host);
15
- const services = createServices(createHostGameDb(host, CHAIN_TABLES));
16
- return services;
17
- }
18
- //# sourceMappingURL=memory-db.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"memory-db.js","sourceRoot":"","sources":["../src/memory-db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,cAAc,EAA2C,MAAM,sBAAsB,CAAC;AAE/F,MAAM,YAAY,GAAG,CAAC,sBAAsB,CAAU,CAAC;AAEvD,sFAAsF;AACtF,MAAM,UAAU,qBAAqB;IACnC,OAAO,oBAAoB,CAAC,YAAY,CAA6B,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,wBAAwB;IACtC,MAAM,QAAQ,GAAG,cAAc,CAAC,qBAAqB,EAAE,CAAC,CAAC;IACzD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,IAAkB;IACvD,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACvB,MAAM,QAAQ,GAAG,cAAc,CAAC,gBAAgB,CAAC,IAAI,EAAE,YAAY,CAA6B,CAAC,CAAC;IAClG,OAAO,QAAQ,CAAC;AAClB,CAAC"}
package/plugin.ts DELETED
@@ -1,64 +0,0 @@
1
- import { definePlugin, databaseHostToken, scheduleHostToken } from '@zhin.js/plugin-runtime';
2
- import {
3
- registerRuntimeGame,
4
- initGameRecordHost,
5
- DEFAULT_GAME_STALE_CRON,
6
- DEFAULT_GAME_STALE_IDLE_MS,
7
- } from '@zhin.js/game-kit';
8
- import { mountChainHostServices, mountChainMemoryServices } from './src/memory-db.js';
9
- import { gameServicesToken } from './src/runtime-store.js';
10
- import type { SessionService } from './src/session-service.js';
11
-
12
- /**
13
- * Plugin Runtime:
14
- * - Commands under `commands/` are authoritative (help + start/continue/quit via in-memory DB).
15
- * - DB: prefer databaseHostToken; else in-memory SessionService.
16
- * - Text middleware under `middlewares/` handles idiom answer payloads.
17
- */
18
- export default definePlugin({
19
- name: 'idiom-chain',
20
- metadata: {
21
- displayName: 'Idiom Chain',
22
- },
23
- setup(context) {
24
- let services: SessionService;
25
- if (context.resources.has(databaseHostToken)) {
26
- const host = context.resources.use(databaseHostToken);
27
- services = mountChainHostServices(host);
28
- context.lifecycle.add(initGameRecordHost(host));
29
- } else {
30
- services = mountChainMemoryServices();
31
- }
32
- context.resources.provide(gameServicesToken, services);
33
- const disposeHub = registerRuntimeGame({
34
- id: 'chain',
35
- title: '成语接龙',
36
- icon: '📜',
37
- description: '四字成语接龙(同音/同字)',
38
- commandPrefix: '/接龙',
39
- quickStart: 'start_pinyin',
40
- aliases: ['chain'],
41
- menus: [
42
- { id: 'start_pinyin', label: '🎮 同音接龙' },
43
- { id: 'start_char', label: '📝 同字接龙' },
44
- { id: 'continue', label: '🔄 继续' },
45
- { id: 'help', label: '📖 玩法说明' },
46
- ],
47
- });
48
- context.lifecycle.add(disposeHub);
49
-
50
- if (context.resources.has(scheduleHostToken)) {
51
- const schedule = context.resources.use(scheduleHostToken);
52
- const disposeCron = schedule.register({
53
- id: 'chain/abort-stale',
54
- cron: DEFAULT_GAME_STALE_CRON,
55
- description: 'Abort stale idiom-chain sessions',
56
- async execute() {
57
- if (!services.abortStale) return;
58
- await services.abortStale(DEFAULT_GAME_STALE_IDLE_MS);
59
- },
60
- });
61
- context.lifecycle.add(disposeCron);
62
- }
63
- },
64
- });
package/src/memory-db.ts DELETED
@@ -1,22 +0,0 @@
1
- import { createHostGameDb, createInMemoryGameDb } from '@zhin.js/game-kit';
2
- import type { DatabaseHost } from '@zhin.js/plugin-runtime';
3
- import { defineHostTables } from './models.js';
4
- import { createServices, type ChainDatabase, type SessionService } from './session-service.js';
5
-
6
- const CHAIN_TABLES = ['idiom_chain_sessions'] as const;
7
-
8
- /** In-memory idiom_chain_sessions for Plugin Runtime slice-2 (no DatabaseFeature). */
9
- export function createInMemoryChainDb(): ChainDatabase {
10
- return createInMemoryGameDb(CHAIN_TABLES) as unknown as ChainDatabase;
11
- }
12
-
13
- export function mountChainMemoryServices(): SessionService {
14
- const services = createServices(createInMemoryChainDb());
15
- return services;
16
- }
17
-
18
- export function mountChainHostServices(host: DatabaseHost): SessionService {
19
- defineHostTables(host);
20
- const services = createServices(createHostGameDb(host, CHAIN_TABLES) as unknown as ChainDatabase);
21
- return services;
22
- }