koishi-plugin-ggcevo-game 2.0.7 → 2.0.9

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/database.d.ts CHANGED
@@ -28,6 +28,8 @@ declare module 'koishi' {
28
28
  ggcevo_explore: explore;
29
29
  ggcevo_global_stats: GlobalStats;
30
30
  ggcevo_guess: guess;
31
+ roulettes: Roulette;
32
+ roulette_groups: RouletteGroup;
31
33
  }
32
34
  }
33
35
  export interface Backpack {
@@ -248,3 +250,12 @@ export interface bossweights {
248
250
  weight: number;
249
251
  lastSpawn: Date;
250
252
  }
253
+ export interface Roulette {
254
+ id: number;
255
+ items: string[];
256
+ }
257
+ export interface RouletteGroup {
258
+ id: number;
259
+ name: string;
260
+ items: number[];
261
+ }
package/lib/index.d.ts CHANGED
@@ -21,6 +21,7 @@ export interface Config {
21
21
  enablePlayRequirement: boolean;
22
22
  enableGuguBattle: boolean;
23
23
  enableMatchesRequirement: boolean;
24
+ signInGroupId: string[];
24
25
  }
25
26
  export declare const Config: Schema<Config>;
26
27
  export declare function apply(ctx: Context, config: Config): void;
package/lib/index.js CHANGED
@@ -7474,7 +7474,7 @@ var Config = import_koishi.Schema.intersect([
7474
7474
  proxyAgent: import_koishi.Schema.string().description("代理服务器地址"),
7475
7475
  enablePlayRequirement: import_koishi.Schema.boolean().description("开启签到需3天游戏记录(关闭时无限制)").default(false),
7476
7476
  enableCurfew: import_koishi.Schema.boolean().description("是否开启宵禁模式(18:00-24:00禁止群聊指令)").default(false),
7477
- enableGuguBattle: import_koishi.Schema.boolean().description("是否开启咕咕之战功能").default(true)
7477
+ enableGuguBattle: import_koishi.Schema.boolean().description("是否开启咕咕之战游戏功能").default(true)
7478
7478
  }).description("基础设置"),
7479
7479
  // 赛季与兑换配置组
7480
7480
  import_koishi.Schema.object({
@@ -7494,11 +7494,15 @@ var Config = import_koishi.Schema.intersect([
7494
7494
  }).description("对战限制"),
7495
7495
  // 通知系统配置组 - 新增违规提醒开关
7496
7496
  import_koishi.Schema.object({
7497
- groupId: import_koishi.Schema.array(import_koishi.Schema.string()).description("广播通知群组").default([]),
7497
+ groupId: import_koishi.Schema.array(import_koishi.Schema.string()).description("咕咕之战广播通知群组").default([]),
7498
7498
  checkInterval: import_koishi.Schema.number().description("大厅监控检查间隔(秒)").default(60),
7499
7499
  enableViolationAlert: import_koishi.Schema.boolean().description("启用违规玩家房间提醒").default(false)
7500
7500
  // 新增配置项
7501
- }).description("通知设置").collapse()
7501
+ }).description("通知设置").collapse(),
7502
+ // 新增:签到配置组
7503
+ import_koishi.Schema.object({
7504
+ signInGroupId: import_koishi.Schema.array(import_koishi.Schema.string()).description("允许签到的群组ID列表(为空则不限制)").default([])
7505
+ }).description("签到设置")
7502
7506
  ]);
7503
7507
  function apply(ctx, config) {
7504
7508
  ctx.model.extend("ggcevo_backpack", {
@@ -7804,6 +7808,21 @@ function apply(ctx, config) {
7804
7808
  }, {
7805
7809
  primary: ["handle", "itemId"]
7806
7810
  });
7811
+ ctx.model.extend("roulettes", {
7812
+ id: "unsigned",
7813
+ items: "list"
7814
+ }, {
7815
+ primary: "id",
7816
+ autoInc: true
7817
+ });
7818
+ ctx.model.extend("roulette_groups", {
7819
+ id: "unsigned",
7820
+ name: "string",
7821
+ items: "json"
7822
+ }, {
7823
+ primary: "id",
7824
+ autoInc: true
7825
+ });
7807
7826
  ctx.setInterval(async () => {
7808
7827
  const now = /* @__PURE__ */ new Date();
7809
7828
  await ctx.database.set(
@@ -8048,8 +8067,20 @@ function apply(ctx, config) {
8048
8067
  });
8049
8068
  }, 24 * 60 * 60 * 1e3);
8050
8069
  }
8070
+ const checkGroupAccess = /* @__PURE__ */ __name((session, featureName = "该功能") => {
8071
+ if (!config.signInGroupId?.length) return null;
8072
+ if (session.isDirect) {
8073
+ return `⛔ ${featureName}仅限在指定群组中使用,请前往指定的QQ群进行操作。`;
8074
+ }
8075
+ if (!config.signInGroupId.includes(session.guildId)) {
8076
+ return `⛔ 当前群组不允许使用${featureName},请前往指定的QQ群进行操作。`;
8077
+ }
8078
+ return null;
8079
+ }, "checkGroupAccess");
8051
8080
  ctx.command("ggcevo/抽奖").action(async (argv) => {
8052
8081
  const session = argv.session;
8082
+ const accessError = checkGroupAccess(session, "抽奖");
8083
+ if (accessError) return accessError;
8053
8084
  let winCount = 0;
8054
8085
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId, isActive: true });
8055
8086
  if (!profile) {
@@ -8079,14 +8110,17 @@ function apply(ctx, config) {
8079
8110
  const result = await gachaWithPity(ctx, handle);
8080
8111
  if (result) winCount++;
8081
8112
  }
8113
+ const [updatedRecord] = await ctx.database.get("ggcevo_sign", { handle });
8082
8114
  return [
8083
8115
  `🎰 您使用了${quantity}枚咕咕币`,
8084
8116
  winCount > 0 ? `🎉 其中获得${winCount}张兑换券!` : "💔 本次未获得任何兑换券",
8085
- `📊 当前保底进度:${record.pityCounter || 0}/90`
8117
+ `📊 当前保底进度:${updatedRecord?.pityCounter || 0}/90`
8086
8118
  ].join("\n");
8087
8119
  });
8088
8120
  ctx.command("ggcevo/单抽").action(async (argv) => {
8089
8121
  const session = argv.session;
8122
+ const accessError = checkGroupAccess(session, "单抽");
8123
+ if (accessError) return accessError;
8090
8124
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId, isActive: true });
8091
8125
  if (!profile) {
8092
8126
  return "🔒 需要先绑定游戏句柄。";
@@ -8114,6 +8148,8 @@ function apply(ctx, config) {
8114
8148
  });
8115
8149
  ctx.command("ggcevo/十连抽").action(async (argv) => {
8116
8150
  const session = argv.session;
8151
+ const accessError = checkGroupAccess(session, "十连抽");
8152
+ if (accessError) return accessError;
8117
8153
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId, isActive: true });
8118
8154
  if (!profile) {
8119
8155
  return "🔒 需要先绑定游戏句柄。";
@@ -8146,6 +8182,8 @@ function apply(ctx, config) {
8146
8182
  });
8147
8183
  ctx.command("ggcevo/背包").action(async (argv) => {
8148
8184
  const session = argv.session;
8185
+ const accessError = checkGroupAccess(session, "背包");
8186
+ if (accessError) return accessError;
8149
8187
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId, isActive: true });
8150
8188
  if (!profile) return "🔒 需要先绑定游戏句柄。";
8151
8189
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
@@ -8166,6 +8204,8 @@ ${itemDetails.join("\n")}`;
8166
8204
  ctx.command("ggcevo/签到").action(async (argv) => {
8167
8205
  try {
8168
8206
  const session = argv.session;
8207
+ const accessError = checkGroupAccess(session, "签到");
8208
+ if (accessError) return accessError;
8169
8209
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId, isActive: true });
8170
8210
  if (!profile) return "🔒 需要先绑定游戏句柄。";
8171
8211
  const { regionId, realmId, profileId } = profile;
@@ -8324,6 +8364,8 @@ ${ticketMessage}${effectMessage}`;
8324
8364
  ctx.command("ggcevo/补签").action(async (argv) => {
8325
8365
  try {
8326
8366
  const session = argv.session;
8367
+ const accessError = checkGroupAccess(session, "补签");
8368
+ if (accessError) return accessError;
8327
8369
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId, isActive: true });
8328
8370
  if (!profile) return "🔒 需要先绑定游戏句柄。";
8329
8371
  const { regionId, realmId, profileId } = profile;
@@ -8379,6 +8421,8 @@ ${ticketMessage}${effectMessage}`;
8379
8421
  });
8380
8422
  ctx.guild().command("ggcevo/每月津贴").action(async (argv) => {
8381
8423
  const session = argv.session;
8424
+ const accessError = checkGroupAccess(session, "每月津贴");
8425
+ if (accessError) return accessError;
8382
8426
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId, isActive: true });
8383
8427
  if (!profile) return "🔒 需要先绑定游戏句柄。";
8384
8428
  const { regionId, realmId, profileId } = profile;
@@ -8419,6 +8463,8 @@ ${ticketMessage}${effectMessage}`;
8419
8463
  });
8420
8464
  ctx.command("ggcevo/领取 [name]").action(async (argv, name2) => {
8421
8465
  const session = argv.session;
8466
+ const accessError = checkGroupAccess(session, "领取");
8467
+ if (accessError) return accessError;
8422
8468
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
8423
8469
  if (!profile) return "🔒 需要先绑定游戏句柄。";
8424
8470
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
@@ -8503,6 +8549,8 @@ ${ticketMessage}${effectMessage}`;
8503
8549
  return `活动【${activityName}】创建成功!奖励内容:${itemName} x${quantity}。`;
8504
8550
  });
8505
8551
  ctx.command("ggcevo/活动列表").action(async ({ session }) => {
8552
+ const accessError = checkGroupAccess(session, "活动列表");
8553
+ if (accessError) return accessError;
8506
8554
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
8507
8555
  if (!profile) return "🔒 需要先绑定游戏句柄。";
8508
8556
  const activities = await ctx.database.get(
@@ -8587,6 +8635,8 @@ ${ticketMessage}${effectMessage}`;
8587
8635
  }
8588
8636
  });
8589
8637
  ctx.command("ggcevo/胜点榜 [page]").alias("排行榜").usage("输入 胜点榜 [页码] 查看对应页的排行榜,每页10条").action(async ({ session }, page) => {
8638
+ const accessError = checkGroupAccess(session, "胜点榜");
8639
+ if (accessError) return accessError;
8590
8640
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
8591
8641
  if (!profile) return "🔒 需要先绑定游戏句柄。";
8592
8642
  const pageNum = parseInt(page) || 1;
@@ -8730,6 +8780,8 @@ ${ticketMessage}${effectMessage}`;
8730
8780
  });
8731
8781
  ctx.command("ggcevo/排名 [player]", "查询个人排名").alias("rank").usage("输入“排名”查看自己的排名信息").action(async (argv, player) => {
8732
8782
  const session = argv.session;
8783
+ const accessError = checkGroupAccess(session, "排名");
8784
+ if (accessError) return accessError;
8733
8785
  const ctx2 = session.bot.ctx;
8734
8786
  let handle;
8735
8787
  if (!player) {
@@ -8798,6 +8850,8 @@ ${ticketMessage}${effectMessage}`;
8798
8850
  });
8799
8851
  ctx.command("ggcevo/违规记录 [user]", "违规记录查询").usage("输入 违规记录 [@玩家] -p 页码 查看处罚记录,每页1条").option("p", "-p <page:number> 指定页码").action(async (argv) => {
8800
8852
  const session = argv.session;
8853
+ const accessError = checkGroupAccess(session, "违规记录");
8854
+ if (accessError) return accessError;
8801
8855
  const pageNum = argv.options.p ? argv.options.p : 1;
8802
8856
  const user = argv.args[0];
8803
8857
  let handle;
@@ -8850,6 +8904,8 @@ ${ticketMessage}${effectMessage}`;
8850
8904
  ].join("\n");
8851
8905
  });
8852
8906
  ctx.command("ggcevo/兑换赞助物品", "兑换赞助物品").action(async ({ session }) => {
8907
+ const accessError = checkGroupAccess(session, "兑换赞助物品");
8908
+ if (accessError) return accessError;
8853
8909
  try {
8854
8910
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId, isActive: true });
8855
8911
  if (!profile) return "🔒 需要先绑定游戏句柄。";
@@ -9017,6 +9073,8 @@ ${items.join("、")}
9017
9073
  }
9018
9074
  });
9019
9075
  ctx.command("ggcevo/兑换扭蛋币").action(async ({ session }) => {
9076
+ const accessError = checkGroupAccess(session, "兑换扭蛋币");
9077
+ if (accessError) return accessError;
9020
9078
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
9021
9079
  if (!profile) return "🔒 需要先绑定游戏句柄。";
9022
9080
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
@@ -9046,6 +9104,8 @@ ${items.join("、")}
9046
9104
  });
9047
9105
  ctx.command("ggcevo/扭蛋").action(async (argv) => {
9048
9106
  const session = argv.session;
9107
+ const accessError = checkGroupAccess(session, "兑换扭蛋币");
9108
+ if (accessError) return accessError;
9049
9109
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId, isActive: true });
9050
9110
  if (!profile) {
9051
9111
  return "🔒 需要先绑定游戏句柄。";
@@ -9161,6 +9221,8 @@ ${items.join("、")}
9161
9221
  });
9162
9222
  ctx.command("ggcevo/个人信息").action(async (argv) => {
9163
9223
  const session = argv.session;
9224
+ const accessError = checkGroupAccess(session, "个人信息");
9225
+ if (accessError) return accessError;
9164
9226
  const output = [];
9165
9227
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId, isActive: true });
9166
9228
  if (!profile) return "🔒 需要先绑定游戏句柄。";
@@ -13081,18 +13143,17 @@ ${validBossNames.join("、")}`;
13081
13143
  return "查询BOSS权重时发生错误,请检查服务器日志";
13082
13144
  }
13083
13145
  });
13084
- }
13085
- ctx.command("ggcevo/签到奖励").action(({}) => {
13086
- return `
13146
+ ctx.command("ggcevo/签到奖励").action(({}) => {
13147
+ return `
13087
13148
  签到金币奖励:
13088
13149
  每天获得50-100金币
13089
13150
  --------------
13090
13151
  签到红晶奖励(辛迪加财务经理职业加成):
13091
13152
  每天签到获得5枚红晶
13092
13153
  `.trim();
13093
- });
13094
- ctx.command("ggcevo/pk规则").action(({}) => {
13095
- return `
13154
+ });
13155
+ ctx.command("ggcevo/pk规则").action(({}) => {
13156
+ return `
13096
13157
  ⚔️【全新PK规则】⚔️
13097
13158
  1️⃣ 阵营限制
13098
13159
  仅限「人类联盟」与「辛迪加海盗」成员参与PK
@@ -13138,9 +13199,9 @@ PK同玩家限战:1次/日
13138
13199
  清洁工,辛迪加财务经理,计算机专家,指挥官,装甲兵,破坏者,征募官:+3000
13139
13200
  能量武器专家,枪手,猩红杀手,纵火狂:+4000
13140
13201
  `.trim();
13141
- });
13142
- ctx.command("ggcevo/击败奖励").alias("击杀奖励").action(({}) => {
13143
- return `
13202
+ });
13203
+ ctx.command("ggcevo/击败奖励").alias("击杀奖励").action(({}) => {
13204
+ return `
13144
13205
  🌟 异形主宰击败奖励规则 🌟
13145
13206
  🏆 伤害榜奖励(按伤害排名):
13146
13207
  1️⃣ 第1名:
@@ -13165,9 +13226,9 @@ PK同玩家限战:1次/日
13165
13226
  2. 精灵双倍祈愿可通过“祈愿”指令概率获得
13166
13227
  3. 排名根据实际造成伤害计算
13167
13228
  `.trim();
13168
- });
13169
- ctx.command("ggcevo/祈愿系统").action(({}) => {
13170
- return `
13229
+ });
13230
+ ctx.command("ggcevo/祈愿系统").action(({}) => {
13231
+ return `
13171
13232
  🎋 祈愿系统
13172
13233
  祈愿是连接星界的神秘仪式,消耗50金币可换取随机祈愿效果!通过智慧与运气的交织,助你在咕咕之战路上突破瓶颈。效果持续7天​​ ,冷却期间无法再次祈愿。
13173
13234
 
@@ -13185,9 +13246,9 @@ PK同玩家限战:1次/日
13185
13246
  🎵 ​​暴击韵律​​:攻击暴击率提高20%
13186
13247
  ⚠️ ​​酥手空空​​:立即失去50枚金币(可触发彩蛋)
13187
13248
  `.trim();
13188
- });
13189
- ctx.command("ggcevo/赛季奖励").alias("排名奖励").action(({}) => {
13190
- return `
13249
+ });
13250
+ ctx.command("ggcevo/赛季奖励").alias("排名奖励").action(({}) => {
13251
+ return `
13191
13252
  🏆 赛季排名奖励规则:
13192
13253
  🥇 第1名:
13193
13254
  100 咕咕币 + 🥇 赛季冠军勋章
@@ -13213,6 +13274,238 @@ PK同玩家限战:1次/日
13213
13274
  2. 勋章可通过背包查看
13214
13275
  3. 每个赛季持续2个月,可通过“胜点榜”指令查看
13215
13276
  `.trim();
13277
+ });
13278
+ }
13279
+ ctx.command("roulette/创建轮盘 <items:text>", "创建轮盘(用逗号分隔选项)", { authority: 3 }).action(async ({ session }, items) => {
13280
+ if (!items) return "请输入轮盘选项,用逗号分隔。\n示例:roulette/创建轮盘 选项1,选项2,选项3";
13281
+ const itemsArray = items.split(",").map((item) => item.trim()).filter((item) => item);
13282
+ if (itemsArray.length === 0) return "至少需要一个有效的选项";
13283
+ try {
13284
+ const roulette = await ctx.model.create("roulettes", {
13285
+ items: itemsArray
13286
+ });
13287
+ return `轮盘创建成功!ID: ${roulette.id}
13288
+ 包含选项:${itemsArray.join("、")}`;
13289
+ } catch (error) {
13290
+ return "创建轮盘失败:" + error.message;
13291
+ }
13292
+ });
13293
+ ctx.command("roulette/轮盘列表 [page:number]", "查看轮盘列表").option("group", "-g 查看轮盘组列表").action(async ({ session, options }, page = 1) => {
13294
+ const pageSize = 10;
13295
+ if (options.group) {
13296
+ const groups = await ctx.model.get("roulette_groups", {});
13297
+ const total = groups.length;
13298
+ const start = (page - 1) * pageSize;
13299
+ const end = start + pageSize;
13300
+ const pagedGroups = groups.slice(start, end);
13301
+ if (pagedGroups.length === 0) {
13302
+ return "暂无轮盘组";
13303
+ }
13304
+ let message = "轮盘组列表:\n";
13305
+ pagedGroups.forEach((group) => {
13306
+ message += `ID: ${group.id} | 名称: ${group.name} | 包含轮盘数: ${group.items.length}
13307
+ `;
13308
+ });
13309
+ message += `
13310
+ 第${page}页,共${Math.ceil(total / pageSize)}页`;
13311
+ return message;
13312
+ } else {
13313
+ const roulettes = await ctx.model.get("roulettes", {});
13314
+ const total = roulettes.length;
13315
+ const start = (page - 1) * pageSize;
13316
+ const end = start + pageSize;
13317
+ const pagedRoulettes = roulettes.slice(start, end);
13318
+ if (pagedRoulettes.length === 0) {
13319
+ return "暂无轮盘";
13320
+ }
13321
+ let message = "轮盘列表:\n";
13322
+ pagedRoulettes.forEach((roulette) => {
13323
+ message += `ID: ${roulette.id} | 选项数: ${roulette.items.length}
13324
+ `;
13325
+ message += `选项: ${roulette.items.join("、")}
13326
+
13327
+ `;
13328
+ });
13329
+ message += `第${page}页,共${Math.ceil(total / pageSize)}页`;
13330
+ return message;
13331
+ }
13332
+ });
13333
+ ctx.command("roulette/创建轮盘组 <name> <rouletteIds:text>", "创建轮盘组(轮盘ID用逗号分隔)", { authority: 3 }).action(async ({ session }, name2, rouletteIds) => {
13334
+ if (!name2) return "请输入轮盘组名称";
13335
+ if (!rouletteIds) return "请输入轮盘ID,用逗号分隔";
13336
+ const ids = rouletteIds.split(",").map((id) => parseInt(id.trim())).filter((id) => !isNaN(id));
13337
+ if (ids.length === 0) return "至少需要一个有效的轮盘ID";
13338
+ for (const id of ids) {
13339
+ const roulette = await ctx.model.get("roulettes", { id });
13340
+ if (!roulette || roulette.length === 0) {
13341
+ return `轮盘 ID ${id} 不存在`;
13342
+ }
13343
+ }
13344
+ try {
13345
+ const existingGroup = await ctx.model.get("roulette_groups", { name: name2 });
13346
+ if (existingGroup && existingGroup.length > 0) {
13347
+ return "轮盘组名称已存在";
13348
+ }
13349
+ const group = await ctx.model.create("roulette_groups", {
13350
+ name: name2,
13351
+ items: ids
13352
+ });
13353
+ return `轮盘组创建成功!
13354
+ 名称: ${group.name}
13355
+ ID: ${group.id}
13356
+ 包含轮盘: ${ids.join("、")}`;
13357
+ } catch (error) {
13358
+ return "创建轮盘组失败:" + error.message;
13359
+ }
13360
+ });
13361
+ ctx.command("roulette/轮盘抽奖 <target>", "抽奖(输入轮盘ID或轮盘组名称)").option("count", "-c <count:number> 抽奖次数,默认1次", { fallback: 1 }).action(async ({ session, options }, target) => {
13362
+ if (!target) return "请输入轮盘ID(数字)或轮盘组名称(中文)";
13363
+ const count = Math.min(Math.max(1, options.count || 1), 10);
13364
+ const isNumeric = /^\d+$/.test(target);
13365
+ if (isNumeric) {
13366
+ const roulette = await ctx.model.get("roulettes", { id: parseInt(target) });
13367
+ if (!roulette || roulette.length === 0) {
13368
+ return `轮盘 ID ${target} 不存在`;
13369
+ }
13370
+ const items = roulette[0].items;
13371
+ if (items.length === 0) {
13372
+ return "该轮盘没有可抽奖的选项";
13373
+ }
13374
+ const results = [];
13375
+ for (let i = 0; i < count; i++) {
13376
+ const randomIndex = Math.floor(Math.random() * items.length);
13377
+ results.push(items[randomIndex]);
13378
+ }
13379
+ let message = `轮盘 ID: ${target}
13380
+ 抽奖结果:
13381
+ `;
13382
+ if (count === 1) {
13383
+ message += `🎉 ${results[0]} 🎉`;
13384
+ } else {
13385
+ results.forEach((result, index) => {
13386
+ message += `${index + 1}. ${result}
13387
+ `;
13388
+ });
13389
+ }
13390
+ return message;
13391
+ } else {
13392
+ const group = await ctx.model.get("roulette_groups", { name: target });
13393
+ if (!group || group.length === 0) {
13394
+ return `轮盘组 "${target}" 不存在`;
13395
+ }
13396
+ const rouletteIds = group[0].items;
13397
+ if (rouletteIds.length === 0) {
13398
+ return "该轮盘组没有可抽奖的轮盘";
13399
+ }
13400
+ const randomRouletteId = rouletteIds[Math.floor(Math.random() * rouletteIds.length)];
13401
+ const roulette = await ctx.model.get("roulettes", { id: randomRouletteId });
13402
+ if (!roulette || roulette.length === 0) {
13403
+ return "轮盘组中的某个轮盘已不存在";
13404
+ }
13405
+ const items = roulette[0].items;
13406
+ if (items.length === 0) {
13407
+ return "选中的轮盘没有可抽奖的选项";
13408
+ }
13409
+ const results = [];
13410
+ for (let i = 0; i < count; i++) {
13411
+ const randomIndex = Math.floor(Math.random() * items.length);
13412
+ results.push(items[randomIndex]);
13413
+ }
13414
+ let message = `轮盘组: ${target}
13415
+ (从轮盘 ID: ${randomRouletteId} 中抽取)
13416
+ 抽奖结果:
13417
+ `;
13418
+ if (count === 1) {
13419
+ message += `🎉 ${results[0]} 🎉`;
13420
+ } else {
13421
+ results.forEach((result, index) => {
13422
+ message += `${index + 1}. ${result}
13423
+ `;
13424
+ });
13425
+ }
13426
+ return message;
13427
+ }
13428
+ });
13429
+ ctx.command("roulette/删除轮盘 <id:number>", "删除轮盘", { authority: 3 }).option("group", "-g 删除轮盘组").action(async ({ session, options }, id) => {
13430
+ if (!id) return "请输入要删除的ID";
13431
+ if (options.group) {
13432
+ const deleted = await ctx.model.remove("roulette_groups", { id });
13433
+ if (deleted) {
13434
+ return "轮盘组删除成功";
13435
+ } else {
13436
+ return "轮盘组不存在";
13437
+ }
13438
+ } else {
13439
+ const deleted = await ctx.model.remove("roulettes", { id });
13440
+ if (deleted) {
13441
+ return "轮盘删除成功";
13442
+ } else {
13443
+ return "轮盘不存在";
13444
+ }
13445
+ }
13446
+ });
13447
+ ctx.command("roulette/轮盘详情 <target>", "查看轮盘或轮盘组详情").action(async ({ session }, target) => {
13448
+ if (!target) return "请输入轮盘ID(数字)或轮盘组名称(中文)";
13449
+ const isNumeric = /^\d+$/.test(target);
13450
+ if (isNumeric) {
13451
+ const roulette = await ctx.model.get("roulettes", { id: parseInt(target) });
13452
+ if (!roulette || roulette.length === 0) {
13453
+ return `轮盘 ID ${target} 不存在`;
13454
+ }
13455
+ const data = roulette[0];
13456
+ return `轮盘 ID: ${data.id}
13457
+ 选项数: ${data.items.length}
13458
+ 选项列表:
13459
+ ${data.items.map((item, index) => `${index + 1}. ${item}`).join("\n")}`;
13460
+ } else {
13461
+ const group = await ctx.model.get("roulette_groups", { name: target });
13462
+ if (!group || group.length === 0) {
13463
+ return `轮盘组 "${target}" 不存在`;
13464
+ }
13465
+ const data = group[0];
13466
+ let roulettesInfo = "";
13467
+ for (const rouletteId of data.items) {
13468
+ const roulette = await ctx.model.get("roulettes", { id: rouletteId });
13469
+ if (roulette && roulette.length > 0) {
13470
+ roulettesInfo += `
13471
+ - 轮盘 ID ${rouletteId}: ${roulette[0].items.length} 个选项`;
13472
+ } else {
13473
+ roulettesInfo += `
13474
+ - 轮盘 ID ${rouletteId}: 已删除`;
13475
+ }
13476
+ }
13477
+ return `轮盘组: ${data.name}
13478
+ ID: ${data.id}
13479
+ 包含轮盘数: ${data.items.length}
13480
+ 轮盘列表:${roulettesInfo}`;
13481
+ }
13482
+ });
13483
+ ctx.command("roulette/批量轮盘抽奖 <ids:text>", "从多个轮盘中各抽一次奖(ID用逗号分隔)").action(async ({ session }, idsText) => {
13484
+ if (!idsText) return "请输入轮盘ID,用逗号分隔\n示例:roulette/multi 1,3,5";
13485
+ const ids = idsText.split(",").map((id) => parseInt(id.trim())).filter((id) => !isNaN(id));
13486
+ if (ids.length === 0) return "请输入有效的轮盘ID";
13487
+ let message = "批量抽奖结果:\n\n";
13488
+ for (const id of ids) {
13489
+ const roulette = await ctx.model.get("roulettes", { id });
13490
+ if (!roulette || roulette.length === 0) {
13491
+ message += `轮盘 ID ${id}: 不存在
13492
+
13493
+ `;
13494
+ continue;
13495
+ }
13496
+ const items = roulette[0].items;
13497
+ if (items.length === 0) {
13498
+ message += `轮盘 ID ${id}: 无选项
13499
+
13500
+ `;
13501
+ continue;
13502
+ }
13503
+ const randomIndex = Math.floor(Math.random() * items.length);
13504
+ message += `轮盘 ID ${id}: ${items[randomIndex]}
13505
+
13506
+ `;
13507
+ }
13508
+ return message;
13216
13509
  });
13217
13510
  }
13218
13511
  __name(apply, "apply");
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-ggcevo-game",
3
3
  "description": "星际争霸2咕咕虫-evolved地图的专属游戏助手插件,集成天梯排行、抽奖系统、签到福利、兑换商城等丰富功能。",
4
- "version": "2.0.7",
4
+ "version": "2.0.9",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [