koishi-plugin-mcdle 0.0.1 → 0.0.2
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/data.d.ts +5 -0
- package/lib/index.js +558 -541
- package/package.json +1 -1
package/lib/data.d.ts
CHANGED
|
@@ -51,3 +51,8 @@ export interface ItemData {
|
|
|
51
51
|
export declare const mobData: MobData[];
|
|
52
52
|
export declare const blockData: BlockData[];
|
|
53
53
|
export declare const itemData: ItemData[];
|
|
54
|
+
export declare const keyMap: Record<string, string>;
|
|
55
|
+
export declare const valueMap: Record<string, Record<string, string>>;
|
|
56
|
+
export declare const blockChineseTitle: string[];
|
|
57
|
+
export declare const mobChineseTitle: string[];
|
|
58
|
+
export declare const itemChineseTitle: string[];
|
package/lib/index.js
CHANGED
|
@@ -13653,547 +13653,6 @@ var itemData = [
|
|
|
13653
13653
|
"wiki_image_url": "https://minecraft.wiki/images/Copper_Nugget_JE1_BE1.png?42865"
|
|
13654
13654
|
}
|
|
13655
13655
|
];
|
|
13656
|
-
|
|
13657
|
-
// src/index.ts
|
|
13658
|
-
var name = "mcdle";
|
|
13659
|
-
var usage = `# MCDLE - 我的世界猜谜游戏
|
|
13660
|
-
|
|
13661
|
-
灵感源于 **Wordle** 玩法
|
|
13662
|
-
|
|
13663
|
-
## 基本玩法
|
|
13664
|
-
|
|
13665
|
-
- **mcdle.猜 [名称]** - 开始游戏或进行猜测
|
|
13666
|
-
- 系统随机选择**生物、物品或方块**作为答案
|
|
13667
|
-
- 通过**颜色提示**判断接近程度:
|
|
13668
|
-
|
|
13669
|
-
| 符号 | 含义 |
|
|
13670
|
-
|------|------|
|
|
13671
|
-
| 🟩 绿色 | 字段完全匹配 |
|
|
13672
|
-
| 🟨 黄色 | 部分匹配 |
|
|
13673
|
-
| 🟥 红色 | 不匹配 |
|
|
13674
|
-
| 🟥⬆️ | 答案更大 |
|
|
13675
|
-
| 🟥⬇️ | 答案更小 |
|
|
13676
|
-
|
|
13677
|
-
## QQ 群
|
|
13678
|
-
|
|
13679
|
-
956758505`;
|
|
13680
|
-
var inject = ["database"];
|
|
13681
|
-
var Config = import_koishi.Schema.object({
|
|
13682
|
-
atReply: import_koishi.Schema.boolean().default(false).description("响应时@用户"),
|
|
13683
|
-
quoteReply: import_koishi.Schema.boolean().default(true).description("响应时引用消息"),
|
|
13684
|
-
isEnableMiddleware: import_koishi.Schema.boolean().default(false).description("启用中间件(无需指令直接猜测)"),
|
|
13685
|
-
maxRank: import_koishi.Schema.number().default(10).min(0).description("排行榜最大显示人数"),
|
|
13686
|
-
dailyPlayLimit: import_koishi.Schema.number().default(1).min(1).description("每日游玩次数上限")
|
|
13687
|
-
});
|
|
13688
|
-
function apply(ctx, cfg) {
|
|
13689
|
-
ctx.model.extend(
|
|
13690
|
-
"mcdle",
|
|
13691
|
-
{
|
|
13692
|
-
channelId: "string",
|
|
13693
|
-
answer: { type: "json", initial: null },
|
|
13694
|
-
guesses: { type: "list", initial: [] },
|
|
13695
|
-
historyChineseTitles: { type: "list", initial: [] },
|
|
13696
|
-
guessedChineseTitles: { type: "list", initial: [] },
|
|
13697
|
-
dailyPlayedToday: { type: "unsigned", initial: 0 },
|
|
13698
|
-
gameEnded: { type: "boolean", initial: true },
|
|
13699
|
-
lastGameStartTime: { type: "timestamp", initial: /* @__PURE__ */ new Date(0) },
|
|
13700
|
-
gameMode: { type: "string", initial: null }
|
|
13701
|
-
},
|
|
13702
|
-
{
|
|
13703
|
-
primary: "channelId"
|
|
13704
|
-
}
|
|
13705
|
-
);
|
|
13706
|
-
ctx.model.extend(
|
|
13707
|
-
"mcdle_rank",
|
|
13708
|
-
{
|
|
13709
|
-
userId: "string",
|
|
13710
|
-
username: { type: "string", initial: "" },
|
|
13711
|
-
mobSuccessCount: { type: "unsigned", initial: 0 },
|
|
13712
|
-
itemSuccessCount: { type: "unsigned", initial: 0 },
|
|
13713
|
-
blockSuccessCount: { type: "unsigned", initial: 0 },
|
|
13714
|
-
totalSuccessCount: { type: "unsigned", initial: 0 }
|
|
13715
|
-
},
|
|
13716
|
-
{
|
|
13717
|
-
primary: "userId"
|
|
13718
|
-
}
|
|
13719
|
-
);
|
|
13720
|
-
if (cfg.isEnableMiddleware) {
|
|
13721
|
-
ctx.middleware(async (session, next) => {
|
|
13722
|
-
let gameRecords = await ctx.database.get("mcdle", { channelId: session.channelId });
|
|
13723
|
-
if (!gameRecords || gameRecords.length === 0) {
|
|
13724
|
-
return next();
|
|
13725
|
-
}
|
|
13726
|
-
const game = gameRecords[0];
|
|
13727
|
-
if (game.gameEnded) {
|
|
13728
|
-
return next();
|
|
13729
|
-
}
|
|
13730
|
-
const content = session.content.trim();
|
|
13731
|
-
if (content.length > 10 || /[,。!?;:'"“”‘’【】()《》.,!?;:'"\[\]()<>]/.test(content)) return next();
|
|
13732
|
-
if (game.guessedChineseTitles.includes(content)) {
|
|
13733
|
-
return next();
|
|
13734
|
-
}
|
|
13735
|
-
let dataSource = [];
|
|
13736
|
-
if (game.gameMode === "mob") dataSource = mobData;
|
|
13737
|
-
else if (game.gameMode === "item") dataSource = itemData;
|
|
13738
|
-
else if (game.gameMode === "block") dataSource = blockData;
|
|
13739
|
-
else return next();
|
|
13740
|
-
const matched = dataSource.find(
|
|
13741
|
-
(d) => d.chinese_title === content
|
|
13742
|
-
);
|
|
13743
|
-
if (!matched) {
|
|
13744
|
-
return next();
|
|
13745
|
-
}
|
|
13746
|
-
await session.execute(`mcdle.猜 ${content}`);
|
|
13747
|
-
return;
|
|
13748
|
-
});
|
|
13749
|
-
}
|
|
13750
|
-
ctx.command("mcdle", "我的世界wordle");
|
|
13751
|
-
ctx.command("mcdle.猜 [guess:string]").action(async ({ session }, guess) => c(session, guess?.trim()));
|
|
13752
|
-
ctx.command("mcdle.帮助").action(async ({ session }) => bz(session));
|
|
13753
|
-
ctx.command("mcdle.排行榜").action(async ({ session }) => phb(session));
|
|
13754
|
-
ctx.command("mcdle.词库").action(async ({ session }) => ck(session));
|
|
13755
|
-
async function ck(session) {
|
|
13756
|
-
if (session.bot?.platform === "onebot" && session.bot?.internal?.sendForwardMsg) {
|
|
13757
|
-
const nodes = [
|
|
13758
|
-
{
|
|
13759
|
-
type: "node",
|
|
13760
|
-
data: {
|
|
13761
|
-
name: "MCDLE词库",
|
|
13762
|
-
uin: session.bot.selfId,
|
|
13763
|
-
content: `生物词库:
|
|
13764
|
-
${mobChineseTitle.join(" ")}`
|
|
13765
|
-
}
|
|
13766
|
-
},
|
|
13767
|
-
{
|
|
13768
|
-
type: "node",
|
|
13769
|
-
data: {
|
|
13770
|
-
name: "MCDLE词库",
|
|
13771
|
-
uin: session.bot.selfId,
|
|
13772
|
-
content: `方块词库:
|
|
13773
|
-
${blockChineseTitle.join(" ")}`
|
|
13774
|
-
}
|
|
13775
|
-
},
|
|
13776
|
-
{
|
|
13777
|
-
type: "node",
|
|
13778
|
-
data: {
|
|
13779
|
-
name: "MCDLE词库",
|
|
13780
|
-
uin: session.bot.selfId,
|
|
13781
|
-
content: `物品词库:
|
|
13782
|
-
${itemChineseTitle.join(" ")}`
|
|
13783
|
-
}
|
|
13784
|
-
}
|
|
13785
|
-
];
|
|
13786
|
-
try {
|
|
13787
|
-
await session.bot.internal.sendForwardMsg(session.channelId, nodes);
|
|
13788
|
-
return;
|
|
13789
|
-
} catch (error) {
|
|
13790
|
-
console.warn("合并转发失败,降级为普通消息:", error);
|
|
13791
|
-
}
|
|
13792
|
-
}
|
|
13793
|
-
await sendMsg(session, `生物词库:
|
|
13794
|
-
${mobChineseTitle.join(" ")}`);
|
|
13795
|
-
await sendMsg(session, `方块词库:
|
|
13796
|
-
${blockChineseTitle.join(" ")}`);
|
|
13797
|
-
await sendMsg(session, `物品词库:
|
|
13798
|
-
${itemChineseTitle.join(" ")}`);
|
|
13799
|
-
}
|
|
13800
|
-
__name(ck, "ck");
|
|
13801
|
-
async function c(session, guess) {
|
|
13802
|
-
let records = await ctx.database.get("mcdle", { channelId: session.channelId });
|
|
13803
|
-
if (!records || records.length === 0) {
|
|
13804
|
-
records = [await ctx.database.create("mcdle", {
|
|
13805
|
-
channelId: session.channelId,
|
|
13806
|
-
answer: null,
|
|
13807
|
-
guesses: [],
|
|
13808
|
-
historyChineseTitles: [],
|
|
13809
|
-
guessedChineseTitles: [],
|
|
13810
|
-
dailyPlayedToday: 0,
|
|
13811
|
-
gameEnded: true,
|
|
13812
|
-
lastGameStartTime: /* @__PURE__ */ new Date(0),
|
|
13813
|
-
gameMode: null
|
|
13814
|
-
})];
|
|
13815
|
-
}
|
|
13816
|
-
const record = records[0];
|
|
13817
|
-
const now = /* @__PURE__ */ new Date();
|
|
13818
|
-
const lastDate = new Date(record.lastGameStartTime);
|
|
13819
|
-
if (now.getFullYear() !== lastDate.getFullYear() || now.getMonth() !== lastDate.getMonth() || now.getDate() !== lastDate.getDate()) {
|
|
13820
|
-
record.dailyPlayedToday = 0;
|
|
13821
|
-
await ctx.database.set("mcdle", { channelId: session.channelId }, { dailyPlayedToday: 0 });
|
|
13822
|
-
}
|
|
13823
|
-
if (record.gameEnded) {
|
|
13824
|
-
let isInHistory = function(title) {
|
|
13825
|
-
return record.historyChineseTitles.includes(title);
|
|
13826
|
-
};
|
|
13827
|
-
__name(isInHistory, "isInHistory");
|
|
13828
|
-
if (record.dailyPlayedToday >= cfg.dailyPlayLimit) {
|
|
13829
|
-
await sendMsg(session, `今日游戏次数已达上限,请明日再来!`);
|
|
13830
|
-
return;
|
|
13831
|
-
}
|
|
13832
|
-
let chosenMode;
|
|
13833
|
-
let dataSource;
|
|
13834
|
-
let matchedData = void 0;
|
|
13835
|
-
if (guess) {
|
|
13836
|
-
matchedData = mobData.find((d) => d.chinese_title === guess) || itemData.find((d) => d.chinese_title === guess) || blockData.find((d) => d.chinese_title === guess);
|
|
13837
|
-
}
|
|
13838
|
-
if (!matchedData) {
|
|
13839
|
-
const choices = ["mob", "item", "block"];
|
|
13840
|
-
chosenMode = choices[Math.floor(Math.random() * choices.length)];
|
|
13841
|
-
} else {
|
|
13842
|
-
if (mobData.includes(matchedData)) chosenMode = "mob";
|
|
13843
|
-
else if (itemData.includes(matchedData)) chosenMode = "item";
|
|
13844
|
-
else chosenMode = "block";
|
|
13845
|
-
}
|
|
13846
|
-
if (!matchedData) {
|
|
13847
|
-
if (chosenMode === "mob") dataSource = mobData;
|
|
13848
|
-
else if (chosenMode === "item") dataSource = itemData;
|
|
13849
|
-
else dataSource = blockData;
|
|
13850
|
-
const filtered = dataSource.filter((d) => !isInHistory(d.chinese_title));
|
|
13851
|
-
if (filtered.length === 0) {
|
|
13852
|
-
const remainingHistory = record.historyChineseTitles.filter((title) => {
|
|
13853
|
-
const isMob = mobData.some((mob) => mob.chinese_title === title);
|
|
13854
|
-
const isItem = itemData.some((item) => item.chinese_title === title);
|
|
13855
|
-
const isBlock = blockData.some((block) => block.chinese_title === title);
|
|
13856
|
-
if (chosenMode === "mob") return !isMob;
|
|
13857
|
-
if (chosenMode === "item") return !isItem;
|
|
13858
|
-
if (chosenMode === "block") return !isBlock;
|
|
13859
|
-
return true;
|
|
13860
|
-
});
|
|
13861
|
-
await ctx.database.set("mcdle", { channelId: session.channelId }, {
|
|
13862
|
-
historyChineseTitles: remainingHistory
|
|
13863
|
-
});
|
|
13864
|
-
dataSource = chosenMode === "mob" ? mobData : chosenMode === "item" ? itemData : blockData;
|
|
13865
|
-
} else {
|
|
13866
|
-
dataSource = filtered;
|
|
13867
|
-
}
|
|
13868
|
-
const answer = dataSource[Math.floor(Math.random() * dataSource.length)];
|
|
13869
|
-
await ctx.database.set("mcdle", { channelId: session.channelId }, {
|
|
13870
|
-
answer,
|
|
13871
|
-
guesses: [],
|
|
13872
|
-
guessedChineseTitles: [],
|
|
13873
|
-
gameEnded: false,
|
|
13874
|
-
lastGameStartTime: now,
|
|
13875
|
-
dailyPlayedToday: record.dailyPlayedToday + 1,
|
|
13876
|
-
historyChineseTitles: [...record.historyChineseTitles, answer.chinese_title],
|
|
13877
|
-
gameMode: chosenMode
|
|
13878
|
-
});
|
|
13879
|
-
await sendMsg(session, `游戏开始!模式: ${chosenMode === "mob" ? "生物" : chosenMode === "item" ? "物品" : "方块"}`);
|
|
13880
|
-
return;
|
|
13881
|
-
}
|
|
13882
|
-
if (matchedData) {
|
|
13883
|
-
if (mobData.includes(matchedData)) chosenMode = "mob";
|
|
13884
|
-
else if (itemData.includes(matchedData)) chosenMode = "item";
|
|
13885
|
-
else chosenMode = "block";
|
|
13886
|
-
if (chosenMode === "mob") dataSource = mobData;
|
|
13887
|
-
else if (chosenMode === "item") dataSource = itemData;
|
|
13888
|
-
else dataSource = blockData;
|
|
13889
|
-
let filtered = dataSource.filter((d) => !isInHistory(d.chinese_title));
|
|
13890
|
-
if (filtered.length === 0) {
|
|
13891
|
-
const remainingHistory = record.historyChineseTitles.filter((title) => {
|
|
13892
|
-
const isMob = mobData.some((mob) => mob.chinese_title === title);
|
|
13893
|
-
const isItem = itemData.some((item) => item.chinese_title === title);
|
|
13894
|
-
const isBlock = blockData.some((block) => block.chinese_title === title);
|
|
13895
|
-
if (chosenMode === "mob") return !isMob;
|
|
13896
|
-
if (chosenMode === "item") return !isItem;
|
|
13897
|
-
if (chosenMode === "block") return !isBlock;
|
|
13898
|
-
return true;
|
|
13899
|
-
});
|
|
13900
|
-
await ctx.database.set("mcdle", { channelId: session.channelId }, {
|
|
13901
|
-
historyChineseTitles: remainingHistory
|
|
13902
|
-
});
|
|
13903
|
-
filtered = chosenMode === "mob" ? mobData : chosenMode === "item" ? itemData : blockData;
|
|
13904
|
-
}
|
|
13905
|
-
const answer = filtered[Math.floor(Math.random() * filtered.length)];
|
|
13906
|
-
await ctx.database.set("mcdle", { channelId: session.channelId }, {
|
|
13907
|
-
answer,
|
|
13908
|
-
guesses: [],
|
|
13909
|
-
guessedChineseTitles: [],
|
|
13910
|
-
gameEnded: false,
|
|
13911
|
-
lastGameStartTime: now,
|
|
13912
|
-
dailyPlayedToday: record.dailyPlayedToday + 1,
|
|
13913
|
-
historyChineseTitles: [...record.historyChineseTitles, answer.chinese_title],
|
|
13914
|
-
gameMode: chosenMode
|
|
13915
|
-
});
|
|
13916
|
-
const comparisonResult = compareData(matchedData, answer);
|
|
13917
|
-
await ctx.database.set("mcdle", { channelId: session.channelId }, {
|
|
13918
|
-
guesses: [...record.guesses, comparisonResult],
|
|
13919
|
-
guessedChineseTitles: [...record.guessedChineseTitles, matchedData.chinese_title]
|
|
13920
|
-
});
|
|
13921
|
-
await generateAndSendComparison(session, [...record.guesses, comparisonResult]);
|
|
13922
|
-
if (matchedData.chinese_title === answer.chinese_title) {
|
|
13923
|
-
await sendMsg(session, `恭喜你猜对啦!
|
|
13924
|
-
答案:${matchedData.chinese_title}
|
|
13925
|
-
猜测:${record.guesses.length + 1} 次`);
|
|
13926
|
-
await ctx.database.set("mcdle", { channelId: session.channelId }, {
|
|
13927
|
-
gameEnded: true,
|
|
13928
|
-
answer: null,
|
|
13929
|
-
guesses: [],
|
|
13930
|
-
guessedChineseTitles: [],
|
|
13931
|
-
gameMode: null
|
|
13932
|
-
});
|
|
13933
|
-
await updateRank(session.userId, session.username, chosenMode);
|
|
13934
|
-
}
|
|
13935
|
-
await sendMsg(session, `游戏开始!模式:${chosenMode === "mob" ? "生物" : chosenMode === "item" ? "物品" : "方块"}`);
|
|
13936
|
-
return;
|
|
13937
|
-
}
|
|
13938
|
-
} else {
|
|
13939
|
-
if (!guess) {
|
|
13940
|
-
await sendMsg(session, `请输入 ${record.gameMode === "mob" ? "生物" : record.gameMode === "item" ? "物品" : "方块"}名称 猜测`);
|
|
13941
|
-
return;
|
|
13942
|
-
}
|
|
13943
|
-
let dataSource;
|
|
13944
|
-
if (record.gameMode === "mob") dataSource = mobData;
|
|
13945
|
-
else if (record.gameMode === "item") dataSource = itemData;
|
|
13946
|
-
else if (record.gameMode === "block") dataSource = blockData;
|
|
13947
|
-
else {
|
|
13948
|
-
await sendMsg(session, `模式数据异常`);
|
|
13949
|
-
return;
|
|
13950
|
-
}
|
|
13951
|
-
if (record.guessedChineseTitles.includes(guess)) {
|
|
13952
|
-
await sendMsg(session, `${guess} 已猜过`);
|
|
13953
|
-
return;
|
|
13954
|
-
}
|
|
13955
|
-
const matched = dataSource.find((d) => d.chinese_title === guess);
|
|
13956
|
-
if (!matched) {
|
|
13957
|
-
const fuzzyMatches = dataSource.filter(
|
|
13958
|
-
(d) => d.chinese_title.includes(guess) || guess.includes(d.chinese_title)
|
|
13959
|
-
).slice(0, 3);
|
|
13960
|
-
if (fuzzyMatches.length > 0) {
|
|
13961
|
-
const suggestions = fuzzyMatches.map((d) => d.chinese_title).join("、");
|
|
13962
|
-
await sendMsg(session, `${guess} 不在词库中
|
|
13963
|
-
|
|
13964
|
-
是否想猜:${suggestions}?`);
|
|
13965
|
-
} else {
|
|
13966
|
-
await sendMsg(session, `${guess} 不在词库中`);
|
|
13967
|
-
}
|
|
13968
|
-
return;
|
|
13969
|
-
}
|
|
13970
|
-
const answer = record.answer;
|
|
13971
|
-
if (!answer) {
|
|
13972
|
-
await sendMsg(session, `数据异常`);
|
|
13973
|
-
return;
|
|
13974
|
-
}
|
|
13975
|
-
const comparisonResult = compareData(matched, answer);
|
|
13976
|
-
const updatedGuesses = [...record.guesses, comparisonResult];
|
|
13977
|
-
const updatedChineseTitles = [...record.guessedChineseTitles, matched.chinese_title];
|
|
13978
|
-
await ctx.database.set("mcdle", { channelId: session.channelId }, {
|
|
13979
|
-
guesses: updatedGuesses,
|
|
13980
|
-
guessedChineseTitles: updatedChineseTitles
|
|
13981
|
-
});
|
|
13982
|
-
await generateAndSendComparison(session, updatedGuesses);
|
|
13983
|
-
if (matched.chinese_title === answer.chinese_title) {
|
|
13984
|
-
await sendMsg(session, `恭喜你猜对啦!
|
|
13985
|
-
答案:${matched.chinese_title}
|
|
13986
|
-
猜测:${record.guesses.length + 1} 次`);
|
|
13987
|
-
await ctx.database.set("mcdle", { channelId: session.channelId }, {
|
|
13988
|
-
gameEnded: true,
|
|
13989
|
-
answer: null,
|
|
13990
|
-
guesses: [],
|
|
13991
|
-
guessedChineseTitles: [],
|
|
13992
|
-
gameMode: null
|
|
13993
|
-
});
|
|
13994
|
-
await updateRank(session.userId, session.username, record.gameMode);
|
|
13995
|
-
}
|
|
13996
|
-
}
|
|
13997
|
-
}
|
|
13998
|
-
__name(c, "c");
|
|
13999
|
-
function bz(session) {
|
|
14000
|
-
return sendMsg(
|
|
14001
|
-
session,
|
|
14002
|
-
[
|
|
14003
|
-
"MCDLE 我的世界猜谜(类 Wordle)",
|
|
14004
|
-
"玩法核心:根据猜测物品/生物/方块与答案字段对应,标记正确、部分匹配、不匹配。",
|
|
14005
|
-
"颜色标识:",
|
|
14006
|
-
"🟩 绿色 - 字段完全匹配",
|
|
14007
|
-
"🟨 黄色 - 部分匹配",
|
|
14008
|
-
"🟥 红色 - 不匹配",
|
|
14009
|
-
"🟥⬆️ 红色上箭头 - 答案更大",
|
|
14010
|
-
"🟥⬇️ 红色下箭头 - 答案更小",
|
|
14011
|
-
"使用指令:mcdle.猜 [名称] 进行开始或猜测,mcdle.排行榜 查看成绩。",
|
|
14012
|
-
`每日游玩次数限制:${cfg.dailyPlayLimit}次`,
|
|
14013
|
-
"我的世界中文Wiki:https://zh.minecraft.wiki/w/Minecraft_Wiki"
|
|
14014
|
-
].join("\n")
|
|
14015
|
-
);
|
|
14016
|
-
}
|
|
14017
|
-
__name(bz, "bz");
|
|
14018
|
-
async function phb(session) {
|
|
14019
|
-
const ranks = await ctx.database.get("mcdle_rank", {}, {
|
|
14020
|
-
limit: cfg.maxRank,
|
|
14021
|
-
sort: { totalSuccessCount: "desc" }
|
|
14022
|
-
});
|
|
14023
|
-
if (!ranks || ranks.length === 0) {
|
|
14024
|
-
await sendMsg(session, "暂无排行榜数据");
|
|
14025
|
-
return;
|
|
14026
|
-
}
|
|
14027
|
-
const text = "MCDLE 排行榜:\n" + ranks.map((r, i) => `${i + 1}. ${r.username} ${r.totalSuccessCount}`).join("\n") + "\n...";
|
|
14028
|
-
await sendMsg(session, text);
|
|
14029
|
-
}
|
|
14030
|
-
__name(phb, "phb");
|
|
14031
|
-
function compareData(guess, answer) {
|
|
14032
|
-
const result = { ...guess };
|
|
14033
|
-
for (const key in guess) {
|
|
14034
|
-
if (key === "initial_release") {
|
|
14035
|
-
const guessVersion = normalizeVersion(guess[key]);
|
|
14036
|
-
const answerVersion = normalizeVersion(answer[key]);
|
|
14037
|
-
if (guessVersion === answerVersion) {
|
|
14038
|
-
result[`${key}_gui`] = "true";
|
|
14039
|
-
} else {
|
|
14040
|
-
const guessParts = guessVersion.split(".").map((part) => parseInt(part, 10) || 0);
|
|
14041
|
-
const answerParts = answerVersion.split(".").map((part) => parseInt(part, 10) || 0);
|
|
14042
|
-
let setFlag = false;
|
|
14043
|
-
for (let i = 0; i < Math.max(guessParts.length, answerParts.length); i++) {
|
|
14044
|
-
const g = guessParts[i] || 0;
|
|
14045
|
-
const a = answerParts[i] || 0;
|
|
14046
|
-
if (g < a) {
|
|
14047
|
-
result[`${key}_gui`] = "false_up";
|
|
14048
|
-
setFlag = true;
|
|
14049
|
-
break;
|
|
14050
|
-
} else if (g > a) {
|
|
14051
|
-
result[`${key}_gui`] = "false_down";
|
|
14052
|
-
setFlag = true;
|
|
14053
|
-
break;
|
|
14054
|
-
}
|
|
14055
|
-
}
|
|
14056
|
-
if (!setFlag) {
|
|
14057
|
-
result[`${key}_gui`] = "true";
|
|
14058
|
-
}
|
|
14059
|
-
}
|
|
14060
|
-
} else if (typeof guess[key] === "number" && typeof answer[key] === "number") {
|
|
14061
|
-
if (guess[key] === answer[key]) {
|
|
14062
|
-
result[`${key}_gui`] = "true";
|
|
14063
|
-
} else if (guess[key] < answer[key]) {
|
|
14064
|
-
result[`${key}_gui`] = "false_up";
|
|
14065
|
-
} else {
|
|
14066
|
-
result[`${key}_gui`] = "false_down";
|
|
14067
|
-
}
|
|
14068
|
-
} else if (Array.isArray(guess[key]) && Array.isArray(answer[key])) {
|
|
14069
|
-
const guessArr = guess[key];
|
|
14070
|
-
const answerArr = answer[key];
|
|
14071
|
-
const intersection = guessArr.filter((x) => answerArr.includes(x));
|
|
14072
|
-
if (intersection.length === guessArr.length && intersection.length === answerArr.length) {
|
|
14073
|
-
result[`${key}_gui`] = "true";
|
|
14074
|
-
} else if (intersection.length > 0) {
|
|
14075
|
-
result[`${key}_gui`] = "mixed";
|
|
14076
|
-
} else {
|
|
14077
|
-
result[`${key}_gui`] = "false";
|
|
14078
|
-
}
|
|
14079
|
-
} else if (guess[key] === answer[key]) {
|
|
14080
|
-
result[`${key}_gui`] = "true";
|
|
14081
|
-
} else {
|
|
14082
|
-
result[`${key}_gui`] = "false";
|
|
14083
|
-
}
|
|
14084
|
-
}
|
|
14085
|
-
return result;
|
|
14086
|
-
}
|
|
14087
|
-
__name(compareData, "compareData");
|
|
14088
|
-
async function updateRank(userId, username, mode) {
|
|
14089
|
-
let rankRecord = await ctx.database.get("mcdle_rank", { userId });
|
|
14090
|
-
if (!rankRecord || rankRecord.length === 0) {
|
|
14091
|
-
rankRecord = [await ctx.database.create("mcdle_rank", {
|
|
14092
|
-
userId,
|
|
14093
|
-
username,
|
|
14094
|
-
mobSuccessCount: 0,
|
|
14095
|
-
itemSuccessCount: 0,
|
|
14096
|
-
blockSuccessCount: 0,
|
|
14097
|
-
totalSuccessCount: 0
|
|
14098
|
-
})];
|
|
14099
|
-
}
|
|
14100
|
-
const record = rankRecord[0];
|
|
14101
|
-
const updates = {
|
|
14102
|
-
username,
|
|
14103
|
-
totalSuccessCount: record.totalSuccessCount + 1
|
|
14104
|
-
};
|
|
14105
|
-
if (mode === "mob") updates.mobSuccessCount = record.mobSuccessCount + 1;
|
|
14106
|
-
else if (mode === "item") updates.itemSuccessCount = record.itemSuccessCount + 1;
|
|
14107
|
-
else updates.blockSuccessCount = record.blockSuccessCount + 1;
|
|
14108
|
-
await ctx.database.set("mcdle_rank", { userId }, updates);
|
|
14109
|
-
}
|
|
14110
|
-
__name(updateRank, "updateRank");
|
|
14111
|
-
async function generateAndSendComparison(session, guesses) {
|
|
14112
|
-
if (guesses.length === 0) {
|
|
14113
|
-
await sendMsg(session, "暂无猜测结果");
|
|
14114
|
-
return;
|
|
14115
|
-
}
|
|
14116
|
-
const lastGuess = guesses[guesses.length - 1];
|
|
14117
|
-
let resultText = "";
|
|
14118
|
-
if (lastGuess.wiki_image_url) {
|
|
14119
|
-
resultText += `${import_koishi.h.image(lastGuess.wiki_image_url)}
|
|
14120
|
-
`;
|
|
14121
|
-
if (lastGuess.chinese_title) {
|
|
14122
|
-
resultText += `名称:${lastGuess.chinese_title}
|
|
14123
|
-
`;
|
|
14124
|
-
}
|
|
14125
|
-
}
|
|
14126
|
-
for (const key in lastGuess) {
|
|
14127
|
-
if (key.endsWith("_gui")) continue;
|
|
14128
|
-
if (key === "id" || key === "title" || key === "url" || key === "image_url") continue;
|
|
14129
|
-
if (key === "wiki_image_url" || key === "chinese_title") continue;
|
|
14130
|
-
const guiKey = `${key}_gui`;
|
|
14131
|
-
const guiStatus = lastGuess[guiKey];
|
|
14132
|
-
let statusEmoji = "❓";
|
|
14133
|
-
if (guiStatus === "true") statusEmoji = "🟩";
|
|
14134
|
-
else if (guiStatus === "mixed") statusEmoji = "🟨";
|
|
14135
|
-
else if (guiStatus === "false") statusEmoji = "🟥";
|
|
14136
|
-
else if (guiStatus === "false_up") statusEmoji = "🟥⬆️";
|
|
14137
|
-
else if (guiStatus === "false_down") statusEmoji = "🟥⬇️";
|
|
14138
|
-
const displayKey = keyMap[key] || key;
|
|
14139
|
-
let value = lastGuess[key];
|
|
14140
|
-
if (Array.isArray(value)) {
|
|
14141
|
-
value = value.map((v) => {
|
|
14142
|
-
if (typeof v === "string" && valueMap[key]?.[v]) {
|
|
14143
|
-
return valueMap[key][v];
|
|
14144
|
-
}
|
|
14145
|
-
return v;
|
|
14146
|
-
}).join("、");
|
|
14147
|
-
} else if (typeof value === "string") {
|
|
14148
|
-
if (valueMap[key]?.[value]) {
|
|
14149
|
-
value = valueMap[key][value];
|
|
14150
|
-
}
|
|
14151
|
-
}
|
|
14152
|
-
resultText += `${displayKey}: ${value} ${statusEmoji}
|
|
14153
|
-
`;
|
|
14154
|
-
}
|
|
14155
|
-
await sendMsg(session, resultText);
|
|
14156
|
-
}
|
|
14157
|
-
__name(generateAndSendComparison, "generateAndSendComparison");
|
|
14158
|
-
function normalizeVersion(versionString) {
|
|
14159
|
-
if (versionString === "pre-alpha") return "0";
|
|
14160
|
-
if (versionString.startsWith("Alpha ")) return "0.0.0.0." + versionString.replace("Alpha ", "");
|
|
14161
|
-
if (versionString.startsWith("Beta ")) return "0." + versionString.replace("Beta ", "");
|
|
14162
|
-
switch (versionString) {
|
|
14163
|
-
case "2.0":
|
|
14164
|
-
return "1.5.1.1";
|
|
14165
|
-
case "15w14a":
|
|
14166
|
-
return "1.8.3.1";
|
|
14167
|
-
case "1.RV-Pre1":
|
|
14168
|
-
return "1.9.2.1";
|
|
14169
|
-
case "3D Shareware v1.34":
|
|
14170
|
-
return "1.13.2.1";
|
|
14171
|
-
case "20w14∞":
|
|
14172
|
-
return "1.14.4.1";
|
|
14173
|
-
case "22w13oneBlockAtATime":
|
|
14174
|
-
return "1.18.2.1";
|
|
14175
|
-
case "23w13a_or_b":
|
|
14176
|
-
return "1.19.4.1";
|
|
14177
|
-
case "24w14potato":
|
|
14178
|
-
return "1.20.4.1";
|
|
14179
|
-
case "25w14craftmine":
|
|
14180
|
-
return "1.21.5.1";
|
|
14181
|
-
}
|
|
14182
|
-
return versionString;
|
|
14183
|
-
}
|
|
14184
|
-
__name(normalizeVersion, "normalizeVersion");
|
|
14185
|
-
async function sendMsg(session, msg) {
|
|
14186
|
-
if (cfg.atReply) {
|
|
14187
|
-
msg = `${import_koishi.h.at(session.userId)}${(0, import_koishi.h)("p", "")}${msg}`;
|
|
14188
|
-
}
|
|
14189
|
-
if (cfg.quoteReply) {
|
|
14190
|
-
msg = `${import_koishi.h.quote(session.messageId)}${msg}`;
|
|
14191
|
-
}
|
|
14192
|
-
await session.send(msg);
|
|
14193
|
-
}
|
|
14194
|
-
__name(sendMsg, "sendMsg");
|
|
14195
|
-
}
|
|
14196
|
-
__name(apply, "apply");
|
|
14197
13656
|
var keyMap = {
|
|
14198
13657
|
renewable: "可再生性",
|
|
14199
13658
|
tool: "工具",
|
|
@@ -15158,6 +14617,564 @@ var itemChineseTitle = [
|
|
|
15158
14617
|
"挽具",
|
|
15159
14618
|
"铜粒"
|
|
15160
14619
|
];
|
|
14620
|
+
|
|
14621
|
+
// src/index.ts
|
|
14622
|
+
var name = "mcdle";
|
|
14623
|
+
var usage = `# MCDLE - 我的世界猜谜游戏
|
|
14624
|
+
|
|
14625
|
+
灵感源于 **Wordle** 玩法
|
|
14626
|
+
|
|
14627
|
+
## 基本玩法
|
|
14628
|
+
|
|
14629
|
+
- **mcdle.猜 [名称]** - 开始游戏或进行猜测
|
|
14630
|
+
- 系统随机选择**生物、物品或方块**作为答案
|
|
14631
|
+
- 通过**颜色提示**判断接近程度:
|
|
14632
|
+
|
|
14633
|
+
| 符号 | 含义 |
|
|
14634
|
+
|------|------|
|
|
14635
|
+
| 🟩 绿色 | 字段完全匹配 |
|
|
14636
|
+
| 🟨 黄色 | 部分匹配 |
|
|
14637
|
+
| 🟥 红色 | 不匹配 |
|
|
14638
|
+
| 🟥⬆️ | 答案更大 |
|
|
14639
|
+
| 🟥⬇️ | 答案更小 |
|
|
14640
|
+
|
|
14641
|
+
## QQ 群
|
|
14642
|
+
|
|
14643
|
+
956758505`;
|
|
14644
|
+
var inject = ["database"];
|
|
14645
|
+
var Config = import_koishi.Schema.object({
|
|
14646
|
+
atReply: import_koishi.Schema.boolean().default(false).description("响应时@用户"),
|
|
14647
|
+
quoteReply: import_koishi.Schema.boolean().default(true).description("响应时引用消息"),
|
|
14648
|
+
isEnableMiddleware: import_koishi.Schema.boolean().default(false).description("启用中间件(无需指令直接猜测)"),
|
|
14649
|
+
maxRank: import_koishi.Schema.number().default(10).min(0).description("排行榜最大显示人数"),
|
|
14650
|
+
dailyPlayLimit: import_koishi.Schema.number().default(1).min(1).description("每日游玩次数上限")
|
|
14651
|
+
});
|
|
14652
|
+
function apply(ctx, cfg) {
|
|
14653
|
+
ctx.model.extend(
|
|
14654
|
+
"mcdle",
|
|
14655
|
+
{
|
|
14656
|
+
channelId: "string",
|
|
14657
|
+
answer: { type: "json", initial: null },
|
|
14658
|
+
guesses: { type: "list", initial: [] },
|
|
14659
|
+
historyChineseTitles: { type: "list", initial: [] },
|
|
14660
|
+
guessedChineseTitles: { type: "list", initial: [] },
|
|
14661
|
+
dailyPlayedToday: { type: "unsigned", initial: 0 },
|
|
14662
|
+
gameEnded: { type: "boolean", initial: true },
|
|
14663
|
+
lastGameStartTime: { type: "timestamp", initial: /* @__PURE__ */ new Date(0) },
|
|
14664
|
+
gameMode: { type: "string", initial: null }
|
|
14665
|
+
},
|
|
14666
|
+
{
|
|
14667
|
+
primary: "channelId"
|
|
14668
|
+
}
|
|
14669
|
+
);
|
|
14670
|
+
ctx.model.extend(
|
|
14671
|
+
"mcdle_rank",
|
|
14672
|
+
{
|
|
14673
|
+
userId: "string",
|
|
14674
|
+
username: { type: "string", initial: "" },
|
|
14675
|
+
mobSuccessCount: { type: "unsigned", initial: 0 },
|
|
14676
|
+
itemSuccessCount: { type: "unsigned", initial: 0 },
|
|
14677
|
+
blockSuccessCount: { type: "unsigned", initial: 0 },
|
|
14678
|
+
totalSuccessCount: { type: "unsigned", initial: 0 }
|
|
14679
|
+
},
|
|
14680
|
+
{
|
|
14681
|
+
primary: "userId"
|
|
14682
|
+
}
|
|
14683
|
+
);
|
|
14684
|
+
if (cfg.isEnableMiddleware) {
|
|
14685
|
+
ctx.middleware(async (session, next) => {
|
|
14686
|
+
let gameRecords = await ctx.database.get("mcdle", { channelId: session.channelId });
|
|
14687
|
+
if (!gameRecords || gameRecords.length === 0) {
|
|
14688
|
+
return next();
|
|
14689
|
+
}
|
|
14690
|
+
const game = gameRecords[0];
|
|
14691
|
+
if (game.gameEnded) {
|
|
14692
|
+
return next();
|
|
14693
|
+
}
|
|
14694
|
+
const content = session.content.trim();
|
|
14695
|
+
if (content.length > 10 || /[,。!?;:'"“”‘’【】()《》.,!?;:'"\[\]()<>]/.test(content)) return next();
|
|
14696
|
+
if (game.guessedChineseTitles.includes(content)) {
|
|
14697
|
+
return next();
|
|
14698
|
+
}
|
|
14699
|
+
let dataSource = [];
|
|
14700
|
+
if (game.gameMode === "mob") dataSource = mobData;
|
|
14701
|
+
else if (game.gameMode === "item") dataSource = itemData;
|
|
14702
|
+
else if (game.gameMode === "block") dataSource = blockData;
|
|
14703
|
+
else return next();
|
|
14704
|
+
const matched = dataSource.find(
|
|
14705
|
+
(d) => d.chinese_title === content
|
|
14706
|
+
);
|
|
14707
|
+
if (!matched) {
|
|
14708
|
+
return next();
|
|
14709
|
+
}
|
|
14710
|
+
await session.execute(`mcdle.猜 ${content}`);
|
|
14711
|
+
return;
|
|
14712
|
+
});
|
|
14713
|
+
}
|
|
14714
|
+
ctx.command("mcdle", "我的世界猜谜游戏").action(() => {
|
|
14715
|
+
return [
|
|
14716
|
+
"欢迎使用 MCDLE",
|
|
14717
|
+
"",
|
|
14718
|
+
"猜生物 物品 方块",
|
|
14719
|
+
"挑战知识边界",
|
|
14720
|
+
"",
|
|
14721
|
+
"颜色与箭头指引方向",
|
|
14722
|
+
"每日限次 排行榜更新",
|
|
14723
|
+
"",
|
|
14724
|
+
"指令示例:",
|
|
14725
|
+
" mcdle.猜 [名称]",
|
|
14726
|
+
" mcdle.帮助",
|
|
14727
|
+
" mcdle.排行榜",
|
|
14728
|
+
"",
|
|
14729
|
+
"愿你洞察世界万象"
|
|
14730
|
+
].join("\n");
|
|
14731
|
+
});
|
|
14732
|
+
ctx.command("mcdle.猜 [guess:string]").action(async ({ session }, guess) => c(session, guess?.trim()));
|
|
14733
|
+
ctx.command("mcdle.帮助").action(async ({ session }) => bz(session));
|
|
14734
|
+
ctx.command("mcdle.排行榜").action(async ({ session }) => phb(session));
|
|
14735
|
+
ctx.command("mcdle.词库").action(async ({ session }) => ck(session));
|
|
14736
|
+
async function ck(session) {
|
|
14737
|
+
if (session.bot?.platform === "onebot" && session.bot?.internal?.sendForwardMsg) {
|
|
14738
|
+
const nodes = [
|
|
14739
|
+
{
|
|
14740
|
+
type: "node",
|
|
14741
|
+
data: {
|
|
14742
|
+
name: "MCDLE词库",
|
|
14743
|
+
uin: session.bot.selfId,
|
|
14744
|
+
content: `生物词库:
|
|
14745
|
+
${mobChineseTitle.join(" ")}`
|
|
14746
|
+
}
|
|
14747
|
+
},
|
|
14748
|
+
{
|
|
14749
|
+
type: "node",
|
|
14750
|
+
data: {
|
|
14751
|
+
name: "MCDLE词库",
|
|
14752
|
+
uin: session.bot.selfId,
|
|
14753
|
+
content: `方块词库:
|
|
14754
|
+
${blockChineseTitle.join(" ")}`
|
|
14755
|
+
}
|
|
14756
|
+
},
|
|
14757
|
+
{
|
|
14758
|
+
type: "node",
|
|
14759
|
+
data: {
|
|
14760
|
+
name: "MCDLE词库",
|
|
14761
|
+
uin: session.bot.selfId,
|
|
14762
|
+
content: `物品词库:
|
|
14763
|
+
${itemChineseTitle.join(" ")}`
|
|
14764
|
+
}
|
|
14765
|
+
}
|
|
14766
|
+
];
|
|
14767
|
+
try {
|
|
14768
|
+
await session.bot.internal.sendForwardMsg(session.channelId, nodes);
|
|
14769
|
+
return;
|
|
14770
|
+
} catch (error) {
|
|
14771
|
+
console.warn("合并转发失败,降级为普通消息:", error);
|
|
14772
|
+
}
|
|
14773
|
+
}
|
|
14774
|
+
await sendMsg(session, `生物词库:
|
|
14775
|
+
${mobChineseTitle.join(" ")}`);
|
|
14776
|
+
await sendMsg(session, `方块词库:
|
|
14777
|
+
${blockChineseTitle.join(" ")}`);
|
|
14778
|
+
await sendMsg(session, `物品词库:
|
|
14779
|
+
${itemChineseTitle.join(" ")}`);
|
|
14780
|
+
}
|
|
14781
|
+
__name(ck, "ck");
|
|
14782
|
+
async function c(session, guess) {
|
|
14783
|
+
let records = await ctx.database.get("mcdle", { channelId: session.channelId });
|
|
14784
|
+
if (!records || records.length === 0) {
|
|
14785
|
+
records = [await ctx.database.create("mcdle", {
|
|
14786
|
+
channelId: session.channelId,
|
|
14787
|
+
answer: null,
|
|
14788
|
+
guesses: [],
|
|
14789
|
+
historyChineseTitles: [],
|
|
14790
|
+
guessedChineseTitles: [],
|
|
14791
|
+
dailyPlayedToday: 0,
|
|
14792
|
+
gameEnded: true,
|
|
14793
|
+
lastGameStartTime: /* @__PURE__ */ new Date(0),
|
|
14794
|
+
gameMode: null
|
|
14795
|
+
})];
|
|
14796
|
+
}
|
|
14797
|
+
const record = records[0];
|
|
14798
|
+
const now = /* @__PURE__ */ new Date();
|
|
14799
|
+
const lastDate = new Date(record.lastGameStartTime);
|
|
14800
|
+
if (now.getFullYear() !== lastDate.getFullYear() || now.getMonth() !== lastDate.getMonth() || now.getDate() !== lastDate.getDate()) {
|
|
14801
|
+
record.dailyPlayedToday = 0;
|
|
14802
|
+
await ctx.database.set("mcdle", { channelId: session.channelId }, { dailyPlayedToday: 0 });
|
|
14803
|
+
}
|
|
14804
|
+
if (record.gameEnded) {
|
|
14805
|
+
let isInHistory = function(title) {
|
|
14806
|
+
return record.historyChineseTitles.includes(title);
|
|
14807
|
+
};
|
|
14808
|
+
__name(isInHistory, "isInHistory");
|
|
14809
|
+
if (record.dailyPlayedToday >= cfg.dailyPlayLimit) {
|
|
14810
|
+
await sendMsg(session, `今日游戏次数已达上限,请明日再来!`);
|
|
14811
|
+
return;
|
|
14812
|
+
}
|
|
14813
|
+
let chosenMode;
|
|
14814
|
+
let dataSource;
|
|
14815
|
+
let matchedData = void 0;
|
|
14816
|
+
if (guess) {
|
|
14817
|
+
matchedData = mobData.find((d) => d.chinese_title === guess) || itemData.find((d) => d.chinese_title === guess) || blockData.find((d) => d.chinese_title === guess);
|
|
14818
|
+
}
|
|
14819
|
+
if (!matchedData) {
|
|
14820
|
+
const choices = ["mob", "item", "block"];
|
|
14821
|
+
chosenMode = choices[Math.floor(Math.random() * choices.length)];
|
|
14822
|
+
} else {
|
|
14823
|
+
if (mobData.includes(matchedData)) chosenMode = "mob";
|
|
14824
|
+
else if (itemData.includes(matchedData)) chosenMode = "item";
|
|
14825
|
+
else chosenMode = "block";
|
|
14826
|
+
}
|
|
14827
|
+
if (!matchedData) {
|
|
14828
|
+
if (chosenMode === "mob") dataSource = mobData;
|
|
14829
|
+
else if (chosenMode === "item") dataSource = itemData;
|
|
14830
|
+
else dataSource = blockData;
|
|
14831
|
+
const filtered = dataSource.filter((d) => !isInHistory(d.chinese_title));
|
|
14832
|
+
if (filtered.length === 0) {
|
|
14833
|
+
const remainingHistory = record.historyChineseTitles.filter((title) => {
|
|
14834
|
+
const isMob = mobData.some((mob) => mob.chinese_title === title);
|
|
14835
|
+
const isItem = itemData.some((item) => item.chinese_title === title);
|
|
14836
|
+
const isBlock = blockData.some((block) => block.chinese_title === title);
|
|
14837
|
+
if (chosenMode === "mob") return !isMob;
|
|
14838
|
+
if (chosenMode === "item") return !isItem;
|
|
14839
|
+
if (chosenMode === "block") return !isBlock;
|
|
14840
|
+
return true;
|
|
14841
|
+
});
|
|
14842
|
+
await ctx.database.set("mcdle", { channelId: session.channelId }, {
|
|
14843
|
+
historyChineseTitles: remainingHistory
|
|
14844
|
+
});
|
|
14845
|
+
dataSource = chosenMode === "mob" ? mobData : chosenMode === "item" ? itemData : blockData;
|
|
14846
|
+
} else {
|
|
14847
|
+
dataSource = filtered;
|
|
14848
|
+
}
|
|
14849
|
+
const answer = dataSource[Math.floor(Math.random() * dataSource.length)];
|
|
14850
|
+
await ctx.database.set("mcdle", { channelId: session.channelId }, {
|
|
14851
|
+
answer,
|
|
14852
|
+
guesses: [],
|
|
14853
|
+
guessedChineseTitles: [],
|
|
14854
|
+
gameEnded: false,
|
|
14855
|
+
lastGameStartTime: now,
|
|
14856
|
+
dailyPlayedToday: record.dailyPlayedToday + 1,
|
|
14857
|
+
historyChineseTitles: [...record.historyChineseTitles, answer.chinese_title],
|
|
14858
|
+
gameMode: chosenMode
|
|
14859
|
+
});
|
|
14860
|
+
await sendMsg(session, `游戏开始!模式: ${chosenMode === "mob" ? "生物" : chosenMode === "item" ? "物品" : "方块"}`);
|
|
14861
|
+
return;
|
|
14862
|
+
}
|
|
14863
|
+
if (matchedData) {
|
|
14864
|
+
if (mobData.includes(matchedData)) chosenMode = "mob";
|
|
14865
|
+
else if (itemData.includes(matchedData)) chosenMode = "item";
|
|
14866
|
+
else chosenMode = "block";
|
|
14867
|
+
if (chosenMode === "mob") dataSource = mobData;
|
|
14868
|
+
else if (chosenMode === "item") dataSource = itemData;
|
|
14869
|
+
else dataSource = blockData;
|
|
14870
|
+
let filtered = dataSource.filter((d) => !isInHistory(d.chinese_title));
|
|
14871
|
+
if (filtered.length === 0) {
|
|
14872
|
+
const remainingHistory = record.historyChineseTitles.filter((title) => {
|
|
14873
|
+
const isMob = mobData.some((mob) => mob.chinese_title === title);
|
|
14874
|
+
const isItem = itemData.some((item) => item.chinese_title === title);
|
|
14875
|
+
const isBlock = blockData.some((block) => block.chinese_title === title);
|
|
14876
|
+
if (chosenMode === "mob") return !isMob;
|
|
14877
|
+
if (chosenMode === "item") return !isItem;
|
|
14878
|
+
if (chosenMode === "block") return !isBlock;
|
|
14879
|
+
return true;
|
|
14880
|
+
});
|
|
14881
|
+
await ctx.database.set("mcdle", { channelId: session.channelId }, {
|
|
14882
|
+
historyChineseTitles: remainingHistory
|
|
14883
|
+
});
|
|
14884
|
+
filtered = chosenMode === "mob" ? mobData : chosenMode === "item" ? itemData : blockData;
|
|
14885
|
+
}
|
|
14886
|
+
const answer = filtered[Math.floor(Math.random() * filtered.length)];
|
|
14887
|
+
await ctx.database.set("mcdle", { channelId: session.channelId }, {
|
|
14888
|
+
answer,
|
|
14889
|
+
guesses: [],
|
|
14890
|
+
guessedChineseTitles: [],
|
|
14891
|
+
gameEnded: false,
|
|
14892
|
+
lastGameStartTime: now,
|
|
14893
|
+
dailyPlayedToday: record.dailyPlayedToday + 1,
|
|
14894
|
+
historyChineseTitles: [...record.historyChineseTitles, answer.chinese_title],
|
|
14895
|
+
gameMode: chosenMode
|
|
14896
|
+
});
|
|
14897
|
+
const comparisonResult = compareData(matchedData, answer);
|
|
14898
|
+
await ctx.database.set("mcdle", { channelId: session.channelId }, {
|
|
14899
|
+
guesses: [...record.guesses, comparisonResult],
|
|
14900
|
+
guessedChineseTitles: [...record.guessedChineseTitles, matchedData.chinese_title]
|
|
14901
|
+
});
|
|
14902
|
+
await generateAndSendComparison(session, [...record.guesses, comparisonResult]);
|
|
14903
|
+
if (matchedData.chinese_title === answer.chinese_title) {
|
|
14904
|
+
await sendMsg(session, `恭喜你猜对啦!
|
|
14905
|
+
答案:${matchedData.chinese_title}
|
|
14906
|
+
猜测:${record.guesses.length + 1} 次`);
|
|
14907
|
+
await ctx.database.set("mcdle", { channelId: session.channelId }, {
|
|
14908
|
+
gameEnded: true,
|
|
14909
|
+
answer: null,
|
|
14910
|
+
guesses: [],
|
|
14911
|
+
guessedChineseTitles: [],
|
|
14912
|
+
gameMode: null
|
|
14913
|
+
});
|
|
14914
|
+
await updateRank(session.userId, session.username, chosenMode);
|
|
14915
|
+
}
|
|
14916
|
+
await sendMsg(session, `游戏开始!模式:${chosenMode === "mob" ? "生物" : chosenMode === "item" ? "物品" : "方块"}`);
|
|
14917
|
+
return;
|
|
14918
|
+
}
|
|
14919
|
+
} else {
|
|
14920
|
+
if (!guess) {
|
|
14921
|
+
await sendMsg(session, `请输入 ${record.gameMode === "mob" ? "生物" : record.gameMode === "item" ? "物品" : "方块"}名称 猜测`);
|
|
14922
|
+
return;
|
|
14923
|
+
}
|
|
14924
|
+
let dataSource;
|
|
14925
|
+
if (record.gameMode === "mob") dataSource = mobData;
|
|
14926
|
+
else if (record.gameMode === "item") dataSource = itemData;
|
|
14927
|
+
else if (record.gameMode === "block") dataSource = blockData;
|
|
14928
|
+
else {
|
|
14929
|
+
await sendMsg(session, `模式数据异常`);
|
|
14930
|
+
return;
|
|
14931
|
+
}
|
|
14932
|
+
if (record.guessedChineseTitles.includes(guess)) {
|
|
14933
|
+
await sendMsg(session, `${guess} 已猜过`);
|
|
14934
|
+
return;
|
|
14935
|
+
}
|
|
14936
|
+
const matched = dataSource.find((d) => d.chinese_title === guess);
|
|
14937
|
+
if (!matched) {
|
|
14938
|
+
const fuzzyMatches = dataSource.filter(
|
|
14939
|
+
(d) => d.chinese_title.includes(guess) || guess.includes(d.chinese_title)
|
|
14940
|
+
).slice(0, 3);
|
|
14941
|
+
if (fuzzyMatches.length > 0) {
|
|
14942
|
+
const suggestions = fuzzyMatches.map((d) => d.chinese_title).join("、");
|
|
14943
|
+
await sendMsg(session, `${guess} 不在词库中
|
|
14944
|
+
|
|
14945
|
+
是否想猜:${suggestions}?`);
|
|
14946
|
+
} else {
|
|
14947
|
+
await sendMsg(session, `${guess} 不在词库中`);
|
|
14948
|
+
}
|
|
14949
|
+
return;
|
|
14950
|
+
}
|
|
14951
|
+
const answer = record.answer;
|
|
14952
|
+
if (!answer) {
|
|
14953
|
+
await sendMsg(session, `数据异常`);
|
|
14954
|
+
return;
|
|
14955
|
+
}
|
|
14956
|
+
const comparisonResult = compareData(matched, answer);
|
|
14957
|
+
const updatedGuesses = [...record.guesses, comparisonResult];
|
|
14958
|
+
const updatedChineseTitles = [...record.guessedChineseTitles, matched.chinese_title];
|
|
14959
|
+
await ctx.database.set("mcdle", { channelId: session.channelId }, {
|
|
14960
|
+
guesses: updatedGuesses,
|
|
14961
|
+
guessedChineseTitles: updatedChineseTitles
|
|
14962
|
+
});
|
|
14963
|
+
await generateAndSendComparison(session, updatedGuesses);
|
|
14964
|
+
if (matched.chinese_title === answer.chinese_title) {
|
|
14965
|
+
await sendMsg(session, `恭喜你猜对啦!
|
|
14966
|
+
答案:${matched.chinese_title}
|
|
14967
|
+
猜测:${record.guesses.length + 1} 次`);
|
|
14968
|
+
await ctx.database.set("mcdle", { channelId: session.channelId }, {
|
|
14969
|
+
gameEnded: true,
|
|
14970
|
+
answer: null,
|
|
14971
|
+
guesses: [],
|
|
14972
|
+
guessedChineseTitles: [],
|
|
14973
|
+
gameMode: null
|
|
14974
|
+
});
|
|
14975
|
+
await updateRank(session.userId, session.username, record.gameMode);
|
|
14976
|
+
}
|
|
14977
|
+
}
|
|
14978
|
+
}
|
|
14979
|
+
__name(c, "c");
|
|
14980
|
+
function bz(session) {
|
|
14981
|
+
return sendMsg(
|
|
14982
|
+
session,
|
|
14983
|
+
[
|
|
14984
|
+
"MCDLE 我的世界猜谜(类 Wordle)",
|
|
14985
|
+
"玩法核心:根据猜测物品/生物/方块与答案字段对应,标记正确、部分匹配、不匹配。",
|
|
14986
|
+
"颜色标识:",
|
|
14987
|
+
"🟩 绿色 - 字段完全匹配",
|
|
14988
|
+
"🟨 黄色 - 部分匹配",
|
|
14989
|
+
"🟥 红色 - 不匹配",
|
|
14990
|
+
"🟥⬆️ 红色上箭头 - 答案更大",
|
|
14991
|
+
"🟥⬇️ 红色下箭头 - 答案更小",
|
|
14992
|
+
"使用指令:mcdle.猜 [名称] 进行开始或猜测,mcdle.排行榜 查看成绩。",
|
|
14993
|
+
`每日游玩次数限制:${cfg.dailyPlayLimit}次`,
|
|
14994
|
+
"我的世界中文Wiki:https://zh.minecraft.wiki/w/Minecraft_Wiki"
|
|
14995
|
+
].join("\n")
|
|
14996
|
+
);
|
|
14997
|
+
}
|
|
14998
|
+
__name(bz, "bz");
|
|
14999
|
+
async function phb(session) {
|
|
15000
|
+
const ranks = await ctx.database.get("mcdle_rank", {}, {
|
|
15001
|
+
limit: cfg.maxRank,
|
|
15002
|
+
sort: { totalSuccessCount: "desc" }
|
|
15003
|
+
});
|
|
15004
|
+
if (!ranks || ranks.length === 0) {
|
|
15005
|
+
await sendMsg(session, "暂无排行榜数据");
|
|
15006
|
+
return;
|
|
15007
|
+
}
|
|
15008
|
+
const text = "MCDLE 排行榜:\n" + ranks.map((r, i) => `${i + 1}. ${r.username} ${r.totalSuccessCount}`).join("\n") + "\n...";
|
|
15009
|
+
await sendMsg(session, text);
|
|
15010
|
+
}
|
|
15011
|
+
__name(phb, "phb");
|
|
15012
|
+
function compareData(guess, answer) {
|
|
15013
|
+
const result = { ...guess };
|
|
15014
|
+
for (const key in guess) {
|
|
15015
|
+
if (key === "initial_release") {
|
|
15016
|
+
const guessVersion = normalizeVersion(guess[key]);
|
|
15017
|
+
const answerVersion = normalizeVersion(answer[key]);
|
|
15018
|
+
if (guessVersion === answerVersion) {
|
|
15019
|
+
result[`${key}_gui`] = "true";
|
|
15020
|
+
} else {
|
|
15021
|
+
const guessParts = guessVersion.split(".").map((part) => parseInt(part, 10) || 0);
|
|
15022
|
+
const answerParts = answerVersion.split(".").map((part) => parseInt(part, 10) || 0);
|
|
15023
|
+
let setFlag = false;
|
|
15024
|
+
for (let i = 0; i < Math.max(guessParts.length, answerParts.length); i++) {
|
|
15025
|
+
const g = guessParts[i] || 0;
|
|
15026
|
+
const a = answerParts[i] || 0;
|
|
15027
|
+
if (g < a) {
|
|
15028
|
+
result[`${key}_gui`] = "false_up";
|
|
15029
|
+
setFlag = true;
|
|
15030
|
+
break;
|
|
15031
|
+
} else if (g > a) {
|
|
15032
|
+
result[`${key}_gui`] = "false_down";
|
|
15033
|
+
setFlag = true;
|
|
15034
|
+
break;
|
|
15035
|
+
}
|
|
15036
|
+
}
|
|
15037
|
+
if (!setFlag) {
|
|
15038
|
+
result[`${key}_gui`] = "true";
|
|
15039
|
+
}
|
|
15040
|
+
}
|
|
15041
|
+
} else if (typeof guess[key] === "number" && typeof answer[key] === "number") {
|
|
15042
|
+
if (guess[key] === answer[key]) {
|
|
15043
|
+
result[`${key}_gui`] = "true";
|
|
15044
|
+
} else if (guess[key] < answer[key]) {
|
|
15045
|
+
result[`${key}_gui`] = "false_up";
|
|
15046
|
+
} else {
|
|
15047
|
+
result[`${key}_gui`] = "false_down";
|
|
15048
|
+
}
|
|
15049
|
+
} else if (Array.isArray(guess[key]) && Array.isArray(answer[key])) {
|
|
15050
|
+
const guessArr = guess[key];
|
|
15051
|
+
const answerArr = answer[key];
|
|
15052
|
+
const intersection = guessArr.filter((x) => answerArr.includes(x));
|
|
15053
|
+
if (intersection.length === guessArr.length && intersection.length === answerArr.length) {
|
|
15054
|
+
result[`${key}_gui`] = "true";
|
|
15055
|
+
} else if (intersection.length > 0) {
|
|
15056
|
+
result[`${key}_gui`] = "mixed";
|
|
15057
|
+
} else {
|
|
15058
|
+
result[`${key}_gui`] = "false";
|
|
15059
|
+
}
|
|
15060
|
+
} else if (guess[key] === answer[key]) {
|
|
15061
|
+
result[`${key}_gui`] = "true";
|
|
15062
|
+
} else {
|
|
15063
|
+
result[`${key}_gui`] = "false";
|
|
15064
|
+
}
|
|
15065
|
+
}
|
|
15066
|
+
return result;
|
|
15067
|
+
}
|
|
15068
|
+
__name(compareData, "compareData");
|
|
15069
|
+
async function updateRank(userId, username, mode) {
|
|
15070
|
+
let rankRecord = await ctx.database.get("mcdle_rank", { userId });
|
|
15071
|
+
if (!rankRecord || rankRecord.length === 0) {
|
|
15072
|
+
rankRecord = [await ctx.database.create("mcdle_rank", {
|
|
15073
|
+
userId,
|
|
15074
|
+
username,
|
|
15075
|
+
mobSuccessCount: 0,
|
|
15076
|
+
itemSuccessCount: 0,
|
|
15077
|
+
blockSuccessCount: 0,
|
|
15078
|
+
totalSuccessCount: 0
|
|
15079
|
+
})];
|
|
15080
|
+
}
|
|
15081
|
+
const record = rankRecord[0];
|
|
15082
|
+
const updates = {
|
|
15083
|
+
username,
|
|
15084
|
+
totalSuccessCount: record.totalSuccessCount + 1
|
|
15085
|
+
};
|
|
15086
|
+
if (mode === "mob") updates.mobSuccessCount = record.mobSuccessCount + 1;
|
|
15087
|
+
else if (mode === "item") updates.itemSuccessCount = record.itemSuccessCount + 1;
|
|
15088
|
+
else updates.blockSuccessCount = record.blockSuccessCount + 1;
|
|
15089
|
+
await ctx.database.set("mcdle_rank", { userId }, updates);
|
|
15090
|
+
}
|
|
15091
|
+
__name(updateRank, "updateRank");
|
|
15092
|
+
async function generateAndSendComparison(session, guesses) {
|
|
15093
|
+
if (guesses.length === 0) {
|
|
15094
|
+
await sendMsg(session, "暂无猜测结果");
|
|
15095
|
+
return;
|
|
15096
|
+
}
|
|
15097
|
+
const lastGuess = guesses[guesses.length - 1];
|
|
15098
|
+
let resultText = "";
|
|
15099
|
+
if (lastGuess.wiki_image_url) {
|
|
15100
|
+
resultText += `${import_koishi.h.image(lastGuess.wiki_image_url)}
|
|
15101
|
+
`;
|
|
15102
|
+
if (lastGuess.chinese_title) {
|
|
15103
|
+
resultText += `名称:${lastGuess.chinese_title}
|
|
15104
|
+
`;
|
|
15105
|
+
}
|
|
15106
|
+
}
|
|
15107
|
+
for (const key in lastGuess) {
|
|
15108
|
+
if (key.endsWith("_gui")) continue;
|
|
15109
|
+
if (key === "id" || key === "title" || key === "url" || key === "image_url") continue;
|
|
15110
|
+
if (key === "wiki_image_url" || key === "chinese_title") continue;
|
|
15111
|
+
const guiKey = `${key}_gui`;
|
|
15112
|
+
const guiStatus = lastGuess[guiKey];
|
|
15113
|
+
let statusEmoji = "❓";
|
|
15114
|
+
if (guiStatus === "true") statusEmoji = "🟩";
|
|
15115
|
+
else if (guiStatus === "mixed") statusEmoji = "🟨";
|
|
15116
|
+
else if (guiStatus === "false") statusEmoji = "🟥";
|
|
15117
|
+
else if (guiStatus === "false_up") statusEmoji = "🟥⬆️";
|
|
15118
|
+
else if (guiStatus === "false_down") statusEmoji = "🟥⬇️";
|
|
15119
|
+
const displayKey = keyMap[key] || key;
|
|
15120
|
+
let value = lastGuess[key];
|
|
15121
|
+
if (Array.isArray(value)) {
|
|
15122
|
+
value = value.map((v) => {
|
|
15123
|
+
if (typeof v === "string" && valueMap[key]?.[v]) {
|
|
15124
|
+
return valueMap[key][v];
|
|
15125
|
+
}
|
|
15126
|
+
return v;
|
|
15127
|
+
}).join("、");
|
|
15128
|
+
} else if (typeof value === "string") {
|
|
15129
|
+
if (valueMap[key]?.[value]) {
|
|
15130
|
+
value = valueMap[key][value];
|
|
15131
|
+
}
|
|
15132
|
+
}
|
|
15133
|
+
resultText += `${displayKey}: ${value} ${statusEmoji}
|
|
15134
|
+
`;
|
|
15135
|
+
}
|
|
15136
|
+
await sendMsg(session, resultText);
|
|
15137
|
+
}
|
|
15138
|
+
__name(generateAndSendComparison, "generateAndSendComparison");
|
|
15139
|
+
function normalizeVersion(versionString) {
|
|
15140
|
+
if (versionString === "pre-alpha") return "0";
|
|
15141
|
+
if (versionString.startsWith("Alpha ")) return "0.0.0.0." + versionString.replace("Alpha ", "");
|
|
15142
|
+
if (versionString.startsWith("Beta ")) return "0." + versionString.replace("Beta ", "");
|
|
15143
|
+
switch (versionString) {
|
|
15144
|
+
case "2.0":
|
|
15145
|
+
return "1.5.1.1";
|
|
15146
|
+
case "15w14a":
|
|
15147
|
+
return "1.8.3.1";
|
|
15148
|
+
case "1.RV-Pre1":
|
|
15149
|
+
return "1.9.2.1";
|
|
15150
|
+
case "3D Shareware v1.34":
|
|
15151
|
+
return "1.13.2.1";
|
|
15152
|
+
case "20w14∞":
|
|
15153
|
+
return "1.14.4.1";
|
|
15154
|
+
case "22w13oneBlockAtATime":
|
|
15155
|
+
return "1.18.2.1";
|
|
15156
|
+
case "23w13a_or_b":
|
|
15157
|
+
return "1.19.4.1";
|
|
15158
|
+
case "24w14potato":
|
|
15159
|
+
return "1.20.4.1";
|
|
15160
|
+
case "25w14craftmine":
|
|
15161
|
+
return "1.21.5.1";
|
|
15162
|
+
}
|
|
15163
|
+
return versionString;
|
|
15164
|
+
}
|
|
15165
|
+
__name(normalizeVersion, "normalizeVersion");
|
|
15166
|
+
async function sendMsg(session, msg) {
|
|
15167
|
+
if (cfg.atReply) {
|
|
15168
|
+
msg = `${import_koishi.h.at(session.userId)}${(0, import_koishi.h)("p", "")}${msg}`;
|
|
15169
|
+
}
|
|
15170
|
+
if (cfg.quoteReply) {
|
|
15171
|
+
msg = `${import_koishi.h.quote(session.messageId)}${msg}`;
|
|
15172
|
+
}
|
|
15173
|
+
await session.send(msg);
|
|
15174
|
+
}
|
|
15175
|
+
__name(sendMsg, "sendMsg");
|
|
15176
|
+
}
|
|
15177
|
+
__name(apply, "apply");
|
|
15161
15178
|
// Annotate the CommonJS export names for ESM import in node:
|
|
15162
15179
|
0 && (module.exports = {
|
|
15163
15180
|
Config,
|