koishi-plugin-game-mini 0.2.5 → 0.2.7
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 +137 -11
- package/lib/index.js +808 -598
- package/package.json +2 -4
- package/readme.md +121 -106
package/lib/index.js
CHANGED
|
@@ -11,76 +11,303 @@ const path_1 = __importDefault(require("path"));
|
|
|
11
11
|
const yaml_1 = __importDefault(require("yaml"));
|
|
12
12
|
const axios_1 = __importDefault(require("axios"));
|
|
13
13
|
exports.name = 'game-mini';
|
|
14
|
-
exports.using = ['i18n'];
|
|
14
|
+
exports.using = ['i18n', 'database'];
|
|
15
15
|
exports.inject = ['console'];
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
16
|
+
const defaultMessages = {
|
|
17
|
+
guessNumber: {
|
|
18
|
+
usage: "用法错误!正确用法:猜数字 开始 | [数字] | 猜数字 结束",
|
|
19
|
+
start: "猜数字比赛开始!本次共 {0} 回合~",
|
|
20
|
+
stop: "猜数字比赛已停止",
|
|
21
|
+
outOfRange: "数字超出当前范围 [{0}-{1}],请重新输入!",
|
|
22
|
+
tooSmall: "猜小啦!当前范围更新为 [{0}-{1}]",
|
|
23
|
+
tooBig: "猜大啦!当前范围更新为 [{0}-{1}]",
|
|
24
|
+
correct: "恭喜你猜中数字!",
|
|
25
|
+
roundEnd: "第 {0} 回合结束!剩余回合:{1}",
|
|
26
|
+
gameEnd: "🎉 猜数字比赛结束!🎉",
|
|
27
|
+
rankTitle: "🏆 本局排行榜 🏆",
|
|
28
|
+
rankEmpty: "暂无参与记录~",
|
|
29
|
+
disabled: "猜数字功能已关闭,请联系管理员开启",
|
|
30
|
+
autoStop: "太久没人玩啦,比赛自动结束~"
|
|
31
|
+
},
|
|
32
|
+
wzHero: {
|
|
33
|
+
start: "猜王者英雄开始!本次共 {0} 回合~当前难度:{1}",
|
|
34
|
+
startUsage: "用法错误!正确用法:猜王者英雄 开始 | [答案] | 提示 | 结束",
|
|
35
|
+
stop: "猜王者英雄比赛已停止",
|
|
36
|
+
notStarted: "猜王者英雄比赛尚未开始,请输入 猜王者英雄 开始 开始游戏",
|
|
37
|
+
hint: "提示",
|
|
38
|
+
apiError: "API请求失败,请稍后再试",
|
|
39
|
+
correct: "答对啦!你获得1分~",
|
|
40
|
+
wrong: "答错啦~正确答案是:{0},你不得分",
|
|
41
|
+
roundEnd: "第 {0} 回合结束!剩余回合:{1}",
|
|
42
|
+
gameEnd: "🎉 猜王者英雄比赛结束!🎉",
|
|
43
|
+
rankTitle: "🏆 本局排行榜 🏆",
|
|
44
|
+
rankEmpty: "暂无参与记录~",
|
|
45
|
+
disabled: "猜王者英雄功能已关闭,请联系管理员开启",
|
|
46
|
+
autoStop: "太久没人玩啦,比赛自动结束~"
|
|
47
|
+
},
|
|
48
|
+
chengyuImage: {
|
|
49
|
+
start: "看图猜成语比赛开始!本次共 {0} 回合~当前提示级别:{1}",
|
|
50
|
+
stop: "看图猜成语比赛已停止",
|
|
51
|
+
submitUsage: "请直接输入 [答案],或输入 提示 获取线索",
|
|
52
|
+
notStarted: "看图猜成语比赛尚未开始,请输入 看图猜成语 开始 开始游戏",
|
|
53
|
+
next: "第 {0} 题来啦!",
|
|
54
|
+
hintGet: "【提示】{0}",
|
|
55
|
+
hintError: "获取提示失败,请稍后再试",
|
|
56
|
+
apiError: "API请求失败,请稍后再试",
|
|
57
|
+
correct: "答对啦!你获得1分~",
|
|
58
|
+
wrong: "答错啦~正确答案是:{0},你不得分",
|
|
59
|
+
roundEnd: "第 {0} 回合结束!剩余回合:{1}",
|
|
60
|
+
gameEnd: "🎉 看图猜成语比赛结束!🎉",
|
|
61
|
+
rankTitle: "🏆 本局排行榜 🏆",
|
|
62
|
+
rankEmpty: "暂无参与记录~",
|
|
63
|
+
disabled: "看图猜成语功能已关闭,请联系管理员开启",
|
|
64
|
+
autoStop: "太久没人玩啦,比赛自动结束~"
|
|
65
|
+
},
|
|
66
|
+
chengyuJielong: {
|
|
67
|
+
start: "成语接龙比赛开始!本次共 {0} 回合~我先来~",
|
|
68
|
+
stop: "成语接龙比赛已停止",
|
|
69
|
+
notStarted: "成语接龙比赛尚未开始,请输入 成语接龙 开始 开始游戏",
|
|
70
|
+
joinUsage: "请直接发送成语参与接龙",
|
|
71
|
+
apiError: "API请求失败,请稍后再试",
|
|
72
|
+
botTurn: "该我了!我接:{0}",
|
|
73
|
+
botWin: "哈哈我接不上了!本轮结束~",
|
|
74
|
+
autoPlayTooMany: "自动参与次数已达上限 {0}",
|
|
75
|
+
notIdiom: "请输入4字成语",
|
|
76
|
+
correct: "接龙成功!",
|
|
77
|
+
wrong: "接龙失败!",
|
|
78
|
+
roundEnd: "第 {0} 回合结束!剩余回合:{1}",
|
|
79
|
+
gameEnd: "🎉 成语接龙比赛结束!🎉",
|
|
80
|
+
rankTitle: "🏆 本局排行榜 🏆",
|
|
81
|
+
rankEmpty: "暂无参与记录~",
|
|
82
|
+
disabled: "成语接龙功能已关闭,请联系管理员开启",
|
|
83
|
+
autoStop: "太久没人玩啦,比赛自动结束~"
|
|
84
|
+
},
|
|
85
|
+
calc24: {
|
|
86
|
+
start: "算24点游戏开始!本次共 {0} 回合~当前难度:{1}",
|
|
87
|
+
stop: "算24点游戏已停止",
|
|
88
|
+
notStarted: "算24点游戏尚未开始,请输入 算24点 开始 开始游戏",
|
|
89
|
+
generate: "📝 第 {0} 题({1}):用 {2} 通过加减乘除和括号算出24!",
|
|
90
|
+
correct: "答对啦!你获得1分~",
|
|
91
|
+
wrong: "答错啦~",
|
|
92
|
+
solved: "这组数已经被答对啦,换一组数字~",
|
|
93
|
+
roundEnd: "第 {0} 回合结束!剩余回合:{1}",
|
|
94
|
+
gameEnd: "🎉 算24点游戏结束!🎉",
|
|
95
|
+
rankTitle: "🏆 本局排行榜 🏆",
|
|
96
|
+
rankEmpty: "暂无参与记录~",
|
|
97
|
+
disabled: "算24点功能已关闭,请联系管理员开启",
|
|
98
|
+
autoStop: "太久没人玩啦,比赛自动结束~"
|
|
99
|
+
},
|
|
100
|
+
rank: {
|
|
101
|
+
title: "📊 群游戏总排行榜",
|
|
102
|
+
empty: "暂无玩家数据",
|
|
103
|
+
playerInfo: "{0}. {1} - 得分:{2}分 | 答对:{3}题 | 游玩:{4}次",
|
|
104
|
+
totalStats: "\n📈 总统计:共 {0} 位玩家 | 总得分:{1} | 总答对:{2} | 总游玩:{3}",
|
|
105
|
+
noPermission: "❌ 你没有权限执行此操作",
|
|
106
|
+
clearSuccess: "✅ 本群所有玩家数据已清零"
|
|
107
|
+
},
|
|
108
|
+
common: {
|
|
109
|
+
gameRunning: "当前已有游戏在运行中,请先结束当前游戏后再开始新游戏!",
|
|
110
|
+
gameStoppedByInactive: "太久没人玩啦,比赛自动结束~",
|
|
111
|
+
paramError: "❌ 参数错误!请检查输入格式"
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
exports.Config = koishi_1.Schema.intersect([
|
|
115
|
+
koishi_1.Schema.object({
|
|
116
|
+
enableNumberGuess: koishi_1.Schema.boolean().default(true).description('🎲 启用猜数字游戏'),
|
|
117
|
+
enableWzHero: koishi_1.Schema.boolean().default(true).description('⚔️ 启用王者英雄猜谜'),
|
|
118
|
+
enableChengyuImage: koishi_1.Schema.boolean().default(true).description('🖼️ 启用看图猜成语'),
|
|
119
|
+
enableChengyuJielong: koishi_1.Schema.boolean().default(true).description('🐉 启用成语接龙'),
|
|
120
|
+
enableCalc24: koishi_1.Schema.boolean().default(true).description('🧮 启用算24点'),
|
|
121
|
+
}).description('⚙️ 游戏开关'),
|
|
122
|
+
koishi_1.Schema.object({
|
|
123
|
+
privateGame: koishi_1.Schema.object({
|
|
124
|
+
enableNumberGuess: koishi_1.Schema.boolean().default(true).description('🎲 允许私聊玩猜数字'),
|
|
125
|
+
enableWzHero: koishi_1.Schema.boolean().default(true).description('⚔️ 允许私聊玩王者英雄'),
|
|
126
|
+
enableChengyuImage: koishi_1.Schema.boolean().default(true).description('🖼️ 允许私聊玩看图猜成语'),
|
|
127
|
+
enableChengyuJielong: koishi_1.Schema.boolean().default(true).description('🐉 允许私聊玩成语接龙'),
|
|
128
|
+
enableCalc24: koishi_1.Schema.boolean().default(true).description('🧮 允许私聊玩算24点'),
|
|
129
|
+
}).description('💬 私聊游戏开关'),
|
|
130
|
+
}),
|
|
131
|
+
koishi_1.Schema.object({
|
|
132
|
+
rank: koishi_1.Schema.object({
|
|
133
|
+
enableCommand: koishi_1.Schema.boolean().default(true).description('📊 启用排行榜指令'),
|
|
134
|
+
maxDisplay: koishi_1.Schema.number().min(1).max(100).default(10).description('📋 排行榜最多显示人数'),
|
|
135
|
+
clearDataPermission: koishi_1.Schema.number().default(5).description('🔑 清零数据所需权限等级'),
|
|
136
|
+
messages: koishi_1.Schema.object({
|
|
137
|
+
title: koishi_1.Schema.string().default(defaultMessages.rank.title).description('排行榜标题'),
|
|
138
|
+
empty: koishi_1.Schema.string().default(defaultMessages.rank.empty).description('排行榜为空提示'),
|
|
139
|
+
playerInfo: koishi_1.Schema.string().default(defaultMessages.rank.playerInfo).description('玩家信息格式\n{0}-排名, {1}-玩家名, {2}-得分, {3}-答对题数, {4}-游玩次数'),
|
|
140
|
+
totalStats: koishi_1.Schema.string().default(defaultMessages.rank.totalStats).description('总统计信息\n{0}-总玩家数, {1}-总得分, {2}-总答对, {3}-总游玩'),
|
|
141
|
+
noPermission: koishi_1.Schema.string().default(defaultMessages.rank.noPermission).description('无权限提示'),
|
|
142
|
+
clearSuccess: koishi_1.Schema.string().default(defaultMessages.rank.clearSuccess).description('清零成功提示'),
|
|
143
|
+
showTotalStats: koishi_1.Schema.boolean().default(true).description('是否显示总统计数据'),
|
|
144
|
+
}).description('📊 排行榜消息配置'),
|
|
145
|
+
}).description('📊 排行榜配置'),
|
|
146
|
+
}),
|
|
147
|
+
koishi_1.Schema.object({
|
|
148
|
+
guessNumber: koishi_1.Schema.object({
|
|
149
|
+
min: koishi_1.Schema.number().min(0).default(0).description('最小值'),
|
|
150
|
+
max: koishi_1.Schema.number().min(1).default(100).description('最大值'),
|
|
151
|
+
botParticipateInGroup: koishi_1.Schema.boolean().default(true).description('群聊中机器人是否参与'),
|
|
152
|
+
totalRounds: koishi_1.Schema.number().min(1).default(10).description('总回合数'),
|
|
153
|
+
showRank: koishi_1.Schema.boolean().default(true).description('游戏结束后显示本局排行榜'),
|
|
154
|
+
autoPlayDelay: koishi_1.Schema.number().min(0).default(10).description('机器人自动操作延迟(秒)'),
|
|
155
|
+
autoPlayMaxCount: koishi_1.Schema.number().min(1).default(5).description('机器人最大自动操作次数'),
|
|
156
|
+
autoStopInactiveTime: koishi_1.Schema.number().min(0).default(60).description('游戏无操作自动停止时间(秒)'),
|
|
157
|
+
enablePenalty: koishi_1.Schema.boolean().default(true).description('启用惩罚机制'),
|
|
158
|
+
rewardScore: koishi_1.Schema.number().min(0).default(1).description('猜中者奖励分数'),
|
|
159
|
+
penaltyScore: koishi_1.Schema.number().max(0).default(-1).description('其他人扣除分数'),
|
|
160
|
+
messages: koishi_1.Schema.object({
|
|
161
|
+
usage: koishi_1.Schema.string().default(defaultMessages.guessNumber.usage).description('用法错误提示\n{0}-最小值, {1}-最大值'),
|
|
162
|
+
start: koishi_1.Schema.string().default(defaultMessages.guessNumber.start).description('游戏开始提示\n{0}-总回合数'),
|
|
163
|
+
stop: koishi_1.Schema.string().default(defaultMessages.guessNumber.stop).description('游戏停止提示'),
|
|
164
|
+
outOfRange: koishi_1.Schema.string().default(defaultMessages.guessNumber.outOfRange).description('数字超出范围提示\n{0}-最小值, {1}-最大值'),
|
|
165
|
+
tooSmall: koishi_1.Schema.string().default(defaultMessages.guessNumber.tooSmall).description('猜小了提示\n{0}-新最小值, {1}-新最大值'),
|
|
166
|
+
tooBig: koishi_1.Schema.string().default(defaultMessages.guessNumber.tooBig).description('猜大了提示\n{0}-新最小值, {1}-新最大值'),
|
|
167
|
+
correct: koishi_1.Schema.string().default(defaultMessages.guessNumber.correct).description('猜中提示'),
|
|
168
|
+
roundEnd: koishi_1.Schema.string().default(defaultMessages.guessNumber.roundEnd).description('回合结束提示\n{0}-当前回合, {1}-剩余回合'),
|
|
169
|
+
gameEnd: koishi_1.Schema.string().default(defaultMessages.guessNumber.gameEnd).description('游戏结束提示'),
|
|
170
|
+
rankTitle: koishi_1.Schema.string().default(defaultMessages.guessNumber.rankTitle).description('本局排行榜标题'),
|
|
171
|
+
rankEmpty: koishi_1.Schema.string().default(defaultMessages.guessNumber.rankEmpty).description('本局排行榜为空提示'),
|
|
172
|
+
disabled: koishi_1.Schema.string().default(defaultMessages.guessNumber.disabled).description('功能禁用提示'),
|
|
173
|
+
autoStop: koishi_1.Schema.string().default("太久没人玩啦,比赛自动结束~").description('自动停止提示'),
|
|
174
|
+
}).description('💬 猜数字消息配置'),
|
|
175
|
+
}).description('🎲 猜数字游戏配置'),
|
|
176
|
+
}),
|
|
177
|
+
koishi_1.Schema.object({
|
|
178
|
+
wzHero: koishi_1.Schema.object({
|
|
179
|
+
totalRounds: koishi_1.Schema.number().min(1).default(10).description('总回合数'),
|
|
180
|
+
showRank: koishi_1.Schema.boolean().default(true).description('游戏结束后显示本局排行榜'),
|
|
181
|
+
defaultDifficulty: koishi_1.Schema.union(['简单', '中等', '困难']).default('简单').description('默认难度'),
|
|
182
|
+
autoStopInactiveTime: koishi_1.Schema.number().min(0).default(60).description('游戏无操作自动停止时间(秒)'),
|
|
183
|
+
rewardScore: koishi_1.Schema.number().min(0).default(1).description('答对奖励分数'),
|
|
184
|
+
messages: koishi_1.Schema.object({
|
|
185
|
+
start: koishi_1.Schema.string().default(defaultMessages.wzHero.start).description('游戏开始提示\n{0}-总回合数, {1}-难度'),
|
|
186
|
+
startUsage: koishi_1.Schema.string().default(defaultMessages.wzHero.startUsage).description('开始用法提示'),
|
|
187
|
+
stop: koishi_1.Schema.string().default(defaultMessages.wzHero.stop).description('游戏停止提示'),
|
|
188
|
+
notStarted: koishi_1.Schema.string().default(defaultMessages.wzHero.notStarted).description('游戏未开始提示'),
|
|
189
|
+
hint: koishi_1.Schema.string().default(defaultMessages.wzHero.hint).description('提示命令'),
|
|
190
|
+
apiError: koishi_1.Schema.string().default(defaultMessages.wzHero.apiError).description('API错误提示'),
|
|
191
|
+
correct: koishi_1.Schema.string().default(defaultMessages.wzHero.correct).description('答对提示\n{0}-当前得分'),
|
|
192
|
+
wrong: koishi_1.Schema.string().default(defaultMessages.wzHero.wrong).description('答错提示\n{0}-正确答案'),
|
|
193
|
+
roundEnd: koishi_1.Schema.string().default(defaultMessages.wzHero.roundEnd).description('回合结束提示\n{0}-当前回合, {1}-剩余回合'),
|
|
194
|
+
gameEnd: koishi_1.Schema.string().default(defaultMessages.wzHero.gameEnd).description('游戏结束提示'),
|
|
195
|
+
rankTitle: koishi_1.Schema.string().default(defaultMessages.wzHero.rankTitle).description('本局排行榜标题'),
|
|
196
|
+
rankEmpty: koishi_1.Schema.string().default(defaultMessages.wzHero.rankEmpty).description('本局排行榜为空提示'),
|
|
197
|
+
disabled: koishi_1.Schema.string().default(defaultMessages.wzHero.disabled).description('功能禁用提示'),
|
|
198
|
+
autoStop: koishi_1.Schema.string().default("太久没人玩啦,比赛自动结束~").description('自动停止提示'),
|
|
199
|
+
}).description('💬 王者英雄猜谜消息配置'),
|
|
200
|
+
}).description('⚔️ 王者英雄猜谜配置'),
|
|
201
|
+
}),
|
|
202
|
+
koishi_1.Schema.object({
|
|
203
|
+
chengyuImage: koishi_1.Schema.object({
|
|
204
|
+
totalRounds: koishi_1.Schema.number().min(1).default(10).description('总回合数'),
|
|
205
|
+
showRank: koishi_1.Schema.boolean().default(true).description('游戏结束后显示本局排行榜'),
|
|
206
|
+
defaultHintLevel: koishi_1.Schema.union([1, 2, 3, 4, 5]).default(1).description('默认提示级别'),
|
|
207
|
+
autoStopInactiveTime: koishi_1.Schema.number().min(0).default(60).description('游戏无操作自动停止时间(秒)'),
|
|
208
|
+
rewardScore: koishi_1.Schema.number().min(0).default(1).description('答对奖励分数'),
|
|
209
|
+
messages: koishi_1.Schema.object({
|
|
210
|
+
start: koishi_1.Schema.string().default(defaultMessages.chengyuImage.start).description('游戏开始提示\n{0}-总回合数, {1}-提示级别'),
|
|
211
|
+
stop: koishi_1.Schema.string().default(defaultMessages.chengyuImage.stop).description('游戏停止提示'),
|
|
212
|
+
submitUsage: koishi_1.Schema.string().default(defaultMessages.chengyuImage.submitUsage).description('提交答案用法提示'),
|
|
213
|
+
notStarted: koishi_1.Schema.string().default(defaultMessages.chengyuImage.notStarted).description('游戏未开始提示'),
|
|
214
|
+
next: koishi_1.Schema.string().default(defaultMessages.chengyuImage.next).description('下一题提示\n{0}-当前回合'),
|
|
215
|
+
hintGet: koishi_1.Schema.string().default(defaultMessages.chengyuImage.hintGet).description('获取提示成功\n{0}-提示内容'),
|
|
216
|
+
hintError: koishi_1.Schema.string().default(defaultMessages.chengyuImage.hintError).description('获取提示失败'),
|
|
217
|
+
apiError: koishi_1.Schema.string().default(defaultMessages.chengyuImage.apiError).description('API错误提示'),
|
|
218
|
+
correct: koishi_1.Schema.string().default(defaultMessages.chengyuImage.correct).description('答对提示\n{0}-当前得分'),
|
|
219
|
+
wrong: koishi_1.Schema.string().default(defaultMessages.chengyuImage.wrong).description('答错提示\n{0}-正确答案, {1}-当前得分'),
|
|
220
|
+
roundEnd: koishi_1.Schema.string().default(defaultMessages.chengyuImage.roundEnd).description('回合结束提示\n{0}-当前回合, {1}-剩余回合'),
|
|
221
|
+
gameEnd: koishi_1.Schema.string().default(defaultMessages.chengyuImage.gameEnd).description('游戏结束提示'),
|
|
222
|
+
rankTitle: koishi_1.Schema.string().default(defaultMessages.chengyuImage.rankTitle).description('本局排行榜标题'),
|
|
223
|
+
rankEmpty: koishi_1.Schema.string().default(defaultMessages.chengyuImage.rankEmpty).description('本局排行榜为空提示'),
|
|
224
|
+
disabled: koishi_1.Schema.string().default(defaultMessages.chengyuImage.disabled).description('功能禁用提示'),
|
|
225
|
+
autoStop: koishi_1.Schema.string().default("太久没人玩啦,比赛自动结束~").description('自动停止提示'),
|
|
226
|
+
}).description('💬 看图猜成语消息配置'),
|
|
227
|
+
}).description('🖼️ 看图猜成语配置'),
|
|
228
|
+
}),
|
|
229
|
+
koishi_1.Schema.object({
|
|
230
|
+
chengyuJielong: koishi_1.Schema.object({
|
|
231
|
+
totalRounds: koishi_1.Schema.number().min(1).default(10).description('总回合数'),
|
|
232
|
+
showRank: koishi_1.Schema.boolean().default(true).description('游戏结束后显示本局排行榜'),
|
|
233
|
+
autoPlayDelay: koishi_1.Schema.number().min(0).default(10).description('机器人自动操作延迟(秒)'),
|
|
234
|
+
autoPlayMaxCount: koishi_1.Schema.number().min(1).default(5).description('机器人最大自动操作次数'),
|
|
235
|
+
autoStopInactiveTime: koishi_1.Schema.number().min(0).default(60).description('游戏无操作自动停止时间(秒)'),
|
|
236
|
+
maxRounds: koishi_1.Schema.number().min(0).default(10).description('最大接龙回合数(0为无限)'),
|
|
237
|
+
botParticipate: koishi_1.Schema.boolean().default(false).description('机器人是否参与接龙'),
|
|
238
|
+
rewardScore: koishi_1.Schema.number().min(0).default(1).description('接龙成功奖励分数'),
|
|
239
|
+
messages: koishi_1.Schema.object({
|
|
240
|
+
start: koishi_1.Schema.string().default(defaultMessages.chengyuJielong.start).description('游戏开始提示\n{0}-总回合数'),
|
|
241
|
+
stop: koishi_1.Schema.string().default(defaultMessages.chengyuJielong.stop).description('游戏停止提示'),
|
|
242
|
+
notStarted: koishi_1.Schema.string().default(defaultMessages.chengyuJielong.notStarted).description('游戏未开始提示'),
|
|
243
|
+
joinUsage: koishi_1.Schema.string().default(defaultMessages.chengyuJielong.joinUsage).description('参与用法提示'),
|
|
244
|
+
apiError: koishi_1.Schema.string().default(defaultMessages.chengyuJielong.apiError).description('API错误提示'),
|
|
245
|
+
botTurn: koishi_1.Schema.string().default(defaultMessages.chengyuJielong.botTurn).description('机器人回合提示\n{0}-成语'),
|
|
246
|
+
botWin: koishi_1.Schema.string().default(defaultMessages.chengyuJielong.botWin).description('机器人赢提示'),
|
|
247
|
+
autoPlayTooMany: koishi_1.Schema.string().default(defaultMessages.chengyuJielong.autoPlayTooMany).description('自动参与次数过多提示\n{0}-最大次数'),
|
|
248
|
+
notIdiom: koishi_1.Schema.string().default(defaultMessages.chengyuJielong.notIdiom).description('非成语提示'),
|
|
249
|
+
correct: koishi_1.Schema.string().default(defaultMessages.chengyuJielong.correct).description('接龙成功提示'),
|
|
250
|
+
wrong: koishi_1.Schema.string().default(defaultMessages.chengyuJielong.wrong).description('接龙失败提示'),
|
|
251
|
+
roundEnd: koishi_1.Schema.string().default(defaultMessages.chengyuJielong.roundEnd).description('回合结束提示\n{0}-当前回合, {1}-剩余回合'),
|
|
252
|
+
gameEnd: koishi_1.Schema.string().default(defaultMessages.chengyuJielong.gameEnd).description('游戏结束提示'),
|
|
253
|
+
rankTitle: koishi_1.Schema.string().default(defaultMessages.chengyuJielong.rankTitle).description('本局排行榜标题'),
|
|
254
|
+
rankEmpty: koishi_1.Schema.string().default(defaultMessages.chengyuJielong.rankEmpty).description('本局排行榜为空提示'),
|
|
255
|
+
disabled: koishi_1.Schema.string().default(defaultMessages.chengyuJielong.disabled).description('功能禁用提示'),
|
|
256
|
+
autoStop: koishi_1.Schema.string().default("太久没人玩啦,比赛自动结束~").description('自动停止提示'),
|
|
257
|
+
}).description('💬 成语接龙消息配置'),
|
|
258
|
+
}).description('🐉 成语接龙配置'),
|
|
259
|
+
}),
|
|
260
|
+
koishi_1.Schema.object({
|
|
261
|
+
calc24: koishi_1.Schema.object({
|
|
262
|
+
totalRounds: koishi_1.Schema.number().min(1).default(5).description('总回合数'),
|
|
263
|
+
showRank: koishi_1.Schema.boolean().default(true).description('游戏结束后显示本局排行榜'),
|
|
264
|
+
defaultDifficulty: koishi_1.Schema.union(['简单', '中等', '困难']).default('中等').description('默认难度'),
|
|
265
|
+
difficultyLevels: koishi_1.Schema.object({
|
|
266
|
+
easy: koishi_1.Schema.object({
|
|
267
|
+
min: koishi_1.Schema.number().default(1).description('最小值'),
|
|
268
|
+
max: koishi_1.Schema.number().default(8).description('最大值'),
|
|
269
|
+
}).description('简单难度数字范围'),
|
|
270
|
+
medium: koishi_1.Schema.object({
|
|
271
|
+
min: koishi_1.Schema.number().default(1).description('最小值'),
|
|
272
|
+
max: koishi_1.Schema.number().default(10).description('最大值'),
|
|
273
|
+
}).description('中等难度数字范围'),
|
|
274
|
+
hard: koishi_1.Schema.object({
|
|
275
|
+
min: koishi_1.Schema.number().default(1).description('最小值'),
|
|
276
|
+
max: koishi_1.Schema.number().default(13).description('最大值'),
|
|
277
|
+
}).description('困难难度数字范围'),
|
|
278
|
+
}).description('各难度数字范围配置'),
|
|
279
|
+
autoStopInactiveTime: koishi_1.Schema.number().min(0).default(60).description('游戏无操作自动停止时间(秒)'),
|
|
280
|
+
rewardScore: koishi_1.Schema.number().min(0).default(1).description('答对奖励分数'),
|
|
281
|
+
messages: koishi_1.Schema.object({
|
|
282
|
+
start: koishi_1.Schema.string().default(defaultMessages.calc24.start).description('游戏开始提示\n{0}-总回合数, {1}-难度'),
|
|
283
|
+
stop: koishi_1.Schema.string().default(defaultMessages.calc24.stop).description('游戏停止提示'),
|
|
284
|
+
notStarted: koishi_1.Schema.string().default(defaultMessages.calc24.notStarted).description('游戏未开始提示'),
|
|
285
|
+
generate: koishi_1.Schema.string().default(defaultMessages.calc24.generate).description('生成题目提示\n{0}-当前回合, {1}-难度, {2}-数字列表'),
|
|
286
|
+
correct: koishi_1.Schema.string().default(defaultMessages.calc24.correct).description('答对提示'),
|
|
287
|
+
wrong: koishi_1.Schema.string().default(defaultMessages.calc24.wrong).description('答错提示'),
|
|
288
|
+
solved: koishi_1.Schema.string().default(defaultMessages.calc24.solved).description('已解决提示'),
|
|
289
|
+
roundEnd: koishi_1.Schema.string().default(defaultMessages.calc24.roundEnd).description('回合结束提示\n{0}-当前回合, {1}-剩余回合'),
|
|
290
|
+
gameEnd: koishi_1.Schema.string().default(defaultMessages.calc24.gameEnd).description('游戏结束提示'),
|
|
291
|
+
rankTitle: koishi_1.Schema.string().default(defaultMessages.calc24.rankTitle).description('本局排行榜标题'),
|
|
292
|
+
rankEmpty: koishi_1.Schema.string().default(defaultMessages.calc24.rankEmpty).description('本局排行榜为空提示'),
|
|
293
|
+
disabled: koishi_1.Schema.string().default(defaultMessages.calc24.disabled).description('功能禁用提示'),
|
|
294
|
+
autoStop: koishi_1.Schema.string().default("太久没人玩啦,比赛自动结束~").description('自动停止提示'),
|
|
295
|
+
}).description('💬 算24点消息配置'),
|
|
296
|
+
}).description('🧮 算24点配置'),
|
|
297
|
+
}),
|
|
298
|
+
koishi_1.Schema.object({
|
|
299
|
+
apiConfig: koishi_1.Schema.object({
|
|
300
|
+
timeout: koishi_1.Schema.number().default(5000).description('API请求超时时间(毫秒)'),
|
|
301
|
+
}).description('🌐 API接口配置'),
|
|
302
|
+
}),
|
|
303
|
+
koishi_1.Schema.object({
|
|
304
|
+
commonMessages: koishi_1.Schema.object({
|
|
305
|
+
gameRunning: koishi_1.Schema.string().default(defaultMessages.common.gameRunning).description('游戏运行中提示'),
|
|
306
|
+
gameStoppedByInactive: koishi_1.Schema.string().default("太久没人玩啦,比赛自动结束~").description('无操作停止提示'),
|
|
307
|
+
paramError: koishi_1.Schema.string().default("❌ 参数错误!请检查输入格式").description('参数错误提示'),
|
|
308
|
+
}).description('💬 通用消息配置'),
|
|
309
|
+
}),
|
|
310
|
+
]);
|
|
84
311
|
const logger = new koishi_1.Logger('game-mini');
|
|
85
312
|
const gameStates = new Map();
|
|
86
313
|
const getSessionKey = (s) => s.channelId ? `g:${s.channelId}` : `p:${s.userId}`;
|
|
@@ -89,372 +316,30 @@ const getIntUserId = (session) => {
|
|
|
89
316
|
const hash = userIdStr.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0);
|
|
90
317
|
return hash || 1000000;
|
|
91
318
|
};
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
if (t !== 'chengyuImage' && s.chengyuImage.started)
|
|
108
|
-
return true;
|
|
109
|
-
if (t !== 'chengyuJielong' && s.chengyuJielong.started)
|
|
110
|
-
return true;
|
|
111
|
-
if (t !== 'calc24' && s.calc24.started)
|
|
112
|
-
return true;
|
|
113
|
-
if (t !== 'passwordLock' && s.passwordLock.started)
|
|
114
|
-
return true;
|
|
115
|
-
return false;
|
|
116
|
-
};
|
|
117
|
-
const clearGameTimer = (state) => {
|
|
118
|
-
if (state.stopTimer)
|
|
119
|
-
clearTimeout(state.stopTimer);
|
|
120
|
-
if (state.autoPlayTimer)
|
|
121
|
-
clearTimeout(state.autoPlayTimer);
|
|
122
|
-
};
|
|
123
|
-
const clearAllTimers = (st) => {
|
|
124
|
-
clearGameTimer(st.guessNumber);
|
|
125
|
-
clearGameTimer(st.wzHero);
|
|
126
|
-
clearGameTimer(st.chengyuImage);
|
|
127
|
-
clearGameTimer(st.chengyuJielong);
|
|
128
|
-
clearGameTimer(st.calc24);
|
|
129
|
-
clearGameTimer(st.passwordLock);
|
|
130
|
-
};
|
|
131
|
-
const initState = (key, c) => {
|
|
132
|
-
const s = {
|
|
133
|
-
guessNumber: {
|
|
134
|
-
started: false,
|
|
135
|
-
totalRounds: c.guessNumber.totalRounds,
|
|
136
|
-
currentRound: 0,
|
|
137
|
-
players: {},
|
|
138
|
-
participants: [],
|
|
139
|
-
target: 0,
|
|
140
|
-
currentMin: c.guessNumber.min,
|
|
141
|
-
currentMax: c.guessNumber.max,
|
|
142
|
-
botGuess: []
|
|
143
|
-
},
|
|
144
|
-
wzHero: {
|
|
145
|
-
started: false,
|
|
146
|
-
totalRounds: c.wzHero.totalRounds,
|
|
147
|
-
currentRound: 0,
|
|
148
|
-
players: {},
|
|
149
|
-
participants: [],
|
|
150
|
-
difficulty: c.wzHero.defaultDifficulty,
|
|
151
|
-
botAnswered: false,
|
|
152
|
-
lastHint: '',
|
|
153
|
-
currentHeroId: '',
|
|
154
|
-
currentAnswer: ''
|
|
155
|
-
},
|
|
156
|
-
chengyuImage: {
|
|
157
|
-
started: false,
|
|
158
|
-
totalRounds: c.chengyuImage.totalRounds,
|
|
159
|
-
currentRound: 0,
|
|
160
|
-
players: {},
|
|
161
|
-
participants: [],
|
|
162
|
-
currentId: '',
|
|
163
|
-
currentPage: 1,
|
|
164
|
-
options: [],
|
|
165
|
-
answer: ''
|
|
166
|
-
},
|
|
167
|
-
chengyuJielong: {
|
|
168
|
-
started: false,
|
|
169
|
-
totalRounds: c.chengyuJielong.totalRounds,
|
|
170
|
-
currentRound: 0,
|
|
171
|
-
players: {},
|
|
172
|
-
participants: [],
|
|
173
|
-
lastChar: '',
|
|
174
|
-
botTurn: true,
|
|
175
|
-
autoPlayCount: 0,
|
|
176
|
-
hasTriggeredAutoPlay: false,
|
|
177
|
-
lastActiveTime: Date.now()
|
|
178
|
-
},
|
|
179
|
-
calc24: {
|
|
180
|
-
started: false,
|
|
181
|
-
totalRounds: c.calc24.totalRounds,
|
|
182
|
-
currentRound: 0,
|
|
183
|
-
players: {},
|
|
184
|
-
participants: [],
|
|
185
|
-
difficulty: c.calc24.defaultDifficulty,
|
|
186
|
-
numbers: [],
|
|
187
|
-
playerAnswer: '',
|
|
188
|
-
solved: false,
|
|
189
|
-
availableNumbers: []
|
|
190
|
-
},
|
|
191
|
-
passwordLock: {
|
|
192
|
-
started: false,
|
|
193
|
-
totalRounds: 1,
|
|
194
|
-
currentRound: 0,
|
|
195
|
-
players: {},
|
|
196
|
-
participants: [],
|
|
197
|
-
password: '',
|
|
198
|
-
playerGuess: '',
|
|
199
|
-
guessTimes: 0,
|
|
200
|
-
maxGuessTimes: c.passwordLock.maxGuessTimes,
|
|
201
|
-
hints: [],
|
|
202
|
-
solved: false
|
|
203
|
-
}
|
|
204
|
-
};
|
|
205
|
-
gameStates.set(key, s);
|
|
206
|
-
return s;
|
|
207
|
-
};
|
|
208
|
-
const isFourCharIdiom = (text) => {
|
|
209
|
-
const t = text.trim();
|
|
210
|
-
return /^[\u4e00-\u9fa5]{4}$/.test(t);
|
|
211
|
-
};
|
|
212
|
-
const generateRankText = (players) => {
|
|
213
|
-
const playerList = Object.values(players);
|
|
214
|
-
if (playerList.length === 0) {
|
|
215
|
-
return '🏆 排行榜 🏆\n暂无参与记录~';
|
|
216
|
-
}
|
|
217
|
-
const sortedPlayers = playerList.sort((a, b) => b.score - a.score);
|
|
218
|
-
let rankText = '🏆 排行榜 🏆\n';
|
|
219
|
-
sortedPlayers.forEach((player, index) => {
|
|
220
|
-
rankText += `${index + 1}. ${player.name} - 得分:${player.score}分(答对${player.correctCount}题)\n`;
|
|
221
|
-
});
|
|
222
|
-
return rankText.trim();
|
|
223
|
-
};
|
|
224
|
-
const clearGameData = (gameState) => {
|
|
225
|
-
gameState.players = {};
|
|
226
|
-
gameState.participants = [];
|
|
227
|
-
gameState.currentRound = 0;
|
|
228
|
-
gameState.started = false;
|
|
229
|
-
clearGameTimer(gameState);
|
|
230
|
-
};
|
|
231
|
-
const addScoreToOthers = (players, excludePlayerKey) => {
|
|
232
|
-
Object.keys(players).forEach(playerKey => {
|
|
233
|
-
if (playerKey !== excludePlayerKey) {
|
|
234
|
-
players[playerKey].score += 1;
|
|
235
|
-
}
|
|
319
|
+
async function apply(ctx, cfg) {
|
|
320
|
+
ctx.model.extend('game_mini_player', {
|
|
321
|
+
id: 'unsigned',
|
|
322
|
+
guildId: 'string',
|
|
323
|
+
platform: 'string',
|
|
324
|
+
userId: 'string',
|
|
325
|
+
name: 'string',
|
|
326
|
+
score: 'integer',
|
|
327
|
+
correctCount: 'integer',
|
|
328
|
+
playCount: 'integer',
|
|
329
|
+
lastGameTime: 'unsigned'
|
|
330
|
+
}, {
|
|
331
|
+
primary: 'id',
|
|
332
|
+
autoInc: true,
|
|
333
|
+
unique: [['guildId', 'platform', 'userId']]
|
|
236
334
|
});
|
|
237
|
-
};
|
|
238
|
-
const setupAutoStop = (session, state, cfg, gameType, endMsg, showRank) => {
|
|
239
|
-
clearGameTimer(state);
|
|
240
|
-
let inactiveTime = 30;
|
|
241
|
-
if (gameType === 'guessNumber')
|
|
242
|
-
inactiveTime = cfg.guessNumber.autoStopInactiveTime;
|
|
243
|
-
else if (gameType === 'wzHero')
|
|
244
|
-
inactiveTime = cfg.wzHero.autoStopInactiveTime;
|
|
245
|
-
else if (gameType === 'chengyuImage')
|
|
246
|
-
inactiveTime = cfg.chengyuImage.autoStopInactiveTime;
|
|
247
|
-
else if (gameType === 'chengyuJielong')
|
|
248
|
-
inactiveTime = cfg.chengyuJielong.autoStopInactiveTime;
|
|
249
|
-
else if (gameType === 'calc24')
|
|
250
|
-
inactiveTime = cfg.calc24.autoStopInactiveTime;
|
|
251
|
-
else if (gameType === 'passwordLock')
|
|
252
|
-
inactiveTime = cfg.passwordLock.autoStopInactiveTime;
|
|
253
|
-
if (inactiveTime <= 0)
|
|
254
|
-
return;
|
|
255
|
-
state.stopTimer = setTimeout(() => {
|
|
256
|
-
clearGameData(state);
|
|
257
|
-
session.send(endMsg);
|
|
258
|
-
if (showRank && session.channelId) {
|
|
259
|
-
session.send(generateRankText(state.players));
|
|
260
|
-
}
|
|
261
|
-
}, inactiveTime * 1000);
|
|
262
|
-
};
|
|
263
|
-
const calculate24 = (numbers) => {
|
|
264
|
-
if (numbers.length === 1)
|
|
265
|
-
return Math.abs(numbers[0] - 24) < 0.001;
|
|
266
|
-
for (let i = 0; i < numbers.length; i++) {
|
|
267
|
-
for (let j = 0; j < numbers.length; j++) {
|
|
268
|
-
if (i === j)
|
|
269
|
-
continue;
|
|
270
|
-
const rest = [];
|
|
271
|
-
for (let k = 0; k < numbers.length; k++) {
|
|
272
|
-
if (k !== i && k !== j)
|
|
273
|
-
rest.push(numbers[k]);
|
|
274
|
-
}
|
|
275
|
-
const a = numbers[i];
|
|
276
|
-
const b = numbers[j];
|
|
277
|
-
if (calculate24([...rest, a + b]))
|
|
278
|
-
return true;
|
|
279
|
-
if (calculate24([...rest, a - b]))
|
|
280
|
-
return true;
|
|
281
|
-
if (calculate24([...rest, b - a]))
|
|
282
|
-
return true;
|
|
283
|
-
if (calculate24([...rest, a * b]))
|
|
284
|
-
return true;
|
|
285
|
-
if (b !== 0 && calculate24([...rest, a / b]))
|
|
286
|
-
return true;
|
|
287
|
-
if (a !== 0 && calculate24([...rest, b / a]))
|
|
288
|
-
return true;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
return false;
|
|
292
|
-
};
|
|
293
|
-
const generateSolvable24Numbers = (min, max) => {
|
|
294
|
-
const maxAttempts = 1000;
|
|
295
|
-
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
296
|
-
const numbers = [
|
|
297
|
-
koishi_1.Random.int(min, max + 1),
|
|
298
|
-
koishi_1.Random.int(min, max + 1),
|
|
299
|
-
koishi_1.Random.int(min, max + 1),
|
|
300
|
-
koishi_1.Random.int(min, max + 1)
|
|
301
|
-
];
|
|
302
|
-
if (calculate24([...numbers])) {
|
|
303
|
-
return numbers;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
return [6, 4, 3, 1];
|
|
307
|
-
};
|
|
308
|
-
const generatePasswordHint = (password, guess) => {
|
|
309
|
-
let correctPos = 0;
|
|
310
|
-
let correctNum = 0;
|
|
311
|
-
const passwordArr = password.split('');
|
|
312
|
-
const guessArr = guess.split('');
|
|
313
|
-
const passwordUsed = [false, false, false, false];
|
|
314
|
-
const guessUsed = [false, false, false, false];
|
|
315
|
-
for (let i = 0; i < 4; i++) {
|
|
316
|
-
if (passwordArr[i] === guessArr[i]) {
|
|
317
|
-
correctPos++;
|
|
318
|
-
passwordUsed[i] = true;
|
|
319
|
-
guessUsed[i] = true;
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
for (let i = 0; i < 4; i++) {
|
|
323
|
-
if (guessUsed[i])
|
|
324
|
-
continue;
|
|
325
|
-
for (let j = 0; j < 4; j++) {
|
|
326
|
-
if (!passwordUsed[j] && passwordArr[j] === guessArr[i]) {
|
|
327
|
-
correctNum++;
|
|
328
|
-
passwordUsed[j] = true;
|
|
329
|
-
break;
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
return `提示:${correctPos}个数字位置正确,${correctNum}个数字正确但位置错误`;
|
|
334
|
-
};
|
|
335
|
-
const evaluateExpression = (expr) => {
|
|
336
|
-
try {
|
|
337
|
-
const cleanExpr = expr.replace(/[^\d\+\-\*\/\(\)\[\]\{\}\s]/g, '');
|
|
338
|
-
const normalizedExpr = cleanExpr.replace(/[\[\{]/g, '(').replace(/[\]\}]/g, ')');
|
|
339
|
-
const func = new Function('return ' + normalizedExpr);
|
|
340
|
-
const result = func();
|
|
341
|
-
if (typeof result === 'number' && isFinite(result)) {
|
|
342
|
-
return result;
|
|
343
|
-
}
|
|
344
|
-
return null;
|
|
345
|
-
}
|
|
346
|
-
catch {
|
|
347
|
-
return null;
|
|
348
|
-
}
|
|
349
|
-
};
|
|
350
|
-
function apply(ctx, cfg) {
|
|
351
335
|
const d = {
|
|
352
|
-
guessNumber:
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
correct: "恭喜你猜中数字!本轮你不得分,其他参与者各得1分~",
|
|
360
|
-
roundEnd: "第 {0} 回合结束!剩余回合:{1}",
|
|
361
|
-
gameEnd: "🎉 猜数字比赛结束!🎉",
|
|
362
|
-
rankTitle: "🏆 排行榜 🏆",
|
|
363
|
-
rankEmpty: "暂无参与记录~",
|
|
364
|
-
disabled: "猜数字功能已关闭,请联系管理员开启",
|
|
365
|
-
autoStop: "游戏因长时间无人操作,已自动结束"
|
|
366
|
-
},
|
|
367
|
-
wzHero: {
|
|
368
|
-
start: "猜王者英雄开始!本次共 {0} 回合~当前难度:{1}",
|
|
369
|
-
startUsage: "用法错误!正确用法:猜王者英雄 开始 | 猜王者英雄 [答案] | 猜王者英雄 提示 | 猜王者英雄 结束",
|
|
370
|
-
stop: "猜王者英雄比赛已停止",
|
|
371
|
-
notStarted: "猜王者英雄比赛尚未开始,请输入 猜王者英雄 开始 开始游戏",
|
|
372
|
-
hint: "提示",
|
|
373
|
-
apiError: "API请求失败,请稍后再试",
|
|
374
|
-
correct: "答对啦!你获得1分~",
|
|
375
|
-
wrong: "答错啦~正确答案是:{0},你不得分",
|
|
376
|
-
roundEnd: "第 {0} 回合结束!剩余回合:{1}",
|
|
377
|
-
gameEnd: "🎉 猜王者英雄比赛结束!🎉",
|
|
378
|
-
rankTitle: "🏆 排行榜 🏆",
|
|
379
|
-
rankEmpty: "暂无参与记录~",
|
|
380
|
-
disabled: "猜王者英雄功能已关闭,请联系管理员开启",
|
|
381
|
-
autoStop: "游戏因长时间无人操作,已自动结束"
|
|
382
|
-
},
|
|
383
|
-
chengyuImage: {
|
|
384
|
-
start: "看图猜成语比赛开始!本次共 {0} 回合~当前提示级别:{1}",
|
|
385
|
-
stop: "看图猜成语比赛已停止",
|
|
386
|
-
submitUsage: "请直接输入 看图猜成语 [答案],或输入 看图猜成语 提示 获取线索",
|
|
387
|
-
notStarted: "看图猜成语比赛尚未开始,请输入 看图猜成语 开始 开始游戏",
|
|
388
|
-
next: "第 {0} 题来啦!",
|
|
389
|
-
hintGet: "【提示】{0}",
|
|
390
|
-
hintError: "获取提示失败,请稍后再试",
|
|
391
|
-
apiError: "API请求失败,请稍后再试",
|
|
392
|
-
correct: "答对啦!你获得1分~",
|
|
393
|
-
wrong: "答错啦~正确答案是:{0},你不得分",
|
|
394
|
-
roundEnd: "第 {0} 回合结束!剩余回合:{1}",
|
|
395
|
-
gameEnd: "🎉 看图猜成语比赛结束!🎉",
|
|
396
|
-
rankTitle: "🏆 排行榜 🏆",
|
|
397
|
-
rankEmpty: "暂无参与记录~",
|
|
398
|
-
disabled: "看图猜成语功能已关闭,请联系管理员开启",
|
|
399
|
-
autoStop: "游戏因长时间无人操作,已自动结束"
|
|
400
|
-
},
|
|
401
|
-
chengyuJielong: {
|
|
402
|
-
start: "成语接龙比赛开始!本次共 {0} 回合~我先来~",
|
|
403
|
-
stop: "成语接龙比赛已停止",
|
|
404
|
-
notStarted: "成语接龙比赛尚未开始,请输入 成语接龙 开始 开始游戏",
|
|
405
|
-
joinUsage: "请直接发送 成语接龙 [成语] 参与接龙",
|
|
406
|
-
apiError: "API请求失败,请稍后再试",
|
|
407
|
-
botTurn: "该我了!我接:{0}({1})\n释义:{2}",
|
|
408
|
-
botWin: "哈哈我接不上了!本轮结束~",
|
|
409
|
-
autoPlayTooMany: "我已经主动参与 {0} 次啦,不再主动接啦~",
|
|
410
|
-
gameInactiveStop: "太久没人玩啦,比赛自动结束~",
|
|
411
|
-
notIdiom: "请发送四字成语参与游戏~",
|
|
412
|
-
correct: "接龙成功!你获得1分~",
|
|
413
|
-
wrong: "接龙失败!你不得分,其他参与者各得1分~",
|
|
414
|
-
roundEnd: "第 {0} 回合结束!剩余回合:{1}",
|
|
415
|
-
gameEnd: "🎉 成语接龙比赛结束!🎉",
|
|
416
|
-
rankTitle: "🏆 排行榜 🏆",
|
|
417
|
-
rankEmpty: "暂无参与记录~",
|
|
418
|
-
disabled: "成语接龙功能已关闭,请联系管理员开启",
|
|
419
|
-
autoStop: "游戏因长时间无人操作,已自动结束"
|
|
420
|
-
},
|
|
421
|
-
calc24: {
|
|
422
|
-
start: "算24点游戏开始!本次共 {0} 回合~当前难度:{1}",
|
|
423
|
-
stop: "算24点游戏已停止",
|
|
424
|
-
notStarted: "算24点游戏尚未开始,请输入 算24点 开始 开始游戏",
|
|
425
|
-
generate: "📝 第 {0} 题({1}):用 {2} 通过加减乘除和括号算出24!",
|
|
426
|
-
correct: "答对啦!你获得1分~",
|
|
427
|
-
wrong: "答错啦~",
|
|
428
|
-
impossible: "这组数无法算出24!本题作废,换一组数字~",
|
|
429
|
-
solved: "这组数已经被答对啦,换一组数字~",
|
|
430
|
-
roundEnd: "第 {0} 回合结束!剩余回合:{1}",
|
|
431
|
-
gameEnd: "🎉 算24点游戏结束!🎉",
|
|
432
|
-
rankTitle: "🏆 排行榜 🏆",
|
|
433
|
-
rankEmpty: "暂无参与记录~",
|
|
434
|
-
disabled: "算24点功能已关闭,请联系管理员开启",
|
|
435
|
-
autoStop: "游戏因长时间无人操作,已自动结束"
|
|
436
|
-
},
|
|
437
|
-
passwordLock: {
|
|
438
|
-
start: "猜密码游戏开始!密码为4位数字,你有 {0} 次猜测机会~",
|
|
439
|
-
stop: "猜密码游戏已停止",
|
|
440
|
-
notStarted: "猜密码游戏尚未开始,请输入 猜密码 开始 开始游戏",
|
|
441
|
-
guess: "你猜测的密码是:{0},这是第 {1} 次猜测",
|
|
442
|
-
correct: "🎉 恭喜!你猜对了密码 {0}!总共猜测了 {1} 次,获得10分~",
|
|
443
|
-
wrong: "密码错误!{0}",
|
|
444
|
-
solved: "密码已经被猜出来啦,游戏结束~",
|
|
445
|
-
noChance: "❌ 没有猜测机会了!正确密码是:{0}~",
|
|
446
|
-
invalidPassword: "无效的密码!请输入4位数字",
|
|
447
|
-
gameEnd: "🎉 猜密码游戏结束!🎉",
|
|
448
|
-
rankTitle: "🏆 排行榜 🏆",
|
|
449
|
-
rankEmpty: "暂无参与记录~",
|
|
450
|
-
disabled: "猜密码功能已关闭,请联系管理员开启",
|
|
451
|
-
autoStop: "游戏因长时间无人操作,已自动结束"
|
|
452
|
-
},
|
|
453
|
-
common: {
|
|
454
|
-
gameRunning: "当前已有游戏在运行中,请先结束当前游戏后再开始新游戏!",
|
|
455
|
-
gameStoppedByInactive: "游戏因长时间无人操作,已自动结束",
|
|
456
|
-
paramError: "参数错误!请检查输入格式"
|
|
457
|
-
}
|
|
336
|
+
guessNumber: cfg.guessNumber.messages,
|
|
337
|
+
wzHero: cfg.wzHero.messages,
|
|
338
|
+
chengyuImage: cfg.chengyuImage.messages,
|
|
339
|
+
chengyuJielong: cfg.chengyuJielong.messages,
|
|
340
|
+
calc24: cfg.calc24.messages,
|
|
341
|
+
rank: cfg.rank.messages,
|
|
342
|
+
common: cfg.commonMessages
|
|
458
343
|
};
|
|
459
344
|
try {
|
|
460
345
|
const p = path_1.default.join(__dirname, './locales/zh-CN.yml');
|
|
@@ -467,6 +352,318 @@ function apply(ctx, cfg) {
|
|
|
467
352
|
ctx.i18n.define('zh-CN', d);
|
|
468
353
|
}
|
|
469
354
|
const isPrivate = (s) => !s.channelId;
|
|
355
|
+
const canPlayPrivate = (game) => {
|
|
356
|
+
if (game === 'guessNumber')
|
|
357
|
+
return cfg.privateGame.enableNumberGuess;
|
|
358
|
+
if (game === 'wzHero')
|
|
359
|
+
return cfg.privateGame.enableWzHero;
|
|
360
|
+
if (game === 'chengyuImage')
|
|
361
|
+
return cfg.privateGame.enableChengyuImage;
|
|
362
|
+
if (game === 'chengyuJielong')
|
|
363
|
+
return cfg.privateGame.enableChengyuJielong;
|
|
364
|
+
if (game === 'calc24')
|
|
365
|
+
return cfg.privateGame.enableCalc24;
|
|
366
|
+
return false;
|
|
367
|
+
};
|
|
368
|
+
const getPlayerData = async (session) => {
|
|
369
|
+
if (!session.channelId) {
|
|
370
|
+
return {
|
|
371
|
+
platform: session.platform,
|
|
372
|
+
userId: session.userId || 'unknown_user',
|
|
373
|
+
name: session.username || session.userId || '未知用户',
|
|
374
|
+
score: 0,
|
|
375
|
+
correctCount: 0,
|
|
376
|
+
playCount: 0,
|
|
377
|
+
lastGameTime: 0
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
const guildId = session.channelId;
|
|
381
|
+
const platform = session.platform;
|
|
382
|
+
const userId = session.userId || 'unknown_user';
|
|
383
|
+
const name = session.username || userId;
|
|
384
|
+
let player = await ctx.database.get('game_mini_player', {
|
|
385
|
+
guildId,
|
|
386
|
+
platform,
|
|
387
|
+
userId
|
|
388
|
+
});
|
|
389
|
+
if (!player.length) {
|
|
390
|
+
const newPlayer = {
|
|
391
|
+
guildId,
|
|
392
|
+
platform,
|
|
393
|
+
userId,
|
|
394
|
+
name,
|
|
395
|
+
score: 0,
|
|
396
|
+
correctCount: 0,
|
|
397
|
+
playCount: 0,
|
|
398
|
+
lastGameTime: 0
|
|
399
|
+
};
|
|
400
|
+
const id = await ctx.database.create('game_mini_player', newPlayer);
|
|
401
|
+
return {
|
|
402
|
+
guildId,
|
|
403
|
+
platform,
|
|
404
|
+
userId,
|
|
405
|
+
name,
|
|
406
|
+
score: 0,
|
|
407
|
+
correctCount: 0,
|
|
408
|
+
playCount: 0,
|
|
409
|
+
lastGameTime: 0
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
return player[0];
|
|
413
|
+
};
|
|
414
|
+
const savePlayerData = async (session, playerData) => {
|
|
415
|
+
if (!session.channelId)
|
|
416
|
+
return;
|
|
417
|
+
await ctx.database.set('game_mini_player', { guildId: session.channelId, platform: session.platform, userId: session.userId }, {
|
|
418
|
+
name: playerData.name,
|
|
419
|
+
score: playerData.score,
|
|
420
|
+
correctCount: playerData.correctCount,
|
|
421
|
+
playCount: playerData.playCount,
|
|
422
|
+
lastGameTime: playerData.lastGameTime
|
|
423
|
+
});
|
|
424
|
+
};
|
|
425
|
+
const updatePlayerPlayCount = async (session) => {
|
|
426
|
+
if (!session.channelId)
|
|
427
|
+
return;
|
|
428
|
+
const player = await getPlayerData(session);
|
|
429
|
+
player.playCount += 1;
|
|
430
|
+
player.lastGameTime = Date.now();
|
|
431
|
+
await savePlayerData(session, player);
|
|
432
|
+
};
|
|
433
|
+
const generateTotalRankText = async (session) => {
|
|
434
|
+
if (!session.channelId)
|
|
435
|
+
return cfg.rank.messages.empty;
|
|
436
|
+
const players = await ctx.database.get('game_mini_player', { guildId: session.channelId });
|
|
437
|
+
if (players.length === 0) {
|
|
438
|
+
return cfg.rank.messages.empty;
|
|
439
|
+
}
|
|
440
|
+
const sortedPlayers = players.sort((a, b) => b.score - a.score);
|
|
441
|
+
let rankText = cfg.rank.messages.title + '\n';
|
|
442
|
+
const displayCount = Math.min(cfg.rank.maxDisplay, sortedPlayers.length);
|
|
443
|
+
for (let i = 0; i < displayCount; i++) {
|
|
444
|
+
const player = sortedPlayers[i];
|
|
445
|
+
rankText += cfg.rank.messages.playerInfo
|
|
446
|
+
.replace('{0}', String(i + 1))
|
|
447
|
+
.replace('{1}', player.name)
|
|
448
|
+
.replace('{2}', String(player.score))
|
|
449
|
+
.replace('{3}', String(player.correctCount))
|
|
450
|
+
.replace('{4}', String(player.playCount)) + '\n';
|
|
451
|
+
}
|
|
452
|
+
if (cfg.rank.messages.showTotalStats) {
|
|
453
|
+
const totalScore = players.reduce((sum, p) => sum + p.score, 0);
|
|
454
|
+
const totalCorrect = players.reduce((sum, p) => sum + p.correctCount, 0);
|
|
455
|
+
const totalPlay = players.reduce((sum, p) => sum + p.playCount, 0);
|
|
456
|
+
rankText += cfg.rank.messages.totalStats
|
|
457
|
+
.replace('{0}', String(players.length))
|
|
458
|
+
.replace('{1}', String(totalScore))
|
|
459
|
+
.replace('{2}', String(totalCorrect))
|
|
460
|
+
.replace('{3}', String(totalPlay));
|
|
461
|
+
}
|
|
462
|
+
return rankText;
|
|
463
|
+
};
|
|
464
|
+
const checkGameRunning = (s, t) => {
|
|
465
|
+
if (t !== 'guessNumber' && s.guessNumber.started)
|
|
466
|
+
return true;
|
|
467
|
+
if (t !== 'wzHero' && s.wzHero.started)
|
|
468
|
+
return true;
|
|
469
|
+
if (t !== 'chengyuImage' && s.chengyuImage.started)
|
|
470
|
+
return true;
|
|
471
|
+
if (t !== 'chengyuJielong' && s.chengyuJielong.started)
|
|
472
|
+
return true;
|
|
473
|
+
if (t !== 'calc24' && s.calc24.started)
|
|
474
|
+
return true;
|
|
475
|
+
return false;
|
|
476
|
+
};
|
|
477
|
+
const clearGameTimer = (state) => {
|
|
478
|
+
if (state.stopTimer)
|
|
479
|
+
clearTimeout(state.stopTimer);
|
|
480
|
+
if (state.autoPlayTimer)
|
|
481
|
+
clearTimeout(state.autoPlayTimer);
|
|
482
|
+
};
|
|
483
|
+
const clearAllTimers = (st) => {
|
|
484
|
+
clearGameTimer(st.guessNumber);
|
|
485
|
+
clearGameTimer(st.wzHero);
|
|
486
|
+
clearGameTimer(st.chengyuImage);
|
|
487
|
+
clearGameTimer(st.chengyuJielong);
|
|
488
|
+
clearGameTimer(st.calc24);
|
|
489
|
+
};
|
|
490
|
+
const initState = (key) => {
|
|
491
|
+
const s = {
|
|
492
|
+
guessNumber: {
|
|
493
|
+
started: false,
|
|
494
|
+
totalRounds: cfg.guessNumber.totalRounds,
|
|
495
|
+
currentRound: 0,
|
|
496
|
+
players: {},
|
|
497
|
+
participants: [],
|
|
498
|
+
target: 0,
|
|
499
|
+
currentMin: cfg.guessNumber.min,
|
|
500
|
+
currentMax: cfg.guessNumber.max,
|
|
501
|
+
botGuess: []
|
|
502
|
+
},
|
|
503
|
+
wzHero: {
|
|
504
|
+
started: false,
|
|
505
|
+
totalRounds: cfg.wzHero.totalRounds,
|
|
506
|
+
currentRound: 0,
|
|
507
|
+
players: {},
|
|
508
|
+
participants: [],
|
|
509
|
+
difficulty: cfg.wzHero.defaultDifficulty,
|
|
510
|
+
botAnswered: false,
|
|
511
|
+
lastHint: '',
|
|
512
|
+
currentHeroId: '',
|
|
513
|
+
currentAnswer: ''
|
|
514
|
+
},
|
|
515
|
+
chengyuImage: {
|
|
516
|
+
started: false,
|
|
517
|
+
totalRounds: cfg.chengyuImage.totalRounds,
|
|
518
|
+
currentRound: 0,
|
|
519
|
+
players: {},
|
|
520
|
+
participants: [],
|
|
521
|
+
currentId: '',
|
|
522
|
+
currentPage: 1,
|
|
523
|
+
options: [],
|
|
524
|
+
answer: ''
|
|
525
|
+
},
|
|
526
|
+
chengyuJielong: {
|
|
527
|
+
started: false,
|
|
528
|
+
totalRounds: cfg.chengyuJielong.totalRounds,
|
|
529
|
+
currentRound: 0,
|
|
530
|
+
players: {},
|
|
531
|
+
participants: [],
|
|
532
|
+
lastChar: '',
|
|
533
|
+
botTurn: true,
|
|
534
|
+
autoPlayCount: 0,
|
|
535
|
+
hasTriggeredAutoPlay: false,
|
|
536
|
+
lastActiveTime: Date.now(),
|
|
537
|
+
jielongCount: 0
|
|
538
|
+
},
|
|
539
|
+
calc24: {
|
|
540
|
+
started: false,
|
|
541
|
+
totalRounds: cfg.calc24.totalRounds,
|
|
542
|
+
currentRound: 0,
|
|
543
|
+
players: {},
|
|
544
|
+
participants: [],
|
|
545
|
+
difficulty: cfg.calc24.defaultDifficulty,
|
|
546
|
+
numbers: [],
|
|
547
|
+
playerAnswer: '',
|
|
548
|
+
solved: false,
|
|
549
|
+
availableNumbers: []
|
|
550
|
+
}
|
|
551
|
+
};
|
|
552
|
+
gameStates.set(key, s);
|
|
553
|
+
return s;
|
|
554
|
+
};
|
|
555
|
+
const isFourCharIdiom = (text) => {
|
|
556
|
+
const t = text.trim();
|
|
557
|
+
return /^[\u4e00-\u9fa5]{4}$/.test(t);
|
|
558
|
+
};
|
|
559
|
+
const generateGameRankText = (players, rankTitle, rankEmpty) => {
|
|
560
|
+
const playerList = Object.values(players);
|
|
561
|
+
if (playerList.length === 0) {
|
|
562
|
+
return `${rankTitle}\n${rankEmpty}`;
|
|
563
|
+
}
|
|
564
|
+
const sortedPlayers = playerList.sort((a, b) => b.score - a.score);
|
|
565
|
+
let rankText = `${rankTitle}\n`;
|
|
566
|
+
sortedPlayers.forEach((player, index) => {
|
|
567
|
+
rankText += `${index + 1}. ${player.name} - 得分:${player.score}分\n`;
|
|
568
|
+
});
|
|
569
|
+
return rankText.trim();
|
|
570
|
+
};
|
|
571
|
+
const clearGameData = (gameState, showRank = false, session, rankTitle, rankEmpty) => {
|
|
572
|
+
if (showRank && session && session.channelId && rankTitle && rankEmpty) {
|
|
573
|
+
session.send(generateGameRankText(gameState.players, rankTitle, rankEmpty));
|
|
574
|
+
}
|
|
575
|
+
gameState.players = {};
|
|
576
|
+
gameState.participants = [];
|
|
577
|
+
gameState.currentRound = 0;
|
|
578
|
+
gameState.started = false;
|
|
579
|
+
clearGameTimer(gameState);
|
|
580
|
+
};
|
|
581
|
+
const setupAutoStop = (session, state, gameType, endMsg, showRank, rankTitle, rankEmpty) => {
|
|
582
|
+
clearGameTimer(state);
|
|
583
|
+
let inactiveTime = 60;
|
|
584
|
+
if (gameType === 'guessNumber')
|
|
585
|
+
inactiveTime = cfg.guessNumber.autoStopInactiveTime;
|
|
586
|
+
else if (gameType === 'wzHero')
|
|
587
|
+
inactiveTime = cfg.wzHero.autoStopInactiveTime;
|
|
588
|
+
else if (gameType === 'chengyuImage')
|
|
589
|
+
inactiveTime = cfg.chengyuImage.autoStopInactiveTime;
|
|
590
|
+
else if (gameType === 'chengyuJielong')
|
|
591
|
+
inactiveTime = cfg.chengyuJielong.autoStopInactiveTime;
|
|
592
|
+
else if (gameType === 'calc24')
|
|
593
|
+
inactiveTime = cfg.calc24.autoStopInactiveTime;
|
|
594
|
+
if (inactiveTime <= 0)
|
|
595
|
+
return;
|
|
596
|
+
state.stopTimer = setTimeout(() => {
|
|
597
|
+
clearGameData(state, showRank, session, rankTitle, rankEmpty);
|
|
598
|
+
session.send(endMsg);
|
|
599
|
+
}, inactiveTime * 1000);
|
|
600
|
+
};
|
|
601
|
+
const calculate24 = (numbers) => {
|
|
602
|
+
if (numbers.length === 1)
|
|
603
|
+
return Math.abs(numbers[0] - 24) < 0.001;
|
|
604
|
+
for (let i = 0; i < numbers.length; i++) {
|
|
605
|
+
for (let j = 0; j < numbers.length; j++) {
|
|
606
|
+
if (i === j)
|
|
607
|
+
continue;
|
|
608
|
+
const rest = [];
|
|
609
|
+
for (let k = 0; k < numbers.length; k++) {
|
|
610
|
+
if (k !== i && k !== j)
|
|
611
|
+
rest.push(numbers[k]);
|
|
612
|
+
}
|
|
613
|
+
const a = numbers[i];
|
|
614
|
+
const b = numbers[j];
|
|
615
|
+
if (calculate24([...rest, a + b]))
|
|
616
|
+
return true;
|
|
617
|
+
if (calculate24([...rest, a - b]))
|
|
618
|
+
return true;
|
|
619
|
+
if (calculate24([...rest, b - a]))
|
|
620
|
+
return true;
|
|
621
|
+
if (calculate24([...rest, a * b]))
|
|
622
|
+
return true;
|
|
623
|
+
if (b !== 0 && calculate24([...rest, a / b]))
|
|
624
|
+
return true;
|
|
625
|
+
if (a !== 0 && calculate24([...rest, b / a]))
|
|
626
|
+
return true;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
return false;
|
|
630
|
+
};
|
|
631
|
+
const generateSolvable24Numbers = (min, max) => {
|
|
632
|
+
const maxAttempts = 1000;
|
|
633
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
634
|
+
const numbers = [
|
|
635
|
+
koishi_1.Random.int(min, max + 1),
|
|
636
|
+
koishi_1.Random.int(min, max + 1),
|
|
637
|
+
koishi_1.Random.int(min, max + 1),
|
|
638
|
+
koishi_1.Random.int(min, max + 1)
|
|
639
|
+
];
|
|
640
|
+
if (calculate24([...numbers])) {
|
|
641
|
+
return numbers;
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
return [6, 4, 3, 1];
|
|
645
|
+
};
|
|
646
|
+
const evaluateExpression = (expr) => {
|
|
647
|
+
try {
|
|
648
|
+
let cleanExpr = expr.replace(/\s+/g, '');
|
|
649
|
+
cleanExpr = cleanExpr.replace(/[×xX]/g, '*');
|
|
650
|
+
cleanExpr = cleanExpr.replace(/[÷/]/g, '/');
|
|
651
|
+
cleanExpr = cleanExpr.replace(/\/\//g, '/');
|
|
652
|
+
if (!/^[\d\+\-\*\/\(\)\[\]\{\}]+$/.test(cleanExpr)) {
|
|
653
|
+
return null;
|
|
654
|
+
}
|
|
655
|
+
const normalizedExpr = cleanExpr.replace(/[\[\{]/g, '(').replace(/[\]\}]/g, ')');
|
|
656
|
+
const func = new Function('return ' + normalizedExpr);
|
|
657
|
+
const result = func();
|
|
658
|
+
if (typeof result === 'number' && isFinite(result)) {
|
|
659
|
+
return result;
|
|
660
|
+
}
|
|
661
|
+
return null;
|
|
662
|
+
}
|
|
663
|
+
catch {
|
|
664
|
+
return null;
|
|
665
|
+
}
|
|
666
|
+
};
|
|
470
667
|
const refreshActive = (st) => {
|
|
471
668
|
st.chengyuJielong.lastActiveTime = Date.now();
|
|
472
669
|
};
|
|
@@ -476,7 +673,7 @@ function apply(ctx, cfg) {
|
|
|
476
673
|
doAutoPlay(session, key, st);
|
|
477
674
|
return;
|
|
478
675
|
}
|
|
479
|
-
if (!cfg.chengyuJielong.
|
|
676
|
+
if (!cfg.chengyuJielong.botParticipate)
|
|
480
677
|
return;
|
|
481
678
|
if (st.chengyuJielong.hasTriggeredAutoPlay)
|
|
482
679
|
return;
|
|
@@ -491,10 +688,9 @@ function apply(ctx, cfg) {
|
|
|
491
688
|
if (st.chengyuJielong.hasTriggeredAutoPlay)
|
|
492
689
|
return;
|
|
493
690
|
if (st.chengyuJielong.autoPlayCount >= cfg.chengyuJielong.autoPlayMaxCount) {
|
|
494
|
-
session.send(d.chengyuJielong.autoPlayTooMany.replace('{0}', String(cfg.chengyuJielong.autoPlayMaxCount)));
|
|
495
691
|
st.chengyuJielong.hasTriggeredAutoPlay = true;
|
|
496
692
|
gameStates.set(key, st);
|
|
497
|
-
setupAutoStop(session, st.chengyuJielong,
|
|
693
|
+
setupAutoStop(session, st.chengyuJielong, 'chengyuJielong', d.chengyuJielong.autoStop, cfg.chengyuJielong.showRank, d.chengyuJielong.rankTitle, d.chengyuJielong.rankEmpty);
|
|
498
694
|
return;
|
|
499
695
|
}
|
|
500
696
|
st.chengyuJielong.hasTriggeredAutoPlay = true;
|
|
@@ -516,8 +712,9 @@ function apply(ctx, cfg) {
|
|
|
516
712
|
let m = '';
|
|
517
713
|
if (dt.code === 200 && dt.data?.system) {
|
|
518
714
|
const sys = dt.data.system;
|
|
519
|
-
m = d.chengyuJielong.botTurn.replace('{0}', sys.idiom)
|
|
715
|
+
m = d.chengyuJielong.botTurn.replace('{0}', sys.idiom);
|
|
520
716
|
st.chengyuJielong.lastChar = dt.data.current_char || '';
|
|
717
|
+
st.chengyuJielong.jielongCount += 1;
|
|
521
718
|
}
|
|
522
719
|
else {
|
|
523
720
|
m = dt.msg || d.chengyuJielong.botWin;
|
|
@@ -528,7 +725,7 @@ function apply(ctx, cfg) {
|
|
|
528
725
|
await session.send(m);
|
|
529
726
|
await session.send(d.chengyuJielong.gameEnd);
|
|
530
727
|
if (cfg.chengyuJielong.showRank && !isPrivate(session)) {
|
|
531
|
-
const rankText =
|
|
728
|
+
const rankText = generateGameRankText(st.chengyuJielong.players, d.chengyuJielong.rankTitle, d.chengyuJielong.rankEmpty);
|
|
532
729
|
await session.send(rankText);
|
|
533
730
|
}
|
|
534
731
|
clearGameData(st.chengyuJielong);
|
|
@@ -539,34 +736,63 @@ function apply(ctx, cfg) {
|
|
|
539
736
|
m += '\n' + d.chengyuJielong.roundEnd.replace('{0}', st.chengyuJielong.currentRound.toString()).replace('{1}', (st.chengyuJielong.totalRounds - st.chengyuJielong.currentRound).toString());
|
|
540
737
|
}
|
|
541
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(m);
|
|
743
|
+
await session.send(d.chengyuJielong.gameEnd);
|
|
744
|
+
if (cfg.chengyuJielong.showRank && !isPrivate(session)) {
|
|
745
|
+
const rankText = generateGameRankText(st.chengyuJielong.players, d.chengyuJielong.rankTitle, d.chengyuJielong.rankEmpty);
|
|
746
|
+
await session.send(rankText);
|
|
747
|
+
}
|
|
748
|
+
clearGameData(st.chengyuJielong);
|
|
749
|
+
gameStates.set(key, st);
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
542
752
|
await session.send(m);
|
|
543
753
|
}
|
|
544
754
|
catch (error) {
|
|
545
755
|
await session.send(d.chengyuJielong.apiError);
|
|
546
756
|
}
|
|
547
757
|
gameStates.set(key, st);
|
|
548
|
-
setupAutoStop(session, st.chengyuJielong,
|
|
758
|
+
setupAutoStop(session, st.chengyuJielong, 'chengyuJielong', d.chengyuJielong.autoStop, cfg.chengyuJielong.showRank, d.chengyuJielong.rankTitle, d.chengyuJielong.rankEmpty);
|
|
549
759
|
};
|
|
550
760
|
ctx.middleware(async (session, next) => {
|
|
551
761
|
if (!session.content)
|
|
552
762
|
return next();
|
|
553
763
|
const key = getSessionKey(session);
|
|
554
|
-
const st = gameStates.get(key) || initState(key
|
|
555
|
-
if (isPrivate(session)
|
|
556
|
-
|
|
764
|
+
const st = gameStates.get(key) || initState(key);
|
|
765
|
+
if (isPrivate(session)) {
|
|
766
|
+
const gameActive = st.guessNumber.started || st.wzHero.started || st.chengyuImage.started || st.chengyuJielong.started || st.calc24.started;
|
|
767
|
+
if (gameActive) {
|
|
768
|
+
if (st.guessNumber.started && !canPlayPrivate('guessNumber'))
|
|
769
|
+
return next();
|
|
770
|
+
if (st.wzHero.started && !canPlayPrivate('wzHero'))
|
|
771
|
+
return next();
|
|
772
|
+
if (st.chengyuImage.started && !canPlayPrivate('chengyuImage'))
|
|
773
|
+
return next();
|
|
774
|
+
if (st.chengyuJielong.started && !canPlayPrivate('chengyuJielong'))
|
|
775
|
+
return next();
|
|
776
|
+
if (st.calc24.started && !canPlayPrivate('calc24'))
|
|
777
|
+
return next();
|
|
778
|
+
}
|
|
779
|
+
}
|
|
557
780
|
const content = session.content.trim();
|
|
558
781
|
const playerKey = `${session.platform}_${session.userId || 'unknown'}`;
|
|
559
782
|
if (cfg.enableChengyuJielong && st.chengyuJielong.started) {
|
|
560
783
|
refreshActive(st);
|
|
561
784
|
clearGameTimer(st.chengyuJielong);
|
|
562
785
|
if (!st.chengyuJielong.players[playerKey]) {
|
|
563
|
-
|
|
786
|
+
const playerData = await getPlayerData(session);
|
|
787
|
+
st.chengyuJielong.players[playerKey] = playerData;
|
|
564
788
|
st.chengyuJielong.participants.push(playerKey);
|
|
789
|
+
await updatePlayerPlayCount(session);
|
|
565
790
|
}
|
|
566
791
|
if (!isFourCharIdiom(content)) {
|
|
567
|
-
|
|
792
|
+
await session.send(d.chengyuJielong.notIdiom);
|
|
793
|
+
setupAutoStop(session, st.chengyuJielong, 'chengyuJielong', d.chengyuJielong.autoStop, cfg.chengyuJielong.showRank, d.chengyuJielong.rankTitle, d.chengyuJielong.rankEmpty);
|
|
568
794
|
scheduleAutoPlay(session, key, st);
|
|
569
|
-
return
|
|
795
|
+
return;
|
|
570
796
|
}
|
|
571
797
|
try {
|
|
572
798
|
const intUserId = getIntUserId(session);
|
|
@@ -585,27 +811,41 @@ function apply(ctx, cfg) {
|
|
|
585
811
|
if (dt.code === 200) {
|
|
586
812
|
m = dt.msg + '\n';
|
|
587
813
|
if (dt.data?.user) {
|
|
588
|
-
|
|
814
|
+
m += d.chengyuJielong.correct + '\n';
|
|
815
|
+
m += `你的成语:${dt.data.user.idiom}\n`;
|
|
816
|
+
st.chengyuJielong.players[playerKey].score += cfg.chengyuJielong.rewardScore;
|
|
589
817
|
st.chengyuJielong.players[playerKey].correctCount += 1;
|
|
590
|
-
|
|
591
|
-
m += `你的成语:${dt.data.user.idiom}(${dt.data.user.pinyin})\n释义:${dt.data.user.meaning}\n`;
|
|
818
|
+
await savePlayerData(session, st.chengyuJielong.players[playerKey]);
|
|
592
819
|
}
|
|
593
820
|
else {
|
|
594
|
-
|
|
595
|
-
m += d.chengyuJielong.wrong.replace('{1}', st.chengyuJielong.players[playerKey].score.toString()) + '\n';
|
|
821
|
+
m += d.chengyuJielong.wrong + '\n';
|
|
596
822
|
}
|
|
597
823
|
if (dt.data?.system) {
|
|
598
|
-
m += `我的接龙:${dt.data.system.idiom}
|
|
824
|
+
m += `我的接龙:${dt.data.system.idiom}`;
|
|
599
825
|
st.chengyuJielong.lastChar = dt.data.current_char || '';
|
|
826
|
+
st.chengyuJielong.jielongCount += 1;
|
|
600
827
|
}
|
|
601
828
|
st.chengyuJielong.currentRound += 1;
|
|
829
|
+
if (cfg.chengyuJielong.maxRounds > 0 && st.chengyuJielong.jielongCount >= cfg.chengyuJielong.maxRounds) {
|
|
830
|
+
st.chengyuJielong.started = false;
|
|
831
|
+
clearAllTimers(st);
|
|
832
|
+
await session.send(m);
|
|
833
|
+
await session.send(d.chengyuJielong.gameEnd);
|
|
834
|
+
if (cfg.chengyuJielong.showRank && !isPrivate(session)) {
|
|
835
|
+
const rankText = generateGameRankText(st.chengyuJielong.players, d.chengyuJielong.rankTitle, d.chengyuJielong.rankEmpty);
|
|
836
|
+
await session.send(rankText);
|
|
837
|
+
}
|
|
838
|
+
clearGameData(st.chengyuJielong);
|
|
839
|
+
gameStates.set(key, st);
|
|
840
|
+
return;
|
|
841
|
+
}
|
|
602
842
|
if (st.chengyuJielong.currentRound > st.chengyuJielong.totalRounds) {
|
|
603
843
|
st.chengyuJielong.started = false;
|
|
604
844
|
clearAllTimers(st);
|
|
605
845
|
await session.send(m);
|
|
606
846
|
await session.send(d.chengyuJielong.gameEnd);
|
|
607
847
|
if (cfg.chengyuJielong.showRank && !isPrivate(session)) {
|
|
608
|
-
const rankText =
|
|
848
|
+
const rankText = generateGameRankText(st.chengyuJielong.players, d.chengyuJielong.rankTitle, d.chengyuJielong.rankEmpty);
|
|
609
849
|
await session.send(rankText);
|
|
610
850
|
}
|
|
611
851
|
clearGameData(st.chengyuJielong);
|
|
@@ -614,20 +854,19 @@ function apply(ctx, cfg) {
|
|
|
614
854
|
m += '\n' + d.chengyuJielong.roundEnd.replace('{0}', st.chengyuJielong.currentRound.toString()).replace('{1}', (st.chengyuJielong.totalRounds - st.chengyuJielong.currentRound).toString());
|
|
615
855
|
await session.send(m);
|
|
616
856
|
st.chengyuJielong.hasTriggeredAutoPlay = false;
|
|
617
|
-
setupAutoStop(session, st.chengyuJielong,
|
|
857
|
+
setupAutoStop(session, st.chengyuJielong, 'chengyuJielong', d.chengyuJielong.autoStop, cfg.chengyuJielong.showRank, d.chengyuJielong.rankTitle, d.chengyuJielong.rankEmpty);
|
|
618
858
|
scheduleAutoPlay(session, key, st);
|
|
619
859
|
}
|
|
620
860
|
}
|
|
621
861
|
else {
|
|
622
862
|
m = dt.msg || '接龙失败';
|
|
623
|
-
|
|
624
|
-
m += '\n' + d.chengyuJielong.wrong.replace('{1}', st.chengyuJielong.players[playerKey].score.toString());
|
|
863
|
+
m += '\n' + d.chengyuJielong.wrong;
|
|
625
864
|
await session.send(m);
|
|
626
865
|
}
|
|
627
866
|
}
|
|
628
867
|
catch (error) {
|
|
629
868
|
await session.send(d.chengyuJielong.apiError);
|
|
630
|
-
setupAutoStop(session, st.chengyuJielong,
|
|
869
|
+
setupAutoStop(session, st.chengyuJielong, 'chengyuJielong', d.chengyuJielong.autoStop, cfg.chengyuJielong.showRank, d.chengyuJielong.rankTitle, d.chengyuJielong.rankEmpty);
|
|
631
870
|
scheduleAutoPlay(session, key, st);
|
|
632
871
|
}
|
|
633
872
|
gameStates.set(key, st);
|
|
@@ -636,8 +875,10 @@ function apply(ctx, cfg) {
|
|
|
636
875
|
if (cfg.enableChengyuImage && st.chengyuImage.started) {
|
|
637
876
|
clearGameTimer(st.chengyuImage);
|
|
638
877
|
if (!st.chengyuImage.players[playerKey]) {
|
|
639
|
-
|
|
878
|
+
const playerData = await getPlayerData(session);
|
|
879
|
+
st.chengyuImage.players[playerKey] = playerData;
|
|
640
880
|
st.chengyuImage.participants.push(playerKey);
|
|
881
|
+
await updatePlayerPlayCount(session);
|
|
641
882
|
}
|
|
642
883
|
if (content === '提示') {
|
|
643
884
|
try {
|
|
@@ -660,12 +901,13 @@ function apply(ctx, cfg) {
|
|
|
660
901
|
catch (error) {
|
|
661
902
|
await session.send(d.chengyuImage.hintError);
|
|
662
903
|
}
|
|
663
|
-
setupAutoStop(session, st.chengyuImage,
|
|
904
|
+
setupAutoStop(session, st.chengyuImage, 'chengyuImage', d.chengyuImage.autoStop, cfg.chengyuImage.showRank, d.chengyuImage.rankTitle, d.chengyuImage.rankEmpty);
|
|
664
905
|
return;
|
|
665
906
|
}
|
|
666
907
|
if (!isFourCharIdiom(content)) {
|
|
667
|
-
|
|
668
|
-
|
|
908
|
+
await session.send('请输入4字成语');
|
|
909
|
+
setupAutoStop(session, st.chengyuImage, 'chengyuImage', d.chengyuImage.autoStop, cfg.chengyuImage.showRank, d.chengyuImage.rankTitle, d.chengyuImage.rankEmpty);
|
|
910
|
+
return;
|
|
669
911
|
}
|
|
670
912
|
try {
|
|
671
913
|
const r = await axios_1.default.get('https://jcy.lvlong.xyz/api/api/chengyu.php', {
|
|
@@ -680,8 +922,9 @@ function apply(ctx, cfg) {
|
|
|
680
922
|
if (dt.success) {
|
|
681
923
|
let reply = '';
|
|
682
924
|
if (dt.message.includes('正确') || dt.message.includes('答对')) {
|
|
683
|
-
st.chengyuImage.players[playerKey].score +=
|
|
925
|
+
st.chengyuImage.players[playerKey].score += cfg.chengyuImage.rewardScore;
|
|
684
926
|
st.chengyuImage.players[playerKey].correctCount += 1;
|
|
927
|
+
await savePlayerData(session, st.chengyuImage.players[playerKey]);
|
|
685
928
|
reply = d.chengyuImage.correct.replace('{0}', st.chengyuImage.players[playerKey].score.toString());
|
|
686
929
|
st.chengyuImage.currentRound += 1;
|
|
687
930
|
if (st.chengyuImage.currentRound > st.chengyuImage.totalRounds) {
|
|
@@ -690,7 +933,7 @@ function apply(ctx, cfg) {
|
|
|
690
933
|
await session.send(reply);
|
|
691
934
|
await session.send(d.chengyuImage.gameEnd);
|
|
692
935
|
if (cfg.chengyuImage.showRank && !isPrivate(session)) {
|
|
693
|
-
const rankText =
|
|
936
|
+
const rankText = generateGameRankText(st.chengyuImage.players, d.chengyuImage.rankTitle, d.chengyuImage.rankEmpty);
|
|
694
937
|
await session.send(rankText);
|
|
695
938
|
}
|
|
696
939
|
clearGameData(st.chengyuImage);
|
|
@@ -720,7 +963,7 @@ function apply(ctx, cfg) {
|
|
|
720
963
|
st.chengyuImage.started = false;
|
|
721
964
|
clearGameTimer(st.chengyuImage);
|
|
722
965
|
if (cfg.chengyuImage.showRank && !isPrivate(session)) {
|
|
723
|
-
const rankText =
|
|
966
|
+
const rankText = generateGameRankText(st.chengyuImage.players, d.chengyuImage.rankTitle, d.chengyuImage.rankEmpty);
|
|
724
967
|
await session.send(rankText);
|
|
725
968
|
}
|
|
726
969
|
clearGameData(st.chengyuImage);
|
|
@@ -740,18 +983,20 @@ function apply(ctx, cfg) {
|
|
|
740
983
|
catch (error) {
|
|
741
984
|
await session.send(d.chengyuImage.apiError);
|
|
742
985
|
}
|
|
743
|
-
setupAutoStop(session, st.chengyuImage,
|
|
986
|
+
setupAutoStop(session, st.chengyuImage, 'chengyuImage', d.chengyuImage.autoStop, cfg.chengyuImage.showRank, d.chengyuImage.rankTitle, d.chengyuImage.rankEmpty);
|
|
744
987
|
gameStates.set(key, st);
|
|
745
988
|
return;
|
|
746
989
|
}
|
|
747
990
|
if (cfg.enableWzHero && st.wzHero.started) {
|
|
748
991
|
clearGameTimer(st.wzHero);
|
|
749
992
|
if (!st.wzHero.players[playerKey]) {
|
|
750
|
-
|
|
993
|
+
const playerData = await getPlayerData(session);
|
|
994
|
+
st.wzHero.players[playerKey] = playerData;
|
|
751
995
|
st.wzHero.participants.push(playerKey);
|
|
996
|
+
await updatePlayerPlayCount(session);
|
|
752
997
|
}
|
|
753
998
|
if (content === '结束') {
|
|
754
|
-
clearGameData(st.wzHero);
|
|
999
|
+
clearGameData(st.wzHero, cfg.wzHero.showRank && !isPrivate(session), session, d.wzHero.rankTitle, d.wzHero.rankEmpty);
|
|
755
1000
|
await session.send(d.wzHero.stop);
|
|
756
1001
|
gameStates.set(key, st);
|
|
757
1002
|
return;
|
|
@@ -765,8 +1010,9 @@ function apply(ctx, cfg) {
|
|
|
765
1010
|
let text = `${dt.message || ''}\n${dt.hint || ''}\n剩余提示次数:${dt.remaining_hints}\n${dt.guide || ''}`;
|
|
766
1011
|
text = text.replace(/\\n/g, '\n');
|
|
767
1012
|
if (content !== '提示' && dt.message.includes('正确')) {
|
|
768
|
-
st.wzHero.players[playerKey].score +=
|
|
1013
|
+
st.wzHero.players[playerKey].score += cfg.wzHero.rewardScore;
|
|
769
1014
|
st.wzHero.players[playerKey].correctCount += 1;
|
|
1015
|
+
await savePlayerData(session, st.wzHero.players[playerKey]);
|
|
770
1016
|
text += '\n' + d.wzHero.correct.replace('{0}', st.wzHero.players[playerKey].score.toString());
|
|
771
1017
|
st.wzHero.currentRound += 1;
|
|
772
1018
|
if (st.wzHero.currentRound > st.wzHero.totalRounds) {
|
|
@@ -775,7 +1021,7 @@ function apply(ctx, cfg) {
|
|
|
775
1021
|
await session.send(text);
|
|
776
1022
|
await session.send(d.wzHero.gameEnd);
|
|
777
1023
|
if (cfg.wzHero.showRank && !isPrivate(session)) {
|
|
778
|
-
const rankText =
|
|
1024
|
+
const rankText = generateGameRankText(st.wzHero.players, d.wzHero.rankTitle, d.wzHero.rankEmpty);
|
|
779
1025
|
await session.send(rankText);
|
|
780
1026
|
}
|
|
781
1027
|
clearGameData(st.wzHero);
|
|
@@ -808,37 +1054,55 @@ function apply(ctx, cfg) {
|
|
|
808
1054
|
catch (error) {
|
|
809
1055
|
await session.send(d.wzHero.apiError);
|
|
810
1056
|
}
|
|
811
|
-
setupAutoStop(session, st.wzHero,
|
|
1057
|
+
setupAutoStop(session, st.wzHero, 'wzHero', d.wzHero.autoStop, cfg.wzHero.showRank, d.wzHero.rankTitle, d.wzHero.rankEmpty);
|
|
812
1058
|
gameStates.set(key, st);
|
|
813
1059
|
return;
|
|
814
1060
|
}
|
|
815
1061
|
if (cfg.enableNumberGuess && st.guessNumber.started) {
|
|
816
1062
|
clearGameTimer(st.guessNumber);
|
|
817
1063
|
if (!st.guessNumber.players[playerKey]) {
|
|
818
|
-
|
|
1064
|
+
const playerData = await getPlayerData(session);
|
|
1065
|
+
st.guessNumber.players[playerKey] = playerData;
|
|
819
1066
|
st.guessNumber.participants.push(playerKey);
|
|
1067
|
+
await updatePlayerPlayCount(session);
|
|
820
1068
|
}
|
|
821
1069
|
if (content === '结束') {
|
|
822
|
-
clearGameData(st.guessNumber);
|
|
1070
|
+
clearGameData(st.guessNumber, cfg.guessNumber.showRank && !isPrivate(session), session, d.guessNumber.rankTitle, d.guessNumber.rankEmpty);
|
|
823
1071
|
await session.send(d.guessNumber.stop);
|
|
824
1072
|
gameStates.set(key, st);
|
|
825
1073
|
return;
|
|
826
1074
|
}
|
|
827
1075
|
const num = parseInt(content);
|
|
828
1076
|
if (isNaN(num)) {
|
|
829
|
-
setupAutoStop(session, st.guessNumber,
|
|
1077
|
+
setupAutoStop(session, st.guessNumber, 'guessNumber', d.guessNumber.autoStop, cfg.guessNumber.showRank, d.guessNumber.rankTitle, d.guessNumber.rankEmpty);
|
|
830
1078
|
return next();
|
|
831
1079
|
}
|
|
1080
|
+
if (num < st.guessNumber.currentMin || num > st.guessNumber.currentMax) {
|
|
1081
|
+
await session.send(d.guessNumber.outOfRange.replace('{0}', st.guessNumber.currentMin.toString()).replace('{1}', st.guessNumber.currentMax.toString()));
|
|
1082
|
+
setupAutoStop(session, st.guessNumber, 'guessNumber', d.guessNumber.autoStop, cfg.guessNumber.showRank, d.guessNumber.rankTitle, d.guessNumber.rankEmpty);
|
|
1083
|
+
return;
|
|
1084
|
+
}
|
|
832
1085
|
if (num === st.guessNumber.target) {
|
|
833
|
-
|
|
834
|
-
|
|
1086
|
+
st.guessNumber.players[playerKey].score += cfg.guessNumber.rewardScore;
|
|
1087
|
+
st.guessNumber.players[playerKey].correctCount += 1;
|
|
1088
|
+
await savePlayerData(session, st.guessNumber.players[playerKey]);
|
|
1089
|
+
let message = d.guessNumber.correct;
|
|
1090
|
+
if (cfg.guessNumber.enablePenalty) {
|
|
1091
|
+
Object.keys(st.guessNumber.players).forEach(key => {
|
|
1092
|
+
if (key !== playerKey) {
|
|
1093
|
+
st.guessNumber.players[key].score += cfg.guessNumber.penaltyScore;
|
|
1094
|
+
savePlayerData(session, st.guessNumber.players[key]);
|
|
1095
|
+
}
|
|
1096
|
+
});
|
|
1097
|
+
}
|
|
1098
|
+
await session.send(message);
|
|
835
1099
|
st.guessNumber.currentRound += 1;
|
|
836
1100
|
if (st.guessNumber.currentRound > st.guessNumber.totalRounds) {
|
|
837
1101
|
st.guessNumber.started = false;
|
|
838
1102
|
clearGameTimer(st.guessNumber);
|
|
839
1103
|
await session.send(d.guessNumber.gameEnd);
|
|
840
1104
|
if (cfg.guessNumber.showRank && !isPrivate(session)) {
|
|
841
|
-
const rankText =
|
|
1105
|
+
const rankText = generateGameRankText(st.guessNumber.players, d.guessNumber.rankTitle, d.guessNumber.rankEmpty);
|
|
842
1106
|
await session.send(rankText);
|
|
843
1107
|
}
|
|
844
1108
|
clearGameData(st.guessNumber);
|
|
@@ -857,18 +1121,20 @@ function apply(ctx, cfg) {
|
|
|
857
1121
|
st.guessNumber.currentMax = num - 1;
|
|
858
1122
|
await session.send(d.guessNumber.tooBig.replace('{0}', st.guessNumber.currentMin.toString()).replace('{1}', st.guessNumber.currentMax.toString()));
|
|
859
1123
|
}
|
|
860
|
-
setupAutoStop(session, st.guessNumber,
|
|
1124
|
+
setupAutoStop(session, st.guessNumber, 'guessNumber', d.guessNumber.autoStop, cfg.guessNumber.showRank, d.guessNumber.rankTitle, d.guessNumber.rankEmpty);
|
|
861
1125
|
gameStates.set(key, st);
|
|
862
1126
|
return;
|
|
863
1127
|
}
|
|
864
1128
|
if (cfg.enableCalc24 && st.calc24.started) {
|
|
865
1129
|
clearGameTimer(st.calc24);
|
|
866
1130
|
if (!st.calc24.players[playerKey]) {
|
|
867
|
-
|
|
1131
|
+
const playerData = await getPlayerData(session);
|
|
1132
|
+
st.calc24.players[playerKey] = playerData;
|
|
868
1133
|
st.calc24.participants.push(playerKey);
|
|
1134
|
+
await updatePlayerPlayCount(session);
|
|
869
1135
|
}
|
|
870
1136
|
if (content === '结束') {
|
|
871
|
-
clearGameData(st.calc24);
|
|
1137
|
+
clearGameData(st.calc24, cfg.calc24.showRank && !isPrivate(session), session, d.calc24.rankTitle, d.calc24.rankEmpty);
|
|
872
1138
|
await session.send(d.calc24.stop);
|
|
873
1139
|
gameStates.set(key, st);
|
|
874
1140
|
return;
|
|
@@ -883,19 +1149,20 @@ function apply(ctx, cfg) {
|
|
|
883
1149
|
.replace('{1}', st.calc24.difficulty)
|
|
884
1150
|
.replace('{2}', st.calc24.numbers.join('、')));
|
|
885
1151
|
}
|
|
886
|
-
setupAutoStop(session, st.calc24,
|
|
1152
|
+
setupAutoStop(session, st.calc24, 'calc24', d.calc24.autoStop, cfg.calc24.showRank, d.calc24.rankTitle, d.calc24.rankEmpty);
|
|
887
1153
|
return;
|
|
888
1154
|
}
|
|
889
1155
|
if (st.calc24.solved) {
|
|
890
1156
|
await session.send(d.calc24.solved);
|
|
891
|
-
setupAutoStop(session, st.calc24,
|
|
1157
|
+
setupAutoStop(session, st.calc24, 'calc24', d.calc24.autoStop, cfg.calc24.showRank, d.calc24.rankTitle, d.calc24.rankEmpty);
|
|
892
1158
|
return;
|
|
893
1159
|
}
|
|
894
1160
|
const result = evaluateExpression(content);
|
|
895
1161
|
if (result !== null && Math.abs(result - 24) < 0.001) {
|
|
896
1162
|
await session.send(d.calc24.correct);
|
|
897
|
-
st.calc24.players[playerKey].score +=
|
|
1163
|
+
st.calc24.players[playerKey].score += cfg.calc24.rewardScore;
|
|
898
1164
|
st.calc24.players[playerKey].correctCount += 1;
|
|
1165
|
+
await savePlayerData(session, st.calc24.players[playerKey]);
|
|
899
1166
|
st.calc24.solved = true;
|
|
900
1167
|
st.calc24.currentRound += 1;
|
|
901
1168
|
if (st.calc24.currentRound > st.calc24.totalRounds) {
|
|
@@ -903,7 +1170,7 @@ function apply(ctx, cfg) {
|
|
|
903
1170
|
clearGameTimer(st.calc24);
|
|
904
1171
|
await session.send(d.calc24.gameEnd);
|
|
905
1172
|
if (cfg.calc24.showRank && !isPrivate(session)) {
|
|
906
|
-
const rankText =
|
|
1173
|
+
const rankText = generateGameRankText(st.calc24.players, d.calc24.rankTitle, d.calc24.rankEmpty);
|
|
907
1174
|
await session.send(rankText);
|
|
908
1175
|
}
|
|
909
1176
|
clearGameData(st.calc24);
|
|
@@ -922,75 +1189,7 @@ function apply(ctx, cfg) {
|
|
|
922
1189
|
else {
|
|
923
1190
|
await session.send(d.calc24.wrong);
|
|
924
1191
|
}
|
|
925
|
-
setupAutoStop(session, st.calc24,
|
|
926
|
-
gameStates.set(key, st);
|
|
927
|
-
return;
|
|
928
|
-
}
|
|
929
|
-
if (cfg.enablePasswordLock && st.passwordLock.started) {
|
|
930
|
-
clearGameTimer(st.passwordLock);
|
|
931
|
-
if (!st.passwordLock.players[playerKey]) {
|
|
932
|
-
st.passwordLock.players[playerKey] = getPlayerData(session);
|
|
933
|
-
st.passwordLock.participants.push(playerKey);
|
|
934
|
-
}
|
|
935
|
-
if (content === '结束') {
|
|
936
|
-
clearGameData(st.passwordLock);
|
|
937
|
-
await session.send(d.passwordLock.stop);
|
|
938
|
-
gameStates.set(key, st);
|
|
939
|
-
return;
|
|
940
|
-
}
|
|
941
|
-
if (st.passwordLock.solved) {
|
|
942
|
-
await session.send(d.passwordLock.solved);
|
|
943
|
-
setupAutoStop(session, st.passwordLock, cfg, 'passwordLock', d.passwordLock.autoStop, cfg.passwordLock.showRank);
|
|
944
|
-
return;
|
|
945
|
-
}
|
|
946
|
-
if (!/^\d{4}$/.test(content)) {
|
|
947
|
-
await session.send(d.passwordLock.invalidPassword);
|
|
948
|
-
setupAutoStop(session, st.passwordLock, cfg, 'passwordLock', d.passwordLock.autoStop, cfg.passwordLock.showRank);
|
|
949
|
-
return;
|
|
950
|
-
}
|
|
951
|
-
st.passwordLock.playerGuess = content;
|
|
952
|
-
st.passwordLock.guessTimes += 1;
|
|
953
|
-
await session.send(d.passwordLock.guess.replace('{0}', content).replace('{1}', st.passwordLock.guessTimes.toString()));
|
|
954
|
-
if (content === st.passwordLock.password) {
|
|
955
|
-
const score = 10 - (st.passwordLock.guessTimes - 1);
|
|
956
|
-
await session.send(d.passwordLock.correct.replace('{0}', content).replace('{1}', st.passwordLock.guessTimes.toString()));
|
|
957
|
-
st.passwordLock.players[playerKey].score += score > 0 ? score : 1;
|
|
958
|
-
st.passwordLock.players[playerKey].correctCount += 1;
|
|
959
|
-
st.passwordLock.solved = true;
|
|
960
|
-
st.passwordLock.started = false;
|
|
961
|
-
clearGameTimer(st.passwordLock);
|
|
962
|
-
await session.send(d.passwordLock.gameEnd);
|
|
963
|
-
if (cfg.passwordLock.showRank && !isPrivate(session)) {
|
|
964
|
-
const rankText = generateRankText(st.passwordLock.players);
|
|
965
|
-
await session.send(rankText);
|
|
966
|
-
}
|
|
967
|
-
clearGameData(st.passwordLock);
|
|
968
|
-
}
|
|
969
|
-
else {
|
|
970
|
-
let hint = '';
|
|
971
|
-
if (cfg.passwordLock.showHint) {
|
|
972
|
-
hint = generatePasswordHint(st.passwordLock.password, content);
|
|
973
|
-
await session.send(d.passwordLock.wrong.replace('{0}', hint));
|
|
974
|
-
}
|
|
975
|
-
else {
|
|
976
|
-
await session.send(d.passwordLock.wrong.replace('{0}', ''));
|
|
977
|
-
}
|
|
978
|
-
if (st.passwordLock.guessTimes >= st.passwordLock.maxGuessTimes) {
|
|
979
|
-
await session.send(d.passwordLock.noChance.replace('{0}', st.passwordLock.password));
|
|
980
|
-
st.passwordLock.started = false;
|
|
981
|
-
clearGameTimer(st.passwordLock);
|
|
982
|
-
await session.send(d.passwordLock.gameEnd);
|
|
983
|
-
if (cfg.passwordLock.showRank && !isPrivate(session)) {
|
|
984
|
-
const rankText = generateRankText(st.passwordLock.players);
|
|
985
|
-
await session.send(rankText);
|
|
986
|
-
}
|
|
987
|
-
clearGameData(st.passwordLock);
|
|
988
|
-
}
|
|
989
|
-
else {
|
|
990
|
-
await session.send(`剩余猜测次数:${st.passwordLock.maxGuessTimes - st.passwordLock.guessTimes}`);
|
|
991
|
-
}
|
|
992
|
-
}
|
|
993
|
-
setupAutoStop(session, st.passwordLock, cfg, 'passwordLock', d.passwordLock.autoStop, cfg.passwordLock.showRank);
|
|
1192
|
+
setupAutoStop(session, st.calc24, 'calc24', d.calc24.autoStop, cfg.calc24.showRank, d.calc24.rankTitle, d.calc24.rankEmpty);
|
|
994
1193
|
gameStates.set(key, st);
|
|
995
1194
|
return;
|
|
996
1195
|
}
|
|
@@ -1001,8 +1200,12 @@ function apply(ctx, cfg) {
|
|
|
1001
1200
|
const session = argv.session;
|
|
1002
1201
|
if (!session)
|
|
1003
1202
|
return;
|
|
1203
|
+
if (isPrivate(session) && !canPlayPrivate('guessNumber')) {
|
|
1204
|
+
await session.send('私聊已禁用猜数字游戏');
|
|
1205
|
+
return;
|
|
1206
|
+
}
|
|
1004
1207
|
const key = getSessionKey(session);
|
|
1005
|
-
const st = gameStates.get(key) || initState(key
|
|
1208
|
+
const st = gameStates.get(key) || initState(key);
|
|
1006
1209
|
if (checkGameRunning(st, 'guessNumber')) {
|
|
1007
1210
|
await session.send(d.common.gameRunning);
|
|
1008
1211
|
return;
|
|
@@ -1016,10 +1219,10 @@ function apply(ctx, cfg) {
|
|
|
1016
1219
|
await session.send(d.guessNumber.start.replace('{0}', st.guessNumber.totalRounds.toString()));
|
|
1017
1220
|
await session.send(`猜数字范围:${st.guessNumber.currentMin} - ${st.guessNumber.currentMax}`);
|
|
1018
1221
|
gameStates.set(key, st);
|
|
1019
|
-
setupAutoStop(session, st.guessNumber,
|
|
1222
|
+
setupAutoStop(session, st.guessNumber, 'guessNumber', d.guessNumber.autoStop, cfg.guessNumber.showRank, d.guessNumber.rankTitle, d.guessNumber.rankEmpty);
|
|
1020
1223
|
}
|
|
1021
1224
|
else if (action === '结束') {
|
|
1022
|
-
clearGameData(st.guessNumber);
|
|
1225
|
+
clearGameData(st.guessNumber, cfg.guessNumber.showRank && !isPrivate(session), session, d.guessNumber.rankTitle, d.guessNumber.rankEmpty);
|
|
1023
1226
|
await session.send(d.guessNumber.stop);
|
|
1024
1227
|
gameStates.set(key, st);
|
|
1025
1228
|
}
|
|
@@ -1032,8 +1235,12 @@ function apply(ctx, cfg) {
|
|
|
1032
1235
|
const session = argv.session;
|
|
1033
1236
|
if (!session)
|
|
1034
1237
|
return;
|
|
1238
|
+
if (isPrivate(session) && !canPlayPrivate('wzHero')) {
|
|
1239
|
+
await session.send('私聊已禁用王者英雄猜谜');
|
|
1240
|
+
return;
|
|
1241
|
+
}
|
|
1035
1242
|
const key = getSessionKey(session);
|
|
1036
|
-
const st = gameStates.get(key) || initState(key
|
|
1243
|
+
const st = gameStates.get(key) || initState(key);
|
|
1037
1244
|
if (checkGameRunning(st, 'wzHero')) {
|
|
1038
1245
|
await session.send(d.common.gameRunning);
|
|
1039
1246
|
return;
|
|
@@ -1058,10 +1265,10 @@ function apply(ctx, cfg) {
|
|
|
1058
1265
|
await session.send(d.wzHero.apiError);
|
|
1059
1266
|
}
|
|
1060
1267
|
gameStates.set(key, st);
|
|
1061
|
-
setupAutoStop(session, st.wzHero,
|
|
1268
|
+
setupAutoStop(session, st.wzHero, 'wzHero', d.wzHero.autoStop, cfg.wzHero.showRank, d.wzHero.rankTitle, d.wzHero.rankEmpty);
|
|
1062
1269
|
}
|
|
1063
1270
|
else if (action === '结束') {
|
|
1064
|
-
clearGameData(st.wzHero);
|
|
1271
|
+
clearGameData(st.wzHero, cfg.wzHero.showRank && !isPrivate(session), session, d.wzHero.rankTitle, d.wzHero.rankEmpty);
|
|
1065
1272
|
await session.send(d.wzHero.stop);
|
|
1066
1273
|
gameStates.set(key, st);
|
|
1067
1274
|
}
|
|
@@ -1074,8 +1281,12 @@ function apply(ctx, cfg) {
|
|
|
1074
1281
|
const session = argv.session;
|
|
1075
1282
|
if (!session)
|
|
1076
1283
|
return;
|
|
1284
|
+
if (isPrivate(session) && !canPlayPrivate('chengyuImage')) {
|
|
1285
|
+
await session.send('私聊已禁用看图猜成语');
|
|
1286
|
+
return;
|
|
1287
|
+
}
|
|
1077
1288
|
const key = getSessionKey(session);
|
|
1078
|
-
const st = gameStates.get(key) || initState(key
|
|
1289
|
+
const st = gameStates.get(key) || initState(key);
|
|
1079
1290
|
if (checkGameRunning(st, 'chengyuImage')) {
|
|
1080
1291
|
await session.send(d.common.gameRunning);
|
|
1081
1292
|
return;
|
|
@@ -1106,15 +1317,15 @@ function apply(ctx, cfg) {
|
|
|
1106
1317
|
await session.send(d.chengyuImage.apiError);
|
|
1107
1318
|
}
|
|
1108
1319
|
gameStates.set(key, st);
|
|
1109
|
-
setupAutoStop(session, st.chengyuImage,
|
|
1320
|
+
setupAutoStop(session, st.chengyuImage, 'chengyuImage', d.chengyuImage.autoStop, cfg.chengyuImage.showRank, d.chengyuImage.rankTitle, d.chengyuImage.rankEmpty);
|
|
1110
1321
|
}
|
|
1111
1322
|
else if (action === '结束') {
|
|
1112
|
-
clearGameData(st.chengyuImage);
|
|
1323
|
+
clearGameData(st.chengyuImage, cfg.chengyuImage.showRank && !isPrivate(session), session, d.chengyuImage.rankTitle, d.chengyuImage.rankEmpty);
|
|
1113
1324
|
await session.send(d.chengyuImage.stop);
|
|
1114
1325
|
gameStates.set(key, st);
|
|
1115
1326
|
}
|
|
1116
1327
|
else {
|
|
1117
|
-
await session.send(
|
|
1328
|
+
await session.send('请直接输入答案或 提示');
|
|
1118
1329
|
}
|
|
1119
1330
|
});
|
|
1120
1331
|
ctx.command('成语接龙 <action>', '成语接龙')
|
|
@@ -1122,8 +1333,12 @@ function apply(ctx, cfg) {
|
|
|
1122
1333
|
const session = argv.session;
|
|
1123
1334
|
if (!session)
|
|
1124
1335
|
return;
|
|
1336
|
+
if (isPrivate(session) && !canPlayPrivate('chengyuJielong')) {
|
|
1337
|
+
await session.send('私聊已禁用成语接龙');
|
|
1338
|
+
return;
|
|
1339
|
+
}
|
|
1125
1340
|
const key = getSessionKey(session);
|
|
1126
|
-
const st = gameStates.get(key) || initState(key
|
|
1341
|
+
const st = gameStates.get(key) || initState(key);
|
|
1127
1342
|
if (checkGameRunning(st, 'chengyuJielong')) {
|
|
1128
1343
|
await session.send(d.common.gameRunning);
|
|
1129
1344
|
return;
|
|
@@ -1133,18 +1348,19 @@ function apply(ctx, cfg) {
|
|
|
1133
1348
|
st.chengyuJielong.currentRound = 1;
|
|
1134
1349
|
st.chengyuJielong.hasTriggeredAutoPlay = false;
|
|
1135
1350
|
st.chengyuJielong.autoPlayCount = 0;
|
|
1351
|
+
st.chengyuJielong.jielongCount = 0;
|
|
1136
1352
|
await session.send(d.chengyuJielong.start.replace('{0}', st.chengyuJielong.totalRounds.toString()));
|
|
1137
1353
|
gameStates.set(key, st);
|
|
1138
1354
|
scheduleAutoPlay(session, key, st);
|
|
1139
|
-
setupAutoStop(session, st.chengyuJielong,
|
|
1355
|
+
setupAutoStop(session, st.chengyuJielong, 'chengyuJielong', d.chengyuJielong.autoStop, cfg.chengyuJielong.showRank, d.chengyuJielong.rankTitle, d.chengyuJielong.rankEmpty);
|
|
1140
1356
|
}
|
|
1141
1357
|
else if (action === '结束') {
|
|
1142
|
-
clearGameData(st.chengyuJielong);
|
|
1358
|
+
clearGameData(st.chengyuJielong, cfg.chengyuJielong.showRank && !isPrivate(session), session, d.chengyuJielong.rankTitle, d.chengyuJielong.rankEmpty);
|
|
1143
1359
|
await session.send(d.chengyuJielong.stop);
|
|
1144
1360
|
gameStates.set(key, st);
|
|
1145
1361
|
}
|
|
1146
1362
|
else {
|
|
1147
|
-
await session.send(
|
|
1363
|
+
await session.send('请直接发送成语参与游戏');
|
|
1148
1364
|
}
|
|
1149
1365
|
});
|
|
1150
1366
|
ctx.command('算24点 <action>', '算24点游戏')
|
|
@@ -1152,8 +1368,12 @@ function apply(ctx, cfg) {
|
|
|
1152
1368
|
const session = argv.session;
|
|
1153
1369
|
if (!session)
|
|
1154
1370
|
return;
|
|
1371
|
+
if (isPrivate(session) && !canPlayPrivate('calc24')) {
|
|
1372
|
+
await session.send('私聊已禁用算24点');
|
|
1373
|
+
return;
|
|
1374
|
+
}
|
|
1155
1375
|
const key = getSessionKey(session);
|
|
1156
|
-
const st = gameStates.get(key) || initState(key
|
|
1376
|
+
const st = gameStates.get(key) || initState(key);
|
|
1157
1377
|
if (checkGameRunning(st, 'calc24')) {
|
|
1158
1378
|
await session.send(d.common.gameRunning);
|
|
1159
1379
|
return;
|
|
@@ -1171,10 +1391,10 @@ function apply(ctx, cfg) {
|
|
|
1171
1391
|
.replace('{1}', st.calc24.difficulty)
|
|
1172
1392
|
.replace('{2}', st.calc24.numbers.join('、')));
|
|
1173
1393
|
gameStates.set(key, st);
|
|
1174
|
-
setupAutoStop(session, st.calc24,
|
|
1394
|
+
setupAutoStop(session, st.calc24, 'calc24', d.calc24.autoStop, cfg.calc24.showRank, d.calc24.rankTitle, d.calc24.rankEmpty);
|
|
1175
1395
|
}
|
|
1176
1396
|
else if (action === '结束') {
|
|
1177
|
-
clearGameData(st.calc24);
|
|
1397
|
+
clearGameData(st.calc24, cfg.calc24.showRank && !isPrivate(session), session, d.calc24.rankTitle, d.calc24.rankEmpty);
|
|
1178
1398
|
await session.send(d.calc24.stop);
|
|
1179
1399
|
gameStates.set(key, st);
|
|
1180
1400
|
}
|
|
@@ -1182,34 +1402,24 @@ function apply(ctx, cfg) {
|
|
|
1182
1402
|
await session.send('请输入:算24点 开始 或 算24点 结束');
|
|
1183
1403
|
}
|
|
1184
1404
|
});
|
|
1185
|
-
|
|
1186
|
-
.
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
await session.send(d.
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
}
|
|
1206
|
-
else if (action === '结束') {
|
|
1207
|
-
clearGameData(st.passwordLock);
|
|
1208
|
-
await session.send(d.passwordLock.stop);
|
|
1209
|
-
gameStates.set(key, st);
|
|
1210
|
-
}
|
|
1211
|
-
else {
|
|
1212
|
-
await session.send('请输入:猜密码 开始 或 猜密码 结束');
|
|
1213
|
-
}
|
|
1214
|
-
});
|
|
1405
|
+
if (cfg.rank.enableCommand) {
|
|
1406
|
+
ctx.command('排行榜', '查看本群游戏排行榜')
|
|
1407
|
+
.action(async ({ session }) => {
|
|
1408
|
+
if (!session || !session.channelId)
|
|
1409
|
+
return;
|
|
1410
|
+
const rankText = await generateTotalRankText(session);
|
|
1411
|
+
await session.send(rankText);
|
|
1412
|
+
});
|
|
1413
|
+
ctx.command('清零', '清零本群所有玩家数据')
|
|
1414
|
+
.action(async ({ session }) => {
|
|
1415
|
+
if (!session || !session.channelId)
|
|
1416
|
+
return;
|
|
1417
|
+
if (session.user?.authority < cfg.rank.clearDataPermission) {
|
|
1418
|
+
await session.send(d.rank.noPermission);
|
|
1419
|
+
return;
|
|
1420
|
+
}
|
|
1421
|
+
await ctx.database.remove('game_mini_player', { guildId: session.channelId });
|
|
1422
|
+
await session.send(d.rank.clearSuccess);
|
|
1423
|
+
});
|
|
1424
|
+
}
|
|
1215
1425
|
}
|