koishi-plugin-ggcevo-game 1.3.23 → 1.3.25

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.js CHANGED
@@ -41,8 +41,8 @@ var Config = import_koishi.Schema.intersect([
41
41
  }).description("赛季配置"),
42
42
  // 核心功能开关组
43
43
  import_koishi.Schema.object({
44
- signrequire: import_koishi.Schema.boolean().description("游戏对局签到要求").default(true),
45
- autorank: import_koishi.Schema.boolean().description("自动同步天梯数据").default(true)
44
+ signrequire: import_koishi.Schema.boolean().description("游戏对局签到要求").default(false),
45
+ autorank: import_koishi.Schema.boolean().description("自动同步天梯数据").default(false)
46
46
  }).description("功能开关"),
47
47
  // 对战系统配置组
48
48
  import_koishi.Schema.object({
@@ -184,13 +184,6 @@ function apply(ctx, config) {
184
184
  }, {
185
185
  primary: "handle"
186
186
  });
187
- ctx.model.extend("ggcevo_achievements", {
188
- handle: "string",
189
- achievementname: "string",
190
- gaintime: "timestamp"
191
- }, {
192
- primary: ["handle", "achievementname"]
193
- });
194
187
  ctx.model.extend("ggcevo_pk", {
195
188
  handle: "string",
196
189
  name: "string",
@@ -298,8 +291,9 @@ function apply(ctx, config) {
298
291
  type: "实弹武器",
299
292
  damage: 10,
300
293
  description: "标准配置武器,中距离作战利器",
294
+ specialeffect: "",
301
295
  price: 100,
302
- redCrystalCost: 2,
296
+ redCrystalCost: 5,
303
297
  isantiair: true,
304
298
  tagEffects: {
305
299
  "轻甲": 1.5
@@ -311,6 +305,7 @@ function apply(ctx, config) {
311
305
  type: "能量武器",
312
306
  damage: 23,
313
307
  description: "先进激光武器,远距离精准打击",
308
+ specialeffect: "",
314
309
  price: 300,
315
310
  redCrystalCost: 5,
316
311
  isantiair: true,
@@ -325,6 +320,7 @@ function apply(ctx, config) {
325
320
  type: "热能武器",
326
321
  damage: 20,
327
322
  description: "基于热能的强大武器,烧烬一切",
323
+ specialeffect: "",
328
324
  price: 450,
329
325
  redCrystalCost: 5,
330
326
  isantiair: false,
@@ -339,8 +335,9 @@ function apply(ctx, config) {
339
335
  type: "能量武器",
340
336
  damage: 28,
341
337
  description: "由激光步枪改良而来,高效的对重甲武器",
338
+ specialeffect: "",
342
339
  price: 850,
343
- redCrystalCost: 15,
340
+ redCrystalCost: 10,
344
341
  isantiair: true,
345
342
  tagEffects: {
346
343
  "重甲": 2,
@@ -353,8 +350,9 @@ function apply(ctx, config) {
353
350
  type: "实弹武器",
354
351
  damage: 12,
355
352
  description: "一种改造后的采矿切割机,有效对抗重甲目标",
353
+ specialeffect: "",
356
354
  price: 150,
357
- redCrystalCost: 2,
355
+ redCrystalCost: 5,
358
356
  isantiair: true,
359
357
  tagEffects: {
360
358
  "重甲": 1.5,
@@ -367,6 +365,7 @@ function apply(ctx, config) {
367
365
  type: "实弹武器",
368
366
  damage: 28,
369
367
  description: "近距离攻击武器,专为遭遇战设计使用",
368
+ specialeffect: "",
370
369
  price: 325,
371
370
  redCrystalCost: 5,
372
371
  isantiair: false,
@@ -380,6 +379,7 @@ function apply(ctx, config) {
380
379
  type: "实弹武器",
381
380
  damage: 50,
382
381
  description: "用于隐秘射击的最佳武器,但是无法穿透护甲",
382
+ specialeffect: "",
383
383
  price: 550,
384
384
  redCrystalCost: 10,
385
385
  isantiair: true,
@@ -393,6 +393,7 @@ function apply(ctx, config) {
393
393
  type: "热能武器",
394
394
  damage: 25,
395
395
  description: "喷射稳定的液氮恒流,对长时间接触者造成致命的损伤",
396
+ specialeffect: "",
396
397
  price: 775,
397
398
  redCrystalCost: 10,
398
399
  isantiair: false,
@@ -406,6 +407,7 @@ function apply(ctx, config) {
406
407
  type: "能量武器",
407
408
  damage: 25,
408
409
  description: "一种经过改造的电动工具,可对近距离的目标放出高压电",
410
+ specialeffect: "",
409
411
  price: 750,
410
412
  redCrystalCost: 10,
411
413
  isantiair: true,
@@ -418,13 +420,27 @@ function apply(ctx, config) {
418
420
  id: 10,
419
421
  type: "热能武器",
420
422
  damage: 24,
421
- description: "一种高度危险性的武器,设计用辐射照射并伤害敌人; 攻击使生物目标(无机械标签)叠加“辐射”层数,每层使其受到的伤害+1%",
423
+ description: "一种高度危险性的武器,设计用辐射照射并伤害敌人",
424
+ specialeffect: "攻击使生物目标(无机械标签)叠加“辐射”层数,每层使其受到的伤害+1%",
422
425
  price: 825,
423
- redCrystalCost: 15,
426
+ redCrystalCost: 10,
424
427
  isantiair: true,
425
428
  tagEffects: {
426
429
  "生物": 1.2
427
430
  }
431
+ },
432
+ "中子步枪": {
433
+ id: 11,
434
+ type: "能量武器",
435
+ damage: 30,
436
+ description: "激光步枪的变种,采用折射技术升级",
437
+ specialeffect: "",
438
+ price: 1450,
439
+ redCrystalCost: 15,
440
+ isantiair: true,
441
+ tagEffects: {
442
+ "灵能": 1.5
443
+ }
428
444
  }
429
445
  };
430
446
  const SyndicatedItems = {
@@ -483,9 +499,15 @@ function apply(ctx, config) {
483
499
  },
484
500
  "助燃核心": {
485
501
  cost: 2550,
486
- effect: "对惧热目标改为造成400%伤害",
502
+ effect: "对惧热目标改为造成300%伤害; 对生物目标改为造成200%伤害",
487
503
  exclusiveTo: "焚烧枪",
488
504
  isExclusive: true
505
+ },
506
+ "光束曲射晶片": {
507
+ cost: 2250,
508
+ effect: "攻击目标后,若有其他的存活异形,则对其造成50%的武器基础伤害",
509
+ exclusiveTo: "碎骨步枪",
510
+ isExclusive: true
489
511
  }
490
512
  };
491
513
  const wishConfig = {
@@ -520,11 +542,11 @@ function apply(ctx, config) {
520
542
  },
521
543
  {
522
544
  name: "精灵双倍",
523
- effect: "下一次击败首领时可获得双倍金币和咕咕币奖励"
545
+ effect: "下一次击败首领时可获得双倍的金币和咕咕币奖励"
524
546
  },
525
547
  {
526
548
  name: "喵喵财源",
527
- effect: "签到金币和咕咕币奖励翻倍"
549
+ effect: "签到获得双倍的金币和咕咕币"
528
550
  },
529
551
  {
530
552
  name: "暴击韵律",
@@ -1036,7 +1058,11 @@ function apply(ctx, config) {
1036
1058
  totalAdditive += wishAdditive.value;
1037
1059
  if (wishAdditive.message) effectMessage.push(wishAdditive.message);
1038
1060
  const [rankRecord] = await ctx2.database.get("ggcevo_rank", { handle, rankseason: config.rankseason });
1039
- totalAdditive += calculateRankAdditive(rankRecord);
1061
+ const rankAddResult = calculateRankAdditive(rankRecord);
1062
+ totalAdditive += rankAddResult.value;
1063
+ if (rankAddResult.message) {
1064
+ effectMessage.push(rankAddResult.message);
1065
+ }
1040
1066
  let finalDamage = baseDamage * (1 + totalAdditive);
1041
1067
  const minDamage = baseDamage * 0.01;
1042
1068
  if (finalDamage < minDamage) {
@@ -1063,7 +1089,8 @@ function apply(ctx, config) {
1063
1089
  async function calculateTagMultiplier(weaponData, tags, equippedWeapon) {
1064
1090
  const MOD_EFFECTS = [
1065
1091
  { mod: "裂甲核心", tag: "重甲", value: 1.2 },
1066
- { mod: "助燃核心", tag: "惧热", value: 4 }
1092
+ { mod: "助燃核心", tag: "惧热", value: 3 },
1093
+ { mod: "助燃核心", tag: "生物", value: 2 }
1067
1094
  ];
1068
1095
  let totalAdditive = 0;
1069
1096
  for (const tag of tags) {
@@ -1184,8 +1211,16 @@ function apply(ctx, config) {
1184
1211
  }
1185
1212
  __name(calculateWishAdditive, "calculateWishAdditive");
1186
1213
  function calculateRankAdditive(rankRecord) {
1187
- if (!rankRecord || rankRecord.rank <= 0) return 0;
1188
- return Math.floor(rankRecord.rank / 400) * 0.01;
1214
+ if (!rankRecord || rankRecord.rank <= 0) return { value: 0, message: "" };
1215
+ const value = Math.floor(rankRecord.rank / 400) * 0.01;
1216
+ if (value > 0) {
1217
+ const percentage = Math.round(value * 100);
1218
+ return {
1219
+ value,
1220
+ message: `🏆 排名加成:攻击伤害+${percentage}%`
1221
+ };
1222
+ }
1223
+ return { value: 0, message: "" };
1189
1224
  }
1190
1225
  __name(calculateRankAdditive, "calculateRankAdditive");
1191
1226
  const initDefaultItems = {
@@ -1619,7 +1654,7 @@ function apply(ctx, config) {
1619
1654
  }, "handleStructuralArmor"),
1620
1655
  // 吸血效果处理(返回综合系数)
1621
1656
  handleBloodEffects: /* @__PURE__ */ __name(function(targetBoss, currentHP, maxHP) {
1622
- if (!targetBoss.skills.includes("吸血唾液") || !targetBoss.skills.includes("嗜血狂暴") || !targetBoss.skills.includes("吐血")) return null;
1657
+ if (!targetBoss.skills.includes("吸血唾液") || !targetBoss.skills.includes("吐血")) return null;
1623
1658
  const bloodStacks = targetBoss.Skillcountpoints || 0;
1624
1659
  let damageMultiplier = 0;
1625
1660
  const messages = [];
@@ -1641,7 +1676,7 @@ function apply(ctx, config) {
1641
1676
  return { damageMultiplier, messages };
1642
1677
  }, "handleBloodEffects"),
1643
1678
  handleBloodCount: /* @__PURE__ */ __name(async function(ctx2, targetBoss, currentHP, maxHP) {
1644
- if (!targetBoss.skills.includes("吸血唾液") || !targetBoss.skills.includes("进食") || !targetBoss.skills.includes("嗜血狂暴")) {
1679
+ if (!targetBoss.skills.includes("吸血唾液") || !targetBoss.skills.includes("进食")) {
1645
1680
  return null;
1646
1681
  }
1647
1682
  let messages = [];
@@ -1678,12 +1713,15 @@ function apply(ctx, config) {
1678
1713
  const messages = [];
1679
1714
  const hasRadiation = targetBoss.skills.includes("辐射");
1680
1715
  const currentLayers = targetBoss.Vulnerability || 0;
1681
- const newSkills = hasRadiation ? targetBoss.skills : [...targetBoss.skills, "辐射"];
1716
+ const skillUpdates = [];
1682
1717
  const newLayers = hasRadiation ? Math.min(currentLayers + 1, 100) : 1;
1683
1718
  let layerMsg;
1684
- 0;
1685
1719
  if (!hasRadiation) {
1686
1720
  layerMsg = `☢️ ${targetBoss.name} 获得【辐射】效果`;
1721
+ skillUpdates.push({
1722
+ name: targetBoss.name,
1723
+ add: ["辐射"]
1724
+ });
1687
1725
  } else if (newLayers === currentLayers) {
1688
1726
  layerMsg = `☢️ 辐射层数已达上限(100层)`;
1689
1727
  } else {
@@ -1693,13 +1731,11 @@ function apply(ctx, config) {
1693
1731
  "ggcevo_boss",
1694
1732
  { name: targetBoss.name },
1695
1733
  {
1696
- skills: Array.from(new Set(newSkills)),
1697
- // 显式类型断言
1698
1734
  Vulnerability: newLayers
1699
1735
  }
1700
1736
  );
1701
1737
  messages.push(layerMsg);
1702
- return { messages };
1738
+ return { messages, skillUpdates };
1703
1739
  }, "handleGammaRadiation"),
1704
1740
  // 伽马枪辐射计算(返回增伤系数)
1705
1741
  calculateRadiationDamage: /* @__PURE__ */ __name((targetBoss) => {
@@ -1812,6 +1848,7 @@ function apply(ctx, config) {
1812
1848
  const gammaRadResult = await this.handleGammaRadiation(ctx2, targetBoss, weaponName);
1813
1849
  if (gammaRadResult) {
1814
1850
  messages.push(...gammaRadResult.messages);
1851
+ skillUpdates.push(...gammaRadResult.skillUpdates);
1815
1852
  }
1816
1853
  return {
1817
1854
  currentHP,
@@ -1820,40 +1857,71 @@ function apply(ctx, config) {
1820
1857
  initialDamage: finalDamage
1821
1858
  };
1822
1859
  }, "handlePassives"),
1823
- // 应用技能更新到数据库
1860
+ // 应用技能更新到数据库(优化合并同名boss的更新)
1824
1861
  applySkillUpdates: /* @__PURE__ */ __name(async (ctx2, skillUpdates) => {
1825
- const updates = skillUpdates.map(async (update) => {
1826
- const boss = await ctx2.database.get("ggcevo_boss", { name: update.name });
1827
- const originalSkills = boss[0]?.skills || [];
1828
- const newSkills = [
1829
- ...originalSkills.filter((s) => !update.remove?.includes(s)),
1830
- ...update.add || []
1831
- ];
1862
+ const mergedUpdates = skillUpdates.reduce((acc, update) => {
1863
+ const existing = acc.find((u) => u.name === update.name);
1864
+ if (existing) {
1865
+ if (update.remove) {
1866
+ existing.remove = [.../* @__PURE__ */ new Set([...existing.remove, ...update.remove])];
1867
+ }
1868
+ if (update.add) {
1869
+ existing.add = [.../* @__PURE__ */ new Set([...existing.add, ...update.add])];
1870
+ }
1871
+ } else {
1872
+ acc.push({
1873
+ name: update.name,
1874
+ remove: [...new Set(update.remove || [])],
1875
+ add: [...new Set(update.add || [])]
1876
+ });
1877
+ }
1878
+ return acc;
1879
+ }, []);
1880
+ const updates = mergedUpdates.map(async (update) => {
1881
+ const [boss] = await ctx2.database.get("ggcevo_boss", { name: update.name });
1882
+ if (!boss) return;
1883
+ let newSkills = [...boss.skills];
1884
+ if (update.remove?.length) {
1885
+ newSkills = newSkills.filter((s) => !update.remove.includes(s));
1886
+ }
1887
+ if (update.add?.length) {
1888
+ newSkills = [...newSkills, ...update.add];
1889
+ newSkills = [...new Set(newSkills)];
1890
+ }
1832
1891
  return ctx2.database.set(
1833
1892
  "ggcevo_boss",
1834
1893
  { name: update.name },
1835
- { skills: [...new Set(newSkills)] }
1836
- // 去重
1894
+ { skills: newSkills }
1837
1895
  );
1838
1896
  });
1839
1897
  await Promise.all(updates);
1840
1898
  }, "applySkillUpdates")
1841
1899
  };
1842
- async function handleBossDefeatRewards(ctx2, targetBoss, session) {
1900
+ async function handleBossDefeatRewards(ctx2, targetBoss) {
1843
1901
  const damageRecords = await ctx2.database.select("ggcevo_boss_damage").where({
1844
1902
  bossGroupId: targetBoss.groupId,
1845
1903
  totalDamage: { $gt: 0 }
1846
1904
  }).orderBy("totalDamage", "desc").execute();
1847
1905
  const rewardMessages = [];
1848
1906
  const rewardMap = /* @__PURE__ */ new Map();
1849
- const updatePromises = [];
1850
1907
  const handles = damageRecords.map((r) => r.handle);
1851
- const pirateCleaners = await ctx2.database.get("ggcevo_careers", {
1852
- handle: { $in: handles },
1853
- group: "辛迪加海盗",
1854
- career: "清洁工"
1855
- });
1908
+ const [pirateCleaners, doubleWishRecords] = await Promise.all([
1909
+ ctx2.database.get("ggcevo_careers", {
1910
+ handle: { $in: handles },
1911
+ group: "辛迪加海盗",
1912
+ career: "清洁工"
1913
+ }),
1914
+ // 获取双倍祈愿信息
1915
+ ctx2.database.get("ggcevo_Wish_Record", {
1916
+ handle: { $in: handles },
1917
+ wishname: "精灵双倍",
1918
+ startTime: { $lte: /* @__PURE__ */ new Date() },
1919
+ endTime: { $gte: /* @__PURE__ */ new Date() },
1920
+ isused: false
1921
+ })
1922
+ ]);
1856
1923
  const cleanerHandles = new Set(pirateCleaners.map((c) => c.handle));
1924
+ const doubleWishHandles = new Set(doubleWishRecords.map((r) => r.handle));
1857
1925
  if (damageRecords.length > 0) {
1858
1926
  const top20 = damageRecords.slice(0, 20);
1859
1927
  top20.forEach((record, index) => {
@@ -1877,6 +1945,10 @@ function apply(ctx, config) {
1877
1945
  gold = 1e3;
1878
1946
  break;
1879
1947
  }
1948
+ if (doubleWishHandles.has(record.handle)) {
1949
+ guguCoins *= 2;
1950
+ gold *= 2;
1951
+ }
1880
1952
  let redCrystal = 0;
1881
1953
  if (cleanerHandles.has(record.handle)) {
1882
1954
  switch (true) {
@@ -1912,18 +1984,22 @@ function apply(ctx, config) {
1912
1984
  const others = damageRecords.slice(20);
1913
1985
  if (others.length > 0) {
1914
1986
  others.forEach((record) => {
1987
+ let guguCoins = 3;
1988
+ let gold = 200;
1989
+ if (doubleWishHandles.has(record.handle)) {
1990
+ guguCoins *= 2;
1991
+ gold *= 2;
1992
+ }
1915
1993
  const baseReward = {
1916
- guguCoins: 3,
1917
- gold: 200,
1994
+ guguCoins,
1995
+ gold,
1918
1996
  redCrystal: cleanerHandles.has(record.handle) ? 3 : 0,
1919
1997
  playerName: record.playerName
1920
1998
  };
1921
1999
  rewardMap.set(record.handle, baseReward);
1922
2000
  });
1923
- rewardMessages.push(`其他参与者各获得: 3 咕咕币 + 200 金币` + (cleanerHandles.size > 0 ? " (清洁工额外+3红晶)" : ""));
2001
+ rewardMessages.push(`其他参与者各获得: 3 咕咕币 + 200 金币` + (cleanerHandles.size > 0 ? " (清洁工额外+3红晶)" : "") + (doubleWishHandles.size > 0 ? " (精灵双倍祈愿玩家奖励翻倍)" : ""));
1924
2002
  }
1925
- const doubleRewardPlayers = await handleDoubleRewards(ctx2, damageRecords, rewardMap);
1926
- await applyDoubleRewards(ctx2, doubleRewardPlayers, rewardMap, rewardMessages);
1927
2003
  await ctx2.database.withTransaction(async () => {
1928
2004
  for (const [handle, reward] of rewardMap) {
1929
2005
  const [signData] = await ctx2.database.get("ggcevo_sign", { handle });
@@ -1953,58 +2029,6 @@ function apply(ctx, config) {
1953
2029
  return { rewardMessages };
1954
2030
  }
1955
2031
  __name(handleBossDefeatRewards, "handleBossDefeatRewards");
1956
- async function handleDoubleRewards(ctx2, damageRecords, rewardMap) {
1957
- const doubleRewardPlayers = /* @__PURE__ */ new Map();
1958
- for (const record of damageRecords) {
1959
- const [elfEffect] = await ctx2.database.get("ggcevo_Wish_Record", {
1960
- handle: record.handle,
1961
- wishname: "精灵双倍",
1962
- isused: false,
1963
- startTime: { $lte: /* @__PURE__ */ new Date() },
1964
- endTime: { $gte: /* @__PURE__ */ new Date() }
1965
- });
1966
- if (elfEffect) {
1967
- doubleRewardPlayers.set(record.handle, {
1968
- effect: elfEffect,
1969
- originalReward: {
1970
- guguCoins: rewardMap.get(record.handle)?.guguCoins || 0,
1971
- gold: rewardMap.get(record.handle)?.gold || 0
1972
- }
1973
- });
1974
- }
1975
- }
1976
- return doubleRewardPlayers;
1977
- }
1978
- __name(handleDoubleRewards, "handleDoubleRewards");
1979
- async function applyDoubleRewards(ctx2, doubleRewardPlayers, rewardMap, rewardMessages) {
1980
- if (doubleRewardPlayers.size > 0) {
1981
- await ctx2.database.withTransaction(async () => {
1982
- for (const [handle, data] of doubleRewardPlayers) {
1983
- const reward = rewardMap.get(handle);
1984
- reward.guguCoins = data.originalReward.guguCoins * 2;
1985
- reward.gold = data.originalReward.gold * 2;
1986
- await ctx2.database.set(
1987
- "ggcevo_Wish_Record",
1988
- { id: data.effect.id },
1989
- { isused: true }
1990
- );
1991
- }
1992
- });
1993
- rewardMessages.forEach((msg, index) => {
1994
- const match = msg.match(/(\d+\.) (.+?) 获得奖励/);
1995
- if (match) {
1996
- const playerName = match[2];
1997
- const targetHandle = [...rewardMap.keys()].find(
1998
- (key) => rewardMap.get(key).playerName === playerName
1999
- );
2000
- if (targetHandle && doubleRewardPlayers.has(targetHandle)) {
2001
- rewardMessages[index] = `${match[1]} ${playerName} 🧚 获得双倍奖励: ${rewardMap.get(targetHandle).guguCoins} 咕咕币 + ${rewardMap.get(targetHandle).gold} 金币(精灵双倍祈愿生效)`;
2002
- }
2003
- }
2004
- });
2005
- }
2006
- }
2007
- __name(applyDoubleRewards, "applyDoubleRewards");
2008
2032
  async function checkTransferRequirements(ctx2, handle, profession) {
2009
2033
  const [mainBoss] = await ctx2.database.get("ggcevo_boss", {
2010
2034
  type: "主宰",
@@ -2131,18 +2155,18 @@ function apply(ctx, config) {
2131
2155
  handle,
2132
2156
  totalRewards: (signRecords[0]?.totalRewards || 0) + damageValue
2133
2157
  }], ["handle"]);
2134
- const damageRecords = await ctx.database.get("ggcevo_boss_damage", { handle });
2158
+ const [damageRecords] = await ctx.database.get("ggcevo_boss_damage", { handle });
2135
2159
  await ctx.database.upsert("ggcevo_boss_damage", [{
2136
2160
  handle,
2137
2161
  playerName: session.username,
2138
- totalDamage: (damageRecords[0]?.totalDamage || 0) + damageValue,
2139
- attackCount: damageRecords[0]?.attackCount || 0,
2162
+ totalDamage: (damageRecords?.totalDamage || 0) + damageValue,
2163
+ attackCount: damageRecords?.attackCount || 0,
2140
2164
  bossGroupId: 4
2141
2165
  }], ["handle"]);
2142
2166
  });
2143
2167
  return {
2144
2168
  success: true,
2145
- message: `成功引爆${itemName},造成 ${damageValue} 点伤害,获得等额金币`
2169
+ message: `成功引爆 ${itemName},造成 ${damageValue} 点伤害,获得等额金币`
2146
2170
  };
2147
2171
  }
2148
2172
  if (itemConfig2.id === 2) {
@@ -2206,7 +2230,7 @@ function apply(ctx, config) {
2206
2230
  }
2207
2231
  const [signInfo] = await ctx.database.get("ggcevo_sign", { handle });
2208
2232
  if (signInfo?.totalRewards < actualCost) {
2209
- const originalHint = careerData.career === "情报副官" ? `(原价${levelData.cost})` : "";
2233
+ const originalHint = careerData.career === "情报副官" ? `(原价${levelData.cost})` : "";
2210
2234
  return `❌ 需要 ${actualCost} 金币${originalHint},当前持有:${signInfo?.totalRewards || 0}`;
2211
2235
  }
2212
2236
  await ctx.database.withTransaction(async () => {
@@ -2219,9 +2243,11 @@ function apply(ctx, config) {
2219
2243
  level: nextLevel
2220
2244
  }], ["handle", "techId"]);
2221
2245
  });
2222
- const costHint = careerData.career === "情报副官" ? `${actualCost}(情报副官:已享8折优惠)` : actualCost;
2246
+ const costLine = careerData.career === "情报副官" ? `💰 花费金币: ${actualCost}(原价${levelData.cost})` : `💰 花费金币: ${actualCost}`;
2247
+ const discountHint = careerData.career === "情报副官" ? `📉 情报副官职业加成:20%折扣
2248
+ ` : "";
2223
2249
  return `✅ ${tech.techname} 升级至 Lv.${nextLevel}
2224
- 💰 花费金币: ${costHint}
2250
+ ${discountHint}${costLine}
2225
2251
  📝 ${levelData.description}
2226
2252
  💼 ${levelData.careerBonus}`;
2227
2253
  }
@@ -2232,36 +2258,42 @@ function apply(ctx, config) {
2232
2258
  handle,
2233
2259
  weaponId: weaponData.id
2234
2260
  });
2235
- if (!equipment) return "❌ 尚未获得该武器";
2236
- if (equipment.level >= 6) return "❌ 武器已达最高等级";
2261
+ if (!equipment) return "❌ 您尚未获得该武器";
2262
+ if (equipment.level >= 6) return "❌ 该武器已达最高等级";
2237
2263
  const BASE_COST = [1050, 1450, 1850, 2250, 2650, 3050];
2238
2264
  const baseCost = BASE_COST[equipment.level];
2239
2265
  const weaponTechConfig = Spacestationtechnology.find((t) => t.techId === 2);
2240
2266
  const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
2241
- let discountedCost = baseCost;
2242
- let weaponDiscount = 0;
2243
- let techLevel;
2244
- let baseDiscount;
2245
- let careerDiscount;
2267
+ let techLevel = 0;
2268
+ let totalDiscount = 0;
2269
+ const discountDetails = [];
2246
2270
  if (careerData?.group === "人类联盟") {
2247
2271
  const [weaponTech] = await ctx.database.get("ggcevo_tech", { handle, techId: 2 }).catch(() => [{ level: 0 }]);
2248
2272
  techLevel = Math.min(Math.max(weaponTech?.level || 0, 0), 5);
2249
2273
  const isCareerMatch = weaponTechConfig?.careerNames.includes(careerData?.career);
2250
2274
  const BASE_DISCOUNTS = [5, 10, 15, 20, 25];
2251
2275
  const CAREER_DISCOUNTS = [10, 20, 30, 40, 50];
2252
- baseDiscount = techLevel > 0 ? BASE_DISCOUNTS[techLevel - 1] : 0;
2253
- careerDiscount = isCareerMatch && techLevel > 0 ? CAREER_DISCOUNTS[techLevel - 1] : 0;
2254
- weaponDiscount = Math.max(baseDiscount, careerDiscount) / 100;
2255
- discountedCost = baseCost * (1 - weaponDiscount);
2276
+ const baseDiscount = techLevel > 0 ? BASE_DISCOUNTS[techLevel - 1] : 0;
2277
+ const careerDiscount = isCareerMatch && techLevel > 0 ? CAREER_DISCOUNTS[techLevel - 1] : 0;
2278
+ const weaponDiscount = Math.max(baseDiscount, careerDiscount);
2279
+ if (weaponDiscount > 0) {
2280
+ totalDiscount += weaponDiscount;
2281
+ discountDetails.push(
2282
+ `武器系统 Lv${techLevel}${isCareerMatch ? "(科技职业加成)" : ""}:${weaponDiscount}%)`
2283
+ );
2284
+ }
2256
2285
  }
2257
2286
  const activeWish = await checkFoxBlessing(handle);
2258
2287
  if (activeWish) {
2259
- discountedCost *= 0.8;
2288
+ totalDiscount += 20;
2289
+ discountDetails.push("灵狐升运祈愿生效:20%");
2260
2290
  }
2291
+ totalDiscount = Math.min(totalDiscount, 100);
2292
+ const discountedCost = baseCost * (100 - totalDiscount) / 100;
2261
2293
  const actualCost = Math.floor(discountedCost);
2262
2294
  const [signInfo] = await ctx.database.get("ggcevo_sign", { handle });
2263
2295
  if (signInfo?.totalRewards < actualCost) {
2264
- return `❌ 需要 ${actualCost} 金币,当前持有:${signInfo?.totalRewards || 0}`;
2296
+ return `❌ 需要 ${actualCost} 金币(原价${baseCost}),当前持有:${signInfo?.totalRewards || 0}`;
2265
2297
  }
2266
2298
  await ctx.database.withTransaction(async () => {
2267
2299
  await ctx.database.set("ggcevo_sign", { handle }, {
@@ -2286,20 +2318,14 @@ function apply(ctx, config) {
2286
2318
  const newLevel = equipment.level + 1;
2287
2319
  const damage = (weaponData.damage * (1 + 0.1 * newLevel)).toFixed(1);
2288
2320
  let msg = `${target} 升级成功!Lv.${newLevel}`;
2289
- const priceInfo = actualCost === baseCost ? `
2290
- 💸 消耗:${actualCost}金币` : `
2291
- 💸 消耗:${actualCost}金币 (原价${baseCost})`;
2321
+ const priceInfo = totalDiscount > 0 ? `
2322
+ 💸 消耗:${actualCost}金币 (原价${baseCost})` : `
2323
+ 💸 消耗:${actualCost}金币`;
2292
2324
  msg += priceInfo;
2293
- let discountDetails = [];
2294
- if (weaponDiscount > 0) {
2295
- discountDetails.push(`${Math.round(weaponDiscount * 100)}% (武器系统 Lv${techLevel})`);
2296
- }
2297
- if (activeWish) {
2298
- discountDetails.push("20% (灵狐升运祈愿生效)");
2299
- }
2300
2325
  if (discountDetails.length > 0) {
2301
2326
  msg += `
2302
- 🔧 折扣:${discountDetails.join(" + ")}`;
2327
+ 🔧 折扣:
2328
+ ${discountDetails.join("\n▸ ")}`;
2303
2329
  }
2304
2330
  msg += `
2305
2331
  💥 伤害:${damage}`;
@@ -2338,14 +2364,11 @@ function apply(ctx, config) {
2338
2364
  const level = `${index}→${index + 1}`;
2339
2365
  let finalPrice = baseCost;
2340
2366
  if (hasTechDiscount || hasFoxDiscount) {
2341
- let discounted = baseCost;
2342
- if (hasTechDiscount) {
2343
- discounted *= 1 - techDiscountRate / 100;
2344
- }
2345
- if (hasFoxDiscount) {
2346
- discounted *= 0.8;
2347
- }
2348
- finalPrice = Math.floor(discounted);
2367
+ let totalDiscount = 0;
2368
+ if (hasTechDiscount) totalDiscount += techDiscountRate;
2369
+ if (hasFoxDiscount) totalDiscount += foxDiscount;
2370
+ totalDiscount = Math.min(totalDiscount, 100);
2371
+ finalPrice = Math.floor(baseCost * (1 - totalDiscount / 100));
2349
2372
  }
2350
2373
  const showOriginal = finalPrice < baseCost;
2351
2374
  return [
@@ -2358,7 +2381,7 @@ function apply(ctx, config) {
2358
2381
  discountNotice.push(`🔧 武器系统 Lv${techLevel} (${techDiscountRate}% 折扣)`);
2359
2382
  }
2360
2383
  if (hasFoxDiscount) {
2361
- discountNotice.push("🦊 灵狐升运生效中 (20% 折扣)");
2384
+ discountNotice.push("🦊 灵狐升运祈愿 (20% 折扣)");
2362
2385
  }
2363
2386
  if (!hasTechDiscount && !hasFoxDiscount) {
2364
2387
  discountNotice.push("💡 提示:加入人类联盟并升级武器系统可获得折扣");
@@ -2390,27 +2413,38 @@ function apply(ctx, config) {
2390
2413
  return total;
2391
2414
  }
2392
2415
  __name(calculateTotalPower, "calculateTotalPower");
2416
+ function getBossMaxHP(bossName) {
2417
+ for (const bossGroup of bossPool) {
2418
+ if (bossGroup.main.name === bossName) {
2419
+ return bossGroup.main.maxHP;
2420
+ }
2421
+ for (const minion of bossGroup.minions) {
2422
+ if (minion.name === bossName) {
2423
+ return minion.maxHP;
2424
+ }
2425
+ }
2426
+ }
2427
+ return 0;
2428
+ }
2429
+ __name(getBossMaxHP, "getBossMaxHP");
2393
2430
  ctx.command("ggcevo/抽奖").action(async (argv) => {
2394
2431
  const session = argv.session;
2395
2432
  let winCount = 0;
2396
2433
  let hiddenWinCount = 0;
2397
2434
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
2398
2435
  if (!profile) {
2399
- return "🔒 需要先绑定游戏句柄。";
2436
+ return "🔒 需要先绑定游戏句柄";
2400
2437
  }
2401
2438
  const { regionId, realmId, profileId } = profile;
2402
2439
  const handle = `${regionId}-S2-${realmId}-${profileId}`;
2403
2440
  const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
2404
2441
  if (existingEntries.length > 0) {
2405
- return `❌ 拒绝访问,您已被列入黑名单。`;
2442
+ return `⛔ 您已被列入黑名单`;
2406
2443
  }
2407
2444
  const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 1 });
2408
- if (!backpack) {
2409
- return "您还没有签到。";
2410
- }
2411
- const quantity = backpack.quantity;
2445
+ const quantity = backpack?.quantity;
2412
2446
  if (quantity < 1) {
2413
- return "您的咕咕币不足。";
2447
+ return "您背包中的咕咕币不足";
2414
2448
  }
2415
2449
  await ctx.database.upsert("ggcevo_backpack", [{
2416
2450
  handle,
@@ -2435,20 +2469,17 @@ function apply(ctx, config) {
2435
2469
  const session = argv.session;
2436
2470
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
2437
2471
  if (!profile) {
2438
- return "🔒 需要先绑定游戏句柄。";
2472
+ return "🔒 需要先绑定游戏句柄";
2439
2473
  }
2440
2474
  const { regionId, realmId, profileId } = profile;
2441
2475
  const handle = `${regionId}-S2-${realmId}-${profileId}`;
2442
2476
  const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
2443
2477
  if (existingEntries.length > 0) {
2444
- return `❌ 拒绝访问,您已被列入黑名单。`;
2478
+ return `⛔ 您已被列入黑名单`;
2445
2479
  }
2446
2480
  const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 1 });
2447
- if (!backpack) {
2448
- return "您还没有签到。";
2449
- }
2450
- if (backpack.quantity < 1) {
2451
- return "您的咕咕币不足。";
2481
+ if (backpack?.quantity < 1) {
2482
+ return "您背包中的咕咕币不足";
2452
2483
  }
2453
2484
  await ctx.database.upsert("ggcevo_backpack", [{
2454
2485
  handle,
@@ -2468,20 +2499,17 @@ function apply(ctx, config) {
2468
2499
  let hiddenWinCount = 0;
2469
2500
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
2470
2501
  if (!profile) {
2471
- return "🔒 需要先绑定游戏句柄。";
2502
+ return "🔒 需要先绑定游戏句柄";
2472
2503
  }
2473
2504
  const { regionId, realmId, profileId } = profile;
2474
2505
  const handle = `${regionId}-S2-${realmId}-${profileId}`;
2475
2506
  const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
2476
2507
  if (existingEntries.length > 0) {
2477
- return `❌ 拒绝访问,您已被列入黑名单。`;
2508
+ return `⛔ 您已被列入黑名单`;
2478
2509
  }
2479
2510
  const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 1 });
2480
- if (!backpack) {
2481
- return "您还没有签到。";
2482
- }
2483
- if (backpack.quantity < 10) {
2484
- return "您的咕咕币不足。";
2511
+ if (backpack?.quantity < 10) {
2512
+ return "您背包中的咕咕币不足";
2485
2513
  }
2486
2514
  await ctx.database.upsert("ggcevo_backpack", [{
2487
2515
  handle,
@@ -2497,35 +2525,19 @@ function apply(ctx, config) {
2497
2525
  const [record] = await ctx.database.get("ggcevo_records", { handle });
2498
2526
  return [
2499
2527
  "十连抽结果:",
2500
- ...results.map((r) => r ? "⭐获得兑换券" : "❌未中奖"),
2528
+ ...results.map((r) => r ? "🎉 获得兑换券" : "❌ 未中奖"),
2501
2529
  `保底进度:${record.pityCounter}/90`,
2502
2530
  ...hiddenWinCount > 0 ? [`🎉 恭喜你抽中隐藏奖励,额外获得 ${hiddenWinCount} 张兑换券和 ${hiddenWinCount} 枚扭蛋币!`] : []
2503
2531
  ].join("\n");
2504
2532
  });
2505
- ctx.command("ggcevo/抽奖记录").action(async (argv) => {
2506
- const session = argv.session;
2507
- const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
2508
- if (!profile) {
2509
- return "🔒 需要先绑定游戏句柄。";
2510
- }
2511
- const { regionId, realmId, profileId } = profile;
2512
- const handle = `${regionId}-S2-${realmId}-${profileId}`;
2513
- const [record] = await ctx.database.get("ggcevo_records", { handle });
2514
- return record ? [
2515
- `总抽数:${record.totalPulls}`,
2516
- `下次保底剩余:${90 - record.pityCounter}抽`,
2517
- `已保底次数:${record.fullPityCount}`,
2518
- ...record.hiddenawards ? [`抽中隐藏奖励次数:${record.hiddenawards}`] : []
2519
- ].join("\n") : "您还没有进行过抽奖";
2520
- });
2521
2533
  ctx.command("ggcevo/背包").action(async (argv) => {
2522
2534
  const session = argv.session;
2523
2535
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
2524
- if (!profile) return "🔒 需要先绑定游戏句柄。";
2536
+ if (!profile) return "🔒 需要先绑定游戏句柄";
2525
2537
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
2526
2538
  const items = await ctx.database.get("ggcevo_backpack", { handle });
2527
2539
  const validItems = items.filter((item) => item.quantity > 0);
2528
- if (!validItems.length) return "你的背包空空如也。";
2540
+ if (!validItems.length) return "您的背包空空如也。";
2529
2541
  const itemDetails = validItems.map((userItem) => {
2530
2542
  const entry = Object.entries(initDefaultItems).find(
2531
2543
  ([, item]) => item.id === userItem.itemId
@@ -2542,11 +2554,11 @@ ${itemDetails.join("\n")}`;
2542
2554
  const session = argv.session;
2543
2555
  let latestTime;
2544
2556
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
2545
- if (!profile) return "🔒 需要先绑定游戏句柄。";
2557
+ if (!profile) return "🔒 需要先绑定游戏句柄";
2546
2558
  const { regionId, realmId, profileId } = profile;
2547
2559
  const handle = `${regionId}-S2-${realmId}-${profileId}`;
2548
2560
  const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
2549
- if (existingEntries.length > 0) return " 拒绝访问,您已被列入黑名单。";
2561
+ if (existingEntries.length > 0) return " 您已被列入黑名单";
2550
2562
  const now = /* @__PURE__ */ new Date();
2551
2563
  const currentChinaTime = convertUTCtoChinaTime(now);
2552
2564
  if (config.signrequire) {
@@ -2564,7 +2576,7 @@ ${itemDetails.join("\n")}`;
2564
2576
  } else {
2565
2577
  latestTime = currentChinaTime;
2566
2578
  }
2567
- if (!latestTime) return "您还没有游玩过“咕咕虫-evolved”。";
2579
+ if (!latestTime) return "请游玩过“咕咕虫-evolved”后签到。";
2568
2580
  const targetDateChina = new Date(latestTime);
2569
2581
  targetDateChina.setUTCDate(targetDateChina.getUTCDate() + 1);
2570
2582
  if (!isSameDate(latestTime, currentChinaTime) && !isSameDate(targetDateChina, currentChinaTime)) {
@@ -2587,15 +2599,10 @@ ${itemDetails.join("\n")}`;
2587
2599
  monthlyDays = record.monthlyDays + 1;
2588
2600
  }
2589
2601
  }
2590
- const [meowEffect] = await ctx.database.get("ggcevo_Wish_Record", {
2591
- handle,
2592
- wishname: "喵喵财源",
2593
- startTime: { $lte: now },
2594
- endTime: { $gte: now },
2595
- isused: false
2596
- });
2602
+ const messages = [];
2603
+ let totalBonus = 0;
2604
+ let basePoints;
2597
2605
  let tickets = 3;
2598
- let points = getRandomInt(20, 40);
2599
2606
  if (monthlyDays === 7) {
2600
2607
  tickets = 4;
2601
2608
  } else if (monthlyDays === 14) {
@@ -2605,62 +2612,61 @@ ${itemDetails.join("\n")}`;
2605
2612
  } else if (monthlyDays === 28) {
2606
2613
  tickets = 7;
2607
2614
  }
2608
- if (monthlyDays >= 7 && monthlyDays < 14) {
2609
- points = getRandomInt(40, 60);
2610
- } else if (monthlyDays >= 14 && monthlyDays < 21) {
2611
- points = getRandomInt(60, 80);
2612
- } else if (monthlyDays >= 21 && monthlyDays < 28) {
2613
- points = getRandomInt(80, 100);
2614
- } else if (monthlyDays >= 28) {
2615
- points = getRandomInt(100, 200);
2616
- }
2617
- let redCrystal = 0;
2618
- let effectMessage = "";
2619
- let bonusMessage = "";
2620
- let careerCrystalMessage = "";
2621
- let cred17Message = "";
2622
- let allianceBonusMessage = "";
2615
+ if (monthlyDays < 7) basePoints = getRandomInt(20, 40);
2616
+ else if (monthlyDays < 14) basePoints = getRandomInt(40, 60);
2617
+ else if (monthlyDays < 21) basePoints = getRandomInt(60, 80);
2618
+ else if (monthlyDays < 28) basePoints = getRandomInt(80, 100);
2619
+ else basePoints = getRandomInt(100, 200);
2623
2620
  const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
2624
2621
  if (careerData?.group === "人类联盟") {
2625
- const baseAllianceBonus = 0.2;
2626
- points = Math.round(points * (1 + baseAllianceBonus));
2627
- allianceBonusMessage = `
2628
- 🏛️ 人类联盟基础加成:金币+${baseAllianceBonus * 100}%`;
2629
- let miningBonus = 0;
2630
- let miningMessage = "";
2631
- const BASE_BONUS = [5, 10, 15, 20, 25];
2632
- const CAREER_BONUS = [10, 20, 30, 40, 50];
2622
+ totalBonus += 0.2;
2623
+ messages.push("🏛️ 人类联盟阵营加成:金币+20%");
2624
+ const [userMiningTech] = await ctx.database.get("ggcevo_tech", { handle, techId: 1 }).catch(() => [{ level: 0 }]);
2625
+ const techLevel = Math.min(userMiningTech?.level || 0, 5);
2633
2626
  const miningTechConfig = Spacestationtechnology.find((t) => t.techId === 1);
2634
2627
  if (miningTechConfig) {
2635
- const [userMiningTech] = await ctx.database.get("ggcevo_tech", {
2636
- handle,
2637
- techId: 1
2638
- }).catch(() => [{ level: 0 }]);
2639
- const techLevel = Math.min(Math.max(userMiningTech?.level || 0, 0), 5);
2640
- const baseBonus = techLevel > 0 ? BASE_BONUS[techLevel - 1] : 0;
2628
+ const BASE_BONUS = [5, 10, 15, 20, 25];
2629
+ const baseTechBonus = techLevel > 0 ? BASE_BONUS[techLevel - 1] : 0;
2641
2630
  let careerTechBonus = 0;
2642
- if (careerData?.career && miningTechConfig.careerNames.includes(careerData.career)) {
2631
+ if (careerData.career && miningTechConfig.careerNames.includes(careerData.career)) {
2632
+ const CAREER_BONUS = [10, 20, 30, 40, 50];
2643
2633
  careerTechBonus = techLevel > 0 ? CAREER_BONUS[techLevel - 1] : 0;
2644
2634
  }
2645
- miningBonus = Math.max(baseBonus, careerTechBonus);
2646
- if (miningBonus > 0) {
2647
- miningMessage = `
2648
- ⚙️ 采掘系统 Lv${techLevel} 金币加成:+${miningBonus}%`;
2635
+ const finalBonus = Math.max(baseTechBonus, careerTechBonus);
2636
+ if (finalBonus > 0) {
2637
+ totalBonus += finalBonus / 100;
2638
+ messages.push(`⚙️ 采掘系统 Lv${techLevel} 加成:金币+${finalBonus}%`);
2649
2639
  }
2650
2640
  }
2651
- let minerBonus = 0;
2652
- let minerMessage = "";
2653
- if (careerData?.career === "深空矿工") {
2654
- minerBonus = 50;
2655
- minerMessage = `
2656
- ⛏️ 深空矿工职业加成:金币+50%`;
2641
+ if (careerData.career === "深空矿工") {
2642
+ totalBonus += 0.5;
2643
+ messages.push("⛏️ 深空矿工职业加成:金币+50%");
2657
2644
  }
2658
- const totalBonus = miningBonus + minerBonus;
2659
- if (totalBonus > 0) {
2660
- points = Math.round(points * (1 + totalBonus / 100));
2645
+ }
2646
+ if (careerData?.group === "辛迪加海盗") {
2647
+ const [cred17Item] = await ctx.database.get("ggcevo_warehouse", { handle, itemId: 3 });
2648
+ if (cred17Item?.quantity >= 1) {
2649
+ const currentGold = record?.totalRewards || 0;
2650
+ const additional = Math.min(Math.floor(currentGold / 100), 100);
2651
+ const credBonus = 0.5 + additional / 100;
2652
+ totalBonus += credBonus;
2653
+ messages.push(`💎 CRED-17生效:金币+50% 额外+${additional}%`);
2661
2654
  }
2662
- bonusMessage = miningMessage + minerMessage;
2663
2655
  }
2656
+ const [meowEffect] = await ctx.database.get("ggcevo_Wish_Record", {
2657
+ handle,
2658
+ wishname: "喵喵财源",
2659
+ startTime: { $lte: now },
2660
+ endTime: { $gte: now },
2661
+ isused: false
2662
+ });
2663
+ if (meowEffect) {
2664
+ tickets *= 2;
2665
+ totalBonus += 1;
2666
+ messages.push("🐾 喵喵财源祈愿生效:咕咕币×2,金币+100%");
2667
+ }
2668
+ const finalPoints = Math.round(basePoints * (1 + totalBonus));
2669
+ let redCrystal = 0;
2664
2670
  if (careerData?.group === "辛迪加海盗" && careerData.career === "辛迪加财务经理") {
2665
2671
  if (monthlyDays < 7) {
2666
2672
  redCrystal = 1;
@@ -2673,32 +2679,14 @@ ${itemDetails.join("\n")}`;
2673
2679
  } else {
2674
2680
  redCrystal = 5;
2675
2681
  }
2676
- careerCrystalMessage = `
2677
- ⚓ 辛迪加财务经理职业加成:获得 ${redCrystal} 红晶`;
2678
- }
2679
- if (careerData?.group === "辛迪加海盗") {
2680
- const [cred17Item] = await ctx.database.get("ggcevo_warehouse", { handle, itemId: 3 });
2681
- if (cred17Item?.quantity >= 1) {
2682
- const currentGold = record?.totalRewards || 0;
2683
- const additionalBonus = Math.min(Math.floor(currentGold / 100), 100);
2684
- const totalBonus = 0.5 + additionalBonus * 0.01;
2685
- points = Math.round(points * (1 + totalBonus));
2686
- cred17Message = `
2687
- 💎 CRED-17生效:签到奖励+50%,当前金币${currentGold}(+${additionalBonus}%),总计加成+${(totalBonus * 100).toFixed(0)}%`;
2688
- }
2682
+ messages.push(`⚓ 辛迪加财务经理职业加成:获得${redCrystal}枚红晶`);
2689
2683
  }
2690
- if (meowEffect) {
2691
- tickets *= 2;
2692
- points *= 2;
2693
- effectMessage = "\n🐾 喵喵财源祈愿生效,获得双倍奖励(金币和咕咕币)!";
2694
- }
2695
- effectMessage += cred17Message;
2696
2684
  await ctx.database.withTransaction(async () => {
2697
2685
  await ctx.database.upsert("ggcevo_sign", [{
2698
2686
  handle,
2699
2687
  lastSign: now,
2700
2688
  monthlyDays,
2701
- totalRewards: (record?.totalRewards || 0) + points
2689
+ totalRewards: (record?.totalRewards || 0) + finalPoints
2702
2690
  }]);
2703
2691
  await ctx.database.upsert("ggcevo_backpack", [{
2704
2692
  handle,
@@ -2712,9 +2700,15 @@ ${itemDetails.join("\n")}`;
2712
2700
  }], ["handle"]);
2713
2701
  }
2714
2702
  });
2703
+ let effectMessage = "";
2704
+ if (messages.length > 0) {
2705
+ effectMessage = `
2706
+ ⚡ 加成效果:
2707
+ ▸ ${messages.join("\n▸ ")}`;
2708
+ }
2715
2709
  return `签到成功!本月累计签到${monthlyDays}天,获得:
2716
- 💰 金币 x ${points}
2717
- 🪙 咕咕币 x ${tickets}` + (effectMessage || "") + allianceBonusMessage + (bonusMessage || "") + (careerCrystalMessage || "");
2710
+ 💰 金币 x ${finalPoints}${totalBonus > 0 ? `(基础值 ${basePoints})` : ""}
2711
+ 🪙 咕咕币 x ${tickets}${effectMessage}`;
2718
2712
  } catch (error) {
2719
2713
  console.error("签到命令时发生错误:", error);
2720
2714
  return "服务器繁忙,请稍后尝试。";
@@ -2724,13 +2718,13 @@ ${itemDetails.join("\n")}`;
2724
2718
  try {
2725
2719
  const session = argv.session;
2726
2720
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
2727
- if (!profile) return "🔒 需要先绑定游戏句柄。";
2721
+ if (!profile) return "🔒 需要先绑定游戏句柄";
2728
2722
  const { regionId, realmId, profileId } = profile;
2729
2723
  const handle = `${regionId}-S2-${realmId}-${profileId}`;
2730
2724
  const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
2731
- if (existingEntries.length > 0) return " 拒绝访问,您已被列入黑名单。";
2725
+ if (existingEntries.length > 0) return " 您已被列入黑名单";
2732
2726
  const [record] = await ctx.database.get("ggcevo_sign", { handle });
2733
- if (!record) return "您还没有签到。";
2727
+ if (!record) return "暂未查询到您的签到记录";
2734
2728
  const lastSignChina = convertUTCtoChinaTime(record.lastSign);
2735
2729
  const targetDateChina = new Date(lastSignChina);
2736
2730
  const nowChina = convertUTCtoChinaTime(/* @__PURE__ */ new Date());
@@ -2739,7 +2733,7 @@ ${itemDetails.join("\n")}`;
2739
2733
  const yesterday = new Date(targetDateChina).getUTCDate() - 1;
2740
2734
  if (targetDateChina.getUTCFullYear() !== currentYear || targetDateChina.getUTCMonth() !== currentMonth || // 必须当月
2741
2735
  record.monthlyDays > yesterday) {
2742
- return "暂时没有可补签的日期。";
2736
+ return "暂时没有可补签的日期";
2743
2737
  }
2744
2738
  const costPoints = 100;
2745
2739
  if (record.totalRewards < costPoints) {
@@ -2776,46 +2770,16 @@ ${itemDetails.join("\n")}`;
2776
2770
  return "补签失败,请稍后重试。";
2777
2771
  }
2778
2772
  });
2779
- ctx.command("ggcevo/签到记录").action(async (argv) => {
2780
- const session = argv.session;
2781
- const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
2782
- if (!profile) return "🔒 需要先绑定游戏句柄。";
2783
- const { regionId, realmId, profileId } = profile;
2784
- const handle = `${regionId}-S2-${realmId}-${profileId}`;
2785
- const [record] = await ctx.database.get("ggcevo_sign", { handle });
2786
- if (!record) return "您还没有签到。";
2787
- const chinaTime = record.lastSign.toLocaleString("zh-CN", {
2788
- timeZone: "Asia/Shanghai",
2789
- year: "numeric",
2790
- month: "2-digit",
2791
- day: "2-digit",
2792
- hour: "2-digit",
2793
- minute: "2-digit",
2794
- second: "2-digit",
2795
- hour12: false
2796
- });
2797
- return [
2798
- `您的句柄:${handle}`,
2799
- `📅 最后签到时间:${chinaTime}`,
2800
- `🔥 累计签到:${record.monthlyDays}天`,
2801
- `💰 拥有金币:${record.totalRewards}枚金币`
2802
- ].join("\n");
2803
- });
2804
2773
  ctx.guild().command("ggcevo/每月津贴").action(async (argv) => {
2805
2774
  const session = argv.session;
2806
2775
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
2807
- if (!profile) return "🔒 需要先绑定游戏句柄。";
2776
+ if (!profile) return "🔒 需要先绑定游戏句柄";
2808
2777
  const { regionId, realmId, profileId } = profile;
2809
2778
  const handle = `${regionId}-S2-${realmId}-${profileId}`;
2810
- const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
2811
- if (existingEntries.length > 0) {
2812
- return `❌ 拒绝访问,您已被列入黑名单。`;
2813
- }
2814
2779
  const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 1 });
2815
- if (!backpack) return "您还没有签到。";
2816
2780
  const memberInfo = await session.event?.member?.roles;
2817
2781
  if (memberInfo?.includes("member")) {
2818
- return "❌ 拒绝访问,仅限管理员和群主领取每月津贴。";
2782
+ return "❌ 仅限管理员和群主领取每月津贴";
2819
2783
  }
2820
2784
  const now = /* @__PURE__ */ new Date();
2821
2785
  const chinatime = convertUTCtoChinaTime(now);
@@ -2842,26 +2806,26 @@ ${itemDetails.join("\n")}`;
2842
2806
  await ctx.database.upsert("ggcevo_backpack", [{
2843
2807
  handle,
2844
2808
  itemId: 1,
2845
- quantity: (backpack.quantity || 0) + 50
2809
+ quantity: (backpack?.quantity || 0) + 50
2846
2810
  }]);
2847
2811
  return `[管理专属] 成功领取本月津贴,获得了50枚咕咕币!`;
2848
2812
  });
2849
2813
  ctx.command("ggcevo/领取 [name]").action(async (argv, name2) => {
2850
2814
  const session = argv.session;
2815
+ const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
2816
+ if (!profile) return "🔒 需要先绑定游戏句柄";
2817
+ const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
2818
+ const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
2819
+ if (existingEntries.length > 0) return "⛔ 您已被列入黑名单";
2851
2820
  if (!name2) {
2852
- await session.send("请在30秒内输入活动名称");
2821
+ await session.send("请在30秒内输入活动名称:");
2853
2822
  name2 = await session.prompt(3e4);
2854
- if (!name2) return "输入超时,请重新输入。";
2823
+ if (!name2) return "已取消操作,请重新输入。";
2855
2824
  }
2856
2825
  const itemIdToName = {};
2857
2826
  for (const [name3, item] of Object.entries(initDefaultItems)) {
2858
2827
  itemIdToName[item.id] = name3;
2859
2828
  }
2860
- const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
2861
- if (!profile) return "🔒 需要先绑定游戏句柄。";
2862
- const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
2863
- const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
2864
- if (existingEntries.length > 0) return "❌ 拒绝访问,您已被列入黑名单。";
2865
2829
  const [activity] = await ctx.database.get("ggcevo_activity", {
2866
2830
  name: name2,
2867
2831
  status: "进行中"
@@ -2931,7 +2895,9 @@ ${itemDetails.join("\n")}`;
2931
2895
  });
2932
2896
  return `活动【${activityName}】创建成功!奖励内容:${itemName} x${quantity}。`;
2933
2897
  });
2934
- ctx.command("ggcevo/活动列表").action(async () => {
2898
+ ctx.command("ggcevo/活动列表").action(async ({ session }) => {
2899
+ const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
2900
+ if (!profile) return "🔒 需要先绑定游戏句柄";
2935
2901
  const activities = await ctx.database.get(
2936
2902
  "ggcevo_activity",
2937
2903
  { status: "进行中" },
@@ -2946,7 +2912,7 @@ ${itemDetails.join("\n")}`;
2946
2912
  `活动时间:${formatDate(a.startTime)} - ${formatDate(a.endTime)}`,
2947
2913
  `活动描述:${a.description}`,
2948
2914
  `活动奖励:${a.quantity} ${itemMap.get(a.itemId) || "未知物品"}`,
2949
- "━".repeat(20)
2915
+ "━".repeat(14)
2950
2916
  ].join("\n")),
2951
2917
  "请输入「领取 活动名称」领取奖励"
2952
2918
  ].join("\n") : "当前没有进行中的活动。";
@@ -3095,7 +3061,9 @@ ${itemDetails.join("\n")}`;
3095
3061
  return "服务器繁忙,请稍后尝试。";
3096
3062
  }
3097
3063
  });
3098
- ctx.command("ggcevo/胜点榜 [page]").usage("输入 胜点榜 [页码] 查看对应页的排行榜,每页10条").action(async (_, page) => {
3064
+ ctx.command("ggcevo/胜点榜 [page]").usage("输入 胜点榜 [页码] 查看对应页的排行榜,每页10条").action(async ({ session }, page) => {
3065
+ const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
3066
+ if (!profile) return "🔒 需要先绑定游戏句柄";
3099
3067
  const pageNum = parseInt(page) || 1;
3100
3068
  if (pageNum < 1) return "请输入有效的页码。";
3101
3069
  const offset = (pageNum - 1) * 10;
@@ -3104,7 +3072,7 @@ ${itemDetails.join("\n")}`;
3104
3072
  ctx.database.select("ggcevo_rank").where({ Blacklist: false, rankseason: config.rankseason }).execute((row) => import_koishi.$.count(row.handle))
3105
3073
  ]);
3106
3074
  const totalPages = Math.ceil(total / 10);
3107
- if (pageNum > totalPages) return `最多有 ${totalPages} 页`;
3075
+ if (pageNum > totalPages) return `查询失败,最多有 ${totalPages} 页`;
3108
3076
  const processedRecords = await Promise.all(
3109
3077
  records.map(async (item) => ({
3110
3078
  ...item,
@@ -3259,7 +3227,7 @@ ${itemDetails.join("\n")}`;
3259
3227
  if (!player) {
3260
3228
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
3261
3229
  if (!profile) {
3262
- return "🔒 需要先绑定游戏句柄。";
3230
+ return "🔒 需要先绑定游戏句柄";
3263
3231
  }
3264
3232
  const { regionId, realmId, profileId } = profile;
3265
3233
  const handle = `${regionId}-S2-${realmId}-${profileId}`;
@@ -3287,7 +3255,7 @@ ${itemDetails.join("\n")}`;
3287
3255
  } else {
3288
3256
  const parsedUser = import_koishi.h.parse(player)[0];
3289
3257
  if (!parsedUser || parsedUser.type !== "at" || !parsedUser.attrs.id) {
3290
- return "请输入正确的格式。";
3258
+ return "参数错误,请输入“排名 @玩家”";
3291
3259
  }
3292
3260
  const targetUserId = parsedUser.attrs.id;
3293
3261
  let targetUsername = parsedUser.attrs.name || targetUserId;
@@ -3323,7 +3291,7 @@ ${itemDetails.join("\n")}`;
3323
3291
  ctx.command("ggcevo/给予 <handle> <itemName:string> <amount:number>", "增加用户物品/金币", { authority: 3 }).action(async (_, handle, itemName, amount) => {
3324
3292
  try {
3325
3293
  if (!handle || !itemName || amount <= 0) {
3326
- return "参数格式错误,正确格式:给予 用户句柄 物品名称 数量";
3294
+ return "参数格式错误,正确格式:给予 句柄 物品名称 数量";
3327
3295
  }
3328
3296
  const parsedAmount = Math.floor(amount);
3329
3297
  if (itemName === "金币") {
@@ -3368,19 +3336,19 @@ ${itemDetails.join("\n")}`;
3368
3336
  return "操作失败:" + (err instanceof Error ? err.message : "数据库异常");
3369
3337
  }
3370
3338
  });
3371
- ctx.command("ggcevo/违规记录 [user]", "违规记录查询").usage("输入 违规记录 [@用户] -p 页码 查看处罚记录,每页1条").option("p", "-p <page:number> 指定页码").action(async (argv) => {
3339
+ ctx.command("ggcevo/违规记录 [user]", "违规记录查询").usage("输入 违规记录 [@玩家] -p 页码 查看处罚记录,每页1条").option("p", "-p <page:number> 指定页码").action(async (argv) => {
3372
3340
  const session = argv.session;
3373
3341
  const pageNum = argv.options.p ? argv.options.p : 1;
3374
3342
  const user = argv.args[0];
3375
3343
  let handle;
3376
3344
  if (!user) {
3377
3345
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
3378
- if (!profile) return "🔒 需要先绑定游戏句柄。";
3346
+ if (!profile) return "🔒 需要先绑定游戏句柄";
3379
3347
  handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
3380
3348
  } else {
3381
3349
  const parsedUser = import_koishi.h.parse(user)[0];
3382
3350
  if (!parsedUser || parsedUser.type !== "at" || !parsedUser.attrs.id) {
3383
- return "请输入正确的格式。";
3351
+ return "参数错误,请输入“违规记录 @玩家”";
3384
3352
  }
3385
3353
  const targetUserId = parsedUser.attrs.id;
3386
3354
  let targetUsername = parsedUser.attrs.name || targetUserId;
@@ -3418,17 +3386,17 @@ ${itemDetails.join("\n")}`;
3418
3386
  "------------------------------",
3419
3387
  recordText,
3420
3388
  "------------------------------",
3421
- pageNum < totalPages ? `输入 违规记录 (@用户) -p ${pageNum + 1} 查看下一条` : "已是最后一页"
3389
+ pageNum < totalPages ? `输入 违规记录 (@玩家) -p ${pageNum + 1} 查看下一条` : "已是最后一页"
3422
3390
  ].join("\n");
3423
3391
  });
3424
3392
  ctx.command("ggcevo/兑换", "兑换物品").action(async ({ session }) => {
3425
3393
  try {
3426
3394
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
3427
- if (!profile) return "🔒 需要先绑定游戏句柄。";
3395
+ if (!profile) return "🔒 需要先绑定游戏句柄";
3428
3396
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
3429
3397
  const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
3430
3398
  if (existingEntries.length > 0) {
3431
- return `❌ 拒绝访问,您已被列入黑名单。`;
3399
+ return `⛔ 您已被列入黑名单`;
3432
3400
  }
3433
3401
  const currentSeason = config.rankseason;
3434
3402
  const qualityGroups = {};
@@ -3472,7 +3440,7 @@ ${items.join("、")}
3472
3440
  }
3473
3441
  await session.send(message);
3474
3442
  const name2 = await session.prompt(3e4);
3475
- if (!name2) return "输入超时,请重新输入。";
3443
+ if (!name2) return "已取消操作,请重新输入。";
3476
3444
  const configname = itemConfig[name2];
3477
3445
  if (!configname) return "无效的物品名称,请重新输入。";
3478
3446
  const userRecords = await ctx.database.get("ggcevo_exchange", { handle, item: name2 });
@@ -3511,7 +3479,7 @@ ${items.join("、")}
3511
3479
  if (!coupon || coupon.quantity < cost) {
3512
3480
  const requireMsg = petItems.has(name2) ? `需要1个${configname.quality}级宠物扭蛋 或${configname.cost}张兑奖券` : `需要${configname.cost}张兑奖券`;
3513
3481
  return `${requireMsg}
3514
- 当前持有:${coupon?.quantity || 0}个${couponName}`;
3482
+ 您当前持有:${coupon?.quantity || 0}个${couponName}`;
3515
3483
  }
3516
3484
  const isGlobal = configname.isLimited || config.ignoreGlobalLimit === false;
3517
3485
  await ctx.database.withTransaction(async () => {
@@ -3532,38 +3500,19 @@ ${items.join("、")}
3532
3500
  season: currentSeason
3533
3501
  });
3534
3502
  });
3535
- return `兑换成功!消耗${cost}个${couponName}获得【${name2}】`;
3503
+ return `🎉 恭喜!您使用 ${cost} 个 ${couponName} 兑换了 【${name2}】`;
3536
3504
  } catch (error) {
3537
3505
  console.error("兑换失败:", error);
3538
3506
  return "兑换失败";
3539
3507
  }
3540
3508
  });
3541
- ctx.command("ggcevo/兑换记录").action(async ({ session }) => {
3542
- const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
3543
- if (!profile) return "🔒 需要先绑定游戏句柄。";
3544
- const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
3545
- const exchanges = await ctx.database.get("ggcevo_exchange", { handle });
3546
- if (!exchanges.length) return "您暂无兑换记录";
3547
- const output = exchanges.map((e) => {
3548
- const date = new Date(e.date);
3549
- const cnTime = date.toLocaleString("zh-CN", {
3550
- timeZone: "Asia/Shanghai",
3551
- year: "numeric",
3552
- month: "2-digit",
3553
- day: "2-digit"
3554
- });
3555
- return `${e.type}: ${e.item} | 时间: ${cnTime}`;
3556
- }).join("\n");
3557
- return `${handle} 的兑换记录:
3558
- ${output}`;
3559
- });
3560
3509
  ctx.command("ggcevo/兑换扭蛋币").action(async ({ session }) => {
3561
3510
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
3562
- if (!profile) return "🔒 需要先绑定游戏句柄。";
3511
+ if (!profile) return "🔒 需要先绑定游戏句柄";
3563
3512
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
3564
3513
  const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
3565
3514
  if (existingEntries.length > 0) {
3566
- return `❌ 拒绝访问,您已被列入黑名单。`;
3515
+ return `⛔ 您已被列入黑名单`;
3567
3516
  }
3568
3517
  await session.send(`您确定要使用3张兑换券换取一枚扭蛋币吗?(请在30秒内回复“是”确认)`);
3569
3518
  const confirm = await session.prompt(3e4);
@@ -3571,7 +3520,7 @@ ${output}`;
3571
3520
  const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 3 });
3572
3521
  const [coupon] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 2 });
3573
3522
  if (!coupon || coupon.quantity < 3) {
3574
- return `兑换扭蛋币需要3张兑奖券,当前持有:${coupon?.quantity || 0}`;
3523
+ return `兑换扭蛋币需要3张兑奖券,您当前持有:${coupon?.quantity || 0}`;
3575
3524
  }
3576
3525
  await ctx.database.set(
3577
3526
  "ggcevo_backpack",
@@ -3583,23 +3532,23 @@ ${output}`;
3583
3532
  itemId: 3,
3584
3533
  quantity: (backpack?.quantity || 0) + 1
3585
3534
  }]);
3586
- return `兑换成功!消耗3张兑奖券获得1枚扭蛋币`;
3535
+ return `🎉恭喜!您使用 3 张兑奖券兑换了 1 枚扭蛋币`;
3587
3536
  });
3588
3537
  ctx.command("ggcevo/扭蛋").action(async (argv) => {
3589
3538
  const session = argv.session;
3590
3539
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
3591
3540
  if (!profile) {
3592
- return "🔒 需要先绑定游戏句柄。";
3541
+ return "🔒 需要先绑定游戏句柄";
3593
3542
  }
3594
3543
  const { regionId, realmId, profileId } = profile;
3595
3544
  const handle = `${regionId}-S2-${realmId}-${profileId}`;
3596
3545
  const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
3597
3546
  if (existingEntries.length > 0) {
3598
- return `❌ 拒绝访问,您已被列入黑名单。`;
3547
+ return `⛔ 您已被列入黑名单`;
3599
3548
  }
3600
3549
  const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 3 });
3601
3550
  if (!backpack || backpack.quantity < 1) {
3602
- return `当前扭蛋币不足,剩余:${backpack?.quantity || 0}枚`;
3551
+ return `当前扭蛋币不足,您拥有:${backpack?.quantity || 0}枚`;
3603
3552
  }
3604
3553
  const awardName = PetCapsuleToy();
3605
3554
  const awardItem = Object.entries(initDefaultItems).find(
@@ -3621,16 +3570,18 @@ ${output}`;
3621
3570
  itemId: itemData.id,
3622
3571
  quantity: currentQuantity + 1
3623
3572
  }]);
3624
- return `🎉 恭喜您获得:${itemName}`;
3573
+ return `🎉 恭喜!您获得了 ${itemName}`;
3625
3574
  });
3626
- ctx.command("ggcevo/拉黑", "添加用户到黑名单").action(async (argv) => {
3575
+ ctx.command("ggcevo/拉黑 [handle]", "添加用户到黑名单").action(async (argv, handle) => {
3627
3576
  const session = argv.session;
3628
3577
  if (!ctx.config.admins.includes(session.userId)) {
3629
3578
  return "⚠️ 没有操作权限。";
3630
3579
  }
3631
- await session.send("请在30秒内输入需要拉黑的句柄:\n(句柄格式为: [区域ID]-S2-[服务器ID]-[档案ID])");
3632
- const handle = await session.prompt(3e4);
3633
- if (!handle) return "输入超时,请重新输入。";
3580
+ if (!handle) {
3581
+ await session.send("请在30秒内输入需要拉黑的句柄:\n(句柄格式为: [区域ID]-S2-[服务器ID]-[档案ID])");
3582
+ handle = await session.prompt(3e4);
3583
+ if (!handle) return "已取消操作,请重新输入。";
3584
+ }
3634
3585
  try {
3635
3586
  const handleRegex = /^([1235])-S2-([12])-(\d+)$/;
3636
3587
  if (!handleRegex.test(handle)) {
@@ -3644,20 +3595,22 @@ ${output}`;
3644
3595
  handle,
3645
3596
  createdAt: /* @__PURE__ */ new Date()
3646
3597
  });
3647
- return `✅ 用户${handle}已被列入黑名单。`;
3598
+ return `✅ 操作成功,用户${handle}被列入黑名单。`;
3648
3599
  } catch (error) {
3649
3600
  console.error("黑名单操作失败:", error);
3650
3601
  return "操作失败,请稍后重试。错误详情已记录";
3651
3602
  }
3652
3603
  });
3653
- ctx.command("ggcevo/标记", "标记用户到胜点榜黑名单").action(async (argv) => {
3604
+ ctx.command("ggcevo/标记 [handle]", "标记用户到胜点榜黑名单").action(async (argv, handle) => {
3654
3605
  const session = argv.session;
3655
3606
  if (!ctx.config.admins.includes(session.userId)) {
3656
3607
  return "⚠️ 没有操作权限。";
3657
3608
  }
3658
- await session.send("请在30秒内输入需要标记的句柄:\n(句柄格式为: [区域ID]-S2-[服务器ID]-[档案ID])");
3659
- const handle = await session.prompt(3e4);
3660
- if (!handle) return "输入超时,请重新输入。";
3609
+ if (!handle) {
3610
+ await session.send("请在30秒内输入需要标记的句柄:\n(句柄格式为: [区域ID]-S2-[服务器ID]-[档案ID])");
3611
+ handle = await session.prompt(3e4);
3612
+ if (!handle) return "已取消操作,请重新输入。";
3613
+ }
3661
3614
  try {
3662
3615
  const handleRegex = /^([1235])-S2-([12])-(\d+)$/;
3663
3616
  if (!handleRegex.test(handle)) {
@@ -3665,48 +3618,24 @@ ${output}`;
3665
3618
  }
3666
3619
  const existingEntries = await ctx.database.get("ggcevo_rank", { handle, Blacklist: true, rankseason: config.rankseason });
3667
3620
  if (existingEntries.length > 0) {
3668
- return `${handle}已被标记在咕咕胜点榜黑名单中。`;
3621
+ return `${handle}已在当前赛季胜点榜上被标记。`;
3669
3622
  }
3670
3623
  await ctx.database.upsert("ggcevo_rank", [{
3671
3624
  handle,
3672
3625
  Blacklist: true,
3673
3626
  rankseason: config.rankseason
3674
3627
  }]);
3675
- return `✅ 用户${handle}已被标记在咕咕胜点榜黑名单。`;
3628
+ return `✅ 操作成功,用户${handle}在当前赛季胜点榜上被标记。`;
3676
3629
  } catch (error) {
3677
3630
  console.error("黑名单操作失败:", error);
3678
3631
  return "操作失败,请稍后重试。错误详情已记录";
3679
3632
  }
3680
3633
  });
3681
- ctx.command("ggcevo/成就").action(async ({ session }) => {
3682
- const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
3683
- if (!profile) {
3684
- return "🔒 需要先绑定游戏句柄。";
3685
- }
3686
- const { regionId, realmId, profileId } = profile;
3687
- const achievements = await ctx.database.get("ggcevo_achievements", {
3688
- handle: `${regionId}-S2-${realmId}-${profileId}`
3689
- });
3690
- if (!achievements.length) {
3691
- return "你还没有获得任何成就。";
3692
- }
3693
- const achievementList = achievements.map((achievement) => {
3694
- const date = new Date(achievement.gaintime);
3695
- return `${achievement.achievementname} (获得于 ${date.toLocaleDateString("zh-CN", {
3696
- timeZone: "Asia/Shanghai",
3697
- year: "numeric",
3698
- month: "2-digit",
3699
- day: "2-digit"
3700
- })})`;
3701
- });
3702
- return `${regionId}-S2-${realmId}-${profileId} 已获得的成就:
3703
- ${achievementList.join("\n")}`;
3704
- });
3705
3634
  ctx.command("ggcevo/个人信息").action(async (argv) => {
3706
3635
  const session = argv.session;
3707
3636
  const output = [];
3708
3637
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
3709
- if (!profile) return "🔒 需要先绑定游戏句柄。";
3638
+ if (!profile) return "🔒 需要先绑定游戏句柄";
3710
3639
  const { regionId, realmId, profileId } = profile;
3711
3640
  const handle = `${regionId}-S2-${realmId}-${profileId}`;
3712
3641
  output.push(`🎮 游戏句柄:${handle}
@@ -3733,10 +3662,10 @@ ${achievementList.join("\n")}`;
3733
3662
  if (lottery) {
3734
3663
  output.push(
3735
3664
  "🎉 抽奖统计:",
3736
- `总抽奖次数:${lottery.totalPulls}`,
3665
+ `总计抽奖:${lottery.totalPulls} 次`,
3737
3666
  `距离保底剩余:${90 - lottery.pityCounter} 抽`,
3738
- `已达成保底:${lottery.fullPityCount} 次`,
3739
- ...lottery.hiddenawards ? [`隐藏奖励次数:${lottery.hiddenawards}`] : [],
3667
+ `触发保底:${lottery.fullPityCount} 次`,
3668
+ ...lottery.hiddenawards ? [`隐藏奖励:${lottery.hiddenawards} 次`] : [],
3740
3669
  "──────────────"
3741
3670
  );
3742
3671
  }
@@ -3838,16 +3767,16 @@ ${achievementList.join("\n")}`;
3838
3767
  ctx.command("ggcevo/pk [user]", "发起玩家对战").alias("挑战").action(async (argv, user) => {
3839
3768
  try {
3840
3769
  const session = argv.session;
3841
- if (!user) return "请输入“pk @指定pk玩家”。";
3842
3770
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
3843
- if (!profile) return "🔒 需要先绑定游戏句柄。";
3771
+ if (!profile) return "🔒 需要先绑定游戏句柄";
3844
3772
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
3845
3773
  const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
3846
3774
  if (existingEntries.length > 0) {
3847
- return `❌ 拒绝访问,您已被列入黑名单。`;
3775
+ return `⛔ 您已被列入黑名单`;
3848
3776
  }
3777
+ if (!user) return "请输入“pk @玩家”。";
3849
3778
  const parsedUser = import_koishi.h.parse(user)[0];
3850
- if (!parsedUser || parsedUser.type !== "at" || !parsedUser.attrs.id) return "参数格式错误,请输入“pk @指定pk玩家”。";
3779
+ if (!parsedUser || parsedUser.type !== "at" || !parsedUser.attrs.id) return "参数格式错误,请输入“pk @玩家”。";
3851
3780
  const targetUserId = parsedUser.attrs.id;
3852
3781
  const targetUsername = await session.bot.getGuildMember(session.guildId, targetUserId);
3853
3782
  const [targetprofile] = await ctx.database.get("sc2arcade_player", { userId: targetUserId });
@@ -4016,7 +3945,7 @@ ${achievementList.join("\n")}`;
4016
3945
  `🎰 金币变动:${stealPercentage}%`
4017
3946
  ];
4018
3947
  isWin ? result.push(`💰 您从对方的口袋里抢夺了${goldTransfer}枚金币`) : result.push(`💸 您从口袋里拿出了${goldTransfer}枚金币上交给对方`);
4019
- initiatorCareer?.group === "辛迪加海盗" ? result.push(`🔴 海盗阵营奖励:获得1枚红晶`) : "";
3948
+ initiatorCareer?.group === "辛迪加海盗" ? result.push(`🔴 辛迪加海盗阵营加成:获得1枚红晶`) : "";
4020
3949
  result.push(`📅 剩余挑战次数:${config.dailyPKLimit - (initiatorPK.todayCount + 1)}`);
4021
3950
  return result.join("\n");
4022
3951
  } catch (error) {
@@ -4024,7 +3953,9 @@ ${achievementList.join("\n")}`;
4024
3953
  return "对战功能暂时不可用,请稍后重试";
4025
3954
  }
4026
3955
  });
4027
- ctx.command("ggcevo/pk榜 [page]", "查看玩家PK排行榜").usage("输入 pk榜 [页码] 查看对应页的排行榜,每页10条").action(async (_, page) => {
3956
+ ctx.command("ggcevo/pk榜 [page]", "查看玩家PK排行榜").usage("输入 pk榜 [页码] 查看对应页的排行榜,每页10条").action(async ({ session }, page) => {
3957
+ const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
3958
+ if (!profile) return "🔒 需要先绑定游戏句柄";
4028
3959
  const pageNum = parseInt(page) || 1;
4029
3960
  if (pageNum < 1) return "请输入有效的页码。";
4030
3961
  const offset = (pageNum - 1) * 10;
@@ -4035,7 +3966,7 @@ ${achievementList.join("\n")}`;
4035
3966
  ctx.database.select("ggcevo_pk").where({ enable: true }).execute((row) => import_koishi.$.count(row.handle))
4036
3967
  ]);
4037
3968
  const totalPages = Math.ceil(total / 10);
4038
- if (pageNum > totalPages) return `最多有 ${totalPages} 页`;
3969
+ if (pageNum > totalPages) return `查询失败,最多有 ${totalPages} 页`;
4039
3970
  if (!records.length) return "暂无PK记录";
4040
3971
  const rankingText = records.map((record, index) => {
4041
3972
  const winRate = record.total > 0 ? `${(record.wins / record.total * 100).toFixed(1)}%` : "N/A";
@@ -4057,7 +3988,7 @@ ${achievementList.join("\n")}`;
4057
3988
  });
4058
3989
  ctx.command("ggcevo/切换pk", "切换玩家对战状态").alias("切换pk状态").action(async ({ session }) => {
4059
3990
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
4060
- if (!profile) return "🔒 需要先绑定游戏句柄。";
3991
+ if (!profile) return "🔒 需要先绑定游戏句柄";
4061
3992
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
4062
3993
  const [pkRecord] = await ctx.database.get("ggcevo_pk", { handle }) || [null];
4063
3994
  const currentState = pkRecord?.enable ?? true;
@@ -4077,12 +4008,12 @@ ${achievementList.join("\n")}`;
4077
4008
  const now = convertUTCtoChinaTime(/* @__PURE__ */ new Date());
4078
4009
  const lastToggleTime = convertUTCtoChinaTime(lastToggle);
4079
4010
  const diffDays = Math.floor((now.getTime() - lastToggleTime.getTime()) / (1e3 * 3600 * 24));
4011
+ const [careers] = await ctx.database.get("ggcevo_careers", { handle });
4012
+ if (careers?.group === "辛迪加海盗") return "您已经加入了辛迪加海盗阵营,无法切换PK状态!";
4080
4013
  if (diffDays < 3 && lastToggleTime.getTime() !== 0) {
4081
4014
  const remaining = 3 - diffDays;
4082
4015
  return `状态切换冷却中,${remaining}天后再试(下次可切换时间:${new Date(lastToggle.getTime() + 3 * 864e5).toLocaleDateString("zh-CN")})。`;
4083
4016
  }
4084
- const [careers] = await ctx.database.get("ggcevo_careers", { handle });
4085
- if (careers?.group === "辛迪加海盗") return "您已经加入了辛迪加海盗阵营,无法切换PK状态!";
4086
4017
  const action = currentState ? "关闭" : "开启";
4087
4018
  await session.send(`您当前的PK状态为【${currentState ? "开启" : "关闭"}】,确认要${action}吗?(请在30秒内回复“是”确认)`);
4088
4019
  const confirm = await session.prompt(3e4);
@@ -4115,7 +4046,24 @@ ${achievementList.join("\n")}`;
4115
4046
  const CAREER_DISCOUNTS = [0, 0, 10, 15, 20];
4116
4047
  const baseDiscount = techLevel > 0 ? BASE_DISCOUNTS[techLevel - 1] : 0;
4117
4048
  const careerDiscount = isCareerMatch ? CAREER_DISCOUNTS[techLevel - 1] : 0;
4118
- const discountRate = Math.max(baseDiscount, careerDiscount);
4049
+ const techDiscount = Math.max(baseDiscount, careerDiscount);
4050
+ const activeWish = await ctx.database.get("ggcevo_Wish_Record", {
4051
+ handle,
4052
+ wishname: "蚱蜢优购",
4053
+ startTime: { $lte: /* @__PURE__ */ new Date() },
4054
+ endTime: { $gte: /* @__PURE__ */ new Date() },
4055
+ isused: false
4056
+ }).then((records) => records[0]);
4057
+ const grasshopperDiscount = activeWish ? 20 : 0;
4058
+ let totalDiscount = techDiscount + grasshopperDiscount;
4059
+ totalDiscount = Math.min(totalDiscount, 100);
4060
+ const discountDetails = [];
4061
+ if (techDiscount > 0) {
4062
+ discountDetails.push(`武器系统 Lv${techLevel}:${techDiscount}%`);
4063
+ }
4064
+ if (grasshopperDiscount > 0) {
4065
+ discountDetails.push(`蚱蜢优购祈愿:${grasshopperDiscount}%`);
4066
+ }
4119
4067
  const typeStats = Object.values(weaponConfig).filter((weapon) => weapon.price !== 0).reduce((stats, weapon) => {
4120
4068
  stats[weapon.type] = (stats[weapon.type] || 0) + 1;
4121
4069
  return stats;
@@ -4127,8 +4075,9 @@ ${achievementList.join("\n")}`;
4127
4075
  "====================",
4128
4076
  ...Object.entries(typeStats).map(([typeName, count]) => `▸ ${typeName} (${count}种)`),
4129
4077
  "====================",
4130
- discountRate > 0 && `
4131
- 🔧 当前购买折扣:${discountRate}% (武器系统 Lv${techLevel})`
4078
+ totalDiscount > 0 && `
4079
+ 🔧 当前购买折扣:
4080
+ ${discountDetails.length ? ` ${discountDetails.join(" \n ")}` : ""}`
4132
4081
  ].filter(Boolean).join("\n");
4133
4082
  }
4134
4083
  if (!Object.keys(typeStats).includes(type)) {
@@ -4136,22 +4085,27 @@ ${achievementList.join("\n")}`;
4136
4085
  ${Object.keys(typeStats).join("、")}`;
4137
4086
  }
4138
4087
  const items = Object.entries(weaponConfig).filter(([_, config2]) => config2.type === type && config2.price !== 0).map(([name2, config2]) => {
4139
- const actualPrice = Math.floor(config2.price * (1 - discountRate / 100));
4088
+ const actualPrice = Math.floor(config2.price * (100 - totalDiscount) / 100);
4140
4089
  const tagEffectsDesc = config2.tagEffects ? Object.entries(config2.tagEffects).map(([tag, multiplier]) => `▸ 对${tag}目标造成${(multiplier * 100).toFixed(0)}%伤害`).join("\n") : "▸ 无特殊加成效果";
4090
+ const specialEffect = config2.specialeffect ? `
4091
+ 特殊效果:${config2.specialeffect}` : "";
4141
4092
  return [
4142
4093
  `【${name2}】`,
4143
4094
  `类型:${config2.type}`,
4144
4095
  `基础伤害:${config2.damage}`,
4145
- `价格:${actualPrice}金币${discountRate > 0 ? ` (原价${config2.price})` : ""}`,
4096
+ `价格:${actualPrice}金币${totalDiscount > 0 ? ` (原价${config2.price})` : ""}`,
4146
4097
  "特性:",
4147
4098
  tagEffectsDesc,
4099
+ specialEffect,
4100
+ // 新增特殊效果显示
4148
4101
  `描述:${config2.description}`
4149
- ].join("\n");
4102
+ ].filter(Boolean).join("\n");
4150
4103
  });
4151
4104
  return [
4152
4105
  `🏪 咕咕武器库 - ${type} 🏪`,
4153
4106
  "使用“购买 武器名称”指令进行购买",
4154
- discountRate > 0 && `🔧 当前购买折扣:${discountRate}% (武器系统 Lv${techLevel})`,
4107
+ totalDiscount > 0 && `🔧 当前购买折扣:
4108
+ ${discountDetails.length ? ` ${discountDetails.join(" \n ")}` : ""}`,
4155
4109
  "====================",
4156
4110
  ...items,
4157
4111
  items.length === 0 ? "⚠️ 该分类下暂无可用武器" : ""
@@ -4199,10 +4153,10 @@ ${validTypes.join("、")}`;
4199
4153
  });
4200
4154
  ctx.command("ggcevo/购买 <item>").action(async ({ session }, item) => {
4201
4155
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
4202
- if (!profile) return "🔒 需要先绑定游戏句柄。";
4156
+ if (!profile) return "🔒 需要先绑定游戏句柄";
4203
4157
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
4204
4158
  const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
4205
- if (existingEntries.length > 0) return " 拒绝访问,您已被列入黑名单。";
4159
+ if (existingEntries.length > 0) return " 您已被列入黑名单";
4206
4160
  const allItems = { ...weaponConfig, ...SyndicatedItems };
4207
4161
  if (!item) return "请输入“购买 物品名称”来购买所需物品。";
4208
4162
  const config2 = allItems[item];
@@ -4219,8 +4173,8 @@ ${validTypes.join("、")}`;
4219
4173
  const [signInfo] = await ctx.database.get("ggcevo_sign", { handle });
4220
4174
  const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
4221
4175
  const [weaponTech] = await ctx.database.get("ggcevo_tech", { handle, techId: 2 });
4222
- let discountDetails = [];
4223
4176
  let totalDiscount = 0;
4177
+ let discountDetails = [];
4224
4178
  if (isWeapon && careerData?.group === "人类联盟") {
4225
4179
  const techDiscountTable = {
4226
4180
  3: [0, 10],
@@ -4235,7 +4189,7 @@ ${validTypes.join("、")}`;
4235
4189
  if (techDiscount > 0) {
4236
4190
  totalDiscount += techDiscount;
4237
4191
  discountDetails.push(
4238
- `武器系统 Lv${techLevel}${isQualifiedCareer ? "(职业加成)" : ""} ${techDiscount}%折扣`
4192
+ `武器系统 Lv${techLevel}${isQualifiedCareer ? "(职业加成)" : ""}:${techDiscount}%折扣`
4239
4193
  );
4240
4194
  }
4241
4195
  }
@@ -4249,8 +4203,9 @@ ${validTypes.join("、")}`;
4249
4203
  }).then((records) => records[0]) : null;
4250
4204
  if (activeWish) {
4251
4205
  const wishDiscount = 20;
4252
- totalDiscount = 100 - (100 - totalDiscount) * (100 - wishDiscount) / 100;
4253
- discountDetails.push(`蚱蜢优购祈愿生效 ${wishDiscount}%折扣`);
4206
+ totalDiscount += wishDiscount;
4207
+ discountDetails.push(`蚱蜢优购祈愿生效:${wishDiscount}%折扣`);
4208
+ totalDiscount = Math.min(totalDiscount, 100);
4254
4209
  }
4255
4210
  let actualPrice = config2.price;
4256
4211
  if (totalDiscount > 0) {
@@ -4260,7 +4215,7 @@ ${validTypes.join("、")}`;
4260
4215
  if ((signInfo?.totalRewards || 0) < actualPrice) {
4261
4216
  let priceInfo = `需要 ${actualPrice} 金币`;
4262
4217
  if (discountDetails.length > 0) {
4263
- priceInfo += `(原价 ${config2.price},累计折扣 ${totalDiscount}%)`;
4218
+ priceInfo += `(原价 ${config2.price})`;
4264
4219
  }
4265
4220
  return `❌ 金币不足,${priceInfo}`;
4266
4221
  }
@@ -4325,7 +4280,7 @@ ${validTypes.join("、")}`;
4325
4280
  });
4326
4281
  ctx.command("ggcevo/武器仓库").action(async ({ session }) => {
4327
4282
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
4328
- if (!profile) return "🔒 需要先绑定游戏句柄。";
4283
+ if (!profile) return "🔒 需要先绑定游戏句柄";
4329
4284
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
4330
4285
  const weapons = await ctx.database.get("ggcevo_equipment", {
4331
4286
  handle
@@ -4345,7 +4300,7 @@ ${validTypes.join("、")}`;
4345
4300
  ].join("\n");
4346
4301
  }));
4347
4302
  return [
4348
- `🛡️ ${handle}当前拥有的武器`,
4303
+ `🛡️ ${handle}拥有的武器`,
4349
4304
  '使用"装备 武器名称"来装备武器',
4350
4305
  "⚡表示当前装备武器",
4351
4306
  "──────────────",
@@ -4357,20 +4312,20 @@ ${validTypes.join("、")}`;
4357
4312
  });
4358
4313
  ctx.command("ggcevo/装备 <weapon>").action(async ({ session }, weapon) => {
4359
4314
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
4360
- if (!profile) return "🔒 需要先绑定游戏句柄。";
4361
- if (!weapon) return "请输入“装备 武器名称”来装备一把你拥有的武器。";
4362
- if (!weaponConfig[weapon]) return "请输入“装备 武器名称”来装备一把你拥有的武器。";
4363
- const config2 = weaponConfig[weapon];
4315
+ if (!profile) return "🔒 需要先绑定游戏句柄";
4364
4316
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
4365
4317
  const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
4366
4318
  if (existingEntries.length > 0) {
4367
- return `❌ 拒绝访问,您已被列入黑名单。`;
4319
+ return `⛔ 您已被列入黑名单`;
4368
4320
  }
4321
+ if (!weapon) return "请输入“装备 武器名称”来装备一把你拥有的武器。";
4322
+ if (!weaponConfig[weapon]) return "武器名称错误,请输入“装备 武器名称”来装备一把你拥有的武器。";
4323
+ const config2 = weaponConfig[weapon];
4369
4324
  const [owned] = await ctx.database.get("ggcevo_equipment", {
4370
4325
  handle,
4371
4326
  weaponId: config2.id
4372
4327
  });
4373
- if (!owned) return "尚未获得该武器。";
4328
+ if (!owned) return "您尚未获得该武器。";
4374
4329
  await ctx.database.withTransaction(async () => {
4375
4330
  await ctx.database.set(
4376
4331
  "ggcevo_equipment",
@@ -4391,10 +4346,10 @@ ${validTypes.join("、")}`;
4391
4346
  });
4392
4347
  ctx.command("ggcevo/升级 <target>", "升级武器或科技").action(async ({ session }, target) => {
4393
4348
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
4394
- if (!profile) return "🔒 需要先绑定游戏句柄。";
4349
+ if (!profile) return "🔒 需要先绑定游戏句柄";
4395
4350
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
4396
4351
  if ((await ctx.database.get("ggcevo_blacklist", { handle })).length) {
4397
- return " 拒绝访问,您已被列入黑名单";
4352
+ return " 您已被列入黑名单";
4398
4353
  }
4399
4354
  if (!target) {
4400
4355
  return generateUpgradePriceList(handle);
@@ -4412,10 +4367,10 @@ ${validTypes.join("、")}`;
4412
4367
  });
4413
4368
  ctx.command("ggcevo/改装 <weapon> [mod]", "安装武器模块").action(async ({ session }, weapon, mod) => {
4414
4369
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
4415
- if (!profile) return "🔒 需要先绑定游戏句柄。";
4370
+ if (!profile) return "🔒 需要先绑定游戏句柄";
4416
4371
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
4417
4372
  const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
4418
- if (existingEntries.length > 0) return " 拒绝访问,您已被列入黑名单";
4373
+ if (existingEntries.length > 0) return " 您已被列入黑名单";
4419
4374
  const isValidWeapon = weapon && weaponConfig[weapon]?.id !== void 0;
4420
4375
  const processModInstallation = /* @__PURE__ */ __name(async () => {
4421
4376
  const modInfo = modConfig[mod];
@@ -4424,7 +4379,7 @@ ${validTypes.join("、")}`;
4424
4379
  handle,
4425
4380
  weaponId: weaponConfig[weapon].id
4426
4381
  });
4427
- if (!equipment) return "尚未获得该武器。";
4382
+ if (!equipment) return "您尚未获得该武器。";
4428
4383
  if (modInfo.isExclusive) {
4429
4384
  if (modInfo.exclusiveTo !== weapon) return `❌ 该模块只能安装在${modInfo.exclusiveTo}上。`;
4430
4385
  const hasExclusive = equipment.installedMods.some((m) => modConfig[m]?.isExclusive);
@@ -4467,7 +4422,7 @@ ${validTypes.join("、")}`;
4467
4422
  return [
4468
4423
  `✅ ${weapon} 成功安装 ${mod}!`,
4469
4424
  discountMsg,
4470
- `花费金币:${actualCost}`,
4425
+ `花费金币:${actualCost}${discountRate > 0 ? `(原价${modInfo.cost})` : ""}`,
4471
4426
  `改装槽:${equipment.installedMods.length + 1}/${equipment.modificationSlots}`
4472
4427
  ].join("\n");
4473
4428
  }, "processModInstallation");
@@ -4510,7 +4465,8 @@ ${validTypes.join("、")}`;
4510
4465
  const universalMods = Object.entries(modConfig).filter(([_, m]) => !m.isExclusive).map(([name2, cfg]) => formatMod(name2, cfg));
4511
4466
  return [
4512
4467
  "🛠️ 通用武器模块 🛠️",
4513
- "使用「改装 武器名称 模块名称」安装专属模块",
4468
+ "使用「改装 武器名称 模块名称」安装通用模块",
4469
+ "输入「改装 武器名称」查询武器的专属模块",
4514
4470
  universalDiscountRate > 0 && `🔧 当前通用模块折扣:${universalDiscountRate}% (武器升级平台 Lv${techLevel})`,
4515
4471
  "====================",
4516
4472
  universalMods.join("\n\n")
@@ -4527,10 +4483,10 @@ ${validTypes.join("、")}`;
4527
4483
  const session = argv.session;
4528
4484
  let broadcastMessage = null;
4529
4485
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
4530
- if (!profile) return "🔒 需要先绑定游戏句柄。";
4486
+ if (!profile) return "🔒 需要先绑定游戏句柄";
4531
4487
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
4532
4488
  const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
4533
- if (existingEntries.length > 0) return " 拒绝访问,您已被列入黑名单。";
4489
+ if (existingEntries.length > 0) return " 您已被列入黑名单";
4534
4490
  const getActiveBossNames = /* @__PURE__ */ __name(async () => {
4535
4491
  const activeBosses2 = await ctx.database.get("ggcevo_boss", { isActive: true });
4536
4492
  return activeBosses2.map((b) => b.name).join(",");
@@ -4569,7 +4525,7 @@ ${validTypes.join("、")}`;
4569
4525
  const weaponConfigEntry = Object.entries(weaponConfig).find(([_, c]) => c.id === equippedWeapon.weaponId);
4570
4526
  const [weaponName, weaponData] = weaponConfigEntry;
4571
4527
  if (!weaponData.isantiair && targetBoss.groupId === 5) {
4572
- return "您装备的武器无法攻击空中目标!";
4528
+ return "您当前装备的武器无法攻击空中目标!";
4573
4529
  }
4574
4530
  const activeBosses = await ctx.database.get("ggcevo_boss", { isActive: true });
4575
4531
  if (!activeBosses.length) return "当前没有存活的异形,请等待下一轮刷新。";
@@ -4579,6 +4535,120 @@ ${validTypes.join("、")}`;
4579
4535
  if (!bossGroup) return "无法获取异形组配置。";
4580
4536
  const maxHP = targetBoss.type === "主宰" ? bossGroup.main.maxHP : bossGroup.minions.find((m) => m.name === targetBoss.name)?.maxHP || 0;
4581
4537
  const { damage, hasCrit, effectMessage } = await calculateTotalDamage(ctx, session, equippedWeapon, targetBoss);
4538
+ const extraDamages = [];
4539
+ const actuallyDead = [];
4540
+ let scatterBroadcast = null;
4541
+ if (equippedWeapon.installedMods?.includes("光束曲射晶片") && weaponName === "碎骨步枪") {
4542
+ const activeBosses2 = await ctx.database.get("ggcevo_boss", {
4543
+ isActive: true,
4544
+ name: { $ne: targetBoss.name }
4545
+ // 排除当前目标
4546
+ });
4547
+ if (activeBosses2.length > 0) {
4548
+ effectMessage.push("🔆 【光束曲射晶片】触发!");
4549
+ const baseDamage = weaponData.damage * (1 + 0.1 * equippedWeapon.level);
4550
+ const secondaryDamage = Math.round(baseDamage * 0.5);
4551
+ for (const secondaryTarget of activeBosses2) {
4552
+ const secondaryMaxHP = getBossMaxHP(secondaryTarget.name);
4553
+ let currentDamage = secondaryDamage;
4554
+ const passiveResult2 = await PassiveHandler.handlePassives(
4555
+ ctx,
4556
+ secondaryTarget,
4557
+ currentDamage,
4558
+ secondaryTarget.HP - currentDamage,
4559
+ secondaryMaxHP,
4560
+ weaponName,
4561
+ weaponData,
4562
+ activeBosses2,
4563
+ bossGroup
4564
+ );
4565
+ const finalDamage = passiveResult2.initialDamage;
4566
+ const actualDamage = Math.min(finalDamage, secondaryTarget.HP);
4567
+ extraDamages.push({
4568
+ name: secondaryTarget.name,
4569
+ damage: actualDamage
4570
+ });
4571
+ const newHP = passiveResult2.currentHP;
4572
+ if (passiveResult2.skillUpdates.length > 0) {
4573
+ await PassiveHandler.applySkillUpdates(ctx, passiveResult2.skillUpdates);
4574
+ }
4575
+ const isDead = newHP <= 0;
4576
+ await ctx.database.set(
4577
+ "ggcevo_boss",
4578
+ { name: secondaryTarget.name },
4579
+ {
4580
+ HP: Math.max(newHP, 0),
4581
+ isActive: !isDead
4582
+ }
4583
+ );
4584
+ effectMessage.push(...passiveResult2.messages.map((m) => `+ 对 ${secondaryTarget.name} ${m}`));
4585
+ if (isDead) {
4586
+ actuallyDead.push(secondaryTarget.name);
4587
+ if (secondaryTarget.type === "子代") {
4588
+ if (secondaryTarget.name === "机械感染虫") {
4589
+ const [mainBoss] = await ctx.database.get("ggcevo_boss", {
4590
+ groupId: secondaryTarget.groupId,
4591
+ type: "主宰",
4592
+ isActive: true
4593
+ });
4594
+ if (mainBoss && !mainBoss.skills.includes("孤立无援")) {
4595
+ await ctx.database.set("ggcevo_boss", { name: mainBoss.name }, {
4596
+ skills: [...mainBoss.skills, "孤立无援"]
4597
+ });
4598
+ broadcastMessage = "💥 机械感染虫已阵亡,空间站感染虫进入【孤立无援】状态,受到的伤害+20%!";
4599
+ }
4600
+ } else {
4601
+ const remainingMinions = await ctx.database.get("ggcevo_boss", {
4602
+ groupId: secondaryTarget.groupId,
4603
+ type: "子代",
4604
+ isActive: true
4605
+ });
4606
+ if (remainingMinions.length === 0) {
4607
+ const [mainBoss] = await ctx.database.get("ggcevo_boss", {
4608
+ groupId: secondaryTarget.groupId,
4609
+ type: "主宰",
4610
+ isActive: true
4611
+ });
4612
+ if (mainBoss && !mainBoss.skills.includes("孤立无援")) {
4613
+ await ctx.database.set("ggcevo_boss", { name: mainBoss.name }, {
4614
+ skills: [...mainBoss.skills, "孤立无援"]
4615
+ });
4616
+ broadcastMessage = `💥 所有子代已阵亡,${mainBoss.name}进入【孤立无援】状态,受到的伤害+20%!`;
4617
+ }
4618
+ }
4619
+ }
4620
+ } else if (secondaryTarget.type === "主宰") {
4621
+ await ctx.database.set(
4622
+ "ggcevo_boss",
4623
+ { groupId: secondaryTarget.groupId },
4624
+ {
4625
+ isActive: false,
4626
+ HP: 0
4627
+ }
4628
+ );
4629
+ const respawnTime = /* @__PURE__ */ new Date();
4630
+ respawnTime.setSeconds(respawnTime.getSeconds() + 3600);
4631
+ await ctx.database.set(
4632
+ "ggcevo_boss",
4633
+ { name: secondaryTarget.name },
4634
+ { respawnTime }
4635
+ );
4636
+ const { rewardMessages } = await handleBossDefeatRewards(ctx, secondaryTarget);
4637
+ await ctx.database.remove("ggcevo_boss_damage", {
4638
+ bossGroupId: secondaryTarget.groupId
4639
+ });
4640
+ scatterBroadcast = [
4641
+ `🎯 主宰 ${secondaryTarget.name} 已被 ${session.username} 的散射伤害击败!`,
4642
+ `所有子代已消失,下一个主宰将在1小时后重生`,
4643
+ "",
4644
+ "🏆 伤害排行榜奖励:",
4645
+ ...rewardMessages
4646
+ ].join("\n");
4647
+ }
4648
+ }
4649
+ }
4650
+ }
4651
+ }
4582
4652
  let initialDamage = Math.min(damage, targetBoss.HP);
4583
4653
  let currentHP = targetBoss.HP - initialDamage;
4584
4654
  let passiveMessages = [];
@@ -4604,11 +4674,12 @@ ${validTypes.join("、")}`;
4604
4674
  handle,
4605
4675
  bossGroupId: targetBoss.groupId
4606
4676
  });
4677
+ const totalDamage = initialDamage + extraDamages.reduce((sum, d) => sum + d.damage, 0);
4607
4678
  await ctx.database.upsert("ggcevo_boss_damage", [{
4608
4679
  handle,
4609
4680
  bossGroupId: targetBoss.groupId,
4610
4681
  playerName: session.username,
4611
- totalDamage: (existingRecord?.totalDamage || 0) + initialDamage,
4682
+ totalDamage: (existingRecord?.totalDamage || 0) + totalDamage,
4612
4683
  // 改为实际伤害
4613
4684
  attackCount: (existingRecord?.attackCount || 0) + 1,
4614
4685
  lastattackDate: /* @__PURE__ */ new Date()
@@ -4630,7 +4701,7 @@ ${validTypes.join("、")}`;
4630
4701
  { name: targetBoss.name },
4631
4702
  { respawnTime }
4632
4703
  );
4633
- const { rewardMessages } = await handleBossDefeatRewards(ctx, targetBoss, session);
4704
+ const { rewardMessages } = await handleBossDefeatRewards(ctx, targetBoss);
4634
4705
  await ctx.database.remove("ggcevo_boss_damage", {
4635
4706
  bossGroupId: targetBoss.groupId
4636
4707
  });
@@ -4715,7 +4786,7 @@ ${validTypes.join("、")}`;
4715
4786
  }], ["handle"]);
4716
4787
  redcrystalMessage = "🔴 清洁工职业加成:获得1枚红晶";
4717
4788
  }
4718
- const finalReward = Math.round(initialDamage * careerMultiplier);
4789
+ const finalReward = Math.round(totalDamage * careerMultiplier);
4719
4790
  const [existingSign] = await ctx.database.get("ggcevo_sign", { handle });
4720
4791
  await ctx.database.upsert("ggcevo_sign", [{
4721
4792
  handle,
@@ -4734,16 +4805,25 @@ ${effectMessage.map((m) => `▸ ${m}`).join("\n")}`
4734
4805
  ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
4735
4806
  ] : [],
4736
4807
  `造成伤害:${initialDamage}${hasCrit ? "(✨ 暴击)" : ""}`,
4808
+ ...extraDamages.length > 0 ? [
4809
+ `⚡ 散射伤害:`,
4810
+ ...extraDamages.map((d) => `▸ 对 ${d.name} 造成 ${d.damage} 伤害`)
4811
+ ] : [],
4737
4812
  `获得金币:${finalReward}${careerMessage}`,
4738
4813
  redcrystalMessage,
4739
4814
  `目标剩余HP:${Math.max(currentHP, 0)}/${maxHP}`,
4815
+ ...actuallyDead.length > 0 ? [
4816
+ `💀 散射击杀:${actuallyDead.join(", ")}`
4817
+ ] : [],
4740
4818
  isDefeated ? `🎉 恭喜,已成功击败 ${targetBoss.name}!` : ""
4741
4819
  ].filter((line) => line).join("\n");
4742
4820
  await session.send(resultMessage);
4743
- if (broadcastMessage) {
4744
- const finalBroadcast = Array.isArray(broadcastMessage) ? broadcastMessage.join("\n") : broadcastMessage;
4821
+ if (scatterBroadcast) {
4822
+ const groupId = [...config2.groupId];
4823
+ await ctx.broadcast(groupId, Array.isArray(scatterBroadcast) ? scatterBroadcast.join("\n") : scatterBroadcast);
4824
+ } else if (broadcastMessage) {
4745
4825
  const groupId = [...config2.groupId];
4746
- await ctx.broadcast(groupId, finalBroadcast);
4826
+ await ctx.broadcast(groupId, Array.isArray(broadcastMessage) ? broadcastMessage.join("\n") : broadcastMessage);
4747
4827
  }
4748
4828
  });
4749
4829
  ctx.command("ggcevo/攻击假人").option("tags", "-t <tags:string> 添加BOSS标签(逗号分隔)").action(async (argv) => {
@@ -4752,10 +4832,10 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
4752
4832
  const parseList = /* @__PURE__ */ __name((str) => str ? str.split(",").map((s) => s.trim()).filter(Boolean) : [], "parseList");
4753
4833
  const tags = parseList(options.tags);
4754
4834
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
4755
- if (!profile) return "🔒 需要先绑定游戏句柄。";
4835
+ if (!profile) return "🔒 需要先绑定游戏句柄";
4756
4836
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
4757
4837
  const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
4758
- if (existingEntries.length > 0) return " 拒绝访问,您已被列入黑名单。";
4838
+ if (existingEntries.length > 0) return " 您已被列入黑名单";
4759
4839
  const [equippedWeapon] = await ctx.database.get("ggcevo_equipment", {
4760
4840
  handle,
4761
4841
  equipped: true
@@ -4792,14 +4872,14 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
4792
4872
  // 这里添加符号
4793
4873
  ] : [],
4794
4874
  `📊 理论伤害值:${damage}${hasCrit ? " (✨ 触发暴击)" : ""}`,
4795
- "💡 提示:使用 -t 重甲,生物…… 添加测试标签"
4875
+ "💡 提示:使用 -t 重甲,生物……(标签之间用英文逗号分隔) 添加测试标签"
4796
4876
  ].filter((line) => line).join("\n");
4797
4877
  });
4798
4878
  ctx.command("ggcevo/伤害榜 [page]", "查看当前主宰伤害排名").usage("输入 伤害榜 [页码] 查看对应页的排行榜,每页10条").action(async (_, page) => {
4799
4879
  const pageNum = parseInt(page) || 1;
4800
4880
  if (pageNum < 1) return "请输入有效的页码。";
4801
4881
  const activeBosses = await ctx.database.get("ggcevo_boss", { isActive: true });
4802
- if (!activeBosses.length) return "当前没有存活的异形,请等待1小时后刷新。";
4882
+ if (!activeBosses.length) return "当前没有存活的异形,请等待下次刷新。";
4803
4883
  const mainBoss = activeBosses.find((b) => b.type === "主宰");
4804
4884
  if (!mainBoss) return "当前数据异常,请联系管理员";
4805
4885
  const offset = (pageNum - 1) * 10;
@@ -4810,7 +4890,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
4810
4890
  ctx.database.select("ggcevo_boss_damage").where({ bossGroupId: mainBoss.groupId }).execute((row) => import_koishi.$.count(row.handle))
4811
4891
  ]);
4812
4892
  const totalPages = Math.ceil(total / 10);
4813
- if (pageNum > totalPages) return `最多有 ${totalPages} 页`;
4893
+ if (pageNum > totalPages) return `查询失败,最多有 ${totalPages} 页`;
4814
4894
  if (!records.length) return "暂无伤害记录";
4815
4895
  const rankingText = records.map(
4816
4896
  (record, index) => `${offset + index + 1}. ${record.playerName || "未知玩家"} | 总伤害: ${record.totalDamage} | 攻击次数: ${record.attackCount}`
@@ -4826,7 +4906,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
4826
4906
  });
4827
4907
  ctx.command("ggcevo/异形信息", "查看当前主宰信息").alias("yx信息").action(async () => {
4828
4908
  const activeBosses = await ctx.database.get("ggcevo_boss", { isActive: true });
4829
- if (!activeBosses.length) return "当前没有存活的异形,请等待1小时后刷新。";
4909
+ if (!activeBosses.length) return "当前没有存活的异形,请等待下次刷新。";
4830
4910
  const mainBoss = activeBosses.find((b) => b.type === "主宰");
4831
4911
  const minions = activeBosses.filter((b) => b.type === "子代");
4832
4912
  if (!mainBoss) return "当前数据异常,请联系管理员";
@@ -4858,7 +4938,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
4858
4938
  }
4859
4939
  return result.join("\n");
4860
4940
  });
4861
- ctx.command("ggcevo/初始化异形 <groupid:number>", "初始化指定主宰组", { authority: 3 }).action(async (_, groupid) => {
4941
+ ctx.command("ggcevo/初始化异形 <groupid:number>", "初始化指定主宰组", { authority: 3 }).alias("初始化yx").action(async (_, groupid) => {
4862
4942
  if (!groupid) groupid = 1;
4863
4943
  const bossConfig = bossPool.find((g) => g.main.id === groupid);
4864
4944
  if (!bossConfig) {
@@ -4892,11 +4972,11 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
4892
4972
  ctx.command("ggcevo/祈愿").action(async (argv) => {
4893
4973
  const session = argv.session;
4894
4974
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
4895
- if (!profile) return "🔒 需要先绑定游戏句柄。";
4975
+ if (!profile) return "🔒 需要先绑定游戏句柄";
4896
4976
  const { regionId, realmId, profileId } = profile;
4897
4977
  const handle = `${regionId}-S2-${realmId}-${profileId}`;
4898
4978
  const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
4899
- if (existingEntries.length > 0) return " 拒绝访问,您已被列入黑名单。";
4979
+ if (existingEntries.length > 0) return " 您已被列入黑名单";
4900
4980
  const [sign] = await ctx.database.get("ggcevo_sign", { handle });
4901
4981
  if (!sign || sign.totalRewards < 50) return "需要50金币进行祈愿,您的金币不足。";
4902
4982
  const now = /* @__PURE__ */ new Date();
@@ -4967,19 +5047,19 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
4967
5047
  return `✨ 祈愿成功!花费50枚金币获得【${effect.name}】效果:${effect.effect}
4968
5048
  ⏳ 效果持续至 ${formattedEndTime}`;
4969
5049
  });
4970
- ctx.command("兑换金币", "使用兑换券兑换金币").action(async ({ session }) => {
5050
+ ctx.command("ggcevo/兑换金币", "使用兑换券兑换金币").action(async ({ session }) => {
4971
5051
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
4972
- if (!profile) return "🔒 需要先绑定游戏句柄。";
5052
+ if (!profile) return "🔒 需要先绑定游戏句柄";
4973
5053
  const { regionId, realmId, profileId } = profile;
4974
5054
  const handle = `${regionId}-S2-${realmId}-${profileId}`;
4975
5055
  const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
4976
5056
  if (existingEntries.length > 0) {
4977
- return `❌ 拒绝访问,您已被列入黑名单。`;
5057
+ return `⛔ 您已被列入黑名单`;
4978
5058
  }
4979
5059
  await session.send(`请输入你要使用多少张兑换券来兑换金币?(请在30秒内回复数字,回复“0”为取消兑换)
4980
5060
  注意:1张兑换券=2000金币`);
4981
5061
  const exchangeInput = await session.prompt(3e4);
4982
- if (!exchangeInput) return "输入超时,请重新输入。";
5062
+ if (!exchangeInput) return "已取消操作,请重新输入。";
4983
5063
  const exchangeCount = parseInt(exchangeInput, 10);
4984
5064
  if (isNaN(exchangeCount)) return "请输入有效的数字!";
4985
5065
  if (exchangeCount < 0) return "兑换数量不能为负数!";
@@ -5006,13 +5086,13 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
5006
5086
  });
5007
5087
  return `成功使用${exchangeCount}张兑换券,获得${goldAmount}枚金币!`;
5008
5088
  });
5009
- ctx.command("兑换红晶", "使用金币兑换红晶").action(async ({ session }) => {
5089
+ ctx.command("ggcevo/兑换红晶", "使用金币兑换红晶").action(async ({ session }) => {
5010
5090
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
5011
- if (!profile) return "🔒 需要先绑定游戏句柄。";
5091
+ if (!profile) return "🔒 需要先绑定游戏句柄";
5012
5092
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
5013
5093
  const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
5014
5094
  if (existingEntries.length > 0) {
5015
- return `❌ 拒绝访问,您已被列入黑名单。`;
5095
+ return `⛔ 您已被列入黑名单`;
5016
5096
  }
5017
5097
  const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
5018
5098
  if (!careerData || careerData.group !== "辛迪加海盗") {
@@ -5021,7 +5101,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
5021
5101
  await session.send(`请输入你想要兑换多少红晶?(请在30秒内回复数字,回复“0”为取消兑换)
5022
5102
  注意:每块红晶需要950金币。`);
5023
5103
  const exchangeInput = await session.prompt(3e4);
5024
- if (!exchangeInput) return "输入超时,请重新输入。";
5104
+ if (!exchangeInput) return "已取消操作,请重新输入。";
5025
5105
  const exchangeCount = parseInt(exchangeInput, 10);
5026
5106
  if (isNaN(exchangeCount)) return "请输入有效的数字!";
5027
5107
  if (exchangeCount < 0) return "兑换数量不能为负数!";
@@ -5048,12 +5128,12 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
5048
5128
  });
5049
5129
  ctx.command("ggcevo/加入 <faction>", "加入阵营").alias("加入阵营").action(async ({ session }, faction) => {
5050
5130
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
5051
- if (!profile) return "🔒 需要先绑定游戏句柄。";
5131
+ if (!profile) return "🔒 需要先绑定游戏句柄";
5052
5132
  const { regionId, realmId, profileId } = profile;
5053
5133
  const handle = `${regionId}-S2-${realmId}-${profileId}`;
5054
5134
  const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
5055
5135
  if (existingEntries.length > 0) {
5056
- return `❌ 拒绝访问,您已被列入黑名单。`;
5136
+ return `⛔ 您已被列入黑名单`;
5057
5137
  }
5058
5138
  const validFactions = ["人类联盟", "辛迪加海盗"];
5059
5139
  if (!faction) return `请输入“加入 阵营名称”加入对应阵营
@@ -5089,7 +5169,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
5089
5169
  } else if (faction === "辛迪加海盗") {
5090
5170
  const [pkData] = await ctx.database.get("ggcevo_pk", { handle });
5091
5171
  if (userCoins < 2e3) {
5092
- return `加入辛迪加海盗需要2000金币并且永久开启PK功能,你当前拥有${userCoins}金币`;
5172
+ return `加入辛迪加海盗需要缴纳2000金币并且永久开启PK功能,你当前拥有${userCoins}金币`;
5093
5173
  }
5094
5174
  if (pkData && !pkData?.enable) {
5095
5175
  return "当前PK功能未开启,无法加入辛迪加海盗。";
@@ -5117,11 +5197,11 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
5117
5197
  });
5118
5198
  ctx.command("ggcevo/转职 [profession]", "转职系统").action(async ({ session }, profession) => {
5119
5199
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
5120
- if (!profile) return "🔒 需要先绑定游戏句柄。";
5200
+ if (!profile) return "🔒 需要先绑定游戏句柄";
5121
5201
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
5122
5202
  const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
5123
5203
  if (existingEntries.length > 0) {
5124
- return `❌ 拒绝访问,您已被列入黑名单。`;
5204
+ return `⛔ 您已被列入黑名单`;
5125
5205
  }
5126
5206
  const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
5127
5207
  if (!careerData) return "请先加入阵营后使用转职功能。";
@@ -5169,7 +5249,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
5169
5249
  try {
5170
5250
  if (careerData.group === "人类联盟") {
5171
5251
  if (userCoins < targetProfession.costcoins) {
5172
- return `转职需要 ${targetProfession.costcoins} 金币,当前拥有 ${userCoins} 金币`;
5252
+ return `转职需要 ${targetProfession.costcoins} 金币,您当前拥有 ${userCoins}`;
5173
5253
  }
5174
5254
  await ctx.database.upsert("ggcevo_sign", [{
5175
5255
  handle,
@@ -5177,7 +5257,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
5177
5257
  }], ["handle"]);
5178
5258
  } else if (careerData.group === "辛迪加海盗") {
5179
5259
  if (userRedCrystal < (targetProfession.costredcrystal || 0)) {
5180
- return `需要红晶 ${targetProfession.costredcrystal},当前 ${userRedCrystal}`;
5260
+ return `需要红晶 ${targetProfession.costredcrystal},您当前拥有 ${userRedCrystal}`;
5181
5261
  }
5182
5262
  await Promise.all([
5183
5263
  ctx.database.upsert("ggcevo_careers", [{
@@ -5202,7 +5282,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
5202
5282
  const [profile] = await ctx.database.get("sc2arcade_player", {
5203
5283
  userId: session.userId
5204
5284
  });
5205
- if (!profile) return "🔒 需要先绑定游戏句柄。";
5285
+ if (!profile) return "🔒 需要先绑定游戏句柄";
5206
5286
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
5207
5287
  const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
5208
5288
  if (!careerData) return "您尚未加入任何阵营。";
@@ -5241,7 +5321,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
5241
5321
  });
5242
5322
  ctx.command("ggcevo/黑市 [type]", "辛迪加海盗专属黑市").usage("输入“黑市”查看类型,或“黑市 类型”查看详细").action(async ({ session }, type) => {
5243
5323
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
5244
- if (!profile) return "🔒 需要先绑定游戏句柄。";
5324
+ if (!profile) return "🔒 需要先绑定游戏句柄";
5245
5325
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
5246
5326
  const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
5247
5327
  if (!careerData || careerData.group !== "辛迪加海盗") {
@@ -5303,23 +5383,23 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
5303
5383
  ];
5304
5384
  return [
5305
5385
  `🏴☠️ 辛迪加黑市 - ${normalizedType} 🏴☠️`,
5306
- "使用“订购 物品名称”进行购买(仅消耗红晶)",
5386
+ "使用“订购 物品名称”进行购买(仅消耗红晶)",
5307
5387
  "====================",
5308
5388
  ...items
5309
5389
  ].join("\n\n");
5310
5390
  });
5311
5391
  ctx.command("ggcevo/订购 <item>").action(async ({ session }, item) => {
5312
5392
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
5313
- if (!profile) return "🔒 需要先绑定游戏句柄。";
5393
+ if (!profile) return "🔒 需要先绑定游戏句柄";
5314
5394
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
5315
5395
  if (await ctx.database.get("ggcevo_blacklist", { handle }).then((r) => r.length)) {
5316
- return " 拒绝访问,您已被列入黑名单";
5396
+ return " 您已被列入黑名单";
5317
5397
  }
5318
5398
  const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
5319
5399
  if (!careerData || careerData.group !== "辛迪加海盗") {
5320
5400
  return "🚫 该功能需要【辛迪加海盗】阵营权限";
5321
5401
  }
5322
- if (!item) return "请输入“订购 物品名称”来向辛迪加订购物品。";
5402
+ if (!item) return "请输入“订购 物品名称”向辛迪加总部订购物品。";
5323
5403
  const isWeapon = Object.prototype.hasOwnProperty.call(weaponConfig, item);
5324
5404
  const isSyndicatedItem = Object.prototype.hasOwnProperty.call(SyndicatedItems, item);
5325
5405
  if (!isWeapon && !isSyndicatedItem) return "❌ 无效物品名称";
@@ -5396,7 +5476,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
5396
5476
  ctx.command("ggcevo/仓库").action(async (argv) => {
5397
5477
  const session = argv.session;
5398
5478
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
5399
- if (!profile) return "🔒 需要先绑定游戏句柄。";
5479
+ if (!profile) return "🔒 需要先绑定游戏句柄";
5400
5480
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
5401
5481
  const [items, signData, careerData] = await Promise.all([
5402
5482
  ctx.database.get("ggcevo_warehouse", { handle }),
@@ -5427,7 +5507,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
5427
5507
  // 移除数量显示在标题
5428
5508
  `类型:${itemData.type} | 持有数量:${warehouseItem.quantity}`,
5429
5509
  // 从warehouse表读取实际数量
5430
- `特效:${itemData.effects}`,
5510
+ `效果:${itemData.effects}`,
5431
5511
  `描述:${itemData.description}`,
5432
5512
  "――――――――――――――"
5433
5513
  ].join("\n");
@@ -5439,12 +5519,13 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
5439
5519
  ctx.command("ggcevo/使用 [itemName] [target]").action(async (argv, itemName, target) => {
5440
5520
  const session = argv.session;
5441
5521
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
5442
- if (!profile) return "🔒 需要先绑定游戏句柄。";
5522
+ if (!profile) return "🔒 需要先绑定游戏句柄";
5443
5523
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
5444
5524
  if (await ctx.database.get("ggcevo_blacklist", { handle }).then((r) => r.length)) {
5445
5525
  return "⛔ 您已被列入黑名单";
5446
5526
  }
5447
5527
  try {
5528
+ if (!itemName) return "请输入“使用 物品名称 (可选目标)”使用仓库中的物品。";
5448
5529
  const warehouseItems = await ctx.database.get("ggcevo_warehouse", { handle });
5449
5530
  const targetItem = warehouseItems.find((item) => {
5450
5531
  const entry = Object.entries(SyndicatedItems).find(
@@ -5479,13 +5560,14 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
5479
5560
  });
5480
5561
  ctx.command("ggcevo/科技 [techName]", "查看空间站科技信息").usage("输入“科技”查看列表,或“科技 科技名称”查看详细信息").action(async ({ session }, techName) => {
5481
5562
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
5482
- if (!profile) return "🔒 需要先绑定游戏句柄。";
5563
+ if (!profile) return "🔒 需要先绑定游戏句柄";
5483
5564
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
5484
5565
  const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
5485
5566
  if (!careerData || careerData.group !== "人类联盟") {
5486
5567
  return "🚫 该功能需要【人类联盟】阵营权限";
5487
5568
  }
5488
5569
  const romanNumerals = { 1: "I", 2: "II", 3: "III", 4: "IV", 5: "V" };
5570
+ const isIntelligenceOfficer = careerData?.career === "情报副官";
5489
5571
  if (!techName) {
5490
5572
  const techList = Spacestationtechnology.map(
5491
5573
  (tech2) => `▸ ${tech2.techname} (最大等级 ${romanNumerals[tech2.maxLevel]})`
@@ -5495,8 +5577,10 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
5495
5577
  '使用 "科技 科技名称" 查看详细信息',
5496
5578
  "====================",
5497
5579
  ...techList,
5498
- "===================="
5499
- ].join("\n");
5580
+ "====================",
5581
+ isIntelligenceOfficer && "※ 情报副官享受20%升级折扣"
5582
+ // 新增折扣提示
5583
+ ].filter(Boolean).join("\n");
5500
5584
  }
5501
5585
  const tech = Spacestationtechnology.find(
5502
5586
  (t) => t.techname === techName
@@ -5504,9 +5588,13 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
5504
5588
  if (!tech) return `❌ 无效科技名称,可用科技:
5505
5589
  ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
5506
5590
  const techDetails = tech.levels.map((level) => {
5591
+ const originalCost = level.cost;
5592
+ const discountedCost = isIntelligenceOfficer ? Math.floor(originalCost * 0.8) : originalCost;
5593
+ const costDesc = isIntelligenceOfficer ? `▸ 升级花费:${discountedCost}金币 (原价${originalCost})` : `▸ 升级花费:${originalCost}金币`;
5507
5594
  return [
5508
5595
  `✦ 等级 ${romanNumerals[level.level]}`,
5509
- `▸ 升级花费:${level.cost}金币`,
5596
+ costDesc,
5597
+ // 修改后的价格显示
5510
5598
  `▸ 基础效果:${level.description}`,
5511
5599
  `💼 ${level.careerBonus}`,
5512
5600
  "------------------"
@@ -5518,16 +5606,14 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
5518
5606
  '使用 "升级 科技名称" 进行升级',
5519
5607
  "====================",
5520
5608
  ...techDetails,
5521
- "===================="
5522
- ].join("\n");
5609
+ "====================",
5610
+ isIntelligenceOfficer && "※ 情报副官享受20%升级折扣"
5611
+ // 新增折扣提示
5612
+ ].filter(Boolean).join("\n");
5523
5613
  });
5524
5614
  ctx.command("ggcevo/挖矿").action(async ({ session }) => {
5525
- const convertUTCtoChinaTime2 = /* @__PURE__ */ __name((utcDate) => {
5526
- const chinaOffset = 8 * 60 * 60 * 1e3;
5527
- return new Date(utcDate.getTime() + chinaOffset);
5528
- }, "convertUTCtoChinaTime");
5529
5615
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
5530
- if (!profile) return "🔒 需要先绑定游戏句柄。";
5616
+ if (!profile) return "🔒 需要先绑定游戏句柄";
5531
5617
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
5532
5618
  if (await ctx.database.get("ggcevo_blacklist", { handle }).then((r) => r.length)) {
5533
5619
  return "⛔ 您已被列入黑名单";
@@ -5552,8 +5638,8 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
5552
5638
  return "⛏️ 挖矿作业已开始,至少1小时后可收获。";
5553
5639
  }
5554
5640
  const nowtime = /* @__PURE__ */ new Date();
5555
- const chinaStart = convertUTCtoChinaTime2(record.startTime);
5556
- const chinaNow = convertUTCtoChinaTime2(nowtime);
5641
+ const chinaStart = convertUTCtoChinaTime(record.startTime);
5642
+ const chinaNow = convertUTCtoChinaTime(nowtime);
5557
5643
  const duration = Math.floor(
5558
5644
  (chinaNow.getTime() - chinaStart.getTime()) / 1e3 / 60
5559
5645
  );
@@ -5564,7 +5650,7 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
5564
5650
  `🕒 开始时间:${record.startTime.toLocaleString("zh-CN", { hour12: false })}`,
5565
5651
  `⏱️ 当前时间:${nowtime.toLocaleString("zh-CN", { hour12: false })}`,
5566
5652
  `⏳ 还需等待:${remaining}分钟`,
5567
- `💡 提示:达到1小时可随时收获并自动开始下一轮`
5653
+ `💡 提示:挖矿1小时后可随时收获并自动开始下一轮`
5568
5654
  ].join("\n");
5569
5655
  }
5570
5656
  const halfHours = Math.floor(duration / 30);
@@ -5602,11 +5688,8 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
5602
5688
  `🕒 开始时间:${record.startTime.toLocaleString("zh-CN", { hour12: false })}`,
5603
5689
  `⏱️ 结束时间:${nowtime.toLocaleString("zh-CN", { hour12: false })}`,
5604
5690
  `⏳ 持续时间:${formatTime(duration)}`,
5605
- ...tech.level >= 4 ? (
5606
- // 仅当科技等级≥3时显示加成信息
5607
- [`🔧 科技加成(Lv.${tech.level}):+${multiplier * 100}%`]
5608
- ) : [],
5609
5691
  `💰 实际获得:${total}金币`,
5692
+ ...tech.level >= 4 ? [`🔧 挖矿系统 Lv.${tech.level}:金币+${multiplier * 100}%`] : [],
5610
5693
  "💡 已自动开始下一轮挖矿"
5611
5694
  ].join("\n");
5612
5695
  });