koishi-plugin-game-mini 0.0.4 → 0.0.6
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.js +75 -60
- package/lib/locales/locales/zh-CN.yml +10 -10
- package/package.json +16 -24
- package/src/index.ts +128 -0
- package/src/locales/zh-CN.yml +14 -0
package/lib/index.js
CHANGED
|
@@ -24,18 +24,18 @@ function apply(ctx, config) {
|
|
|
24
24
|
const defaultI18n = {
|
|
25
25
|
guessNumber: {
|
|
26
26
|
usage: '用法错误!正确用法:guess start/stop 或 直接输入数字',
|
|
27
|
-
start: '
|
|
27
|
+
start: '猜数字游戏开始!初始范围是 {0}-{1},快来猜猜看~',
|
|
28
28
|
stop: '猜数字游戏已停止,正确答案是 {0}',
|
|
29
|
-
invalid: '
|
|
29
|
+
invalid: '请输入有效的整数!',
|
|
30
30
|
notStarted: '游戏还未开始,请先发送 guess start 开始游戏',
|
|
31
|
-
outOfRange: '
|
|
32
|
-
tooSmall: '
|
|
33
|
-
tooBig: '
|
|
34
|
-
correct: '
|
|
31
|
+
outOfRange: '数字超出当前范围 [{0}-{1}],请重新输入!',
|
|
32
|
+
tooSmall: '猜小啦!当前范围更新为 [{0}-{1}]',
|
|
33
|
+
tooBig: '猜大啦!当前范围更新为 [{0}-{1}]',
|
|
34
|
+
correct: '恭喜你猜中了!数字就是 {0} 🎉',
|
|
35
35
|
botFirstGuess: '我先来猜一个:{0},该你啦~',
|
|
36
|
-
botWin: '
|
|
37
|
-
botGuessTooSmall: '我猜 {0}
|
|
38
|
-
botGuessTooBig: '我猜 {0}
|
|
36
|
+
botWin: '哈哈我猜中了!数字是 {0},我赢啦 🎉',
|
|
37
|
+
botGuessTooSmall: '我猜 {0},猜小啦!当前范围 [{1}-{2}]',
|
|
38
|
+
botGuessTooBig: '我猜 {0},猜大啦!当前范围 [{1}-{2}]'
|
|
39
39
|
}
|
|
40
40
|
};
|
|
41
41
|
if (fs_1.default.existsSync(zhCNPath)) {
|
|
@@ -55,6 +55,64 @@ function apply(ctx, config) {
|
|
|
55
55
|
const getSessionKey = (session) => {
|
|
56
56
|
return session.channelId ? `group:${session.channelId}` : `private:${session.userId}`;
|
|
57
57
|
};
|
|
58
|
+
ctx.middleware(async (session, next) => {
|
|
59
|
+
if (!session.content)
|
|
60
|
+
return next();
|
|
61
|
+
const key = getSessionKey(session);
|
|
62
|
+
const state = guessNumberStates.get(key);
|
|
63
|
+
if (state && state.started) {
|
|
64
|
+
const input = session.content.trim();
|
|
65
|
+
const num = parseInt(input);
|
|
66
|
+
if (!isNaN(num) && Number.isInteger(num)) {
|
|
67
|
+
let reply = '';
|
|
68
|
+
if (num < state.currentMin || num > state.currentMax) {
|
|
69
|
+
reply = session.text('guessNumber.outOfRange', [state.currentMin, state.currentMax]);
|
|
70
|
+
}
|
|
71
|
+
else if (num < state.target) {
|
|
72
|
+
state.currentMin = num + 1;
|
|
73
|
+
reply = session.text('guessNumber.tooSmall', [state.currentMin, state.currentMax]);
|
|
74
|
+
}
|
|
75
|
+
else if (num > state.target) {
|
|
76
|
+
state.currentMax = num - 1;
|
|
77
|
+
reply = session.text('guessNumber.tooBig', [state.currentMin, state.currentMax]);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
state.started = false;
|
|
81
|
+
guessNumberStates.set(key, state);
|
|
82
|
+
reply = session.text('guessNumber.correct', [state.target]);
|
|
83
|
+
return session.send(reply);
|
|
84
|
+
}
|
|
85
|
+
guessNumberStates.set(key, state);
|
|
86
|
+
const isPrivate = !session.channelId;
|
|
87
|
+
const botShouldParticipate = isPrivate || config.guessNumber.botParticipateInGroup;
|
|
88
|
+
if (botShouldParticipate && state.started && state.currentMin <= state.currentMax) {
|
|
89
|
+
let botGuess;
|
|
90
|
+
do {
|
|
91
|
+
botGuess = koishi_1.Random.int(state.currentMin, state.currentMax);
|
|
92
|
+
} while (state.botGuess.includes(botGuess));
|
|
93
|
+
state.botGuess.push(botGuess);
|
|
94
|
+
guessNumberStates.set(key, state);
|
|
95
|
+
if (botGuess === state.target) {
|
|
96
|
+
reply += '\n' + session.text('guessNumber.botWin', [botGuess]);
|
|
97
|
+
state.started = false;
|
|
98
|
+
guessNumberStates.set(key, state);
|
|
99
|
+
}
|
|
100
|
+
else if (botGuess < state.target) {
|
|
101
|
+
state.currentMin = botGuess + 1;
|
|
102
|
+
guessNumberStates.set(key, state);
|
|
103
|
+
reply += '\n' + session.text('guessNumber.botGuessTooSmall', [botGuess, state.currentMin, state.currentMax]);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
state.currentMax = botGuess - 1;
|
|
107
|
+
guessNumberStates.set(key, state);
|
|
108
|
+
reply += '\n' + session.text('guessNumber.botGuessTooBig', [botGuess, state.currentMin, state.currentMax]);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return session.send(reply);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return next();
|
|
115
|
+
});
|
|
58
116
|
ctx.command('guess <action:string>')
|
|
59
117
|
.action(async ({ session }, action) => {
|
|
60
118
|
if (!session)
|
|
@@ -63,68 +121,25 @@ function apply(ctx, config) {
|
|
|
63
121
|
const key = getSessionKey(session);
|
|
64
122
|
let state = guessNumberStates.get(key) || {
|
|
65
123
|
target: 0,
|
|
66
|
-
|
|
67
|
-
|
|
124
|
+
currentMin: config.guessNumber.min,
|
|
125
|
+
currentMax: config.guessNumber.max,
|
|
68
126
|
started: false,
|
|
69
127
|
botGuess: []
|
|
70
128
|
};
|
|
71
|
-
if (!action)
|
|
72
|
-
if (state.started)
|
|
73
|
-
return t('guessNumber.invalid');
|
|
129
|
+
if (!action)
|
|
74
130
|
return t('guessNumber.usage');
|
|
75
|
-
}
|
|
76
|
-
const num = parseInt(action);
|
|
77
|
-
if (!isNaN(num)) {
|
|
78
|
-
if (!state.started)
|
|
79
|
-
return t('guessNumber.notStarted');
|
|
80
|
-
if (num < state.min || num > state.max) {
|
|
81
|
-
return t('guessNumber.outOfRange', [state.min, state.max]);
|
|
82
|
-
}
|
|
83
|
-
let reply = '';
|
|
84
|
-
if (num < state.target) {
|
|
85
|
-
reply = t('guessNumber.tooSmall');
|
|
86
|
-
}
|
|
87
|
-
else if (num > state.target) {
|
|
88
|
-
reply = t('guessNumber.tooBig');
|
|
89
|
-
}
|
|
90
|
-
else {
|
|
91
|
-
state.started = false;
|
|
92
|
-
guessNumberStates.set(key, state);
|
|
93
|
-
return t('guessNumber.correct', [state.target]);
|
|
94
|
-
}
|
|
95
|
-
const isPrivate = !session.channelId;
|
|
96
|
-
const botShouldParticipate = isPrivate || config.guessNumber.botParticipateInGroup;
|
|
97
|
-
if (botShouldParticipate && state.started) {
|
|
98
|
-
let botGuess;
|
|
99
|
-
do {
|
|
100
|
-
botGuess = koishi_1.Random.int(config.guessNumber.min, config.guessNumber.max);
|
|
101
|
-
} while (state.botGuess.includes(botGuess));
|
|
102
|
-
state.botGuess.push(botGuess);
|
|
103
|
-
guessNumberStates.set(key, state);
|
|
104
|
-
if (botGuess === state.target) {
|
|
105
|
-
reply += '\n' + t('guessNumber.botWin', [botGuess]);
|
|
106
|
-
state.started = false;
|
|
107
|
-
guessNumberStates.set(key, state);
|
|
108
|
-
}
|
|
109
|
-
else if (botGuess < state.target) {
|
|
110
|
-
reply += '\n' + t('guessNumber.botGuessTooSmall', [botGuess]);
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
reply += '\n' + t('guessNumber.botGuessTooBig', [botGuess]);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
return reply;
|
|
117
|
-
}
|
|
118
131
|
if (action === 'start') {
|
|
119
132
|
state.target = koishi_1.Random.int(config.guessNumber.min, config.guessNumber.max);
|
|
133
|
+
state.currentMin = config.guessNumber.min;
|
|
134
|
+
state.currentMax = config.guessNumber.max;
|
|
120
135
|
state.started = true;
|
|
121
136
|
state.botGuess = [];
|
|
122
137
|
guessNumberStates.set(key, state);
|
|
123
|
-
let reply = t('guessNumber.start', [
|
|
138
|
+
let reply = t('guessNumber.start', [config.guessNumber.min, config.guessNumber.max]);
|
|
124
139
|
const isPrivate = !session.channelId;
|
|
125
140
|
const botShouldParticipate = isPrivate || config.guessNumber.botParticipateInGroup;
|
|
126
|
-
if (botShouldParticipate) {
|
|
127
|
-
const botFirstGuess = koishi_1.Random.int(
|
|
141
|
+
if (botShouldParticipate && state.started) {
|
|
142
|
+
const botFirstGuess = koishi_1.Random.int(state.currentMin, state.currentMax);
|
|
128
143
|
state.botGuess.push(botFirstGuess);
|
|
129
144
|
guessNumberStates.set(key, state);
|
|
130
145
|
reply += '\n' + t('guessNumber.botFirstGuess', [botFirstGuess]);
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
guessNumber:
|
|
2
2
|
usage: 用法错误!正确用法:guess start/stop 或 直接输入数字
|
|
3
|
-
start:
|
|
3
|
+
start: 猜数字游戏开始!初始范围是 {0}-{1},快来猜猜看~
|
|
4
4
|
stop: 猜数字游戏已停止,正确答案是 {0}
|
|
5
|
-
invalid:
|
|
6
|
-
notStarted:
|
|
7
|
-
outOfRange:
|
|
8
|
-
tooSmall:
|
|
9
|
-
tooBig:
|
|
10
|
-
correct:
|
|
5
|
+
invalid: 请输入有效的整数!
|
|
6
|
+
notStarted: 猜数字游戏还未开始,请先发送 guess start 开始游戏
|
|
7
|
+
outOfRange: 数字超出当前范围 [{0}-{1}],请重新输入!
|
|
8
|
+
tooSmall: 猜小啦!当前范围更新为 [{0}-{1}]
|
|
9
|
+
tooBig: 猜大啦!当前范围更新为 [{0}-{1}]
|
|
10
|
+
correct: 恭喜你猜中了!正确数字就是 {0} 🎉
|
|
11
11
|
botFirstGuess: 我先来猜一个:{0},该你啦~
|
|
12
|
-
botWin:
|
|
13
|
-
botGuessTooSmall: 我猜 {0}
|
|
14
|
-
botGuessTooBig: 我猜 {0}
|
|
12
|
+
botWin: 哈哈我猜中了!正确数字是 {0},我赢啦 🎉
|
|
13
|
+
botGuessTooSmall: 我猜 {0},猜小啦!当前范围 [{1}-{2}]
|
|
14
|
+
botGuessTooBig: 我猜 {0},猜大啦!当前范围 [{1}-{2}]s
|
package/package.json
CHANGED
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koishi-plugin-game-mini",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.0.6",
|
|
4
|
+
"description": "一款简单的猜数字小游戏,支持Bot 参与猜数",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
7
7
|
"files": [
|
|
8
8
|
"lib",
|
|
9
|
-
"
|
|
9
|
+
"src"
|
|
10
10
|
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc && copyfiles -u 1 src/locales/*.yml lib/locales/"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"koishi",
|
|
16
|
+
"plugin",
|
|
17
|
+
"game",
|
|
18
|
+
"猜数字"
|
|
19
|
+
],
|
|
20
|
+
"author": "Minecraft-1314",
|
|
21
|
+
"license": "MIT",
|
|
11
22
|
"repository": {
|
|
12
23
|
"type": "git",
|
|
13
24
|
"url": "git+https://github.com/Minecraft-1314/koishi-plugin-game-mini.git"
|
|
@@ -16,31 +27,12 @@
|
|
|
16
27
|
"url": "https://github.com/Minecraft-1314/koishi-plugin-game-mini/issues"
|
|
17
28
|
},
|
|
18
29
|
"homepage": "https://github.com/Minecraft-1314/koishi-plugin-game-mini#readme",
|
|
19
|
-
"
|
|
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",
|
|
30
|
+
"peerDependencies": {
|
|
34
31
|
"koishi": "^4.0.0",
|
|
35
|
-
"yaml": "^2.
|
|
32
|
+
"yaml": "^2.0.0"
|
|
36
33
|
},
|
|
37
34
|
"devDependencies": {
|
|
38
|
-
"@types/node": "^20.0.0",
|
|
39
35
|
"typescript": "^5.0.0",
|
|
40
36
|
"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
37
|
}
|
|
46
38
|
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { Context, Schema, Random } from 'koishi';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import yaml from 'yaml';
|
|
5
|
+
|
|
6
|
+
export const name = 'game-mini';
|
|
7
|
+
export const using = ['i18n'] as const;
|
|
8
|
+
|
|
9
|
+
export interface Config {}
|
|
10
|
+
export const Config: Schema<Config> = Schema.object({}).i18n({ 'zh-CN': {} });
|
|
11
|
+
|
|
12
|
+
interface GuessNumberState {
|
|
13
|
+
target: number
|
|
14
|
+
currentMin: number
|
|
15
|
+
currentMax: number
|
|
16
|
+
started: boolean
|
|
17
|
+
botGuess: number[]
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function apply(ctx: Context, config: Config) {
|
|
21
|
+
const zhCNPath = path.join(__dirname, './locales/zh-CN.yml');
|
|
22
|
+
const zhCNContent = fs.readFileSync(zhCNPath, 'utf8');
|
|
23
|
+
const zhCN = yaml.parse(zhCNContent);
|
|
24
|
+
ctx.i18n.define('zh-CN', zhCN);
|
|
25
|
+
|
|
26
|
+
const guessNumberStates = new Map<string, GuessNumberState>();
|
|
27
|
+
|
|
28
|
+
const getSessionKey = (session: any) => {
|
|
29
|
+
return session.channelId ? `group:${session.channelId}` : `private:${session.userId}`;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
ctx.middleware(async (session, next) => {
|
|
33
|
+
if (!session.content) return next();
|
|
34
|
+
const key = getSessionKey(session);
|
|
35
|
+
const state = guessNumberStates.get(key);
|
|
36
|
+
if (state && state.started) {
|
|
37
|
+
const input = session.content.trim();
|
|
38
|
+
const num = parseInt(input);
|
|
39
|
+
if (!isNaN(num) && Number.isInteger(num)) {
|
|
40
|
+
let reply = '';
|
|
41
|
+
if (num < state.currentMin || num > state.currentMax) {
|
|
42
|
+
reply = session.text('guessNumber.outOfRange', [state.currentMin, state.currentMax]);
|
|
43
|
+
} else if (num < state.target) {
|
|
44
|
+
state.currentMin = num + 1;
|
|
45
|
+
reply = session.text('guessNumber.tooSmall', [state.currentMin, state.currentMax]);
|
|
46
|
+
} else if (num > state.target) {
|
|
47
|
+
state.currentMax = num - 1;
|
|
48
|
+
reply = session.text('guessNumber.tooBig', [state.currentMin, state.currentMax]);
|
|
49
|
+
} else {
|
|
50
|
+
state.started = false;
|
|
51
|
+
guessNumberStates.set(key, state);
|
|
52
|
+
reply = session.text('guessNumber.correct', [state.target]);
|
|
53
|
+
return session.send(reply);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
guessNumberStates.set(key, state);
|
|
57
|
+
const isPrivate = !session.channelId;
|
|
58
|
+
const botShouldParticipate = isPrivate || true;
|
|
59
|
+
if (botShouldParticipate && state.started && state.currentMin <= state.currentMax) {
|
|
60
|
+
let botGuess;
|
|
61
|
+
do {
|
|
62
|
+
botGuess = Random.int(state.currentMin, state.currentMax);
|
|
63
|
+
} while (state.botGuess.includes(botGuess));
|
|
64
|
+
state.botGuess.push(botGuess);
|
|
65
|
+
guessNumberStates.set(key, state);
|
|
66
|
+
|
|
67
|
+
if (botGuess === state.target) {
|
|
68
|
+
reply += '\n' + session.text('guessNumber.botWin', [botGuess]);
|
|
69
|
+
state.started = false;
|
|
70
|
+
guessNumberStates.set(key, state);
|
|
71
|
+
} else if (botGuess < state.target) {
|
|
72
|
+
state.currentMin = botGuess + 1;
|
|
73
|
+
guessNumberStates.set(key, state);
|
|
74
|
+
reply += '\n' + session.text('guessNumber.botGuessTooSmall', [botGuess, state.currentMin, state.currentMax]);
|
|
75
|
+
} else {
|
|
76
|
+
state.currentMax = botGuess - 1;
|
|
77
|
+
guessNumberStates.set(key, state);
|
|
78
|
+
reply += '\n' + session.text('guessNumber.botGuessTooBig', [botGuess, state.currentMin, state.currentMax]);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return session.send(reply);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return next();
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
ctx.command('guess <action:string>')
|
|
88
|
+
.action(({ session }, action) => {
|
|
89
|
+
if (!session) return;
|
|
90
|
+
const key = getSessionKey(session);
|
|
91
|
+
let state = guessNumberStates.get(key) || {
|
|
92
|
+
target: 0,
|
|
93
|
+
currentMin: 0,
|
|
94
|
+
currentMax: 100,
|
|
95
|
+
started: false,
|
|
96
|
+
botGuess: []
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
if (!action) return session.text('guessNumber.usage');
|
|
100
|
+
|
|
101
|
+
if (action === 'start') {
|
|
102
|
+
state.target = Random.int(0, 100);
|
|
103
|
+
state.currentMin = 0;
|
|
104
|
+
state.currentMax = 100;
|
|
105
|
+
state.started = true;
|
|
106
|
+
state.botGuess = [];
|
|
107
|
+
guessNumberStates.set(key, state);
|
|
108
|
+
let reply = session.text('guessNumber.start', [0, 100]);
|
|
109
|
+
const isPrivate = !session.channelId;
|
|
110
|
+
const botShouldParticipate = isPrivate || true;
|
|
111
|
+
if (botShouldParticipate && state.started) {
|
|
112
|
+
const botFirstGuess = Random.int(state.currentMin, state.currentMax);
|
|
113
|
+
state.botGuess.push(botFirstGuess);
|
|
114
|
+
guessNumberStates.set(key, state);
|
|
115
|
+
reply += '\n' + session.text('guessNumber.botFirstGuess', [botFirstGuess]);
|
|
116
|
+
}
|
|
117
|
+
return reply;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (action === 'stop') {
|
|
121
|
+
state.started = false;
|
|
122
|
+
guessNumberStates.set(key, state);
|
|
123
|
+
return session.text('guessNumber.stop', [state.target]);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return session.text('guessNumber.usage');
|
|
127
|
+
});
|
|
128
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
guessNumber:
|
|
2
|
+
usage: 用法错误!正确用法:guess start/stop 或 直接输入数字
|
|
3
|
+
start: 猜数字游戏开始!初始范围是 {0}-{1},快来猜猜看~
|
|
4
|
+
stop: 猜数字游戏已停止,正确数字是 {0}
|
|
5
|
+
invalid: 请输入有效的整数!
|
|
6
|
+
notStarted: 游戏还未开始,请先发送 guess start 开始游戏
|
|
7
|
+
outOfRange: 数字超出当前范围 [{0}-{1}],请重新输入!
|
|
8
|
+
tooSmall: 猜小啦!当前范围更新为 [{0}-{1}]
|
|
9
|
+
tooBig: 猜大啦!当前范围更新为 [{0}-{1}]
|
|
10
|
+
correct: 恭喜你猜中了!正确数字就是 {0} 🎉
|
|
11
|
+
botFirstGuess: 我先来猜一个:{0},该你啦~
|
|
12
|
+
botWin: 哈哈我猜中了!正确数字是 {0},我赢啦 🎉
|
|
13
|
+
botGuessTooSmall: 我猜 {0},猜小啦!当前范围 [{1}-{2}]
|
|
14
|
+
botGuessTooBig: 我猜 {0},猜大啦!当前范围 [{1}-{2}]
|