koishi-plugin-ggcevo 1.1.20 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.ts CHANGED
@@ -26,7 +26,6 @@ export interface Config {
26
26
  export declare const Config: Schema<Config>;
27
27
  export declare const inject: {
28
28
  required: string[];
29
- optional: string[];
30
29
  };
31
30
  export declare const ItemConfig: Record<number, string>;
32
31
  export declare const LotteryPoolConfig: Record<number, string>;
package/lib/index.js CHANGED
@@ -66,8 +66,7 @@ var Config = import_koishi.Schema.intersect([
66
66
  }).description("调试模式")
67
67
  ]);
68
68
  var inject = {
69
- required: ["database"],
70
- optional: ["puppeteer"]
69
+ required: ["database"]
71
70
  };
72
71
  var ItemConfig = {
73
72
  1: "金币",
@@ -1004,163 +1003,6 @@ ${rewardLines.join("\n")}` : "";
1004
1003
  📊 该星系累计探索 ${newStat.total_count} 次,成功 ${newStat.success_count} 次,累计获得 ${newStat.total_coins} 金币
1005
1004
  🛸 可再次使用 探索 命令选择星系开启新的探索。`;
1006
1005
  });
1007
- const renderMenuImage = /* @__PURE__ */ __name(async (html, session) => {
1008
- const logger = ctx.logger("ggcevo");
1009
- if (!ctx.puppeteer) {
1010
- logger.warn("[menu-render] 未安装 puppeteer 服务, 降级为文本提示");
1011
- return "⚠️ 未安装 puppeteer 服务,无法渲染菜单图片。请安装 `koishi-plugin-puppeteer` 或 `@shangxueink/puppeteer-without-canvas` 并启用其一。";
1012
- }
1013
- const page = await ctx.puppeteer.page();
1014
- try {
1015
- await page.setViewport({ width: 640, height: 800, deviceScaleFactor: 4 });
1016
- logger.info("[menu-render] 页面已创建, 正在写入 HTML...");
1017
- await page.setContent(html, { waitUntil: "networkidle0" });
1018
- logger.info("[menu-render] HTML 写入完成, 正在截图(PNG)...");
1019
- const img = await page.screenshot({ type: "png", fullPage: true });
1020
- const dataUrl = `data:image/png;base64,${img.toString("base64")}`;
1021
- const sizeKB = (img.length / 1024).toFixed(1);
1022
- logger.info("[menu-render] 截图完成(PNG), 体积 %s KB, 生成 data URL 长度 %d", sizeKB, dataUrl.length);
1023
- if (session?.bot && session.platform === "qq") {
1024
- const bot = session.bot;
1025
- if (bot.config && bot.config.uploadThreshold !== 10 * 1024 * 1024) {
1026
- bot.config.uploadThreshold = 10 * 1024 * 1024;
1027
- logger.info("[menu-render] 已调整 QQ 上传阈值至 10MB, 菜单图改走普通上传通道");
1028
- }
1029
- if (config.debugEnabled) {
1030
- try {
1031
- const uploadPath = session.isDirect ? `/v2/users/${session.userId}/files` : `/v2/groups/${session.channelId}/files`;
1032
- const uploadRes = await session.bot.http.post(uploadPath, {
1033
- file_type: 1,
1034
- file_data: img.toString("base64")
1035
- });
1036
- logger.info("[menu-render] QQ 上传探测成功: %o", uploadRes);
1037
- } catch (e) {
1038
- logger.warn("[menu-render] QQ 上传探测失败: %s | 响应: %o", e?.message, e?.response?.data);
1039
- }
1040
- }
1041
- }
1042
- return import_koishi.h.image(dataUrl);
1043
- } catch (e) {
1044
- logger.warn("[menu-render] 渲染菜单图片失败: %o", e);
1045
- return "⚠️ 菜单图片渲染失败,请查看日志。";
1046
- } finally {
1047
- await page.close();
1048
- logger.info("[menu-render] 页面已关闭");
1049
- }
1050
- }, "renderMenuImage");
1051
- const buildMenuHtml = /* @__PURE__ */ __name((title, subtitle, groups) => {
1052
- const palette = ["#4a7dff", "#9b59b6", "#e67e22", "#27ae60", "#e74c3c", "#16a085", "#f39c12", "#8e44ad", "#2980b9", "#d35400", "#2ecc71", "#c0392b"];
1053
- const groupHtml = groups.map((group) => {
1054
- const itemRows = group.items.map((item, i) => {
1055
- const color = palette[i % palette.length];
1056
- return `
1057
- <div class="item">
1058
- <div class="icon" style="background: ${color}">${item.icon}</div>
1059
- <div class="info">
1060
- <div class="name">${item.name}</div>
1061
- <div class="desc">${item.desc}</div>
1062
- </div>
1063
- </div>`;
1064
- }).join("");
1065
- return `
1066
- <div class="group">
1067
- <div class="group-title">${group.title}</div>
1068
- <div class="list">${itemRows}</div>
1069
- </div>`;
1070
- }).join("");
1071
- return `<!DOCTYPE html>
1072
- <html lang="zh">
1073
- <head>
1074
- <meta charset="UTF-8">
1075
- <style>
1076
- body { margin: 0; padding: 24px 28px; background:
1077
- repeating-linear-gradient(45deg, rgba(255,255,255,0.02) 0 1px, transparent 1px 2px),
1078
- linear-gradient(135deg, #1b2a4a 0%, #0f1a33 100%);
1079
- font-family: "Microsoft YaHei", "PingFang SC", sans-serif; color: #e8eefc; }
1080
- .header { text-align: center; padding-bottom: 18px; border-bottom: 2px solid rgba(120,160,255,0.35); }
1081
- .title { font-size: 32px; font-weight: bold; letter-spacing: 6px; color: #8fc0ff; text-shadow: 0 0 18px rgba(90,140,255,0.45); }
1082
- .subtitle { margin-top: 8px; font-size: 14px; color: #93a6c8; }
1083
- .group { margin-top: 22px; }
1084
- .group-title { font-size: 15px; font-weight: bold; color: #ffd98a; letter-spacing: 3px; margin-bottom: 10px; padding-left: 10px; border-left: 3px solid #ffd98a; }
1085
- .list { display: flex; flex-direction: column; gap: 12px; }
1086
- .item { display: flex; align-items: center; gap: 14px; background: rgba(255,255,255,0.07); border: 1px solid rgba(140,170,255,0.22); border-radius: 12px; padding: 12px 16px; }
1087
- .icon { width: 40px; height: 40px; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 19px; font-weight: bold; color: #fff; flex-shrink: 0; }
1088
- .info { flex: 1; }
1089
- .name { font-size: 20px; font-weight: bold; color: #ffffff; }
1090
- .desc { margin-top: 4px; font-size: 13px; color: #9db1d8; line-height: 1.5; }
1091
- .footer { margin-top: 24px; text-align: center; font-size: 12px; color: #6b7ea6; }
1092
- </style>
1093
- </head>
1094
- <body>
1095
- <div class="header">
1096
- <div class="title">${title}</div>
1097
- <div class="subtitle">${subtitle}</div>
1098
- </div>
1099
- ${groupHtml}
1100
- <div class="footer">输入上方指令名即可使用对应功能</div>
1101
- </body>
1102
- </html>`;
1103
- }, "buildMenuHtml");
1104
- const gameMenuGroups = [
1105
- {
1106
- title: "每日玩法",
1107
- items: [
1108
- { icon: "签", name: "签到", desc: "每日签到,获取签到券/补签券等奖励,每月首次签到可领津贴" },
1109
- { icon: "补", name: "补签", desc: "使用补签券补签漏签的日期" },
1110
- { icon: "抽", name: "抽奖", desc: "使用金币/咕咕币/兑换券参与抽奖,选项:-p 奖池ID -c 次数" },
1111
- { icon: "挖", name: "挖矿", desc: "挂机挖矿,每半小时收益4金币,上限24小时,领取后自动进入下一轮" },
1112
- { icon: "探", name: "探索", desc: "选择星系进行12小时探索,探索结束领取金币/道具收益" }
1113
- ]
1114
- },
1115
- {
1116
- title: "物品与背包",
1117
- items: [
1118
- { icon: "兑", name: "兑换列表", desc: "查看可兑换物品列表及兑换券消耗" },
1119
- { icon: "换", name: "兑换", desc: "使用兑换券兑换皮肤/宠物/入场特效/角色冠名权等物品" },
1120
- { icon: "包", name: "背包", desc: "查看自己背包中的物品" },
1121
- { icon: "用", name: "使用", desc: "使用指定物品(如赎罪券等)" },
1122
- { icon: "信", name: "个人信息", desc: "查看自己的签到统计与个人信息" }
1123
- ]
1124
- },
1125
- {
1126
- title: "活动",
1127
- items: [
1128
- { icon: "活", name: "活动列表", desc: "查看进行中/未开始的活动" },
1129
- { icon: "领", name: "领取活动", desc: "领取指定(或最新)活动奖励" }
1130
- ]
1131
- }
1132
- ];
1133
- const handleMenuGroups = [
1134
- {
1135
- title: "句柄管理",
1136
- items: [
1137
- { icon: "绑", name: "绑定句柄", desc: "绑定星际争霸2游戏句柄,格式:[区域ID]-S2-[服务器ID]-[档案ID]" },
1138
- { icon: "切", name: "切换", desc: "切换正在使用的游戏句柄" },
1139
- { icon: "解", name: "解绑句柄", desc: "解除绑定某个游戏句柄" }
1140
- ]
1141
- },
1142
- {
1143
- title: "查询与检测",
1144
- items: [
1145
- { icon: "句", name: "句柄", desc: "查询自己(或他人)已绑定的游戏句柄" },
1146
- { icon: "查", name: "查询", desc: "查询某游戏句柄是否已被绑定" },
1147
- { icon: "图", name: "地图检测", desc: "查询已配置地图的在线状态与离线统计" },
1148
- { icon: "封", name: "封禁记录", desc: "查询自己(或他人)的封禁记录,支持翻页" }
1149
- ]
1150
- }
1151
- ];
1152
- ctx.command("ggcevo/咕咕之战", "查看咕咕之战玩法指令菜单").action(async (argv) => {
1153
- const session = argv.session;
1154
- const html = buildMenuHtml("咕咕之战", "游戏玩法指令(受宵禁影响的玩法见对应指令说明)", gameMenuGroups);
1155
- const result = await renderMenuImage(html, session);
1156
- return typeof result === "string" ? result : (0, import_koishi.h)("quote", { id: session.messageId }, result);
1157
- });
1158
- ctx.command("ggcevo/菜单", "查看 GGCEVO 句柄管理指令菜单").alias("ggcevo指令").action(async (argv) => {
1159
- const session = argv.session;
1160
- const html = buildMenuHtml("GGCEVO", "句柄管理与查询指令", handleMenuGroups);
1161
- const result = await renderMenuImage(html, session);
1162
- return typeof result === "string" ? result : (0, import_koishi.h)("quote", { id: session.messageId }, result);
1163
- });
1164
1006
  ctx.command("ggcevo/兑换 <name:string>").action(async (argv, name2) => {
1165
1007
  const session = argv.session;
1166
1008
  const adminRegistTip = config.exchangeAdminName ? `
@@ -2970,6 +2812,187 @@ ${rewardLines.join("\n")}` : "";
2970
2812
  }
2971
2813
  return "已退出封禁记录查询。";
2972
2814
  });
2815
+ const MENU_PREFIX = "ggg:";
2816
+ const menuCategories = [
2817
+ {
2818
+ key: "daily",
2819
+ label: "📅 每日玩法",
2820
+ desc: "签到 / 挖矿 / 探索 / 补签",
2821
+ items: [
2822
+ { key: "sign", label: "签到", desc: "每日签到, 获取金币与咕咕币", cmd: "签到" },
2823
+ { key: "mine", label: "挖矿", desc: "领取挂机挖矿收益(每半小时4金币)", cmd: "挖矿" },
2824
+ { key: "explore", label: "探索", desc: "选择星系进行12小时探索", cmd: "探索" },
2825
+ { key: "makeup", label: "补签", desc: "使用补签券补签漏签日期", cmd: "补签" }
2826
+ ]
2827
+ },
2828
+ {
2829
+ key: "bag",
2830
+ label: "🎒 物品背包",
2831
+ desc: "背包 / 个人信息 / 使用",
2832
+ items: [
2833
+ { key: "inv", label: "背包", desc: "查看自己的物品背包", cmd: "背包" },
2834
+ { key: "profile", label: "个人信息", desc: "查看签到统计与个人信息", cmd: "个人信息" },
2835
+ { key: "use", label: "使用 <名称>", desc: "使用指定物品(如赎罪券等)", cmd: "使用", input: "请输入要使用的物品名称" }
2836
+ ]
2837
+ },
2838
+ {
2839
+ key: "lottery",
2840
+ label: "🎲 抽奖兑换",
2841
+ desc: "抽奖 / 抽奖概率 / 兑换 / 兑换列表",
2842
+ items: [
2843
+ { key: "lottery", label: "抽奖", desc: "抽奖, 可加选项 -p 奖池ID -c 次数", cmd: "抽奖" },
2844
+ { key: "odds", label: "抽奖概率", desc: "查看各奖池抽奖概率与保底说明", cmd: "抽奖概率" },
2845
+ { key: "exchange", label: "兑换 <名称>", desc: "使用兑换券兑换物品", cmd: "兑换", input: "请输入要兑换的物品名称" },
2846
+ { key: "exchangeList", label: "兑换列表", desc: "查看可兑换物品列表", cmd: "兑换列表" }
2847
+ ]
2848
+ },
2849
+ {
2850
+ key: "activity",
2851
+ label: "🎉 活动",
2852
+ desc: "活动列表 / 领取活动",
2853
+ items: [
2854
+ { key: "actList", label: "活动列表", desc: '查看进行中的活动(参数"全部"查看全部)', cmd: "活动列表" },
2855
+ { key: "actClaim", label: "领取活动", desc: "领取指定(或最新)活动奖励", cmd: "领取活动" }
2856
+ ]
2857
+ },
2858
+ {
2859
+ key: "handle",
2860
+ label: "🔗 句柄绑定",
2861
+ desc: "绑定 / 句柄 / 切换 / 查询 / 解绑 / 迁移",
2862
+ items: [
2863
+ { key: "bind", label: "绑定 <句柄>", desc: "绑定星际争霸2游戏句柄", cmd: "绑定", input: "请输入游戏句柄(格式: 区域-S2-服务器-档案, 如 5-S2-1-1234567)" },
2864
+ { key: "list", label: "句柄", desc: "查询已绑定的游戏句柄", cmd: "句柄" },
2865
+ { key: "switch", label: "切换", desc: "切换正在使用的游戏句柄", cmd: "切换" },
2866
+ { key: "check", label: "查询", desc: "查询某句柄是否已被绑定", cmd: "查询" },
2867
+ { key: "unbind", label: "解绑", desc: "解除绑定某个游戏句柄", cmd: "解绑" },
2868
+ { key: "migrate", label: "迁移 <QQ>", desc: "将指定QQ号绑定的句柄迁移到当前账号", cmd: "迁移", input: "请输入要迁移的QQ号" }
2869
+ ]
2870
+ },
2871
+ {
2872
+ key: "query",
2873
+ label: "📊 查询信息",
2874
+ desc: "地图检测 / 封禁记录 / 签到奖励",
2875
+ items: [
2876
+ { key: "map", label: "地图检测", desc: "查询已配置地图的检测状态", cmd: "地图检测" },
2877
+ { key: "ban", label: "封禁记录", desc: "查询句柄的封禁记录", cmd: "封禁记录" },
2878
+ { key: "reward", label: "签到奖励", desc: "查看签到奖励规则说明", cmd: "签到奖励" }
2879
+ ]
2880
+ }
2881
+ ];
2882
+ const buildPlainMenu = /* @__PURE__ */ __name((category) => {
2883
+ if (category) {
2884
+ return [`🐤 咕咕之战 · ${category.label}`, ...category.items.map((i) => `${i.label}:${i.desc}`)].join("\n");
2885
+ }
2886
+ return [
2887
+ "🐤 咕咕之战菜单",
2888
+ ...menuCategories.map((c) => `${c.label}
2889
+ ${c.items.map((i) => i.label).join(" / ")}`),
2890
+ "",
2891
+ "提示: 当前平台不支持按钮菜单, 请直接输入对应指令使用。"
2892
+ ].join("\n\n");
2893
+ }, "buildPlainMenu");
2894
+ const sendMenu = /* @__PURE__ */ __name(async (session, category) => {
2895
+ if (session.platform !== "qq") {
2896
+ await session.send(buildPlainMenu(category));
2897
+ return;
2898
+ }
2899
+ let title;
2900
+ let lines;
2901
+ let rows;
2902
+ if (category) {
2903
+ title = `🐤 咕咕之战 · ${category.label}`;
2904
+ lines = [
2905
+ ...category.items.map((item, idx) => `${idx + 1}. **${item.label}**:${item.desc}`),
2906
+ "",
2907
+ "点击下方按钮即可使用对应功能, 点「⬅️ 返回」回到主菜单。"
2908
+ ];
2909
+ rows = [
2910
+ category.items.map((item) => ({
2911
+ id: `${MENU_PREFIX}run:${category.key}:${item.key}`,
2912
+ label: item.label,
2913
+ input: item.input,
2914
+ primary: item.key === "sign"
2915
+ })),
2916
+ [{ id: `${MENU_PREFIX}back`, label: "⬅️ 返回" }]
2917
+ ];
2918
+ } else {
2919
+ title = "🐤 咕咕之战菜单";
2920
+ lines = [
2921
+ ...menuCategories.map((cat, idx) => `${idx + 1}. ${cat.label}:${cat.desc}`),
2922
+ "",
2923
+ "点击下方分类按钮进入对应功能菜单。"
2924
+ ];
2925
+ rows = [
2926
+ [
2927
+ { id: `${MENU_PREFIX}cat:daily`, label: "📅 每日玩法", primary: true },
2928
+ { id: `${MENU_PREFIX}cat:bag`, label: "🎒 物品背包" }
2929
+ ],
2930
+ [
2931
+ { id: `${MENU_PREFIX}cat:lottery`, label: "🎲 抽奖兑换" },
2932
+ { id: `${MENU_PREFIX}cat:activity`, label: "🎉 活动" }
2933
+ ],
2934
+ [
2935
+ { id: `${MENU_PREFIX}cat:handle`, label: "🔗 句柄绑定" },
2936
+ { id: `${MENU_PREFIX}cat:query`, label: "📊 查询信息" }
2937
+ ]
2938
+ ];
2939
+ }
2940
+ const elements = [
2941
+ (0, import_koishi.h)("qq:markdown", `**${title}**
2942
+
2943
+ ${lines.join("\n")}`),
2944
+ ...rows.map((row) => (0, import_koishi.h)("button-group", row.map((btn) => (0, import_koishi.h)("button", {
2945
+ id: btn.id,
2946
+ class: btn.primary ? "primary" : void 0,
2947
+ type: btn.input ? "input" : void 0,
2948
+ text: btn.input
2949
+ }, btn.label))))
2950
+ ];
2951
+ try {
2952
+ await session.send(elements);
2953
+ } catch (e) {
2954
+ ctx.logger("ggcevo").warn("咕咕之战菜单 Markdown 发送失败, 回退为纯文本: %o", e);
2955
+ await session.send(buildPlainMenu(category));
2956
+ }
2957
+ }, "sendMenu");
2958
+ const runMenuCommand = /* @__PURE__ */ __name(async (session, name2, args = []) => {
2959
+ session.messageId = "";
2960
+ await session.execute({ name: name2, args, options: {} });
2961
+ }, "runMenuCommand");
2962
+ ctx.command("咕咕之战").alias("菜单").usage("生成咕咕之战内容分类菜单(QQ 官方机器人支持按钮点击使用)").action(async (argv) => {
2963
+ await sendMenu(argv.session, void 0);
2964
+ });
2965
+ ctx.on("interaction/button", async (session) => {
2966
+ const button = session.event?.button;
2967
+ if (!button || typeof button.id !== "string" || !button.id.startsWith(MENU_PREFIX)) return;
2968
+ const parts = button.id.split(":");
2969
+ try {
2970
+ if (parts[1] === "back") {
2971
+ await sendMenu(session, void 0);
2972
+ } else if (parts[1] === "cat") {
2973
+ const category = menuCategories.find((c) => c.key === parts[2]);
2974
+ if (category) await sendMenu(session, category);
2975
+ } else if (parts[1] === "run") {
2976
+ const category = menuCategories.find((c) => c.key === parts[2]);
2977
+ const item = category?.items.find((i) => i.key === parts[3]);
2978
+ if (!category || !item || !item.cmd) return;
2979
+ if (item.input) {
2980
+ const value = String(button.data ?? "").trim();
2981
+ if (!value) {
2982
+ await session.send(`请输入${item.label}后重试。`);
2983
+ return;
2984
+ }
2985
+ await runMenuCommand(session, item.cmd, [value]);
2986
+ } else {
2987
+ await runMenuCommand(session, item.cmd);
2988
+ }
2989
+ }
2990
+ } catch (e) {
2991
+ ctx.logger("ggcevo").warn("咕咕之战按钮回调处理失败: %o", e);
2992
+ await session.send("⚠️ 操作失败, 请重试或直接输入指令使用。").catch(() => {
2993
+ });
2994
+ }
2995
+ });
2973
2996
  }
2974
2997
  __name(apply, "apply");
2975
2998
  function toBeijingTime(isoString) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-ggcevo",
3
3
  "description": "GGCEVO 综合插件:星际争霸2游戏句柄绑定 + 签到/抽奖/兑换/背包/活动系统等虚拟物品玩法",
4
- "version": "1.1.20",
4
+ "version": "1.3.0",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [
@@ -24,23 +24,10 @@
24
24
  "service": {
25
25
  "required": [
26
26
  "database"
27
- ],
28
- "optional": [
29
- "puppeteer"
30
27
  ]
31
28
  }
32
29
  },
33
30
  "peerDependencies": {
34
- "koishi": "^4.18.7",
35
- "koishi-plugin-puppeteer": "^3.9.0",
36
- "@shangxueink/puppeteer-without-canvas": "^3.0.7"
37
- },
38
- "peerDependenciesMeta": {
39
- "koishi-plugin-puppeteer": {
40
- "optional": true
41
- },
42
- "@shangxueink/puppeteer-without-canvas": {
43
- "optional": true
44
- }
31
+ "koishi": "^4.18.7"
45
32
  }
46
33
  }
package/readme.md CHANGED
@@ -96,14 +96,13 @@ npm install koishi-plugin-ggcevo
96
96
  | `查询 [handle]` | — | 查询某游戏句柄是否已被绑定 |
97
97
  | `解绑 [index]` | 解绑句柄 | 解除绑定某个游戏句柄 |
98
98
  | `迁移 <qq>` | — | 将指定QQ号绑定的全部游戏句柄迁移到当前账号(用于从 onebot 机器人切换至 QQ 官方机器人后,将旧 QQ 号下绑定的句柄转移到新的 openid 身份下) |
99
- | `地图检测` | — | 查询已配置地图(`mapMonitorMapIds`)的检测状态:在线状态、最后状态变更时间、24h/30d离线次数、近期事件。当所有配置地图均离线时,底部额外提示推荐游玩的地图名称(需配置 `mapMonitorRecommendMapName`)。需开启 `mapMonitorEnabled` 且配置地图ID |
100
- | `菜单` | ggcevo指令 | 渲染 GGCEVO 句柄管理指令菜单图片(绑定/句柄/切换/查询/解绑/地图检测/封禁记录)。需安装启用 puppeteer 服务(`koishi-plugin-puppeteer` 或 `@shangxueink/puppeteer-without-canvas` 任选其一) |
99
+ | `地图检测` | — | — | 查询已配置地图(`mapMonitorMapIds`)的检测状态:在线状态、最后状态变更时间、24h/30d离线次数、近期事件。当所有配置地图均离线时,底部额外提示推荐游玩的地图名称(需配置 `mapMonitorRecommendMapName`)。需开启 `mapMonitorEnabled` 且配置地图ID |
101
100
 
102
101
  ### 签到与虚拟物品(ggcevo)
103
102
 
104
103
  | 指令 | 别名 | 权限 | 说明 |
105
104
  | --- | --- | --- | --- |
106
- | `咕咕之战` | — | — | 渲染咕咕之战玩法指令菜单图片(签到/抽奖/兑换/背包/个人信息/兑换列表/活动列表/领取活动/补签/使用/挖矿/探索)。需安装启用 puppeteer 服务(`koishi-plugin-puppeteer` 或 `@shangxueink/puppeteer-without-canvas` 任选其一) |
105
+ | `咕咕之战` | 菜单 | — | 生成咕咕之战内容分类菜单(「每日玩法」「物品背包」「抽奖兑换」「活动」「句柄绑定」「查询信息」六类,仅收录普通用户可用指令)。QQ 官方机器人下使用 Markdown+按钮渲染,点击分类按钮进入子菜单、点击指令按钮直接执行(兑换/使用/绑定/迁移等需参数的指令支持输入框按钮);其余平台自动回退为纯文本菜单 |
107
106
  | `签到` | — | — | 每日签到,获取奖励并发放签到券/补签券等。每月首次签到时,若签到者的游戏句柄匹配管理员福利文档记录,额外发放 50 咕咕币津贴(仅校验句柄) |
108
107
  | `挖矿` | — | — | 领取挂机挖矿收益(咕咕之战玩法)。每半小时收益 4 金币,单次存储上限 24 小时,领取后立即进入下一轮挖矿。累计挖矿总时长与累计收益金币数会被记录统计。受宵禁影响:17:00-24:00 禁止领取 |
109
108
  | `探索` | — | — | 选择星系进行 12 小时探索,结束后领取收益(咕咕之战玩法)。星系:天枢(成功率100%,成功80金币)、赤潮(成功率60%,成功120金币/失败60金币)、千帆(成功率80%,成功50金币/失败25金币,成功时独立概率获得补签券×1(10%)、咕咕币1-3枚(50%),失败无道具)。金币/道具发放到背包,按星系累计统计探索次数/成功次数/累计金币。受宵禁影响:17:00-24:00 禁止 |
@@ -174,6 +173,20 @@ npm install koishi-plugin-ggcevo
174
173
 
175
174
  ## 更新日志
176
175
 
176
+ ### v1.3.0
177
+
178
+ 咕咕之战菜单改为 QQ 官方机器人 Markdown 按钮菜单(取代 v1.2.0 移除的图片渲染方案,不再依赖 puppeteer)。
179
+
180
+ - **新增指令 `咕咕之战`**(别名 `菜单`):生成咕咕之战内容分类菜单,分为「每日玩法」「物品背包」「抽奖兑换」「活动」「句柄绑定」「查询信息」六类,仅收录普通用户可用的指令(管理员指令不展示)
181
+ - **QQ 官方机器人按钮交互**:菜单使用 Markdown + 按钮渲染。点击分类按钮进入对应子菜单,点击指令按钮直接执行该指令;`兑换`/`使用`/`绑定`/`迁移` 等需要参数的指令使用输入框按钮,点击后在输入框内填写参数即可执行;子菜单底部提供「返回」按钮回到主菜单
182
+ - **纯文本回退**:非 QQ 平台(或 QQ Markdown 消息发送失败)时自动回退为纯文本分类菜单,保证其它平台可用
183
+ - **前置条件**:按钮回调依赖 QQ 官方机器人的 `INTERACTION_CREATE` 互动事件,需在适配器配置中订阅 `INTERACTIONS` 事件(未订阅时按钮不可用,菜单仍以文本展示)
184
+
185
+ ### v1.2.0
186
+
187
+ - **移除指令菜单功能**:删除 `咕咕之战` 与 `菜单`(别名 `ggcevo指令`)指令及其渲染代码(renderMenuImage / buildMenuHtml / 菜单分组数据)
188
+ - **移除 puppeteer 依赖**:删除对 `koishi-plugin-puppeteer` 与 `@shangxueink/puppeteer-without-canvas` 的可选依赖声明、`puppeteer` 服务注入及 `import type` 引用。插件不再依赖任何图片渲染服务
189
+
177
190
  ### v1.1.20
178
191
 
179
192
  - **修复 QQ 官方机器人无法发送菜单图**:经探测确认 QQ 官方上传接口直接上传 4.4MB PNG 可成功,失败源于适配器在文件超过默认阈值 3MB 时改走分片上传(upload_prepare)通道,而该通道在部分环境不可用且错误被静默吞掉。现于 QQ 官方环境下将上传阈值调大至 10MB,菜单图改走已验证可用的普通上传(file_data)通道