@zhin.js/plugin-dice-duel 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.
- package/README.md +31 -0
- package/commands/dice/[action:string=].ts +15 -0
- package/lib/dice-command.d.ts +4 -3
- package/lib/dice-command.js +5 -1
- package/lib/dice-command.js.map +1 -1
- package/lib/engine.d.ts +0 -1
- package/lib/engine.js +2 -1
- package/lib/engine.js.map +1 -1
- package/lib/game-flow.d.ts +6 -7
- package/lib/game-flow.js +18 -18
- package/lib/game-flow.js.map +1 -1
- package/lib/index.d.ts +8 -2
- package/lib/index.js +8 -25
- package/lib/index.js.map +1 -1
- package/lib/memory-db.d.ts +6 -0
- package/lib/memory-db.js +18 -0
- package/lib/memory-db.js.map +1 -0
- package/lib/models.d.ts +5 -4
- package/lib/models.js +2 -2
- package/lib/models.js.map +1 -1
- package/lib/runtime-store.d.ts +6 -0
- package/lib/runtime-store.js +7 -0
- package/lib/runtime-store.js.map +1 -0
- package/lib/session-service.d.ts +1 -3
- package/lib/session-service.js +3 -9
- package/lib/session-service.js.map +1 -1
- package/lib/view.d.ts +2 -3
- package/lib/view.js +5 -3
- package/lib/view.js.map +1 -1
- package/middlewares/dice-alias.ts +18 -0
- package/middlewares/dice-choice.ts +62 -0
- package/package.json +45 -10
- package/plugin.ts +63 -0
- package/schema.json +6 -0
- package/src/dice-command.ts +12 -3
- package/src/engine.ts +3 -1
- package/src/game-flow.ts +21 -24
- package/src/index.ts +9 -36
- package/src/memory-db.ts +22 -0
- package/src/models.ts +7 -4
- package/src/runtime-store.ts +9 -0
- package/src/session-service.ts +4 -9
- package/src/view.ts +6 -3
- package/lib/commands.d.ts +0 -6
- package/lib/commands.d.ts.map +0 -1
- package/lib/commands.js +0 -82
- package/lib/commands.js.map +0 -1
- package/lib/dice-command.d.ts.map +0 -1
- package/lib/engine.d.ts.map +0 -1
- package/lib/game-flow.d.ts.map +0 -1
- package/lib/hub-register.d.ts +0 -5
- package/lib/hub-register.d.ts.map +0 -1
- package/lib/hub-register.js +0 -26
- package/lib/hub-register.js.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/models.d.ts.map +0 -1
- package/lib/session-service.d.ts.map +0 -1
- package/lib/view.d.ts.map +0 -1
- package/plugin.yml +0 -2
- package/src/commands.ts +0 -98
- package/src/hub-register.ts +0 -30
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/plugin-dice-duel",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Zhin.js 骰子对决 — 三局两胜比大小",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "Zhin.js 骰子对决 — 三局两胜比大小 (Plugin Runtime)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
7
7
|
"types": "./lib/index.d.ts",
|
|
@@ -14,24 +14,59 @@
|
|
|
14
14
|
"./package.json": "./package.json"
|
|
15
15
|
},
|
|
16
16
|
"files": [
|
|
17
|
+
"plugin.ts",
|
|
18
|
+
"schema.json",
|
|
19
|
+
"commands",
|
|
20
|
+
"middlewares",
|
|
17
21
|
"src",
|
|
18
22
|
"lib",
|
|
19
|
-
"plugin.yml",
|
|
20
23
|
"README.md"
|
|
21
24
|
],
|
|
22
25
|
"license": "MIT",
|
|
23
|
-
"peerDependencies": {
|
|
24
|
-
"zhin.js": "4.1.0"
|
|
25
|
-
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@zhin.js/
|
|
27
|
+
"@zhin.js/command": "1.0.1",
|
|
28
|
+
"@zhin.js/core": "1.3.5",
|
|
29
|
+
"@zhin.js/game-kit": "1.0.2",
|
|
30
|
+
"@zhin.js/middleware": "1.0.1",
|
|
31
|
+
"@zhin.js/plugin-runtime": "1.0.1"
|
|
28
32
|
},
|
|
29
33
|
"devDependencies": {
|
|
30
34
|
"typescript": "^6.0.3",
|
|
31
|
-
"
|
|
35
|
+
"vitest": "^4.1.10"
|
|
36
|
+
},
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/zhinjs/zhin.git",
|
|
40
|
+
"directory": "plugins/games/dice-duel"
|
|
41
|
+
},
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public",
|
|
44
|
+
"registry": "https://registry.npmjs.org"
|
|
45
|
+
},
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": "^20.19.0 || >=22.12.0"
|
|
48
|
+
},
|
|
49
|
+
"zhin": {
|
|
50
|
+
"protocol": 1,
|
|
51
|
+
"type": "plugin",
|
|
52
|
+
"entry": "./plugin.ts",
|
|
53
|
+
"engine": "^1.0.0",
|
|
54
|
+
"runtime": "trusted",
|
|
55
|
+
"features": [
|
|
56
|
+
{
|
|
57
|
+
"package": "@zhin.js/command",
|
|
58
|
+
"api": "^1.0.0"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"package": "@zhin.js/middleware",
|
|
62
|
+
"api": "^1.0.0"
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
"plugins": []
|
|
32
66
|
},
|
|
33
67
|
"scripts": {
|
|
34
|
-
"build": "tsc
|
|
35
|
-
"clean": "rimraf lib"
|
|
68
|
+
"build": "tsc",
|
|
69
|
+
"clean": "rimraf lib",
|
|
70
|
+
"test": "NODE_OPTIONS=--experimental-strip-types vitest run --root ../../.. plugins/games/dice-duel/tests"
|
|
36
71
|
}
|
|
37
72
|
}
|
package/plugin.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { definePlugin, databaseHostToken, scheduleHostToken } from '@zhin.js/plugin-runtime';
|
|
2
|
+
import {
|
|
3
|
+
registerRuntimeGame,
|
|
4
|
+
initGameRecordHost,
|
|
5
|
+
DEFAULT_GAME_STALE_CRON,
|
|
6
|
+
DEFAULT_GAME_STALE_IDLE_MS,
|
|
7
|
+
} from '@zhin.js/game-kit';
|
|
8
|
+
import { mountDiceHostServices, mountDiceMemoryServices } from './src/memory-db.js';
|
|
9
|
+
import { gameServicesToken } from './src/runtime-store.js';
|
|
10
|
+
import type { SessionService } from './src/session-service.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Plugin Runtime:
|
|
14
|
+
* - Commands under `commands/` are authoritative (help + start/continue/quit via in-memory DB).
|
|
15
|
+
* - DB: prefer databaseHostToken; else in-memory SessionService.
|
|
16
|
+
* - Choice middleware under `middlewares/` handles dice roll payloads (Sandbox action→text).
|
|
17
|
+
*/
|
|
18
|
+
export default definePlugin({
|
|
19
|
+
name: 'dice-duel',
|
|
20
|
+
metadata: {
|
|
21
|
+
displayName: 'Dice Duel',
|
|
22
|
+
},
|
|
23
|
+
setup(context) {
|
|
24
|
+
let services: SessionService;
|
|
25
|
+
if (context.resources.has(databaseHostToken)) {
|
|
26
|
+
const host = context.resources.use(databaseHostToken);
|
|
27
|
+
services = mountDiceHostServices(host);
|
|
28
|
+
context.lifecycle.add(initGameRecordHost(host));
|
|
29
|
+
} else {
|
|
30
|
+
services = mountDiceMemoryServices();
|
|
31
|
+
}
|
|
32
|
+
context.resources.provide(gameServicesToken, services);
|
|
33
|
+
const disposeHub = registerRuntimeGame({
|
|
34
|
+
id: 'dice',
|
|
35
|
+
title: '骰子对决',
|
|
36
|
+
icon: '🎲',
|
|
37
|
+
description: '掷骰比大小,三局两胜',
|
|
38
|
+
commandPrefix: '/骰子',
|
|
39
|
+
quickStart: '开始',
|
|
40
|
+
aliases: ['dice'],
|
|
41
|
+
menus: [
|
|
42
|
+
{ id: 'start', label: '🎮 开始对局' },
|
|
43
|
+
{ id: 'continue', label: '🔄 继续' },
|
|
44
|
+
{ id: 'help', label: '📖 玩法说明' },
|
|
45
|
+
],
|
|
46
|
+
});
|
|
47
|
+
context.lifecycle.add(disposeHub);
|
|
48
|
+
|
|
49
|
+
if (context.resources.has(scheduleHostToken)) {
|
|
50
|
+
const schedule = context.resources.use(scheduleHostToken);
|
|
51
|
+
const disposeCron = schedule.register({
|
|
52
|
+
id: 'dice/abort-stale',
|
|
53
|
+
cron: DEFAULT_GAME_STALE_CRON,
|
|
54
|
+
description: 'Abort stale dice-duel sessions',
|
|
55
|
+
async execute() {
|
|
56
|
+
if (!services.abortStale) return;
|
|
57
|
+
await services.abortStale(DEFAULT_GAME_STALE_IDLE_MS);
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
context.lifecycle.add(disposeCron);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
});
|
package/schema.json
ADDED
package/src/dice-command.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Message, Plugin } from 'zhin.js';
|
|
2
|
-
import { channelKey } from '@zhin.js/game-
|
|
1
|
+
import type { Message, Plugin } from '@zhin.js/core';
|
|
2
|
+
import { channelKey } from '@zhin.js/game-kit';
|
|
3
3
|
import { continueGame, startGame } from './game-flow.js';
|
|
4
4
|
import type { SessionService } from './session-service.js';
|
|
5
5
|
|
|
@@ -12,7 +12,7 @@ export const DICE_HELP = [
|
|
|
12
12
|
].join('\n');
|
|
13
13
|
|
|
14
14
|
export async function runDiceCommand(
|
|
15
|
-
plugin: Plugin,
|
|
15
|
+
plugin: Plugin | null,
|
|
16
16
|
services: SessionService,
|
|
17
17
|
message: Message<any>,
|
|
18
18
|
action: string,
|
|
@@ -43,3 +43,12 @@ export async function runDiceCommand(
|
|
|
43
43
|
|
|
44
44
|
return `未知子命令:${action}\n\n${DICE_HELP}`;
|
|
45
45
|
}
|
|
46
|
+
|
|
47
|
+
/** Plugin Runtime / smoke: text-only, no Adapter.editMessage. */
|
|
48
|
+
export async function runDiceCommandText(
|
|
49
|
+
services: SessionService,
|
|
50
|
+
message: Message<any>,
|
|
51
|
+
action: string,
|
|
52
|
+
): Promise<string> {
|
|
53
|
+
return (await runDiceCommand(null, services, message, action)) ?? '';
|
|
54
|
+
}
|
package/src/engine.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { secureRandomIntInclusive } from '@zhin.js/game-kit';
|
|
2
|
+
|
|
1
3
|
export const DICE_PREFIX = 'dice';
|
|
2
4
|
export const WIN_TARGET = 2; // best of 3 -> first to 2
|
|
3
5
|
|
|
4
6
|
export function rollD6(): number {
|
|
5
|
-
return 1
|
|
7
|
+
return secureRandomIntInclusive(1, 6);
|
|
6
8
|
}
|
|
7
9
|
|
|
8
10
|
export function diceEmoji(n: number): string {
|
package/src/game-flow.ts
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
import type { Adapter, Message, Plugin } from 'zhin.js';
|
|
1
|
+
import type { Adapter, Message, Plugin } from '@zhin.js/core';
|
|
2
|
+
import { plainTextFromSendContent, recordGameOutcome } from '@zhin.js/game-kit';
|
|
2
3
|
import type { DiceSessionRow } from './models.js';
|
|
3
4
|
import { compareRolls, DICE_PREFIX, rollD6, WIN_TARGET } from './engine.js';
|
|
4
5
|
import type { SessionService } from './session-service.js';
|
|
5
6
|
import { buildDiceView } from './view.js';
|
|
6
7
|
|
|
7
8
|
export async function sendOrEditView(
|
|
8
|
-
plugin: Plugin,
|
|
9
|
+
plugin: Plugin | null,
|
|
9
10
|
services: SessionService,
|
|
10
11
|
message: Message<any>,
|
|
11
12
|
session: DiceSessionRow,
|
|
12
13
|
lastRound?: { player: number; bot: number; result: 0 | 1 | 2 },
|
|
13
|
-
): Promise<void> {
|
|
14
|
-
const content = buildDiceView(session, lastRound);
|
|
14
|
+
): Promise<string | void> {
|
|
15
|
+
const content = buildDiceView(session, lastRound, message.$channel.type);
|
|
16
|
+
if (!plugin) return plainTextFromSendContent(content);
|
|
17
|
+
|
|
15
18
|
const adapter = plugin.root.inject(message.$adapter) as Adapter;
|
|
16
19
|
|
|
17
20
|
if (session.board_message_id) {
|
|
@@ -34,7 +37,7 @@ export async function sendOrEditView(
|
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
export async function startGame(
|
|
37
|
-
plugin: Plugin,
|
|
40
|
+
plugin: Plugin | null,
|
|
38
41
|
services: SessionService,
|
|
39
42
|
message: Message<any>,
|
|
40
43
|
): Promise<string | undefined> {
|
|
@@ -47,12 +50,12 @@ export async function startGame(
|
|
|
47
50
|
return `本频道 ${active.player_name} 正在掷骰对决中。`;
|
|
48
51
|
}
|
|
49
52
|
const session = await services.createSession(message);
|
|
50
|
-
await sendOrEditView(plugin, services, message, session);
|
|
51
|
-
return undefined;
|
|
53
|
+
const text = await sendOrEditView(plugin, services, message, session);
|
|
54
|
+
return typeof text === 'string' ? text : undefined;
|
|
52
55
|
}
|
|
53
56
|
|
|
54
57
|
export async function continueGame(
|
|
55
|
-
plugin: Plugin,
|
|
58
|
+
plugin: Plugin | null,
|
|
56
59
|
services: SessionService,
|
|
57
60
|
message: Message<any>,
|
|
58
61
|
): Promise<string> {
|
|
@@ -61,12 +64,13 @@ export async function continueGame(
|
|
|
61
64
|
message.$sender.id,
|
|
62
65
|
);
|
|
63
66
|
if (!session) return '你没有进行中的骰子对决,发送「骰子 开始」。';
|
|
64
|
-
await sendOrEditView(plugin, services, message, session);
|
|
67
|
+
const text = await sendOrEditView(plugin, services, message, session);
|
|
68
|
+
if (typeof text === 'string') return text;
|
|
65
69
|
return '已刷新骰子界面。';
|
|
66
70
|
}
|
|
67
71
|
|
|
68
72
|
export async function handleChoice(
|
|
69
|
-
plugin: Plugin,
|
|
73
|
+
plugin: Plugin | null,
|
|
70
74
|
services: SessionService,
|
|
71
75
|
message: Message<any>,
|
|
72
76
|
sessionId: string,
|
|
@@ -81,18 +85,9 @@ export async function handleChoice(
|
|
|
81
85
|
}
|
|
82
86
|
|
|
83
87
|
if (choiceId === 'restart') {
|
|
84
|
-
await services.updateSession(session.id, {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
round: 0,
|
|
88
|
-
last_player_roll: 0,
|
|
89
|
-
last_bot_roll: 0,
|
|
90
|
-
status: 'active',
|
|
91
|
-
board_message_id: '',
|
|
92
|
-
});
|
|
93
|
-
const updated = (await services.getById(session.id))!;
|
|
94
|
-
await sendOrEditView(plugin, services, message, updated);
|
|
95
|
-
return null;
|
|
88
|
+
await services.updateSession(session.id, { status: 'aborted' });
|
|
89
|
+
// text-only 模式(plugin===null)下 startGame 的唯一输出就是返回文本
|
|
90
|
+
return (await startGame(plugin, services, message)) ?? null;
|
|
96
91
|
}
|
|
97
92
|
|
|
98
93
|
if (choiceId !== 'roll') return '无效操作。';
|
|
@@ -120,8 +115,10 @@ export async function handleChoice(
|
|
|
120
115
|
});
|
|
121
116
|
|
|
122
117
|
const updated = (await services.getById(session.id))!;
|
|
123
|
-
|
|
124
|
-
|
|
118
|
+
if (status === 'won') void recordGameOutcome(message, 'dice', 'won', playerWins * 10);
|
|
119
|
+
else if (status === 'lost') void recordGameOutcome(message, 'dice', 'lost');
|
|
120
|
+
const text = await sendOrEditView(plugin, services, message, updated, { player, bot, result });
|
|
121
|
+
return typeof text === 'string' ? text : null;
|
|
125
122
|
}
|
|
126
123
|
|
|
127
124
|
export { DICE_PREFIX };
|
package/src/index.ts
CHANGED
|
@@ -1,36 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const plugin = usePlugin();
|
|
12
|
-
const { logger, useContext, addCron } = plugin;
|
|
13
|
-
|
|
14
|
-
registerModels(plugin);
|
|
15
|
-
|
|
16
|
-
let services: SessionService | null = null;
|
|
17
|
-
|
|
18
|
-
useContext('database', (dbFeature: DatabaseFeature) => {
|
|
19
|
-
services = createServices(resolveGameDatabase(dbFeature));
|
|
20
|
-
logger.info(formatCompact({ 模块: '骰子对决', 数据模型: '已就绪' }));
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
registerDiceHub(() => services);
|
|
24
|
-
registerCommands(plugin, () => services);
|
|
25
|
-
registerInteractive(plugin, () => services);
|
|
26
|
-
registerTextFallback(plugin, () => services);
|
|
27
|
-
|
|
28
|
-
addCron(
|
|
29
|
-
new Cron('0 */15 * * * *', async () => {
|
|
30
|
-
if (!services) return;
|
|
31
|
-
const n = await services.abortStale(30 * 60 * 1000);
|
|
32
|
-
if (n > 0) logger.debug(formatCompact({ 骰子对决: '清理超时局', count: n }));
|
|
33
|
-
}),
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
logger.info(formatCompact({ 模块: '骰子对决', 状态: '已加载' }));
|
|
1
|
+
export { DICE_HELP } from './dice-command.js';
|
|
2
|
+
export { gameServicesToken, resolveGameServices } from './runtime-store.js';
|
|
3
|
+
export { createInMemoryDiceDb, mountDiceMemoryServices } from './memory-db.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 已由 plugin.ts 接线:commands/ 命令、middlewares/ 文本与选项中间件、
|
|
7
|
+
* 游戏大厅注册(registerRuntimeGame)、过期会话 cron(scheduleHostToken)、
|
|
8
|
+
* host DatabaseHost(databaseHostToken)。仍未接:interactive 按钮回调。
|
|
9
|
+
*/
|
package/src/memory-db.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createHostGameDb, createInMemoryGameDb } from '@zhin.js/game-kit';
|
|
2
|
+
import type { DatabaseHost } from '@zhin.js/plugin-runtime';
|
|
3
|
+
import { defineHostTables } from './models.js';
|
|
4
|
+
import { createServices, type DiceDatabase, type SessionService } from './session-service.js';
|
|
5
|
+
|
|
6
|
+
const DICE_TABLES = ['dice_sessions'] as const;
|
|
7
|
+
|
|
8
|
+
/** In-memory dice_sessions for Plugin Runtime slice-2 (no DatabaseFeature). */
|
|
9
|
+
export function createInMemoryDiceDb(): DiceDatabase {
|
|
10
|
+
return createInMemoryGameDb(DICE_TABLES) as unknown as DiceDatabase;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function mountDiceMemoryServices(): SessionService {
|
|
14
|
+
const services = createServices(createInMemoryDiceDb());
|
|
15
|
+
return services;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function mountDiceHostServices(host: DatabaseHost): SessionService {
|
|
19
|
+
defineHostTables(host);
|
|
20
|
+
const services = createServices(createHostGameDb(host, DICE_TABLES) as unknown as DiceDatabase);
|
|
21
|
+
return services;
|
|
22
|
+
}
|
package/src/models.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { Models
|
|
1
|
+
import type { Models } from '@zhin.js/core';
|
|
2
2
|
|
|
3
3
|
export type DiceSessionStatus = 'active' | 'won' | 'lost' | 'aborted';
|
|
4
4
|
|
|
5
|
-
declare module 'zhin.js' {
|
|
5
|
+
declare module '@zhin.js/core' {
|
|
6
6
|
interface Models {
|
|
7
7
|
dice_sessions: {
|
|
8
8
|
id: string;
|
|
@@ -28,8 +28,11 @@ declare module 'zhin.js' {
|
|
|
28
28
|
|
|
29
29
|
export type DiceSessionRow = Models['dice_sessions'];
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
|
|
32
|
+
export function defineHostTables(
|
|
33
|
+
db: { define: (name: string, definition: Record<string, unknown>) => void },
|
|
34
|
+
): void {
|
|
35
|
+
db.define('dice_sessions', {
|
|
33
36
|
id: { type: 'text', primary: true },
|
|
34
37
|
adapter: { type: 'text', nullable: false },
|
|
35
38
|
endpoint: { type: 'text', nullable: false },
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createToken } from '@zhin.js/plugin-runtime';
|
|
2
|
+
import type { SessionService } from './session-service.js';
|
|
3
|
+
|
|
4
|
+
/** Owner-scoped service consumed by discovered commands and middleware. */
|
|
5
|
+
export const gameServicesToken = createToken<SessionService>('zhin.game.dice-duel.services');
|
|
6
|
+
|
|
7
|
+
export function resolveGameServices(context: { use<T>(token: typeof gameServicesToken): T }): SessionService {
|
|
8
|
+
return context.use(gameServicesToken) as SessionService;
|
|
9
|
+
}
|
package/src/session-service.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Database,
|
|
2
|
-
import { channelKey, generateSessionId } from '@zhin.js/game-
|
|
1
|
+
import type { Database, Message, Models, RelatedModel } from '@zhin.js/core';
|
|
2
|
+
import { channelKey, generateSessionId, boardMessageMatches } from '@zhin.js/game-kit';
|
|
3
3
|
import type { DiceSessionRow } from './models.js';
|
|
4
4
|
|
|
5
5
|
export type DiceDatabase = Database<unknown, Models, string>;
|
|
@@ -30,11 +30,9 @@ export class SessionService {
|
|
|
30
30
|
|
|
31
31
|
async getActiveByBoardMessageId(messageId: string): Promise<DiceSessionRow | null> {
|
|
32
32
|
if (!messageId) return null;
|
|
33
|
-
const rows = await getModel(this.db).findAll({
|
|
33
|
+
const rows = await getModel(this.db).findAll({});
|
|
34
34
|
for (const row of rows) {
|
|
35
|
-
|
|
36
|
-
if (!stored) continue;
|
|
37
|
-
if (stored === messageId || stored.endsWith(`:${messageId}`)) return row;
|
|
35
|
+
if (boardMessageMatches(row.board_message_id ?? '', messageId)) return row;
|
|
38
36
|
}
|
|
39
37
|
return null;
|
|
40
38
|
}
|
|
@@ -87,6 +85,3 @@ export function createServices(db: DiceDatabase): SessionService {
|
|
|
87
85
|
return new SessionService(db);
|
|
88
86
|
}
|
|
89
87
|
|
|
90
|
-
export function resolveGameDatabase(feature: DatabaseFeature): DiceDatabase {
|
|
91
|
-
return feature.db;
|
|
92
|
-
}
|
package/src/view.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { buildChoiceKeyboard } from '@zhin.js/game-
|
|
2
|
-
import type { SendContent } from 'zhin.js';
|
|
1
|
+
import { buildChoiceKeyboard } from '@zhin.js/game-kit';
|
|
2
|
+
import type { SendContent } from '@zhin.js/core';
|
|
3
3
|
import type { DiceSessionRow } from './models.js';
|
|
4
4
|
import { DICE_PREFIX, diceEmoji, WIN_TARGET } from './engine.js';
|
|
5
5
|
|
|
6
6
|
export function buildDiceView(
|
|
7
7
|
session: DiceSessionRow,
|
|
8
8
|
lastRound?: { player: number; bot: number; result: 0 | 1 | 2 },
|
|
9
|
+
channelType?: string,
|
|
9
10
|
): SendContent {
|
|
10
11
|
const terminal = session.status !== 'active';
|
|
11
12
|
const lines = [
|
|
@@ -35,7 +36,7 @@ export function buildDiceView(
|
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
const choices = terminal
|
|
38
|
-
? [{ id: 'restart', label: '🔄 再来一局', style: 'primary' as const }]
|
|
39
|
+
? [{ id: 'restart', label: '🔄 再来一局', style: 'primary' as const, keepEnabledWhenTerminal: true }]
|
|
39
40
|
: [{ id: 'roll', label: '🎲 掷骰', style: 'primary' as const }];
|
|
40
41
|
|
|
41
42
|
return buildChoiceKeyboard({
|
|
@@ -45,5 +46,7 @@ export function buildDiceView(
|
|
|
45
46
|
choices,
|
|
46
47
|
terminal,
|
|
47
48
|
fallbackHint: '回复 1 掷骰',
|
|
49
|
+
interactionProfile: terminal ? 'terminal' : 'gameplay',
|
|
50
|
+
channelType,
|
|
48
51
|
});
|
|
49
52
|
}
|
package/lib/commands.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
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
|
package/lib/commands.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiD,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AASrF,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;AA2BD,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,CAyBnG"}
|
package/lib/commands.js
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { MessageCommand, getActionFromMessage } from 'zhin.js';
|
|
2
|
-
import { buildChoiceFallbackMap, channelKey, normalizeDiceAction, parseChoicePayload, } from '@zhin.js/game-shared';
|
|
3
|
-
import { DICE_PREFIX, handleChoice } from './game-flow.js';
|
|
4
|
-
import { runDiceCommand } from './dice-command.js';
|
|
5
|
-
function registerPattern(plugin, pattern, desc, getServices) {
|
|
6
|
-
plugin.addCommand(new MessageCommand(pattern)
|
|
7
|
-
.desc(desc)
|
|
8
|
-
.action(async (message, result) => {
|
|
9
|
-
const services = getServices();
|
|
10
|
-
if (!services)
|
|
11
|
-
return '骰子对决需要启用 database 配置。';
|
|
12
|
-
const raw = result.params.action ?? '';
|
|
13
|
-
return runDiceCommand(plugin, services, message, normalizeDiceAction(raw));
|
|
14
|
-
}));
|
|
15
|
-
}
|
|
16
|
-
export function registerCommands(plugin, getServices) {
|
|
17
|
-
registerPattern(plugin, 'dice [action:word]', '骰子对决(dice)', getServices);
|
|
18
|
-
registerPattern(plugin, '骰子 [action:word]', '骰子对决(中文)', getServices);
|
|
19
|
-
}
|
|
20
|
-
async function resolveChoice(message, services) {
|
|
21
|
-
const action = getActionFromMessage(message);
|
|
22
|
-
if (!action)
|
|
23
|
-
return null;
|
|
24
|
-
const parsed = parseChoicePayload(action.payload, DICE_PREFIX);
|
|
25
|
-
if (parsed)
|
|
26
|
-
return { sessionId: parsed.sessionId, choiceId: parsed.choiceId };
|
|
27
|
-
const choiceId = action.id || action.payload;
|
|
28
|
-
if (!choiceId)
|
|
29
|
-
return null;
|
|
30
|
-
const ch = channelKey(message);
|
|
31
|
-
const session = await services.getActiveForUser(ch, message.$sender.id)
|
|
32
|
-
?? (action.sourceMessageId
|
|
33
|
-
? await services.getActiveByBoardMessageId(action.sourceMessageId)
|
|
34
|
-
: null);
|
|
35
|
-
if (!session || session.channel_key !== ch)
|
|
36
|
-
return null;
|
|
37
|
-
if (!['roll', 'restart'].includes(choiceId))
|
|
38
|
-
return null;
|
|
39
|
-
return { sessionId: session.id, choiceId };
|
|
40
|
-
}
|
|
41
|
-
export function registerInteractive(plugin, getServices) {
|
|
42
|
-
plugin.registerInteractiveHandler(`${DICE_PREFIX}:`, async (message) => {
|
|
43
|
-
const services = getServices();
|
|
44
|
-
if (!services)
|
|
45
|
-
return false;
|
|
46
|
-
const choice = await resolveChoice(message, services);
|
|
47
|
-
if (!choice)
|
|
48
|
-
return false;
|
|
49
|
-
const err = await handleChoice(plugin, services, message, choice.sessionId, choice.choiceId);
|
|
50
|
-
if (err)
|
|
51
|
-
await message.$reply?.(err);
|
|
52
|
-
return true;
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
export function registerTextFallback(plugin, getServices) {
|
|
56
|
-
plugin.addMiddleware(async (message, next) => {
|
|
57
|
-
const services = getServices();
|
|
58
|
-
if (!services)
|
|
59
|
-
return next();
|
|
60
|
-
const action = getActionFromMessage(message);
|
|
61
|
-
if (action?.payload.startsWith(`${DICE_PREFIX}:`))
|
|
62
|
-
return next();
|
|
63
|
-
const ch = channelKey(message);
|
|
64
|
-
const session = await services.getActiveForUser(ch, message.$sender.id);
|
|
65
|
-
if (!session || session.status !== 'active')
|
|
66
|
-
return next();
|
|
67
|
-
const raw = message.$raw?.trim() ?? '';
|
|
68
|
-
if (raw !== '1')
|
|
69
|
-
return next();
|
|
70
|
-
const map = buildChoiceFallbackMap(DICE_PREFIX, session.id, [
|
|
71
|
-
{ id: 'roll', label: '掷骰' },
|
|
72
|
-
]);
|
|
73
|
-
const payload = map['1'];
|
|
74
|
-
const parsed = payload ? parseChoicePayload(payload, DICE_PREFIX) : null;
|
|
75
|
-
if (!parsed || parsed.sessionId !== session.id)
|
|
76
|
-
return next();
|
|
77
|
-
const err = await handleChoice(plugin, services, message, session.id, 'roll');
|
|
78
|
-
if (err)
|
|
79
|
-
await message.$reply?.(err);
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
//# sourceMappingURL=commands.js.map
|
package/lib/commands.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dice-command.d.ts","sourceRoot":"","sources":["../src/dice-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAG/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,eAAO,MAAM,SAAS,QAMV,CAAC;AAEb,wBAAsB,cAAc,CAClC,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,CA0B7B"}
|
package/lib/engine.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,SAAS,CAAC;AAClC,eAAO,MAAM,UAAU,IAAI,CAAC;AAE5B,wBAAgB,MAAM,IAAI,MAAM,CAE/B;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAG3C;AAED,wBAAwB;AACxB,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAGnE"}
|
package/lib/game-flow.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAgB,WAAW,EAAsB,MAAM,aAAa,CAAC;AAC5E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,EACrB,OAAO,EAAE,cAAc,EACvB,SAAS,CAAC,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;CAAE,GAC7D,OAAO,CAAC,IAAI,CAAC,CAqBf;AAED,wBAAsB,SAAS,CAC7B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,GACpB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAY7B;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,CAmDxB;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
|
package/lib/hub-register.d.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { DICE_HELP } from './dice-command.js';
|
|
2
|
-
import type { SessionService } from './session-service.js';
|
|
3
|
-
export declare function registerDiceHub(getServices: () => SessionService | null): () => void;
|
|
4
|
-
export { DICE_HELP };
|
|
5
|
-
//# sourceMappingURL=hub-register.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hub-register.d.ts","sourceRoot":"","sources":["../src/hub-register.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,cAAc,GAAG,IAAI,GAAG,MAAM,IAAI,CAoBpF;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
package/lib/hub-register.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { registerGame } from '@zhin.js/game-shared';
|
|
2
|
-
import { runDiceCommand, DICE_HELP } from './dice-command.js';
|
|
3
|
-
export function registerDiceHub(getServices) {
|
|
4
|
-
return registerGame({
|
|
5
|
-
id: 'dice',
|
|
6
|
-
title: '骰子对决',
|
|
7
|
-
icon: '🎲',
|
|
8
|
-
description: '掷骰比大小,三局两胜',
|
|
9
|
-
commandPrefix: '骰子',
|
|
10
|
-
quickStart: '开始',
|
|
11
|
-
aliases: ['dice'],
|
|
12
|
-
menus: [
|
|
13
|
-
{ id: 'start', label: '🎮 开始对局', style: 'primary' },
|
|
14
|
-
{ id: 'continue', label: '🔄 继续' },
|
|
15
|
-
{ id: 'help', label: '📖 玩法说明' },
|
|
16
|
-
],
|
|
17
|
-
runAction: async (actionId, ctx) => {
|
|
18
|
-
const services = getServices();
|
|
19
|
-
if (!services)
|
|
20
|
-
return '骰子对决需要启用 database 配置。';
|
|
21
|
-
return runDiceCommand(ctx.plugin, services, ctx.message, actionId);
|
|
22
|
-
},
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
export { DICE_HELP };
|
|
26
|
-
//# sourceMappingURL=hub-register.js.map
|
package/lib/hub-register.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hub-register.js","sourceRoot":"","sources":["../src/hub-register.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAG9D,MAAM,UAAU,eAAe,CAAC,WAAwC;IACtE,OAAO,YAAY,CAAC;QAClB,EAAE,EAAE,MAAM;QACV,KAAK,EAAE,MAAM;QACb,IAAI,EAAE,IAAI;QACV,WAAW,EAAE,YAAY;QACzB,aAAa,EAAE,IAAI;QACnB,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,MAAM,CAAC;QACjB,KAAK,EAAE;YACL,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;YACnD,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE;YAClC,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,OAAO,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACrE,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
package/lib/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/lib/models.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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,iBAAiB,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC;AAEtE,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,MAAM;QACd,aAAa,EAAE;YACb,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,WAAW,EAAE,MAAM,CAAC;YACpB,QAAQ,EAAE,MAAM,CAAC;YACjB,KAAK,EAAE,MAAM,CAAC;YACd,gBAAgB,EAAE,MAAM,CAAC;YACzB,aAAa,EAAE,MAAM,CAAC;YACtB,MAAM,EAAE,iBAAiB,CAAC;YAC1B,gBAAgB,EAAE,MAAM,CAAC;YACzB,UAAU,EAAE,MAAM,CAAC;YACnB,UAAU,EAAE,MAAM,CAAC;SACpB,CAAC;KACH;CACF;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC;AAErD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAoBnD"}
|
|
@@ -1 +0,0 @@
|
|
|
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,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAQ7D,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,YAAY;IAEvC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAKnE,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAMjF,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAInD,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAW5E,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC;IAyB7D,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxE,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAalD;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,YAAY,GAAG,cAAc,CAE/D;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,eAAe,GAAG,YAAY,CAE1E"}
|
package/lib/view.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../src/view.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,wBAAgB,aAAa,CAC3B,OAAO,EAAE,cAAc,EACvB,SAAS,CAAC,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;CAAE,GAC7D,WAAW,CAwCb"}
|
package/plugin.yml
DELETED