@zhin.js/plugin-blackjack 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/lib/bj-command.d.ts +5 -0
- package/lib/bj-command.d.ts.map +1 -0
- package/lib/bj-command.js +21 -0
- package/lib/bj-command.js.map +1 -0
- package/lib/commands.d.ts +6 -0
- package/lib/commands.d.ts.map +1 -0
- package/lib/commands.js +98 -0
- package/lib/commands.js.map +1 -0
- package/lib/engine.d.ts +14 -0
- package/lib/engine.d.ts.map +1 -0
- package/lib/engine.js +65 -0
- package/lib/engine.js.map +1 -0
- package/lib/game-flow.d.ts +8 -0
- package/lib/game-flow.d.ts.map +1 -0
- package/lib/game-flow.js +118 -0
- package/lib/game-flow.js.map +1 -0
- package/lib/hub-register.d.ts +3 -0
- package/lib/hub-register.d.ts.map +1 -0
- package/lib/hub-register.js +29 -0
- package/lib/hub-register.js.map +1 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +26 -0
- package/lib/index.js.map +1 -0
- package/lib/models.d.ts +26 -0
- package/lib/models.d.ts.map +1 -0
- package/lib/models.js +20 -0
- package/lib/models.js.map +1 -0
- package/lib/session-service.d.ts +19 -0
- package/lib/session-service.d.ts.map +1 -0
- package/lib/session-service.js +108 -0
- package/lib/session-service.js.map +1 -0
- package/lib/view.d.ts +7 -0
- package/lib/view.d.ts.map +1 -0
- package/lib/view.js +64 -0
- package/lib/view.js.map +1 -0
- package/package.json +37 -0
- package/plugin.yml +2 -0
- package/src/bj-command.ts +26 -0
- package/src/commands.ts +117 -0
- package/src/engine.ts +67 -0
- package/src/game-flow.ts +164 -0
- package/src/hub-register.ts +28 -0
- package/src/index.ts +36 -0
- package/src/models.ts +47 -0
- package/src/session-service.ts +118 -0
- package/src/view.ts +70 -0
package/README.md
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Message, Plugin } from 'zhin.js';
|
|
2
|
+
import type { SessionService } from './session-service.js';
|
|
3
|
+
export declare const BJ_HELP: string;
|
|
4
|
+
export declare function runBjCommand(plugin: Plugin, services: SessionService, message: Message<any>, action: string): Promise<string | undefined>;
|
|
5
|
+
//# sourceMappingURL=bj-command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bj-command.d.ts","sourceRoot":"","sources":["../src/bj-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAE/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,eAAO,MAAM,OAAO,QAQR,CAAC;AAEb,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,EACrB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAM7B"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { continueGame, startGame } from './game-flow.js';
|
|
2
|
+
export const BJ_HELP = [
|
|
3
|
+
'🃏 **21 点**',
|
|
4
|
+
'',
|
|
5
|
+
'尽量让手牌点数接近 21 且不超过,比庄家大即获胜。',
|
|
6
|
+
'',
|
|
7
|
+
'• `/21点 开始` — 新局',
|
|
8
|
+
'• `/21点 继续` — 刷新界面',
|
|
9
|
+
'• 对局中点击 **要牌** / **停牌**',
|
|
10
|
+
].join('\n');
|
|
11
|
+
export async function runBjCommand(plugin, services, message, action) {
|
|
12
|
+
const a = action.trim().toLowerCase() || 'help';
|
|
13
|
+
if (a === 'help' || a === '帮助')
|
|
14
|
+
return BJ_HELP;
|
|
15
|
+
if (a === 'start' || a === '开始')
|
|
16
|
+
return startGame(plugin, services, message);
|
|
17
|
+
if (a === 'continue' || a === '继续')
|
|
18
|
+
return continueGame(plugin, services, message);
|
|
19
|
+
return `未知操作「${action}」。发送 \`/21点 帮助\`。`;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=bj-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bj-command.js","sourceRoot":"","sources":["../src/bj-command.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAgB,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGvE,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,aAAa;IACb,EAAE;IACF,4BAA4B;IAC5B,EAAE;IACF,kBAAkB;IAClB,oBAAoB;IACpB,yBAAyB;CAC1B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAc,EACd,QAAwB,EACxB,OAAqB,EACrB,MAAc;IAEd,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,MAAM,CAAC;IAChD,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,OAAO,CAAC;IAC/C,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC7E,IAAI,CAAC,KAAK,UAAU,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnF,OAAO,QAAQ,MAAM,mBAAmB,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type Plugin } from 'zhin.js';
|
|
2
|
+
import type { SessionService } from './session-service.js';
|
|
3
|
+
export declare function registerCommands(plugin: Plugin, getServices: () => SessionService | null): void;
|
|
4
|
+
export declare function registerInteractive(plugin: Plugin, getServices: () => SessionService | null): void;
|
|
5
|
+
export declare function registerTextFallback(plugin: Plugin, getServices: () => SessionService | null): void;
|
|
6
|
+
//# sourceMappingURL=commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiD,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAWrF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAsB3D,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,CAG/F;AAgBD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,CAUlG;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,CAoDnG"}
|
package/lib/commands.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { MessageCommand, getActionFromMessage } from 'zhin.js';
|
|
2
|
+
import { buildChoiceFallbackMap, channelKey, parseChoicePayload, registerGameTextMiddleware, resolveGameChoice, resolveGameTextPayload, } from '@zhin.js/game-shared';
|
|
3
|
+
import { BJ_PREFIX, handleChoice } from './game-flow.js';
|
|
4
|
+
import { runBjCommand } from './bj-command.js';
|
|
5
|
+
const VALID_CHOICES = ['hit', 'stand', 'restart'];
|
|
6
|
+
function registerPattern(plugin, pattern, desc, getServices) {
|
|
7
|
+
plugin.addCommand(new MessageCommand(pattern)
|
|
8
|
+
.desc(desc)
|
|
9
|
+
.action(async (message, result) => {
|
|
10
|
+
const services = getServices();
|
|
11
|
+
if (!services)
|
|
12
|
+
return '21 点需要启用 database 配置。';
|
|
13
|
+
const raw = result.params.action ?? '';
|
|
14
|
+
return runBjCommand(plugin, services, message, raw);
|
|
15
|
+
}));
|
|
16
|
+
}
|
|
17
|
+
export function registerCommands(plugin, getServices) {
|
|
18
|
+
registerPattern(plugin, '/21点 [action:word]', '21 点(中文)', getServices);
|
|
19
|
+
registerPattern(plugin, '/bj [action:word]', 'Blackjack (English)', getServices);
|
|
20
|
+
}
|
|
21
|
+
async function resolveChoice(message, services) {
|
|
22
|
+
return resolveGameChoice({
|
|
23
|
+
message,
|
|
24
|
+
gamePrefix: BJ_PREFIX,
|
|
25
|
+
validChoiceIds: VALID_CHOICES,
|
|
26
|
+
getById: (id) => services.getById(id),
|
|
27
|
+
getActiveForUser: (ch, uid) => services.getActiveForUser(ch, uid),
|
|
28
|
+
getByBoardMessageId: (mid) => services.getActiveByBoardMessageId(mid),
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
export function registerInteractive(plugin, getServices) {
|
|
32
|
+
plugin.registerInteractiveHandler(`${BJ_PREFIX}:`, async (message) => {
|
|
33
|
+
const services = getServices();
|
|
34
|
+
if (!services)
|
|
35
|
+
return false;
|
|
36
|
+
const choice = await resolveChoice(message, services);
|
|
37
|
+
if (!choice)
|
|
38
|
+
return false;
|
|
39
|
+
const err = await handleChoice(plugin, services, message, choice.sessionId, choice.choiceId);
|
|
40
|
+
if (err)
|
|
41
|
+
await message.$reply?.(err);
|
|
42
|
+
return true;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
export function registerTextFallback(plugin, getServices) {
|
|
46
|
+
registerGameTextMiddleware(plugin, async (message, next) => {
|
|
47
|
+
const services = getServices();
|
|
48
|
+
if (!services)
|
|
49
|
+
return next();
|
|
50
|
+
const action = getActionFromMessage(message);
|
|
51
|
+
if (action?.payload.startsWith(`${BJ_PREFIX}:`))
|
|
52
|
+
return next();
|
|
53
|
+
const raw = message.$raw?.trim() ?? '';
|
|
54
|
+
const ch = channelKey(message);
|
|
55
|
+
const payloadFromText = resolveGameTextPayload(raw);
|
|
56
|
+
if (payloadFromText?.startsWith(`${BJ_PREFIX}:`)) {
|
|
57
|
+
const parsed = parseChoicePayload(payloadFromText, BJ_PREFIX);
|
|
58
|
+
if (parsed) {
|
|
59
|
+
const session = await services.getById(parsed.sessionId);
|
|
60
|
+
if (session?.channel_key === ch) {
|
|
61
|
+
const err = await handleChoice(plugin, services, message, parsed.sessionId, parsed.choiceId);
|
|
62
|
+
if (err)
|
|
63
|
+
await message.$reply?.(err);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const session = await services.getActiveForUser(ch, message.$sender.id);
|
|
69
|
+
if (!session)
|
|
70
|
+
return next();
|
|
71
|
+
if (session.status !== 'active') {
|
|
72
|
+
const map = buildChoiceFallbackMap(BJ_PREFIX, session.id, [
|
|
73
|
+
{ id: 'restart', label: '再来一局', keepEnabledWhenTerminal: true },
|
|
74
|
+
]);
|
|
75
|
+
const payload = resolveGameTextPayload(raw, map);
|
|
76
|
+
const parsed = payload ? parseChoicePayload(payload, BJ_PREFIX) : null;
|
|
77
|
+
if (parsed?.choiceId === 'restart') {
|
|
78
|
+
const err = await handleChoice(plugin, services, message, parsed.sessionId, 'restart');
|
|
79
|
+
if (err)
|
|
80
|
+
await message.$reply?.(err);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
return next();
|
|
84
|
+
}
|
|
85
|
+
const map = buildChoiceFallbackMap(BJ_PREFIX, session.id, [
|
|
86
|
+
{ id: 'hit', label: '要牌' },
|
|
87
|
+
{ id: 'stand', label: '停牌' },
|
|
88
|
+
]);
|
|
89
|
+
const payload = resolveGameTextPayload(raw, map);
|
|
90
|
+
const parsed = payload ? parseChoicePayload(payload, BJ_PREFIX) : null;
|
|
91
|
+
if (!parsed || parsed.sessionId !== session.id)
|
|
92
|
+
return next();
|
|
93
|
+
const err = await handleChoice(plugin, services, message, session.id, parsed.choiceId);
|
|
94
|
+
if (err)
|
|
95
|
+
await message.$reply?.(err);
|
|
96
|
+
}, 'bj:text');
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,cAAc,EAAE,oBAAoB,EAAe,MAAM,SAAS,CAAC;AACrF,OAAO,EACL,sBAAsB,EACtB,UAAU,EACV,kBAAkB,EAClB,0BAA0B,EAC1B,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,CAAU,CAAC;AAE3D,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,uBAAuB,CAAC;QAC9C,MAAM,GAAG,GAAI,MAAM,CAAC,MAAM,CAAC,MAA6B,IAAI,EAAE,CAAC;QAC/D,OAAO,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IACtD,CAAC,CAAC,CACL,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAc,EAAE,WAAwC;IACvF,eAAe,CAAC,MAAM,EAAE,oBAAoB,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;IACvE,eAAe,CAAC,MAAM,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,WAAW,CAAC,CAAC;AACnF,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,OAAqB,EACrB,QAAwB;IAExB,OAAO,iBAAiB,CAAC;QACvB,OAAO;QACP,UAAU,EAAE,SAAS;QACrB,cAAc,EAAE,aAAa;QAC7B,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACrC,gBAAgB,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,EAAE,GAAG,CAAC;QACjE,mBAAmB,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC,GAAG,CAAC;KACtE,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAc,EAAE,WAAwC;IAC1F,MAAM,CAAC,0BAA0B,CAAC,GAAG,SAAS,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACnE,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC5B,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC1B,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC7F,IAAI,GAAG;YAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,WAAwC;IAC3F,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,MAAM,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,SAAS,GAAG,CAAC;YAAE,OAAO,IAAI,EAAE,CAAC;QAE/D,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACvC,MAAM,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;QAE/B,MAAM,eAAe,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;QACpD,IAAI,eAAe,EAAE,UAAU,CAAC,GAAG,SAAS,GAAG,CAAC,EAAE,CAAC;YACjD,MAAM,MAAM,GAAG,kBAAkB,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;YAC9D,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;gBACzD,IAAI,OAAO,EAAE,WAAW,KAAK,EAAE,EAAE,CAAC;oBAChC,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;oBAC7F,IAAI,GAAG;wBAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;oBACrC,OAAO;gBACT,CAAC;YACH,CAAC;QACH,CAAC;QAED,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,IAAI,OAAO,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAChC,MAAM,GAAG,GAAG,sBAAsB,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE;gBACxD,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,IAAI,EAAE;aAChE,CAAC,CAAC;YACH,MAAM,OAAO,GAAG,sBAAsB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACjD,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACvE,IAAI,MAAM,EAAE,QAAQ,KAAK,SAAS,EAAE,CAAC;gBACnC,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;gBACvF,IAAI,GAAG;oBAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;gBACrC,OAAO;YACT,CAAC;YACD,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,MAAM,GAAG,GAAG,sBAAsB,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE;YACxD,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE;YAC1B,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE;SAC7B,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,sBAAsB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACvE,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE;YAAE,OAAO,IAAI,EAAE,CAAC;QAE9D,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QACvF,IAAI,GAAG;YAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;IACvC,CAAC,EAAE,SAAS,CAAC,CAAC;AAChB,CAAC"}
|
package/lib/engine.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const BJ_PREFIX = "bj";
|
|
2
|
+
export declare const TARGET = 21;
|
|
3
|
+
declare const RANKS: readonly ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"];
|
|
4
|
+
declare const SUITS: readonly ["♠", "♥", "♦", "♣"];
|
|
5
|
+
export type Card = `${typeof RANKS[number]}${typeof SUITS[number]}`;
|
|
6
|
+
export declare function freshDeck(): Card[];
|
|
7
|
+
export declare function cardValue(rank: string): number;
|
|
8
|
+
export declare function handValue(cards: readonly string[]): number;
|
|
9
|
+
export declare function formatHand(cards: readonly string[], hideSecond?: boolean): string;
|
|
10
|
+
export declare function isBlackjack(cards: readonly string[]): boolean;
|
|
11
|
+
export declare function dealerShouldHit(cards: readonly string[]): boolean;
|
|
12
|
+
export declare function compareHands(player: readonly string[], dealer: readonly string[]): 'won' | 'lost' | 'draw';
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,OAAO,CAAC;AAC9B,eAAO,MAAM,MAAM,KAAK,CAAC;AAEzB,QAAA,MAAM,KAAK,6EAA8E,CAAC;AAC1F,QAAA,MAAM,KAAK,+BAAgC,CAAC;AAE5C,MAAM,MAAM,IAAI,GAAG,GAAG,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,OAAO,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;AAEpE,wBAAgB,SAAS,IAAI,IAAI,EAAE,CAYlC;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI9C;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAa1D;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,UAAU,UAAQ,GAAG,MAAM,CAK/E;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAE7D;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAEjE;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAQ1G"}
|
package/lib/engine.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export const BJ_PREFIX = 'bj';
|
|
2
|
+
export const TARGET = 21;
|
|
3
|
+
const RANKS = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'];
|
|
4
|
+
const SUITS = ['♠', '♥', '♦', '♣'];
|
|
5
|
+
export function freshDeck() {
|
|
6
|
+
const deck = [];
|
|
7
|
+
for (const r of RANKS) {
|
|
8
|
+
for (const s of SUITS) {
|
|
9
|
+
deck.push(`${r}${s}`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
for (let i = deck.length - 1; i > 0; i--) {
|
|
13
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
14
|
+
[deck[i], deck[j]] = [deck[j], deck[i]];
|
|
15
|
+
}
|
|
16
|
+
return deck;
|
|
17
|
+
}
|
|
18
|
+
export function cardValue(rank) {
|
|
19
|
+
if (rank === 'A')
|
|
20
|
+
return 11;
|
|
21
|
+
if (rank === 'J' || rank === 'Q' || rank === 'K')
|
|
22
|
+
return 10;
|
|
23
|
+
return Number(rank);
|
|
24
|
+
}
|
|
25
|
+
export function handValue(cards) {
|
|
26
|
+
let total = 0;
|
|
27
|
+
let aces = 0;
|
|
28
|
+
for (const c of cards) {
|
|
29
|
+
const rank = c.slice(0, c.length - 1);
|
|
30
|
+
if (rank === 'A')
|
|
31
|
+
aces++;
|
|
32
|
+
total += cardValue(rank);
|
|
33
|
+
}
|
|
34
|
+
while (total > TARGET && aces > 0) {
|
|
35
|
+
total -= 10;
|
|
36
|
+
aces--;
|
|
37
|
+
}
|
|
38
|
+
return total;
|
|
39
|
+
}
|
|
40
|
+
export function formatHand(cards, hideSecond = false) {
|
|
41
|
+
if (hideSecond && cards.length >= 2) {
|
|
42
|
+
return `${cards[0]} 🂠 (${handValue([cards[0]])})`;
|
|
43
|
+
}
|
|
44
|
+
return `${cards.join(' ')} (${handValue(cards)})`;
|
|
45
|
+
}
|
|
46
|
+
export function isBlackjack(cards) {
|
|
47
|
+
return cards.length === 2 && handValue(cards) === TARGET;
|
|
48
|
+
}
|
|
49
|
+
export function dealerShouldHit(cards) {
|
|
50
|
+
return handValue(cards) < 17;
|
|
51
|
+
}
|
|
52
|
+
export function compareHands(player, dealer) {
|
|
53
|
+
const pv = handValue(player);
|
|
54
|
+
const dv = handValue(dealer);
|
|
55
|
+
if (pv > TARGET)
|
|
56
|
+
return 'lost';
|
|
57
|
+
if (dv > TARGET)
|
|
58
|
+
return 'won';
|
|
59
|
+
if (pv > dv)
|
|
60
|
+
return 'won';
|
|
61
|
+
if (pv < dv)
|
|
62
|
+
return 'lost';
|
|
63
|
+
return 'draw';
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Message, Plugin } from 'zhin.js';
|
|
2
|
+
import { BJ_PREFIX, handValue, TARGET } from './engine.js';
|
|
3
|
+
import type { SessionService } from './session-service.js';
|
|
4
|
+
export declare function startGame(plugin: Plugin, services: SessionService, message: Message<any>): Promise<string | undefined>;
|
|
5
|
+
export declare function continueGame(plugin: Plugin, services: SessionService, message: Message<any>): Promise<string>;
|
|
6
|
+
export declare function handleChoice(plugin: Plugin, services: SessionService, message: Message<any>, sessionId: string, choiceId: string): Promise<string | null>;
|
|
7
|
+
export { BJ_PREFIX, handValue, TARGET };
|
|
8
|
+
//# sourceMappingURL=game-flow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"game-flow.d.ts","sourceRoot":"","sources":["../src/game-flow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAExD,OAAO,EACL,SAAS,EAGT,SAAS,EACT,MAAM,EACP,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AA8D3D,wBAAsB,SAAS,CAC7B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,GACpB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAiB7B;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,GACpB,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,EACrB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA8CxB;AAED,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC"}
|
package/lib/game-flow.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { recordGameOutcome } from '@zhin.js/game-shared';
|
|
2
|
+
import { BJ_PREFIX, compareHands, dealerShouldHit, handValue, TARGET, } from './engine.js';
|
|
3
|
+
import { parseCards, parseDeck } from './session-service.js';
|
|
4
|
+
import { buildBjView, naturalOutcome, playerBust } from './view.js';
|
|
5
|
+
async function sendOrEditView(plugin, services, message, session, terminal = false, revealDealer = false) {
|
|
6
|
+
const content = buildBjView(session, terminal, revealDealer, message.$channel.type);
|
|
7
|
+
const adapter = plugin.root.inject(message.$adapter);
|
|
8
|
+
if (session.board_message_id) {
|
|
9
|
+
const msgId = await adapter.editMessage({
|
|
10
|
+
messageId: session.board_message_id,
|
|
11
|
+
context: String(message.$adapter),
|
|
12
|
+
endpoint: message.$endpoint,
|
|
13
|
+
id: message.$channel.id,
|
|
14
|
+
type: message.$channel.type,
|
|
15
|
+
content,
|
|
16
|
+
});
|
|
17
|
+
if (msgId !== session.board_message_id) {
|
|
18
|
+
await services.updateSession(session.id, { board_message_id: msgId });
|
|
19
|
+
}
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const msgId = await message.$reply?.(content);
|
|
23
|
+
if (msgId)
|
|
24
|
+
await services.updateSession(session.id, { board_message_id: msgId });
|
|
25
|
+
}
|
|
26
|
+
async function finishRound(plugin, services, message, session, status) {
|
|
27
|
+
await services.updateSession(session.id, { status });
|
|
28
|
+
const updated = (await services.getById(session.id));
|
|
29
|
+
if (status === 'won')
|
|
30
|
+
void recordGameOutcome(message, 'blackjack', 'won', 30);
|
|
31
|
+
else if (status === 'lost')
|
|
32
|
+
void recordGameOutcome(message, 'blackjack', 'lost');
|
|
33
|
+
else if (status === 'draw')
|
|
34
|
+
void recordGameOutcome(message, 'blackjack', 'draw');
|
|
35
|
+
await sendOrEditView(plugin, services, message, updated, true, true);
|
|
36
|
+
}
|
|
37
|
+
async function dealerPlay(deck, dealer) {
|
|
38
|
+
const hand = [...dealer];
|
|
39
|
+
while (dealerShouldHit(hand)) {
|
|
40
|
+
const card = deck.pop();
|
|
41
|
+
if (!card)
|
|
42
|
+
break;
|
|
43
|
+
hand.push(card);
|
|
44
|
+
}
|
|
45
|
+
return hand;
|
|
46
|
+
}
|
|
47
|
+
export async function startGame(plugin, services, message) {
|
|
48
|
+
const ch = `${message.$adapter}-${message.$endpoint}-${message.$channel.type}:${message.$channel.id}`;
|
|
49
|
+
const active = await services.getActiveByChannel(ch);
|
|
50
|
+
if (active) {
|
|
51
|
+
if (active.player_id === message.$sender.id) {
|
|
52
|
+
return '你已有进行中的 21 点,发送「21点 继续」刷新。';
|
|
53
|
+
}
|
|
54
|
+
return `本频道 ${active.player_name} 正在玩 21 点。`;
|
|
55
|
+
}
|
|
56
|
+
const session = await services.createSession(message);
|
|
57
|
+
const natural = naturalOutcome(session);
|
|
58
|
+
if (natural) {
|
|
59
|
+
await finishRound(plugin, services, message, session, natural);
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
await sendOrEditView(plugin, services, message, session);
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
export async function continueGame(plugin, services, message) {
|
|
66
|
+
const session = await services.getActiveForUser(`${message.$adapter}-${message.$endpoint}-${message.$channel.type}:${message.$channel.id}`, message.$sender.id);
|
|
67
|
+
if (!session)
|
|
68
|
+
return '你没有进行中的 21 点,发送「21点 开始」。';
|
|
69
|
+
await sendOrEditView(plugin, services, message, session);
|
|
70
|
+
return '已刷新 21 点界面。';
|
|
71
|
+
}
|
|
72
|
+
export async function handleChoice(plugin, services, message, sessionId, choiceId) {
|
|
73
|
+
const session = await services.getById(sessionId);
|
|
74
|
+
if (!session)
|
|
75
|
+
return '对局不存在。';
|
|
76
|
+
if (session.player_id !== message.$sender.id)
|
|
77
|
+
return '这是别人的对局。';
|
|
78
|
+
if (session.status !== 'active' && choiceId === 'restart') {
|
|
79
|
+
await services.updateSession(session.id, { status: 'aborted' });
|
|
80
|
+
await startGame(plugin, services, message);
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
if (session.status !== 'active')
|
|
84
|
+
return '对局已结束,请点击再来一局。';
|
|
85
|
+
let deck = parseDeck(session.deck_json);
|
|
86
|
+
let player = parseCards(session.player_cards_json);
|
|
87
|
+
let dealer = parseCards(session.dealer_cards_json);
|
|
88
|
+
if (choiceId === 'hit') {
|
|
89
|
+
const card = deck.pop();
|
|
90
|
+
if (!card)
|
|
91
|
+
return '牌堆已空。';
|
|
92
|
+
player = [...player, card];
|
|
93
|
+
await services.updateSession(session.id, {
|
|
94
|
+
deck_json: JSON.stringify(deck),
|
|
95
|
+
player_cards_json: JSON.stringify(player),
|
|
96
|
+
});
|
|
97
|
+
if (playerBust({ ...session, player_cards_json: JSON.stringify(player) })) {
|
|
98
|
+
await finishRound(plugin, services, message, session, 'lost');
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
const updated = (await services.getById(session.id));
|
|
102
|
+
await sendOrEditView(plugin, services, message, updated);
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
if (choiceId !== 'stand')
|
|
106
|
+
return '无效操作。';
|
|
107
|
+
dealer = await dealerPlay(deck, dealer);
|
|
108
|
+
await services.updateSession(session.id, {
|
|
109
|
+
deck_json: JSON.stringify(deck),
|
|
110
|
+
dealer_cards_json: JSON.stringify(dealer),
|
|
111
|
+
});
|
|
112
|
+
const outcome = compareHands(player, dealer);
|
|
113
|
+
const status = outcome === 'won' ? 'won' : outcome === 'lost' ? 'lost' : 'draw';
|
|
114
|
+
await finishRound(plugin, services, message, session, status);
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
export { BJ_PREFIX, handValue, TARGET };
|
|
118
|
+
//# sourceMappingURL=game-flow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"game-flow.js","sourceRoot":"","sources":["../src/game-flow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub-register.d.ts","sourceRoot":"","sources":["../src/hub-register.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,cAAc,GAAG,IAAI,GAAG,MAAM,IAAI,CAsBlF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { getPlugin } from 'zhin.js';
|
|
2
|
+
import { ensureGameHubService } from '@zhin.js/game-shared';
|
|
3
|
+
import { runBjCommand, BJ_HELP } from './bj-command.js';
|
|
4
|
+
export function registerBjHub(getServices) {
|
|
5
|
+
const plugin = getPlugin();
|
|
6
|
+
ensureGameHubService(plugin);
|
|
7
|
+
return plugin.registerGame({
|
|
8
|
+
id: 'blackjack',
|
|
9
|
+
title: '21 点',
|
|
10
|
+
icon: '🃏',
|
|
11
|
+
description: '经典 Blackjack,要牌或停牌挑战庄家',
|
|
12
|
+
commandPrefix: '/21点',
|
|
13
|
+
quickStart: '开始',
|
|
14
|
+
aliases: ['bj', '21点'],
|
|
15
|
+
menus: [
|
|
16
|
+
{ id: 'start', label: '🎮 开始新局', style: 'primary' },
|
|
17
|
+
{ id: 'help', label: '📖 玩法说明' },
|
|
18
|
+
],
|
|
19
|
+
runAction: async (actionId, ctx) => {
|
|
20
|
+
const services = getServices();
|
|
21
|
+
if (!services)
|
|
22
|
+
return '21 点需要启用 database 配置。';
|
|
23
|
+
if (actionId === 'help')
|
|
24
|
+
return BJ_HELP;
|
|
25
|
+
return runBjCommand(plugin, services, ctx.message, actionId === 'start' ? '开始' : actionId);
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=hub-register.js.map
|
|
@@ -0,0 +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,YAAY,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAGxD,MAAM,UAAU,aAAa,CAAC,WAAwC;IACpE,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,OAAO,MAAM,CAAC,YAAY,CAAC;QACzB,EAAE,EAAE,WAAW;QACf,KAAK,EAAE,MAAM;QACb,IAAI,EAAE,IAAI;QACV,WAAW,EAAE,wBAAwB;QACrC,aAAa,EAAE,MAAM;QACrB,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC;QACtB,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,uBAAuB,CAAC;YAC9C,IAAI,QAAQ,KAAK,MAAM;gBAAE,OAAO,OAAO,CAAC;YACxC,OAAO,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,OAAO,EAAE,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC7F,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
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 { registerBjHub } 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({ 模块: '21点', 数据模型: '已就绪' }));
|
|
13
|
+
});
|
|
14
|
+
registerBjHub(() => 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({ '21点': '清理超时局', count: n }));
|
|
24
|
+
}));
|
|
25
|
+
logger.info(formatCompact({ 模块: '21点', 状态: '已加载' }));
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +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,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,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,aAAa,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC;AAC9B,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,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AACvE,CAAC,CAAC,CACH,CAAC;AAEF,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC"}
|
package/lib/models.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Models, Plugin } from 'zhin.js';
|
|
2
|
+
export type BjSessionStatus = 'active' | 'won' | 'lost' | 'draw' | 'aborted';
|
|
3
|
+
declare module 'zhin.js' {
|
|
4
|
+
interface Models {
|
|
5
|
+
bj_sessions: {
|
|
6
|
+
id: string;
|
|
7
|
+
adapter: string;
|
|
8
|
+
endpoint: string;
|
|
9
|
+
channel_type: string;
|
|
10
|
+
channel_id: string;
|
|
11
|
+
channel_key: string;
|
|
12
|
+
player_id: string;
|
|
13
|
+
player_name: string;
|
|
14
|
+
deck_json: string;
|
|
15
|
+
player_cards_json: string;
|
|
16
|
+
dealer_cards_json: string;
|
|
17
|
+
board_message_id: string;
|
|
18
|
+
status: BjSessionStatus;
|
|
19
|
+
updated_at: number;
|
|
20
|
+
created_at: number;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export type BjSessionRow = Models['bj_sessions'];
|
|
25
|
+
export declare function registerModels(plugin: Plugin): void;
|
|
26
|
+
//# sourceMappingURL=models.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAE9C,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAE7E,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,MAAM;QACd,WAAW,EAAE;YACX,EAAE,EAAE,MAAM,CAAC;YACX,OAAO,EAAE,MAAM,CAAC;YAChB,QAAQ,EAAE,MAAM,CAAC;YACjB,YAAY,EAAE,MAAM,CAAC;YACrB,UAAU,EAAE,MAAM,CAAC;YACnB,WAAW,EAAE,MAAM,CAAC;YACpB,SAAS,EAAE,MAAM,CAAC;YAClB,WAAW,EAAE,MAAM,CAAC;YACpB,SAAS,EAAE,MAAM,CAAC;YAClB,iBAAiB,EAAE,MAAM,CAAC;YAC1B,iBAAiB,EAAE,MAAM,CAAC;YAC1B,gBAAgB,EAAE,MAAM,CAAC;YACzB,MAAM,EAAE,eAAe,CAAC;YACxB,UAAU,EAAE,MAAM,CAAC;YACnB,UAAU,EAAE,MAAM,CAAC;SACpB,CAAC;KACH;CACF;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;AAEjD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAkBnD"}
|
package/lib/models.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function registerModels(plugin) {
|
|
2
|
+
plugin.defineModel('bj_sessions', {
|
|
3
|
+
id: { type: 'text', primary: true },
|
|
4
|
+
adapter: { type: 'text', nullable: false },
|
|
5
|
+
endpoint: { type: 'text', nullable: false },
|
|
6
|
+
channel_type: { type: 'text', nullable: false },
|
|
7
|
+
channel_id: { type: 'text', nullable: false },
|
|
8
|
+
channel_key: { type: 'text', nullable: false },
|
|
9
|
+
player_id: { type: 'text', nullable: false },
|
|
10
|
+
player_name: { type: 'text', default: '' },
|
|
11
|
+
deck_json: { type: 'text', default: '[]' },
|
|
12
|
+
player_cards_json: { type: 'text', default: '[]' },
|
|
13
|
+
dealer_cards_json: { type: 'text', default: '[]' },
|
|
14
|
+
board_message_id: { type: 'text', default: '' },
|
|
15
|
+
status: { type: 'text', default: 'active' },
|
|
16
|
+
updated_at: { type: 'integer', default: 0 },
|
|
17
|
+
created_at: { type: 'integer', default: 0 },
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=models.js.map
|
|
@@ -0,0 +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,aAAa,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,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;QAC1C,iBAAiB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;QAClD,iBAAiB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;QAClD,gBAAgB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QAC/C,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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Database, DatabaseFeature, Message, Models } from 'zhin.js';
|
|
2
|
+
import type { BjSessionRow } from './models.js';
|
|
3
|
+
export type BjDatabase = Database<unknown, Models, string>;
|
|
4
|
+
export declare function resolveGameDatabase(feature: DatabaseFeature): BjDatabase;
|
|
5
|
+
export declare class SessionService {
|
|
6
|
+
private readonly db;
|
|
7
|
+
constructor(db: BjDatabase);
|
|
8
|
+
createSession(message: Message<any>): Promise<BjSessionRow>;
|
|
9
|
+
getById(id: string): Promise<BjSessionRow | null>;
|
|
10
|
+
getActiveForUser(channelKeyValue: string, userId: string): Promise<BjSessionRow | null>;
|
|
11
|
+
getActiveByChannel(channelKeyValue: string): Promise<BjSessionRow | null>;
|
|
12
|
+
getActiveByBoardMessageId(messageId: string): Promise<BjSessionRow | null>;
|
|
13
|
+
updateSession(id: string, patch: Partial<BjSessionRow>): Promise<void>;
|
|
14
|
+
abortStale(maxAgeMs: number): Promise<number>;
|
|
15
|
+
}
|
|
16
|
+
export declare function createServices(db: BjDatabase): SessionService;
|
|
17
|
+
export declare function parseCards(json: string | string[]): string[];
|
|
18
|
+
export declare function parseDeck(json: string | string[]): string[];
|
|
19
|
+
//# sourceMappingURL=session-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-service.d.ts","sourceRoot":"","sources":["../src/session-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,EAAgB,MAAM,SAAS,CAAC;AAExF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAQ3D,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,eAAe,GAAG,UAAU,CAExE;AAED,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,UAAU;IAErC,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC;IA0B3D,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAIjD,gBAAgB,CAAC,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IASvF,kBAAkB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAQzE,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAQ1E,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAItE,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAapD;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,UAAU,GAAG,cAAc,CAE7D;AAeD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,CAE5D;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,CAE3D"}
|