koishi-plugin-game-mini 0.2.2 → 0.2.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.js CHANGED
@@ -15,109 +15,189 @@ exports.using = ['i18n'];
15
15
  exports.inject = ['console'];
16
16
  exports.Config = koishi_1.Schema.object({
17
17
  enableNumberGuess: koishi_1.Schema.boolean().default(true)
18
- .description('是否启用猜数字游戏')
18
+ .description('启用猜数字游戏')
19
19
  .i18n({ 'zh-CN': '启用猜数字游戏' }),
20
20
  enableWzHero: koishi_1.Schema.boolean().default(true)
21
- .description('是否启用王者英雄猜谜游戏')
22
- .i18n({ 'zh-CN': '启用王者英雄猜谜' }),
21
+ .description('启用王者英雄猜谜游戏')
22
+ .i18n({ 'zh-CN': '启用王者英雄猜谜游戏' }),
23
23
  enableChengyuImage: koishi_1.Schema.boolean().default(true)
24
- .description('是否启用看图猜成语游戏')
25
- .i18n({ 'zh-CN': '启用看图猜成语' }),
24
+ .description('启用看图猜成语游戏')
25
+ .i18n({ 'zh-CN': '启用看图猜成语游戏' }),
26
26
  enableChengyuJielong: koishi_1.Schema.boolean().default(true)
27
- .description('是否启用成语接龙游戏')
28
- .i18n({ 'zh-CN': '启用成语接龙' }),
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': '启用密码锁破解游戏' }),
29
41
  enablePrivateGame: koishi_1.Schema.boolean().default(true)
30
- .description('是否允许私聊玩游戏')
42
+ .description('允许私聊玩游戏')
31
43
  .i18n({ 'zh-CN': '允许私聊玩游戏' }),
32
44
  autoPlayDelay: koishi_1.Schema.number().min(0).default(10)
33
- .description('成语接龙机器人自动接龙延迟(秒)')
34
- .i18n({ 'zh-CN': '机器人自动接龙延迟(秒)' }),
45
+ .description('机器人自动操作延迟(秒)')
46
+ .i18n({ 'zh-CN': '机器人自动操作延迟(秒)' }),
35
47
  autoPlayMaxCount: koishi_1.Schema.number().min(1).default(5)
36
- .description('成语接龙机器人最大自动接龙次数')
37
- .i18n({ 'zh-CN': '机器人最大自动接龙次数' }),
48
+ .description('机器人最大自动操作次数')
49
+ .i18n({ 'zh-CN': '机器人最大自动操作次数' }),
38
50
  autoStopInactiveTime: koishi_1.Schema.number().min(0).default(30)
39
51
  .description('游戏无操作自动停止时间(秒)')
40
- .i18n({ 'zh-CN': '无操作自动停止时间(秒)' }),
52
+ .i18n({ 'zh-CN': '游戏无操作自动停止时间(秒)' }),
41
53
  guessNumber: koishi_1.Schema.object({
42
54
  min: koishi_1.Schema.number().min(0).default(0)
43
55
  .description('猜数字最小值')
44
- .i18n({ 'zh-CN': '最小值' }),
56
+ .i18n({ 'zh-CN': '猜数字最小值' }),
45
57
  max: koishi_1.Schema.number().min(1).default(100)
46
58
  .description('猜数字最大值')
47
- .i18n({ 'zh-CN': '最大值' }),
59
+ .i18n({ 'zh-CN': '猜数字最大值' }),
48
60
  botParticipateInGroup: koishi_1.Schema.boolean().default(true)
49
- .description('群聊中机器人是否参与猜数字')
50
- .i18n({ 'zh-CN': '机器人参与群聊游戏' }),
61
+ .description('群聊中机器人参与猜数字')
62
+ .i18n({ 'zh-CN': '群聊中机器人参与猜数字' }),
51
63
  totalRounds: koishi_1.Schema.number().min(1).default(10)
52
64
  .description('猜数字总回合数')
53
- .i18n({ 'zh-CN': '总回合数' }),
65
+ .i18n({ 'zh-CN': '猜数字总回合数' }),
54
66
  showRank: koishi_1.Schema.boolean().default(true)
55
- .description('游戏结束后是否显示排行榜')
56
- .i18n({ 'zh-CN': '显示排行榜' }),
67
+ .description('猜数字显示排行榜')
68
+ .i18n({ 'zh-CN': '猜数字显示排行榜' }),
57
69
  }).description('猜数字游戏配置')
58
70
  .i18n({ 'zh-CN': '猜数字游戏配置' }),
59
71
  wzHero: koishi_1.Schema.object({
60
72
  totalRounds: koishi_1.Schema.number().min(1).default(10)
61
73
  .description('王者英雄猜谜总回合数')
62
- .i18n({ 'zh-CN': '总回合数' }),
74
+ .i18n({ 'zh-CN': '王者英雄猜谜总回合数' }),
63
75
  showRank: koishi_1.Schema.boolean().default(true)
64
- .description('游戏结束后是否显示排行榜')
65
- .i18n({ 'zh-CN': '显示排行榜' }),
76
+ .description('王者英雄猜谜显示排行榜')
77
+ .i18n({ 'zh-CN': '王者英雄猜谜显示排行榜' }),
66
78
  }).description('王者英雄猜谜游戏配置')
67
- .i18n({ 'zh-CN': '王者英雄猜谜配置' }),
79
+ .i18n({ 'zh-CN': '王者英雄猜谜游戏配置' }),
68
80
  chengyuImage: koishi_1.Schema.object({
69
81
  totalRounds: koishi_1.Schema.number().min(1).default(10)
70
82
  .description('看图猜成语总回合数')
71
- .i18n({ 'zh-CN': '总回合数' }),
83
+ .i18n({ 'zh-CN': '看图猜成语总回合数' }),
72
84
  showRank: koishi_1.Schema.boolean().default(true)
73
- .description('游戏结束后是否显示排行榜')
74
- .i18n({ 'zh-CN': '显示排行榜' }),
85
+ .description('看图猜成语显示排行榜')
86
+ .i18n({ 'zh-CN': '看图猜成语显示排行榜' }),
75
87
  }).description('看图猜成语游戏配置')
76
- .i18n({ 'zh-CN': '看图猜成语配置' }),
88
+ .i18n({ 'zh-CN': '看图猜成语游戏配置' }),
77
89
  chengyuJielong: koishi_1.Schema.object({
78
90
  botParticipateInGroup: koishi_1.Schema.boolean().default(true)
79
- .description('群聊中机器人是否参与成语接龙')
80
- .i18n({ 'zh-CN': '机器人参与群聊游戏' }),
91
+ .description('群聊中机器人参与成语接龙')
92
+ .i18n({ 'zh-CN': '群聊中机器人参与成语接龙' }),
81
93
  totalRounds: koishi_1.Schema.number().min(1).default(10)
82
94
  .description('成语接龙总回合数')
83
- .i18n({ 'zh-CN': '总回合数' }),
95
+ .i18n({ 'zh-CN': '成语接龙总回合数' }),
84
96
  showRank: koishi_1.Schema.boolean().default(true)
85
- .description('游戏结束后是否显示排行榜')
86
- .i18n({ 'zh-CN': '显示排行榜' }),
97
+ .description('成语接龙显示排行榜')
98
+ .i18n({ 'zh-CN': '成语接龙显示排行榜' }),
87
99
  }).description('成语接龙游戏配置')
88
- .i18n({ 'zh-CN': '成语接龙配置' }),
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': '石头剪刀布游戏配置' }),
125
+ 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点游戏配置' }),
137
+ 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': '密码锁破解游戏配置' }),
89
149
  apiConfig: koishi_1.Schema.object({
90
150
  timeout: koishi_1.Schema.number().default(5000)
91
151
  .description('API请求超时时间(毫秒)')
92
- .i18n({ 'zh-CN': '请求超时时间(毫秒)' }),
152
+ .i18n({ 'zh-CN': 'API请求超时时间(毫秒)' }),
93
153
  }).description('API接口配置')
94
154
  .i18n({ 'zh-CN': 'API接口配置' }),
95
155
  }).i18n({
96
156
  'zh-CN': {
97
157
  'enableNumberGuess': '启用猜数字游戏',
98
- 'enableWzHero': '启用王者英雄猜谜',
99
- 'enableChengyuImage': '启用看图猜成语',
100
- 'enableChengyuJielong': '启用成语接龙',
158
+ 'enableWzHero': '启用王者英雄猜谜游戏',
159
+ 'enableChengyuImage': '启用看图猜成语游戏',
160
+ 'enableChengyuJielong': '启用成语接龙游戏',
161
+ 'enableDice': '启用掷骰子比大小游戏',
162
+ 'enableRps': '启用石头剪刀布游戏',
163
+ 'enableCalc24': '启用算24点游戏',
164
+ 'enablePasswordLock': '启用密码锁破解游戏',
101
165
  'enablePrivateGame': '允许私聊玩游戏',
102
- 'autoPlayDelay': '机器人自动接龙延迟(秒)',
103
- 'autoPlayMaxCount': '机器人最大自动接龙次数',
104
- 'autoStopInactiveTime': '无操作自动停止时间(秒)',
166
+ 'autoPlayDelay': '机器人自动操作延迟(秒)',
167
+ 'autoPlayMaxCount': '机器人最大自动操作次数',
168
+ 'autoStopInactiveTime': '游戏无操作自动停止时间(秒)',
105
169
  'guessNumber': '猜数字游戏配置',
106
- 'guessNumber.min': '最小值',
107
- 'guessNumber.max': '最大值',
108
- 'guessNumber.botParticipateInGroup': '机器人参与群聊游戏',
109
- 'guessNumber.totalRounds': '总回合数',
110
- 'guessNumber.showRank': '显示排行榜',
170
+ 'guessNumber.min': '猜数字最小值',
171
+ 'guessNumber.max': '猜数字最大值',
172
+ 'guessNumber.botParticipateInGroup': '群聊中机器人参与猜数字',
173
+ 'guessNumber.totalRounds': '猜数字总回合数',
174
+ 'guessNumber.showRank': '猜数字显示排行榜',
111
175
  'wzHero': '王者英雄猜谜配置',
112
- 'wzHero.totalRounds': '总回合数',
113
- 'wzHero.showRank': '显示排行榜',
176
+ 'wzHero.totalRounds': '王者英雄猜谜总回合数',
177
+ 'wzHero.showRank': '王者英雄猜谜显示排行榜',
114
178
  'chengyuImage': '看图猜成语配置',
115
- 'chengyuImage.totalRounds': '总回合数',
116
- 'chengyuImage.showRank': '显示排行榜',
179
+ 'chengyuImage.totalRounds': '看图猜成语总回合数',
180
+ 'chengyuImage.showRank': '看图猜成语显示排行榜',
117
181
  'chengyuJielong': '成语接龙配置',
118
- 'chengyuJielong.botParticipateInGroup': '机器人参与群聊游戏',
119
- 'chengyuJielong.totalRounds': '总回合数',
120
- 'chengyuJielong.showRank': '显示排行榜',
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': '密码锁显示排行榜',
121
201
  'apiConfig': 'API接口配置',
122
202
  'apiConfig.timeout': '请求超时时间(毫秒)'
123
203
  }
@@ -149,6 +229,14 @@ const checkGameRunning = (s, t) => {
149
229
  return true;
150
230
  if (t !== 'chengyuJielong' && s.chengyuJielong.started)
151
231
  return true;
232
+ if (t !== 'dice' && s.dice.started)
233
+ return true;
234
+ if (t !== 'rps' && s.rps.started)
235
+ return true;
236
+ if (t !== 'calc24' && s.calc24.started)
237
+ return true;
238
+ if (t !== 'passwordLock' && s.passwordLock.started)
239
+ return true;
152
240
  return false;
153
241
  };
154
242
  const clearGameTimer = (state) => {
@@ -160,6 +248,10 @@ const clearAllTimers = (st) => {
160
248
  clearGameTimer(st.wzHero);
161
249
  clearGameTimer(st.chengyuImage);
162
250
  clearGameTimer(st.chengyuJielong);
251
+ clearGameTimer(st.dice);
252
+ clearGameTimer(st.rps);
253
+ clearGameTimer(st.calc24);
254
+ clearGameTimer(st.passwordLock);
163
255
  if (st.chengyuJielong.autoPlayTimer)
164
256
  clearTimeout(st.chengyuJielong.autoPlayTimer);
165
257
  };
@@ -209,8 +301,49 @@ const initState = (key, c) => {
209
301
  botTurn: true,
210
302
  autoPlayCount: 0,
211
303
  hasTriggeredAutoPlay: false,
212
- lastActiveTime: Date.now()
304
+ lastActiveTime: Date.now(),
305
+ autoPlayTimer: undefined
213
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: ['石头', '剪刀', '布']
325
+ },
326
+ calc24: {
327
+ started: false,
328
+ totalRounds: c.calc24.totalRounds,
329
+ currentRound: 0,
330
+ players: {},
331
+ participants: [],
332
+ numbers: [],
333
+ playerAnswer: ''
334
+ },
335
+ passwordLock: {
336
+ started: false,
337
+ totalRounds: 1,
338
+ currentRound: 0,
339
+ players: {},
340
+ participants: [],
341
+ password: '',
342
+ playerGuess: '',
343
+ guessTimes: 0,
344
+ maxGuessTimes: c.passwordLock.maxGuessTimes,
345
+ hints: []
346
+ }
214
347
  };
215
348
  gameStates.set(key, s);
216
349
  return s;
@@ -257,10 +390,67 @@ const setupAutoStop = (session, state, cfg, endMsg, showRank) => {
257
390
  }
258
391
  }, cfg.autoStopInactiveTime * 1000);
259
392
  };
393
+ const calculate24 = (numbers) => {
394
+ if (numbers.length === 1)
395
+ return Math.abs(numbers[0] - 24) < 0.001;
396
+ for (let i = 0; i < numbers.length; i++) {
397
+ for (let j = 0; j < numbers.length; j++) {
398
+ if (i === j)
399
+ continue;
400
+ const rest = [];
401
+ for (let k = 0; k < numbers.length; k++) {
402
+ if (k !== i && k !== j)
403
+ rest.push(numbers[k]);
404
+ }
405
+ const a = numbers[i];
406
+ const b = numbers[j];
407
+ if (calculate24([...rest, a + b]))
408
+ return true;
409
+ if (calculate24([...rest, a - b]))
410
+ return true;
411
+ if (calculate24([...rest, b - a]))
412
+ return true;
413
+ if (calculate24([...rest, a * b]))
414
+ return true;
415
+ if (b !== 0 && calculate24([...rest, a / b]))
416
+ return true;
417
+ if (a !== 0 && calculate24([...rest, b / a]))
418
+ return true;
419
+ }
420
+ }
421
+ return false;
422
+ };
423
+ const generatePasswordHint = (password, guess) => {
424
+ let correctPos = 0;
425
+ let correctNum = 0;
426
+ const passwordArr = password.split('');
427
+ const guessArr = guess.split('');
428
+ const passwordUsed = [false, false, false, false];
429
+ const guessUsed = [false, false, false, false];
430
+ for (let i = 0; i < 4; i++) {
431
+ if (passwordArr[i] === guessArr[i]) {
432
+ correctPos++;
433
+ passwordUsed[i] = true;
434
+ guessUsed[i] = true;
435
+ }
436
+ }
437
+ for (let i = 0; i < 4; i++) {
438
+ if (guessUsed[i])
439
+ continue;
440
+ for (let j = 0; j < 4; j++) {
441
+ if (!passwordUsed[j] && passwordArr[j] === guessArr[i]) {
442
+ correctNum++;
443
+ passwordUsed[j] = true;
444
+ break;
445
+ }
446
+ }
447
+ }
448
+ return `提示:${correctPos}个数字位置正确,${correctNum}个数字正确但位置错误`;
449
+ };
260
450
  function apply(ctx, cfg) {
261
451
  const d = {
262
452
  guessNumber: {
263
- usage: "用法错误!正确用法:guess start/stop 直接输入数字",
453
+ usage: "用法错误!正确用法:猜数字 开始 | 猜数字 [数字] | 猜数字 结束",
264
454
  start: "猜数字比赛开始!本次共 {0} 回合~",
265
455
  stop: "猜数字比赛已停止",
266
456
  outOfRange: "数字超出当前范围 [{0}-{1}],请重新输入!",
@@ -276,9 +466,9 @@ function apply(ctx, cfg) {
276
466
  },
277
467
  wzHero: {
278
468
  start: "王者英雄猜谜开始!本次共 {0} 回合~",
279
- startUsage: "用法错误!正确用法:wzhero start [难度] 开始游戏",
469
+ startUsage: "用法错误!正确用法:王者英雄 开始 [难度] | 王者英雄 [答案] | 王者英雄 提示 | 王者英雄 结束",
280
470
  stop: "王者英雄猜谜比赛已停止",
281
- notStarted: "王者英雄猜谜比赛尚未开始,请输入 wzhero start [难度] 开始游戏",
471
+ notStarted: "王者英雄猜谜比赛尚未开始,请输入 王者英雄 开始 [难度] 开始游戏",
282
472
  hint: "提示",
283
473
  apiError: "API请求失败,请稍后再试",
284
474
  correct: "答对啦!你获得1分~",
@@ -293,8 +483,8 @@ function apply(ctx, cfg) {
293
483
  chengyuImage: {
294
484
  start: "看图猜成语比赛开始!本次共 {0} 回合~",
295
485
  stop: "看图猜成语比赛已停止",
296
- submitUsage: "请直接输入你猜测的成语,或输入 提示 获取线索",
297
- notStarted: "看图猜成语比赛尚未开始,请输入 cyimage start 开始游戏",
486
+ submitUsage: "请直接输入 看图猜成语 [答案],或输入 看图猜成语 提示 获取线索",
487
+ notStarted: "看图猜成语比赛尚未开始,请输入 看图猜成语 开始 开始游戏",
298
488
  next: "第 {0} 题来啦!",
299
489
  hintGet: "【提示】{0}",
300
490
  hintError: "获取提示失败,请稍后再试",
@@ -311,8 +501,8 @@ function apply(ctx, cfg) {
311
501
  chengyuJielong: {
312
502
  start: "成语接龙比赛开始!本次共 {0} 回合~我先来~",
313
503
  stop: "成语接龙比赛已停止",
314
- notStarted: "成语接龙比赛尚未开始,请输入 cyjl start 开始游戏",
315
- joinUsage: "请直接发送四字成语参与接龙",
504
+ notStarted: "成语接龙比赛尚未开始,请输入 成语接龙 开始 开始游戏",
505
+ joinUsage: "请直接发送 成语接龙 [成语] 参与接龙",
316
506
  apiError: "API请求失败,请稍后再试",
317
507
  botTurn: "该我了!我接:{0}({1})\n释义:{2}",
318
508
  botWin: "哈哈我接不上了!本轮结束~",
@@ -328,6 +518,67 @@ function apply(ctx, cfg) {
328
518
  disabled: "成语接龙功能已关闭,请联系管理员开启",
329
519
  autoStop: "游戏因长时间无人操作,已自动结束"
330
520
  },
521
+ dice: {
522
+ start: "掷骰子比大小游戏开始!本次共 {0} 回合~",
523
+ stop: "掷骰子比大小游戏已停止",
524
+ notStarted: "掷骰子比大小游戏尚未开始,请输入 掷骰子 开始 开始游戏",
525
+ roll: "🎲 你掷出了 {0} 点!机器人掷出了 {1} 点!",
526
+ win: "你赢了这一回合!获得1分~",
527
+ lose: "机器人赢了这一回合!",
528
+ draw: "平局!双方都不得分~",
529
+ roundEnd: "第 {0} 回合结束!剩余回合:{1}",
530
+ gameEnd: "🎉 掷骰子比大小游戏结束!🎉",
531
+ rankTitle: "🏆 排行榜 🏆",
532
+ rankEmpty: "暂无参与记录~",
533
+ disabled: "掷骰子比大小功能已关闭,请联系管理员开启",
534
+ autoStop: "游戏因长时间无人操作,已自动结束"
535
+ },
536
+ rps: {
537
+ start: "石头剪刀布游戏开始!本次共 {0} 回合~",
538
+ stop: "石头剪刀布游戏已停止",
539
+ notStarted: "石头剪刀布游戏尚未开始,请输入 石头剪刀布 开始 开始游戏",
540
+ choice: "你选择了 {0},机器人选择了 {1}!",
541
+ win: "你赢了这一回合!获得1分~",
542
+ lose: "机器人赢了这一回合!",
543
+ draw: "平局!双方都不得分~",
544
+ invalidChoice: "无效的选择!请输入 石头、剪刀 或 布",
545
+ roundEnd: "第 {0} 回合结束!剩余回合:{1}",
546
+ gameEnd: "🎉 石头剪刀布游戏结束!🎉",
547
+ rankTitle: "🏆 排行榜 🏆",
548
+ rankEmpty: "暂无参与记录~",
549
+ disabled: "石头剪刀布功能已关闭,请联系管理员开启",
550
+ autoStop: "游戏因长时间无人操作,已自动结束"
551
+ },
552
+ calc24: {
553
+ start: "算24点游戏开始!本次共 {0} 回合~",
554
+ stop: "算24点游戏已停止",
555
+ notStarted: "算24点游戏尚未开始,请输入 算24点 开始 开始游戏",
556
+ generate: "📝 第 {0} 题:用 {1} 通过加减乘除算出24!",
557
+ correct: "答对啦!你获得1分~",
558
+ wrong: "答错啦~这组数可以算出24哦!",
559
+ impossible: "这组数无法算出24!本轮作废~",
560
+ roundEnd: "第 {0} 回合结束!剩余回合:{1}",
561
+ gameEnd: "🎉 算24点游戏结束!🎉",
562
+ rankTitle: "🏆 排行榜 🏆",
563
+ rankEmpty: "暂无参与记录~",
564
+ disabled: "算24点功能已关闭,请联系管理员开启",
565
+ autoStop: "游戏因长时间无人操作,已自动结束"
566
+ },
567
+ passwordLock: {
568
+ start: "密码锁破解游戏开始!密码为4位数字,你有 {0} 次猜测机会~",
569
+ stop: "密码锁破解游戏已停止",
570
+ notStarted: "密码锁破解游戏尚未开始,请输入 密码锁 开始 开始游戏",
571
+ guess: "你猜测的密码是:{0},这是第 {1} 次猜测",
572
+ correct: "🎉 恭喜!你猜对了密码 {0}!总共猜测了 {1} 次,获得10分~",
573
+ wrong: "密码错误!{0}",
574
+ noChance: "❌ 没有猜测机会了!正确密码是:{0}~",
575
+ invalidPassword: "无效的密码!请输入4位数字",
576
+ gameEnd: "🎉 密码锁破解游戏结束!🎉",
577
+ rankTitle: "🏆 排行榜 🏆",
578
+ rankEmpty: "暂无参与记录~",
579
+ disabled: "密码锁破解功能已关闭,请联系管理员开启",
580
+ autoStop: "游戏因长时间无人操作,已自动结束"
581
+ },
331
582
  common: {
332
583
  gameRunning: "当前已有游戏在运行中,请先结束当前游戏后再开始新游戏!",
333
584
  gameStoppedByInactive: "游戏因长时间无人操作,已自动结束",
@@ -522,7 +773,8 @@ function apply(ctx, cfg) {
522
773
  const r = await axios_1.default.get('https://jcy.lvlong.xyz/api/api/chengyu.php', {
523
774
  params: {
524
775
  action: 'get_hint',
525
- id: st.chengyuImage.currentId
776
+ id: st.chengyuImage.currentId,
777
+ level: 1
526
778
  },
527
779
  timeout: cfg.apiConfig.timeout
528
780
  });
@@ -587,7 +839,7 @@ function apply(ctx, cfg) {
587
839
  st.chengyuImage.currentId = nextDt.data.question.id;
588
840
  st.chengyuImage.currentPage = nextDt.data.question.page;
589
841
  st.chengyuImage.options = nextDt.data.question.options;
590
- st.chengyuImage.answer = nextDt.data.question.answer;
842
+ st.chengyuImage.answer = nextDt.data.question.answer || '';
591
843
  await session.send(d.chengyuImage.next.replace('{0}', st.chengyuImage.currentRound.toString()));
592
844
  await session.send(`请从选项中选择4个字组成成语\n选项:${nextDt.data.question.options.join('、')}`);
593
845
  await session.send(koishi_1.segment.image(nextDt.data.question.image_url));
@@ -605,7 +857,8 @@ function apply(ctx, cfg) {
605
857
  }
606
858
  }
607
859
  else {
608
- reply = d.chengyuImage.wrong.replace('{0}', st.chengyuImage.answer).replace('{1}', st.chengyuImage.players[playerKey].score.toString());
860
+ const correctAnswer = dt.data?.correct_answer || st.chengyuImage.answer;
861
+ reply = d.chengyuImage.wrong.replace('{0}', correctAnswer).replace('{1}', st.chengyuImage.players[playerKey].score.toString());
609
862
  await session.send(reply);
610
863
  }
611
864
  }
@@ -714,251 +967,483 @@ function apply(ctx, cfg) {
714
967
  }
715
968
  }
716
969
  else if (num < st.guessNumber.target) {
717
- await session.send(d.guessNumber.tooSmall.replace('{0}', num.toString()).replace('{1}', st.guessNumber.currentMax.toString()));
970
+ st.guessNumber.currentMin = num + 1;
971
+ await session.send(d.guessNumber.tooSmall.replace('{0}', st.guessNumber.currentMin.toString()).replace('{1}', st.guessNumber.currentMax.toString()));
718
972
  }
719
973
  else {
720
- await session.send(d.guessNumber.tooBig.replace('{0}', num.toString()).replace('{1}', st.guessNumber.currentMin.toString()));
974
+ st.guessNumber.currentMax = num - 1;
975
+ await session.send(d.guessNumber.tooBig.replace('{0}', st.guessNumber.currentMin.toString()).replace('{1}', st.guessNumber.currentMax.toString()));
721
976
  }
722
977
  setupAutoStop(session, st.guessNumber, cfg, d.guessNumber.autoStop, cfg.guessNumber.showRank);
723
978
  gameStates.set(key, st);
724
979
  return;
725
980
  }
726
- return next();
727
- });
728
- if (cfg.enableWzHero) {
729
- ctx.command('wzhero <action:string> [difficulty:string]')
730
- .action(async (argv, action, difficulty) => {
731
- const s = argv.session;
732
- if (!s)
733
- return '';
734
- const key = getSessionKey(s);
735
- const st = gameStates.get(key) || initState(key, cfg);
736
- if (action === 'start') {
737
- if (checkGameRunning(st, 'wzHero')) {
738
- s.send(d.common.gameRunning);
739
- return '';
740
- }
741
- const fd = difficulty || '中等';
742
- if (!['简单', '中等', '困难'].includes(fd)) {
743
- await s.send(d.wzHero.startUsage);
744
- return '';
745
- }
746
- st.wzHero.started = true;
747
- st.wzHero.difficulty = fd;
748
- st.wzHero.totalRounds = cfg.wzHero.totalRounds;
749
- st.wzHero.currentRound = 1;
750
- st.wzHero.players = {};
751
- st.wzHero.participants = [];
752
- gameStates.set(key, st);
753
- try {
754
- const r = await axios_1.default.get('https://api.suol.cc/v1/game_wz.php', {
755
- params: { id: getIntUserId(s), msg: `开始游戏${fd}` }, timeout: cfg.apiConfig.timeout
756
- });
757
- const dt = r.data;
758
- if (dt.status === 'success') {
759
- let t = `${dt.message}\n${dt.hint}\n剩余提示次数:${dt.remaining_hints}\n${dt.guide}`;
760
- t = t.replace(/\\n/g, '\n');
761
- t = d.wzHero.start.replace('{0}', cfg.wzHero.totalRounds.toString()) + '\n' + t;
762
- st.wzHero.currentAnswer = dt.hint || '';
763
- await s.send(t);
764
- setupAutoStop(s, st.wzHero, cfg, d.wzHero.autoStop, cfg.wzHero.showRank);
765
- }
766
- else {
767
- await s.send(dt.message || '开始失败');
768
- }
981
+ if (cfg.enableDice && st.dice.started) {
982
+ clearGameTimer(st.dice);
983
+ if (!st.dice.players[playerKey]) {
984
+ st.dice.players[playerKey] = getPlayerData(session);
985
+ st.dice.participants.push(playerKey);
986
+ }
987
+ if (content !== '掷骰子') {
988
+ setupAutoStop(session, st.dice, cfg, d.dice.autoStop, cfg.dice.showRank);
989
+ return next();
990
+ }
991
+ st.dice.playerDice = koishi_1.Random.int(1, 6);
992
+ st.dice.botDice = cfg.dice.botParticipate ? koishi_1.Random.int(1, 6) : 0;
993
+ let resultMsg = d.dice.roll.replace('{0}', st.dice.playerDice.toString()).replace('{1}', st.dice.botDice.toString());
994
+ if (cfg.dice.botParticipate) {
995
+ if (st.dice.playerDice > st.dice.botDice) {
996
+ resultMsg += '\n' + d.dice.win;
997
+ st.dice.players[playerKey].score += 1;
998
+ st.dice.players[playerKey].correctCount += 1;
769
999
  }
770
- catch (error) {
771
- await s.send(d.wzHero.apiError);
772
- st.wzHero.started = false;
1000
+ else if (st.dice.playerDice < st.dice.botDice) {
1001
+ resultMsg += '\n' + d.dice.lose;
1002
+ }
1003
+ else {
1004
+ resultMsg += '\n' + d.dice.draw;
773
1005
  }
774
1006
  }
775
- else if (action === 'stop') {
776
- st.wzHero.started = false;
777
- clearGameTimer(st.wzHero);
778
- await s.send(d.wzHero.stop);
779
- if (cfg.wzHero.showRank && !isPrivate(s)) {
780
- const rankText = generateRankText(st.wzHero.players);
781
- await s.send(rankText);
1007
+ else {
1008
+ resultMsg += '\n你掷出了 ' + st.dice.playerDice + ' 点!';
1009
+ st.dice.players[playerKey].score += 1;
1010
+ }
1011
+ await session.send(resultMsg);
1012
+ st.dice.currentRound += 1;
1013
+ if (st.dice.currentRound > st.dice.totalRounds) {
1014
+ st.dice.started = false;
1015
+ clearGameTimer(st.dice);
1016
+ await session.send(d.dice.gameEnd);
1017
+ if (cfg.dice.showRank && !isPrivate(session)) {
1018
+ const rankText = generateRankText(st.dice.players);
1019
+ await session.send(rankText);
782
1020
  }
783
- clearGameData(st.wzHero);
784
- gameStates.set(key, st);
1021
+ clearGameData(st.dice);
785
1022
  }
786
1023
  else {
787
- await s.send(d.wzHero.startUsage);
1024
+ await session.send(d.dice.roundEnd.replace('{0}', st.dice.currentRound.toString()).replace('{1}', (st.dice.totalRounds - st.dice.currentRound).toString()));
788
1025
  }
789
- return '';
790
- });
791
- }
792
- if (cfg.enableChengyuImage) {
793
- ctx.command('cyimage <action:string>')
794
- .action(async (argv, action) => {
795
- const s = argv.session;
796
- if (!s)
797
- return '';
798
- const key = getSessionKey(s);
799
- const st = gameStates.get(key) || initState(key, cfg);
800
- if (action === 'start') {
801
- if (checkGameRunning(st, 'chengyuImage')) {
802
- s.send(d.common.gameRunning);
803
- return '';
804
- }
805
- st.chengyuImage.started = true;
806
- st.chengyuImage.totalRounds = cfg.chengyuImage.totalRounds;
807
- st.chengyuImage.currentRound = 1;
808
- st.chengyuImage.players = {};
809
- st.chengyuImage.participants = [];
810
- try {
811
- const r = await axios_1.default.get('https://jcy.lvlong.xyz/api/api/chengyu.php', {
812
- params: { action: 'get_question' }, timeout: cfg.apiConfig.timeout
813
- });
814
- const dt = r.data;
815
- if (dt.success) {
816
- st.chengyuImage.currentId = dt.data.question.id;
817
- st.chengyuImage.currentPage = dt.data.question.page;
818
- st.chengyuImage.options = dt.data.question.options;
819
- st.chengyuImage.answer = dt.data.question.answer;
820
- gameStates.set(key, st);
821
- await s.send(d.chengyuImage.start.replace('{0}', cfg.chengyuImage.totalRounds.toString()));
822
- await s.send(`第 1 题来啦!\n请从选项中选择4个字组成成语\n选项:${dt.data.question.options.join('、')}`);
823
- await s.send(koishi_1.segment.image(dt.data.question.image_url));
824
- setupAutoStop(s, st.chengyuImage, cfg, d.chengyuImage.autoStop, cfg.chengyuImage.showRank);
825
- }
826
- else {
827
- await s.send('获取题目失败,请稍后再试');
828
- st.chengyuImage.started = false;
829
- }
1026
+ setupAutoStop(session, st.dice, cfg, d.dice.autoStop, cfg.dice.showRank);
1027
+ gameStates.set(key, st);
1028
+ return;
1029
+ }
1030
+ if (cfg.enableRps && st.rps.started) {
1031
+ clearGameTimer(st.rps);
1032
+ if (!st.rps.players[playerKey]) {
1033
+ st.rps.players[playerKey] = getPlayerData(session);
1034
+ st.rps.participants.push(playerKey);
1035
+ }
1036
+ if (!st.rps.choices.includes(content)) {
1037
+ await session.send(d.rps.invalidChoice);
1038
+ setupAutoStop(session, st.rps, cfg, d.rps.autoStop, cfg.rps.showRank);
1039
+ return next();
1040
+ }
1041
+ st.rps.playerChoice = content;
1042
+ st.rps.botChoice = cfg.rps.botParticipate ? st.rps.choices[koishi_1.Random.int(0, 2)] : '';
1043
+ let resultMsg = d.rps.choice.replace('{0}', st.rps.playerChoice).replace('{1}', st.rps.botChoice);
1044
+ if (cfg.rps.botParticipate) {
1045
+ if ((st.rps.playerChoice === '石头' && st.rps.botChoice === '剪刀') ||
1046
+ (st.rps.playerChoice === '剪刀' && st.rps.botChoice === '布') ||
1047
+ (st.rps.playerChoice === '布' && st.rps.botChoice === '石头')) {
1048
+ resultMsg += '\n' + d.rps.win;
1049
+ st.rps.players[playerKey].score += 1;
1050
+ st.rps.players[playerKey].correctCount += 1;
830
1051
  }
831
- catch (error) {
832
- await s.send(d.chengyuImage.apiError);
833
- st.chengyuImage.started = false;
1052
+ else if (st.rps.playerChoice === st.rps.botChoice) {
1053
+ resultMsg += '\n' + d.rps.draw;
834
1054
  }
1055
+ else {
1056
+ resultMsg += '\n' + d.rps.lose;
1057
+ }
1058
+ }
1059
+ else {
1060
+ resultMsg += '\n你选择了 ' + st.rps.playerChoice + '!';
1061
+ st.rps.players[playerKey].score += 1;
835
1062
  }
836
- else if (action === 'stop') {
837
- st.chengyuImage.started = false;
838
- clearGameTimer(st.chengyuImage);
839
- await s.send(d.chengyuImage.stop);
840
- if (cfg.chengyuImage.showRank && !isPrivate(s)) {
841
- const rankText = generateRankText(st.chengyuImage.players);
842
- await s.send(rankText);
1063
+ await session.send(resultMsg);
1064
+ st.rps.currentRound += 1;
1065
+ if (st.rps.currentRound > st.rps.totalRounds) {
1066
+ st.rps.started = false;
1067
+ clearGameTimer(st.rps);
1068
+ await session.send(d.rps.gameEnd);
1069
+ if (cfg.rps.showRank && !isPrivate(session)) {
1070
+ const rankText = generateRankText(st.rps.players);
1071
+ await session.send(rankText);
843
1072
  }
844
- clearGameData(st.chengyuImage);
845
- gameStates.set(key, st);
1073
+ clearGameData(st.rps);
846
1074
  }
847
1075
  else {
848
- await s.send(d.chengyuImage.notStarted);
1076
+ await session.send(d.rps.roundEnd.replace('{0}', st.rps.currentRound.toString()).replace('{1}', (st.rps.totalRounds - st.rps.currentRound).toString()));
849
1077
  }
850
- return '';
851
- });
852
- }
853
- if (cfg.enableChengyuJielong) {
854
- ctx.command('cyjl <action:string>')
855
- .action(async (argv, a) => {
856
- const s = argv.session;
857
- if (!s)
858
- return '';
859
- if (isPrivate(s) && !cfg.enablePrivateGame)
860
- return '';
861
- const key = getSessionKey(s);
862
- const st = gameStates.get(key) || initState(key, cfg);
863
- if (a === 'start') {
864
- if (checkGameRunning(st, 'chengyuJielong')) {
865
- s.send(d.common.gameRunning);
866
- return '';
867
- }
868
- st.chengyuJielong.started = true;
869
- st.chengyuJielong.totalRounds = cfg.chengyuJielong.totalRounds;
870
- st.chengyuJielong.currentRound = 1;
871
- st.chengyuJielong.botTurn = true;
872
- st.chengyuJielong.autoPlayCount = 0;
873
- st.chengyuJielong.hasTriggeredAutoPlay = false;
874
- st.chengyuJielong.players = {};
875
- st.chengyuJielong.participants = [];
876
- refreshActive(st);
877
- gameStates.set(key, st);
1078
+ setupAutoStop(session, st.rps, cfg, d.rps.autoStop, cfg.rps.showRank);
1079
+ gameStates.set(key, st);
1080
+ return;
1081
+ }
1082
+ if (cfg.enableCalc24 && st.calc24.started) {
1083
+ clearGameTimer(st.calc24);
1084
+ if (!st.calc24.players[playerKey]) {
1085
+ st.calc24.players[playerKey] = getPlayerData(session);
1086
+ st.calc24.participants.push(playerKey);
1087
+ }
1088
+ if (content === '换题') {
1089
+ st.calc24.numbers = [];
1090
+ for (let i = 0; i < 4; i++) {
1091
+ st.calc24.numbers.push(koishi_1.Random.int(cfg.calc24.numberRange[0], cfg.calc24.numberRange[1]));
1092
+ }
1093
+ await session.send(d.calc24.generate.replace('{0}', st.calc24.currentRound.toString()).replace('{1}', st.calc24.numbers.join('、')));
1094
+ setupAutoStop(session, st.calc24, cfg, d.calc24.autoStop, cfg.calc24.showRank);
1095
+ return next();
1096
+ }
1097
+ st.calc24.playerAnswer = content;
1098
+ const canCalculate = calculate24([...st.calc24.numbers]);
1099
+ if (!canCalculate) {
1100
+ await session.send(d.calc24.impossible);
1101
+ }
1102
+ else {
878
1103
  try {
879
- const intUserId = getIntUserId(s);
880
- const r = await axios_1.default.get('https://api.suol.cc/v1/game_cyjl.php', {
881
- params: {
882
- id: intUserId,
883
- msg: '开始成语接龙'
884
- },
885
- timeout: cfg.apiConfig.timeout,
886
- headers: {
887
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
888
- }
889
- });
890
- const dt = r.data;
891
- let m = d.chengyuJielong.start.replace('{0}', cfg.chengyuJielong.totalRounds.toString());
892
- if (dt.code === 200 && dt.data?.system) {
893
- const sys = dt.data.system;
894
- m += `\n我的第一个成语:${sys.idiom}(${sys.pinyin})\n释义:${sys.meaning}`;
895
- st.chengyuJielong.lastChar = dt.data.current_char || '';
1104
+ const result = eval(content.replace(/[^\d\+\-\*\/\(\)\.]/g, ''));
1105
+ if (Math.abs(result - 24) < 0.001) {
1106
+ await session.send(d.calc24.correct);
1107
+ st.calc24.players[playerKey].score += 1;
1108
+ st.calc24.players[playerKey].correctCount += 1;
1109
+ }
1110
+ else {
1111
+ await session.send(d.calc24.wrong);
896
1112
  }
897
- await s.send(m);
898
1113
  }
899
- catch (error) {
900
- await s.send(d.chengyuJielong.apiError);
1114
+ catch {
1115
+ await session.send(d.calc24.wrong);
901
1116
  }
902
- setupAutoStop(s, st.chengyuJielong, cfg, d.chengyuJielong.autoStop, cfg.chengyuJielong.showRank);
903
- gameStates.set(key, st);
904
- scheduleAutoPlay(s, key, st);
905
1117
  }
906
- else if (a === 'stop') {
907
- st.chengyuJielong.started = false;
908
- clearAllTimers(st);
909
- await s.send(d.chengyuJielong.stop);
910
- if (cfg.chengyuJielong.showRank && !isPrivate(s)) {
911
- const rankText = generateRankText(st.chengyuJielong.players);
912
- await s.send(rankText);
1118
+ st.calc24.currentRound += 1;
1119
+ if (st.calc24.currentRound > st.calc24.totalRounds) {
1120
+ st.calc24.started = false;
1121
+ clearGameTimer(st.calc24);
1122
+ await session.send(d.calc24.gameEnd);
1123
+ if (cfg.calc24.showRank && !isPrivate(session)) {
1124
+ const rankText = generateRankText(st.calc24.players);
1125
+ await session.send(rankText);
913
1126
  }
914
- clearGameData(st.chengyuJielong);
915
- gameStates.set(key, st);
1127
+ clearGameData(st.calc24);
916
1128
  }
917
1129
  else {
918
- await s.send(d.chengyuJielong.notStarted);
1130
+ st.calc24.numbers = [];
1131
+ for (let i = 0; i < 4; i++) {
1132
+ st.calc24.numbers.push(koishi_1.Random.int(cfg.calc24.numberRange[0], cfg.calc24.numberRange[1]));
1133
+ }
1134
+ await session.send(d.calc24.roundEnd.replace('{0}', st.calc24.currentRound.toString()).replace('{1}', (st.calc24.totalRounds - st.calc24.currentRound).toString()));
1135
+ await session.send(d.calc24.generate.replace('{0}', st.calc24.currentRound.toString()).replace('{1}', st.calc24.numbers.join('、')));
919
1136
  }
920
- return '';
921
- });
922
- }
923
- if (cfg.enableNumberGuess) {
924
- ctx.command('guess <action:string>')
925
- .action(async (argv, action) => {
926
- const s = argv.session;
927
- if (!s)
928
- return '';
929
- const key = getSessionKey(s);
930
- const st = gameStates.get(key) || initState(key, cfg);
931
- if (action === 'start') {
932
- if (checkGameRunning(st, 'guessNumber')) {
933
- s.send(d.common.gameRunning);
934
- return '';
935
- }
936
- st.guessNumber.started = true;
937
- st.guessNumber.totalRounds = cfg.guessNumber.totalRounds;
938
- st.guessNumber.currentRound = 1;
939
- st.guessNumber.target = koishi_1.Random.int(st.guessNumber.currentMin, st.guessNumber.currentMax);
940
- st.guessNumber.players = {};
941
- st.guessNumber.participants = [];
942
- gameStates.set(key, st);
943
- await s.send(d.guessNumber.start.replace('{0}', cfg.guessNumber.totalRounds.toString()));
944
- await s.send(`猜数字范围:${st.guessNumber.currentMin} - ${st.guessNumber.currentMax},开始你的猜测吧!`);
945
- setupAutoStop(s, st.guessNumber, cfg, d.guessNumber.autoStop, cfg.guessNumber.showRank);
946
- }
947
- else if (action === 'stop') {
948
- st.guessNumber.started = false;
949
- clearGameTimer(st.guessNumber);
950
- await s.send(d.guessNumber.stop);
951
- if (cfg.guessNumber.showRank && !isPrivate(s)) {
952
- const rankText = generateRankText(st.guessNumber.players);
953
- await s.send(rankText);
954
- }
955
- clearGameData(st.guessNumber);
956
- gameStates.set(key, st);
1137
+ setupAutoStop(session, st.calc24, cfg, d.calc24.autoStop, cfg.calc24.showRank);
1138
+ gameStates.set(key, st);
1139
+ return;
1140
+ }
1141
+ if (cfg.enablePasswordLock && st.passwordLock.started) {
1142
+ clearGameTimer(st.passwordLock);
1143
+ if (!st.passwordLock.players[playerKey]) {
1144
+ st.passwordLock.players[playerKey] = getPlayerData(session);
1145
+ st.passwordLock.participants.push(playerKey);
1146
+ }
1147
+ if (!/^\d{4}$/.test(content)) {
1148
+ await session.send(d.passwordLock.invalidPassword);
1149
+ setupAutoStop(session, st.passwordLock, cfg, d.passwordLock.autoStop, cfg.passwordLock.showRank);
1150
+ return next();
1151
+ }
1152
+ st.passwordLock.playerGuess = content;
1153
+ st.passwordLock.guessTimes += 1;
1154
+ await session.send(d.passwordLock.guess.replace('{0}', content).replace('{1}', st.passwordLock.guessTimes.toString()));
1155
+ if (content === st.passwordLock.password) {
1156
+ await session.send(d.passwordLock.correct.replace('{0}', content).replace('{1}', st.passwordLock.guessTimes.toString()));
1157
+ st.passwordLock.players[playerKey].score += 10 - (st.passwordLock.guessTimes - 1);
1158
+ st.passwordLock.players[playerKey].correctCount += 1;
1159
+ st.passwordLock.started = false;
1160
+ clearGameTimer(st.passwordLock);
1161
+ await session.send(d.passwordLock.gameEnd);
1162
+ if (cfg.passwordLock.showRank && !isPrivate(session)) {
1163
+ const rankText = generateRankText(st.passwordLock.players);
1164
+ await session.send(rankText);
1165
+ }
1166
+ clearGameData(st.passwordLock);
957
1167
  }
958
1168
  else {
959
- await s.send(d.guessNumber.usage);
1169
+ let hint = '';
1170
+ if (cfg.passwordLock.showHint) {
1171
+ hint = generatePasswordHint(st.passwordLock.password, content);
1172
+ }
1173
+ if (st.passwordLock.guessTimes >= st.passwordLock.maxGuessTimes) {
1174
+ await session.send(d.passwordLock.noChance.replace('{0}', st.passwordLock.password));
1175
+ st.passwordLock.started = false;
1176
+ clearGameTimer(st.passwordLock);
1177
+ await session.send(d.passwordLock.gameEnd);
1178
+ if (cfg.passwordLock.showRank && !isPrivate(session)) {
1179
+ const rankText = generateRankText(st.passwordLock.players);
1180
+ await session.send(rankText);
1181
+ }
1182
+ clearGameData(st.passwordLock);
1183
+ }
1184
+ else {
1185
+ await session.send(d.passwordLock.wrong.replace('{0}', hint));
1186
+ await session.send(`剩余猜测次数:${st.passwordLock.maxGuessTimes - st.passwordLock.guessTimes}`);
1187
+ }
960
1188
  }
961
- return '';
962
- });
963
- }
1189
+ setupAutoStop(session, st.passwordLock, cfg, d.passwordLock.autoStop, cfg.passwordLock.showRank);
1190
+ gameStates.set(key, st);
1191
+ return;
1192
+ }
1193
+ return next();
1194
+ });
1195
+ ctx.command('猜数字 <action> [param]', '猜数字游戏')
1196
+ .action(async (argv, action, param) => {
1197
+ const session = argv.session;
1198
+ if (!session)
1199
+ return;
1200
+ const key = getSessionKey(session);
1201
+ const st = gameStates.get(key) || initState(key, cfg);
1202
+ if (checkGameRunning(st)) {
1203
+ await session.send(d.common.gameRunning);
1204
+ return;
1205
+ }
1206
+ if (action === '开始') {
1207
+ st.guessNumber.started = true;
1208
+ st.guessNumber.target = koishi_1.Random.int(cfg.guessNumber.min, cfg.guessNumber.max);
1209
+ st.guessNumber.currentMin = cfg.guessNumber.min;
1210
+ st.guessNumber.currentMax = cfg.guessNumber.max;
1211
+ st.guessNumber.currentRound = 1;
1212
+ await session.send(d.guessNumber.start.replace('{0}', st.guessNumber.totalRounds.toString()));
1213
+ await session.send(`猜数字范围:${st.guessNumber.currentMin} - ${st.guessNumber.currentMax}`);
1214
+ gameStates.set(key, st);
1215
+ setupAutoStop(session, st.guessNumber, cfg, d.guessNumber.autoStop, cfg.guessNumber.showRank);
1216
+ }
1217
+ else if (action === '结束') {
1218
+ clearGameData(st.guessNumber);
1219
+ await session.send(d.guessNumber.stop);
1220
+ gameStates.set(key, st);
1221
+ }
1222
+ else {
1223
+ await session.send(d.guessNumber.usage);
1224
+ }
1225
+ });
1226
+ ctx.command('王者英雄 <action> [param]', '王者英雄猜谜')
1227
+ .action(async (argv, action, param) => {
1228
+ const session = argv.session;
1229
+ if (!session)
1230
+ return;
1231
+ const key = getSessionKey(session);
1232
+ const st = gameStates.get(key) || initState(key, cfg);
1233
+ if (checkGameRunning(st)) {
1234
+ await session.send(d.common.gameRunning);
1235
+ return;
1236
+ }
1237
+ if (action === '开始') {
1238
+ st.wzHero.started = true;
1239
+ st.wzHero.difficulty = param || '简单';
1240
+ st.wzHero.currentRound = 1;
1241
+ try {
1242
+ const r = await axios_1.default.get('https://api.suol.cc/v1/game_wz.php', {
1243
+ params: { id: getIntUserId(session), msg: `开始游戏${st.wzHero.difficulty}` },
1244
+ timeout: cfg.apiConfig.timeout
1245
+ });
1246
+ const dt = r.data;
1247
+ let text = `${dt.message || ''}\n${dt.hint || ''}\n剩余提示次数:${dt.remaining_hints}\n${dt.guide || ''}`;
1248
+ text = text.replace(/\\n/g, '\n');
1249
+ await session.send(d.wzHero.start.replace('{0}', st.wzHero.totalRounds.toString()));
1250
+ await session.send(text);
1251
+ st.wzHero.currentAnswer = dt.hint || '';
1252
+ }
1253
+ catch (e) {
1254
+ await session.send(d.wzHero.apiError);
1255
+ }
1256
+ gameStates.set(key, st);
1257
+ setupAutoStop(session, st.wzHero, cfg, d.wzHero.autoStop, cfg.wzHero.showRank);
1258
+ }
1259
+ else if (action === '结束') {
1260
+ clearGameData(st.wzHero);
1261
+ await session.send(d.wzHero.stop);
1262
+ gameStates.set(key, st);
1263
+ }
1264
+ else {
1265
+ await session.send(d.wzHero.startUsage);
1266
+ }
1267
+ });
1268
+ ctx.command('看图猜成语 <action>', '看图猜成语')
1269
+ .action(async (argv, action) => {
1270
+ const session = argv.session;
1271
+ if (!session)
1272
+ return;
1273
+ const key = getSessionKey(session);
1274
+ const st = gameStates.get(key) || initState(key, cfg);
1275
+ if (checkGameRunning(st)) {
1276
+ await session.send(d.common.gameRunning);
1277
+ return;
1278
+ }
1279
+ if (action === '开始') {
1280
+ st.chengyuImage.started = true;
1281
+ st.chengyuImage.currentRound = 1;
1282
+ try {
1283
+ const r = await axios_1.default.get('https://jcy.lvlong.xyz/api/api/chengyu.php', {
1284
+ params: { action: 'next_question', page: 1 },
1285
+ timeout: cfg.apiConfig.timeout
1286
+ });
1287
+ const dt = r.data;
1288
+ if (dt.success) {
1289
+ st.chengyuImage.currentId = dt.data.question.id;
1290
+ st.chengyuImage.currentPage = dt.data.question.page;
1291
+ st.chengyuImage.options = dt.data.question.options;
1292
+ st.chengyuImage.answer = dt.data.question.answer || '';
1293
+ await session.send(d.chengyuImage.start.replace('{0}', st.chengyuImage.totalRounds.toString()));
1294
+ await session.send(`请从选项中选择4个字组成成语\n选项:${dt.data.question.options.join('、')}`);
1295
+ await session.send(koishi_1.segment.image(dt.data.question.image_url));
1296
+ }
1297
+ else {
1298
+ await session.send(d.chengyuImage.apiError);
1299
+ }
1300
+ }
1301
+ catch (e) {
1302
+ await session.send(d.chengyuImage.apiError);
1303
+ }
1304
+ gameStates.set(key, st);
1305
+ setupAutoStop(session, st.chengyuImage, cfg, d.chengyuImage.autoStop, cfg.chengyuImage.showRank);
1306
+ }
1307
+ else if (action === '结束') {
1308
+ clearGameData(st.chengyuImage);
1309
+ await session.send(d.chengyuImage.stop);
1310
+ gameStates.set(key, st);
1311
+ }
1312
+ else {
1313
+ await session.send(d.chengyuImage.submitUsage);
1314
+ }
1315
+ });
1316
+ ctx.command('成语接龙 <action>', '成语接龙')
1317
+ .action(async (argv, action) => {
1318
+ const session = argv.session;
1319
+ if (!session)
1320
+ return;
1321
+ const key = getSessionKey(session);
1322
+ const st = gameStates.get(key) || initState(key, cfg);
1323
+ if (checkGameRunning(st)) {
1324
+ await session.send(d.common.gameRunning);
1325
+ return;
1326
+ }
1327
+ if (action === '开始') {
1328
+ st.chengyuJielong.started = true;
1329
+ st.chengyuJielong.currentRound = 1;
1330
+ st.chengyuJielong.hasTriggeredAutoPlay = false;
1331
+ st.chengyuJielong.autoPlayCount = 0;
1332
+ await session.send(d.chengyuJielong.start.replace('{0}', st.chengyuJielong.totalRounds.toString()));
1333
+ gameStates.set(key, st);
1334
+ scheduleAutoPlay(session, key, st);
1335
+ setupAutoStop(session, st.chengyuJielong, cfg, d.chengyuJielong.autoStop, cfg.chengyuJielong.showRank);
1336
+ }
1337
+ else if (action === '结束') {
1338
+ clearGameData(st.chengyuJielong);
1339
+ await session.send(d.chengyuJielong.stop);
1340
+ gameStates.set(key, st);
1341
+ }
1342
+ else {
1343
+ await session.send(d.chengyuJielong.joinUsage);
1344
+ }
1345
+ });
1346
+ ctx.command('掷骰子 <action>', '掷骰子比大小')
1347
+ .action(async (argv, action) => {
1348
+ const session = argv.session;
1349
+ if (!session)
1350
+ return;
1351
+ const key = getSessionKey(session);
1352
+ const st = gameStates.get(key) || initState(key, cfg);
1353
+ if (checkGameRunning(st)) {
1354
+ await session.send(d.common.gameRunning);
1355
+ return;
1356
+ }
1357
+ if (action === '开始') {
1358
+ st.dice.started = true;
1359
+ st.dice.currentRound = 1;
1360
+ await session.send(d.dice.start.replace('{0}', st.dice.totalRounds.toString()));
1361
+ gameStates.set(key, st);
1362
+ setupAutoStop(session, st.dice, cfg, d.dice.autoStop, cfg.dice.showRank);
1363
+ }
1364
+ else if (action === '结束') {
1365
+ clearGameData(st.dice);
1366
+ await session.send(d.dice.stop);
1367
+ gameStates.set(key, st);
1368
+ }
1369
+ });
1370
+ ctx.command('石头剪刀布 <action>', '石头剪刀布')
1371
+ .action(async (argv, action) => {
1372
+ const session = argv.session;
1373
+ if (!session)
1374
+ return;
1375
+ const key = getSessionKey(session);
1376
+ const st = gameStates.get(key) || initState(key, cfg);
1377
+ if (checkGameRunning(st)) {
1378
+ await session.send(d.common.gameRunning);
1379
+ return;
1380
+ }
1381
+ if (action === '开始') {
1382
+ st.rps.started = true;
1383
+ st.rps.currentRound = 1;
1384
+ await session.send(d.rps.start.replace('{0}', st.rps.totalRounds.toString()));
1385
+ gameStates.set(key, st);
1386
+ setupAutoStop(session, st.rps, cfg, d.rps.autoStop, cfg.rps.showRank);
1387
+ }
1388
+ else if (action === '结束') {
1389
+ clearGameData(st.rps);
1390
+ await session.send(d.rps.stop);
1391
+ gameStates.set(key, st);
1392
+ }
1393
+ });
1394
+ ctx.command('算24点 <action>', '算24点游戏')
1395
+ .action(async (argv, action) => {
1396
+ const session = argv.session;
1397
+ if (!session)
1398
+ return;
1399
+ const key = getSessionKey(session);
1400
+ const st = gameStates.get(key) || initState(key, cfg);
1401
+ if (checkGameRunning(st)) {
1402
+ await session.send(d.common.gameRunning);
1403
+ return;
1404
+ }
1405
+ if (action === '开始') {
1406
+ st.calc24.started = true;
1407
+ st.calc24.currentRound = 1;
1408
+ st.calc24.numbers = [];
1409
+ for (let i = 0; i < 4; i++) {
1410
+ st.calc24.numbers.push(koishi_1.Random.int(cfg.calc24.numberRange[0], cfg.calc24.numberRange[1]));
1411
+ }
1412
+ await session.send(d.calc24.start.replace('{0}', st.calc24.totalRounds.toString()));
1413
+ await session.send(d.calc24.generate.replace('{0}', st.calc24.currentRound.toString()).replace('{1}', st.calc24.numbers.join('、')));
1414
+ gameStates.set(key, st);
1415
+ setupAutoStop(session, st.calc24, cfg, d.calc24.autoStop, cfg.calc24.showRank);
1416
+ }
1417
+ else if (action === '结束') {
1418
+ clearGameData(st.calc24);
1419
+ await session.send(d.calc24.stop);
1420
+ gameStates.set(key, st);
1421
+ }
1422
+ });
1423
+ ctx.command('密码锁 <action>', '密码锁破解')
1424
+ .action(async (argv, action) => {
1425
+ const session = argv.session;
1426
+ if (!session)
1427
+ return;
1428
+ const key = getSessionKey(session);
1429
+ const st = gameStates.get(key) || initState(key, cfg);
1430
+ if (checkGameRunning(st)) {
1431
+ await session.send(d.common.gameRunning);
1432
+ return;
1433
+ }
1434
+ if (action === '开始') {
1435
+ st.passwordLock.started = true;
1436
+ st.passwordLock.currentRound = 1;
1437
+ st.passwordLock.guessTimes = 0;
1438
+ st.passwordLock.password = koishi_1.Random.int(1000, 9999).toString();
1439
+ await session.send(d.passwordLock.start.replace('{0}', st.passwordLock.maxGuessTimes.toString()));
1440
+ gameStates.set(key, st);
1441
+ setupAutoStop(session, st.passwordLock, cfg, d.passwordLock.autoStop, cfg.passwordLock.showRank);
1442
+ }
1443
+ else if (action === '结束') {
1444
+ clearGameData(st.passwordLock);
1445
+ await session.send(d.passwordLock.stop);
1446
+ gameStates.set(key, st);
1447
+ }
1448
+ });
964
1449
  }