@zhin.js/plugin-rps 1.0.0 → 1.0.2

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.
Files changed (61) hide show
  1. package/README.md +31 -0
  2. package/commands/rps/[action:string=].ts +15 -0
  3. package/lib/engine.d.ts +0 -1
  4. package/lib/engine.js +2 -1
  5. package/lib/engine.js.map +1 -1
  6. package/lib/game-flow.d.ts +6 -7
  7. package/lib/game-flow.js +18 -16
  8. package/lib/game-flow.js.map +1 -1
  9. package/lib/index.d.ts +8 -2
  10. package/lib/index.js +8 -25
  11. package/lib/index.js.map +1 -1
  12. package/lib/memory-db.d.ts +6 -0
  13. package/lib/memory-db.js +18 -0
  14. package/lib/memory-db.js.map +1 -0
  15. package/lib/models.d.ts +5 -4
  16. package/lib/models.js +2 -2
  17. package/lib/models.js.map +1 -1
  18. package/lib/rps-command.d.ts +4 -3
  19. package/lib/rps-command.js +5 -1
  20. package/lib/rps-command.js.map +1 -1
  21. package/lib/runtime-store.d.ts +6 -0
  22. package/lib/runtime-store.js +7 -0
  23. package/lib/runtime-store.js.map +1 -0
  24. package/lib/session-service.d.ts +1 -3
  25. package/lib/session-service.js +3 -12
  26. package/lib/session-service.js.map +1 -1
  27. package/lib/view.d.ts +2 -3
  28. package/lib/view.js +5 -3
  29. package/lib/view.js.map +1 -1
  30. package/middlewares/rps-alias.ts +18 -0
  31. package/middlewares/rps-choice.ts +66 -0
  32. package/package.json +45 -10
  33. package/plugin.ts +63 -0
  34. package/schema.json +6 -0
  35. package/src/engine.ts +3 -1
  36. package/src/game-flow.ts +21 -22
  37. package/src/index.ts +9 -36
  38. package/src/memory-db.ts +22 -0
  39. package/src/models.ts +7 -4
  40. package/src/rps-command.ts +12 -3
  41. package/src/runtime-store.ts +9 -0
  42. package/src/session-service.ts +4 -11
  43. package/src/view.ts +6 -3
  44. package/lib/commands.d.ts +0 -6
  45. package/lib/commands.d.ts.map +0 -1
  46. package/lib/commands.js +0 -86
  47. package/lib/commands.js.map +0 -1
  48. package/lib/engine.d.ts.map +0 -1
  49. package/lib/game-flow.d.ts.map +0 -1
  50. package/lib/hub-register.d.ts +0 -5
  51. package/lib/hub-register.d.ts.map +0 -1
  52. package/lib/hub-register.js +0 -26
  53. package/lib/hub-register.js.map +0 -1
  54. package/lib/index.d.ts.map +0 -1
  55. package/lib/models.d.ts.map +0 -1
  56. package/lib/rps-command.d.ts.map +0 -1
  57. package/lib/session-service.d.ts.map +0 -1
  58. package/lib/view.d.ts.map +0 -1
  59. package/plugin.yml +0 -2
  60. package/src/commands.ts +0 -102
  61. package/src/hub-register.ts +0 -30
package/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # @zhin.js/plugin-rps
2
+
3
+ 石头剪刀布猜拳插件,三局两胜;支持游戏大厅按钮与文本命令。
4
+
5
+ ## 安装
6
+
7
+ ```yaml
8
+ plugins:
9
+ - "@zhin.js/plugin-rps"
10
+ database:
11
+ dialect: sqlite
12
+ storage: ./data/zhin.db
13
+ ```
14
+
15
+ ## 命令
16
+
17
+ | 命令 | 说明 |
18
+ |------|------|
19
+ | `/猜拳` | 帮助与频道状态 |
20
+ | `/猜拳 开始` | 开始对局 |
21
+ | `/猜拳 继续` | 继续当前局 |
22
+ | `/rps` | 英文别名 |
23
+
24
+ 也可通过 `/游戏` 大厅按钮进入。
25
+
26
+ ## 开发
27
+
28
+ ```bash
29
+ pnpm --filter @zhin.js/plugin-rps build
30
+ pnpm vitest run plugins/games/rps/tests
31
+ ```
@@ -0,0 +1,15 @@
1
+ import { defineCommand } from '@zhin.js/command';
2
+ import { messageFromCommandInput, normalizeRpsAction } from '@zhin.js/game-kit';
3
+ import { RPS_HELP, runRpsCommandText } from '../../src/rps-command.js';
4
+ import { resolveGameServices } from '../../src/runtime-store.js';
5
+
6
+ export default defineCommand({
7
+ description: 'RPS',
8
+ async execute({ params, input, use, owner }) {
9
+ const action = normalizeRpsAction(String(params.action ?? ''));
10
+ if (!action || action === 'help') return RPS_HELP;
11
+ const services = resolveGameServices({ use, owner });
12
+ const message = messageFromCommandInput(input);
13
+ return runRpsCommandText(services, message, action);
14
+ },
15
+ });
package/lib/engine.d.ts CHANGED
@@ -6,4 +6,3 @@ export declare function randomBotMove(): RpsMove;
6
6
  export declare function resolveRound(player: RpsMove, bot: RpsMove): 0 | 1 | 2;
7
7
  export declare function parseMove(raw: string): RpsMove | null;
8
8
  export declare const WIN_TARGET = 3;
9
- //# sourceMappingURL=engine.d.ts.map
package/lib/engine.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { secureRandomItem } from '@zhin.js/game-kit';
1
2
  export const RPS_PREFIX = 'rps';
2
3
  export const MOVE_LABELS = {
3
4
  rock: '✊ 石头',
@@ -11,7 +12,7 @@ const BEATS = {
11
12
  };
12
13
  export function randomBotMove() {
13
14
  const moves = ['rock', 'paper', 'scissors'];
14
- return moves[Math.floor(Math.random() * moves.length)];
15
+ return secureRandomItem(moves);
15
16
  }
16
17
  /** 1=玩家胜 2=机器人胜 0=平局 */
17
18
  export function resolveRound(player, bot) {
package/lib/engine.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,CAAC;AAIhC,MAAM,CAAC,MAAM,WAAW,GAA4B;IAClD,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,KAAK;IACZ,QAAQ,EAAE,OAAO;CAClB,CAAC;AAEF,MAAM,KAAK,GAA6B;IACtC,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,MAAM;IACb,QAAQ,EAAE,OAAO;CAClB,CAAC;AAEF,MAAM,UAAU,aAAa;IAC3B,MAAM,KAAK,GAAc,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IACvD,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAE,CAAC;AAC1D,CAAC;AAED,wBAAwB;AACxB,MAAM,UAAU,YAAY,CAAC,MAAe,EAAE,GAAY;IACxD,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,CAAC,CAAC;IAC7B,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACnC,MAAM,GAAG,GAA4B;QACnC,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,OAAO;QACd,QAAQ,EAAE,UAAU;QACpB,EAAE,EAAE,MAAM;QACV,CAAC,EAAE,OAAO;QACV,EAAE,EAAE,UAAU;QACd,CAAC,EAAE,MAAM;QACT,CAAC,EAAE,OAAO;QACV,CAAC,EAAE,UAAU;KACd,CAAC;IACF,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AACxB,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC"}
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,CAAC;AAIhC,MAAM,CAAC,MAAM,WAAW,GAA4B;IAClD,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,KAAK;IACZ,QAAQ,EAAE,OAAO;CAClB,CAAC;AAEF,MAAM,KAAK,GAA6B;IACtC,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,MAAM;IACb,QAAQ,EAAE,OAAO;CAClB,CAAC;AAEF,MAAM,UAAU,aAAa;IAC3B,MAAM,KAAK,GAAc,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IACvD,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC;AAED,wBAAwB;AACxB,MAAM,UAAU,YAAY,CAAC,MAAe,EAAE,GAAY;IACxD,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,CAAC,CAAC;IAC7B,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACnC,MAAM,GAAG,GAA4B;QACnC,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,OAAO;QACd,QAAQ,EAAE,UAAU;QACpB,EAAE,EAAE,MAAM;QACV,CAAC,EAAE,OAAO;QACV,EAAE,EAAE,UAAU;QACd,CAAC,EAAE,MAAM;QACT,CAAC,EAAE,OAAO;QACV,CAAC,EAAE,UAAU;KACd,CAAC;IACF,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AACxB,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC"}
@@ -1,14 +1,13 @@
1
- import type { Message, Plugin } from 'zhin.js';
1
+ import type { Message, Plugin } from '@zhin.js/core';
2
2
  import type { RpsSessionRow } from './models.js';
3
3
  import { RPS_PREFIX, type RpsMove } from './engine.js';
4
4
  import type { SessionService } from './session-service.js';
5
- export declare function sendOrEditView(plugin: Plugin, services: SessionService, message: Message<any>, session: RpsSessionRow, lastRound?: {
5
+ export declare function sendOrEditView(plugin: Plugin | null, services: SessionService, message: Message<any>, session: RpsSessionRow, lastRound?: {
6
6
  player: RpsMove;
7
7
  bot: RpsMove;
8
8
  result: 0 | 1 | 2;
9
- }): Promise<void>;
10
- export declare function startGame(plugin: Plugin, services: SessionService, message: Message<any>): Promise<string | undefined>;
11
- export declare function handleChoice(plugin: Plugin, services: SessionService, message: Message<any>, sessionId: string, choiceId: string): Promise<string | null>;
12
- export declare function continueGame(plugin: Plugin, services: SessionService, message: Message<any>): Promise<string>;
9
+ }): Promise<string | void>;
10
+ export declare function startGame(plugin: Plugin | null, services: SessionService, message: Message<any>): Promise<string | undefined>;
11
+ export declare function handleChoice(plugin: Plugin | null, services: SessionService, message: Message<any>, sessionId: string, choiceId: string): Promise<string | null>;
12
+ export declare function continueGame(plugin: Plugin | null, services: SessionService, message: Message<any>): Promise<string>;
13
13
  export { RPS_PREFIX };
14
- //# sourceMappingURL=game-flow.d.ts.map
package/lib/game-flow.js CHANGED
@@ -1,7 +1,10 @@
1
+ import { plainTextFromSendContent, recordGameOutcome } from '@zhin.js/game-kit';
1
2
  import { RPS_PREFIX, WIN_TARGET, randomBotMove, resolveRound, } from './engine.js';
2
3
  import { buildRpsView } from './view.js';
3
4
  export async function sendOrEditView(plugin, services, message, session, lastRound) {
4
- const content = buildRpsView(session, lastRound);
5
+ const content = buildRpsView(session, lastRound, message.$channel.type);
6
+ if (!plugin)
7
+ return plainTextFromSendContent(content);
5
8
  const adapter = plugin.root.inject(message.$adapter);
6
9
  if (session.board_message_id) {
7
10
  const msgId = await adapter.editMessage({
@@ -31,8 +34,8 @@ export async function startGame(plugin, services, message) {
31
34
  return `本频道 ${active.player_name} 正在猜拳对决中。`;
32
35
  }
33
36
  const session = await services.createSession(message);
34
- await sendOrEditView(plugin, services, message, session);
35
- return undefined;
37
+ const text = await sendOrEditView(plugin, services, message, session);
38
+ return typeof text === 'string' ? text : undefined;
36
39
  }
37
40
  export async function handleChoice(plugin, services, message, sessionId, choiceId) {
38
41
  const session = await services.getById(sessionId);
@@ -44,16 +47,9 @@ export async function handleChoice(plugin, services, message, sessionId, choiceI
44
47
  if (session.player_id !== message.$sender.id)
45
48
  return '这是别人的对局。';
46
49
  if (choiceId === 'restart') {
47
- await services.updateSession(session.id, {
48
- player_wins: 0,
49
- bot_wins: 0,
50
- round: 0,
51
- status: 'active',
52
- board_message_id: '',
53
- });
54
- const updated = (await services.getById(session.id));
55
- await sendOrEditView(plugin, services, message, updated);
56
- return null;
50
+ await services.updateSession(session.id, { status: 'aborted' });
51
+ // text-only 模式(plugin===null)下 startGame 的唯一输出就是返回文本
52
+ return (await startGame(plugin, services, message)) ?? null;
57
53
  }
58
54
  const player = choiceId;
59
55
  if (!['rock', 'paper', 'scissors'].includes(player))
@@ -78,14 +74,20 @@ export async function handleChoice(plugin, services, message, sessionId, choiceI
78
74
  status,
79
75
  });
80
76
  const updated = (await services.getById(session.id));
81
- await sendOrEditView(plugin, services, message, updated, { player, bot, result });
82
- return null;
77
+ if (status === 'won')
78
+ void recordGameOutcome(message, 'rps', 'won', playerWins * 10);
79
+ else if (status === 'lost')
80
+ void recordGameOutcome(message, 'rps', 'lost');
81
+ const text = await sendOrEditView(plugin, services, message, updated, { player, bot, result });
82
+ return typeof text === 'string' ? text : null;
83
83
  }
84
84
  export async function continueGame(plugin, services, message) {
85
85
  const session = await services.getActiveForUser(`${message.$adapter}-${message.$endpoint}-${message.$channel.type}:${message.$channel.id}`, message.$sender.id);
86
86
  if (!session)
87
87
  return '你没有进行中的猜拳,发送「猜拳 开始」。';
88
- await sendOrEditView(plugin, services, message, session);
88
+ const text = await sendOrEditView(plugin, services, message, session);
89
+ if (typeof text === 'string')
90
+ return text;
89
91
  return '已刷新猜拳界面。';
90
92
  }
91
93
  export { RPS_PREFIX };
@@ -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,2 +1,8 @@
1
- export {};
2
- //# sourceMappingURL=index.d.ts.map
1
+ export { RPS_HELP } from './rps-command.js';
2
+ export { gameServicesToken, resolveGameServices } from './runtime-store.js';
3
+ export { createInMemoryRpsDb, mountRpsMemoryServices } from './memory-db.js';
4
+ /**
5
+ * 已由 plugin.ts 接线:commands/ 命令、middlewares/ 文本与选项中间件、
6
+ * 游戏大厅注册(registerRuntimeGame)、过期会话 cron(scheduleHostToken)、
7
+ * host DatabaseHost(databaseHostToken)。仍未接:interactive 按钮回调。
8
+ */
package/lib/index.js CHANGED
@@ -1,26 +1,9 @@
1
- import { Cron, formatCompact, usePlugin } from 'zhin.js';
2
- import { registerModels } from './models.js';
3
- import { createServices, resolveGameDatabase, } from './session-service.js';
4
- import { registerCommands, registerInteractive, registerTextFallback } from './commands.js';
5
- import { registerRpsHub } from './hub-register.js';
6
- const plugin = usePlugin();
7
- const { logger, useContext, addCron } = plugin;
8
- registerModels(plugin);
9
- let services = null;
10
- useContext('database', (dbFeature) => {
11
- services = createServices(resolveGameDatabase(dbFeature));
12
- logger.info(formatCompact({ 模块: '猜拳', 数据模型: '已就绪' }));
13
- });
14
- registerRpsHub(() => services);
15
- registerCommands(plugin, () => services);
16
- registerInteractive(plugin, () => services);
17
- registerTextFallback(plugin, () => services);
18
- addCron(new Cron('0 */15 * * * *', async () => {
19
- if (!services)
20
- return;
21
- const n = await services.abortStale(30 * 60 * 1000);
22
- if (n > 0)
23
- logger.debug(formatCompact({ 猜拳: '清理超时局', count: n }));
24
- }));
25
- logger.info(formatCompact({ 模块: '猜拳', 状态: '已加载' }));
1
+ export { RPS_HELP } from './rps-command.js';
2
+ export { gameServicesToken, resolveGameServices } from './runtime-store.js';
3
+ export { createInMemoryRpsDb, mountRpsMemoryServices } from './memory-db.js';
4
+ /**
5
+ * 已由 plugin.ts 接线:commands/ 命令、middlewares/ 文本与选项中间件、
6
+ * 游戏大厅注册(registerRuntimeGame)、过期会话 cron(scheduleHostToken)、
7
+ * host DatabaseHost(databaseHostToken)。仍未接:interactive 按钮回调。
8
+ */
26
9
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAwB,MAAM,SAAS,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EACL,cAAc,EACd,mBAAmB,GAEpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC5F,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;AAC3B,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;AAE/C,cAAc,CAAC,MAAM,CAAC,CAAC;AAEvB,IAAI,QAAQ,GAA0B,IAAI,CAAC;AAE3C,UAAU,CAAC,UAAU,EAAE,CAAC,SAA0B,EAAE,EAAE;IACpD,QAAQ,GAAG,cAAc,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC;IAC1D,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;AACxD,CAAC,CAAC,CAAC;AAEH,cAAc,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC;AAC/B,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC;AACzC,mBAAmB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC;AAC5C,oBAAoB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC;AAE7C,OAAO,CACL,IAAI,IAAI,CAAC,gBAAgB,EAAE,KAAK,IAAI,EAAE;IACpC,IAAI,CAAC,QAAQ;QAAE,OAAO;IACtB,MAAM,CAAC,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IACpD,IAAI,CAAC,GAAG,CAAC;QAAE,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AACpE,CAAC,CAAC,CACH,CAAC;AAEF,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAE7E;;;;GAIG"}
@@ -0,0 +1,6 @@
1
+ import type { DatabaseHost } from '@zhin.js/plugin-runtime';
2
+ import { type RpsDatabase, type SessionService } from './session-service.js';
3
+ /** In-memory rps_sessions for Plugin Runtime slice-2 (no DatabaseFeature). */
4
+ export declare function createInMemoryRpsDb(): RpsDatabase;
5
+ export declare function mountRpsMemoryServices(): SessionService;
6
+ export declare function mountRpsHostServices(host: DatabaseHost): SessionService;
@@ -0,0 +1,18 @@
1
+ import { createHostGameDb, createInMemoryGameDb } from '@zhin.js/game-kit';
2
+ import { defineHostTables } from './models.js';
3
+ import { createServices } from './session-service.js';
4
+ const RPS_TABLES = ['rps_sessions'];
5
+ /** In-memory rps_sessions for Plugin Runtime slice-2 (no DatabaseFeature). */
6
+ export function createInMemoryRpsDb() {
7
+ return createInMemoryGameDb(RPS_TABLES);
8
+ }
9
+ export function mountRpsMemoryServices() {
10
+ const services = createServices(createInMemoryRpsDb());
11
+ return services;
12
+ }
13
+ export function mountRpsHostServices(host) {
14
+ defineHostTables(host);
15
+ const services = createServices(createHostGameDb(host, RPS_TABLES));
16
+ return services;
17
+ }
18
+ //# sourceMappingURL=memory-db.js.map
@@ -0,0 +1 @@
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,EAAyC,MAAM,sBAAsB,CAAC;AAE7F,MAAM,UAAU,GAAG,CAAC,cAAc,CAAU,CAAC;AAE7C,8EAA8E;AAC9E,MAAM,UAAU,mBAAmB;IACjC,OAAO,oBAAoB,CAAC,UAAU,CAA2B,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,MAAM,QAAQ,GAAG,cAAc,CAAC,mBAAmB,EAAE,CAAC,CAAC;IACvD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAkB;IACrD,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACvB,MAAM,QAAQ,GAAG,cAAc,CAAC,gBAAgB,CAAC,IAAI,EAAE,UAAU,CAA2B,CAAC,CAAC;IAC9F,OAAO,QAAQ,CAAC;AAClB,CAAC"}
package/lib/models.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import type { Models, Plugin } from 'zhin.js';
1
+ import type { Models } from '@zhin.js/core';
2
2
  export type RpsSessionStatus = 'active' | 'won' | 'lost' | 'aborted';
3
- declare module 'zhin.js' {
3
+ declare module '@zhin.js/core' {
4
4
  interface Models {
5
5
  rps_sessions: {
6
6
  id: string;
@@ -22,5 +22,6 @@ declare module 'zhin.js' {
22
22
  }
23
23
  }
24
24
  export type RpsSessionRow = Models['rps_sessions'];
25
- export declare function registerModels(plugin: Plugin): void;
26
- //# sourceMappingURL=models.d.ts.map
25
+ export declare function defineHostTables(db: {
26
+ define: (name: string, definition: Record<string, unknown>) => void;
27
+ }): void;
package/lib/models.js CHANGED
@@ -1,5 +1,5 @@
1
- export function registerModels(plugin) {
2
- plugin.defineModel('rps_sessions', {
1
+ export function defineHostTables(db) {
2
+ db.define('rps_sessions', {
3
3
  id: { type: 'text', primary: true },
4
4
  adapter: { type: 'text', nullable: false },
5
5
  endpoint: { type: 'text', nullable: false },
package/lib/models.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"models.js","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AA4BA,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,MAAM,CAAC,WAAW,CAAC,cAAc,EAAE;QACjC,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,WAAW,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QAC5C,QAAQ,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QACzC,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QACtC,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":"AA6BA,MAAM,UAAU,gBAAgB,CAC9B,EAA2E;IAE3E,EAAE,CAAC,MAAM,CAAC,cAAc,EAAE;QACxB,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,WAAW,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QAC5C,QAAQ,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QACzC,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QACtC,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,5 +1,6 @@
1
- import type { Message, Plugin } from 'zhin.js';
1
+ import type { Message, Plugin } from '@zhin.js/core';
2
2
  import type { SessionService } from './session-service.js';
3
3
  export declare const RPS_HELP: string;
4
- export declare function runRpsCommand(plugin: Plugin, services: SessionService, message: Message<any>, action: string): Promise<string | undefined>;
5
- //# sourceMappingURL=rps-command.d.ts.map
4
+ export declare function runRpsCommand(plugin: Plugin | null, services: SessionService, message: Message<any>, action: string): Promise<string | undefined>;
5
+ /** Plugin Runtime / smoke: text-only, no Adapter.editMessage. */
6
+ export declare function runRpsCommandText(services: SessionService, message: Message<any>, action: string): Promise<string>;
@@ -1,4 +1,4 @@
1
- import { channelKey } from '@zhin.js/game-shared';
1
+ import { channelKey } from '@zhin.js/game-kit';
2
2
  import { continueGame, startGame } from './game-flow.js';
3
3
  export const RPS_HELP = [
4
4
  '✊✋✌️ 猜拳对决(三局两胜)',
@@ -34,4 +34,8 @@ export async function runRpsCommand(plugin, services, message, action) {
34
34
  }
35
35
  return `未知子命令:${action}\n\n${RPS_HELP}`;
36
36
  }
37
+ /** Plugin Runtime / smoke: text-only, no Adapter.editMessage. */
38
+ export async function runRpsCommandText(services, message, action) {
39
+ return (await runRpsCommand(null, services, message, action)) ?? '';
40
+ }
37
41
  //# sourceMappingURL=rps-command.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rps-command.js","sourceRoot":"","sources":["../src/rps-command.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGzD,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,iBAAiB;IACjB,eAAe;IACf,aAAa;IACb,cAAc;IACd,cAAc;CACf,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAc,EACd,QAAwB,EACxB,OAAqB,EACrB,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,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC7B,IAAI,MAAM,EAAE,CAAC;YACX,KAAK,CAAC,IAAI,CAAC,OAAO,MAAM,CAAC,WAAW,MAAM,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QACrF,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,OAAO;QAAE,OAAO,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACpE,IAAI,MAAM,KAAK,UAAU;QAAE,OAAO,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAE1E,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,QAAQ,EAAE,CAAC;AAC1C,CAAC"}
1
+ {"version":3,"file":"rps-command.js","sourceRoot":"","sources":["../src/rps-command.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGzD,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,iBAAiB;IACjB,eAAe;IACf,aAAa;IACb,cAAc;IACd,cAAc;CACf,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAqB,EACrB,QAAwB,EACxB,OAAqB,EACrB,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,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC7B,IAAI,MAAM,EAAE,CAAC;YACX,KAAK,CAAC,IAAI,CAAC,OAAO,MAAM,CAAC,WAAW,MAAM,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QACrF,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,OAAO;QAAE,OAAO,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACpE,IAAI,MAAM,KAAK,UAAU;QAAE,OAAO,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAE1E,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,QAAQ,EAAE,CAAC;AAC1C,CAAC;AAED,iEAAiE;AACjE,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,QAAwB,EACxB,OAAqB,EACrB,MAAc;IAEd,OAAO,CAAC,MAAM,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;AACtE,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { SessionService } from './session-service.js';
2
+ /** Owner-scoped service consumed by discovered commands and middleware. */
3
+ export declare const gameServicesToken: import("@zhin.js/plugin-runtime").Token<SessionService>;
4
+ export declare function resolveGameServices(context: {
5
+ use<T>(token: typeof gameServicesToken): T;
6
+ }): SessionService;
@@ -0,0 +1,7 @@
1
+ import { createToken } from '@zhin.js/plugin-runtime';
2
+ /** Owner-scoped service consumed by discovered commands and middleware. */
3
+ export const gameServicesToken = createToken('zhin.game.rps.services');
4
+ export function resolveGameServices(context) {
5
+ return context.use(gameServicesToken);
6
+ }
7
+ //# sourceMappingURL=runtime-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-store.js","sourceRoot":"","sources":["../src/runtime-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAGtD,2EAA2E;AAC3E,MAAM,CAAC,MAAM,iBAAiB,GAAG,WAAW,CAAiB,wBAAwB,CAAC,CAAC;AAEvF,MAAM,UAAU,mBAAmB,CAAC,OAAuD;IACzF,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAmB,CAAC;AAC1D,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { Database, DatabaseFeature, Message, Models } from 'zhin.js';
1
+ import type { Database, Message, Models } from '@zhin.js/core';
2
2
  import type { RpsSessionRow } from './models.js';
3
3
  export type RpsDatabase = Database<unknown, Models, string>;
4
4
  export declare class SessionService {
@@ -13,5 +13,3 @@ export declare class SessionService {
13
13
  abortStale(idleMs: number): Promise<number>;
14
14
  }
15
15
  export declare function createServices(db: RpsDatabase): SessionService;
16
- export declare function resolveGameDatabase(feature: DatabaseFeature): RpsDatabase;
17
- //# sourceMappingURL=session-service.d.ts.map
@@ -1,4 +1,4 @@
1
- import { channelKey, generateSessionId } from '@zhin.js/game-shared';
1
+ import { channelKey, generateSessionId, boardMessageMatches } from '@zhin.js/game-kit';
2
2
  function getModel(db) {
3
3
  const model = db.models.get('rps_sessions');
4
4
  if (!model)
@@ -26,15 +26,9 @@ export class SessionService {
26
26
  async getActiveByBoardMessageId(messageId) {
27
27
  if (!messageId)
28
28
  return null;
29
- const rows = await getModel(this.db).findAll({ status: 'active' });
29
+ const rows = await getModel(this.db).findAll({});
30
30
  for (const row of rows) {
31
- const stored = row.board_message_id;
32
- if (!stored)
33
- continue;
34
- if (stored === messageId || stored.endsWith(`:${messageId}`))
35
- return row;
36
- const tail = stored.split(':').pop();
37
- if (tail && messageId.endsWith(tail))
31
+ if (boardMessageMatches(row.board_message_id ?? '', messageId))
38
32
  return row;
39
33
  }
40
34
  return null;
@@ -81,7 +75,4 @@ export class SessionService {
81
75
  export function createServices(db) {
82
76
  return new SessionService(db);
83
77
  }
84
- export function resolveGameDatabase(feature) {
85
- return feature.db;
86
- }
87
78
  //# sourceMappingURL=session-service.js.map
@@ -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":"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"}
package/lib/view.d.ts CHANGED
@@ -1,9 +1,8 @@
1
- import type { SendContent } from 'zhin.js';
1
+ import type { SendContent } from '@zhin.js/core';
2
2
  import type { RpsSessionRow } from './models.js';
3
3
  import { type RpsMove } from './engine.js';
4
4
  export declare function buildRpsView(session: RpsSessionRow, lastRound?: {
5
5
  player: RpsMove;
6
6
  bot: RpsMove;
7
7
  result: 0 | 1 | 2;
8
- }): SendContent;
9
- //# sourceMappingURL=view.d.ts.map
8
+ }, channelType?: string): SendContent;
package/lib/view.js CHANGED
@@ -1,6 +1,6 @@
1
- import { buildChoiceKeyboard } from '@zhin.js/game-shared';
1
+ import { buildChoiceKeyboard } from '@zhin.js/game-kit';
2
2
  import { MOVE_LABELS, RPS_PREFIX, WIN_TARGET } from './engine.js';
3
- export function buildRpsView(session, lastRound) {
3
+ export function buildRpsView(session, lastRound, channelType) {
4
4
  const terminal = session.status !== 'active';
5
5
  const lines = [
6
6
  '✊✋✌️ **猜拳对决**',
@@ -30,7 +30,7 @@ export function buildRpsView(session, lastRound) {
30
30
  lines.push('', '继续出拳:');
31
31
  }
32
32
  const choices = terminal
33
- ? [{ id: 'restart', label: '🔄 再来一局', style: 'primary' }]
33
+ ? [{ id: 'restart', label: '🔄 再来一局', style: 'primary', keepEnabledWhenTerminal: true }]
34
34
  : ['rock', 'paper', 'scissors'].map((m) => ({
35
35
  id: m,
36
36
  label: MOVE_LABELS[m],
@@ -44,6 +44,8 @@ export function buildRpsView(session, lastRound) {
44
44
  terminal,
45
45
  buttonsPerRow: 3,
46
46
  fallbackHint: '回复数字出拳(1石头 2布 3剪刀)',
47
+ interactionProfile: terminal ? 'terminal' : 'gameplay',
48
+ channelType,
47
49
  });
48
50
  }
49
51
  //# sourceMappingURL=view.js.map
package/lib/view.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"view.js","sourceRoot":"","sources":["../src/view.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAgB,MAAM,aAAa,CAAC;AAEhF,MAAM,UAAU,YAAY,CAC1B,OAAsB,EACtB,SAAgE;IAEhE,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,KAAK,QAAQ,CAAC;IAC7C,MAAM,KAAK,GAAG;QACZ,eAAe;QACf,EAAE;QACF,YAAY,OAAO,CAAC,WAAW,UAAU,OAAO,CAAC,QAAQ,YAAY,UAAU,KAAK;KACrF,CAAC;IAEF,IAAI,SAAS,EAAE,CAAC;QACd,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,MAAM,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACrF,KAAK,CAAC,IAAI,CACR,SAAS,CAAC,MAAM,KAAK,CAAC;YACpB,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;gBACtB,CAAC,CAAC,YAAY;gBACd,CAAC,CAAC,cAAc,CACrB,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,EAAE,CAAC;QACb,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK;YAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;aACrD,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACpE,CAAC;SAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IACzB,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ;QACtB,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAkB,EAAE,CAAC;QAClE,CAAC,CAAE,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACvD,EAAE,EAAE,CAAC;YACL,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC;YACrB,KAAK,EAAE,WAAoB;SAC5B,CAAC,CAAC,CAAC;IAER,OAAO,mBAAmB,CAAC;QACzB,UAAU,EAAE,UAAU;QACtB,SAAS,EAAE,OAAO,CAAC,EAAE;QACrB,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;QAC3B,OAAO;QACP,QAAQ;QACR,aAAa,EAAE,CAAC;QAChB,YAAY,EAAE,oBAAoB;KACnC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"view.js","sourceRoot":"","sources":["../src/view.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAGxD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAgB,MAAM,aAAa,CAAC;AAEhF,MAAM,UAAU,YAAY,CAC1B,OAAsB,EACtB,SAAgE,EAChE,WAAoB;IAEpB,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,KAAK,QAAQ,CAAC;IAC7C,MAAM,KAAK,GAAG;QACZ,eAAe;QACf,EAAE;QACF,YAAY,OAAO,CAAC,WAAW,UAAU,OAAO,CAAC,QAAQ,YAAY,UAAU,KAAK;KACrF,CAAC;IAEF,IAAI,SAAS,EAAE,CAAC;QACd,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,MAAM,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACrF,KAAK,CAAC,IAAI,CACR,SAAS,CAAC,MAAM,KAAK,CAAC;YACpB,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;gBACtB,CAAC,CAAC,YAAY;gBACd,CAAC,CAAC,cAAc,CACrB,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,EAAE,CAAC;QACb,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK;YAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;aACrD,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACpE,CAAC;SAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IACzB,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ;QACtB,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAkB,EAAE,uBAAuB,EAAE,IAAI,EAAE,CAAC;QACjG,CAAC,CAAE,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACvD,EAAE,EAAE,CAAC;YACL,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC;YACrB,KAAK,EAAE,WAAoB;SAC5B,CAAC,CAAC,CAAC;IAER,OAAO,mBAAmB,CAAC;QACzB,UAAU,EAAE,UAAU;QACtB,SAAS,EAAE,OAAO,CAAC,EAAE;QACrB,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;QAC3B,OAAO;QACP,QAAQ;QACR,aAAa,EAAE,CAAC;QAChB,YAAY,EAAE,oBAAoB;QAClC,kBAAkB,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU;QACtD,WAAW;KACZ,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,18 @@
1
+ import {
2
+ defineGameCommandAliasMiddleware,
3
+ messageFromCommandInput,
4
+ normalizeRpsAction,
5
+ } from '@zhin.js/game-kit';
6
+ import { RPS_HELP, runRpsCommandText } from '../src/rps-command.js';
7
+ import { resolveGameServices } from '../src/runtime-store.js';
8
+
9
+ export default defineGameCommandAliasMiddleware({
10
+ aliases: ['猜拳', 'rps'],
11
+ async run(action, input, context) {
12
+ const normalized = normalizeRpsAction(String(action ?? ''));
13
+ if (!normalized || normalized === 'help') return RPS_HELP;
14
+ const services = resolveGameServices(context);
15
+ const message = messageFromCommandInput(input);
16
+ return runRpsCommandText(services, message, normalized);
17
+ },
18
+ });
@@ -0,0 +1,66 @@
1
+ import { defineMiddleware } from '@zhin.js/middleware';
2
+ import type { Message } from '@zhin.js/core/runtime';
3
+ import {
4
+ buildChoiceFallbackMap,
5
+ channelKey,
6
+ messageFromCommandInput,
7
+ parseChoicePayload,
8
+ resolveGameTextPayload,
9
+ } from '@zhin.js/game-kit';
10
+ import { resolveGameServices } from '../src/runtime-store.js';
11
+ import { handleChoice, RPS_PREFIX } from '../src/game-flow.js';
12
+
13
+ /**
14
+ * 文本入口:按钮 payload(`rps:session:rock|paper|scissors|restart`)与数字 fallback
15
+ * (『1石头 2布 3剪刀』,对应 view 的 fallbackHint)。
16
+ */
17
+ export default defineMiddleware<Message>({
18
+ target: 'inbound',
19
+ async handle(context, next) {
20
+ const raw = context.input.content?.trim() ?? '';
21
+ if (!raw) {
22
+ await next();
23
+ return;
24
+ }
25
+ const services = resolveGameServices(context);
26
+ const message = messageFromCommandInput(context.input);
27
+ const ch = channelKey(message);
28
+
29
+ // 直接 payload(QQ 指令预填 / Sandbox action→text)
30
+ const payloadFromText = resolveGameTextPayload(raw);
31
+ if (payloadFromText?.startsWith(`${RPS_PREFIX}:`)) {
32
+ const parsed = parseChoicePayload(payloadFromText, RPS_PREFIX);
33
+ if (parsed) {
34
+ const session = await services.getById(parsed.sessionId);
35
+ if (session?.channel_key === ch) {
36
+ const reply = await handleChoice(null, services, message, parsed.sessionId, parsed.choiceId);
37
+ if (reply) await context.input.$reply(reply);
38
+ return;
39
+ }
40
+ }
41
+ await next();
42
+ return;
43
+ }
44
+
45
+ const session = await services.getActiveForUser(ch, message.$sender.id);
46
+ if (!session || session.status !== 'active') {
47
+ await next();
48
+ return;
49
+ }
50
+
51
+ const map = buildChoiceFallbackMap(RPS_PREFIX, session.id, [
52
+ { id: 'rock', label: '石头' },
53
+ { id: 'paper', label: '布' },
54
+ { id: 'scissors', label: '剪刀' },
55
+ ]);
56
+ const payload = resolveGameTextPayload(raw, map);
57
+ const parsed = payload ? parseChoicePayload(payload, RPS_PREFIX) : null;
58
+ if (!parsed || parsed.sessionId !== session.id) {
59
+ await next();
60
+ return;
61
+ }
62
+
63
+ const reply = await handleChoice(null, services, message, session.id, parsed.choiceId);
64
+ if (reply) await context.input.$reply(reply);
65
+ },
66
+ });