koishi-plugin-game-mini 0.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/lib/index.d.ts +18 -0
- package/lib/index.js +166 -0
- package/lib/locales/locales/zh-CN.yml +26 -0
- package/package.json +46 -0
- package/readme.md +70 -0
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Context, Schema } from 'koishi';
|
|
2
|
+
declare module 'koishi' {
|
|
3
|
+
interface Context {
|
|
4
|
+
console?: {
|
|
5
|
+
createConfig: (config: any) => void;
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export declare const name = "game-mini";
|
|
10
|
+
export interface Config {
|
|
11
|
+
guessNumber: {
|
|
12
|
+
min: number;
|
|
13
|
+
max: number;
|
|
14
|
+
botParticipateInGroup: boolean;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export declare const Config: Schema<Config>;
|
|
18
|
+
export declare function apply(ctx: Context, config: Config): void;
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Config = exports.name = void 0;
|
|
7
|
+
exports.apply = apply;
|
|
8
|
+
const koishi_1 = require("koishi");
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const loadLocales = (ctx) => {
|
|
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
|
+
};
|
|
29
|
+
exports.name = 'game-mini';
|
|
30
|
+
exports.Config = koishi_1.Schema.object({
|
|
31
|
+
guessNumber: koishi_1.Schema.object({
|
|
32
|
+
min: koishi_1.Schema.number()
|
|
33
|
+
.min(0)
|
|
34
|
+
.default(0)
|
|
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是否参与猜数字(私聊强制参与)'),
|
|
43
|
+
}).description('猜数字游戏配置'),
|
|
44
|
+
});
|
|
45
|
+
function apply(ctx, config) {
|
|
46
|
+
loadLocales(ctx);
|
|
47
|
+
if (ctx.console) {
|
|
48
|
+
ctx.console.createConfig({
|
|
49
|
+
schema: exports.Config,
|
|
50
|
+
ui: {
|
|
51
|
+
form: [
|
|
52
|
+
{
|
|
53
|
+
key: 'guessNumber.min',
|
|
54
|
+
label: '猜数字最小值',
|
|
55
|
+
type: 'number',
|
|
56
|
+
attrs: {
|
|
57
|
+
min: 0,
|
|
58
|
+
placeholder: '输入最小值(最低为0)'
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
key: 'guessNumber.max',
|
|
63
|
+
label: '猜数字最大值',
|
|
64
|
+
type: 'number',
|
|
65
|
+
attrs: {
|
|
66
|
+
min: 1,
|
|
67
|
+
placeholder: '输入最大值'
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
key: 'guessNumber.botParticipateInGroup',
|
|
72
|
+
label: '群聊中Bot参与猜数字',
|
|
73
|
+
type: 'switch',
|
|
74
|
+
description: '私聊时Bot强制参与,不受此配置影响'
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
const guessNumberStates = new Map();
|
|
81
|
+
const getSessionKey = (session) => {
|
|
82
|
+
return session.channelId ? `group:${session.channelId}` : `private:${session.userId}`;
|
|
83
|
+
};
|
|
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')
|
|
89
|
+
.action(async ({ session }, action) => {
|
|
90
|
+
if (!session)
|
|
91
|
+
return;
|
|
92
|
+
if (!action)
|
|
93
|
+
return session.text('guessNumber.usage');
|
|
94
|
+
const key = getSessionKey(session);
|
|
95
|
+
let state = guessNumberStates.get(key) || {
|
|
96
|
+
target: 0,
|
|
97
|
+
min: config.guessNumber.min,
|
|
98
|
+
max: config.guessNumber.max,
|
|
99
|
+
started: false,
|
|
100
|
+
botGuess: []
|
|
101
|
+
};
|
|
102
|
+
if (action === 'start') {
|
|
103
|
+
state.target = koishi_1.Random.int(config.guessNumber.min, config.guessNumber.max);
|
|
104
|
+
state.started = true;
|
|
105
|
+
state.botGuess = [];
|
|
106
|
+
guessNumberStates.set(key, state);
|
|
107
|
+
let reply = session.text('guessNumber.start', [config.guessNumber.min, config.guessNumber.max]);
|
|
108
|
+
const isPrivate = !session.channelId;
|
|
109
|
+
const botShouldParticipate = isPrivate || config.guessNumber.botParticipateInGroup;
|
|
110
|
+
if (botShouldParticipate) {
|
|
111
|
+
const botFirstGuess = koishi_1.Random.int(config.guessNumber.min, config.guessNumber.max);
|
|
112
|
+
state.botGuess.push(botFirstGuess);
|
|
113
|
+
guessNumberStates.set(key, state);
|
|
114
|
+
reply += '\n' + session.text('guessNumber.botFirstGuess', [botFirstGuess]);
|
|
115
|
+
}
|
|
116
|
+
return reply;
|
|
117
|
+
}
|
|
118
|
+
if (action === 'stop') {
|
|
119
|
+
state.started = false;
|
|
120
|
+
guessNumberStates.set(key, state);
|
|
121
|
+
return session.text('guessNumber.stop', [state.target]);
|
|
122
|
+
}
|
|
123
|
+
const num = parseInt(action);
|
|
124
|
+
if (isNaN(num))
|
|
125
|
+
return session.text('guessNumber.invalid');
|
|
126
|
+
if (!state.started)
|
|
127
|
+
return session.text('guessNumber.notStarted');
|
|
128
|
+
if (num < state.min || num > state.max) {
|
|
129
|
+
return session.text('guessNumber.outOfRange', [state.min, state.max]);
|
|
130
|
+
}
|
|
131
|
+
let reply = '';
|
|
132
|
+
if (num < state.target) {
|
|
133
|
+
reply = session.text('guessNumber.tooSmall');
|
|
134
|
+
}
|
|
135
|
+
else if (num > state.target) {
|
|
136
|
+
reply = session.text('guessNumber.tooBig');
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
state.started = false;
|
|
140
|
+
guessNumberStates.set(key, state);
|
|
141
|
+
return session.text('guessNumber.correct', [state.target]);
|
|
142
|
+
}
|
|
143
|
+
const isPrivate = !session.channelId;
|
|
144
|
+
const botShouldParticipate = isPrivate || config.guessNumber.botParticipateInGroup;
|
|
145
|
+
if (botShouldParticipate && state.started) {
|
|
146
|
+
let botGuess;
|
|
147
|
+
do {
|
|
148
|
+
botGuess = koishi_1.Random.int(config.guessNumber.min, config.guessNumber.max);
|
|
149
|
+
} while (state.botGuess.includes(botGuess));
|
|
150
|
+
state.botGuess.push(botGuess);
|
|
151
|
+
guessNumberStates.set(key, state);
|
|
152
|
+
if (botGuess === state.target) {
|
|
153
|
+
reply += '\n' + session.text('guessNumber.botWin', [botGuess]);
|
|
154
|
+
state.started = false;
|
|
155
|
+
guessNumberStates.set(key, state);
|
|
156
|
+
}
|
|
157
|
+
else if (botGuess < state.target) {
|
|
158
|
+
reply += '\n' + session.text('guessNumber.botGuessTooSmall', [botGuess]);
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
reply += '\n' + session.text('guessNumber.botGuessTooBig', [botGuess]);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return reply;
|
|
165
|
+
});
|
|
166
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
commands:
|
|
2
|
+
guess-number:
|
|
3
|
+
description: 猜数字小游戏
|
|
4
|
+
usage: |-
|
|
5
|
+
guess-number start - 开始猜数字游戏
|
|
6
|
+
guess-number <数字> - 输入数字进行猜测
|
|
7
|
+
guess-number stop - 停止猜数字游戏
|
|
8
|
+
examples: |-
|
|
9
|
+
guess-number start
|
|
10
|
+
guess-number 50
|
|
11
|
+
guess-number stop
|
|
12
|
+
|
|
13
|
+
guessNumber:
|
|
14
|
+
usage: 用法错误!正确用法:guess-number start/stop 或 输入数字
|
|
15
|
+
start: 猜数字游戏开始!数字范围是 {0} 到 {1},快来猜猜看~
|
|
16
|
+
stop: 猜数字游戏已停止,正确答案是 {0}
|
|
17
|
+
invalid: 请输入有效的数字!
|
|
18
|
+
notStarted: 游戏还未开始,请先发送 guess-number start 开始游戏
|
|
19
|
+
outOfRange: 数字超出范围!请输入 {0} 到 {1} 之间的数字
|
|
20
|
+
tooSmall: 猜小啦,再试试更大的数字~
|
|
21
|
+
tooBig: 猜大啦,再试试更小的数字~
|
|
22
|
+
correct: 恭喜你猜对了!正确答案就是 {0} 🎉
|
|
23
|
+
botFirstGuess: 我先来猜一个:{0},该你啦~
|
|
24
|
+
botWin: 哈哈我猜对了!答案就是 {0},我赢啦 🎉
|
|
25
|
+
botGuessTooSmall: 我猜 {0},好像猜小了~
|
|
26
|
+
botGuessTooBig: 我猜 {0},好像猜大了~
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "koishi-plugin-game-mini",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Koishi猜数字小游戏插件",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"typings": "lib/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"lib",
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/Minecraft-1314/koishi-plugin-game-mini.git"
|
|
14
|
+
},
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/Minecraft-1314/koishi-plugin-game-mini/issues"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/Minecraft-1314/koishi-plugin-game-mini#readme",
|
|
19
|
+
"koishi": {
|
|
20
|
+
"description": {
|
|
21
|
+
"zh-CN": "Koishi猜数字小游戏插件"
|
|
22
|
+
},
|
|
23
|
+
"locales": [
|
|
24
|
+
"zh-CN"
|
|
25
|
+
],
|
|
26
|
+
"service": {
|
|
27
|
+
"required": [
|
|
28
|
+
"console"
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@koishijs/plugin-console": "^5.0.0",
|
|
34
|
+
"koishi": "^4.0.0",
|
|
35
|
+
"yaml": "^2.3.4"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "^20.0.0",
|
|
39
|
+
"typescript": "^5.0.0",
|
|
40
|
+
"copyfiles": "^2.4.1"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "tsc && copyfiles -u 1 src/locales/*.yml lib/locales/",
|
|
44
|
+
"dev": "tsc -w && copyfiles -u 1 src/locales/*.yml lib/locales/ -w"
|
|
45
|
+
}
|
|
46
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# koishi-plugin-game-mini
|
|
2
|
+
|
|
3
|
+
## 项目介绍 (Project Introduction)
|
|
4
|
+
|
|
5
|
+
### 中文
|
|
6
|
+
这是一个为 Koishi 聊天机器人框架开发的猜数字小游戏插件。该插件具有以下特点:
|
|
7
|
+
- 支持自定义猜数字的数值范围(最小值最低为0)
|
|
8
|
+
- 区分群聊/私聊模式:私聊时 Bot 强制参与,群聊可配置 Bot 是否参与
|
|
9
|
+
- 提供可视化控制台配置页面,支持汉化
|
|
10
|
+
- Bot 参与时会智能猜数,且不会重复猜测同一数字
|
|
11
|
+
|
|
12
|
+
### English
|
|
13
|
+
This is a number guessing game plugin developed for the Koishi chatbot framework. This plugin has the following features:
|
|
14
|
+
- Support customizing the numerical range of the number guessing game (minimum value is 0)
|
|
15
|
+
- Distinguish between group chat/private chat modes: Bot participates compulsorily in private chats, and Bot participation in group chats is configurable
|
|
16
|
+
- Provide a visual console configuration page with Chinese localization support
|
|
17
|
+
- When the Bot participates, it will guess numbers intelligently and will not guess the same number repeatedly
|
|
18
|
+
|
|
19
|
+
## 使用说明 (Usage)
|
|
20
|
+
|
|
21
|
+
### 中文
|
|
22
|
+
| 命令 (Command) | 功能说明 (Description) |
|
|
23
|
+
| --- | --- |
|
|
24
|
+
| guess-number start | 启动猜数字游戏,Bot(配置参与时)会先猜一个数字 |
|
|
25
|
+
| guess-number <数字> | 输入数字进行猜测,系统会提示猜大/猜小或猜对 |
|
|
26
|
+
| guess-number stop | 停止当前猜数字游戏,并公布正确答案 |
|
|
27
|
+
|
|
28
|
+
### English
|
|
29
|
+
| Command | Description |
|
|
30
|
+
| --- | --- |
|
|
31
|
+
| guess-number start | Start the number guessing game, and the Bot (if configured to participate) will guess a number first |
|
|
32
|
+
| guess-number <number> | Enter a number to guess, and the system will prompt if it's too big/too small or correct |
|
|
33
|
+
| guess-number stop | Stop the current number guessing game and announce the correct answer |
|
|
34
|
+
|
|
35
|
+
## 配置说明 (Configuration)
|
|
36
|
+
|
|
37
|
+
### 中文
|
|
38
|
+
| 配置项 (Config Item) | 说明 (Description) | 默认值 (Default) |
|
|
39
|
+
| --- | --- | --- |
|
|
40
|
+
| guessNumber.min | 猜数字最小值(最低为0) | 0 |
|
|
41
|
+
| guessNumber.max | 猜数字最大值 | 100 |
|
|
42
|
+
| guessNumber.botParticipateInGroup | 群聊中 Bot 是否参与猜数字(私聊强制参与) | true |
|
|
43
|
+
|
|
44
|
+
### English
|
|
45
|
+
| Config Item | Description | Default |
|
|
46
|
+
| --- | --- | --- |
|
|
47
|
+
| guessNumber.min | Minimum value for number guessing (minimum 0) | 0 |
|
|
48
|
+
| guessNumber.max | Maximum value for number guessing | 100 |
|
|
49
|
+
| guessNumber.botParticipateInGroup | Whether the Bot participates in number guessing in group chats (compulsory in private chats) | true |
|
|
50
|
+
|
|
51
|
+
## 项目贡献者 (Contributors)
|
|
52
|
+
| 贡献者 (Contributor) | 贡献内容 (Contribution) |
|
|
53
|
+
| --- | --- |
|
|
54
|
+
| (您的名字/昵称) | 插件完整开发 (Complete plugin development) |
|
|
55
|
+
| (欢迎提交 PR 加入贡献者列表) | (Welcome to submit PR to join the contributor list) |
|
|
56
|
+
|
|
57
|
+
## 许可协议 (License)
|
|
58
|
+
本项目采用 MIT 许可证,详情参见 LICENSE 文件。
|
|
59
|
+
|
|
60
|
+
This project is licensed under the MIT License, see the LICENSE file for details.
|
|
61
|
+
|
|
62
|
+
## 支持我们 (Support Us)
|
|
63
|
+
如果这个项目对您有帮助,欢迎点亮右上角的 Star ⭐ 支持我们,这将是对所有贡献者最大的鼓励!
|
|
64
|
+
|
|
65
|
+
If this project is helpful to you, please feel free to star it in the upper right corner ⭐ to support us, which will be the greatest encouragement to all contributors!
|
|
66
|
+
|
|
67
|
+
## 问题反馈 (Feedback)
|
|
68
|
+
如有问题或建议,可通过 Issues 提交反馈。
|
|
69
|
+
|
|
70
|
+
If you have any questions or suggestions, please submit feedback via Issues.
|