koishi-plugin-game-mini 0.2.4 → 0.2.5

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 CHANGED
@@ -14,193 +14,72 @@ exports.name = 'game-mini';
14
14
  exports.using = ['i18n'];
15
15
  exports.inject = ['console'];
16
16
  exports.Config = koishi_1.Schema.object({
17
- enableNumberGuess: koishi_1.Schema.boolean().default(true)
18
- .description('启用猜数字游戏')
19
- .i18n({ 'zh-CN': '启用猜数字游戏' }),
20
- enableWzHero: koishi_1.Schema.boolean().default(true)
21
- .description('启用王者英雄猜谜游戏')
22
- .i18n({ 'zh-CN': '启用王者英雄猜谜游戏' }),
23
- enableChengyuImage: koishi_1.Schema.boolean().default(true)
24
- .description('启用看图猜成语游戏')
25
- .i18n({ 'zh-CN': '启用看图猜成语游戏' }),
26
- enableChengyuJielong: koishi_1.Schema.boolean().default(true)
27
- .description('启用成语接龙游戏')
28
- .i18n({ 'zh-CN': '启用成语接龙游戏' }),
29
- enableDice: koishi_1.Schema.boolean().default(true)
30
- .description('启用掷骰子比大小游戏')
31
- .i18n({ 'zh-CN': '启用掷骰子比大小游戏' }),
32
- enableRps: koishi_1.Schema.boolean().default(true)
33
- .description('启用石头剪刀布游戏')
34
- .i18n({ 'zh-CN': '启用石头剪刀布游戏' }),
35
- enableCalc24: koishi_1.Schema.boolean().default(true)
36
- .description('启用算24点游戏')
37
- .i18n({ 'zh-CN': '启用算24点游戏' }),
38
- enablePasswordLock: koishi_1.Schema.boolean().default(true)
39
- .description('启用密码锁破解游戏')
40
- .i18n({ 'zh-CN': '启用密码锁破解游戏' }),
41
- enablePrivateGame: koishi_1.Schema.boolean().default(true)
42
- .description('允许私聊玩游戏')
43
- .i18n({ 'zh-CN': '允许私聊玩游戏' }),
44
- autoPlayDelay: koishi_1.Schema.number().min(0).default(10)
45
- .description('机器人自动操作延迟(秒)')
46
- .i18n({ 'zh-CN': '机器人自动操作延迟(秒)' }),
47
- autoPlayMaxCount: koishi_1.Schema.number().min(1).default(5)
48
- .description('机器人最大自动操作次数')
49
- .i18n({ 'zh-CN': '机器人最大自动操作次数' }),
50
- autoStopInactiveTime: koishi_1.Schema.number().min(0).default(30)
51
- .description('游戏无操作自动停止时间(秒)')
52
- .i18n({ 'zh-CN': '游戏无操作自动停止时间(秒)' }),
17
+ enableNumberGuess: koishi_1.Schema.boolean().default(true).description('启用猜数字游戏'),
18
+ enableWzHero: koishi_1.Schema.boolean().default(true).description('启用王者英雄猜谜游戏'),
19
+ enableChengyuImage: koishi_1.Schema.boolean().default(true).description('启用看图猜成语游戏'),
20
+ enableChengyuJielong: koishi_1.Schema.boolean().default(true).description('启用成语接龙游戏'),
21
+ enableCalc24: koishi_1.Schema.boolean().default(true).description('启用算24点游戏'),
22
+ enablePasswordLock: koishi_1.Schema.boolean().default(true).description('启用密码锁破解游戏'),
23
+ enablePrivateGame: koishi_1.Schema.boolean().default(true).description('允许私聊玩游戏'),
53
24
  guessNumber: koishi_1.Schema.object({
54
- min: koishi_1.Schema.number().min(0).default(0)
55
- .description('猜数字最小值')
56
- .i18n({ 'zh-CN': '猜数字最小值' }),
57
- max: koishi_1.Schema.number().min(1).default(100)
58
- .description('猜数字最大值')
59
- .i18n({ 'zh-CN': '猜数字最大值' }),
60
- botParticipateInGroup: koishi_1.Schema.boolean().default(true)
61
- .description('群聊中机器人参与猜数字')
62
- .i18n({ 'zh-CN': '群聊中机器人参与猜数字' }),
63
- totalRounds: koishi_1.Schema.number().min(1).default(10)
64
- .description('猜数字总回合数')
65
- .i18n({ 'zh-CN': '猜数字总回合数' }),
66
- showRank: koishi_1.Schema.boolean().default(true)
67
- .description('猜数字显示排行榜')
68
- .i18n({ 'zh-CN': '猜数字显示排行榜' }),
69
- }).description('猜数字游戏配置')
70
- .i18n({ 'zh-CN': '猜数字游戏配置' }),
25
+ min: koishi_1.Schema.number().min(0).default(0).description('猜数字最小值'),
26
+ max: koishi_1.Schema.number().min(1).default(100).description('猜数字最大值'),
27
+ botParticipateInGroup: koishi_1.Schema.boolean().default(true).description('群聊中机器人参与猜数字'),
28
+ totalRounds: koishi_1.Schema.number().min(1).default(10).description('猜数字总回合数'),
29
+ showRank: koishi_1.Schema.boolean().default(true).description('猜数字显示排行榜'),
30
+ autoPlayDelay: koishi_1.Schema.number().min(0).default(10).description('机器人自动操作延迟(秒)'),
31
+ autoPlayMaxCount: koishi_1.Schema.number().min(1).default(5).description('机器人最大自动操作次数'),
32
+ autoStopInactiveTime: koishi_1.Schema.number().min(0).default(30).description('游戏无操作自动停止时间(秒)'),
33
+ }).description('猜数字游戏配置'),
71
34
  wzHero: koishi_1.Schema.object({
72
- totalRounds: koishi_1.Schema.number().min(1).default(10)
73
- .description('王者英雄猜谜总回合数')
74
- .i18n({ 'zh-CN': '王者英雄猜谜总回合数' }),
75
- showRank: koishi_1.Schema.boolean().default(true)
76
- .description('王者英雄猜谜显示排行榜')
77
- .i18n({ 'zh-CN': '王者英雄猜谜显示排行榜' }),
78
- }).description('王者英雄猜谜游戏配置')
79
- .i18n({ 'zh-CN': '王者英雄猜谜游戏配置' }),
35
+ totalRounds: koishi_1.Schema.number().min(1).default(10).description('王者英雄猜谜总回合数'),
36
+ showRank: koishi_1.Schema.boolean().default(true).description('王者英雄猜谜显示排行榜'),
37
+ defaultDifficulty: koishi_1.Schema.union(['简单', '中等', '困难']).default('简单').description('默认难度'),
38
+ autoStopInactiveTime: koishi_1.Schema.number().min(0).default(30).description('游戏无操作自动停止时间(秒)'),
39
+ }).description('王者英雄猜谜游戏配置'),
80
40
  chengyuImage: koishi_1.Schema.object({
81
- totalRounds: koishi_1.Schema.number().min(1).default(10)
82
- .description('看图猜成语总回合数')
83
- .i18n({ 'zh-CN': '看图猜成语总回合数' }),
84
- showRank: koishi_1.Schema.boolean().default(true)
85
- .description('看图猜成语显示排行榜')
86
- .i18n({ 'zh-CN': '看图猜成语显示排行榜' }),
87
- }).description('看图猜成语游戏配置')
88
- .i18n({ 'zh-CN': '看图猜成语游戏配置' }),
41
+ totalRounds: koishi_1.Schema.number().min(1).default(10).description('看图猜成语总回合数'),
42
+ showRank: koishi_1.Schema.boolean().default(true).description('看图猜成语显示排行榜'),
43
+ defaultHintLevel: koishi_1.Schema.union([1, 2, 3, 4, 5]).default(1).description('默认提示级别(1-5)'),
44
+ autoStopInactiveTime: koishi_1.Schema.number().min(0).default(30).description('游戏无操作自动停止时间(秒)'),
45
+ }).description('看图猜成语游戏配置'),
89
46
  chengyuJielong: koishi_1.Schema.object({
90
- botParticipateInGroup: koishi_1.Schema.boolean().default(true)
91
- .description('群聊中机器人参与成语接龙')
92
- .i18n({ 'zh-CN': '群聊中机器人参与成语接龙' }),
93
- totalRounds: koishi_1.Schema.number().min(1).default(10)
94
- .description('成语接龙总回合数')
95
- .i18n({ 'zh-CN': '成语接龙总回合数' }),
96
- showRank: koishi_1.Schema.boolean().default(true)
97
- .description('成语接龙显示排行榜')
98
- .i18n({ 'zh-CN': '成语接龙显示排行榜' }),
99
- }).description('成语接龙游戏配置')
100
- .i18n({ 'zh-CN': '成语接龙游戏配置' }),
101
- dice: koishi_1.Schema.object({
102
- totalRounds: koishi_1.Schema.number().min(1).default(5)
103
- .description('掷骰子总回合数')
104
- .i18n({ 'zh-CN': '掷骰子总回合数' }),
105
- showRank: koishi_1.Schema.boolean().default(true)
106
- .description('掷骰子显示排行榜')
107
- .i18n({ 'zh-CN': '掷骰子显示排行榜' }),
108
- botParticipate: koishi_1.Schema.boolean().default(true)
109
- .description('机器人参与掷骰子')
110
- .i18n({ 'zh-CN': '机器人参与掷骰子' }),
111
- }).description('掷骰子比大小游戏配置')
112
- .i18n({ 'zh-CN': '掷骰子比大小游戏配置' }),
113
- rps: koishi_1.Schema.object({
114
- totalRounds: koishi_1.Schema.number().min(1).default(5)
115
- .description('石头剪刀布总回合数')
116
- .i18n({ 'zh-CN': '石头剪刀布总回合数' }),
117
- showRank: koishi_1.Schema.boolean().default(true)
118
- .description('石头剪刀布显示排行榜')
119
- .i18n({ 'zh-CN': '石头剪刀布显示排行榜' }),
120
- botParticipate: koishi_1.Schema.boolean().default(true)
121
- .description('机器人参与石头剪刀布')
122
- .i18n({ 'zh-CN': '机器人参与石头剪刀布' }),
123
- }).description('石头剪刀布游戏配置')
124
- .i18n({ 'zh-CN': '石头剪刀布游戏配置' }),
47
+ botParticipateInGroup: koishi_1.Schema.boolean().default(true).description('群聊中机器人参与成语接龙'),
48
+ totalRounds: koishi_1.Schema.number().min(1).default(10).description('成语接龙总回合数'),
49
+ showRank: koishi_1.Schema.boolean().default(true).description('成语接龙显示排行榜'),
50
+ autoPlayDelay: koishi_1.Schema.number().min(0).default(10).description('机器人自动操作延迟(秒)'),
51
+ autoPlayMaxCount: koishi_1.Schema.number().min(1).default(5).description('机器人最大自动操作次数'),
52
+ autoStopInactiveTime: koishi_1.Schema.number().min(0).default(30).description('游戏无操作自动停止时间(秒)'),
53
+ }).description('成语接龙游戏配置'),
125
54
  calc24: koishi_1.Schema.object({
126
- totalRounds: koishi_1.Schema.number().min(1).default(5)
127
- .description('算24点总回合数')
128
- .i18n({ 'zh-CN': '算24点总回合数' }),
129
- showRank: koishi_1.Schema.boolean().default(true)
130
- .description('算24点显示排行榜')
131
- .i18n({ 'zh-CN': '算24点显示排行榜' }),
132
- numberRange: koishi_1.Schema.array(koishi_1.Schema.number()).default([1, 13])
133
- .description('算24点数字范围 [最小值, 最大值]')
134
- .i18n({ 'zh-CN': '算24点数字范围 [最小值, 最大值]' }),
135
- }).description('算24点游戏配置')
136
- .i18n({ 'zh-CN': '算24点游戏配置' }),
55
+ totalRounds: koishi_1.Schema.number().min(1).default(5).description('算24点总回合数'),
56
+ showRank: koishi_1.Schema.boolean().default(true).description('算24点显示排行榜'),
57
+ defaultDifficulty: koishi_1.Schema.union(['简单', '中等', '困难']).default('中等').description('默认难度'),
58
+ difficultyLevels: koishi_1.Schema.object({
59
+ easy: koishi_1.Schema.object({
60
+ min: koishi_1.Schema.number().default(1).description('最小值'),
61
+ max: koishi_1.Schema.number().default(8).description('最大值'),
62
+ }).description('简单难度'),
63
+ medium: koishi_1.Schema.object({
64
+ min: koishi_1.Schema.number().default(1).description('最小值'),
65
+ max: koishi_1.Schema.number().default(10).description('最大值'),
66
+ }).description('中等难度'),
67
+ hard: koishi_1.Schema.object({
68
+ min: koishi_1.Schema.number().default(1).description('最小值'),
69
+ max: koishi_1.Schema.number().default(13).description('最大值'),
70
+ }).description('困难难度'),
71
+ }).description('难度等级配置'),
72
+ autoStopInactiveTime: koishi_1.Schema.number().min(0).default(30).description('游戏无操作自动停止时间(秒)'),
73
+ }).description('算24点游戏配置'),
137
74
  passwordLock: koishi_1.Schema.object({
138
- maxGuessTimes: koishi_1.Schema.number().min(1).default(10)
139
- .description('密码锁最大猜测次数')
140
- .i18n({ 'zh-CN': '密码锁最大猜测次数' }),
141
- showHint: koishi_1.Schema.boolean().default(true)
142
- .description('密码锁显示提示')
143
- .i18n({ 'zh-CN': '密码锁显示提示' }),
144
- showRank: koishi_1.Schema.boolean().default(true)
145
- .description('密码锁显示排行榜')
146
- .i18n({ 'zh-CN': '密码锁显示排行榜' }),
147
- }).description('密码锁破解游戏配置')
148
- .i18n({ 'zh-CN': '密码锁破解游戏配置' }),
75
+ maxGuessTimes: koishi_1.Schema.number().min(1).default(10).description('密码锁最大猜测次数'),
76
+ showHint: koishi_1.Schema.boolean().default(true).description('密码锁显示提示'),
77
+ showRank: koishi_1.Schema.boolean().default(true).description('密码锁显示排行榜'),
78
+ autoStopInactiveTime: koishi_1.Schema.number().min(0).default(30).description('游戏无操作自动停止时间(秒)'),
79
+ }).description('密码锁破解游戏配置'),
149
80
  apiConfig: koishi_1.Schema.object({
150
- timeout: koishi_1.Schema.number().default(5000)
151
- .description('API请求超时时间(毫秒)')
152
- .i18n({ 'zh-CN': 'API请求超时时间(毫秒)' }),
153
- }).description('API接口配置')
154
- .i18n({ 'zh-CN': 'API接口配置' }),
155
- }).i18n({
156
- 'zh-CN': {
157
- 'enableNumberGuess': '启用猜数字游戏',
158
- 'enableWzHero': '启用王者英雄猜谜游戏',
159
- 'enableChengyuImage': '启用看图猜成语游戏',
160
- 'enableChengyuJielong': '启用成语接龙游戏',
161
- 'enableDice': '启用掷骰子比大小游戏',
162
- 'enableRps': '启用石头剪刀布游戏',
163
- 'enableCalc24': '启用算24点游戏',
164
- 'enablePasswordLock': '启用猜密码游戏',
165
- 'enablePrivateGame': '允许私聊玩游戏',
166
- 'autoPlayDelay': '机器人自动操作延迟(秒)',
167
- 'autoPlayMaxCount': '机器人最大自动操作次数',
168
- 'autoStopInactiveTime': '游戏无操作自动停止时间(秒)',
169
- 'guessNumber': '猜数字游戏配置',
170
- 'guessNumber.min': '猜数字最小值',
171
- 'guessNumber.max': '猜数字最大值',
172
- 'guessNumber.botParticipateInGroup': '群聊中机器人参与猜数字',
173
- 'guessNumber.totalRounds': '猜数字总回合数',
174
- 'guessNumber.showRank': '猜数字显示排行榜',
175
- 'wzHero': '猜王者英雄配置',
176
- 'wzHero.totalRounds': '猜王者英雄总回合数',
177
- 'wzHero.showRank': '猜王者英雄显示排行榜',
178
- 'chengyuImage': '看图猜成语配置',
179
- 'chengyuImage.totalRounds': '看图猜成语总回合数',
180
- 'chengyuImage.showRank': '看图猜成语显示排行榜',
181
- 'chengyuJielong': '成语接龙配置',
182
- 'chengyuJielong.botParticipateInGroup': '群聊中机器人参与成语接龙',
183
- 'chengyuJielong.totalRounds': '成语接龙总回合数',
184
- 'chengyuJielong.showRank': '成语接龙显示排行榜',
185
- 'dice': '掷骰子比大小配置',
186
- 'dice.totalRounds': '掷骰子总回合数',
187
- 'dice.showRank': '掷骰子显示排行榜',
188
- 'dice.botParticipate': '机器人参与掷骰子',
189
- 'rps': '石头剪刀布配置',
190
- 'rps.totalRounds': '石头剪刀布总回合数',
191
- 'rps.showRank': '石头剪刀布显示排行榜',
192
- 'rps.botParticipate': '机器人参与石头剪刀布',
193
- 'calc24': '算24点配置',
194
- 'calc24.totalRounds': '算24点总回合数',
195
- 'calc24.showRank': '算24点显示排行榜',
196
- 'calc24.numberRange': '算24点数字范围',
197
- 'passwordLock': '猜密码配置',
198
- 'passwordLock.maxGuessTimes': '猜密码最大猜测次数',
199
- 'passwordLock.showHint': '猜密码显示提示',
200
- 'passwordLock.showRank': '猜密码显示排行榜',
201
- 'apiConfig': 'API接口配置',
202
- 'apiConfig.timeout': '请求超时时间(毫秒)'
203
- }
81
+ timeout: koishi_1.Schema.number().default(5000).description('API请求超时时间(毫秒)'),
82
+ }).description('API接口配置'),
204
83
  });
205
84
  const logger = new koishi_1.Logger('game-mini');
206
85
  const gameStates = new Map();
@@ -229,10 +108,6 @@ const checkGameRunning = (s, t) => {
229
108
  return true;
230
109
  if (t !== 'chengyuJielong' && s.chengyuJielong.started)
231
110
  return true;
232
- if (t !== 'dice' && s.dice.started)
233
- return true;
234
- if (t !== 'rps' && s.rps.started)
235
- return true;
236
111
  if (t !== 'calc24' && s.calc24.started)
237
112
  return true;
238
113
  if (t !== 'passwordLock' && s.passwordLock.started)
@@ -242,18 +117,16 @@ const checkGameRunning = (s, t) => {
242
117
  const clearGameTimer = (state) => {
243
118
  if (state.stopTimer)
244
119
  clearTimeout(state.stopTimer);
120
+ if (state.autoPlayTimer)
121
+ clearTimeout(state.autoPlayTimer);
245
122
  };
246
123
  const clearAllTimers = (st) => {
247
124
  clearGameTimer(st.guessNumber);
248
125
  clearGameTimer(st.wzHero);
249
126
  clearGameTimer(st.chengyuImage);
250
127
  clearGameTimer(st.chengyuJielong);
251
- clearGameTimer(st.dice);
252
- clearGameTimer(st.rps);
253
128
  clearGameTimer(st.calc24);
254
129
  clearGameTimer(st.passwordLock);
255
- if (st.chengyuJielong.autoPlayTimer)
256
- clearTimeout(st.chengyuJielong.autoPlayTimer);
257
130
  };
258
131
  const initState = (key, c) => {
259
132
  const s = {
@@ -274,7 +147,7 @@ const initState = (key, c) => {
274
147
  currentRound: 0,
275
148
  players: {},
276
149
  participants: [],
277
- difficulty: '',
150
+ difficulty: c.wzHero.defaultDifficulty,
278
151
  botAnswered: false,
279
152
  lastHint: '',
280
153
  currentHeroId: '',
@@ -301,27 +174,7 @@ const initState = (key, c) => {
301
174
  botTurn: true,
302
175
  autoPlayCount: 0,
303
176
  hasTriggeredAutoPlay: false,
304
- lastActiveTime: Date.now(),
305
- autoPlayTimer: undefined
306
- },
307
- dice: {
308
- started: false,
309
- totalRounds: c.dice.totalRounds,
310
- currentRound: 0,
311
- players: {},
312
- participants: [],
313
- playerDice: 0,
314
- botDice: 0
315
- },
316
- rps: {
317
- started: false,
318
- totalRounds: c.rps.totalRounds,
319
- currentRound: 0,
320
- players: {},
321
- participants: [],
322
- playerChoice: '',
323
- botChoice: '',
324
- choices: ['石头', '剪刀', '布']
177
+ lastActiveTime: Date.now()
325
178
  },
326
179
  calc24: {
327
180
  started: false,
@@ -329,9 +182,11 @@ const initState = (key, c) => {
329
182
  currentRound: 0,
330
183
  players: {},
331
184
  participants: [],
185
+ difficulty: c.calc24.defaultDifficulty,
332
186
  numbers: [],
333
187
  playerAnswer: '',
334
- solved: false
188
+ solved: false,
189
+ availableNumbers: []
335
190
  },
336
191
  passwordLock: {
337
192
  started: false,
@@ -380,9 +235,22 @@ const addScoreToOthers = (players, excludePlayerKey) => {
380
235
  }
381
236
  });
382
237
  };
383
- const setupAutoStop = (session, state, cfg, endMsg, showRank) => {
238
+ const setupAutoStop = (session, state, cfg, gameType, endMsg, showRank) => {
384
239
  clearGameTimer(state);
385
- if (cfg.autoStopInactiveTime <= 0)
240
+ let inactiveTime = 30;
241
+ if (gameType === 'guessNumber')
242
+ inactiveTime = cfg.guessNumber.autoStopInactiveTime;
243
+ else if (gameType === 'wzHero')
244
+ inactiveTime = cfg.wzHero.autoStopInactiveTime;
245
+ else if (gameType === 'chengyuImage')
246
+ inactiveTime = cfg.chengyuImage.autoStopInactiveTime;
247
+ else if (gameType === 'chengyuJielong')
248
+ inactiveTime = cfg.chengyuJielong.autoStopInactiveTime;
249
+ else if (gameType === 'calc24')
250
+ inactiveTime = cfg.calc24.autoStopInactiveTime;
251
+ else if (gameType === 'passwordLock')
252
+ inactiveTime = cfg.passwordLock.autoStopInactiveTime;
253
+ if (inactiveTime <= 0)
386
254
  return;
387
255
  state.stopTimer = setTimeout(() => {
388
256
  clearGameData(state);
@@ -390,7 +258,7 @@ const setupAutoStop = (session, state, cfg, endMsg, showRank) => {
390
258
  if (showRank && session.channelId) {
391
259
  session.send(generateRankText(state.players));
392
260
  }
393
- }, cfg.autoStopInactiveTime * 1000);
261
+ }, inactiveTime * 1000);
394
262
  };
395
263
  const calculate24 = (numbers) => {
396
264
  if (numbers.length === 1)
@@ -422,6 +290,21 @@ const calculate24 = (numbers) => {
422
290
  }
423
291
  return false;
424
292
  };
293
+ const generateSolvable24Numbers = (min, max) => {
294
+ const maxAttempts = 1000;
295
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
296
+ const numbers = [
297
+ koishi_1.Random.int(min, max + 1),
298
+ koishi_1.Random.int(min, max + 1),
299
+ koishi_1.Random.int(min, max + 1),
300
+ koishi_1.Random.int(min, max + 1)
301
+ ];
302
+ if (calculate24([...numbers])) {
303
+ return numbers;
304
+ }
305
+ }
306
+ return [6, 4, 3, 1];
307
+ };
425
308
  const generatePasswordHint = (password, guess) => {
426
309
  let correctPos = 0;
427
310
  let correctNum = 0;
@@ -449,6 +332,21 @@ const generatePasswordHint = (password, guess) => {
449
332
  }
450
333
  return `提示:${correctPos}个数字位置正确,${correctNum}个数字正确但位置错误`;
451
334
  };
335
+ const evaluateExpression = (expr) => {
336
+ try {
337
+ const cleanExpr = expr.replace(/[^\d\+\-\*\/\(\)\[\]\{\}\s]/g, '');
338
+ const normalizedExpr = cleanExpr.replace(/[\[\{]/g, '(').replace(/[\]\}]/g, ')');
339
+ const func = new Function('return ' + normalizedExpr);
340
+ const result = func();
341
+ if (typeof result === 'number' && isFinite(result)) {
342
+ return result;
343
+ }
344
+ return null;
345
+ }
346
+ catch {
347
+ return null;
348
+ }
349
+ };
452
350
  function apply(ctx, cfg) {
453
351
  const d = {
454
352
  guessNumber: {
@@ -467,10 +365,10 @@ function apply(ctx, cfg) {
467
365
  autoStop: "游戏因长时间无人操作,已自动结束"
468
366
  },
469
367
  wzHero: {
470
- start: "猜王者英雄开始!本次共 {0} 回合~",
471
- startUsage: "用法错误!正确用法:猜王者英雄 开始 [难度] | 猜王者英雄 [答案] | 猜王者英雄 提示 | 猜王者英雄 结束",
368
+ start: "猜王者英雄开始!本次共 {0} 回合~当前难度:{1}",
369
+ startUsage: "用法错误!正确用法:猜王者英雄 开始 | 猜王者英雄 [答案] | 猜王者英雄 提示 | 猜王者英雄 结束",
472
370
  stop: "猜王者英雄比赛已停止",
473
- notStarted: "猜王者英雄比赛尚未开始,请输入 猜王者英雄 开始 [难度] 开始游戏",
371
+ notStarted: "猜王者英雄比赛尚未开始,请输入 猜王者英雄 开始 开始游戏",
474
372
  hint: "提示",
475
373
  apiError: "API请求失败,请稍后再试",
476
374
  correct: "答对啦!你获得1分~",
@@ -483,7 +381,7 @@ function apply(ctx, cfg) {
483
381
  autoStop: "游戏因长时间无人操作,已自动结束"
484
382
  },
485
383
  chengyuImage: {
486
- start: "看图猜成语比赛开始!本次共 {0} 回合~",
384
+ start: "看图猜成语比赛开始!本次共 {0} 回合~当前提示级别:{1}",
487
385
  stop: "看图猜成语比赛已停止",
488
386
  submitUsage: "请直接输入 看图猜成语 [答案],或输入 看图猜成语 提示 获取线索",
489
387
  notStarted: "看图猜成语比赛尚未开始,请输入 看图猜成语 开始 开始游戏",
@@ -520,42 +418,11 @@ function apply(ctx, cfg) {
520
418
  disabled: "成语接龙功能已关闭,请联系管理员开启",
521
419
  autoStop: "游戏因长时间无人操作,已自动结束"
522
420
  },
523
- dice: {
524
- start: "掷骰子比大小游戏开始!本次共 {0} 回合~",
525
- stop: "掷骰子比大小游戏已停止",
526
- notStarted: "掷骰子比大小游戏尚未开始,请输入 掷骰子 开始 开始游戏",
527
- roll: "🎲 你掷出了 {0} 点!机器人掷出了 {1} 点!",
528
- win: "你赢了这一回合!获得1分~",
529
- lose: "机器人赢了这一回合!",
530
- draw: "平局!双方都不得分~",
531
- roundEnd: "第 {0} 回合结束!剩余回合:{1}",
532
- gameEnd: "🎉 掷骰子比大小游戏结束!🎉",
533
- rankTitle: "🏆 排行榜 🏆",
534
- rankEmpty: "暂无参与记录~",
535
- disabled: "掷骰子比大小功能已关闭,请联系管理员开启",
536
- autoStop: "游戏因长时间无人操作,已自动结束"
537
- },
538
- rps: {
539
- start: "石头剪刀布游戏开始!本次共 {0} 回合~",
540
- stop: "石头剪刀布游戏已停止",
541
- notStarted: "石头剪刀布游戏尚未开始,请输入 石头剪刀布 开始 开始游戏",
542
- choice: "你选择了 {0},机器人选择了 {1}!",
543
- win: "你赢了这一回合!获得1分~",
544
- lose: "机器人赢了这一回合!",
545
- draw: "平局!双方都不得分~",
546
- invalidChoice: "无效的选择!请输入 石头、剪刀 或 布",
547
- roundEnd: "第 {0} 回合结束!剩余回合:{1}",
548
- gameEnd: "🎉 石头剪刀布游戏结束!🎉",
549
- rankTitle: "🏆 排行榜 🏆",
550
- rankEmpty: "暂无参与记录~",
551
- disabled: "石头剪刀布功能已关闭,请联系管理员开启",
552
- autoStop: "游戏因长时间无人操作,已自动结束"
553
- },
554
421
  calc24: {
555
- start: "算24点游戏开始!本次共 {0} 回合~",
422
+ start: "算24点游戏开始!本次共 {0} 回合~当前难度:{1}",
556
423
  stop: "算24点游戏已停止",
557
424
  notStarted: "算24点游戏尚未开始,请输入 算24点 开始 开始游戏",
558
- generate: "📝 第 {0} 题:用 {1} 通过加减乘除算出24!",
425
+ generate: "📝 第 {0} 题({1}):用 {2} 通过加减乘除和括号算出24!",
559
426
  correct: "答对啦!你获得1分~",
560
427
  wrong: "答错啦~",
561
428
  impossible: "这组数无法算出24!本题作废,换一组数字~",
@@ -613,7 +480,7 @@ function apply(ctx, cfg) {
613
480
  return;
614
481
  if (st.chengyuJielong.hasTriggeredAutoPlay)
615
482
  return;
616
- const delay = cfg.autoPlayDelay * 1000;
483
+ const delay = cfg.chengyuJielong.autoPlayDelay * 1000;
617
484
  st.chengyuJielong.autoPlayTimer = setTimeout(() => {
618
485
  doAutoPlay(session, key, st);
619
486
  }, delay);
@@ -623,11 +490,11 @@ function apply(ctx, cfg) {
623
490
  return;
624
491
  if (st.chengyuJielong.hasTriggeredAutoPlay)
625
492
  return;
626
- if (st.chengyuJielong.autoPlayCount >= cfg.autoPlayMaxCount) {
627
- session.send(d.chengyuJielong.autoPlayTooMany.replace('{0}', String(cfg.autoPlayMaxCount)));
493
+ if (st.chengyuJielong.autoPlayCount >= cfg.chengyuJielong.autoPlayMaxCount) {
494
+ session.send(d.chengyuJielong.autoPlayTooMany.replace('{0}', String(cfg.chengyuJielong.autoPlayMaxCount)));
628
495
  st.chengyuJielong.hasTriggeredAutoPlay = true;
629
496
  gameStates.set(key, st);
630
- setupAutoStop(session, st.chengyuJielong, cfg, d.chengyuJielong.autoStop, cfg.chengyuJielong.showRank);
497
+ setupAutoStop(session, st.chengyuJielong, cfg, 'chengyuJielong', d.chengyuJielong.autoStop, cfg.chengyuJielong.showRank);
631
498
  return;
632
499
  }
633
500
  st.chengyuJielong.hasTriggeredAutoPlay = true;
@@ -678,7 +545,7 @@ function apply(ctx, cfg) {
678
545
  await session.send(d.chengyuJielong.apiError);
679
546
  }
680
547
  gameStates.set(key, st);
681
- setupAutoStop(session, st.chengyuJielong, cfg, d.chengyuJielong.autoStop, cfg.chengyuJielong.showRank);
548
+ setupAutoStop(session, st.chengyuJielong, cfg, 'chengyuJielong', d.chengyuJielong.autoStop, cfg.chengyuJielong.showRank);
682
549
  };
683
550
  ctx.middleware(async (session, next) => {
684
551
  if (!session.content)
@@ -697,7 +564,7 @@ function apply(ctx, cfg) {
697
564
  st.chengyuJielong.participants.push(playerKey);
698
565
  }
699
566
  if (!isFourCharIdiom(content)) {
700
- setupAutoStop(session, st.chengyuJielong, cfg, d.chengyuJielong.autoStop, cfg.chengyuJielong.showRank);
567
+ setupAutoStop(session, st.chengyuJielong, cfg, 'chengyuJielong', d.chengyuJielong.autoStop, cfg.chengyuJielong.showRank);
701
568
  scheduleAutoPlay(session, key, st);
702
569
  return next();
703
570
  }
@@ -747,7 +614,7 @@ function apply(ctx, cfg) {
747
614
  m += '\n' + d.chengyuJielong.roundEnd.replace('{0}', st.chengyuJielong.currentRound.toString()).replace('{1}', (st.chengyuJielong.totalRounds - st.chengyuJielong.currentRound).toString());
748
615
  await session.send(m);
749
616
  st.chengyuJielong.hasTriggeredAutoPlay = false;
750
- setupAutoStop(session, st.chengyuJielong, cfg, d.chengyuJielong.autoStop, cfg.chengyuJielong.showRank);
617
+ setupAutoStop(session, st.chengyuJielong, cfg, 'chengyuJielong', d.chengyuJielong.autoStop, cfg.chengyuJielong.showRank);
751
618
  scheduleAutoPlay(session, key, st);
752
619
  }
753
620
  }
@@ -760,7 +627,7 @@ function apply(ctx, cfg) {
760
627
  }
761
628
  catch (error) {
762
629
  await session.send(d.chengyuJielong.apiError);
763
- setupAutoStop(session, st.chengyuJielong, cfg, d.chengyuJielong.autoStop, cfg.chengyuJielong.showRank);
630
+ setupAutoStop(session, st.chengyuJielong, cfg, 'chengyuJielong', d.chengyuJielong.autoStop, cfg.chengyuJielong.showRank);
764
631
  scheduleAutoPlay(session, key, st);
765
632
  }
766
633
  gameStates.set(key, st);
@@ -778,7 +645,7 @@ function apply(ctx, cfg) {
778
645
  params: {
779
646
  action: 'get_hint',
780
647
  id: st.chengyuImage.currentId,
781
- level: 1
648
+ level: cfg.chengyuImage.defaultHintLevel
782
649
  },
783
650
  timeout: cfg.apiConfig.timeout
784
651
  });
@@ -793,11 +660,11 @@ function apply(ctx, cfg) {
793
660
  catch (error) {
794
661
  await session.send(d.chengyuImage.hintError);
795
662
  }
796
- setupAutoStop(session, st.chengyuImage, cfg, d.chengyuImage.autoStop, cfg.chengyuImage.showRank);
663
+ setupAutoStop(session, st.chengyuImage, cfg, 'chengyuImage', d.chengyuImage.autoStop, cfg.chengyuImage.showRank);
797
664
  return;
798
665
  }
799
666
  if (!isFourCharIdiom(content)) {
800
- setupAutoStop(session, st.chengyuImage, cfg, d.chengyuImage.autoStop, cfg.chengyuImage.showRank);
667
+ setupAutoStop(session, st.chengyuImage, cfg, 'chengyuImage', d.chengyuImage.autoStop, cfg.chengyuImage.showRank);
801
668
  return next();
802
669
  }
803
670
  try {
@@ -873,7 +740,7 @@ function apply(ctx, cfg) {
873
740
  catch (error) {
874
741
  await session.send(d.chengyuImage.apiError);
875
742
  }
876
- setupAutoStop(session, st.chengyuImage, cfg, d.chengyuImage.autoStop, cfg.chengyuImage.showRank);
743
+ setupAutoStop(session, st.chengyuImage, cfg, 'chengyuImage', d.chengyuImage.autoStop, cfg.chengyuImage.showRank);
877
744
  gameStates.set(key, st);
878
745
  return;
879
746
  }
@@ -941,7 +808,7 @@ function apply(ctx, cfg) {
941
808
  catch (error) {
942
809
  await session.send(d.wzHero.apiError);
943
810
  }
944
- setupAutoStop(session, st.wzHero, cfg, d.wzHero.autoStop, cfg.wzHero.showRank);
811
+ setupAutoStop(session, st.wzHero, cfg, 'wzHero', d.wzHero.autoStop, cfg.wzHero.showRank);
945
812
  gameStates.set(key, st);
946
813
  return;
947
814
  }
@@ -959,7 +826,7 @@ function apply(ctx, cfg) {
959
826
  }
960
827
  const num = parseInt(content);
961
828
  if (isNaN(num)) {
962
- setupAutoStop(session, st.guessNumber, cfg, d.guessNumber.autoStop, cfg.guessNumber.showRank);
829
+ setupAutoStop(session, st.guessNumber, cfg, 'guessNumber', d.guessNumber.autoStop, cfg.guessNumber.showRank);
963
830
  return next();
964
831
  }
965
832
  if (num === st.guessNumber.target) {
@@ -990,108 +857,7 @@ function apply(ctx, cfg) {
990
857
  st.guessNumber.currentMax = num - 1;
991
858
  await session.send(d.guessNumber.tooBig.replace('{0}', st.guessNumber.currentMin.toString()).replace('{1}', st.guessNumber.currentMax.toString()));
992
859
  }
993
- setupAutoStop(session, st.guessNumber, cfg, d.guessNumber.autoStop, cfg.guessNumber.showRank);
994
- gameStates.set(key, st);
995
- return;
996
- }
997
- if (cfg.enableDice && st.dice.started) {
998
- clearGameTimer(st.dice);
999
- if (!st.dice.players[playerKey]) {
1000
- st.dice.players[playerKey] = getPlayerData(session);
1001
- st.dice.participants.push(playerKey);
1002
- }
1003
- if (content === '结束') {
1004
- clearGameData(st.dice);
1005
- await session.send(d.dice.stop);
1006
- gameStates.set(key, st);
1007
- return;
1008
- }
1009
- if (content !== '掷骰子') {
1010
- setupAutoStop(session, st.dice, cfg, d.dice.autoStop, cfg.dice.showRank);
1011
- return next();
1012
- }
1013
- st.dice.playerDice = koishi_1.Random.int(1, 6);
1014
- st.dice.botDice = koishi_1.Random.int(1, 6);
1015
- let resultMsg = d.dice.roll.replace('{0}', st.dice.playerDice.toString()).replace('{1}', st.dice.botDice.toString());
1016
- if (st.dice.playerDice > st.dice.botDice) {
1017
- resultMsg += '\n' + d.dice.win;
1018
- st.dice.players[playerKey].score += 1;
1019
- st.dice.players[playerKey].correctCount += 1;
1020
- }
1021
- else if (st.dice.playerDice < st.dice.botDice) {
1022
- resultMsg += '\n' + d.dice.lose;
1023
- }
1024
- else {
1025
- resultMsg += '\n' + d.dice.draw;
1026
- }
1027
- await session.send(resultMsg);
1028
- st.dice.currentRound += 1;
1029
- if (st.dice.currentRound > st.dice.totalRounds) {
1030
- st.dice.started = false;
1031
- clearGameTimer(st.dice);
1032
- await session.send(d.dice.gameEnd);
1033
- if (cfg.dice.showRank && !isPrivate(session)) {
1034
- const rankText = generateRankText(st.dice.players);
1035
- await session.send(rankText);
1036
- }
1037
- clearGameData(st.dice);
1038
- }
1039
- else {
1040
- await session.send(d.dice.roundEnd.replace('{0}', st.dice.currentRound.toString()).replace('{1}', (st.dice.totalRounds - st.dice.currentRound).toString()));
1041
- }
1042
- setupAutoStop(session, st.dice, cfg, d.dice.autoStop, cfg.dice.showRank);
1043
- gameStates.set(key, st);
1044
- return;
1045
- }
1046
- if (cfg.enableRps && st.rps.started) {
1047
- clearGameTimer(st.rps);
1048
- if (!st.rps.players[playerKey]) {
1049
- st.rps.players[playerKey] = getPlayerData(session);
1050
- st.rps.participants.push(playerKey);
1051
- }
1052
- if (content === '结束') {
1053
- clearGameData(st.rps);
1054
- await session.send(d.rps.stop);
1055
- gameStates.set(key, st);
1056
- return;
1057
- }
1058
- if (!st.rps.choices.includes(content)) {
1059
- await session.send(d.rps.invalidChoice);
1060
- setupAutoStop(session, st.rps, cfg, d.rps.autoStop, cfg.rps.showRank);
1061
- return;
1062
- }
1063
- st.rps.playerChoice = content;
1064
- st.rps.botChoice = st.rps.choices[koishi_1.Random.int(0, 2)];
1065
- let resultMsg = d.rps.choice.replace('{0}', st.rps.playerChoice).replace('{1}', st.rps.botChoice);
1066
- if ((st.rps.playerChoice === '石头' && st.rps.botChoice === '剪刀') ||
1067
- (st.rps.playerChoice === '剪刀' && st.rps.botChoice === '布') ||
1068
- (st.rps.playerChoice === '布' && st.rps.botChoice === '石头')) {
1069
- resultMsg += '\n' + d.rps.win;
1070
- st.rps.players[playerKey].score += 1;
1071
- st.rps.players[playerKey].correctCount += 1;
1072
- }
1073
- else if (st.rps.playerChoice === st.rps.botChoice) {
1074
- resultMsg += '\n' + d.rps.draw;
1075
- }
1076
- else {
1077
- resultMsg += '\n' + d.rps.lose;
1078
- }
1079
- await session.send(resultMsg);
1080
- st.rps.currentRound += 1;
1081
- if (st.rps.currentRound > st.rps.totalRounds) {
1082
- st.rps.started = false;
1083
- clearGameTimer(st.rps);
1084
- await session.send(d.rps.gameEnd);
1085
- if (cfg.rps.showRank && !isPrivate(session)) {
1086
- const rankText = generateRankText(st.rps.players);
1087
- await session.send(rankText);
1088
- }
1089
- clearGameData(st.rps);
1090
- }
1091
- else {
1092
- await session.send(d.rps.roundEnd.replace('{0}', st.rps.currentRound.toString()).replace('{1}', (st.rps.totalRounds - st.rps.currentRound).toString()));
1093
- }
1094
- setupAutoStop(session, st.rps, cfg, d.rps.autoStop, cfg.rps.showRank);
860
+ setupAutoStop(session, st.guessNumber, cfg, 'guessNumber', d.guessNumber.autoStop, cfg.guessNumber.showRank);
1095
861
  gameStates.set(key, st);
1096
862
  return;
1097
863
  }
@@ -1109,81 +875,54 @@ function apply(ctx, cfg) {
1109
875
  }
1110
876
  if (content === '换题') {
1111
877
  if (!st.calc24.solved) {
1112
- st.calc24.numbers = [];
1113
- for (let i = 0; i < 4; i++) {
1114
- st.calc24.numbers.push(koishi_1.Random.int(cfg.calc24.numberRange[0], cfg.calc24.numberRange[1]));
1115
- }
878
+ const range = cfg.calc24.difficultyLevels[st.calc24.difficulty === '简单' ? 'easy' :
879
+ st.calc24.difficulty === '中等' ? 'medium' : 'hard'];
880
+ st.calc24.numbers = generateSolvable24Numbers(range.min, range.max);
1116
881
  st.calc24.solved = false;
1117
- const canCalculate = calculate24([...st.calc24.numbers]);
1118
- if (!canCalculate) {
1119
- await session.send(d.calc24.impossible);
1120
- }
1121
- else {
1122
- await session.send(d.calc24.generate.replace('{0}', st.calc24.currentRound.toString()).replace('{1}', st.calc24.numbers.join('、')));
1123
- }
882
+ await session.send(d.calc24.generate.replace('{0}', st.calc24.currentRound.toString())
883
+ .replace('{1}', st.calc24.difficulty)
884
+ .replace('{2}', st.calc24.numbers.join('、')));
1124
885
  }
1125
- setupAutoStop(session, st.calc24, cfg, d.calc24.autoStop, cfg.calc24.showRank);
886
+ setupAutoStop(session, st.calc24, cfg, 'calc24', d.calc24.autoStop, cfg.calc24.showRank);
1126
887
  return;
1127
888
  }
1128
889
  if (st.calc24.solved) {
1129
890
  await session.send(d.calc24.solved);
1130
- setupAutoStop(session, st.calc24, cfg, d.calc24.autoStop, cfg.calc24.showRank);
891
+ setupAutoStop(session, st.calc24, cfg, 'calc24', d.calc24.autoStop, cfg.calc24.showRank);
1131
892
  return;
1132
893
  }
1133
- st.calc24.playerAnswer = content;
1134
- const canCalculate = calculate24([...st.calc24.numbers]);
1135
- if (!canCalculate) {
1136
- await session.send(d.calc24.impossible);
1137
- st.calc24.numbers = [];
1138
- for (let i = 0; i < 4; i++) {
1139
- st.calc24.numbers.push(koishi_1.Random.int(cfg.calc24.numberRange[0], cfg.calc24.numberRange[1]));
1140
- }
1141
- await session.send(d.calc24.generate.replace('{0}', st.calc24.currentRound.toString()).replace('{1}', st.calc24.numbers.join('、')));
1142
- }
1143
- else {
1144
- try {
1145
- const result = eval(content.replace(/[^\d\+\-\*\/\(\)\.]/g, ''));
1146
- if (Math.abs(result - 24) < 0.001) {
1147
- await session.send(d.calc24.correct);
1148
- st.calc24.players[playerKey].score += 1;
1149
- st.calc24.players[playerKey].correctCount += 1;
1150
- st.calc24.solved = true;
1151
- st.calc24.currentRound += 1;
1152
- if (st.calc24.currentRound > st.calc24.totalRounds) {
1153
- st.calc24.started = false;
1154
- clearGameTimer(st.calc24);
1155
- await session.send(d.calc24.gameEnd);
1156
- if (cfg.calc24.showRank && !isPrivate(session)) {
1157
- const rankText = generateRankText(st.calc24.players);
1158
- await session.send(rankText);
1159
- }
1160
- clearGameData(st.calc24);
1161
- }
1162
- else {
1163
- await session.send(d.calc24.roundEnd.replace('{0}', st.calc24.currentRound.toString()).replace('{1}', (st.calc24.totalRounds - st.calc24.currentRound).toString()));
1164
- st.calc24.numbers = [];
1165
- for (let i = 0; i < 4; i++) {
1166
- st.calc24.numbers.push(koishi_1.Random.int(cfg.calc24.numberRange[0], cfg.calc24.numberRange[1]));
1167
- }
1168
- st.calc24.solved = false;
1169
- const nextCanCalculate = calculate24([...st.calc24.numbers]);
1170
- if (!nextCanCalculate) {
1171
- await session.send(d.calc24.impossible);
1172
- }
1173
- else {
1174
- await session.send(d.calc24.generate.replace('{0}', st.calc24.currentRound.toString()).replace('{1}', st.calc24.numbers.join('、')));
1175
- }
1176
- }
1177
- }
1178
- else {
1179
- await session.send(d.calc24.wrong);
894
+ const result = evaluateExpression(content);
895
+ if (result !== null && Math.abs(result - 24) < 0.001) {
896
+ await session.send(d.calc24.correct);
897
+ st.calc24.players[playerKey].score += 1;
898
+ st.calc24.players[playerKey].correctCount += 1;
899
+ st.calc24.solved = true;
900
+ st.calc24.currentRound += 1;
901
+ if (st.calc24.currentRound > st.calc24.totalRounds) {
902
+ st.calc24.started = false;
903
+ clearGameTimer(st.calc24);
904
+ await session.send(d.calc24.gameEnd);
905
+ if (cfg.calc24.showRank && !isPrivate(session)) {
906
+ const rankText = generateRankText(st.calc24.players);
907
+ await session.send(rankText);
1180
908
  }
909
+ clearGameData(st.calc24);
1181
910
  }
1182
- catch {
1183
- await session.send(d.calc24.wrong);
911
+ else {
912
+ await session.send(d.calc24.roundEnd.replace('{0}', st.calc24.currentRound.toString()).replace('{1}', (st.calc24.totalRounds - st.calc24.currentRound).toString()));
913
+ const range = cfg.calc24.difficultyLevels[st.calc24.difficulty === '简单' ? 'easy' :
914
+ st.calc24.difficulty === '中等' ? 'medium' : 'hard'];
915
+ st.calc24.numbers = generateSolvable24Numbers(range.min, range.max);
916
+ st.calc24.solved = false;
917
+ await session.send(d.calc24.generate.replace('{0}', st.calc24.currentRound.toString())
918
+ .replace('{1}', st.calc24.difficulty)
919
+ .replace('{2}', st.calc24.numbers.join('、')));
1184
920
  }
1185
921
  }
1186
- setupAutoStop(session, st.calc24, cfg, d.calc24.autoStop, cfg.calc24.showRank);
922
+ else {
923
+ await session.send(d.calc24.wrong);
924
+ }
925
+ setupAutoStop(session, st.calc24, cfg, 'calc24', d.calc24.autoStop, cfg.calc24.showRank);
1187
926
  gameStates.set(key, st);
1188
927
  return;
1189
928
  }
@@ -1201,20 +940,21 @@ function apply(ctx, cfg) {
1201
940
  }
1202
941
  if (st.passwordLock.solved) {
1203
942
  await session.send(d.passwordLock.solved);
1204
- setupAutoStop(session, st.passwordLock, cfg, d.passwordLock.autoStop, cfg.passwordLock.showRank);
943
+ setupAutoStop(session, st.passwordLock, cfg, 'passwordLock', d.passwordLock.autoStop, cfg.passwordLock.showRank);
1205
944
  return;
1206
945
  }
1207
946
  if (!/^\d{4}$/.test(content)) {
1208
947
  await session.send(d.passwordLock.invalidPassword);
1209
- setupAutoStop(session, st.passwordLock, cfg, d.passwordLock.autoStop, cfg.passwordLock.showRank);
948
+ setupAutoStop(session, st.passwordLock, cfg, 'passwordLock', d.passwordLock.autoStop, cfg.passwordLock.showRank);
1210
949
  return;
1211
950
  }
1212
951
  st.passwordLock.playerGuess = content;
1213
952
  st.passwordLock.guessTimes += 1;
1214
953
  await session.send(d.passwordLock.guess.replace('{0}', content).replace('{1}', st.passwordLock.guessTimes.toString()));
1215
954
  if (content === st.passwordLock.password) {
955
+ const score = 10 - (st.passwordLock.guessTimes - 1);
1216
956
  await session.send(d.passwordLock.correct.replace('{0}', content).replace('{1}', st.passwordLock.guessTimes.toString()));
1217
- st.passwordLock.players[playerKey].score += 10 - (st.passwordLock.guessTimes - 1);
957
+ st.passwordLock.players[playerKey].score += score > 0 ? score : 1;
1218
958
  st.passwordLock.players[playerKey].correctCount += 1;
1219
959
  st.passwordLock.solved = true;
1220
960
  st.passwordLock.started = false;
@@ -1230,6 +970,10 @@ function apply(ctx, cfg) {
1230
970
  let hint = '';
1231
971
  if (cfg.passwordLock.showHint) {
1232
972
  hint = generatePasswordHint(st.passwordLock.password, content);
973
+ await session.send(d.passwordLock.wrong.replace('{0}', hint));
974
+ }
975
+ else {
976
+ await session.send(d.passwordLock.wrong.replace('{0}', ''));
1233
977
  }
1234
978
  if (st.passwordLock.guessTimes >= st.passwordLock.maxGuessTimes) {
1235
979
  await session.send(d.passwordLock.noChance.replace('{0}', st.passwordLock.password));
@@ -1243,11 +987,10 @@ function apply(ctx, cfg) {
1243
987
  clearGameData(st.passwordLock);
1244
988
  }
1245
989
  else {
1246
- await session.send(d.passwordLock.wrong.replace('{0}', hint));
1247
990
  await session.send(`剩余猜测次数:${st.passwordLock.maxGuessTimes - st.passwordLock.guessTimes}`);
1248
991
  }
1249
992
  }
1250
- setupAutoStop(session, st.passwordLock, cfg, d.passwordLock.autoStop, cfg.passwordLock.showRank);
993
+ setupAutoStop(session, st.passwordLock, cfg, 'passwordLock', d.passwordLock.autoStop, cfg.passwordLock.showRank);
1251
994
  gameStates.set(key, st);
1252
995
  return;
1253
996
  }
@@ -1273,7 +1016,7 @@ function apply(ctx, cfg) {
1273
1016
  await session.send(d.guessNumber.start.replace('{0}', st.guessNumber.totalRounds.toString()));
1274
1017
  await session.send(`猜数字范围:${st.guessNumber.currentMin} - ${st.guessNumber.currentMax}`);
1275
1018
  gameStates.set(key, st);
1276
- setupAutoStop(session, st.guessNumber, cfg, d.guessNumber.autoStop, cfg.guessNumber.showRank);
1019
+ setupAutoStop(session, st.guessNumber, cfg, 'guessNumber', d.guessNumber.autoStop, cfg.guessNumber.showRank);
1277
1020
  }
1278
1021
  else if (action === '结束') {
1279
1022
  clearGameData(st.guessNumber);
@@ -1297,7 +1040,7 @@ function apply(ctx, cfg) {
1297
1040
  }
1298
1041
  if (action === '开始') {
1299
1042
  st.wzHero.started = true;
1300
- st.wzHero.difficulty = param || '简单';
1043
+ st.wzHero.difficulty = cfg.wzHero.defaultDifficulty;
1301
1044
  st.wzHero.currentRound = 1;
1302
1045
  try {
1303
1046
  const r = await axios_1.default.get('https://api.suol.cc/v1/game_wz.php', {
@@ -1307,7 +1050,7 @@ function apply(ctx, cfg) {
1307
1050
  const dt = r.data;
1308
1051
  let text = `${dt.message || ''}\n${dt.hint || ''}\n剩余提示次数:${dt.remaining_hints}\n${dt.guide || ''}`;
1309
1052
  text = text.replace(/\\n/g, '\n');
1310
- await session.send(d.wzHero.start.replace('{0}', st.wzHero.totalRounds.toString()));
1053
+ await session.send(d.wzHero.start.replace('{0}', st.wzHero.totalRounds.toString()).replace('{1}', st.wzHero.difficulty));
1311
1054
  await session.send(text);
1312
1055
  st.wzHero.currentAnswer = dt.hint || '';
1313
1056
  }
@@ -1315,7 +1058,7 @@ function apply(ctx, cfg) {
1315
1058
  await session.send(d.wzHero.apiError);
1316
1059
  }
1317
1060
  gameStates.set(key, st);
1318
- setupAutoStop(session, st.wzHero, cfg, d.wzHero.autoStop, cfg.wzHero.showRank);
1061
+ setupAutoStop(session, st.wzHero, cfg, 'wzHero', d.wzHero.autoStop, cfg.wzHero.showRank);
1319
1062
  }
1320
1063
  else if (action === '结束') {
1321
1064
  clearGameData(st.wzHero);
@@ -1351,7 +1094,7 @@ function apply(ctx, cfg) {
1351
1094
  st.chengyuImage.currentPage = dt.data.question.page;
1352
1095
  st.chengyuImage.options = dt.data.question.options;
1353
1096
  st.chengyuImage.answer = dt.data.question.answer || '';
1354
- await session.send(d.chengyuImage.start.replace('{0}', st.chengyuImage.totalRounds.toString()));
1097
+ await session.send(d.chengyuImage.start.replace('{0}', st.chengyuImage.totalRounds.toString()).replace('{1}', cfg.chengyuImage.defaultHintLevel.toString()));
1355
1098
  await session.send(`请从选项中选择4个字组成成语\n选项:${dt.data.question.options.join('、')}`);
1356
1099
  await session.send(koishi_1.segment.image(dt.data.question.image_url));
1357
1100
  }
@@ -1363,7 +1106,7 @@ function apply(ctx, cfg) {
1363
1106
  await session.send(d.chengyuImage.apiError);
1364
1107
  }
1365
1108
  gameStates.set(key, st);
1366
- setupAutoStop(session, st.chengyuImage, cfg, d.chengyuImage.autoStop, cfg.chengyuImage.showRank);
1109
+ setupAutoStop(session, st.chengyuImage, cfg, 'chengyuImage', d.chengyuImage.autoStop, cfg.chengyuImage.showRank);
1367
1110
  }
1368
1111
  else if (action === '结束') {
1369
1112
  clearGameData(st.chengyuImage);
@@ -1393,7 +1136,7 @@ function apply(ctx, cfg) {
1393
1136
  await session.send(d.chengyuJielong.start.replace('{0}', st.chengyuJielong.totalRounds.toString()));
1394
1137
  gameStates.set(key, st);
1395
1138
  scheduleAutoPlay(session, key, st);
1396
- setupAutoStop(session, st.chengyuJielong, cfg, d.chengyuJielong.autoStop, cfg.chengyuJielong.showRank);
1139
+ setupAutoStop(session, st.chengyuJielong, cfg, 'chengyuJielong', d.chengyuJielong.autoStop, cfg.chengyuJielong.showRank);
1397
1140
  }
1398
1141
  else if (action === '结束') {
1399
1142
  clearGameData(st.chengyuJielong);
@@ -1404,60 +1147,6 @@ function apply(ctx, cfg) {
1404
1147
  await session.send(d.chengyuJielong.joinUsage);
1405
1148
  }
1406
1149
  });
1407
- ctx.command('掷骰子 <action>', '掷骰子比大小')
1408
- .action(async (argv, action) => {
1409
- const session = argv.session;
1410
- if (!session)
1411
- return;
1412
- const key = getSessionKey(session);
1413
- const st = gameStates.get(key) || initState(key, cfg);
1414
- if (checkGameRunning(st, 'dice')) {
1415
- await session.send(d.common.gameRunning);
1416
- return;
1417
- }
1418
- if (action === '开始') {
1419
- st.dice.started = true;
1420
- st.dice.currentRound = 1;
1421
- await session.send(d.dice.start.replace('{0}', st.dice.totalRounds.toString()));
1422
- gameStates.set(key, st);
1423
- setupAutoStop(session, st.dice, cfg, d.dice.autoStop, cfg.dice.showRank);
1424
- }
1425
- else if (action === '结束') {
1426
- clearGameData(st.dice);
1427
- await session.send(d.dice.stop);
1428
- gameStates.set(key, st);
1429
- }
1430
- else {
1431
- await session.send('请输入:掷骰子 开始 或 掷骰子 结束');
1432
- }
1433
- });
1434
- ctx.command('石头剪刀布 <action>', '石头剪刀布')
1435
- .action(async (argv, action) => {
1436
- const session = argv.session;
1437
- if (!session)
1438
- return;
1439
- const key = getSessionKey(session);
1440
- const st = gameStates.get(key) || initState(key, cfg);
1441
- if (checkGameRunning(st, 'rps')) {
1442
- await session.send(d.common.gameRunning);
1443
- return;
1444
- }
1445
- if (action === '开始') {
1446
- st.rps.started = true;
1447
- st.rps.currentRound = 1;
1448
- await session.send(d.rps.start.replace('{0}', st.rps.totalRounds.toString()));
1449
- gameStates.set(key, st);
1450
- setupAutoStop(session, st.rps, cfg, d.rps.autoStop, cfg.rps.showRank);
1451
- }
1452
- else if (action === '结束') {
1453
- clearGameData(st.rps);
1454
- await session.send(d.rps.stop);
1455
- gameStates.set(key, st);
1456
- }
1457
- else {
1458
- await session.send('请输入:石头剪刀布 开始 或 石头剪刀布 结束');
1459
- }
1460
- });
1461
1150
  ctx.command('算24点 <action>', '算24点游戏')
1462
1151
  .action(async (argv, action) => {
1463
1152
  const session = argv.session;
@@ -1470,23 +1159,19 @@ function apply(ctx, cfg) {
1470
1159
  return;
1471
1160
  }
1472
1161
  if (action === '开始') {
1162
+ st.calc24.difficulty = cfg.calc24.defaultDifficulty;
1473
1163
  st.calc24.started = true;
1474
1164
  st.calc24.currentRound = 1;
1475
1165
  st.calc24.solved = false;
1476
- st.calc24.numbers = [];
1477
- for (let i = 0; i < 4; i++) {
1478
- st.calc24.numbers.push(koishi_1.Random.int(cfg.calc24.numberRange[0], cfg.calc24.numberRange[1]));
1479
- }
1480
- await session.send(d.calc24.start.replace('{0}', st.calc24.totalRounds.toString()));
1481
- const canCalculate = calculate24([...st.calc24.numbers]);
1482
- if (!canCalculate) {
1483
- await session.send(d.calc24.impossible);
1484
- }
1485
- else {
1486
- await session.send(d.calc24.generate.replace('{0}', st.calc24.currentRound.toString()).replace('{1}', st.calc24.numbers.join('、')));
1487
- }
1166
+ const range = cfg.calc24.difficultyLevels[st.calc24.difficulty === '简单' ? 'easy' :
1167
+ st.calc24.difficulty === '中等' ? 'medium' : 'hard'];
1168
+ st.calc24.numbers = generateSolvable24Numbers(range.min, range.max);
1169
+ await session.send(d.calc24.start.replace('{0}', st.calc24.totalRounds.toString()).replace('{1}', st.calc24.difficulty));
1170
+ await session.send(d.calc24.generate.replace('{0}', st.calc24.currentRound.toString())
1171
+ .replace('{1}', st.calc24.difficulty)
1172
+ .replace('{2}', st.calc24.numbers.join('、')));
1488
1173
  gameStates.set(key, st);
1489
- setupAutoStop(session, st.calc24, cfg, d.calc24.autoStop, cfg.calc24.showRank);
1174
+ setupAutoStop(session, st.calc24, cfg, 'calc24', d.calc24.autoStop, cfg.calc24.showRank);
1490
1175
  }
1491
1176
  else if (action === '结束') {
1492
1177
  clearGameData(st.calc24);
@@ -1516,7 +1201,7 @@ function apply(ctx, cfg) {
1516
1201
  st.passwordLock.password = koishi_1.Random.int(1000, 9999).toString();
1517
1202
  await session.send(d.passwordLock.start.replace('{0}', st.passwordLock.maxGuessTimes.toString()));
1518
1203
  gameStates.set(key, st);
1519
- setupAutoStop(session, st.passwordLock, cfg, d.passwordLock.autoStop, cfg.passwordLock.showRank);
1204
+ setupAutoStop(session, st.passwordLock, cfg, 'passwordLock', d.passwordLock.autoStop, cfg.passwordLock.showRank);
1520
1205
  }
1521
1206
  else if (action === '结束') {
1522
1207
  clearGameData(st.passwordLock);