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 +3 -3
- package/lib/index.js +72 -64
- package/package.json +1 -1
- package/readme.md +4 -0
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
|
|
682
|
-
|
|
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
|
-
|
|
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
|
-
|
|
732
|
+
logDebug(`[成语接龙] 成功获取成语: ${sys.idiom}`);
|
|
703
733
|
await session.send(m);
|
|
734
|
+
await session.send('请输入要接的成语');
|
|
704
735
|
}
|
|
705
736
|
else {
|
|
706
|
-
|
|
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
|
-
|
|
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
|
|
791
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
814
|
+
st.chengyuJielong.currentRound += 1;
|
|
815
|
+
logDebug(`[成语接龙玩家] 接龙成功: ${dt.data.user.idiom}`);
|
|
812
816
|
}
|
|
813
817
|
else {
|
|
814
818
|
m += d.chengyuJielong.wrong + '\n';
|
|
815
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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
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 |
|