koishi-plugin-wordle-game 1.2.2 → 1.2.4
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 +2 -1
- package/lib/index.js +116 -53
- package/package.json +1 -1
- package/readme.md +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export declare const inject: {
|
|
|
4
4
|
optional: string[];
|
|
5
5
|
};
|
|
6
6
|
export declare const name = "wordle-game";
|
|
7
|
-
export declare const usage = "## \uD83C\uDFA3 \u4F7F\u7528\n\n- \u542F\u52A8\u5FC5\u8981\u7684\u670D\u52A1\u3002\u60A8\u9700\u8981\u542F\u7528 `monetary`\uFF0C`database` \u548C `puppeteer` \u63D2\u4EF6\uFF0C\u4EE5\u5B9E\u73B0\u8D27\u5E01\u7CFB\u7EDF\uFF0C\u6570\u636E\u5B58\u50A8\u548C\u56FE\u7247\u751F\u6210\u7684\u529F\u80FD\u3002\n- \u5EFA\u8BAE\u81EA\u884C\u6DFB\u52A0\u6307\u4EE4\u522B\u540D\uFF0C\u4EE5\u65B9\u4FBF\u60A8\u548C\u60A8\u7684\u7528\u6237\u4F7F\u7528\u3002\n- \u4EAB\u53D7\u731C\u5355\u8BCD\u6E38\u620F\u5427\uFF01\uD83D\uDE0A\n\n## \uD83C\uDFB3 \u6E38\u620F\u6307\u4EE4\n\n\u4EE5\u4E0B\u662F\u8BE5\u63D2\u4EF6\u63D0\u4F9B\u7684\u6307\u4EE4\u5217\u8868:\n\n### \u6E38\u620F\u64CD\u4F5C\n\n- `wordleGame.\u52A0\u5165 [money:number]` - \u52A0\u5165\u6E38\u620F\uFF0C\u53EF\u9009\u53C2\u6570\u4E3A\u6295\u5165\u7684\u8D27\u5E01\u6570\u989D\u3002\n- `wordleGame.\u9000\u51FA` - \u9000\u51FA\u6E38\u620F\uFF0C\u53EA\u80FD\u5728\u6E38\u620F\u672A\u5F00\u59CB\u65F6\u4F7F\u7528\u3002\n- `wordleGame.\u7ED3\u675F` - \u7ED3\u675F\u6E38\u620F\uFF0C\u53EA\u80FD\u5728\u6E38\u620F\u5DF2\u5F00\u59CB\u65F6\u4F7F\u7528\u3002\n\n### \u6E38\u620F\u6A21\u5F0F\n\n- `wordleGame.\u5F00\u59CB [guessWordLength:number]` - \u5F00\u59CB\u6E38\u620F\u5F15\u5BFC\uFF0C\u53EF\u9009\u53C2\u6570\u4E3A\u731C\u5355\u8BCD\u7684\u957F\u5EA6\u3002\n- `wordleGame.\u5F00\u59CB.\u7ECF\u5178` - \u5F00\u59CB\u7ECF\u5178\u731C\u5355\u8BCD\u6E38\u620F\uFF0C\u9700\u8981\u6295\u5165\u8D27\u5E01\uFF0C\u8D62\u4E86\u6709\u5956\u52B1\u3002\n - `--hard` - \u6307\u4EE4\u7684\u9009\u9879\uFF0C\u56F0\u96BE\u6A21\u5F0F\uFF0C\u540E\u7EED\u731C\u5355\u8BCD\u5FC5\u987B\u4F7F\u7528\u524D\u9762\u6B63\u786E\u6216\u51FA\u73B0\u7684\u5B57\u6BCD\u3002\n- `wordleGame.\u5F00\u59CB.CET4/6/GMAT/GRE/IELTS/SAT/TOEFL/\u8003\u7814/\u4E13\u516B/\u4E13\u56DB/ALL [guessWordLength:number]` -\n \u5F00\u59CB\u731C\u4E0D\u540C\u8003\u8BD5/\u7C7B\u522B\u7684\u5355\u8BCD\u6E38\u620F\uFF0C\u53EF\u9009\u53C2\u6570\u4E3A\u731C\u5355\u8BCD\u7684\u957F\u5EA6\u3002\n - `--hard` - \u6307\u4EE4\u7684\u9009\u9879\uFF0C\u56F0\u96BE\u6A21\u5F0F\uFF0C\u540E\u7EED\u731C\u5355\u8BCD\u5FC5\u987B\u4F7F\u7528\u524D\u9762\u6B63\u786E\u6216\u51FA\u73B0\u7684\u5B57\u6BCD\u3002\n\n### \u6E38\u620F\u64CD\u4F5C\n\n- `wordleGame.\u731C [inputWord:text]` - \u731C\u5355\u8BCD\uFF0C\u53C2\u6570\u4E3A\u8F93\u5165\u7684\u5355\u8BCD\u3002\n- `wordleGame.\u67E5\u8BE2\u8FDB\u5EA6` - \u67E5\u8BE2\u5F53\u524D\u6E38\u620F\u8FDB\u5EA6\u3002\n\n### \u6570\u636E\u67E5\u8BE2\n\n- `wordleGame.\u67E5\u8BE2\u5355\u8BCD [targetWord:text]` - \u5728 ALL \u8BCD\u5E93\u4E2D\u67E5\u8BE2\u5355\u8BCD\u4FE1\u606F\uFF08\u7FFB\u8BD1\uFF09\u3002\n- `wordleGame.\u67E5\u8BE2\u73A9\u5BB6\u8BB0\u5F55 [targetUser:text]` - \u67E5\u8BE2\u73A9\u5BB6\u8BB0\u5F55\uFF0C\u53EF\u9009\u53C2\u6570\u4E3A\u76EE\u6807\u73A9\u5BB6\u7684 at \u4FE1\u606F\u3002\n- `wordleGame.\u6392\u884C\u699C [number:number]` - \u67E5\u770B\u6392\u884C\u699C\uFF0C\u53EF\u9009\u53C2\u6570\u4E3A\u6392\u884C\u699C\u7684\u4EBA\u6570\u3002\n- `wordleGame.\u6392\u884C\u699C.\u635F\u76CA/\u603B.\u80DC\u573A/\u603B.\u8F93\u573A/\u7ECF\u5178/CET4/CET6/GMAT/GRE/IELTS/SAT/TOEFL/\u8003\u7814/\u4E13\u516B/\u4E13\u56DB/ALL.\u80DC\u573A/\u8F93\u573A [number:number]` -\n \u67E5\u770B\u4E0D\u540C\u6A21\u5F0F\u7684\u73A9\u5BB6\u6392\u884C\u699C\uFF0C\u53EF\u9009\u53C2\u6570\u4E3A\u6392\u884C\u699C\u7684\u4EBA\u6570\u3002";
|
|
7
|
+
export declare const usage = "## \uD83C\uDFA3 \u4F7F\u7528\n\n- \u542F\u52A8\u5FC5\u8981\u7684\u670D\u52A1\u3002\u60A8\u9700\u8981\u542F\u7528 `monetary`\uFF0C`database` \u548C `puppeteer` \u63D2\u4EF6\uFF0C\u4EE5\u5B9E\u73B0\u8D27\u5E01\u7CFB\u7EDF\uFF0C\u6570\u636E\u5B58\u50A8\u548C\u56FE\u7247\u751F\u6210\u7684\u529F\u80FD\u3002\n- \u5EFA\u8BAE\u81EA\u884C\u6DFB\u52A0\u6307\u4EE4\u522B\u540D\uFF0C\u4EE5\u65B9\u4FBF\u60A8\u548C\u60A8\u7684\u7528\u6237\u4F7F\u7528\u3002\n- \u4EAB\u53D7\u731C\u5355\u8BCD\u6E38\u620F\u5427\uFF01\uD83D\uDE0A\n\n## \uD83C\uDFB3 \u6E38\u620F\u6307\u4EE4\n\n\u4EE5\u4E0B\u662F\u8BE5\u63D2\u4EF6\u63D0\u4F9B\u7684\u6307\u4EE4\u5217\u8868:\n\n### \u6E38\u620F\u64CD\u4F5C\n\n- `wordleGame.\u52A0\u5165 [money:number]` - \u52A0\u5165\u6E38\u620F\uFF0C\u53EF\u9009\u53C2\u6570\u4E3A\u6295\u5165\u7684\u8D27\u5E01\u6570\u989D\u3002\n- `wordleGame.\u9000\u51FA` - \u9000\u51FA\u6E38\u620F\uFF0C\u53EA\u80FD\u5728\u6E38\u620F\u672A\u5F00\u59CB\u65F6\u4F7F\u7528\u3002\n- `wordleGame.\u7ED3\u675F` - \u7ED3\u675F\u6E38\u620F\uFF0C\u53EA\u80FD\u5728\u6E38\u620F\u5DF2\u5F00\u59CB\u65F6\u4F7F\u7528\u3002\n\n### \u6E38\u620F\u6A21\u5F0F\n\n- `wordleGame.\u5F00\u59CB [guessWordLength:number]` - \u5F00\u59CB\u6E38\u620F\u5F15\u5BFC\uFF0C\u53EF\u9009\u53C2\u6570\u4E3A\u731C\u5355\u8BCD\u7684\u957F\u5EA6\u3002\n- `wordleGame.\u5F00\u59CB.\u7ECF\u5178` - \u5F00\u59CB\u7ECF\u5178\u731C\u5355\u8BCD\u6E38\u620F\uFF0C\u9700\u8981\u6295\u5165\u8D27\u5E01\uFF0C\u8D62\u4E86\u6709\u5956\u52B1\u3002\n - `--hard` - \u6307\u4EE4\u7684\u9009\u9879\uFF0C\u56F0\u96BE\u6A21\u5F0F\uFF0C\u540E\u7EED\u731C\u5355\u8BCD\u5FC5\u987B\u4F7F\u7528\u524D\u9762\u6B63\u786E\u6216\u51FA\u73B0\u7684\u5B57\u6BCD\u3002\n- `wordleGame.\u5F00\u59CB.CET4/6/GMAT/GRE/IELTS/SAT/TOEFL/\u8003\u7814/\u4E13\u516B/\u4E13\u56DB/ALL [guessWordLength:number]` -\n \u5F00\u59CB\u731C\u4E0D\u540C\u8003\u8BD5/\u7C7B\u522B\u7684\u5355\u8BCD\u6E38\u620F\uFF0C\u53EF\u9009\u53C2\u6570\u4E3A\u731C\u5355\u8BCD\u7684\u957F\u5EA6\u3002\n - `--hard` - \u6307\u4EE4\u7684\u9009\u9879\uFF0C\u56F0\u96BE\u6A21\u5F0F\uFF0C\u540E\u7EED\u731C\u5355\u8BCD\u5FC5\u987B\u4F7F\u7528\u524D\u9762\u6B63\u786E\u6216\u51FA\u73B0\u7684\u5B57\u6BCD\u3002\n\n### \u6E38\u620F\u64CD\u4F5C\n\n- `wordleGame.\u731C [inputWord:text]` - \u731C\u5355\u8BCD\uFF0C\u53C2\u6570\u4E3A\u8F93\u5165\u7684\u5355\u8BCD\u3002\n- `wordleGame.\u67E5\u8BE2\u8FDB\u5EA6` - \u67E5\u8BE2\u5F53\u524D\u6E38\u620F\u8FDB\u5EA6\u3002\n\n### \u6570\u636E\u67E5\u8BE2\n\n- `wordleGame.\u67E5\u8BE2\u5355\u8BCD [targetWord:text]` - \u5728 ALL \u8BCD\u5E93\u4E2D\u67E5\u8BE2\u5355\u8BCD\u4FE1\u606F\uFF08\u7FFB\u8BD1\uFF09\u3002\n- `wordleGame.\u67E5\u8BE2\u73A9\u5BB6\u8BB0\u5F55 [targetUser:text]` - \u67E5\u8BE2\u73A9\u5BB6\u8BB0\u5F55\uFF0C\u53EF\u9009\u53C2\u6570\u4E3A\u76EE\u6807\u73A9\u5BB6\u7684 at \u4FE1\u606F\u3002\n- `wordleGame.\u6392\u884C\u699C [number:number]` - \u67E5\u770B\u6392\u884C\u699C\uFF0C\u53EF\u9009\u53C2\u6570\u4E3A\u6392\u884C\u699C\u7684\u4EBA\u6570\u3002\n- `wordleGame.\u6392\u884C\u699C.\u635F\u76CA/\u603B.\u80DC\u573A/\u603B.\u8F93\u573A/\u7ECF\u5178/CET4/CET6/GMAT/GRE/IELTS/SAT/TOEFL/\u8003\u7814/\u4E13\u516B/\u4E13\u56DB/ALL.\u80DC\u573A/\u8F93\u573A/\u6700\u5FEB\u7528\u65F6 [number:number]` -\n \u67E5\u770B\u4E0D\u540C\u6A21\u5F0F\u7684\u73A9\u5BB6\u6392\u884C\u699C\uFF0C\u53EF\u9009\u53C2\u6570\u4E3A\u6392\u884C\u699C\u7684\u4EBA\u6570\u3002";
|
|
8
8
|
export interface Config {
|
|
9
9
|
defaultMaxLeaderboardEntries: number;
|
|
10
10
|
defaultWordLengthForGuessing: number;
|
|
@@ -66,6 +66,7 @@ export interface PlayerRecord {
|
|
|
66
66
|
moneyChange: number;
|
|
67
67
|
wordGuessCount: number;
|
|
68
68
|
stats: PlayerStats;
|
|
69
|
+
fastestGuessTime: Record<string, number>;
|
|
69
70
|
}
|
|
70
71
|
interface PlayerStats {
|
|
71
72
|
经典?: WinLoseStats;
|
package/lib/index.js
CHANGED
|
@@ -68,7 +68,7 @@ exports.usage = `## 🎣 使用
|
|
|
68
68
|
- \`wordleGame.查询单词 [targetWord:text]\` - 在 ALL 词库中查询单词信息(翻译)。
|
|
69
69
|
- \`wordleGame.查询玩家记录 [targetUser:text]\` - 查询玩家记录,可选参数为目标玩家的 at 信息。
|
|
70
70
|
- \`wordleGame.排行榜 [number:number]\` - 查看排行榜,可选参数为排行榜的人数。
|
|
71
|
-
- \`wordleGame.排行榜.损益/总.胜场/总.输场/经典/CET4/CET6/GMAT/GRE/IELTS/SAT/TOEFL/考研/专八/专四/ALL
|
|
71
|
+
- \`wordleGame.排行榜.损益/总.胜场/总.输场/经典/CET4/CET6/GMAT/GRE/IELTS/SAT/TOEFL/考研/专八/专四/ALL.胜场/输场/最快用时 [number:number]\` -
|
|
72
72
|
查看不同模式的玩家排行榜,可选参数为排行榜的人数。`;
|
|
73
73
|
exports.Config = koishi_1.Schema.intersect([
|
|
74
74
|
koishi_1.Schema.object({
|
|
@@ -114,6 +114,20 @@ const initialStats = {
|
|
|
114
114
|
专四: { win: 0, lose: 0 },
|
|
115
115
|
ALL: { win: 0, lose: 0 },
|
|
116
116
|
};
|
|
117
|
+
const initialFastestGuessTime = {
|
|
118
|
+
经典: 0,
|
|
119
|
+
CET4: 0,
|
|
120
|
+
CET6: 0,
|
|
121
|
+
GMAT: 0,
|
|
122
|
+
GRE: 0,
|
|
123
|
+
IELTS: 0,
|
|
124
|
+
SAT: 0,
|
|
125
|
+
TOEFL: 0,
|
|
126
|
+
考研: 0,
|
|
127
|
+
专八: 0,
|
|
128
|
+
专四: 0,
|
|
129
|
+
ALL: 0,
|
|
130
|
+
};
|
|
117
131
|
function apply(ctx, config) {
|
|
118
132
|
// tzb*
|
|
119
133
|
ctx.model.extend('wordle_game_records', {
|
|
@@ -154,7 +168,8 @@ function apply(ctx, config) {
|
|
|
154
168
|
win: 'unsigned',
|
|
155
169
|
moneyChange: 'double',
|
|
156
170
|
wordGuessCount: 'unsigned',
|
|
157
|
-
stats: { type: 'json', initial: initialStats }
|
|
171
|
+
stats: { type: 'json', initial: initialStats },
|
|
172
|
+
fastestGuessTime: { type: 'json', initial: initialFastestGuessTime },
|
|
158
173
|
}, {
|
|
159
174
|
primary: 'id',
|
|
160
175
|
autoInc: true,
|
|
@@ -303,6 +318,8 @@ function apply(ctx, config) {
|
|
|
303
318
|
if (!gameInfo.isStarted) {
|
|
304
319
|
return await sendMessage(session, `【@${username}】\n游戏还没开始哦~怎么结束呐?`);
|
|
305
320
|
}
|
|
321
|
+
// 玩家记录输
|
|
322
|
+
await updatePlayerRecordsLose(channelId, gameInfo);
|
|
306
323
|
// 结束
|
|
307
324
|
await endGame(channelId);
|
|
308
325
|
return await sendMessage(session, `【@${username}】\n由于您执行了操作:【结束】\n游戏已结束!\n${generateGameEndMessage(gameInfo)}`);
|
|
@@ -445,8 +462,8 @@ function apply(ctx, config) {
|
|
|
445
462
|
return await sendMessage(session, `【@${username}】\n游戏还没开始呢!`);
|
|
446
463
|
}
|
|
447
464
|
// 作答时间限制
|
|
465
|
+
const timeDifferenceInSeconds = (timestamp - gameInfo.timestamp) / 1000; // 将时间戳转换为秒
|
|
448
466
|
if (config.enableWordGuessTimeLimit) {
|
|
449
|
-
const timeDifferenceInSeconds = (timestamp - gameInfo.timestamp) / 1000; // 将时间戳转换为秒
|
|
450
467
|
if (timeDifferenceInSeconds > config.wordGuessTimeLimitInSeconds) {
|
|
451
468
|
// 生成 html 字符串
|
|
452
469
|
const emptyGridHtml = generateEmptyGridHtml(gameInfo.remainingGuessesCount, gameInfo.guessWordLength);
|
|
@@ -551,7 +568,14 @@ function apply(ctx, config) {
|
|
|
551
568
|
await updatePlayerRecordsWin(channelId, gameInfo);
|
|
552
569
|
// 增加该玩家猜出单词的次数
|
|
553
570
|
const [playerRecord] = await ctx.database.get('wordle_player_records', { userId });
|
|
554
|
-
|
|
571
|
+
// 更新最快用时
|
|
572
|
+
if (timeDifferenceInSeconds < playerRecord.fastestGuessTime[gameInfo.gameMode] || playerRecord.fastestGuessTime[gameInfo.gameMode] === 0) {
|
|
573
|
+
playerRecord.fastestGuessTime[gameInfo.gameMode] = Math.floor(timeDifferenceInSeconds);
|
|
574
|
+
}
|
|
575
|
+
await ctx.database.set('wordle_player_records', { userId }, {
|
|
576
|
+
wordGuessCount: playerRecord.wordGuessCount + 1,
|
|
577
|
+
fastestGuessTime: playerRecord.fastestGuessTime
|
|
578
|
+
});
|
|
555
579
|
await endGame(channelId);
|
|
556
580
|
return await sendMessage(session, `【@${username}】\n太棒了,你猜出来了!\n${calculateGameDuration(gameInfo.timestamp, timestamp)}\n${koishi_1.h.image(imageBuffer, `image/${config.imageType}`)}\n${generateGameEndMessage(gameInfo)}\n${finalSettlementString === '' ? '' : `最终结算结果如下:\n${finalSettlementString}`}`);
|
|
557
581
|
}
|
|
@@ -567,7 +591,7 @@ function apply(ctx, config) {
|
|
|
567
591
|
return await sendMessage(session, `${koishi_1.h.image(imageBuffer, `image/${config.imageType}`)}`);
|
|
568
592
|
// .action
|
|
569
593
|
});
|
|
570
|
-
// wordleGame.查询玩家记录 cx*
|
|
594
|
+
// wordleGame.查询玩家记录 cx* cxwjjl*
|
|
571
595
|
ctx.command('wordleGame.查询玩家记录 [targetUser:text]', '查询玩家记录')
|
|
572
596
|
.action(async ({ session }, targetUser) => {
|
|
573
597
|
let { userId, username } = session;
|
|
@@ -579,34 +603,19 @@ function apply(ctx, config) {
|
|
|
579
603
|
}
|
|
580
604
|
const targetUserRecord = await ctx.database.get('wordle_player_records', { userId });
|
|
581
605
|
if (targetUserRecord.length === 0) {
|
|
582
|
-
await ctx.database.create('wordle_player_records', {
|
|
583
|
-
|
|
584
|
-
username,
|
|
585
|
-
});
|
|
586
|
-
return sendMessage(session, `查询对象:${username}
|
|
587
|
-
无任何游戏记录。`);
|
|
606
|
+
await ctx.database.create('wordle_player_records', { userId, username });
|
|
607
|
+
return sendMessage(session, `查询对象:${username} 无任何游戏记录。`);
|
|
588
608
|
}
|
|
589
|
-
const { win, lose, moneyChange, wordGuessCount, stats } = targetUserRecord[0];
|
|
590
|
-
const queryInfo =
|
|
609
|
+
const { win, lose, moneyChange, wordGuessCount, stats, fastestGuessTime } = targetUserRecord[0];
|
|
610
|
+
const queryInfo = `【@${session.username}】
|
|
591
611
|
查询对象:${username}
|
|
592
612
|
猜出单词次数:${wordGuessCount} 次
|
|
593
613
|
总胜场:${win} 次
|
|
594
614
|
总输场:${lose} 次
|
|
595
615
|
损益为:${moneyChange} 点
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
CET6 - 胜: ${stats.CET6?.win}, 负: ${stats.CET6?.lose}
|
|
600
|
-
GMAT - 胜: ${stats.GMAT?.win}, 负: ${stats.GMAT?.lose}
|
|
601
|
-
GRE - 胜: ${stats.GRE?.win}, 负: ${stats.GRE?.lose}
|
|
602
|
-
IELTS - 胜: ${stats.IELTS?.win}, 负: ${stats.IELTS?.lose}
|
|
603
|
-
SAT - 胜: ${stats.SAT?.win}, 负: ${stats.SAT?.lose}
|
|
604
|
-
TOEFL - 胜: ${stats.TOEFL?.win}, 负: ${stats.TOEFL?.lose}
|
|
605
|
-
考研 - 胜: ${stats.考研?.win}, 负: ${stats.考研?.lose}
|
|
606
|
-
专八 - 胜: ${stats.专八?.win}, 负: ${stats.专八?.lose}
|
|
607
|
-
专四 - 胜: ${stats.专四?.win}, 负: ${stats.专四?.lose}
|
|
608
|
-
ALL - 胜: ${stats.ALL?.win}, 负: ${stats.ALL?.lose}
|
|
609
|
-
`;
|
|
616
|
+
详细统计信息如下:
|
|
617
|
+
${generateStatsInfo(stats, fastestGuessTime)}
|
|
618
|
+
`;
|
|
610
619
|
return sendMessage(session, queryInfo);
|
|
611
620
|
});
|
|
612
621
|
// wordleGame.查询单词 cxdc*
|
|
@@ -705,7 +714,7 @@ ${rankType.map((type, index) => `${index + 1}. ${type}`).join('\n')}
|
|
|
705
714
|
return '请输入大于等于 0 的数字作为排行榜的参数。';
|
|
706
715
|
}
|
|
707
716
|
const rankType3 = [
|
|
708
|
-
"胜场", "输场"
|
|
717
|
+
"胜场", "输场", "最快用时"
|
|
709
718
|
];
|
|
710
719
|
await sendMessage(session, `当前可查看排行榜如下:
|
|
711
720
|
${rankType3.map((type, index) => `${index + 1}. ${type}`).join('\n')}
|
|
@@ -763,39 +772,43 @@ ${rankType3.map((type, index) => `${index + 1}. ${type}`).join('\n')}
|
|
|
763
772
|
"经典", "CET4", "CET6", "GMAT", "GRE", "IELTS",
|
|
764
773
|
"SAT", "TOEFL", "考研", "专八", "专四", "ALL"
|
|
765
774
|
];
|
|
766
|
-
//
|
|
775
|
+
// 注册胜场、输场、用时排行榜指令
|
|
767
776
|
rankType4.forEach((type) => {
|
|
768
777
|
ctx.command(`wordleGame.排行榜.${type}.胜场 [number:number]`, `查看${type}胜场排行榜`)
|
|
769
778
|
.action(async ({ session }, number = config.defaultMaxLeaderboardEntries) => {
|
|
770
|
-
|
|
771
|
-
return '请输入大于等于 0 的数字作为排行榜的参数。';
|
|
772
|
-
}
|
|
773
|
-
const getPlayers = await ctx.database.get('wordle_player_records', {});
|
|
774
|
-
// 将 getPlayers 按照当前类型的胜场次数降序排序
|
|
775
|
-
getPlayers.sort((a, b) => (b.stats[type]?.win || 0) - (a.stats[type]?.win || 0));
|
|
776
|
-
// 形成一个类似于字符串排行榜的数组
|
|
777
|
-
const leaderboard = getPlayers.slice(0, number).map((player, index) => `${index + 1}. ${player.username}:${player.stats[type]?.win} 次`);
|
|
778
|
-
const result = `${type}模式胜场排行榜:\n${leaderboard.join('\n')}`;
|
|
779
|
-
return await sendMessage(session, result);
|
|
779
|
+
return await sendMessage(session, await getLeaderboardWinOrLose(type, number, 'win', '胜场'));
|
|
780
780
|
});
|
|
781
|
-
});
|
|
782
|
-
// 注册输场排行榜指令
|
|
783
|
-
rankType4.forEach((type) => {
|
|
784
781
|
ctx.command(`wordleGame.排行榜.${type}.输场 [number:number]`, `查看${type}输场排行榜`)
|
|
785
782
|
.action(async ({ session }, number = config.defaultMaxLeaderboardEntries) => {
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
getPlayers.sort((a, b) => (b.stats[type]?.lose || 0) - (a.stats[type]?.lose || 0));
|
|
792
|
-
// 形成一个类似于字符串排行榜的数组
|
|
793
|
-
const leaderboard = getPlayers.slice(0, number).map((player, index) => `${index + 1}. ${player.username}:${player.stats[type]?.lose} 次`);
|
|
794
|
-
const result = `${type}模式输场排行榜:\n${leaderboard.join('\n')}`;
|
|
795
|
-
return await sendMessage(session, result);
|
|
783
|
+
return await sendMessage(session, await getLeaderboardWinOrLose(type, number, 'lose', '输场'));
|
|
784
|
+
});
|
|
785
|
+
ctx.command(`wordleGame.排行榜.${type}.最快用时 [number:number]`, `查看${type}最快用时排行榜`)
|
|
786
|
+
.action(async ({ session }, number = config.defaultMaxLeaderboardEntries) => {
|
|
787
|
+
return await sendMessage(session, await getLeaderboardFastestGuessTime(type, number));
|
|
796
788
|
});
|
|
797
789
|
});
|
|
798
790
|
// ch*
|
|
791
|
+
async function getLeaderboardWinOrLose(type, number, statKey, label) {
|
|
792
|
+
if (typeof number !== 'number' || isNaN(number) || number < 0) {
|
|
793
|
+
return '请输入大于等于 0 的数字作为排行榜的参数。';
|
|
794
|
+
}
|
|
795
|
+
const getPlayers = await ctx.database.get('wordle_player_records', {});
|
|
796
|
+
// 降序排序
|
|
797
|
+
getPlayers.sort((a, b) => (b.stats[type]?.[statKey] || 0) - (a.stats[type]?.[statKey] || 0));
|
|
798
|
+
const leaderboard = getPlayers.slice(0, number).map((player, index) => `${index + 1}. ${player.username}:${player.stats[type]?.[statKey]} 次`);
|
|
799
|
+
return `${type}模式${label}排行榜:\n${leaderboard.join('\n')}`;
|
|
800
|
+
}
|
|
801
|
+
async function getLeaderboardFastestGuessTime(type, number) {
|
|
802
|
+
const getPlayers = await ctx.database.get('wordle_player_records', {});
|
|
803
|
+
const leaderboard = getPlayers
|
|
804
|
+
.filter(player => player.fastestGuessTime[type] > 0)
|
|
805
|
+
.sort((a, b) => a.fastestGuessTime[type] - b.fastestGuessTime[type])
|
|
806
|
+
.slice(0, number)
|
|
807
|
+
.map((player, index) => `${index + 1}. ${player.username}:${formatGameDuration2(player.fastestGuessTime[type])}`)
|
|
808
|
+
.join('\n');
|
|
809
|
+
return `${type}模式最快用时排行榜:\n${leaderboard}`;
|
|
810
|
+
}
|
|
811
|
+
;
|
|
799
812
|
async function generateLetterTilesHtml(wordGuess, inputWord, channelId) {
|
|
800
813
|
const wordHtml = new Array(inputWord.length);
|
|
801
814
|
const letterCountMap = {};
|
|
@@ -852,7 +865,7 @@ ${rankType3.map((type, index) => `${index + 1}. ${type}`).join('\n')}
|
|
|
852
865
|
await ctx.database.set('wordle_game_records', { channelId }, {
|
|
853
866
|
correctLetters,
|
|
854
867
|
presentLetters: uniqueSortedLowercaseLetters(presentLetters),
|
|
855
|
-
absentLetters: uniqueSortedLowercaseLetters(absentLetters),
|
|
868
|
+
absentLetters: removeLetters(gameInfo.wordGuess, uniqueSortedLowercaseLetters(absentLetters)),
|
|
856
869
|
});
|
|
857
870
|
return wordHtml.join("\n");
|
|
858
871
|
}
|
|
@@ -1077,6 +1090,56 @@ ${rankType3.map((type, index) => `${index + 1}. ${type}`).join('\n')}
|
|
|
1077
1090
|
}
|
|
1078
1091
|
exports.apply = apply;
|
|
1079
1092
|
// hs*
|
|
1093
|
+
function generateStatsInfo(stats, fastestGuessTime) {
|
|
1094
|
+
const gameTypes = [
|
|
1095
|
+
'经典',
|
|
1096
|
+
'CET4',
|
|
1097
|
+
'CET6',
|
|
1098
|
+
'GMAT',
|
|
1099
|
+
'GRE',
|
|
1100
|
+
'IELTS',
|
|
1101
|
+
'SAT',
|
|
1102
|
+
'TOEFL',
|
|
1103
|
+
'考研',
|
|
1104
|
+
'专八',
|
|
1105
|
+
'专四',
|
|
1106
|
+
'ALL'
|
|
1107
|
+
];
|
|
1108
|
+
let statsInfo = '';
|
|
1109
|
+
gameTypes.forEach(type => {
|
|
1110
|
+
const winCount = stats[type]?.win || 0;
|
|
1111
|
+
const loseCount = stats[type]?.lose || 0;
|
|
1112
|
+
const fastestTime = fastestGuessTime[type] || 0;
|
|
1113
|
+
statsInfo += `${type} - 胜:${winCount} 次,负:${loseCount} 次`;
|
|
1114
|
+
statsInfo += fastestTime === 0 ? '' : `,最快${formatGameDuration(fastestTime)}`;
|
|
1115
|
+
statsInfo += '\n';
|
|
1116
|
+
});
|
|
1117
|
+
return statsInfo;
|
|
1118
|
+
}
|
|
1119
|
+
function formatGameDuration(elapsedSeconds) {
|
|
1120
|
+
const minutes = Math.floor(elapsedSeconds / 60);
|
|
1121
|
+
const seconds = elapsedSeconds % 60;
|
|
1122
|
+
if (minutes > 0) {
|
|
1123
|
+
return `用时:${minutes} 分 ${seconds} 秒`;
|
|
1124
|
+
}
|
|
1125
|
+
else {
|
|
1126
|
+
return `用时:${seconds} 秒`;
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
function formatGameDuration2(elapsedSeconds) {
|
|
1130
|
+
const minutes = Math.floor(elapsedSeconds / 60);
|
|
1131
|
+
const seconds = elapsedSeconds % 60;
|
|
1132
|
+
if (minutes > 0) {
|
|
1133
|
+
return `${minutes} 分 ${seconds} 秒`;
|
|
1134
|
+
}
|
|
1135
|
+
else {
|
|
1136
|
+
return `${seconds} 秒`;
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
function removeLetters(wordAnswer, absentLetters) {
|
|
1140
|
+
const letterSet = new Set(wordAnswer);
|
|
1141
|
+
return absentLetters.split('').filter(letter => !letterSet.has(letter)).join('');
|
|
1142
|
+
}
|
|
1080
1143
|
function calculateGameDuration(startTime, currentTime) {
|
|
1081
1144
|
const elapsedMilliseconds = currentTime - startTime;
|
|
1082
1145
|
const elapsedSeconds = Math.floor(elapsedMilliseconds / 1000);
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -97,7 +97,7 @@ npm install koishi-plugin-wordle-game
|
|
|
97
97
|
- `wordleGame.查询单词 [targetWord:text]` - 在 ALL 词库中查询单词信息(翻译)。
|
|
98
98
|
- `wordleGame.查询玩家记录 [targetUser:text]` - 查询玩家记录,可选参数为目标玩家的 at 信息。
|
|
99
99
|
- `wordleGame.排行榜 [number:number]` - 查看排行榜,可选参数为排行榜的人数。
|
|
100
|
-
- `wordleGame.排行榜.损益/总.胜场/总.输场/经典/CET4/CET6/GMAT/GRE/IELTS/SAT/TOEFL/考研/专八/专四/ALL
|
|
100
|
+
- `wordleGame.排行榜.损益/总.胜场/总.输场/经典/CET4/CET6/GMAT/GRE/IELTS/SAT/TOEFL/考研/专八/专四/ALL.胜场/输场/最快用时 [number:number]` -
|
|
101
101
|
查看不同模式的玩家排行榜,可选参数为排行榜的人数。
|
|
102
102
|
|
|
103
103
|
## 🍰 致谢
|