@zhin.js/plugin-guess-number 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # @zhin.js/plugin-guess-number
2
+
3
+ 猜数字小游戏:在 1~100 范围内七步内猜中神秘数。
4
+
5
+ ## 安装
6
+
7
+ ```yaml
8
+ plugins:
9
+ - "@zhin.js/plugin-guess-number"
10
+ database:
11
+ dialect: sqlite
12
+ storage: ./data/zhin.db
13
+ ```
14
+
15
+ ## 命令
16
+
17
+ | 命令 | 说明 |
18
+ |------|------|
19
+ | `/猜数` | 帮助与频道状态 |
20
+ | `/猜数 开始` | 开始新局 |
21
+ | `/guess` | 英文别名 |
22
+
23
+ 也可通过 `/游戏` 大厅按钮进入。
24
+
25
+ ## 开发
26
+
27
+ ```bash
28
+ pnpm --filter @zhin.js/plugin-guess-number build
29
+ pnpm vitest run plugins/games/guess-number/tests
30
+ ```
@@ -1 +1 @@
1
- {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAI/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAoB3D,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,CAG/F;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,CAgBtG"}
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiD,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAIrF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAoB3D,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,CAG/F;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,CAgBtG"}
package/lib/commands.js CHANGED
@@ -14,8 +14,8 @@ function registerPattern(plugin, pattern, desc, getServices) {
14
14
  }));
15
15
  }
16
16
  export function registerCommands(plugin, getServices) {
17
- registerPattern(plugin, 'guess [action:word]', '猜数字(guess)', getServices);
18
- registerPattern(plugin, '猜数 [action:word]', '猜数字(中文)', getServices);
17
+ registerPattern(plugin, '/guess [action:word]', '猜数字(guess)', getServices);
18
+ registerPattern(plugin, '/猜数 [action:word]', '猜数字(中文)', getServices);
19
19
  }
20
20
  export function registerGuessMiddleware(plugin, getServices) {
21
21
  registerGameTextMiddleware(plugin, async (message, next) => {
@@ -1 +1 @@
1
- {"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,cAAc,EAAe,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AACpG,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGrD,SAAS,eAAe,CACtB,MAAc,EACd,OAAe,EACf,IAAY,EACZ,WAAwC;IAExC,MAAM,CAAC,UAAU,CACf,IAAI,cAAc,CAAC,OAAO,CAAC;SACxB,IAAI,CAAC,IAAI,CAAC;SACV,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE;QAChC,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,QAAQ;YAAE,OAAO,sBAAsB,CAAC;QAC7C,MAAM,GAAG,GAAI,MAAM,CAAC,MAAM,CAAC,MAA6B,IAAI,EAAE,CAAC;QAC/D,OAAO,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC;IACvE,CAAC,CAAC,CACL,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAc,EAAE,WAAwC;IACvF,eAAe,CAAC,MAAM,EAAE,qBAAqB,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;IAC1E,eAAe,CAAC,MAAM,EAAE,kBAAkB,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,MAAc,EAAE,WAAwC;IAC9F,0BAA0B,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QACzD,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,EAAE,CAAC;QAE7B,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACvC,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,EAAE,CAAC;QAEtB,MAAM,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;QAC/B,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,gBAAgB,CAAC,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACxE,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,EAAE,CAAC;QAE5B,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClE,IAAI,KAAK;YAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC,EAAE,mBAAmB,CAAC,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,cAAc,EAAqC,MAAM,SAAS,CAAC;AACrF,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AACpG,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGrD,SAAS,eAAe,CACtB,MAAc,EACd,OAAe,EACf,IAAY,EACZ,WAAwC;IAExC,MAAM,CAAC,UAAU,CACf,IAAI,cAAc,CAAC,OAAO,CAAC;SACxB,IAAI,CAAC,IAAI,CAAC;SACV,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE;QAChC,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,QAAQ;YAAE,OAAO,sBAAsB,CAAC;QAC7C,MAAM,GAAG,GAAI,MAAM,CAAC,MAAM,CAAC,MAA6B,IAAI,EAAE,CAAC;QAC/D,OAAO,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC;IACvE,CAAC,CAAC,CACL,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAc,EAAE,WAAwC;IACvF,eAAe,CAAC,MAAM,EAAE,sBAAsB,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;IAC3E,eAAe,CAAC,MAAM,EAAE,mBAAmB,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,MAAc,EAAE,WAAwC;IAC9F,0BAA0B,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QACzD,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,EAAE,CAAC;QAE7B,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACvC,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,EAAE,CAAC;QAEtB,MAAM,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;QAC/B,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,gBAAgB,CAAC,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACxE,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,EAAE,CAAC;QAE5B,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClE,IAAI,KAAK;YAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC,EAAE,mBAAmB,CAAC,CAAC;AAC1B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,UAAU,CAAC;AACpC,eAAO,MAAM,GAAG,IAAI,CAAC;AACrB,eAAO,MAAM,GAAG,MAAM,CAAC;AACvB,eAAO,MAAM,YAAY,IAAI,CAAC;AAE9B,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC;AAE7D,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,CAIxE;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,EAAE,KAAK,GAAG,SAAS,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGpH"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,UAAU,CAAC;AACpC,eAAO,MAAM,GAAG,IAAI,CAAC;AACrB,eAAO,MAAM,GAAG,MAAM,CAAC;AACvB,eAAO,MAAM,YAAY,IAAI,CAAC;AAE9B,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC;AAE7D,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,CAIxE;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,EAAE,KAAK,GAAG,SAAS,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGpH"}
package/lib/engine.js CHANGED
@@ -1,9 +1,10 @@
1
+ import { secureRandomIntInclusive } from '@zhin.js/game-shared';
1
2
  export const GUESS_PREFIX = 'guess';
2
3
  export const MIN = 1;
3
4
  export const MAX = 100;
4
5
  export const MAX_ATTEMPTS = 7;
5
6
  export function newSecret() {
6
- return MIN + Math.floor(Math.random() * (MAX - MIN + 1));
7
+ return secureRandomIntInclusive(MIN, MAX);
7
8
  }
8
9
  export function evaluateGuess(secret, value) {
9
10
  if (!Number.isInteger(value) || value < MIN || value > MAX)
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,YAAY,GAAG,OAAO,CAAC;AACpC,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;AACrB,MAAM,CAAC,MAAM,GAAG,GAAG,GAAG,CAAC;AACvB,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC;AAI9B,MAAM,UAAU,SAAS;IACvB,OAAO,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAc,EAAE,KAAa;IACzD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,GAAG,IAAI,KAAK,GAAG,GAAG;QAAE,OAAO,SAAS,CAAC;IAC7E,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IACnC,OAAO,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,MAA+C,EAAE,QAAgB,EAAE,QAAgB;IAC1G,IAAI,MAAM,KAAK,KAAK;QAAE,OAAO,kBAAkB,QAAQ,MAAM,QAAQ,EAAE,CAAC;IACxE,OAAO,kBAAkB,QAAQ,MAAM,QAAQ,EAAE,CAAC;AACpD,CAAC"}
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAEhE,MAAM,CAAC,MAAM,YAAY,GAAG,OAAO,CAAC;AACpC,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;AACrB,MAAM,CAAC,MAAM,GAAG,GAAG,GAAG,CAAC;AACvB,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC;AAI9B,MAAM,UAAU,SAAS;IACvB,OAAO,wBAAwB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAc,EAAE,KAAa;IACzD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,GAAG,IAAI,KAAK,GAAG,GAAG;QAAE,OAAO,SAAS,CAAC;IAC7E,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IACnC,OAAO,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,MAA+C,EAAE,QAAgB,EAAE,QAAgB;IAC1G,IAAI,MAAM,KAAK,KAAK;QAAE,OAAO,kBAAkB,QAAQ,MAAM,QAAQ,EAAE,CAAC;IACxE,OAAO,kBAAkB,QAAQ,MAAM,QAAQ,EAAE,CAAC;AACpD,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import type { Message } from 'zhin.js';
2
- import type { SessionService } from './session-service.js';
2
+ import { type SessionService } from './session-service.js';
3
3
  export declare function startGame(services: SessionService, message: Message<any>): Promise<string>;
4
4
  export declare function processGuess(services: SessionService, message: Message<any>, value: number): Promise<string | null>;
5
5
  //# sourceMappingURL=game-flow.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"game-flow.d.ts","sourceRoot":"","sources":["../src/game-flow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,GACpB,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED,wBAAsB,YAAY,CAChC,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,EACrB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA6CxB"}
1
+ {"version":3,"file":"game-flow.d.ts","sourceRoot":"","sources":["../src/game-flow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAGvC,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEzE,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,GACpB,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED,wBAAsB,YAAY,CAChC,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,EACrB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA+CxB"}
package/lib/game-flow.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { recordGameOutcome } from '@zhin.js/game-shared';
1
2
  import { evaluateGuess, hintText, MAX, MIN } from './engine.js';
2
3
  import { formatStatus } from './session-service.js';
3
4
  export async function startGame(services, message) {
@@ -21,20 +22,22 @@ export async function processGuess(services, message, value) {
21
22
  const attempts = session.attempts + 1;
22
23
  if (result === 'win') {
23
24
  await services.updateSession(session.id, { attempts, status: 'won' });
25
+ void recordGameOutcome(message, 'guess', 'won', Math.max(1, session.max_attempts - attempts + 1) * 10);
24
26
  return [
25
27
  '🎉 **猜对了!**',
26
28
  '',
27
29
  `答案就是 **${session.secret}**,你用了 ${attempts} 次。`,
28
- '发送「猜数 开始」再来一局。',
30
+ '发送 `/猜数 开始` 再来一局。',
29
31
  ].join('\n');
30
32
  }
31
33
  if (attempts >= session.max_attempts) {
32
34
  await services.updateSession(session.id, { attempts, status: 'lost' });
35
+ void recordGameOutcome(message, 'guess', 'lost');
33
36
  return [
34
37
  '💀 **机会用完了!**',
35
38
  '',
36
39
  `正确答案是 **${session.secret}**。`,
37
- '发送「猜数 开始」再来一局。',
40
+ '发送 `/猜数 开始` 再来一局。',
38
41
  ].join('\n');
39
42
  }
40
43
  let rangeMin = session.range_min;
@@ -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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"}
@@ -9,7 +9,7 @@ export function registerGuessHub(getServices) {
9
9
  title: '猜数字',
10
10
  icon: '🔢',
11
11
  description: '1~100 七步猜中神秘数',
12
- commandPrefix: '猜数',
12
+ commandPrefix: '/猜数',
13
13
  quickStart: '开始',
14
14
  aliases: ['guess'],
15
15
  menus: [
@@ -1 +1 @@
1
- {"version":3,"file":"hub-register.js","sourceRoot":"","sources":["../src/hub-register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGjE,MAAM,UAAU,gBAAgB,CAAC,WAAwC;IACvE,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,OAAO,MAAM,CAAC,YAAY,CAAC;QACzB,EAAE,EAAE,OAAO;QACX,KAAK,EAAE,KAAK;QACZ,IAAI,EAAE,IAAI;QACV,WAAW,EAAE,eAAe;QAC5B,aAAa,EAAE,IAAI;QACnB,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,OAAO,CAAC;QAClB,KAAK,EAAE;YACL,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;YACnD,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE;SACjC;QACD,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE;YACjC,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;YAC/B,IAAI,CAAC,QAAQ;gBAAE,OAAO,sBAAsB,CAAC;YAC7C,OAAO,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC1D,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,OAAO,EAAE,UAAU,EAAE,CAAC"}
1
+ {"version":3,"file":"hub-register.js","sourceRoot":"","sources":["../src/hub-register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGjE,MAAM,UAAU,gBAAgB,CAAC,WAAwC;IACvE,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,OAAO,MAAM,CAAC,YAAY,CAAC;QACzB,EAAE,EAAE,OAAO;QACX,KAAK,EAAE,KAAK;QACZ,IAAI,EAAE,IAAI;QACV,WAAW,EAAE,eAAe;QAC5B,aAAa,EAAE,KAAK;QACpB,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,OAAO,CAAC;QAClB,KAAK,EAAE;YACL,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;YACnD,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE;SACjC;QACD,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE;YACjC,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;YAC/B,IAAI,CAAC,QAAQ;gBAAE,OAAO,sBAAsB,CAAC;YAC7C,OAAO,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC1D,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,OAAO,EAAE,UAAU,EAAE,CAAC"}
package/lib/index.js CHANGED
@@ -1,25 +1,25 @@
1
- import { Cron, formatCompact, usePlugin } from 'zhin.js';
1
+ import { formatCompact, usePlugin } from 'zhin.js';
2
2
  import { registerModels } from './models.js';
3
3
  import { createServices, resolveGameDatabase, } from './session-service.js';
4
4
  import { registerCommands, registerGuessMiddleware } from './commands.js';
5
5
  import { registerGuessHub } from './hub-register.js';
6
6
  const plugin = usePlugin();
7
- const { logger, useContext, addCron } = plugin;
7
+ const { logger, useContext, addSchedule } = plugin;
8
8
  registerModels(plugin);
9
9
  let services = null;
10
10
  useContext('database', (dbFeature) => {
11
11
  services = createServices(resolveGameDatabase(dbFeature));
12
- logger.info(formatCompact({ 模块: '猜数字', 数据模型: '已就绪' }));
12
+ logger.debug(formatCompact({ 模块: '猜数字', 数据模型: '已就绪' }));
13
13
  });
14
14
  registerGuessHub(() => services);
15
15
  registerCommands(plugin, () => services);
16
16
  registerGuessMiddleware(plugin, () => services);
17
- addCron(new Cron('0 */15 * * * *', async () => {
17
+ addSchedule({ kind: 'solar', cron: '0 */15 * * * *' }, async () => {
18
18
  if (!services)
19
19
  return;
20
20
  const n = await services.abortStale(30 * 60 * 1000);
21
21
  if (n > 0)
22
22
  logger.debug(formatCompact({ 猜数字: '清理超时局', count: n }));
23
- }));
24
- logger.info(formatCompact({ 模块: '猜数字', 状态: '已加载' }));
23
+ });
24
+ logger.debug(formatCompact({ 模块: '猜数字', 状态: '已加载' }));
25
25
  //# 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,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,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,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;AACzD,CAAC,CAAC,CAAC;AAEH,gBAAgB,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC;AACjC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC;AACzC,uBAAuB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC;AAEhD,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,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AACrE,CAAC,CAAC,CACH,CAAC;AAEF,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAwB,MAAM,SAAS,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EACL,cAAc,EACd,mBAAmB,GAEpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;AAC3B,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC;AAEnD,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,KAAK,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;AAC1D,CAAC,CAAC,CAAC;AAEH,gBAAgB,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC;AACjC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC;AACzC,uBAAuB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC;AAEhD,WAAW,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,KAAK,IAAI,EAAE;IAC9D,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,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AACrE,CAAC,CAAC,CAAC;AAEL,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/plugin-guess-number",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Zhin.js 猜数字 — 1~100 七步之内猜中",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -21,14 +21,23 @@
21
21
  ],
22
22
  "license": "MIT",
23
23
  "peerDependencies": {
24
- "zhin.js": "4.1.0"
24
+ "zhin.js": "4.1.2"
25
25
  },
26
26
  "dependencies": {
27
- "@zhin.js/game-shared": "1.0.0"
27
+ "@zhin.js/game-shared": "1.0.1"
28
28
  },
29
29
  "devDependencies": {
30
30
  "typescript": "^6.0.3",
31
- "zhin.js": "4.1.0"
31
+ "zhin.js": "4.1.2"
32
+ },
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/zhinjs/zhin.git",
36
+ "directory": "plugins/games/guess-number"
37
+ },
38
+ "publishConfig": {
39
+ "access": "public",
40
+ "registry": "https://registry.npmjs.org"
32
41
  },
33
42
  "scripts": {
34
43
  "build": "tsc --build",
package/src/commands.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Message, MessageCommand, type Plugin } from 'zhin.js';
1
+ import { Message, MessageCommand, getActionFromMessage, type Plugin } from 'zhin.js';
2
2
  import { channelKey, normalizeGuessAction, registerGameTextMiddleware } from '@zhin.js/game-shared';
3
3
  import { processGuess } from './game-flow.js';
4
4
  import { runGuessCommand } from './guess-command.js';
@@ -23,8 +23,8 @@ function registerPattern(
23
23
  }
24
24
 
25
25
  export function registerCommands(plugin: Plugin, getServices: () => SessionService | null): void {
26
- registerPattern(plugin, 'guess [action:word]', '猜数字(guess)', getServices);
27
- registerPattern(plugin, '猜数 [action:word]', '猜数字(中文)', getServices);
26
+ registerPattern(plugin, '/guess [action:word]', '猜数字(guess)', getServices);
27
+ registerPattern(plugin, '/猜数 [action:word]', '猜数字(中文)', getServices);
28
28
  }
29
29
 
30
30
  export function registerGuessMiddleware(plugin: Plugin, getServices: () => SessionService | null): void {
package/src/engine.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { secureRandomIntInclusive } from '@zhin.js/game-shared';
2
+
1
3
  export const GUESS_PREFIX = 'guess';
2
4
  export const MIN = 1;
3
5
  export const MAX = 100;
@@ -6,7 +8,7 @@ export const MAX_ATTEMPTS = 7;
6
8
  export type GuessResult = 'win' | 'low' | 'high' | 'invalid';
7
9
 
8
10
  export function newSecret(): number {
9
- return MIN + Math.floor(Math.random() * (MAX - MIN + 1));
11
+ return secureRandomIntInclusive(MIN, MAX);
10
12
  }
11
13
 
12
14
  export function evaluateGuess(secret: number, value: number): GuessResult {
package/src/game-flow.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { Message } from 'zhin.js';
2
+ import { recordGameOutcome } from '@zhin.js/game-shared';
2
3
  import { evaluateGuess, hintText, MAX, MIN } from './engine.js';
3
- import type { SessionService } from './session-service.js';
4
- import { formatStatus } from './session-service.js';
4
+ import { formatStatus, type SessionService } from './session-service.js';
5
5
 
6
6
  export async function startGame(
7
7
  services: SessionService,
@@ -34,21 +34,23 @@ export async function processGuess(
34
34
 
35
35
  if (result === 'win') {
36
36
  await services.updateSession(session.id, { attempts, status: 'won' });
37
+ void recordGameOutcome(message, 'guess', 'won', Math.max(1, session.max_attempts - attempts + 1) * 10);
37
38
  return [
38
39
  '🎉 **猜对了!**',
39
40
  '',
40
41
  `答案就是 **${session.secret}**,你用了 ${attempts} 次。`,
41
- '发送「猜数 开始」再来一局。',
42
+ '发送 `/猜数 开始` 再来一局。',
42
43
  ].join('\n');
43
44
  }
44
45
 
45
46
  if (attempts >= session.max_attempts) {
46
47
  await services.updateSession(session.id, { attempts, status: 'lost' });
48
+ void recordGameOutcome(message, 'guess', 'lost');
47
49
  return [
48
50
  '💀 **机会用完了!**',
49
51
  '',
50
52
  `正确答案是 **${session.secret}**。`,
51
- '发送「猜数 开始」再来一局。',
53
+ '发送 `/猜数 开始` 再来一局。',
52
54
  ].join('\n');
53
55
  }
54
56
 
@@ -11,7 +11,7 @@ export function registerGuessHub(getServices: () => SessionService | null): () =
11
11
  title: '猜数字',
12
12
  icon: '🔢',
13
13
  description: '1~100 七步猜中神秘数',
14
- commandPrefix: '猜数',
14
+ commandPrefix: '/猜数',
15
15
  quickStart: '开始',
16
16
  aliases: ['guess'],
17
17
  menus: [
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Cron, formatCompact, usePlugin, type DatabaseFeature } from 'zhin.js';
1
+ import { formatCompact, usePlugin, type DatabaseFeature } from 'zhin.js';
2
2
  import { registerModels } from './models.js';
3
3
  import {
4
4
  createServices,
@@ -9,7 +9,7 @@ import { registerCommands, registerGuessMiddleware } from './commands.js';
9
9
  import { registerGuessHub } from './hub-register.js';
10
10
 
11
11
  const plugin = usePlugin();
12
- const { logger, useContext, addCron } = plugin;
12
+ const { logger, useContext, addSchedule } = plugin;
13
13
 
14
14
  registerModels(plugin);
15
15
 
@@ -17,19 +17,17 @@ let services: SessionService | null = null;
17
17
 
18
18
  useContext('database', (dbFeature: DatabaseFeature) => {
19
19
  services = createServices(resolveGameDatabase(dbFeature));
20
- logger.info(formatCompact({ 模块: '猜数字', 数据模型: '已就绪' }));
20
+ logger.debug(formatCompact({ 模块: '猜数字', 数据模型: '已就绪' }));
21
21
  });
22
22
 
23
23
  registerGuessHub(() => services);
24
24
  registerCommands(plugin, () => services);
25
25
  registerGuessMiddleware(plugin, () => services);
26
26
 
27
- addCron(
28
- new Cron('0 */15 * * * *', async () => {
27
+ addSchedule({ kind: 'solar', cron: '0 */15 * * * *' }, async () => {
29
28
  if (!services) return;
30
29
  const n = await services.abortStale(30 * 60 * 1000);
31
30
  if (n > 0) logger.debug(formatCompact({ 猜数字: '清理超时局', count: n }));
32
- }),
33
- );
31
+ });
34
32
 
35
- logger.info(formatCompact({ 模块: '猜数字', 状态: '已加载' }));
33
+ logger.debug(formatCompact({ 模块: '猜数字', 状态: '已加载' }));