koishi-plugin-ggcevo-game 1.2.64 → 1.2.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.ts CHANGED
@@ -40,6 +40,7 @@ declare module 'koishi' {
40
40
  ggcevo_boss_damage: BossDamageRecord;
41
41
  ggcevo_Wish_Record: WishRecord;
42
42
  ggcevo_careers: careers;
43
+ ggcevo_warehouse: warehouse;
43
44
  }
44
45
  }
45
46
  export interface backpack {
@@ -178,4 +179,9 @@ export interface careers {
178
179
  redcrystal: number;
179
180
  date: Date;
180
181
  }
182
+ export interface warehouse {
183
+ handle: string;
184
+ itemId: number;
185
+ quantity: number;
186
+ }
181
187
  export declare function apply(ctx: Context, config: Config): void;
package/lib/index.js CHANGED
@@ -271,6 +271,28 @@ function apply(ctx, config) {
271
271
  }, {
272
272
  primary: "handle"
273
273
  });
274
+ ctx.model.extend("ggcevo_warehouse", {
275
+ handle: "string",
276
+ itemId: "unsigned",
277
+ quantity: "unsigned"
278
+ }, {
279
+ primary: ["handle", "itemId"]
280
+ });
281
+ const SyndicatedItems = {
282
+ "E-2能量炸弹": {
283
+ id: 1e3,
284
+ type: "爆破物",
285
+ description: "一种小型的机械装置,用于吸收空间站能量并进行爆破",
286
+ redCrystalCost: 30,
287
+ effects: "仅当主宰为“空间站感染虫”时使用,对“空间站哨枪塔”造成其当前血量值的伤害",
288
+ // 确保结构兼容性
289
+ price: 0,
290
+ damage: 0,
291
+ // 若需要可补充伤害值
292
+ tagEffects: {}
293
+ // 若无属性加成则留空
294
+ }
295
+ };
274
296
  const weaponConfig = {
275
297
  // 武器配置
276
298
  "高斯步枪": {
@@ -279,10 +301,12 @@ function apply(ctx, config) {
279
301
  damage: 10,
280
302
  description: "标准配置武器,中距离作战利器",
281
303
  price: 100,
304
+ redCrystalCost: 2,
282
305
  tagEffects: {
283
306
  "轻甲": 1.5
284
307
  // 对轻甲目标造成150%伤害
285
- }
308
+ },
309
+ effects: ""
286
310
  },
287
311
  "激光步枪": {
288
312
  id: 2,
@@ -290,11 +314,13 @@ function apply(ctx, config) {
290
314
  damage: 23,
291
315
  description: "先进激光武器,远距离精准打击",
292
316
  price: 300,
317
+ redCrystalCost: 5,
293
318
  tagEffects: {
294
319
  "重甲": 1.5,
295
320
  // 对重甲目标造成150%伤害
296
321
  "护盾": 0.5
297
- }
322
+ },
323
+ effects: ""
298
324
  },
299
325
  "焚烧枪": {
300
326
  id: 3,
@@ -302,11 +328,13 @@ function apply(ctx, config) {
302
328
  damage: 20,
303
329
  description: "基于热能的强大武器,烧烬一切",
304
330
  price: 450,
331
+ redCrystalCost: 5,
305
332
  tagEffects: {
306
333
  "惧热": 2,
307
334
  "生物": 1.5,
308
335
  "护盾": 0.5
309
- }
336
+ },
337
+ effects: ""
310
338
  },
311
339
  "碎骨步枪": {
312
340
  id: 4,
@@ -314,11 +342,13 @@ function apply(ctx, config) {
314
342
  damage: 28,
315
343
  description: "由激光步枪改良而来,高效的对重甲武器",
316
344
  price: 850,
345
+ redCrystalCost: 15,
317
346
  tagEffects: {
318
347
  "重甲": 2,
319
348
  "机械": 0.5,
320
349
  "护盾": 0.2
321
- }
350
+ },
351
+ effects: ""
322
352
  },
323
353
  "等离子切割机": {
324
354
  id: 5,
@@ -326,11 +356,13 @@ function apply(ctx, config) {
326
356
  damage: 12,
327
357
  description: "一种改造后的采矿切割机,有效对抗重甲目标",
328
358
  price: 150,
359
+ redCrystalCost: 2,
329
360
  tagEffects: {
330
361
  "重甲": 1.5,
331
362
  "建筑": 1.5,
332
363
  "机械": 1.2
333
- }
364
+ },
365
+ effects: ""
334
366
  },
335
367
  "突击霰弹枪": {
336
368
  id: 6,
@@ -338,10 +370,12 @@ function apply(ctx, config) {
338
370
  damage: 28,
339
371
  description: "近距离攻击武器,专为遭遇战设计使用",
340
372
  price: 325,
373
+ redCrystalCost: 5,
341
374
  tagEffects: {
342
375
  "轻甲": 1.5,
343
376
  "重甲": 0.8
344
- }
377
+ },
378
+ effects: ""
345
379
  },
346
380
  "侦查步枪": {
347
381
  id: 7,
@@ -349,11 +383,13 @@ function apply(ctx, config) {
349
383
  damage: 60,
350
384
  description: "用于隐秘射击的最佳武器,但是无法穿透护甲",
351
385
  price: 550,
386
+ redCrystalCost: 10,
352
387
  tagEffects: {
353
388
  "护盾": 0.5,
354
389
  "轻甲": 0.5,
355
390
  "重甲": 0.2
356
- }
391
+ },
392
+ effects: ""
357
393
  },
358
394
  "零度之下": {
359
395
  id: 8,
@@ -361,22 +397,27 @@ function apply(ctx, config) {
361
397
  damage: 30,
362
398
  description: "喷射稳定的液氮恒流,对长时间接触者造成致命的损伤",
363
399
  price: 775,
400
+ redCrystalCost: 10,
364
401
  tagEffects: {
365
402
  "惧寒": 2,
366
403
  "灵能": 1.5
367
- }
404
+ },
405
+ effects: ""
368
406
  },
369
407
  "弧焊枪": {
370
408
  id: 9,
371
409
  type: "能量武器",
372
- damage: 30,
410
+ damage: 25,
373
411
  description: "一种经过改造的电动工具,可对近距离的目标放出高压电",
374
412
  price: 750,
413
+ redCrystalCost: 10,
375
414
  tagEffects: {
376
415
  "建筑": 2,
377
416
  "机械": 1.5
378
- }
379
- }
417
+ },
418
+ effects: ""
419
+ },
420
+ ...SyndicatedItems
380
421
  };
381
422
  const modConfig = {
382
423
  "动能增幅": {
@@ -524,11 +565,11 @@ function apply(ctx, config) {
524
565
  },
525
566
  "岗哨机枪": {
526
567
  effect: 0,
527
- description: "自己的职责为“保护感染虫”,受到10次攻击后,为存活的机械感染虫和空间站感染虫回复10%的最大生命值(可重复触发)"
568
+ description: "自己的职责为“保护感染虫”,受到10次攻击后,为存活的机械感染虫和主宰回复10%的最大生命值(可重复触发)"
528
569
  },
529
570
  "结构装甲": {
530
571
  effect: 0,
531
- description: "拥有结构装甲,受到的伤害-20%;若伤害来源于能量武器,则受到的伤害-40%"
572
+ description: "拥有结构装甲,受到的伤害-20%;若伤害来源于热能武器,则受到的伤害-40%"
532
573
  }
533
574
  };
534
575
  const bossPool = [
@@ -657,7 +698,7 @@ function apply(ctx, config) {
657
698
  },
658
699
  {
659
700
  professionName: "武器中士",
660
- effect: "攻击伤害+10%",
701
+ effect: "攻击伤害+15%",
661
702
  requirements: "当期伤害榜造成300点伤害",
662
703
  Jobtransfer: true,
663
704
  costcoins: 2e3
@@ -708,8 +749,8 @@ function apply(ctx, config) {
708
749
  const syndicatePirateConfig = [
709
750
  {
710
751
  professionName: "能量武器专家",
711
- effect: "能量武器攻击伤害+15%",
712
- requirements: "拥有一把武器等级为6的能量武器",
752
+ effect: "能量武器攻击伤害+20%,解锁MK-4激光步枪(传奇)购买权限",
753
+ requirements: "拥有一把武器等级为3级以上的能量武器",
713
754
  Jobtransfer: true,
714
755
  costcoins: 0,
715
756
  costredcrystal: 20
@@ -749,7 +790,7 @@ function apply(ctx, config) {
749
790
  {
750
791
  professionName: "辛迪加财务经理",
751
792
  effect: "每日签到能额外获得红晶",
752
- requirements: "当月累计签到28天",
793
+ requirements: "当月累计签到21天",
753
794
  Jobtransfer: true,
754
795
  costcoins: 0,
755
796
  costredcrystal: 40
@@ -872,13 +913,13 @@ function apply(ctx, config) {
872
913
  multiplier = 1.05;
873
914
  message = "⚔️ 职业加成:警卫长(攻击伤害+5%)";
874
915
  } else if (career === "武器中士") {
875
- multiplier = 1.1;
876
- message = "⚔️ 职业加成:武器中士(攻击伤害+10%)";
916
+ multiplier = 1.15;
917
+ message = "⚔️ 职业加成:武器中士(攻击伤害+15%)";
877
918
  }
878
919
  if (faction === "辛迪加海盗" && career === "能量武器专家") {
879
- if (weaponType === "能量") {
880
- multiplier *= 1.15;
881
- message = "⚡ 职业加成:能量武器专家(能量武器伤害+15%)";
920
+ if (weaponType === "能量武器") {
921
+ multiplier *= 1.2;
922
+ message = "⚡ 职业加成:能量武器专家(能量武器伤害+20%)";
882
923
  } else {
883
924
  message = "⚠️ 能量武器专家:未装备能量武器,加成未生效";
884
925
  }
@@ -1118,10 +1159,10 @@ function apply(ctx, config) {
1118
1159
  __name(activateNextBossGroup, "activateNextBossGroup");
1119
1160
  ctx.setInterval(async () => {
1120
1161
  const totalBosses = await ctx.database.select("ggcevo_boss").execute((row) => import_koishi.$.count(row.name));
1121
- const [groupId] = config.groupId;
1162
+ const groupId = [...config.groupId];
1122
1163
  if (totalBosses === 0) {
1123
1164
  await activateNextBossGroup();
1124
- await ctx.broadcast([groupId], `🔄 咕咕PVE系统已初始化,首个主宰已登场!`);
1165
+ await ctx.broadcast(groupId, `🔄 咕咕PVE系统已初始化,首个主宰已登场!`);
1125
1166
  return;
1126
1167
  }
1127
1168
  const now = /* @__PURE__ */ new Date();
@@ -1135,8 +1176,8 @@ function apply(ctx, config) {
1135
1176
  groupId: group.groupId
1136
1177
  });
1137
1178
  await activateNextBossGroup(group.groupId);
1138
- const [groupId2] = config.groupId;
1139
- await ctx.broadcast([groupId2], `🔄 新的主宰已刷新,快去挑战吧!`);
1179
+ const groupId2 = [...config.groupId];
1180
+ await ctx.broadcast(groupId2, `🔄 新的主宰已刷新,快去挑战吧!`);
1140
1181
  }
1141
1182
  }, 60 * 1e3);
1142
1183
  const PassiveHandler = {
@@ -1383,9 +1424,9 @@ function apply(ctx, config) {
1383
1424
  }
1384
1425
  let reduction = 0.2;
1385
1426
  let msg = "常规减伤20%";
1386
- if (weaponData.type === "能量武器") {
1427
+ if (weaponData.type === "热能武器") {
1387
1428
  reduction = 0.4;
1388
- msg = "能量武器减伤40%";
1429
+ msg = "热能武器减伤40%";
1389
1430
  }
1390
1431
  const newDamage = Math.floor(initialDamage * (1 - reduction));
1391
1432
  return {
@@ -1687,11 +1728,11 @@ function apply(ctx, config) {
1687
1728
  case "能量武器专家":
1688
1729
  const weapons = await ctx2.database.get("ggcevo_equipment", {
1689
1730
  handle,
1690
- level: { $gte: 6 }
1731
+ level: { $gte: 3 }
1691
1732
  });
1692
1733
  const hasEnergyWeapon = weapons.some((weapon) => {
1693
1734
  const weaponConfigEntry = Object.values(weaponConfig).find((c) => c.id === weapon.weaponId);
1694
- return weaponConfigEntry?.type === "能量";
1735
+ return weaponConfigEntry?.type === "能量武器";
1695
1736
  });
1696
1737
  return {
1697
1738
  success: hasEnergyWeapon,
@@ -1709,14 +1750,36 @@ function apply(ctx, config) {
1709
1750
  };
1710
1751
  case "辛迪加财务经理":
1711
1752
  return {
1712
- success: signData?.monthlyDays >= 28,
1713
- message: `需要当月累计签到28天(当前${signData?.monthlyDays || 0}天)`
1753
+ success: signData?.monthlyDays >= 21,
1754
+ message: `需要当月累计签到21天(当前${signData?.monthlyDays || 0}天)`
1714
1755
  };
1715
1756
  default:
1716
1757
  return { success: false, message: "未知职业要求" };
1717
1758
  }
1718
1759
  }
1719
1760
  __name(checkTransferRequirements, "checkTransferRequirements");
1761
+ async function applyItemEffect(handle, itemId) {
1762
+ const itemConfig2 = Object.values(weaponConfig).find((v) => v.id === itemId);
1763
+ if (!itemConfig2) return "该物品未配置效果";
1764
+ if (itemId === 1e3) {
1765
+ const [SentryTower] = await ctx.database.get("ggcevo_boss", { name: "空间站哨枪塔", isActive: true });
1766
+ const [record] = await ctx.database.get("ggcevo_sign", { handle });
1767
+ await ctx.database.set(
1768
+ "ggcevo_boss",
1769
+ { name: "空间站哨枪塔" },
1770
+ {
1771
+ isActive: false,
1772
+ HP: 0
1773
+ }
1774
+ );
1775
+ await ctx.database.upsert("ggcevo_sign", [{
1776
+ handle,
1777
+ totalRewards: (record?.totalRewards || 0) + SentryTower.HP
1778
+ }], ["handle"]);
1779
+ return `您使用了E-2能量炸弹,直接摧毁了“空间站哨枪塔”,并且获得了${SentryTower.HP}金币。`;
1780
+ }
1781
+ }
1782
+ __name(applyItemEffect, "applyItemEffect");
1720
1783
  ctx.command("ggcevo/抽奖").action(async (argv) => {
1721
1784
  const session = argv.session;
1722
1785
  let winCount = 0;
@@ -2602,33 +2665,44 @@ ${itemDetails.join("\n")}`;
2602
2665
  if (!handle || !itemName || amount <= 0) {
2603
2666
  return "参数格式错误,正确格式:给予 用户句柄 物品名称 数量";
2604
2667
  }
2668
+ const parsedAmount = Math.floor(amount);
2605
2669
  if (itemName === "金币") {
2606
2670
  const [signData] = await ctx.database.get("ggcevo_sign", { handle });
2671
+ const newTotal = (signData?.totalRewards || 0) + parsedAmount;
2607
2672
  await ctx.database.upsert("ggcevo_sign", [{
2608
2673
  handle,
2609
- totalRewards: (signData?.totalRewards || 0) + Math.floor(amount),
2674
+ totalRewards: newTotal,
2610
2675
  lastSign: signData?.lastSign || /* @__PURE__ */ new Date(0),
2611
- // 保持原有最后签到时间
2612
2676
  monthlyDays: signData?.monthlyDays || 0
2613
- // 保持月签到天数
2614
2677
  }]);
2615
- return `成功为 ${handle} 添加 ${amount} 金币!当前金币总数:${(signData?.totalRewards || 0) + amount}`;
2616
- }
2617
- const validItems = Object.keys(initDefaultItems);
2618
- if (!validItems.includes(itemName)) {
2619
- return `无效物品名称,可用物品:${validItems.join("、")}`;
2678
+ return `成功为 ${handle} 添加 ${parsedAmount} 金币!当前总数:${newTotal}`;
2679
+ } else if (itemName === "红晶") {
2680
+ const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
2681
+ const currentRed = careerData?.redcrystal || 0;
2682
+ const newRed = currentRed + parsedAmount;
2683
+ await ctx.database.upsert("ggcevo_careers", [{
2684
+ handle,
2685
+ redcrystal: newRed,
2686
+ group: careerData?.group || "",
2687
+ career: careerData?.career || "",
2688
+ date: careerData?.date || /* @__PURE__ */ new Date()
2689
+ }]);
2690
+ return `成功为 ${handle} 添加 ${parsedAmount} 红晶!当前总数:${newRed}`;
2691
+ } else {
2692
+ const validItems = Object.keys(initDefaultItems);
2693
+ if (!validItems.includes(itemName)) {
2694
+ return `无效物品名称,可用物品:${validItems.join("、")}`;
2695
+ }
2696
+ const itemId = initDefaultItems[itemName].id;
2697
+ const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId });
2698
+ const newQuantity = (backpack?.quantity || 0) + parsedAmount;
2699
+ await ctx.database.upsert("ggcevo_backpack", [{
2700
+ handle,
2701
+ itemId,
2702
+ quantity: newQuantity
2703
+ }], ["handle", "itemId"]);
2704
+ return `成功为 ${handle} 添加 ${parsedAmount} 个${itemName}!当前总数:${newQuantity}`;
2620
2705
  }
2621
- const itemId = initDefaultItems[itemName].id;
2622
- const [backpack] = await ctx.database.get("ggcevo_backpack", {
2623
- handle,
2624
- itemId
2625
- });
2626
- await ctx.database.upsert("ggcevo_backpack", [{
2627
- handle,
2628
- itemId,
2629
- quantity: (backpack?.quantity || 0) + Math.floor(amount)
2630
- }], ["handle", "itemId"]);
2631
- return `成功为 ${handle} 添加 ${amount} 个${itemName}!当前总数:${(backpack?.quantity || 0) + amount}`;
2632
2706
  } catch (err) {
2633
2707
  console.error("[给予命令错误]", err);
2634
2708
  return "操作失败:" + (err instanceof Error ? err.message : "数据库异常");
@@ -2992,7 +3066,6 @@ ${achievementList.join("\n")}`;
2992
3066
  "📅 签到记录:",
2993
3067
  `最后签到:${chinaTime}`,
2994
3068
  `本月累计:${sign.monthlyDays} 天`,
2995
- `拥有金币:${sign.totalRewards} 枚`,
2996
3069
  "──────────────"
2997
3070
  );
2998
3071
  }
@@ -3092,8 +3165,8 @@ ${achievementList.join("\n")}`;
3092
3165
  `玩家数: ${lobby.slotsHumansTaken}/${lobby.slotsHumansTotal}`,
3093
3166
  `🏆 安全玩家:${atElements || "无"}`
3094
3167
  ].join("\n");
3095
- const [groupId] = config.groupId;
3096
- await ctx.broadcast([groupId], message);
3168
+ const groupId = [...config.groupId];
3169
+ await ctx.broadcast(groupId, message);
3097
3170
  processedLobbies.add(lobby.id);
3098
3171
  }
3099
3172
  }
@@ -3368,7 +3441,7 @@ ${achievementList.join("\n")}`;
3368
3441
  })}`;
3369
3442
  });
3370
3443
  ctx.command("ggcevo/武器库 [type]").usage("输入“武器库”查看类型,或“武器库 类型”查看详细武器信息").action(async (_, type) => {
3371
- const typeStats = Object.values(weaponConfig).reduce((stats, weapon) => {
3444
+ const typeStats = Object.values(weaponConfig).filter((weapon) => weapon.price !== 0).reduce((stats, weapon) => {
3372
3445
  stats[weapon.type] = (stats[weapon.type] || 0) + 1;
3373
3446
  return stats;
3374
3447
  }, {});
@@ -3377,16 +3450,16 @@ ${achievementList.join("\n")}`;
3377
3450
  "🏪 咕咕武器库分类 🏪",
3378
3451
  '使用 "武器库 类型名称" 查看详细列表',
3379
3452
  "====================",
3380
- ...Object.entries(typeStats).map(([typeName, count]) => `▸ ${typeName} (${count}种)`)
3453
+ ...Object.entries(typeStats).map(([typeName, count]) => `▸ ${typeName} (${count}种)`),
3454
+ "===================="
3381
3455
  ].join("\n");
3382
3456
  }
3383
3457
  const validTypes = Object.keys(typeStats);
3384
- const normalizedType = validTypes.find((t) => t === type);
3385
- if (!normalizedType) {
3458
+ if (!validTypes.includes(type)) {
3386
3459
  return `无效武器类型,可用类型:
3387
3460
  ${validTypes.join("、")}`;
3388
3461
  }
3389
- const items = Object.entries(weaponConfig).filter(([_2, config2]) => config2.type === normalizedType).map(([name2, config2]) => {
3462
+ const items = Object.entries(weaponConfig).filter(([_2, config2]) => config2.type === type && config2.price !== 0).map(([name2, config2]) => {
3390
3463
  const tagEffectsDesc = config2.tagEffects ? Object.entries(config2.tagEffects).map(([tag, multiplier]) => `▸ 对${tag}目标造成${(multiplier * 100).toFixed(0)}%伤害`).join("\n") : "▸ 无特殊加成效果";
3391
3464
  return [
3392
3465
  `【${name2}】`,
@@ -3399,10 +3472,11 @@ ${validTypes.join("、")}`;
3399
3472
  ].join("\n");
3400
3473
  });
3401
3474
  return [
3402
- `🏪 咕咕武器库 - ${normalizedType} 🏪`,
3475
+ `🏪 咕咕武器库 - ${type} 🏪`,
3403
3476
  "使用“购买武器 武器名称”命令进行购买",
3404
3477
  "====================",
3405
- ...items
3478
+ ...items,
3479
+ items.length === 0 ? "⚠️ 该分类下暂无可用武器" : ""
3406
3480
  ].join("\n\n");
3407
3481
  });
3408
3482
  ctx.command("ggcevo/购买武器 <weapon>").action(async ({ session }, weapon) => {
@@ -3473,7 +3547,7 @@ ${validTypes.join("、")}`;
3473
3547
  }
3474
3548
  if (equippedCount === 0) {
3475
3549
  message += `
3476
- 已自动为您装备当前武器!`;
3550
+ 已自动为您装备当前武器!`;
3477
3551
  }
3478
3552
  return message + "\n输入“武器仓库”查看你拥有的武器。";
3479
3553
  });
@@ -3881,8 +3955,8 @@ ${validTypes.join("、")}`;
3881
3955
  await session.send(resultMessage);
3882
3956
  if (broadcastMessage) {
3883
3957
  const finalBroadcast = Array.isArray(broadcastMessage) ? broadcastMessage.join("\n") : broadcastMessage;
3884
- const [groupId] = config2.groupId;
3885
- await ctx.broadcast([groupId], finalBroadcast);
3958
+ const groupId = [...config2.groupId];
3959
+ await ctx.broadcast(groupId, finalBroadcast);
3886
3960
  }
3887
3961
  });
3888
3962
  ctx.command("ggcevo/伤害榜 [page]", "查看当前主宰伤害排名").usage("输入 伤害榜 [页码] 查看对应页的排行榜,每页10条").action(async (_, page) => {
@@ -4023,8 +4097,8 @@ ${validTypes.join("、")}`;
4023
4097
  case "酥手空空":
4024
4098
  newGold = Math.max(0, newGold - 50);
4025
4099
  const kfcMsg = '🍗【疯狂星期四警报】有人抽中了"酥手空空"!钱包空空如也,现在急需好心人V他50金币!慈悲为怀的指挥官,速带黄金救场,解救同袍于水火!🆘';
4026
- const [groupId] = config.groupId;
4027
- await ctx.broadcast([groupId], kfcMsg);
4100
+ const groupId = [...config.groupId];
4101
+ await ctx.broadcast(groupId, kfcMsg);
4028
4102
  break;
4029
4103
  case "夜市赠礼":
4030
4104
  const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 1 });
@@ -4062,6 +4136,10 @@ ${validTypes.join("、")}`;
4062
4136
  if (!profile) return "您暂未绑定句柄。";
4063
4137
  const { regionId, realmId, profileId } = profile;
4064
4138
  const handle = `${regionId}-S2-${realmId}-${profileId}`;
4139
+ const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
4140
+ if (existingEntries.length > 0) {
4141
+ return `❌ 拒绝访问,您已被列入黑名单。`;
4142
+ }
4065
4143
  await session.send(`请输入你要使用多少张兑换券来兑换金币?(请在30秒内回复数字,回复“0”为取消兑换)
4066
4144
  注意:1张兑换券=2000金币`);
4067
4145
  const exchangeInput = await session.prompt(3e4);
@@ -4097,6 +4175,10 @@ ${validTypes.join("、")}`;
4097
4175
  if (!profile) return "您暂未绑定句柄。";
4098
4176
  const { regionId, realmId, profileId } = profile;
4099
4177
  const handle = `${regionId}-S2-${realmId}-${profileId}`;
4178
+ const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
4179
+ if (existingEntries.length > 0) {
4180
+ return `❌ 拒绝访问,您已被列入黑名单。`;
4181
+ }
4100
4182
  const validFactions = ["人类联盟", "辛迪加海盗"];
4101
4183
  if (!faction) return `请输入“加入 阵营名称”加入对应阵营
4102
4184
  有效阵营:${validFactions.join(" / ")}`;
@@ -4161,6 +4243,10 @@ ${validTypes.join("、")}`;
4161
4243
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
4162
4244
  if (!profile) return "您暂未绑定句柄。";
4163
4245
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
4246
+ const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
4247
+ if (existingEntries.length > 0) {
4248
+ return `❌ 拒绝访问,您已被列入黑名单。`;
4249
+ }
4164
4250
  const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
4165
4251
  if (!careerData) return "请先加入阵营后使用转职功能。";
4166
4252
  let config2, factionTips;
@@ -4273,6 +4359,202 @@ ${validTypes.join("、")}`;
4273
4359
  return "获取职业信息失败,请稍后重试";
4274
4360
  }
4275
4361
  });
4362
+ ctx.command("ggcevo/黑市 [type]", "辛迪加海盗专属黑市").usage("输入“黑市”查看类型,或“黑市 类型”查看详细").action(async ({ session }, type) => {
4363
+ const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
4364
+ if (!profile) return "⚠️ 需要先绑定游戏句柄";
4365
+ const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
4366
+ const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
4367
+ if (!careerData || careerData.group !== "辛迪加海盗") {
4368
+ return "🚫 该功能需要【辛迪加海盗】阵营权限";
4369
+ }
4370
+ const typeStats = Object.values(weaponConfig).reduce((stats, weapon) => {
4371
+ stats[weapon.type] = (stats[weapon.type] || 0) + 1;
4372
+ return stats;
4373
+ }, {});
4374
+ if (!type) {
4375
+ return [
4376
+ "🏴☠️ 辛迪加黑市 🏴☠️",
4377
+ '使用 "黑市 类型名称" 查看详细信息',
4378
+ "====================",
4379
+ ...Object.entries(typeStats).map(([typeName, count]) => `▸ ${typeName} (${count}种)`),
4380
+ "===================="
4381
+ ].join("\n");
4382
+ }
4383
+ const normalizedType = Object.keys(typeStats).find((t) => t === type);
4384
+ if (!normalizedType) return `无效类型,可用:${Object.keys(typeStats).join("、")}`;
4385
+ const items = Object.entries(weaponConfig).filter(([_, config2]) => config2.type === normalizedType).map(([name2, config2]) => {
4386
+ const infoBlocks = [
4387
+ `【${name2}】`,
4388
+ `类型:${config2.type}`,
4389
+ // 选择性显示伤害值
4390
+ ...config2.damage !== 0 ? [`基础伤害:${config2.damage}`] : [],
4391
+ `订购价:${config2.redCrystalCost}红晶`
4392
+ ];
4393
+ if (Object.keys(config2.tagEffects).length > 0) {
4394
+ const tagEffectsDesc = Object.entries(config2.tagEffects).map(([tag, mul]) => `▸ 对${tag}目标造成${(mul * 100).toFixed(0)}%伤害`).join("\n");
4395
+ infoBlocks.push("特性:", tagEffectsDesc);
4396
+ }
4397
+ if (config2.effects && config2.effects.trim()) {
4398
+ infoBlocks.push(`效果:${config2.effects}`);
4399
+ }
4400
+ infoBlocks.push(
4401
+ config2.description,
4402
+ "──────────────"
4403
+ );
4404
+ return infoBlocks.join("\n");
4405
+ });
4406
+ return [
4407
+ `🏴☠️ 辛迪加黑市 - ${normalizedType} 🏴☠️`,
4408
+ "使用“订购 名称”进行购买(仅消耗红晶)",
4409
+ "====================",
4410
+ ...items
4411
+ ].join("\n\n");
4412
+ });
4413
+ ctx.command("ggcevo/订购 <item>").action(async ({ session }, item) => {
4414
+ const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
4415
+ if (!profile) return "⚠️ 需要先绑定游戏句柄";
4416
+ const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
4417
+ const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
4418
+ if (existingEntries.length > 0) {
4419
+ return "❌ 拒绝访问,您已被列入黑名单";
4420
+ }
4421
+ const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
4422
+ if (!careerData || careerData.group !== "辛迪加海盗") {
4423
+ return "🚫 需要辛迪加海盗阵营权限";
4424
+ }
4425
+ if (!item) return "请输入要订购的物品名称";
4426
+ const config2 = weaponConfig[item];
4427
+ if (!config2?.redCrystalCost) return "❌ 无效物品名称或该物品不可订购";
4428
+ const weaponTypes = ["能量武器", "实弹武器", "热能武器"];
4429
+ const isWeapon = weaponTypes.includes(config2.type);
4430
+ if (isWeapon) {
4431
+ const existing = await ctx.database.get("ggcevo_equipment", {
4432
+ handle,
4433
+ weaponId: config2.id
4434
+ });
4435
+ if (existing.length) return "⚠️ 该武器已在仓库中";
4436
+ }
4437
+ const requiredRed = config2.redCrystalCost;
4438
+ if ((careerData.redcrystal || 0) < requiredRed) {
4439
+ return `❌ 红晶不足!需要:${requiredRed} 当前:${careerData.redcrystal}`;
4440
+ }
4441
+ await ctx.database.withTransaction(async () => {
4442
+ await ctx.database.set("ggcevo_careers", { handle }, {
4443
+ redcrystal: careerData.redcrystal - requiredRed
4444
+ });
4445
+ if (isWeapon) {
4446
+ await ctx.database.upsert("ggcevo_equipment", [{
4447
+ handle,
4448
+ weaponId: config2.id,
4449
+ level: 0,
4450
+ modificationSlots: 1,
4451
+ equipped: false
4452
+ }], ["handle", "weaponId"]);
4453
+ const equippedCount = await ctx.database.select("ggcevo_equipment").where({ handle, equipped: true }).execute((row) => import_koishi.$.count(row.weaponId));
4454
+ if (equippedCount === 0) {
4455
+ await ctx.database.set(
4456
+ "ggcevo_equipment",
4457
+ { handle, weaponId: config2.id },
4458
+ { equipped: true }
4459
+ );
4460
+ }
4461
+ } else {
4462
+ const existingItems = await ctx.database.get("ggcevo_warehouse", {
4463
+ handle,
4464
+ itemId: config2.id
4465
+ });
4466
+ await ctx.database.upsert("ggcevo_warehouse", [{
4467
+ handle,
4468
+ itemId: config2.id,
4469
+ quantity: (existingItems[0]?.quantity || 0) + 1
4470
+ }], ["handle", "itemId"]);
4471
+ }
4472
+ });
4473
+ if (isWeapon) {
4474
+ const equippedCount = await ctx.database.select("ggcevo_equipment").where({ handle, equipped: true }).execute((row) => import_koishi.$.count(row.weaponId));
4475
+ let message = `✅ 成功订购【${item}】!消耗 ${requiredRed}红晶`;
4476
+ if (equippedCount === 0) {
4477
+ message += "\n已自动装备该武器!";
4478
+ }
4479
+ return message + '\n输入"武器仓库"查看已有装备';
4480
+ } else {
4481
+ const [warehouseData] = await ctx.database.get("ggcevo_warehouse", {
4482
+ handle,
4483
+ itemId: config2.id
4484
+ });
4485
+ return `✅ 成功订购【${item}】x1!消耗 ${requiredRed}红晶
4486
+ 当前库存:${warehouseData.quantity}件
4487
+ 输入"仓库"查看所有物品`;
4488
+ }
4489
+ });
4490
+ ctx.command("ggcevo/仓库").action(async (argv) => {
4491
+ const session = argv.session;
4492
+ const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
4493
+ if (!profile) return "您暂未绑定句柄。";
4494
+ const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
4495
+ const [items, signData, careerData] = await Promise.all([
4496
+ ctx.database.get("ggcevo_warehouse", { handle }),
4497
+ ctx.database.get("ggcevo_sign", { handle }),
4498
+ ctx.database.get("ggcevo_careers", { handle })
4499
+ ]);
4500
+ const totalRewards = signData[0]?.totalRewards || 0;
4501
+ const redcrystal = careerData[0]?.redcrystal || 0;
4502
+ const message = [`【${handle}的仓库】`];
4503
+ message.push(`💰 金币:${totalRewards}`);
4504
+ if (redcrystal > 0) message.push(`🔴 红晶:${redcrystal}`);
4505
+ const validItems = items.filter((item) => item.quantity > 0);
4506
+ if (!validItems.length) {
4507
+ message.push("你的仓库空空如也。");
4508
+ } else {
4509
+ message.push(
4510
+ validItems.map((warehouseItem) => {
4511
+ const entry = Object.entries(weaponConfig).find(
4512
+ ([, item]) => item.id === warehouseItem.itemId
4513
+ );
4514
+ if (!entry) return `未知物品 x ${warehouseItem.quantity}:数据异常,请联系管理员`;
4515
+ const [itemName, itemData] = entry;
4516
+ let info = `${itemName} x ${warehouseItem.quantity} | 类型:${itemData.type || "未分类"}`;
4517
+ if (itemData.effects?.trim()) info += `
4518
+ 功能:${itemData.effects}`;
4519
+ return info;
4520
+ }).join("\n\n")
4521
+ );
4522
+ }
4523
+ return message.join("\n");
4524
+ });
4525
+ ctx.command("ggcevo/使用 [itemName]").action(async (argv, itemName) => {
4526
+ const session = argv.session;
4527
+ const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
4528
+ if (!profile) return "您暂未绑定句柄。";
4529
+ const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
4530
+ try {
4531
+ const items = await ctx.database.get("ggcevo_warehouse", { handle });
4532
+ const targetItem = items.find((warehouseItem) => {
4533
+ const entry = Object.entries(weaponConfig).find(
4534
+ ([, config2]) => config2.id === warehouseItem.itemId
4535
+ );
4536
+ if (!entry) return false;
4537
+ const [itemKey] = entry;
4538
+ return itemKey.toLowerCase() === itemName?.toLowerCase();
4539
+ });
4540
+ if (!targetItem) return `仓库中不存在 ${itemName} 或物品名称错误`;
4541
+ if (targetItem.quantity < 1) return `${itemName} 数量不足`;
4542
+ if (targetItem.itemId === 1e3) {
4543
+ const [SentryTower] = await ctx.database.get("ggcevo_boss", { name: "空间站哨枪塔", isActive: true });
4544
+ if (!SentryTower) return "当前没有“空间站哨枪塔”,无法使用E-2能量炸弹。";
4545
+ }
4546
+ await ctx.database.set("ggcevo_warehouse", { handle, itemId: targetItem.itemId }, {
4547
+ quantity: Math.max(targetItem.quantity - 1, 0)
4548
+ });
4549
+ const effectResult = await applyItemEffect(handle, targetItem.itemId);
4550
+ return `使用成功!消耗 ${itemName} ×1
4551
+ 剩余数量:${targetItem.quantity - 1}
4552
+ ${effectResult}`;
4553
+ } catch (error) {
4554
+ ctx.logger("GGCEVO").error(error);
4555
+ return "物品使用失败,请稍后重试";
4556
+ }
4557
+ });
4276
4558
  }
4277
4559
  __name(apply, "apply");
4278
4560
  function simpleDraw() {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-ggcevo-game",
3
3
  "description": "《星际争霸2》咕咕虫-evolved地图的专属游戏助手插件,集成天梯排行、抽奖系统、签到福利、兑换商城等丰富功能。",
4
- "version": "1.2.64",
4
+ "version": "1.2.66",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [