koishi-plugin-game-mini 0.0.1 → 0.0.3
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/lib/index.d.ts +2 -7
- package/lib/index.js +53 -82
- package/package.json +1 -1
- package/readme.md +6 -8
package/lib/index.d.ts
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import { Context, Schema } from 'koishi';
|
|
2
|
-
declare module 'koishi' {
|
|
3
|
-
interface Context {
|
|
4
|
-
console?: {
|
|
5
|
-
createConfig: (config: any) => void;
|
|
6
|
-
};
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
2
|
export declare const name = "game-mini";
|
|
3
|
+
export declare const using: readonly ["i18n"];
|
|
4
|
+
export declare const inject: readonly ["console"];
|
|
10
5
|
export interface Config {
|
|
11
6
|
guessNumber: {
|
|
12
7
|
min: number;
|
package/lib/index.js
CHANGED
|
@@ -3,94 +3,65 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.Config = exports.name = void 0;
|
|
6
|
+
exports.Config = exports.inject = exports.using = exports.name = void 0;
|
|
7
7
|
exports.apply = apply;
|
|
8
8
|
const koishi_1 = require("koishi");
|
|
9
9
|
const fs_1 = __importDefault(require("fs"));
|
|
10
10
|
const path_1 = __importDefault(require("path"));
|
|
11
|
-
const
|
|
12
|
-
const localesDir = path_1.default.join(__dirname, 'locales');
|
|
13
|
-
if (fs_1.default.existsSync(localesDir)) {
|
|
14
|
-
const files = fs_1.default.readdirSync(localesDir);
|
|
15
|
-
for (const file of files) {
|
|
16
|
-
if (file.endsWith('.yml')) {
|
|
17
|
-
const lang = file.replace('.yml', '');
|
|
18
|
-
try {
|
|
19
|
-
const localeData = require(path_1.default.join(localesDir, file));
|
|
20
|
-
ctx.i18n.define(lang, localeData);
|
|
21
|
-
}
|
|
22
|
-
catch (error) {
|
|
23
|
-
console.warn(`Failed to load locale file ${file}:`, error);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
};
|
|
11
|
+
const yaml_1 = __importDefault(require("yaml"));
|
|
29
12
|
exports.name = 'game-mini';
|
|
13
|
+
exports.using = ['i18n'];
|
|
14
|
+
exports.inject = ['console'];
|
|
30
15
|
exports.Config = koishi_1.Schema.object({
|
|
31
16
|
guessNumber: koishi_1.Schema.object({
|
|
32
|
-
min: koishi_1.Schema.number()
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
.description('猜数字最小值(最低为0)'),
|
|
36
|
-
max: koishi_1.Schema.number()
|
|
37
|
-
.min(1)
|
|
38
|
-
.default(100)
|
|
39
|
-
.description('猜数字最大值'),
|
|
40
|
-
botParticipateInGroup: koishi_1.Schema.boolean()
|
|
41
|
-
.default(true)
|
|
42
|
-
.description('群聊中Bot是否参与猜数字(私聊强制参与)'),
|
|
17
|
+
min: koishi_1.Schema.number().min(0).default(0).description('猜数字最小值(最低为0)'),
|
|
18
|
+
max: koishi_1.Schema.number().min(1).default(100).description('猜数字最大值'),
|
|
19
|
+
botParticipateInGroup: koishi_1.Schema.boolean().default(true).description('群聊中Bot是否参与猜数字(私聊强制参与)'),
|
|
43
20
|
}).description('猜数字游戏配置'),
|
|
44
|
-
});
|
|
21
|
+
}).i18n({ 'zh-CN': {} });
|
|
45
22
|
function apply(ctx, config) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
]
|
|
77
|
-
}
|
|
78
|
-
});
|
|
23
|
+
const zhCNPath = path_1.default.resolve(__dirname, './locales/zh-CN.yml');
|
|
24
|
+
const defaultI18n = {
|
|
25
|
+
guessNumber: {
|
|
26
|
+
usage: '用法错误!正确用法:guess-number start/stop 或 输入数字',
|
|
27
|
+
start: '猜数字游戏开始!数字范围是 {0} 到 {1},快来猜猜看~',
|
|
28
|
+
stop: '猜数字游戏已停止,正确答案是 {0}',
|
|
29
|
+
invalid: '请输入有效的数字!',
|
|
30
|
+
notStarted: '游戏还未开始,请先发送 guess-number start 开始游戏',
|
|
31
|
+
outOfRange: '数字超出范围!请输入 {0} 到 {1} 之间的数字',
|
|
32
|
+
tooSmall: '猜小啦,再试试更大的数字~',
|
|
33
|
+
tooBig: '猜大啦,再试试更小的数字~',
|
|
34
|
+
correct: '恭喜你猜对了!正确答案就是 {0} 🎉',
|
|
35
|
+
botFirstGuess: '我先来猜一个:{0},该你啦~',
|
|
36
|
+
botWin: '哈哈我猜对了!答案就是 {0},我赢啦 🎉',
|
|
37
|
+
botGuessTooSmall: '我猜 {0},好像猜小了~',
|
|
38
|
+
botGuessTooBig: '我猜 {0},好像猜大了~'
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
if (fs_1.default.existsSync(zhCNPath)) {
|
|
42
|
+
try {
|
|
43
|
+
const zhCNContent = fs_1.default.readFileSync(zhCNPath, 'utf8');
|
|
44
|
+
const zhCN = yaml_1.default.parse(zhCNContent);
|
|
45
|
+
ctx.i18n.define('zh-CN', zhCN);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
ctx.i18n.define('zh-CN', defaultI18n);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
ctx.i18n.define('zh-CN', defaultI18n);
|
|
79
53
|
}
|
|
80
54
|
const guessNumberStates = new Map();
|
|
81
55
|
const getSessionKey = (session) => {
|
|
82
56
|
return session.channelId ? `group:${session.channelId}` : `private:${session.userId}`;
|
|
83
57
|
};
|
|
84
|
-
ctx.command('guess-number <action:string>'
|
|
85
|
-
.usage('guess-number start - 开始游戏\nguess-number <num> - 猜数字\nguess-number stop - 停止游戏')
|
|
86
|
-
.example('guess-number start')
|
|
87
|
-
.example('guess-number 50')
|
|
88
|
-
.example('guess-number stop')
|
|
58
|
+
ctx.command('guess-number <action:string>')
|
|
89
59
|
.action(async ({ session }, action) => {
|
|
90
60
|
if (!session)
|
|
91
61
|
return;
|
|
62
|
+
const t = (key, ...args) => session.text(key, args);
|
|
92
63
|
if (!action)
|
|
93
|
-
return
|
|
64
|
+
return t('guessNumber.usage');
|
|
94
65
|
const key = getSessionKey(session);
|
|
95
66
|
let state = guessNumberStates.get(key) || {
|
|
96
67
|
target: 0,
|
|
@@ -104,41 +75,41 @@ function apply(ctx, config) {
|
|
|
104
75
|
state.started = true;
|
|
105
76
|
state.botGuess = [];
|
|
106
77
|
guessNumberStates.set(key, state);
|
|
107
|
-
let reply =
|
|
78
|
+
let reply = t('guessNumber.start', [config.guessNumber.min, config.guessNumber.max]);
|
|
108
79
|
const isPrivate = !session.channelId;
|
|
109
80
|
const botShouldParticipate = isPrivate || config.guessNumber.botParticipateInGroup;
|
|
110
81
|
if (botShouldParticipate) {
|
|
111
82
|
const botFirstGuess = koishi_1.Random.int(config.guessNumber.min, config.guessNumber.max);
|
|
112
83
|
state.botGuess.push(botFirstGuess);
|
|
113
84
|
guessNumberStates.set(key, state);
|
|
114
|
-
reply += '\n' +
|
|
85
|
+
reply += '\n' + t('guessNumber.botFirstGuess', [botFirstGuess]);
|
|
115
86
|
}
|
|
116
87
|
return reply;
|
|
117
88
|
}
|
|
118
89
|
if (action === 'stop') {
|
|
119
90
|
state.started = false;
|
|
120
91
|
guessNumberStates.set(key, state);
|
|
121
|
-
return
|
|
92
|
+
return t('guessNumber.stop', [state.target]);
|
|
122
93
|
}
|
|
123
94
|
const num = parseInt(action);
|
|
124
95
|
if (isNaN(num))
|
|
125
|
-
return
|
|
96
|
+
return t('guessNumber.invalid');
|
|
126
97
|
if (!state.started)
|
|
127
|
-
return
|
|
98
|
+
return t('guessNumber.notStarted');
|
|
128
99
|
if (num < state.min || num > state.max) {
|
|
129
|
-
return
|
|
100
|
+
return t('guessNumber.outOfRange', [state.min, state.max]);
|
|
130
101
|
}
|
|
131
102
|
let reply = '';
|
|
132
103
|
if (num < state.target) {
|
|
133
|
-
reply =
|
|
104
|
+
reply = t('guessNumber.tooSmall');
|
|
134
105
|
}
|
|
135
106
|
else if (num > state.target) {
|
|
136
|
-
reply =
|
|
107
|
+
reply = t('guessNumber.tooBig');
|
|
137
108
|
}
|
|
138
109
|
else {
|
|
139
110
|
state.started = false;
|
|
140
111
|
guessNumberStates.set(key, state);
|
|
141
|
-
return
|
|
112
|
+
return t('guessNumber.correct', [state.target]);
|
|
142
113
|
}
|
|
143
114
|
const isPrivate = !session.channelId;
|
|
144
115
|
const botShouldParticipate = isPrivate || config.guessNumber.botParticipateInGroup;
|
|
@@ -150,15 +121,15 @@ function apply(ctx, config) {
|
|
|
150
121
|
state.botGuess.push(botGuess);
|
|
151
122
|
guessNumberStates.set(key, state);
|
|
152
123
|
if (botGuess === state.target) {
|
|
153
|
-
reply += '\n' +
|
|
124
|
+
reply += '\n' + t('guessNumber.botWin', [botGuess]);
|
|
154
125
|
state.started = false;
|
|
155
126
|
guessNumberStates.set(key, state);
|
|
156
127
|
}
|
|
157
128
|
else if (botGuess < state.target) {
|
|
158
|
-
reply += '\n' +
|
|
129
|
+
reply += '\n' + t('guessNumber.botGuessTooSmall', [botGuess]);
|
|
159
130
|
}
|
|
160
131
|
else {
|
|
161
|
-
reply += '\n' +
|
|
132
|
+
reply += '\n' + t('guessNumber.botGuessTooBig', [botGuess]);
|
|
162
133
|
}
|
|
163
134
|
}
|
|
164
135
|
return reply;
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -4,17 +4,15 @@
|
|
|
4
4
|
|
|
5
5
|
### 中文
|
|
6
6
|
这是一个为 Koishi 聊天机器人框架开发的猜数字小游戏插件。该插件具有以下特点:
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
- 提供可视化控制台配置页面,支持汉化
|
|
7
|
+
- 支持自定义猜数字的数值范围- 区分群聊/私聊模式:私聊时 Bot 强制参与,群聊可配置 Bot 是否参与
|
|
8
|
+
- 提供可视化控制台配置页面
|
|
10
9
|
- Bot 参与时会智能猜数,且不会重复猜测同一数字
|
|
11
10
|
|
|
12
11
|
### English
|
|
13
12
|
This is a number guessing game plugin developed for the Koishi chatbot framework. This plugin has the following features:
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
- When the Bot participates, it will guess numbers intelligently and will not guess the same number repeatedly
|
|
13
|
+
- Supports customizable number range for guessing - Differentiates between group chat and private chat modes: Bots are forced to participate in private chats, while bot participation in group chats can be configured.
|
|
14
|
+
- Provides a visual console configuration page
|
|
15
|
+
- When a bot participates, it will intelligently guess numbers and will not repeatedly guess the same number.
|
|
18
16
|
|
|
19
17
|
## 使用说明 (Usage)
|
|
20
18
|
|
|
@@ -51,7 +49,7 @@ This is a number guessing game plugin developed for the Koishi chatbot framework
|
|
|
51
49
|
## 项目贡献者 (Contributors)
|
|
52
50
|
| 贡献者 (Contributor) | 贡献内容 (Contribution) |
|
|
53
51
|
| --- | --- |
|
|
54
|
-
|
|
|
52
|
+
| Minecraft-1314 | 插件完整开发 (Complete plugin development) |
|
|
55
53
|
| (欢迎提交 PR 加入贡献者列表) | (Welcome to submit PR to join the contributor list) |
|
|
56
54
|
|
|
57
55
|
## 许可协议 (License)
|