koishi-plugin-game-mini 0.2.9 → 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 {
@@ -674,37 +697,30 @@ async function apply(ctx, cfg) {
674
697
  const refreshActive = (st) => {
675
698
  st.chengyuJielong.lastActiveTime = Date.now();
676
699
  };
677
- const scheduleAutoPlay = (session, key, st) => {
678
- clearAllTimers(st);
679
- if (st.chengyuJielong.currentRound === 1 && st.chengyuJielong.jielongCount === 0) {
680
- const delay = 100;
681
- st.chengyuJielong.autoPlayTimer = setTimeout(() => {
682
- doAutoPlay(session, key, st);
683
- }, delay);
684
- return;
685
- }
686
- if (cfg.chengyuJielong.botParticipate && st.chengyuJielong.botTurn) {
687
- const delay = cfg.chengyuJielong.autoPlayDelay * 1000;
688
- st.chengyuJielong.autoPlayTimer = setTimeout(() => {
689
- doAutoPlay(session, key, st);
690
- }, delay);
691
- }
692
- };
693
700
  const doAutoPlay = async (session, key, st) => {
694
701
  if (!st.chengyuJielong.started)
695
702
  return;
696
703
  try {
697
- const intUserId = getIntUserId(session);
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
+ }
698
715
  const r = await axios_1.default.get('https://api.suol.cc/v1/game_cyjl.php', {
699
- params: {
700
- id: intUserId,
701
- msg: '我接'
702
- },
716
+ params: params,
703
717
  timeout: cfg.apiConfig.timeout,
704
718
  headers: {
705
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'
706
720
  }
707
721
  });
722
+ logDebug(`[成语接龙] API返回状态码: ${r.status}`);
723
+ logDebug(`[成语接龙] API返回数据:`, r.data);
708
724
  const dt = r.data;
709
725
  let m = '';
710
726
  if (dt.code === 200 && dt.data?.system) {
@@ -713,43 +729,19 @@ async function apply(ctx, cfg) {
713
729
  st.chengyuJielong.lastChar = dt.data.current_char || '';
714
730
  st.chengyuJielong.jielongCount += 1;
715
731
  st.chengyuJielong.botTurn = false;
732
+ logDebug(`[成语接龙] 成功获取成语: ${sys.idiom}`);
716
733
  await session.send(m);
734
+ await session.send('请输入要接的成语');
717
735
  }
718
736
  else {
737
+ logWarn(`[成语接龙] API返回异常: code=${dt.code}, msg=${dt.msg}`);
719
738
  m = dt.msg || d.chengyuJielong.botWin;
720
- st.chengyuJielong.currentRound += 1;
721
- st.chengyuJielong.botTurn = true;
722
739
  await session.send(m);
723
- if (st.chengyuJielong.currentRound > st.chengyuJielong.totalRounds) {
724
- st.chengyuJielong.started = false;
725
- clearAllTimers(st);
726
- await session.send(d.chengyuJielong.gameEnd);
727
- if (cfg.chengyuJielong.showRank && !isPrivate(session)) {
728
- const rankText = generateGameRankText(st.chengyuJielong.players, d.chengyuJielong.rankTitle, d.chengyuJielong.rankEmpty);
729
- await session.send(rankText);
730
- }
731
- clearGameData(st.chengyuJielong);
732
- gameStates.set(key, st);
733
- return;
734
- }
735
- else {
736
- await session.send(d.chengyuJielong.roundEnd.replace('{0}', st.chengyuJielong.currentRound.toString()).replace('{1}', (st.chengyuJielong.totalRounds - st.chengyuJielong.currentRound).toString()));
737
- }
738
- }
739
- if (cfg.chengyuJielong.maxRounds > 0 && st.chengyuJielong.jielongCount >= cfg.chengyuJielong.maxRounds) {
740
- st.chengyuJielong.started = false;
741
- clearAllTimers(st);
742
- await session.send(d.chengyuJielong.gameEnd);
743
- if (cfg.chengyuJielong.showRank && !isPrivate(session)) {
744
- const rankText = generateGameRankText(st.chengyuJielong.players, d.chengyuJielong.rankTitle, d.chengyuJielong.rankEmpty);
745
- await session.send(rankText);
746
- }
747
- clearGameData(st.chengyuJielong);
748
- gameStates.set(key, st);
749
- return;
750
740
  }
751
741
  }
752
742
  catch (error) {
743
+ const err = error;
744
+ logError(`[成语接龙] API调用失败: ${err.message}`, err);
753
745
  await session.send(d.chengyuJielong.apiError);
754
746
  }
755
747
  gameStates.set(key, st);
@@ -797,10 +789,11 @@ async function apply(ctx, cfg) {
797
789
  return;
798
790
  }
799
791
  try {
800
- const intUserId = getIntUserId(session);
792
+ const userId = getUserId(session);
793
+ logDebug(`[成语接龙玩家] 开始调用API,平台: ${session.platform}, 用户ID: ${userId}, 内容: ${content}`);
801
794
  const r = await axios_1.default.get('https://api.suol.cc/v1/game_cyjl.php', {
802
795
  params: {
803
- id: intUserId,
796
+ id: userId,
804
797
  msg: `我接${content}`
805
798
  },
806
799
  timeout: cfg.apiConfig.timeout,
@@ -808,6 +801,8 @@ async function apply(ctx, cfg) {
808
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'
809
802
  }
810
803
  });
804
+ logDebug(`[成语接龙玩家] API返回状态码: ${r.status}`);
805
+ logDebug(`[成语接龙玩家] API返回数据:`, r.data);
811
806
  const dt = r.data;
812
807
  let m = '';
813
808
  if (dt.code === 200) {
@@ -816,28 +811,41 @@ async function apply(ctx, cfg) {
816
811
  m += d.chengyuJielong.correct + '\n';
817
812
  m += `你的成语:${dt.data.user.idiom}\n`;
818
813
  st.chengyuJielong.botTurn = true;
814
+ st.chengyuJielong.currentRound += 1;
815
+ logDebug(`[成语接龙玩家] 接龙成功: ${dt.data.user.idiom}`);
819
816
  }
820
817
  else {
821
818
  m += d.chengyuJielong.wrong + '\n';
819
+ logDebug(`[成语接龙玩家] 接龙失败`);
822
820
  }
823
821
  if (dt.data?.system) {
824
822
  m += `我的接龙:${dt.data.system.idiom}`;
825
823
  st.chengyuJielong.lastChar = dt.data.current_char || '';
826
824
  st.chengyuJielong.jielongCount += 1;
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);
827
832
  }
828
- st.chengyuJielong.currentRound += 1;
829
- await session.send(m);
830
833
  if (cfg.chengyuJielong.botParticipate && st.chengyuJielong.botTurn) {
831
- scheduleAutoPlay(session, key, st);
834
+ setTimeout(() => {
835
+ doAutoPlay(session, key, st);
836
+ }, cfg.chengyuJielong.autoPlayDelay * 1000);
832
837
  }
833
838
  }
834
839
  else {
840
+ logWarn(`[成语接龙玩家] API返回异常: code=${dt.code}, msg=${dt.msg}`);
835
841
  m = dt.msg || '接龙失败';
836
842
  m += '\n' + d.chengyuJielong.wrong;
837
843
  await session.send(m);
838
844
  }
839
845
  }
840
846
  catch (error) {
847
+ const err = error;
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;
@@ -1321,9 +1329,10 @@ async function apply(ctx, cfg) {
1321
1329
  st.chengyuJielong.autoPlayCount = 0;
1322
1330
  st.chengyuJielong.jielongCount = 0;
1323
1331
  st.chengyuJielong.botTurn = true;
1324
- st.chengyuJielong.hasTriggeredAutoPlay = false;
1325
1332
  await session.send(d.chengyuJielong.start.replace('{0}', st.chengyuJielong.totalRounds.toString()));
1326
- scheduleAutoPlay(session, key, st);
1333
+ setTimeout(() => {
1334
+ doAutoPlay(session, key, st);
1335
+ }, 100);
1327
1336
  gameStates.set(key, st);
1328
1337
  setupAutoStop(session, st.chengyuJielong, 'chengyuJielong', d.chengyuJielong.autoStop, cfg.chengyuJielong.showRank, d.chengyuJielong.rankTitle, d.chengyuJielong.rankEmpty);
1329
1338
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koishi-plugin-game-mini",
3
- "version": "0.2.9",
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 |