koishi-plugin-game-mini 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.ts CHANGED
@@ -45,6 +45,9 @@ export interface Config {
45
45
  showTotalStats: boolean;
46
46
  };
47
47
  };
48
+ debug: {
49
+ enableLog: boolean;
50
+ };
48
51
  guessNumber: {
49
52
  min: number;
50
53
  max: number;
@@ -82,7 +85,6 @@ export interface Config {
82
85
  messages: {
83
86
  usage: string;
84
87
  start: string;
85
- startUsage: string;
86
88
  stop: string;
87
89
  notStarted: string;
88
90
  hint: string;
@@ -107,7 +109,6 @@ export interface Config {
107
109
  usage: string;
108
110
  start: string;
109
111
  stop: string;
110
- submitUsage: string;
111
112
  notStarted: string;
112
113
  next: string;
113
114
  hintGet: string;
@@ -136,7 +137,6 @@ export interface Config {
136
137
  start: string;
137
138
  stop: string;
138
139
  notStarted: string;
139
- joinUsage: string;
140
140
  apiError: string;
141
141
  botTurn: string;
142
142
  botWin: string;
package/lib/index.js CHANGED
@@ -32,7 +32,6 @@ const defaultMessages = {
32
32
  wzHero: {
33
33
  usage: "用法错误!正确用法:猜王者英雄 开始 | [答案] | 提示 | 结束",
34
34
  start: "猜王者英雄开始!本次共 {0} 回合~当前难度:{1}",
35
- startUsage: "用法错误!正确用法:猜王者英雄 开始 | [答案] | 提示 | 结束",
36
35
  stop: "猜王者英雄比赛已停止",
37
36
  notStarted: "猜王者英雄比赛尚未开始,请输入 猜王者英雄 开始 开始游戏",
38
37
  hint: "提示",
@@ -50,7 +49,6 @@ const defaultMessages = {
50
49
  usage: "用法错误!正确用法:看图猜成语 开始 | [答案] | 提示 | 结束",
51
50
  start: "看图猜成语比赛开始!本次共 {0} 回合~当前提示级别:{1}",
52
51
  stop: "看图猜成语比赛已停止",
53
- submitUsage: "用法错误!正确用法:看图猜成语 开始 | [答案] | 提示 | 结束",
54
52
  notStarted: "看图猜成语比赛尚未开始,请输入 看图猜成语 开始 开始游戏",
55
53
  next: "第 {0} 题来啦!",
56
54
  hintGet: "【提示】{0}",
@@ -70,7 +68,6 @@ const defaultMessages = {
70
68
  start: "成语接龙比赛开始!本次共 {0} 回合~我先来~",
71
69
  stop: "成语接龙比赛已停止",
72
70
  notStarted: "成语接龙比赛尚未开始,请输入 成语接龙 开始 开始游戏",
73
- joinUsage: "用法错误!正确用法:成语接龙 开始 | [成语] | 结束",
74
71
  apiError: "API请求失败,请稍后再试",
75
72
  botTurn: "该我了!我接:{0}",
76
73
  botWin: "哈哈我接不上了!本轮结束~",
@@ -148,6 +145,11 @@ exports.Config = koishi_1.Schema.intersect([
148
145
  }).description('📊 排行榜消息配置'),
149
146
  }).description('📊 排行榜配置'),
150
147
  }),
148
+ koishi_1.Schema.object({
149
+ debug: koishi_1.Schema.object({
150
+ enableLog: koishi_1.Schema.boolean().default(false).description('📝 启用调试日志输出'),
151
+ }).description('🔧 调试配置'),
152
+ }),
151
153
  koishi_1.Schema.object({
152
154
  guessNumber: koishi_1.Schema.object({
153
155
  min: koishi_1.Schema.number().min(0).default(0).description('最小值'),
@@ -188,7 +190,6 @@ exports.Config = koishi_1.Schema.intersect([
188
190
  messages: koishi_1.Schema.object({
189
191
  usage: koishi_1.Schema.string().default(defaultMessages.wzHero.usage).description('用法错误提示'),
190
192
  start: koishi_1.Schema.string().default(defaultMessages.wzHero.start).description('游戏开始提示\n{0}-总回合数, {1}-难度'),
191
- startUsage: koishi_1.Schema.string().default(defaultMessages.wzHero.startUsage).description('开始用法提示'),
192
193
  stop: koishi_1.Schema.string().default(defaultMessages.wzHero.stop).description('游戏停止提示'),
193
194
  notStarted: koishi_1.Schema.string().default(defaultMessages.wzHero.notStarted).description('游戏未开始提示'),
194
195
  hint: koishi_1.Schema.string().default(defaultMessages.wzHero.hint).description('提示命令'),
@@ -215,7 +216,6 @@ exports.Config = koishi_1.Schema.intersect([
215
216
  usage: koishi_1.Schema.string().default(defaultMessages.chengyuImage.usage).description('用法错误提示'),
216
217
  start: koishi_1.Schema.string().default(defaultMessages.chengyuImage.start).description('游戏开始提示\n{0}-总回合数, {1}-提示级别'),
217
218
  stop: koishi_1.Schema.string().default(defaultMessages.chengyuImage.stop).description('游戏停止提示'),
218
- submitUsage: koishi_1.Schema.string().default(defaultMessages.chengyuImage.submitUsage).description('提交答案用法提示'),
219
219
  notStarted: koishi_1.Schema.string().default(defaultMessages.chengyuImage.notStarted).description('游戏未开始提示'),
220
220
  next: koishi_1.Schema.string().default(defaultMessages.chengyuImage.next).description('下一题提示\n{0}-当前回合'),
221
221
  hintGet: koishi_1.Schema.string().default(defaultMessages.chengyuImage.hintGet).description('获取提示成功\n{0}-提示内容'),
@@ -246,7 +246,6 @@ exports.Config = koishi_1.Schema.intersect([
246
246
  start: koishi_1.Schema.string().default(defaultMessages.chengyuJielong.start).description('游戏开始提示\n{0}-总回合数'),
247
247
  stop: koishi_1.Schema.string().default(defaultMessages.chengyuJielong.stop).description('游戏停止提示'),
248
248
  notStarted: koishi_1.Schema.string().default(defaultMessages.chengyuJielong.notStarted).description('游戏未开始提示'),
249
- joinUsage: koishi_1.Schema.string().default(defaultMessages.chengyuJielong.joinUsage).description('参与用法提示'),
250
249
  apiError: koishi_1.Schema.string().default(defaultMessages.chengyuJielong.apiError).description('API错误提示'),
251
250
  botTurn: koishi_1.Schema.string().default(defaultMessages.chengyuJielong.botTurn).description('机器人回合提示\n{0}-成语'),
252
251
  botWin: koishi_1.Schema.string().default(defaultMessages.chengyuJielong.botWin).description('机器人赢提示'),
@@ -318,11 +317,6 @@ exports.Config = koishi_1.Schema.intersect([
318
317
  const logger = new koishi_1.Logger('game-mini');
319
318
  const gameStates = new Map();
320
319
  const getSessionKey = (s) => s.channelId ? `g:${s.channelId}` : `p:${s.userId}`;
321
- const getIntUserId = (session) => {
322
- const userIdStr = session.userId || '0';
323
- const hash = userIdStr.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0);
324
- return hash || 1000000;
325
- };
326
320
  async function apply(ctx, cfg) {
327
321
  ctx.model.extend('game_mini_player', {
328
322
  id: 'unsigned',
@@ -372,6 +366,35 @@ async function apply(ctx, cfg) {
372
366
  return cfg.privateGame.enableCalc24;
373
367
  return false;
374
368
  };
369
+ const getUserId = (session) => {
370
+ return session.userId || '0';
371
+ };
372
+ const logDebug = (message, data) => {
373
+ if (cfg.debug.enableLog) {
374
+ if (data) {
375
+ logger.info(`${message} ${JSON.stringify(data)}`);
376
+ }
377
+ else {
378
+ logger.info(message);
379
+ }
380
+ }
381
+ };
382
+ const logError = (message, error) => {
383
+ logger.error(message);
384
+ if (cfg.debug.enableLog && error) {
385
+ logger.error(JSON.stringify(error));
386
+ }
387
+ };
388
+ const logWarn = (message, data) => {
389
+ if (cfg.debug.enableLog) {
390
+ if (data) {
391
+ logger.warn(`${message} ${JSON.stringify(data)}`);
392
+ }
393
+ else {
394
+ logger.warn(message);
395
+ }
396
+ }
397
+ };
375
398
  const getPlayerData = async (session) => {
376
399
  if (!session.channelId) {
377
400
  return {
@@ -678,19 +701,26 @@ async function apply(ctx, cfg) {
678
701
  if (!st.chengyuJielong.started)
679
702
  return;
680
703
  try {
681
- const intUserId = getIntUserId(session);
682
- logger.info(`[成语接龙] 开始调用API,用户ID: ${intUserId}`);
704
+ const userId = getUserId(session);
705
+ logDebug(`[成语接龙] 开始调用API,平台: ${session.platform}, 用户ID: ${userId}`);
706
+ const params = {
707
+ id: userId,
708
+ };
709
+ if (st.chengyuJielong.jielongCount === 0) {
710
+ params.msg = '开始游戏';
711
+ }
712
+ else {
713
+ params.msg = '我接';
714
+ }
683
715
  const r = await axios_1.default.get('https://api.suol.cc/v1/game_cyjl.php', {
684
- params: {
685
- id: intUserId,
686
- msg: '我接'
687
- },
716
+ params: params,
688
717
  timeout: cfg.apiConfig.timeout,
689
718
  headers: {
690
719
  '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'
691
720
  }
692
721
  });
693
- logger.info(`[成语接龙] API返回状态码: ${r.status}`);
722
+ logDebug(`[成语接龙] API返回状态码: ${r.status}`);
723
+ logDebug(`[成语接龙] API返回数据:`, r.data);
694
724
  const dt = r.data;
695
725
  let m = '';
696
726
  if (dt.code === 200 && dt.data?.system) {
@@ -699,47 +729,19 @@ async function apply(ctx, cfg) {
699
729
  st.chengyuJielong.lastChar = dt.data.current_char || '';
700
730
  st.chengyuJielong.jielongCount += 1;
701
731
  st.chengyuJielong.botTurn = false;
702
- logger.info(`[成语接龙] 成功获取成语: ${sys.idiom}`);
732
+ logDebug(`[成语接龙] 成功获取成语: ${sys.idiom}`);
703
733
  await session.send(m);
734
+ await session.send('请输入要接的成语');
704
735
  }
705
736
  else {
706
- logger.warn(`[成语接龙] API返回异常: code=${dt.code}, msg=${dt.msg}`);
737
+ logWarn(`[成语接龙] API返回异常: code=${dt.code}, msg=${dt.msg}`);
707
738
  m = dt.msg || d.chengyuJielong.botWin;
708
- st.chengyuJielong.currentRound += 1;
709
- st.chengyuJielong.botTurn = true;
710
739
  await session.send(m);
711
- if (st.chengyuJielong.currentRound > st.chengyuJielong.totalRounds) {
712
- st.chengyuJielong.started = false;
713
- clearAllTimers(st);
714
- await session.send(d.chengyuJielong.gameEnd);
715
- if (cfg.chengyuJielong.showRank && !isPrivate(session)) {
716
- const rankText = generateGameRankText(st.chengyuJielong.players, d.chengyuJielong.rankTitle, d.chengyuJielong.rankEmpty);
717
- await session.send(rankText);
718
- }
719
- clearGameData(st.chengyuJielong);
720
- gameStates.set(key, st);
721
- return;
722
- }
723
- else {
724
- await session.send(d.chengyuJielong.roundEnd.replace('{0}', st.chengyuJielong.currentRound.toString()).replace('{1}', (st.chengyuJielong.totalRounds - st.chengyuJielong.currentRound).toString()));
725
- }
726
- }
727
- if (cfg.chengyuJielong.maxRounds > 0 && st.chengyuJielong.jielongCount >= cfg.chengyuJielong.maxRounds) {
728
- st.chengyuJielong.started = false;
729
- clearAllTimers(st);
730
- await session.send(d.chengyuJielong.gameEnd);
731
- if (cfg.chengyuJielong.showRank && !isPrivate(session)) {
732
- const rankText = generateGameRankText(st.chengyuJielong.players, d.chengyuJielong.rankTitle, d.chengyuJielong.rankEmpty);
733
- await session.send(rankText);
734
- }
735
- clearGameData(st.chengyuJielong);
736
- gameStates.set(key, st);
737
- return;
738
740
  }
739
741
  }
740
742
  catch (error) {
741
743
  const err = error;
742
- logger.error(`[成语接龙] API调用失败: ${err.message}`);
744
+ logError(`[成语接龙] API调用失败: ${err.message}`, err);
743
745
  await session.send(d.chengyuJielong.apiError);
744
746
  }
745
747
  gameStates.set(key, st);
@@ -787,11 +789,11 @@ async function apply(ctx, cfg) {
787
789
  return;
788
790
  }
789
791
  try {
790
- const intUserId = getIntUserId(session);
791
- logger.info(`[成语接龙玩家] 开始调用API,用户ID: ${intUserId}, 内容: ${content}`);
792
+ const userId = getUserId(session);
793
+ logDebug(`[成语接龙玩家] 开始调用API,平台: ${session.platform}, 用户ID: ${userId}, 内容: ${content}`);
792
794
  const r = await axios_1.default.get('https://api.suol.cc/v1/game_cyjl.php', {
793
795
  params: {
794
- id: intUserId,
796
+ id: userId,
795
797
  msg: `我接${content}`
796
798
  },
797
799
  timeout: cfg.apiConfig.timeout,
@@ -799,7 +801,8 @@ async function apply(ctx, cfg) {
799
801
  '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'
800
802
  }
801
803
  });
802
- logger.info(`[成语接龙玩家] API返回状态码: ${r.status}`);
804
+ logDebug(`[成语接龙玩家] API返回状态码: ${r.status}`);
805
+ logDebug(`[成语接龙玩家] API返回数据:`, r.data);
803
806
  const dt = r.data;
804
807
  let m = '';
805
808
  if (dt.code === 200) {
@@ -808,20 +811,25 @@ async function apply(ctx, cfg) {
808
811
  m += d.chengyuJielong.correct + '\n';
809
812
  m += `你的成语:${dt.data.user.idiom}\n`;
810
813
  st.chengyuJielong.botTurn = true;
811
- logger.info(`[成语接龙玩家] 接龙成功: ${dt.data.user.idiom}`);
814
+ st.chengyuJielong.currentRound += 1;
815
+ logDebug(`[成语接龙玩家] 接龙成功: ${dt.data.user.idiom}`);
812
816
  }
813
817
  else {
814
818
  m += d.chengyuJielong.wrong + '\n';
815
- logger.info(`[成语接龙玩家] 接龙失败`);
819
+ logDebug(`[成语接龙玩家] 接龙失败`);
816
820
  }
817
821
  if (dt.data?.system) {
818
822
  m += `我的接龙:${dt.data.system.idiom}`;
819
823
  st.chengyuJielong.lastChar = dt.data.current_char || '';
820
824
  st.chengyuJielong.jielongCount += 1;
821
- logger.info(`[成语接龙玩家] 机器人接龙: ${dt.data.system.idiom}`);
825
+ st.chengyuJielong.botTurn = false;
826
+ logDebug(`[成语接龙玩家] 机器人接龙: ${dt.data.system.idiom}`);
827
+ await session.send(m);
828
+ await session.send('请输入要接的成语');
829
+ }
830
+ else {
831
+ await session.send(m);
822
832
  }
823
- st.chengyuJielong.currentRound += 1;
824
- await session.send(m);
825
833
  if (cfg.chengyuJielong.botParticipate && st.chengyuJielong.botTurn) {
826
834
  setTimeout(() => {
827
835
  doAutoPlay(session, key, st);
@@ -829,7 +837,7 @@ async function apply(ctx, cfg) {
829
837
  }
830
838
  }
831
839
  else {
832
- logger.warn(`[成语接龙玩家] API返回异常: code=${dt.code}, msg=${dt.msg}`);
840
+ logWarn(`[成语接龙玩家] API返回异常: code=${dt.code}, msg=${dt.msg}`);
833
841
  m = dt.msg || '接龙失败';
834
842
  m += '\n' + d.chengyuJielong.wrong;
835
843
  await session.send(m);
@@ -837,7 +845,7 @@ async function apply(ctx, cfg) {
837
845
  }
838
846
  catch (error) {
839
847
  const err = error;
840
- logger.error(`[成语接龙玩家] API调用失败: ${err.message}`);
848
+ logError(`[成语接龙玩家] API调用失败: ${err.message}`, err);
841
849
  await session.send(d.chengyuJielong.apiError);
842
850
  }
843
851
  setupAutoStop(session, st.chengyuJielong, 'chengyuJielong', d.chengyuJielong.autoStop, cfg.chengyuJielong.showRank, d.chengyuJielong.rankTitle, d.chengyuJielong.rankEmpty);
@@ -975,7 +983,7 @@ async function apply(ctx, cfg) {
975
983
  }
976
984
  try {
977
985
  const r = await axios_1.default.get('https://api.suol.cc/v1/game_wz.php', {
978
- params: { id: getIntUserId(session), msg: content }, timeout: cfg.apiConfig.timeout
986
+ params: { id: getUserId(session), msg: content }, timeout: cfg.apiConfig.timeout
979
987
  });
980
988
  const dt = r.data;
981
989
  if (dt.status === 'success') {
@@ -1003,7 +1011,7 @@ async function apply(ctx, cfg) {
1003
1011
  else {
1004
1012
  text += '\n' + d.wzHero.roundEnd.replace('{0}', st.wzHero.currentRound.toString()).replace('{1}', (st.wzHero.totalRounds - st.wzHero.currentRound).toString());
1005
1013
  const nextR = await axios_1.default.get('https://api.suol.cc/v1/game_wz.php', {
1006
- params: { id: getIntUserId(session), msg: `开始游戏${st.wzHero.difficulty}` }, timeout: cfg.apiConfig.timeout
1014
+ params: { id: getUserId(session), msg: `开始游戏${st.wzHero.difficulty}` }, timeout: cfg.apiConfig.timeout
1007
1015
  });
1008
1016
  const nextDt = nextR.data;
1009
1017
  if (nextDt.status === 'success') {
@@ -1223,7 +1231,7 @@ async function apply(ctx, cfg) {
1223
1231
  st.wzHero.currentRound = 1;
1224
1232
  try {
1225
1233
  const r = await axios_1.default.get('https://api.suol.cc/v1/game_wz.php', {
1226
- params: { id: getIntUserId(session), msg: `开始游戏${st.wzHero.difficulty}` },
1234
+ params: { id: getUserId(session), msg: `开始游戏${st.wzHero.difficulty}` },
1227
1235
  timeout: cfg.apiConfig.timeout
1228
1236
  });
1229
1237
  const dt = r.data;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koishi-plugin-game-mini",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Koishi多功能小游戏合集:猜数字、猜王者英雄、看图猜成语、成语接龙、算24点",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
package/readme.md CHANGED
@@ -86,6 +86,8 @@ This is a lightweight, multi-functional mini-game plugin developed for the Koish
86
86
  | `rank.maxDisplay` | 排行榜最多显示人数 | 10 |
87
87
  | `rank.clearDataPermission` | 清零数据所需权限等级 | 5 |
88
88
  | `rank.messages.showTotalStats` | 是否显示总统计数据 | true |
89
+ | **🔧 调试配置** | | |
90
+ | `debug.enableLog` | 启用调试日志输出 | false |
89
91
  | **🎲 猜数字游戏配置** | | |
90
92
  | `guessNumber.min` | 最小值 | 0 |
91
93
  | `guessNumber.max` | 最大值 | 100 |
@@ -154,6 +156,8 @@ This is a lightweight, multi-functional mini-game plugin developed for the Koish
154
156
  | `rank.maxDisplay` | Maximum display count in rank | 10 |
155
157
  | `rank.clearDataPermission` | Authority level required to clear data | 5 |
156
158
  | `rank.messages.showTotalStats` | Whether to show total statistics | true |
159
+ | **🔧 Debug Configuration** | | |
160
+ | `debug.enableLog` | Enable debug log output | false |
157
161
  | **🎲 Number Guessing Configuration** | | |
158
162
  | `guessNumber.min` | Minimum value | 0 |
159
163
  | `guessNumber.max` | Maximum value | 100 |