koishi-plugin-ggcevo-game 1.6.32 → 1.6.34

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
@@ -100,6 +100,7 @@ export interface AdminBenefit {
100
100
  }
101
101
  export interface Blacklist {
102
102
  handle: string;
103
+ name: string;
103
104
  createdAt: Date;
104
105
  }
105
106
  export interface PKProfile {
package/lib/index.js CHANGED
@@ -485,100 +485,116 @@ var modConfig = {
485
485
  effect: "伤害提高15%",
486
486
  // 规范术语
487
487
  exclusiveTo: "",
488
- isExclusive: false
488
+ isExclusive: false,
489
+ recyclable: false
489
490
  },
490
491
  "棱镜水晶": {
491
492
  cost: 2050,
492
493
  effect: "暴击率提升10%",
493
494
  // 保持原描述
494
495
  exclusiveTo: "",
495
- isExclusive: false
496
+ isExclusive: false,
497
+ recyclable: true
496
498
  },
497
499
  "破甲模块": {
498
500
  cost: 1250,
499
501
  effect: "无视目标10%伤害减免",
500
502
  // 术语统一
501
503
  exclusiveTo: "",
502
- isExclusive: false
504
+ isExclusive: false,
505
+ recyclable: false
503
506
  },
504
507
  // 专属模组修改
505
508
  "裂甲核心": {
506
509
  cost: 750,
507
510
  effect: "伤害提高40%,无视目标40%伤害减免",
508
511
  exclusiveTo: "高斯步枪",
509
- isExclusive: true
512
+ isExclusive: true,
513
+ recyclable: false
510
514
  },
511
515
  "棱镜超载核心": {
512
516
  cost: 2250,
513
517
  effect: "暴击率提升20%;连续3次未暴击时,下次攻击必定暴击",
514
518
  exclusiveTo: "激光步枪",
515
- isExclusive: true
519
+ isExclusive: true,
520
+ recyclable: false
516
521
  },
517
522
  "助燃核心": {
518
523
  cost: 2550,
519
524
  effect: "对[惧热]目标改为造成300%伤害,对[生物]目标改为造成200%伤害;攻击时每1点护甲改为增加0.5点伤害;双倍叠加[燃烧]层数",
520
525
  exclusiveTo: "焚烧枪",
521
- isExclusive: true
526
+ isExclusive: true,
527
+ recyclable: false
522
528
  },
523
529
  "光束曲射晶片": {
524
530
  cost: 2750,
525
531
  effect: "攻击触发散射,对次要目标造成100%基础伤害",
526
532
  exclusiveTo: "碎骨步枪",
527
- isExclusive: true
533
+ isExclusive: true,
534
+ recyclable: false
528
535
  },
529
536
  "金刚石瞄准镜": {
530
537
  cost: 2250,
531
538
  effect: "无视目标20%伤害减免",
532
539
  exclusiveTo: "侦察步枪",
533
- isExclusive: true
540
+ isExclusive: true,
541
+ recyclable: false
534
542
  },
535
543
  "微型聚变核心": {
536
544
  cost: 2750,
537
545
  effect: "连续攻击叠加[聚变]效果,每层提高10%伤害(最多6层)",
538
546
  exclusiveTo: "聚变磁轨枪",
539
- isExclusive: true
547
+ isExclusive: true,
548
+ recyclable: false
540
549
  },
541
550
  "辐射充能核心": {
542
551
  cost: 1750,
543
552
  effect: "双倍叠加[辐射]层数,对[生物]目标改为造成150%伤害",
544
553
  exclusiveTo: "伽马枪",
545
- isExclusive: true
554
+ isExclusive: true,
555
+ recyclable: false
546
556
  },
547
557
  "等离子轴承": {
548
558
  cost: 3e3,
549
559
  effect: "每层[横冲直撞]提供双倍伤害",
550
560
  exclusiveTo: "M134轮转机枪",
551
- isExclusive: true
561
+ isExclusive: true,
562
+ recyclable: false
552
563
  },
553
564
  "脉冲稳定核心": {
554
565
  cost: 2500,
555
566
  effect: "攻击减少目标双倍技能层数",
556
567
  exclusiveTo: "脉冲扰乱枪",
557
- isExclusive: true
568
+ isExclusive: true,
569
+ recyclable: false
558
570
  },
559
571
  "高压电池": {
560
572
  cost: 2250,
561
573
  effect: "攻击消耗目标双倍能量值",
562
574
  exclusiveTo: "弧焊枪",
563
- isExclusive: true
575
+ isExclusive: true,
576
+ recyclable: false
564
577
  },
565
578
  "氮气压缩核心": {
566
579
  cost: 2e3,
567
580
  effect: "双倍叠加[寒冷]层数;攻击时每1点护甲改为减少0点伤害",
568
581
  exclusiveTo: "零度之下",
569
- isExclusive: true
582
+ isExclusive: true,
583
+ recyclable: false
570
584
  },
571
585
  "轻型电源节点": {
572
586
  cost: 1250,
573
587
  effect: "伤害提高40%;攻击时每1点护甲改为减少0点伤害",
574
588
  exclusiveTo: "等离子切割机",
575
- isExclusive: true
589
+ isExclusive: true,
590
+ recyclable: false
576
591
  },
577
592
  "强力钻刺核心": {
578
593
  cost: 1750,
579
594
  effect: "攻击时每1点护甲改为减少0.2点伤害;每次攻击削减目标0.1护甲值",
580
595
  exclusiveTo: "动力钻头",
581
- isExclusive: true
596
+ isExclusive: true,
597
+ recyclable: false
582
598
  }
583
599
  };
584
600
 
@@ -800,7 +816,7 @@ var spaceStationCrewConfig = [
800
816
  var syndicatePirateConfig = [
801
817
  {
802
818
  professionName: "能量武器专家",
803
- effect: "能量武器攻击伤害+20%; 使用能量武器攻击时暴击率+10%; 购买MK-4激光步枪(传奇)享有50%的折扣",
819
+ effect: "能量武器攻击伤害+20%; 购买MK-4激光步枪(传奇)享有50%的折扣",
804
820
  requirements: "至少拥有一把3级及以上等级的能量武器",
805
821
  Jobtransfer: true,
806
822
  costredcrystal: 30
@@ -5433,6 +5449,17 @@ var ggcevoUpdates = [
5433
5449
  - 重制了赛季奖励
5434
5450
  - 修改了竞猜项目ID为1的竞猜赔率,并设置了最低投注
5435
5451
  `.trim()
5452
+ },
5453
+ {
5454
+ version: "1.6.33",
5455
+ time: "2025-07-16",
5456
+ content: `
5457
+ - 回调了能量武器专家的职业效果
5458
+ - 禁用了棱镜水晶,使用拆卸可返还100%金币
5459
+ - 新增资源商店,输入“兑换资源”查看
5460
+ - 修改“兑换”指令,更改为“兑换赞助物品”,并且优化了显示信息
5461
+ - 暂时关闭了“兑换金币”和“兑换红晶”
5462
+ `.trim()
5436
5463
  }
5437
5464
  ];
5438
5465
  function compareVersions(a, b) {
@@ -5466,38 +5493,6 @@ async function gachaWithPity(ctx, handle) {
5466
5493
  return isWin;
5467
5494
  }
5468
5495
  __name(gachaWithPity, "gachaWithPity");
5469
- async function gachaWithHiddenAward(ctx, handle) {
5470
- const backpackItems = await ctx.database.get("ggcevo_backpack", {
5471
- handle,
5472
- itemId: { $in: [2, 3] }
5473
- });
5474
- const itemMap = new Map(backpackItems.map((item) => [item.itemId, item]));
5475
- const isWin = HiddenAward();
5476
- if (isWin) {
5477
- const updates = [
5478
- {
5479
- itemId: 2,
5480
- addAmount: 1
5481
- },
5482
- {
5483
- itemId: 3,
5484
- addAmount: 1
5485
- }
5486
- ].map(({ itemId, addAmount }) => ({
5487
- handle,
5488
- itemId,
5489
- quantity: (itemMap.get(itemId)?.quantity || 0) + addAmount
5490
- }));
5491
- await ctx.database.upsert("ggcevo_backpack", updates, ["handle", "itemId"]);
5492
- const [record] = await ctx.database.get("ggcevo_records", { handle });
5493
- await ctx.database.upsert("ggcevo_records", [{
5494
- handle,
5495
- hiddenawards: (record?.hiddenawards || 0) + 1
5496
- }], ["handle"]);
5497
- }
5498
- return isWin;
5499
- }
5500
- __name(gachaWithHiddenAward, "gachaWithHiddenAward");
5501
5496
  async function updatePityCounter(ctx, handle, isWin) {
5502
5497
  const [record] = await ctx.database.get("ggcevo_records", { handle });
5503
5498
  const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 2 });
@@ -5529,10 +5524,6 @@ function simpleDraw() {
5529
5524
  return Math.floor(Math.random() * 1e4) < 50;
5530
5525
  }
5531
5526
  __name(simpleDraw, "simpleDraw");
5532
- function HiddenAward() {
5533
- return Math.floor(Math.random() * 1e4) < 1;
5534
- }
5535
- __name(HiddenAward, "HiddenAward");
5536
5527
  function getRandomInt(min, max) {
5537
5528
  const actualMin = Math.min(min, max);
5538
5529
  const actualMax = Math.max(min, max);
@@ -6367,12 +6358,8 @@ async function calculateCrit(ctx, handle, equippedWeapon, weaponName, careerData
6367
6358
  };
6368
6359
  }
6369
6360
  if (careerData?.career === "能量武器专家" && weaponType === "能量武器") {
6370
- critRate += 10;
6371
- critSources.push("⚔️ 能量武器专家职业:能量武器暴击率+10%");
6372
6361
  }
6373
6362
  if (equippedWeapon.installedMods?.includes("棱镜水晶")) {
6374
- critRate += 10;
6375
- critSources.push("⚙️ 【棱镜水晶】:暴击率+10%");
6376
6363
  }
6377
6364
  if (equippedWeapon.installedMods?.includes("棱镜超载核心") && modConfig["棱镜超载核心"]?.exclusiveTo === weaponName) {
6378
6365
  critRate += 20;
@@ -7448,6 +7435,7 @@ function apply(ctx, config) {
7448
7435
  });
7449
7436
  ctx.model.extend("ggcevo_blacklist", {
7450
7437
  handle: "string",
7438
+ name: "string",
7451
7439
  createdAt: "timestamp"
7452
7440
  }, {
7453
7441
  primary: "handle"
@@ -7853,7 +7841,6 @@ function apply(ctx, config) {
7853
7841
  ctx.command("ggcevo/抽奖").action(async (argv) => {
7854
7842
  const session = argv.session;
7855
7843
  let winCount = 0;
7856
- let hiddenWinCount = 0;
7857
7844
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
7858
7845
  if (!profile) {
7859
7846
  return "🔒 需要先绑定游戏句柄。";
@@ -7876,16 +7863,13 @@ function apply(ctx, config) {
7876
7863
  }]);
7877
7864
  for (let i = 0; i < quantity; i++) {
7878
7865
  const result = await gachaWithPity(ctx, handle);
7879
- const HiddenAward2 = await gachaWithHiddenAward(ctx, handle);
7880
7866
  if (result) winCount++;
7881
- if (HiddenAward2) hiddenWinCount++;
7882
7867
  }
7883
7868
  const [record] = await ctx.database.get("ggcevo_records", { handle });
7884
7869
  return [
7885
7870
  `🎰 您使用了${quantity}枚咕咕币`,
7886
7871
  winCount > 0 ? `🎉 其中获得${winCount}张兑换券!` : "💔 本次未获得任何兑换券",
7887
- `📊 当前保底进度:${record.pityCounter}/90`,
7888
- ...hiddenWinCount > 0 ? [`🎉 恭喜你抽中隐藏奖励,额外获得${hiddenWinCount}张兑换券和${hiddenWinCount}枚扭蛋币!`] : []
7872
+ `📊 当前保底进度:${record.pityCounter}/90`
7889
7873
  ].join("\n");
7890
7874
  });
7891
7875
  ctx.command("ggcevo/单抽").action(async (argv) => {
@@ -7910,16 +7894,13 @@ function apply(ctx, config) {
7910
7894
  quantity: backpack.quantity - 1
7911
7895
  }]);
7912
7896
  const result = await gachaWithPity(ctx, handle);
7913
- const HiddenAward2 = await gachaWithHiddenAward(ctx, handle);
7914
7897
  const [record] = await ctx.database.get("ggcevo_records", { handle });
7915
7898
  return [
7916
- `${result ? "🎉 获得兑换券!" : "❌ 未中奖"} 保底进度:${record.pityCounter}/90`,
7917
- ...HiddenAward2 ? [`🎉 恭喜你抽中隐藏奖励,额外获得1张兑换券和1枚扭蛋币!`] : []
7899
+ `${result ? "🎉 获得兑换券!" : "❌ 未中奖"} 保底进度:${record.pityCounter}/90`
7918
7900
  ].join("\n");
7919
7901
  });
7920
7902
  ctx.command("ggcevo/十连抽").action(async (argv) => {
7921
7903
  const session = argv.session;
7922
- let hiddenWinCount = 0;
7923
7904
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
7924
7905
  if (!profile) {
7925
7906
  return "🔒 需要先绑定游戏句柄。";
@@ -7942,15 +7923,12 @@ function apply(ctx, config) {
7942
7923
  const results = [];
7943
7924
  for (let i = 0; i < 10; i++) {
7944
7925
  results.push(await gachaWithPity(ctx, handle));
7945
- const HiddenAward2 = await gachaWithHiddenAward(ctx, handle);
7946
- if (HiddenAward2) hiddenWinCount++;
7947
7926
  }
7948
7927
  const [record] = await ctx.database.get("ggcevo_records", { handle });
7949
7928
  return [
7950
7929
  "十连抽结果:",
7951
7930
  ...results.map((r) => r ? "🎉 获得兑换券" : "❌ 未中奖"),
7952
- `保底进度:${record.pityCounter}/90`,
7953
- ...hiddenWinCount > 0 ? [`🎉 恭喜你抽中隐藏奖励,额外获得${hiddenWinCount}张兑换券和${hiddenWinCount}枚扭蛋币!`] : []
7931
+ `保底进度:${record.pityCounter}/90`
7954
7932
  ].join("\n");
7955
7933
  });
7956
7934
  ctx.command("ggcevo/背包").action(async (argv) => {
@@ -8629,7 +8607,7 @@ ${ticketMessage}${effectMessage}`;
8629
8607
  pageNum < totalPages ? `输入 违规记录 (@玩家) -p ${pageNum + 1} 查看下一条` : "已是最后一页"
8630
8608
  ].join("\n");
8631
8609
  });
8632
- ctx.command("ggcevo/兑换", "兑换物品").action(async ({ session }) => {
8610
+ ctx.command("ggcevo/兑换赞助物品", "兑换赞助物品").action(async ({ session }) => {
8633
8611
  try {
8634
8612
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
8635
8613
  if (!profile) return "🔒 需要先绑定游戏句柄。";
@@ -8639,6 +8617,17 @@ ${ticketMessage}${effectMessage}`;
8639
8617
  return `⛔ 您已被列入黑名单。`;
8640
8618
  }
8641
8619
  const currentSeason = config.rankseason;
8620
+ const backpackItems = await ctx.database.get("ggcevo_backpack", { handle });
8621
+ const normalCoupon = backpackItems.find((item) => item.itemId === 2);
8622
+ const petCoupons = backpackItems.filter((item) => item.itemId >= 3 && item.itemId <= 6);
8623
+ const petCouponMap = { 3: "t3", 4: "t2", 5: "t1", 6: "t0" };
8624
+ let petCouponInfo = "";
8625
+ for (const coupon of petCoupons) {
8626
+ const quality = petCouponMap[coupon.itemId];
8627
+ if (petCouponInfo) petCouponInfo += " | ";
8628
+ petCouponInfo += `${quality}级券(${coupon.quantity})`;
8629
+ }
8630
+ if (!petCouponInfo) petCouponInfo = "无";
8642
8631
  const qualityGroups = {};
8643
8632
  for (const [itemName, config2] of Object.entries(itemConfig)) {
8644
8633
  const configname2 = config2;
@@ -8668,7 +8657,13 @@ ${ticketMessage}${effectMessage}`;
8668
8657
  t0: 6
8669
8658
  };
8670
8659
  const order = ["t0", "t1", "t2", "t3"];
8671
- let message = "请在30秒内输入可兑换物品名称(显示格式:物品名 [剩余/总量]):\n";
8660
+ let message = "===== 当前资源 =====\n";
8661
+ message += `普通兑奖券: ${normalCoupon?.quantity || 0}张
8662
+ `;
8663
+ message += `宠物扭蛋券: ${petCouponInfo}
8664
+
8665
+ `;
8666
+ message += "请在30秒内输入可兑换物品名称(显示格式:物品名 [剩余/总量]):\n";
8672
8667
  message += "注意:限量物品将在赛季更新时补货,限定物品[史蒂夫]除外。\n";
8673
8668
  for (const quality of order) {
8674
8669
  const items = qualityGroups[quality] || [];
@@ -8698,52 +8693,48 @@ ${items.join("、")}
8698
8693
  }
8699
8694
  const qualityMap = { "t3": 4, "t2": 5, "t1": 6, "t0": 7 };
8700
8695
  const petItems = new Set(
8701
- // 动态生成宠物集合
8702
8696
  Object.entries(itemConfig).filter(([_, config2]) => config2.type === "宠物").map(([name3]) => name3)
8703
8697
  );
8704
8698
  let cost = configname.cost;
8705
8699
  let itemId = 2;
8706
8700
  let couponName = "兑奖券";
8707
8701
  if (petItems.has(name2)) {
8708
- const [specialCoupon] = await ctx.database.get("ggcevo_backpack", {
8709
- handle,
8710
- itemId: qualityMap[configname.quality]
8711
- });
8702
+ const specialCoupon = backpackItems.find(
8703
+ (item) => item.itemId === qualityMap[configname.quality]
8704
+ );
8712
8705
  if (specialCoupon?.quantity >= 1) {
8713
8706
  itemId = qualityMap[configname.quality];
8714
8707
  cost = 1;
8715
- couponName = `${configname.quality}级宠物扭蛋`;
8708
+ couponName = `${configname.quality}级宠物扭蛋券`;
8716
8709
  }
8717
8710
  }
8718
- const [coupon] = await ctx.database.get("ggcevo_backpack", { handle, itemId });
8719
- if (!coupon || coupon.quantity < cost) {
8720
- const requireMsg = petItems.has(name2) ? `需要1个${configname.quality}级宠物扭蛋或${configname.cost}张兑奖券` : `需要${configname.cost}张兑奖券`;
8711
+ const couponItem = backpackItems.find((item) => item.itemId === itemId);
8712
+ if (!couponItem || couponItem.quantity < cost) {
8713
+ const requireMsg = petItems.has(name2) ? `需要1个${configname.quality}级宠物扭蛋券或${configname.cost}张普通兑奖券` : `需要${configname.cost}张普通兑奖券`;
8721
8714
  return `${requireMsg}
8722
- 您当前持有:${coupon?.quantity || 0}个${couponName}`;
8715
+ 您当前持有:${couponItem?.quantity || 0}个${couponName}`;
8723
8716
  }
8724
8717
  const isGlobal = configname.isLimited || config.ignoreGlobalLimit === false;
8725
8718
  await ctx.database.withTransaction(async () => {
8726
8719
  await ctx.database.set(
8727
8720
  "ggcevo_backpack",
8728
8721
  { handle, itemId },
8729
- { quantity: coupon.quantity - cost }
8722
+ { quantity: couponItem.quantity - cost }
8730
8723
  );
8731
8724
  await ctx.database.create("ggcevo_exchange", {
8732
8725
  userId: session.userId,
8733
8726
  handle,
8734
8727
  item: name2,
8735
8728
  type: configname.type,
8736
- // 从配置中获取类型
8737
8729
  date: /* @__PURE__ */ new Date(),
8738
8730
  GlobalLimit: isGlobal,
8739
- // 关键字段设置
8740
8731
  season: currentSeason
8741
8732
  });
8742
8733
  });
8743
8734
  return `🎉 恭喜!您使用${cost}个${couponName}兑换了【${name2}】`;
8744
8735
  } catch (error) {
8745
8736
  console.error("兑换失败:", error);
8746
- return "兑换失败";
8737
+ return "兑换失败,请稍后再试";
8747
8738
  }
8748
8739
  });
8749
8740
  ctx.command("ggcevo/兑换扭蛋币").action(async ({ session }) => {
@@ -8812,30 +8803,42 @@ ${items.join("、")}
8812
8803
  }]);
8813
8804
  return `🎉 恭喜!您获得了${itemName}`;
8814
8805
  });
8815
- ctx.command("ggcevo/拉黑 [handle]", "添加用户到黑名单", { authority: 3 }).action(async (argv, handle) => {
8806
+ ctx.command("ggcevo/拉黑 [user]", "黑名单管理", { authority: 3 }).action(async (argv, user) => {
8816
8807
  const session = argv.session;
8817
- if (!handle) {
8818
- await session.send("请在30秒内输入需要拉黑的句柄:\n(句柄格式为: [区域ID]-S2-[服务器ID]-[档案ID])");
8819
- handle = await session.prompt(3e4);
8820
- if (!handle) return "已取消操作,请重新输入。";
8808
+ if (!user) {
8809
+ const blacklist = await ctx.database.get("ggcevo_blacklist", {}, { fields: ["handle", "name", "createdAt"] });
8810
+ if (blacklist.length === 0) return "当前黑名单为空。";
8811
+ let message = "📋 黑名单列表:\n";
8812
+ for (const entry of blacklist.slice(0, 10)) {
8813
+ const time = new Date(entry.createdAt).toLocaleString();
8814
+ message += `▫️ ${entry.name} (${entry.handle}) - 添加时间: ${time}
8815
+ `;
8816
+ }
8817
+ if (blacklist.length > 10) message += `
8818
+ ...显示前10条,共${blacklist.length}条记录`;
8819
+ return message;
8821
8820
  }
8822
8821
  try {
8823
- const handleRegex = /^([1235])-S2-([12])-(\d+)$/;
8824
- if (!handleRegex.test(handle)) {
8825
- return "句柄格式错误,请重新输入。";
8826
- }
8827
- const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
8828
- if (existingEntries.length > 0) {
8829
- return `${handle}已在黑名单中。`;
8830
- }
8822
+ const parsed = import_koishi.h.parse(user)[0];
8823
+ if (!parsed || parsed.type !== "at") return '格式错误,请使用"拉黑 @用户"格式';
8824
+ const targetUserId = parsed.attrs.id;
8825
+ const targetUserInfo = await session.bot.getGuildMember(session.guildId, targetUserId);
8826
+ if (!targetUserInfo) return "无法获取用户信息";
8827
+ const targetName = targetUserInfo.nick || targetUserInfo.user.name;
8828
+ const [profile] = await ctx.database.get("sc2arcade_player", { userId: targetUserId });
8829
+ if (!profile) return `${targetName} 尚未绑定星际句柄`;
8830
+ const targetHandle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
8831
+ const exists = await ctx.database.get("ggcevo_blacklist", { handle: targetHandle });
8832
+ if (exists.length) return `⚠️ ${targetName} (${targetHandle}) 已在黑名单中`;
8831
8833
  await ctx.database.create("ggcevo_blacklist", {
8832
- handle,
8834
+ handle: targetHandle,
8835
+ name: targetName,
8833
8836
  createdAt: /* @__PURE__ */ new Date()
8834
8837
  });
8835
- return `✅ 操作成功,用户${handle}被列入黑名单。`;
8838
+ return `✅ 已拉黑 ${targetName} (${targetHandle})`;
8836
8839
  } catch (error) {
8837
- console.error("黑名单操作失败:", error);
8838
- return "操作失败,请稍后重试。错误详情已记录";
8840
+ console.error("拉黑操作错误:", error);
8841
+ return "操作失败,请检查控制台日志";
8839
8842
  }
8840
8843
  });
8841
8844
  ctx.command("ggcevo/标记 [handle]", "标记用户到胜点榜黑名单", { authority: 3 }).action(async (argv, handle) => {
@@ -9825,6 +9828,9 @@ ${discountDetails.join("\n")}`;
9825
9828
  const processModInstallation = /* @__PURE__ */ __name(async () => {
9826
9829
  const modInfo = modConfig[mod];
9827
9830
  if (!modInfo) return "❌ 无效模块名称。";
9831
+ if (modInfo.recyclable) {
9832
+ return `❌ ${mod} 已开启回收模式,无法安装该模块。`;
9833
+ }
9828
9834
  if (!weapon || !weaponConfig[weapon]?.id) {
9829
9835
  const validWeapons = Object.keys(weaponConfig).filter((k) => weaponConfig[k].id);
9830
9836
  return `❌ 无效武器名称。可选武器:${validWeapons.join("、")}`;
@@ -9883,7 +9889,7 @@ ${discountDetails.join("\n")}`;
9883
9889
  }, "processModInstallation");
9884
9890
  const showModList = /* @__PURE__ */ __name(async () => {
9885
9891
  const buildModList = /* @__PURE__ */ __name((isExclusive) => {
9886
- const mods = Object.entries(modConfig).filter(([_, m]) => m.isExclusive === isExclusive).map(([name2, cfg]) => {
9892
+ const mods = Object.entries(modConfig).filter(([_, m]) => m.isExclusive === isExclusive && !m.recyclable).map(([name2, cfg]) => {
9887
9893
  const discountRate = calculateDiscountRate(cfg.isExclusive);
9888
9894
  const actualPrice = Math.floor(cfg.cost * (1 - discountRate / 100));
9889
9895
  return [
@@ -9900,7 +9906,8 @@ ${discountDetails.join("\n")}`;
9900
9906
  const exclusiveDiscountRate = calculateDiscountRate(true);
9901
9907
  if (weapon && weaponConfig[weapon]?.id) {
9902
9908
  const weaponExclusiveMods = Object.entries(modConfig).filter(
9903
- ([_, cfg]) => cfg.isExclusive && cfg.exclusiveTo === weapon
9909
+ ([_, cfg]) => cfg.isExclusive && cfg.exclusiveTo === weapon && !cfg.recyclable
9910
+ // 新增回收模式过滤
9904
9911
  );
9905
9912
  const exclusiveList = weaponExclusiveMods.length > 0 ? weaponExclusiveMods.map(([name2, cfg]) => {
9906
9913
  const discountRate = calculateDiscountRate(true);
@@ -9918,7 +9925,6 @@ ${discountDetails.join("\n")}`;
9918
9925
  "使用「改装武器 武器名称 模块名称」安装",
9919
9926
  "※ 每个武器只能安装一个专属模块",
9920
9927
  armorMessage,
9921
- // 新增装甲兵提示
9922
9928
  exclusiveDiscountRate > 0 && `💰 当前专属模块折扣:`,
9923
9929
  exclusiveDiscountRate > 0 && careerData?.group === "人类联盟" && techLevel >= 2 && `▸ ⚙️ 武器升级平台Lv.${techLevel}:${exclusiveDiscountRate}%折扣`,
9924
9930
  exclusiveDiscountRate > 0 && isArmoredPirate && "▸ 🔰 装甲兵职业:10%折扣",
@@ -9932,7 +9938,6 @@ ${discountDetails.join("\n")}`;
9932
9938
  "使用「改装武器 武器名称 模块名称」安装通用模块",
9933
9939
  "※ 使用「改装武器 武器名称」查询武器专属模块",
9934
9940
  armorMessage,
9935
- // 新增装甲兵提示
9936
9941
  universalDiscountRate > 0 && `💰 当前通用模块折扣:`,
9937
9942
  universalDiscountRate > 0 && careerData?.group === "人类联盟" && techLevel >= 1 && `▸ ⚙️ 武器升级平台Lv.${techLevel}:${universalDiscountRate}%折扣`,
9938
9943
  universalDiscountRate > 0 && isArmoredPirate && "▸ 🔰 装甲兵职业:10%折扣",
@@ -9954,11 +9959,9 @@ ${discountDetails.join("\n")}`;
9954
9959
  const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
9955
9960
  if (existingEntries.length > 0) return "⛔ 您已被列入黑名单。";
9956
9961
  const weaponId = weaponConfig[weapon]?.id;
9957
- if (!weaponId) return "请输入“拆卸 武器名称 模块名称”\n注意:通用模块返还80%金币,专属模块返还50%金币";
9962
+ if (!weaponId) return '请输入"拆卸 武器名称 模块名称"\n注意:通用模块返还80%金币,专属模块返还50%金币';
9958
9963
  const modInfo = modConfig[mod];
9959
- if (!modInfo) return "请输入“拆卸 武器名称 模块名称”\n注意:通用模块返还80%金币,专属模块返还50%金币";
9960
- const refundRate = modInfo.isExclusive ? 0.5 : 0.8;
9961
- const refundType = modInfo.isExclusive ? "专属模块返还50%" : "通用模块返还80%";
9964
+ if (!modInfo) return '请输入"拆卸 武器名称 模块名称"\n注意:通用模块返还80%金币,专属模块返还50%金币';
9962
9965
  const [equipment] = await ctx.database.get("ggcevo_weapons", {
9963
9966
  handle,
9964
9967
  weaponId
@@ -9967,6 +9970,19 @@ ${discountDetails.join("\n")}`;
9967
9970
  if (!equipment.installedMods.includes(mod)) {
9968
9971
  return `❌ 该武器未安装${mod}模块。`;
9969
9972
  }
9973
+ const isRecyclable = modInfo.recyclable;
9974
+ let refundRate;
9975
+ let refundReason;
9976
+ if (isRecyclable) {
9977
+ refundRate = 1;
9978
+ refundReason = "⚠️ 回收模式开启:全额返还金币";
9979
+ } else if (modInfo.isExclusive) {
9980
+ refundRate = 0.5;
9981
+ refundReason = "专属模块返还50%";
9982
+ } else {
9983
+ refundRate = 0.8;
9984
+ refundReason = "通用模块返还80%";
9985
+ }
9970
9986
  const refund = Math.floor(modInfo.cost * refundRate);
9971
9987
  const newMods = equipment.installedMods.filter((m) => m !== mod);
9972
9988
  await ctx.database.set(
@@ -9982,10 +9998,10 @@ ${discountDetails.join("\n")}`;
9982
9998
  }], ["handle"]);
9983
9999
  return [
9984
10000
  `✅ 已从 ${weapon} 拆卸 ${mod} 模块`,
9985
- `返还金币:${refund} (原价${modInfo.cost},${refundType})`,
10001
+ `返还金币:${refund} (原价${modInfo.cost}, ${refundReason})`,
9986
10002
  `当前金币总额:${newBalance}`,
9987
10003
  `剩余模块:${newMods.join(", ") || "无"}`,
9988
- modInfo.isExclusive ? "ℹ️ 专属模块拆卸只返还50%" : ""
10004
+ isRecyclable ? "ℹ️ 回收模式模块拆卸返还100%" : modInfo.isExclusive ? "ℹ️ 专属模块拆卸只返还50%" : ""
9989
10005
  ].filter(Boolean).join("\n");
9990
10006
  });
9991
10007
  ctx.guild().command("ggcevo/攻击 <bossName>").usage("请输入要攻击的异形名称(例如:攻击 异齿猛兽 或 攻击 寒冰王蛇)").action(async (argv, bossName) => {
@@ -10588,85 +10604,6 @@ ${testResult.passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
10588
10604
  return `✨ 祈愿成功!花费50枚金币获得【${effect.name}】效果:${effect.effect}
10589
10605
  ⏳ 效果持续至 ${formattedEndTime}`;
10590
10606
  });
10591
- ctx.command("ggcevo/兑换金币", "使用兑换券兑换金币").action(async ({ session }) => {
10592
- const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
10593
- if (!profile) return "🔒 需要先绑定游戏句柄。";
10594
- const { regionId, realmId, profileId } = profile;
10595
- const handle = `${regionId}-S2-${realmId}-${profileId}`;
10596
- const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
10597
- if (existingEntries.length > 0) {
10598
- return `⛔ 您已被列入黑名单。`;
10599
- }
10600
- await session.send(`请输入你要使用多少张兑换券来兑换金币?(请在30秒内回复数字,回复“0”为取消兑换)
10601
- 注意:1张兑换券=2000金币`);
10602
- const exchangeInput = await session.prompt(3e4);
10603
- if (!exchangeInput) return "已取消操作,请重新输入。";
10604
- const exchangeCount = parseInt(exchangeInput, 10);
10605
- if (isNaN(exchangeCount)) return "请输入有效的数字!";
10606
- if (exchangeCount < 0) return "兑换数量不能为负数!";
10607
- if (exchangeCount === 0) return "已取消兑换。";
10608
- const [item] = await ctx.database.get("ggcevo_backpack", {
10609
- handle,
10610
- itemId: 2
10611
- });
10612
- const [coin] = await ctx.database.get("ggcevo_sign", {
10613
- handle
10614
- });
10615
- if (!item || item.quantity < exchangeCount) {
10616
- return "您的兑换券不足,无法兑换!";
10617
- }
10618
- const goldAmount = exchangeCount * 2e3;
10619
- await ctx.database.set("ggcevo_backpack", {
10620
- handle,
10621
- itemId: 2
10622
- }, {
10623
- quantity: item.quantity - exchangeCount
10624
- });
10625
- await ctx.database.set("ggcevo_sign", { handle }, {
10626
- totalRewards: (coin?.totalRewards || 0) + goldAmount
10627
- });
10628
- return `成功使用${exchangeCount}张兑换券,获得${goldAmount}枚金币!`;
10629
- });
10630
- ctx.command("ggcevo/兑换红晶", "使用金币兑换红晶").action(async ({ session }) => {
10631
- const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
10632
- if (!profile) return "🔒 需要先绑定游戏句柄。";
10633
- const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
10634
- const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
10635
- if (existingEntries.length > 0) {
10636
- return `⛔ 您已被列入黑名单。`;
10637
- }
10638
- const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
10639
- if (!careerData || careerData.group !== "辛迪加海盗") {
10640
- return "🚫 该功能需要【辛迪加海盗】阵营权限";
10641
- }
10642
- await session.send(`请输入你想要兑换多少红晶?(请在30秒内回复数字,回复“0”为取消兑换)
10643
- 注意:每块红晶需要500金币。`);
10644
- const exchangeInput = await session.prompt(3e4);
10645
- if (!exchangeInput) return "已取消操作,请重新输入。";
10646
- const exchangeCount = parseInt(exchangeInput, 10);
10647
- if (isNaN(exchangeCount)) return "请输入有效的数字!";
10648
- if (exchangeCount < 0) return "兑换数量不能为负数!";
10649
- if (exchangeCount === 0) return "已取消兑换。";
10650
- const goldAmount = exchangeCount * 500;
10651
- const [coin] = await ctx.database.get("ggcevo_sign", {
10652
- handle
10653
- });
10654
- const [career] = await ctx.database.get("ggcevo_careers", {
10655
- handle
10656
- });
10657
- if (!coin || coin.totalRewards < goldAmount) {
10658
- return "您的金币不足,无法兑换红晶!";
10659
- }
10660
- await ctx.database.set("ggcevo_sign", {
10661
- handle
10662
- }, {
10663
- totalRewards: coin.totalRewards - goldAmount
10664
- });
10665
- await ctx.database.set("ggcevo_careers", { handle }, {
10666
- redcrystal: (career?.redcrystal || 0) + exchangeCount
10667
- });
10668
- return `成功使用${goldAmount}金币,获得${exchangeCount}红晶!`;
10669
- });
10670
10607
  ctx.command("ggcevo/加入 <faction>", "加入阵营").alias("加入阵营").action(async ({ session }, faction) => {
10671
10608
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
10672
10609
  if (!profile) return "🔒 需要先绑定游戏句柄。";
@@ -12250,7 +12187,7 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
12250
12187
  return "⛔ 您已被列入黑名单。";
12251
12188
  }
12252
12189
  const [signRecord] = await ctx.database.get("ggcevo_sign", { handle });
12253
- if (!signRecord) return "请先进行至少一次签到获得金币后购买飞船";
12190
+ if (!signRecord) return "请先进行至少一次签到获得金币后购买飞船";
12254
12191
  const coins = signRecord.totalRewards;
12255
12192
  if (!shipName) {
12256
12193
  const shipList = Object.keys(spaceship).map((name2) => {
@@ -12321,7 +12258,7 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
12321
12258
  return "⛔ 您已被列入黑名单。";
12322
12259
  }
12323
12260
  const [career] = await ctx.database.get("ggcevo_careers", { handle });
12324
- if (!career) return "🚫 未查询到您的阵营信息";
12261
+ if (!career) return "🚫 仅限辛迪加海盗阵营使用";
12325
12262
  if (career.group !== "辛迪加海盗") {
12326
12263
  return `🚫 仅限辛迪加海盗阵营使用`;
12327
12264
  }
@@ -12545,6 +12482,80 @@ ${validBossNames.join("、")}`;
12545
12482
  return "⚠️ 竞猜提交失败,请重试";
12546
12483
  }
12547
12484
  });
12485
+ ctx.command("ggcevo/兑换资源 [name] [amount]").usage('输入"兑换资源"查看可兑换资源列表\n输入"兑换资源 物品名称 [数量]"进行兑换').action(async ({ session }, name2, amount) => {
12486
+ const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
12487
+ if (!profile) return "🔒 需要先绑定游戏句柄";
12488
+ const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
12489
+ if ((await ctx.database.get("ggcevo_blacklist", { handle })).length) {
12490
+ return "⛔ 您已被列入黑名单。";
12491
+ }
12492
+ const resourceItems = {
12493
+ "金币": { valuePerCoupon: 100, currencyField: "totalRewards", table: "ggcevo_sign" },
12494
+ "红晶": { valuePerCoupon: 1, currencyField: "redcrystal", table: "ggcevo_careers" }
12495
+ };
12496
+ if (!name2) {
12497
+ const [coupon] = await ctx.database.get("ggcevo_backpack", {
12498
+ handle,
12499
+ itemId: 8
12500
+ });
12501
+ return [
12502
+ "💰 资源兑换商店 💰",
12503
+ '使用 "兑换资源 物品名称 数量" 进行兑换',
12504
+ `您当前持有: ${coupon?.quantity || 0}张资源兑换券`,
12505
+ "====================",
12506
+ ...Object.entries(resourceItems).map(([itemName, config3]) => `▸ ${itemName}:1张券兑换${config3.valuePerCoupon}${itemName === "金币" ? "金币" : "红晶"}`),
12507
+ "====================",
12508
+ '输入示例:"兑换资源 金币 5"(兑换500金币)'
12509
+ ].join("\n");
12510
+ }
12511
+ const config2 = resourceItems[name2];
12512
+ if (!config2) return `⚠️ 无效物品名称,可用选项:${Object.keys(resourceItems).join("、")}`;
12513
+ if (name2 === "红晶") {
12514
+ const [career] = await ctx.database.get("ggcevo_careers", { handle });
12515
+ if (!career || career.group !== "辛迪加海盗") {
12516
+ return `⚠️ 兑换红晶失败:仅限【辛迪加海盗】组织成员兑换,您当前属于【${career?.group || "无"}】`;
12517
+ }
12518
+ }
12519
+ const exchangeAmount = parseInt(amount) || 1;
12520
+ if (exchangeAmount <= 0 || exchangeAmount > 100) return "⚠️ 兑换数量需在1-100之间";
12521
+ const [couponItem] = await ctx.database.get("ggcevo_backpack", {
12522
+ handle,
12523
+ itemId: 8
12524
+ });
12525
+ const couponCount = couponItem?.quantity || 0;
12526
+ if (couponCount < exchangeAmount) {
12527
+ return `⚠️ 兑换券不足,需要${exchangeAmount}张,当前持有:${couponCount}张`;
12528
+ }
12529
+ const gainAmount = config2.valuePerCoupon * exchangeAmount;
12530
+ try {
12531
+ await ctx.database.withTransaction(async () => {
12532
+ await ctx.database.set(
12533
+ "ggcevo_backpack",
12534
+ { handle, itemId: 8 },
12535
+ { quantity: couponCount - exchangeAmount }
12536
+ );
12537
+ const [record] = await ctx.database.get(config2.table, { handle });
12538
+ if (record) {
12539
+ await ctx.database.set(
12540
+ config2.table,
12541
+ { handle },
12542
+ { [config2.currencyField]: record[config2.currencyField] + gainAmount }
12543
+ );
12544
+ } else {
12545
+ await ctx.database.create(config2.table, {
12546
+ handle,
12547
+ userId: session.userId,
12548
+ [config2.currencyField]: gainAmount,
12549
+ ...config2.table === "ggcevo_sign" ? { lastSign: /* @__PURE__ */ new Date() } : {}
12550
+ });
12551
+ }
12552
+ });
12553
+ return `🎉 兑换成功!使用${exchangeAmount}张资源券兑换了${gainAmount}${name2 === "金币" ? "金币" : "红晶"}`;
12554
+ } catch (error) {
12555
+ console.error("资源兑换失败:", error);
12556
+ return "⚠️ 兑换失败,请稍后再试";
12557
+ }
12558
+ });
12548
12559
  ctx.command("ggcevo/签到奖励").action(({}) => {
12549
12560
  return `
12550
12561
  签到咕咕币奖励:
package/lib/weapons.d.ts CHANGED
@@ -450,95 +450,111 @@ export declare const modConfig: {
450
450
  effect: string;
451
451
  exclusiveTo: string;
452
452
  isExclusive: boolean;
453
+ recyclable: boolean;
453
454
  };
454
455
  棱镜水晶: {
455
456
  cost: number;
456
457
  effect: string;
457
458
  exclusiveTo: string;
458
459
  isExclusive: boolean;
460
+ recyclable: boolean;
459
461
  };
460
462
  破甲模块: {
461
463
  cost: number;
462
464
  effect: string;
463
465
  exclusiveTo: string;
464
466
  isExclusive: boolean;
467
+ recyclable: boolean;
465
468
  };
466
469
  裂甲核心: {
467
470
  cost: number;
468
471
  effect: string;
469
472
  exclusiveTo: string;
470
473
  isExclusive: boolean;
474
+ recyclable: boolean;
471
475
  };
472
476
  棱镜超载核心: {
473
477
  cost: number;
474
478
  effect: string;
475
479
  exclusiveTo: string;
476
480
  isExclusive: boolean;
481
+ recyclable: boolean;
477
482
  };
478
483
  助燃核心: {
479
484
  cost: number;
480
485
  effect: string;
481
486
  exclusiveTo: string;
482
487
  isExclusive: boolean;
488
+ recyclable: boolean;
483
489
  };
484
490
  光束曲射晶片: {
485
491
  cost: number;
486
492
  effect: string;
487
493
  exclusiveTo: string;
488
494
  isExclusive: boolean;
495
+ recyclable: boolean;
489
496
  };
490
497
  金刚石瞄准镜: {
491
498
  cost: number;
492
499
  effect: string;
493
500
  exclusiveTo: string;
494
501
  isExclusive: boolean;
502
+ recyclable: boolean;
495
503
  };
496
504
  微型聚变核心: {
497
505
  cost: number;
498
506
  effect: string;
499
507
  exclusiveTo: string;
500
508
  isExclusive: boolean;
509
+ recyclable: boolean;
501
510
  };
502
511
  辐射充能核心: {
503
512
  cost: number;
504
513
  effect: string;
505
514
  exclusiveTo: string;
506
515
  isExclusive: boolean;
516
+ recyclable: boolean;
507
517
  };
508
518
  等离子轴承: {
509
519
  cost: number;
510
520
  effect: string;
511
521
  exclusiveTo: string;
512
522
  isExclusive: boolean;
523
+ recyclable: boolean;
513
524
  };
514
525
  脉冲稳定核心: {
515
526
  cost: number;
516
527
  effect: string;
517
528
  exclusiveTo: string;
518
529
  isExclusive: boolean;
530
+ recyclable: boolean;
519
531
  };
520
532
  高压电池: {
521
533
  cost: number;
522
534
  effect: string;
523
535
  exclusiveTo: string;
524
536
  isExclusive: boolean;
537
+ recyclable: boolean;
525
538
  };
526
539
  氮气压缩核心: {
527
540
  cost: number;
528
541
  effect: string;
529
542
  exclusiveTo: string;
530
543
  isExclusive: boolean;
544
+ recyclable: boolean;
531
545
  };
532
546
  轻型电源节点: {
533
547
  cost: number;
534
548
  effect: string;
535
549
  exclusiveTo: string;
536
550
  isExclusive: boolean;
551
+ recyclable: boolean;
537
552
  };
538
553
  强力钻刺核心: {
539
554
  cost: number;
540
555
  effect: string;
541
556
  exclusiveTo: string;
542
557
  isExclusive: boolean;
558
+ recyclable: boolean;
543
559
  };
544
560
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-ggcevo-game",
3
3
  "description": "《星际争霸2》咕咕虫-evolved地图的专属游戏助手插件,集成天梯排行、抽奖系统、签到福利、兑换商城等丰富功能。",
4
- "version": "1.6.32",
4
+ "version": "1.6.34",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [