koishi-plugin-ggcevo-game 1.6.31 → 1.6.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/database.d.ts +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +232 -240
- package/lib/weapons.d.ts +16 -0
- package/package.json +1 -1
package/lib/database.d.ts
CHANGED
package/lib/index.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export interface Config {
|
|
|
16
16
|
maxDailyBeChallenged: number;
|
|
17
17
|
unlimitedBossAttack: boolean;
|
|
18
18
|
pointBonusEnabled: boolean;
|
|
19
|
+
enableViolationAlert: boolean;
|
|
19
20
|
}
|
|
20
21
|
export declare const Config: Schema<Config>;
|
|
21
22
|
export declare function apply(ctx: Context, config: Config): void;
|
package/lib/index.js
CHANGED
|
@@ -485,100 +485,116 @@ var modConfig = {
|
|
|
485
485
|
effect: "伤害提高15%",
|
|
486
486
|
// 规范术语
|
|
487
487
|
exclusiveTo: "",
|
|
488
|
-
isExclusive: false
|
|
488
|
+
isExclusive: false,
|
|
489
|
+
recyclable: false
|
|
489
490
|
},
|
|
490
491
|
"棱镜水晶": {
|
|
491
492
|
cost: 2050,
|
|
492
493
|
effect: "暴击率提升10%",
|
|
493
494
|
// 保持原描述
|
|
494
495
|
exclusiveTo: "",
|
|
495
|
-
isExclusive: false
|
|
496
|
+
isExclusive: false,
|
|
497
|
+
recyclable: true
|
|
496
498
|
},
|
|
497
499
|
"破甲模块": {
|
|
498
500
|
cost: 1250,
|
|
499
501
|
effect: "无视目标10%伤害减免",
|
|
500
502
|
// 术语统一
|
|
501
503
|
exclusiveTo: "",
|
|
502
|
-
isExclusive: false
|
|
504
|
+
isExclusive: false,
|
|
505
|
+
recyclable: false
|
|
503
506
|
},
|
|
504
507
|
// 专属模组修改
|
|
505
508
|
"裂甲核心": {
|
|
506
509
|
cost: 750,
|
|
507
510
|
effect: "伤害提高40%,无视目标40%伤害减免",
|
|
508
511
|
exclusiveTo: "高斯步枪",
|
|
509
|
-
isExclusive: true
|
|
512
|
+
isExclusive: true,
|
|
513
|
+
recyclable: false
|
|
510
514
|
},
|
|
511
515
|
"棱镜超载核心": {
|
|
512
516
|
cost: 2250,
|
|
513
517
|
effect: "暴击率提升20%;连续3次未暴击时,下次攻击必定暴击",
|
|
514
518
|
exclusiveTo: "激光步枪",
|
|
515
|
-
isExclusive: true
|
|
519
|
+
isExclusive: true,
|
|
520
|
+
recyclable: false
|
|
516
521
|
},
|
|
517
522
|
"助燃核心": {
|
|
518
523
|
cost: 2550,
|
|
519
524
|
effect: "对[惧热]目标改为造成300%伤害,对[生物]目标改为造成200%伤害;攻击时每1点护甲改为增加0.5点伤害;双倍叠加[燃烧]层数",
|
|
520
525
|
exclusiveTo: "焚烧枪",
|
|
521
|
-
isExclusive: true
|
|
526
|
+
isExclusive: true,
|
|
527
|
+
recyclable: false
|
|
522
528
|
},
|
|
523
529
|
"光束曲射晶片": {
|
|
524
530
|
cost: 2750,
|
|
525
531
|
effect: "攻击触发散射,对次要目标造成100%基础伤害",
|
|
526
532
|
exclusiveTo: "碎骨步枪",
|
|
527
|
-
isExclusive: true
|
|
533
|
+
isExclusive: true,
|
|
534
|
+
recyclable: false
|
|
528
535
|
},
|
|
529
536
|
"金刚石瞄准镜": {
|
|
530
537
|
cost: 2250,
|
|
531
538
|
effect: "无视目标20%伤害减免",
|
|
532
539
|
exclusiveTo: "侦察步枪",
|
|
533
|
-
isExclusive: true
|
|
540
|
+
isExclusive: true,
|
|
541
|
+
recyclable: false
|
|
534
542
|
},
|
|
535
543
|
"微型聚变核心": {
|
|
536
544
|
cost: 2750,
|
|
537
545
|
effect: "连续攻击叠加[聚变]效果,每层提高10%伤害(最多6层)",
|
|
538
546
|
exclusiveTo: "聚变磁轨枪",
|
|
539
|
-
isExclusive: true
|
|
547
|
+
isExclusive: true,
|
|
548
|
+
recyclable: false
|
|
540
549
|
},
|
|
541
550
|
"辐射充能核心": {
|
|
542
551
|
cost: 1750,
|
|
543
552
|
effect: "双倍叠加[辐射]层数,对[生物]目标改为造成150%伤害",
|
|
544
553
|
exclusiveTo: "伽马枪",
|
|
545
|
-
isExclusive: true
|
|
554
|
+
isExclusive: true,
|
|
555
|
+
recyclable: false
|
|
546
556
|
},
|
|
547
557
|
"等离子轴承": {
|
|
548
558
|
cost: 3e3,
|
|
549
559
|
effect: "每层[横冲直撞]提供双倍伤害",
|
|
550
560
|
exclusiveTo: "M134轮转机枪",
|
|
551
|
-
isExclusive: true
|
|
561
|
+
isExclusive: true,
|
|
562
|
+
recyclable: false
|
|
552
563
|
},
|
|
553
564
|
"脉冲稳定核心": {
|
|
554
565
|
cost: 2500,
|
|
555
566
|
effect: "攻击减少目标双倍技能层数",
|
|
556
567
|
exclusiveTo: "脉冲扰乱枪",
|
|
557
|
-
isExclusive: true
|
|
568
|
+
isExclusive: true,
|
|
569
|
+
recyclable: false
|
|
558
570
|
},
|
|
559
571
|
"高压电池": {
|
|
560
572
|
cost: 2250,
|
|
561
573
|
effect: "攻击消耗目标双倍能量值",
|
|
562
574
|
exclusiveTo: "弧焊枪",
|
|
563
|
-
isExclusive: true
|
|
575
|
+
isExclusive: true,
|
|
576
|
+
recyclable: false
|
|
564
577
|
},
|
|
565
578
|
"氮气压缩核心": {
|
|
566
579
|
cost: 2e3,
|
|
567
580
|
effect: "双倍叠加[寒冷]层数;攻击时每1点护甲改为减少0点伤害",
|
|
568
581
|
exclusiveTo: "零度之下",
|
|
569
|
-
isExclusive: true
|
|
582
|
+
isExclusive: true,
|
|
583
|
+
recyclable: false
|
|
570
584
|
},
|
|
571
585
|
"轻型电源节点": {
|
|
572
586
|
cost: 1250,
|
|
573
587
|
effect: "伤害提高40%;攻击时每1点护甲改为减少0点伤害",
|
|
574
588
|
exclusiveTo: "等离子切割机",
|
|
575
|
-
isExclusive: true
|
|
589
|
+
isExclusive: true,
|
|
590
|
+
recyclable: false
|
|
576
591
|
},
|
|
577
592
|
"强力钻刺核心": {
|
|
578
593
|
cost: 1750,
|
|
579
594
|
effect: "攻击时每1点护甲改为减少0.2点伤害;每次攻击削减目标0.1护甲值",
|
|
580
595
|
exclusiveTo: "动力钻头",
|
|
581
|
-
isExclusive: true
|
|
596
|
+
isExclusive: true,
|
|
597
|
+
recyclable: false
|
|
582
598
|
}
|
|
583
599
|
};
|
|
584
600
|
|
|
@@ -800,7 +816,7 @@ var spaceStationCrewConfig = [
|
|
|
800
816
|
var syndicatePirateConfig = [
|
|
801
817
|
{
|
|
802
818
|
professionName: "能量武器专家",
|
|
803
|
-
effect: "能量武器攻击伤害+20%;
|
|
819
|
+
effect: "能量武器攻击伤害+20%; 购买MK-4激光步枪(传奇)享有50%的折扣",
|
|
804
820
|
requirements: "至少拥有一把3级及以上等级的能量武器",
|
|
805
821
|
Jobtransfer: true,
|
|
806
822
|
costredcrystal: 30
|
|
@@ -5433,6 +5449,16 @@ var ggcevoUpdates = [
|
|
|
5433
5449
|
- 重制了赛季奖励
|
|
5434
5450
|
- 修改了竞猜项目ID为1的竞猜赔率,并设置了最低投注
|
|
5435
5451
|
`.trim()
|
|
5452
|
+
},
|
|
5453
|
+
{
|
|
5454
|
+
version: "1.6.33",
|
|
5455
|
+
time: "2025-07-16",
|
|
5456
|
+
content: `
|
|
5457
|
+
- 回调了能量武器专家的职业效果
|
|
5458
|
+
- 禁用了棱镜水晶,使用拆卸可返还100%金币
|
|
5459
|
+
- 新增资源商店,输入“兑换资源”查看
|
|
5460
|
+
- 修改“兑换”指令,更改为“兑换赞助物品”
|
|
5461
|
+
`.trim()
|
|
5436
5462
|
}
|
|
5437
5463
|
];
|
|
5438
5464
|
function compareVersions(a, b) {
|
|
@@ -5466,38 +5492,6 @@ async function gachaWithPity(ctx, handle) {
|
|
|
5466
5492
|
return isWin;
|
|
5467
5493
|
}
|
|
5468
5494
|
__name(gachaWithPity, "gachaWithPity");
|
|
5469
|
-
async function gachaWithHiddenAward(ctx, handle) {
|
|
5470
|
-
const backpackItems = await ctx.database.get("ggcevo_backpack", {
|
|
5471
|
-
handle,
|
|
5472
|
-
itemId: { $in: [2, 3] }
|
|
5473
|
-
});
|
|
5474
|
-
const itemMap = new Map(backpackItems.map((item) => [item.itemId, item]));
|
|
5475
|
-
const isWin = HiddenAward();
|
|
5476
|
-
if (isWin) {
|
|
5477
|
-
const updates = [
|
|
5478
|
-
{
|
|
5479
|
-
itemId: 2,
|
|
5480
|
-
addAmount: 1
|
|
5481
|
-
},
|
|
5482
|
-
{
|
|
5483
|
-
itemId: 3,
|
|
5484
|
-
addAmount: 1
|
|
5485
|
-
}
|
|
5486
|
-
].map(({ itemId, addAmount }) => ({
|
|
5487
|
-
handle,
|
|
5488
|
-
itemId,
|
|
5489
|
-
quantity: (itemMap.get(itemId)?.quantity || 0) + addAmount
|
|
5490
|
-
}));
|
|
5491
|
-
await ctx.database.upsert("ggcevo_backpack", updates, ["handle", "itemId"]);
|
|
5492
|
-
const [record] = await ctx.database.get("ggcevo_records", { handle });
|
|
5493
|
-
await ctx.database.upsert("ggcevo_records", [{
|
|
5494
|
-
handle,
|
|
5495
|
-
hiddenawards: (record?.hiddenawards || 0) + 1
|
|
5496
|
-
}], ["handle"]);
|
|
5497
|
-
}
|
|
5498
|
-
return isWin;
|
|
5499
|
-
}
|
|
5500
|
-
__name(gachaWithHiddenAward, "gachaWithHiddenAward");
|
|
5501
5495
|
async function updatePityCounter(ctx, handle, isWin) {
|
|
5502
5496
|
const [record] = await ctx.database.get("ggcevo_records", { handle });
|
|
5503
5497
|
const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 2 });
|
|
@@ -5529,10 +5523,6 @@ function simpleDraw() {
|
|
|
5529
5523
|
return Math.floor(Math.random() * 1e4) < 50;
|
|
5530
5524
|
}
|
|
5531
5525
|
__name(simpleDraw, "simpleDraw");
|
|
5532
|
-
function HiddenAward() {
|
|
5533
|
-
return Math.floor(Math.random() * 1e4) < 1;
|
|
5534
|
-
}
|
|
5535
|
-
__name(HiddenAward, "HiddenAward");
|
|
5536
5526
|
function getRandomInt(min, max) {
|
|
5537
5527
|
const actualMin = Math.min(min, max);
|
|
5538
5528
|
const actualMax = Math.max(min, max);
|
|
@@ -6367,12 +6357,8 @@ async function calculateCrit(ctx, handle, equippedWeapon, weaponName, careerData
|
|
|
6367
6357
|
};
|
|
6368
6358
|
}
|
|
6369
6359
|
if (careerData?.career === "能量武器专家" && weaponType === "能量武器") {
|
|
6370
|
-
critRate += 10;
|
|
6371
|
-
critSources.push("⚔️ 能量武器专家职业:暴击率+10%");
|
|
6372
6360
|
}
|
|
6373
6361
|
if (equippedWeapon.installedMods?.includes("棱镜水晶")) {
|
|
6374
|
-
critRate += 10;
|
|
6375
|
-
critSources.push("⚙️ 【棱镜水晶】:暴击率+10%");
|
|
6376
6362
|
}
|
|
6377
6363
|
if (equippedWeapon.installedMods?.includes("棱镜超载核心") && modConfig["棱镜超载核心"]?.exclusiveTo === weaponName) {
|
|
6378
6364
|
critRate += 20;
|
|
@@ -7324,10 +7310,12 @@ var Config = import_koishi.Schema.intersect([
|
|
|
7324
7310
|
maxDailyBeChallenged: import_koishi.Schema.number().description("最大被挑战次数(0=无限制)").default(5),
|
|
7325
7311
|
unlimitedBossAttack: import_koishi.Schema.boolean().description("开启无限制PVE攻击").default(false)
|
|
7326
7312
|
}).description("对战限制"),
|
|
7327
|
-
// 通知系统配置组
|
|
7313
|
+
// 通知系统配置组 - 新增违规提醒开关
|
|
7328
7314
|
import_koishi.Schema.object({
|
|
7329
7315
|
groupId: import_koishi.Schema.array(import_koishi.Schema.string()).description("广播通知群组").default([]),
|
|
7330
|
-
checkInterval: import_koishi.Schema.number().description("大厅监控检查间隔(秒)").default(60)
|
|
7316
|
+
checkInterval: import_koishi.Schema.number().description("大厅监控检查间隔(秒)").default(60),
|
|
7317
|
+
enableViolationAlert: import_koishi.Schema.boolean().description("启用违规玩家房间提醒").default(false)
|
|
7318
|
+
// 新增配置项
|
|
7331
7319
|
}).description("通知设置").collapse()
|
|
7332
7320
|
]);
|
|
7333
7321
|
function apply(ctx, config) {
|
|
@@ -7446,6 +7434,7 @@ function apply(ctx, config) {
|
|
|
7446
7434
|
});
|
|
7447
7435
|
ctx.model.extend("ggcevo_blacklist", {
|
|
7448
7436
|
handle: "string",
|
|
7437
|
+
name: "string",
|
|
7449
7438
|
createdAt: "timestamp"
|
|
7450
7439
|
}, {
|
|
7451
7440
|
primary: "handle"
|
|
@@ -7771,70 +7760,72 @@ function apply(ctx, config) {
|
|
|
7771
7760
|
}
|
|
7772
7761
|
}, 60 * 60 * 1e3);
|
|
7773
7762
|
ctx.setInterval(async () => {
|
|
7774
|
-
|
|
7775
|
-
|
|
7776
|
-
|
|
7777
|
-
|
|
7778
|
-
|
|
7779
|
-
|
|
7780
|
-
|
|
7781
|
-
|
|
7782
|
-
|
|
7783
|
-
|
|
7784
|
-
|
|
7785
|
-
|
|
7786
|
-
|
|
7787
|
-
|
|
7788
|
-
|
|
7789
|
-
|
|
7790
|
-
|
|
7791
|
-
|
|
7792
|
-
|
|
7793
|
-
|
|
7794
|
-
|
|
7795
|
-
|
|
7796
|
-
|
|
7797
|
-
|
|
7798
|
-
|
|
7799
|
-
const
|
|
7800
|
-
|
|
7801
|
-
|
|
7802
|
-
|
|
7803
|
-
|
|
7804
|
-
|
|
7805
|
-
|
|
7806
|
-
const violators = lobbyPlayers.filter((p) => punishedHandles.has(p.handle));
|
|
7807
|
-
if (violators.length > 0) {
|
|
7808
|
-
const unpunishedPlayersData = lobbyPlayers.filter(
|
|
7809
|
-
(p) => !punishedHandles.has(p.handle)
|
|
7810
|
-
);
|
|
7811
|
-
const queryConditions = unpunishedPlayersData.map((p) => ({
|
|
7812
|
-
regionId: p.regionId,
|
|
7813
|
-
realmId: p.realmId,
|
|
7814
|
-
profileId: p.profileId
|
|
7763
|
+
if (config.enableViolationAlert) {
|
|
7764
|
+
try {
|
|
7765
|
+
const response = await ctx.http("get", "https://api.sc2arcade.com/lobbies/history?regionId=3&mapId=165561&orderDirection=desc&includeMapInfo=false&includeSlots=true&includeSlotsProfile=true&includeSlotsJoinInfo=false&includeJoinHistory=false&includeMatchResult=false&includeMatchPlayers=false");
|
|
7766
|
+
const data = response.data;
|
|
7767
|
+
const openLobbies = data.results.filter(
|
|
7768
|
+
(lobby) => lobby.status === "open" && !processedLobbies.has(lobby.id)
|
|
7769
|
+
);
|
|
7770
|
+
const allPlayers = openLobbies.flatMap(
|
|
7771
|
+
(lobby) => lobby.slots.filter((slot) => slot.kind === "human" && slot.profile).map((slot) => ({
|
|
7772
|
+
regionId: slot.profile.regionId,
|
|
7773
|
+
realmId: slot.profile.realmId,
|
|
7774
|
+
profileId: slot.profile.profileId,
|
|
7775
|
+
handle: `${slot.profile.regionId}-S2-${slot.profile.realmId}-${slot.profile.profileId}`,
|
|
7776
|
+
name: slot.name
|
|
7777
|
+
// 保留名称用于后续展示
|
|
7778
|
+
}))
|
|
7779
|
+
);
|
|
7780
|
+
const punishmentRecords = await ctx.database.select("ggcevo_punishment").where({
|
|
7781
|
+
$and: [
|
|
7782
|
+
{ handle: { $in: allPlayers.map((p) => p.handle) } },
|
|
7783
|
+
{ id: { $gte: 1889 } },
|
|
7784
|
+
{ level: { $in: ["B", "B+", "A"] } }
|
|
7785
|
+
]
|
|
7786
|
+
}).execute();
|
|
7787
|
+
const punishedHandles = new Set(punishmentRecords.map((r) => r.handle));
|
|
7788
|
+
for (const lobby of openLobbies) {
|
|
7789
|
+
const lobbyPlayers = lobby.slots.filter((slot) => slot.kind === "human" && slot.profile).map((slot) => ({
|
|
7790
|
+
regionId: slot.profile.regionId,
|
|
7791
|
+
realmId: slot.profile.realmId,
|
|
7792
|
+
profileId: slot.profile.profileId,
|
|
7793
|
+
handle: `${slot.profile.regionId}-S2-${slot.profile.realmId}-${slot.profile.profileId}`,
|
|
7794
|
+
name: slot.name
|
|
7815
7795
|
}));
|
|
7816
|
-
const
|
|
7817
|
-
|
|
7818
|
-
|
|
7819
|
-
|
|
7820
|
-
|
|
7821
|
-
|
|
7822
|
-
|
|
7823
|
-
|
|
7824
|
-
|
|
7825
|
-
})
|
|
7826
|
-
|
|
7827
|
-
|
|
7828
|
-
|
|
7829
|
-
|
|
7830
|
-
|
|
7831
|
-
|
|
7832
|
-
|
|
7833
|
-
|
|
7796
|
+
const violators = lobbyPlayers.filter((p) => punishedHandles.has(p.handle));
|
|
7797
|
+
if (violators.length > 0) {
|
|
7798
|
+
const unpunishedPlayersData = lobbyPlayers.filter(
|
|
7799
|
+
(p) => !punishedHandles.has(p.handle)
|
|
7800
|
+
);
|
|
7801
|
+
const queryConditions = unpunishedPlayersData.map((p) => ({
|
|
7802
|
+
regionId: p.regionId,
|
|
7803
|
+
realmId: p.realmId,
|
|
7804
|
+
profileId: p.profileId
|
|
7805
|
+
}));
|
|
7806
|
+
const safePlayers = await ctx.database.select("sc2arcade_player").where({ $or: queryConditions }).execute().then((res) => res.map((r) => r.userId));
|
|
7807
|
+
const atElements = safePlayers.map((userId) => `<at id="${userId}"/>`).join(" ");
|
|
7808
|
+
const message = [
|
|
7809
|
+
`📺 监测到违规玩家正在房间中!`,
|
|
7810
|
+
`创建时间: ${new Date(lobby.createdAt).toLocaleString("zh-CN")}`,
|
|
7811
|
+
`🚨 违规玩家(${violators.length} 人):`,
|
|
7812
|
+
...violators.map((v) => {
|
|
7813
|
+
const record = punishmentRecords.find((r) => r.handle === v.handle);
|
|
7814
|
+
return `· ${v.name}(${record?.level}级处罚)`;
|
|
7815
|
+
}),
|
|
7816
|
+
`房主: ${lobby.hostName}`,
|
|
7817
|
+
`玩家数: ${lobby.slotsHumansTaken}/${lobby.slotsHumansTotal}`,
|
|
7818
|
+
"──────────────",
|
|
7819
|
+
`请以下玩家通知房主踢人:${atElements || "无"}`
|
|
7820
|
+
].join("\n");
|
|
7821
|
+
const groupId = [...config.groupId];
|
|
7822
|
+
await ctx.broadcast(groupId, message);
|
|
7823
|
+
processedLobbies.add(lobby.id);
|
|
7824
|
+
}
|
|
7834
7825
|
}
|
|
7826
|
+
} catch (error) {
|
|
7827
|
+
ctx.logger.error("监控失败:", error);
|
|
7835
7828
|
}
|
|
7836
|
-
} catch (error) {
|
|
7837
|
-
ctx.logger.error("监控失败:", error);
|
|
7838
7829
|
}
|
|
7839
7830
|
}, config.checkInterval * 1e3);
|
|
7840
7831
|
ctx.setInterval(async () => {
|
|
@@ -7849,7 +7840,6 @@ function apply(ctx, config) {
|
|
|
7849
7840
|
ctx.command("ggcevo/抽奖").action(async (argv) => {
|
|
7850
7841
|
const session = argv.session;
|
|
7851
7842
|
let winCount = 0;
|
|
7852
|
-
let hiddenWinCount = 0;
|
|
7853
7843
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
7854
7844
|
if (!profile) {
|
|
7855
7845
|
return "🔒 需要先绑定游戏句柄。";
|
|
@@ -7872,16 +7862,13 @@ function apply(ctx, config) {
|
|
|
7872
7862
|
}]);
|
|
7873
7863
|
for (let i = 0; i < quantity; i++) {
|
|
7874
7864
|
const result = await gachaWithPity(ctx, handle);
|
|
7875
|
-
const HiddenAward2 = await gachaWithHiddenAward(ctx, handle);
|
|
7876
7865
|
if (result) winCount++;
|
|
7877
|
-
if (HiddenAward2) hiddenWinCount++;
|
|
7878
7866
|
}
|
|
7879
7867
|
const [record] = await ctx.database.get("ggcevo_records", { handle });
|
|
7880
7868
|
return [
|
|
7881
7869
|
`🎰 您使用了${quantity}枚咕咕币`,
|
|
7882
7870
|
winCount > 0 ? `🎉 其中获得${winCount}张兑换券!` : "💔 本次未获得任何兑换券",
|
|
7883
|
-
`📊 当前保底进度:${record.pityCounter}/90
|
|
7884
|
-
...hiddenWinCount > 0 ? [`🎉 恭喜你抽中隐藏奖励,额外获得${hiddenWinCount}张兑换券和${hiddenWinCount}枚扭蛋币!`] : []
|
|
7871
|
+
`📊 当前保底进度:${record.pityCounter}/90`
|
|
7885
7872
|
].join("\n");
|
|
7886
7873
|
});
|
|
7887
7874
|
ctx.command("ggcevo/单抽").action(async (argv) => {
|
|
@@ -7906,16 +7893,13 @@ function apply(ctx, config) {
|
|
|
7906
7893
|
quantity: backpack.quantity - 1
|
|
7907
7894
|
}]);
|
|
7908
7895
|
const result = await gachaWithPity(ctx, handle);
|
|
7909
|
-
const HiddenAward2 = await gachaWithHiddenAward(ctx, handle);
|
|
7910
7896
|
const [record] = await ctx.database.get("ggcevo_records", { handle });
|
|
7911
7897
|
return [
|
|
7912
|
-
`${result ? "🎉 获得兑换券!" : "❌ 未中奖"} 保底进度:${record.pityCounter}/90
|
|
7913
|
-
...HiddenAward2 ? [`🎉 恭喜你抽中隐藏奖励,额外获得1张兑换券和1枚扭蛋币!`] : []
|
|
7898
|
+
`${result ? "🎉 获得兑换券!" : "❌ 未中奖"} 保底进度:${record.pityCounter}/90`
|
|
7914
7899
|
].join("\n");
|
|
7915
7900
|
});
|
|
7916
7901
|
ctx.command("ggcevo/十连抽").action(async (argv) => {
|
|
7917
7902
|
const session = argv.session;
|
|
7918
|
-
let hiddenWinCount = 0;
|
|
7919
7903
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
7920
7904
|
if (!profile) {
|
|
7921
7905
|
return "🔒 需要先绑定游戏句柄。";
|
|
@@ -7938,15 +7922,12 @@ function apply(ctx, config) {
|
|
|
7938
7922
|
const results = [];
|
|
7939
7923
|
for (let i = 0; i < 10; i++) {
|
|
7940
7924
|
results.push(await gachaWithPity(ctx, handle));
|
|
7941
|
-
const HiddenAward2 = await gachaWithHiddenAward(ctx, handle);
|
|
7942
|
-
if (HiddenAward2) hiddenWinCount++;
|
|
7943
7925
|
}
|
|
7944
7926
|
const [record] = await ctx.database.get("ggcevo_records", { handle });
|
|
7945
7927
|
return [
|
|
7946
7928
|
"十连抽结果:",
|
|
7947
7929
|
...results.map((r) => r ? "🎉 获得兑换券" : "❌ 未中奖"),
|
|
7948
|
-
`保底进度:${record.pityCounter}/90
|
|
7949
|
-
...hiddenWinCount > 0 ? [`🎉 恭喜你抽中隐藏奖励,额外获得${hiddenWinCount}张兑换券和${hiddenWinCount}枚扭蛋币!`] : []
|
|
7930
|
+
`保底进度:${record.pityCounter}/90`
|
|
7950
7931
|
].join("\n");
|
|
7951
7932
|
});
|
|
7952
7933
|
ctx.command("ggcevo/背包").action(async (argv) => {
|
|
@@ -8625,7 +8606,7 @@ ${ticketMessage}${effectMessage}`;
|
|
|
8625
8606
|
pageNum < totalPages ? `输入 违规记录 (@玩家) -p ${pageNum + 1} 查看下一条` : "已是最后一页"
|
|
8626
8607
|
].join("\n");
|
|
8627
8608
|
});
|
|
8628
|
-
ctx.command("ggcevo
|
|
8609
|
+
ctx.command("ggcevo/兑换赞助物品", "兑换赞助物品").action(async ({ session }) => {
|
|
8629
8610
|
try {
|
|
8630
8611
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
8631
8612
|
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
@@ -8808,30 +8789,42 @@ ${items.join("、")}
|
|
|
8808
8789
|
}]);
|
|
8809
8790
|
return `🎉 恭喜!您获得了${itemName}`;
|
|
8810
8791
|
});
|
|
8811
|
-
ctx.command("ggcevo/拉黑 [
|
|
8792
|
+
ctx.command("ggcevo/拉黑 [user]", "黑名单管理", { authority: 3 }).action(async (argv, user) => {
|
|
8812
8793
|
const session = argv.session;
|
|
8813
|
-
if (!
|
|
8814
|
-
await
|
|
8815
|
-
|
|
8816
|
-
|
|
8794
|
+
if (!user) {
|
|
8795
|
+
const blacklist = await ctx.database.get("ggcevo_blacklist", {}, { fields: ["handle", "name", "createdAt"] });
|
|
8796
|
+
if (blacklist.length === 0) return "当前黑名单为空。";
|
|
8797
|
+
let message = "📋 黑名单列表:\n";
|
|
8798
|
+
for (const entry of blacklist.slice(0, 10)) {
|
|
8799
|
+
const time = new Date(entry.createdAt).toLocaleString();
|
|
8800
|
+
message += `▫️ ${entry.name} (${entry.handle}) - 添加时间: ${time}
|
|
8801
|
+
`;
|
|
8802
|
+
}
|
|
8803
|
+
if (blacklist.length > 10) message += `
|
|
8804
|
+
...显示前10条,共${blacklist.length}条记录`;
|
|
8805
|
+
return message;
|
|
8817
8806
|
}
|
|
8818
8807
|
try {
|
|
8819
|
-
const
|
|
8820
|
-
if (!
|
|
8821
|
-
|
|
8822
|
-
|
|
8823
|
-
|
|
8824
|
-
|
|
8825
|
-
|
|
8826
|
-
}
|
|
8808
|
+
const parsed = import_koishi.h.parse(user)[0];
|
|
8809
|
+
if (!parsed || parsed.type !== "at") return '格式错误,请使用"拉黑 @用户"格式';
|
|
8810
|
+
const targetUserId = parsed.attrs.id;
|
|
8811
|
+
const targetUserInfo = await session.bot.getGuildMember(session.guildId, targetUserId);
|
|
8812
|
+
if (!targetUserInfo) return "无法获取用户信息";
|
|
8813
|
+
const targetName = targetUserInfo.nick || targetUserInfo.user.name;
|
|
8814
|
+
const [profile] = await ctx.database.get("sc2arcade_player", { userId: targetUserId });
|
|
8815
|
+
if (!profile) return `${targetName} 尚未绑定星际句柄`;
|
|
8816
|
+
const targetHandle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
8817
|
+
const exists = await ctx.database.get("ggcevo_blacklist", { handle: targetHandle });
|
|
8818
|
+
if (exists.length) return `⚠️ ${targetName} (${targetHandle}) 已在黑名单中`;
|
|
8827
8819
|
await ctx.database.create("ggcevo_blacklist", {
|
|
8828
|
-
handle,
|
|
8820
|
+
handle: targetHandle,
|
|
8821
|
+
name: targetName,
|
|
8829
8822
|
createdAt: /* @__PURE__ */ new Date()
|
|
8830
8823
|
});
|
|
8831
|
-
return `✅
|
|
8824
|
+
return `✅ 已拉黑 ${targetName} (${targetHandle})`;
|
|
8832
8825
|
} catch (error) {
|
|
8833
|
-
console.error("
|
|
8834
|
-
return "
|
|
8826
|
+
console.error("拉黑操作错误:", error);
|
|
8827
|
+
return "操作失败,请检查控制台日志";
|
|
8835
8828
|
}
|
|
8836
8829
|
});
|
|
8837
8830
|
ctx.command("ggcevo/标记 [handle]", "标记用户到胜点榜黑名单", { authority: 3 }).action(async (argv, handle) => {
|
|
@@ -9821,6 +9814,9 @@ ${discountDetails.join("\n")}`;
|
|
|
9821
9814
|
const processModInstallation = /* @__PURE__ */ __name(async () => {
|
|
9822
9815
|
const modInfo = modConfig[mod];
|
|
9823
9816
|
if (!modInfo) return "❌ 无效模块名称。";
|
|
9817
|
+
if (modInfo.recyclable) {
|
|
9818
|
+
return `❌ ${mod} 已开启回收模式,无法安装该模块。`;
|
|
9819
|
+
}
|
|
9824
9820
|
if (!weapon || !weaponConfig[weapon]?.id) {
|
|
9825
9821
|
const validWeapons = Object.keys(weaponConfig).filter((k) => weaponConfig[k].id);
|
|
9826
9822
|
return `❌ 无效武器名称。可选武器:${validWeapons.join("、")}`;
|
|
@@ -9879,7 +9875,7 @@ ${discountDetails.join("\n")}`;
|
|
|
9879
9875
|
}, "processModInstallation");
|
|
9880
9876
|
const showModList = /* @__PURE__ */ __name(async () => {
|
|
9881
9877
|
const buildModList = /* @__PURE__ */ __name((isExclusive) => {
|
|
9882
|
-
const mods = Object.entries(modConfig).filter(([_, m]) => m.isExclusive === isExclusive).map(([name2, cfg]) => {
|
|
9878
|
+
const mods = Object.entries(modConfig).filter(([_, m]) => m.isExclusive === isExclusive && !m.recyclable).map(([name2, cfg]) => {
|
|
9883
9879
|
const discountRate = calculateDiscountRate(cfg.isExclusive);
|
|
9884
9880
|
const actualPrice = Math.floor(cfg.cost * (1 - discountRate / 100));
|
|
9885
9881
|
return [
|
|
@@ -9896,7 +9892,8 @@ ${discountDetails.join("\n")}`;
|
|
|
9896
9892
|
const exclusiveDiscountRate = calculateDiscountRate(true);
|
|
9897
9893
|
if (weapon && weaponConfig[weapon]?.id) {
|
|
9898
9894
|
const weaponExclusiveMods = Object.entries(modConfig).filter(
|
|
9899
|
-
([_, cfg]) => cfg.isExclusive && cfg.exclusiveTo === weapon
|
|
9895
|
+
([_, cfg]) => cfg.isExclusive && cfg.exclusiveTo === weapon && !cfg.recyclable
|
|
9896
|
+
// 新增回收模式过滤
|
|
9900
9897
|
);
|
|
9901
9898
|
const exclusiveList = weaponExclusiveMods.length > 0 ? weaponExclusiveMods.map(([name2, cfg]) => {
|
|
9902
9899
|
const discountRate = calculateDiscountRate(true);
|
|
@@ -9914,7 +9911,6 @@ ${discountDetails.join("\n")}`;
|
|
|
9914
9911
|
"使用「改装武器 武器名称 模块名称」安装",
|
|
9915
9912
|
"※ 每个武器只能安装一个专属模块",
|
|
9916
9913
|
armorMessage,
|
|
9917
|
-
// 新增装甲兵提示
|
|
9918
9914
|
exclusiveDiscountRate > 0 && `💰 当前专属模块折扣:`,
|
|
9919
9915
|
exclusiveDiscountRate > 0 && careerData?.group === "人类联盟" && techLevel >= 2 && `▸ ⚙️ 武器升级平台Lv.${techLevel}:${exclusiveDiscountRate}%折扣`,
|
|
9920
9916
|
exclusiveDiscountRate > 0 && isArmoredPirate && "▸ 🔰 装甲兵职业:10%折扣",
|
|
@@ -9928,7 +9924,6 @@ ${discountDetails.join("\n")}`;
|
|
|
9928
9924
|
"使用「改装武器 武器名称 模块名称」安装通用模块",
|
|
9929
9925
|
"※ 使用「改装武器 武器名称」查询武器专属模块",
|
|
9930
9926
|
armorMessage,
|
|
9931
|
-
// 新增装甲兵提示
|
|
9932
9927
|
universalDiscountRate > 0 && `💰 当前通用模块折扣:`,
|
|
9933
9928
|
universalDiscountRate > 0 && careerData?.group === "人类联盟" && techLevel >= 1 && `▸ ⚙️ 武器升级平台Lv.${techLevel}:${universalDiscountRate}%折扣`,
|
|
9934
9929
|
universalDiscountRate > 0 && isArmoredPirate && "▸ 🔰 装甲兵职业:10%折扣",
|
|
@@ -9950,11 +9945,9 @@ ${discountDetails.join("\n")}`;
|
|
|
9950
9945
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
9951
9946
|
if (existingEntries.length > 0) return "⛔ 您已被列入黑名单。";
|
|
9952
9947
|
const weaponId = weaponConfig[weapon]?.id;
|
|
9953
|
-
if (!weaponId) return
|
|
9948
|
+
if (!weaponId) return '❌ 请输入"拆卸 武器名称 模块名称"\n注意:通用模块返还80%金币,专属模块返还50%金币';
|
|
9954
9949
|
const modInfo = modConfig[mod];
|
|
9955
|
-
if (!modInfo) return
|
|
9956
|
-
const refundRate = modInfo.isExclusive ? 0.5 : 0.8;
|
|
9957
|
-
const refundType = modInfo.isExclusive ? "专属模块返还50%" : "通用模块返还80%";
|
|
9950
|
+
if (!modInfo) return '❌ 请输入"拆卸 武器名称 模块名称"\n注意:通用模块返还80%金币,专属模块返还50%金币';
|
|
9958
9951
|
const [equipment] = await ctx.database.get("ggcevo_weapons", {
|
|
9959
9952
|
handle,
|
|
9960
9953
|
weaponId
|
|
@@ -9963,6 +9956,19 @@ ${discountDetails.join("\n")}`;
|
|
|
9963
9956
|
if (!equipment.installedMods.includes(mod)) {
|
|
9964
9957
|
return `❌ 该武器未安装${mod}模块。`;
|
|
9965
9958
|
}
|
|
9959
|
+
const isRecyclable = modInfo.recyclable;
|
|
9960
|
+
let refundRate;
|
|
9961
|
+
let refundReason;
|
|
9962
|
+
if (isRecyclable) {
|
|
9963
|
+
refundRate = 1;
|
|
9964
|
+
refundReason = "⚠️ 回收模式开启:全额返还金币";
|
|
9965
|
+
} else if (modInfo.isExclusive) {
|
|
9966
|
+
refundRate = 0.5;
|
|
9967
|
+
refundReason = "专属模块返还50%";
|
|
9968
|
+
} else {
|
|
9969
|
+
refundRate = 0.8;
|
|
9970
|
+
refundReason = "通用模块返还80%";
|
|
9971
|
+
}
|
|
9966
9972
|
const refund = Math.floor(modInfo.cost * refundRate);
|
|
9967
9973
|
const newMods = equipment.installedMods.filter((m) => m !== mod);
|
|
9968
9974
|
await ctx.database.set(
|
|
@@ -9978,10 +9984,10 @@ ${discountDetails.join("\n")}`;
|
|
|
9978
9984
|
}], ["handle"]);
|
|
9979
9985
|
return [
|
|
9980
9986
|
`✅ 已从 ${weapon} 拆卸 ${mod} 模块`,
|
|
9981
|
-
`返还金币:${refund} (原价${modInfo.cost}
|
|
9987
|
+
`返还金币:${refund} (原价${modInfo.cost}, ${refundReason})`,
|
|
9982
9988
|
`当前金币总额:${newBalance}`,
|
|
9983
9989
|
`剩余模块:${newMods.join(", ") || "无"}`,
|
|
9984
|
-
modInfo.isExclusive ? "ℹ️ 专属模块拆卸只返还50%" : ""
|
|
9990
|
+
isRecyclable ? "ℹ️ 回收模式模块拆卸返还100%" : modInfo.isExclusive ? "ℹ️ 专属模块拆卸只返还50%" : ""
|
|
9985
9991
|
].filter(Boolean).join("\n");
|
|
9986
9992
|
});
|
|
9987
9993
|
ctx.guild().command("ggcevo/攻击 <bossName>").usage("请输入要攻击的异形名称(例如:攻击 异齿猛兽 或 攻击 寒冰王蛇)").action(async (argv, bossName) => {
|
|
@@ -10584,85 +10590,6 @@ ${testResult.passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
10584
10590
|
return `✨ 祈愿成功!花费50枚金币获得【${effect.name}】效果:${effect.effect}
|
|
10585
10591
|
⏳ 效果持续至 ${formattedEndTime}`;
|
|
10586
10592
|
});
|
|
10587
|
-
ctx.command("ggcevo/兑换金币", "使用兑换券兑换金币").action(async ({ session }) => {
|
|
10588
|
-
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
10589
|
-
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
10590
|
-
const { regionId, realmId, profileId } = profile;
|
|
10591
|
-
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
10592
|
-
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
10593
|
-
if (existingEntries.length > 0) {
|
|
10594
|
-
return `⛔ 您已被列入黑名单。`;
|
|
10595
|
-
}
|
|
10596
|
-
await session.send(`请输入你要使用多少张兑换券来兑换金币?(请在30秒内回复数字,回复“0”为取消兑换)
|
|
10597
|
-
注意:1张兑换券=2000金币`);
|
|
10598
|
-
const exchangeInput = await session.prompt(3e4);
|
|
10599
|
-
if (!exchangeInput) return "已取消操作,请重新输入。";
|
|
10600
|
-
const exchangeCount = parseInt(exchangeInput, 10);
|
|
10601
|
-
if (isNaN(exchangeCount)) return "请输入有效的数字!";
|
|
10602
|
-
if (exchangeCount < 0) return "兑换数量不能为负数!";
|
|
10603
|
-
if (exchangeCount === 0) return "已取消兑换。";
|
|
10604
|
-
const [item] = await ctx.database.get("ggcevo_backpack", {
|
|
10605
|
-
handle,
|
|
10606
|
-
itemId: 2
|
|
10607
|
-
});
|
|
10608
|
-
const [coin] = await ctx.database.get("ggcevo_sign", {
|
|
10609
|
-
handle
|
|
10610
|
-
});
|
|
10611
|
-
if (!item || item.quantity < exchangeCount) {
|
|
10612
|
-
return "您的兑换券不足,无法兑换!";
|
|
10613
|
-
}
|
|
10614
|
-
const goldAmount = exchangeCount * 2e3;
|
|
10615
|
-
await ctx.database.set("ggcevo_backpack", {
|
|
10616
|
-
handle,
|
|
10617
|
-
itemId: 2
|
|
10618
|
-
}, {
|
|
10619
|
-
quantity: item.quantity - exchangeCount
|
|
10620
|
-
});
|
|
10621
|
-
await ctx.database.set("ggcevo_sign", { handle }, {
|
|
10622
|
-
totalRewards: (coin?.totalRewards || 0) + goldAmount
|
|
10623
|
-
});
|
|
10624
|
-
return `成功使用${exchangeCount}张兑换券,获得${goldAmount}枚金币!`;
|
|
10625
|
-
});
|
|
10626
|
-
ctx.command("ggcevo/兑换红晶", "使用金币兑换红晶").action(async ({ session }) => {
|
|
10627
|
-
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
10628
|
-
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
10629
|
-
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
10630
|
-
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
10631
|
-
if (existingEntries.length > 0) {
|
|
10632
|
-
return `⛔ 您已被列入黑名单。`;
|
|
10633
|
-
}
|
|
10634
|
-
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
10635
|
-
if (!careerData || careerData.group !== "辛迪加海盗") {
|
|
10636
|
-
return "🚫 该功能需要【辛迪加海盗】阵营权限";
|
|
10637
|
-
}
|
|
10638
|
-
await session.send(`请输入你想要兑换多少红晶?(请在30秒内回复数字,回复“0”为取消兑换)
|
|
10639
|
-
注意:每块红晶需要500金币。`);
|
|
10640
|
-
const exchangeInput = await session.prompt(3e4);
|
|
10641
|
-
if (!exchangeInput) return "已取消操作,请重新输入。";
|
|
10642
|
-
const exchangeCount = parseInt(exchangeInput, 10);
|
|
10643
|
-
if (isNaN(exchangeCount)) return "请输入有效的数字!";
|
|
10644
|
-
if (exchangeCount < 0) return "兑换数量不能为负数!";
|
|
10645
|
-
if (exchangeCount === 0) return "已取消兑换。";
|
|
10646
|
-
const goldAmount = exchangeCount * 500;
|
|
10647
|
-
const [coin] = await ctx.database.get("ggcevo_sign", {
|
|
10648
|
-
handle
|
|
10649
|
-
});
|
|
10650
|
-
const [career] = await ctx.database.get("ggcevo_careers", {
|
|
10651
|
-
handle
|
|
10652
|
-
});
|
|
10653
|
-
if (!coin || coin.totalRewards < goldAmount) {
|
|
10654
|
-
return "您的金币不足,无法兑换红晶!";
|
|
10655
|
-
}
|
|
10656
|
-
await ctx.database.set("ggcevo_sign", {
|
|
10657
|
-
handle
|
|
10658
|
-
}, {
|
|
10659
|
-
totalRewards: coin.totalRewards - goldAmount
|
|
10660
|
-
});
|
|
10661
|
-
await ctx.database.set("ggcevo_careers", { handle }, {
|
|
10662
|
-
redcrystal: (career?.redcrystal || 0) + exchangeCount
|
|
10663
|
-
});
|
|
10664
|
-
return `成功使用${goldAmount}金币,获得${exchangeCount}红晶!`;
|
|
10665
|
-
});
|
|
10666
10593
|
ctx.command("ggcevo/加入 <faction>", "加入阵营").alias("加入阵营").action(async ({ session }, faction) => {
|
|
10667
10594
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
10668
10595
|
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
@@ -12541,6 +12468,71 @@ ${validBossNames.join("、")}`;
|
|
|
12541
12468
|
return "⚠️ 竞猜提交失败,请重试";
|
|
12542
12469
|
}
|
|
12543
12470
|
});
|
|
12471
|
+
ctx.command("ggcevo/兑换资源 [name] [amount]").usage('输入"兑换资源"查看可兑换资源列表\n输入"兑换资源 物品名称 [数量]"进行兑换').action(async ({ session }, name2, amount) => {
|
|
12472
|
+
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
12473
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
12474
|
+
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
12475
|
+
const resourceItems = {
|
|
12476
|
+
"金币": { valuePerCoupon: 100, currencyField: "totalRewards", table: "ggcevo_sign" },
|
|
12477
|
+
"红晶": { valuePerCoupon: 1, currencyField: "redcrystal", table: "ggcevo_careers" }
|
|
12478
|
+
};
|
|
12479
|
+
if (!name2) {
|
|
12480
|
+
const [coupon] = await ctx.database.get("ggcevo_backpack", {
|
|
12481
|
+
handle,
|
|
12482
|
+
itemId: 8
|
|
12483
|
+
});
|
|
12484
|
+
return [
|
|
12485
|
+
"💰 资源兑换商店 💰",
|
|
12486
|
+
'使用 "兑换资源 物品名称 数量" 进行兑换',
|
|
12487
|
+
`您当前持有: ${coupon?.quantity || 0}张资源兑换券`,
|
|
12488
|
+
"====================",
|
|
12489
|
+
...Object.entries(resourceItems).map(([itemName, config3]) => `▸ ${itemName}:1张券兑换${config3.valuePerCoupon}${itemName === "金币" ? "金币" : "红晶"}`),
|
|
12490
|
+
"====================",
|
|
12491
|
+
'输入示例:"兑换资源 金币 5"(兑换500金币)'
|
|
12492
|
+
].join("\n");
|
|
12493
|
+
}
|
|
12494
|
+
const config2 = resourceItems[name2];
|
|
12495
|
+
if (!config2) return `⚠️ 无效物品名称,可用选项:${Object.keys(resourceItems).join("、")}`;
|
|
12496
|
+
const exchangeAmount = parseInt(amount) || 1;
|
|
12497
|
+
if (exchangeAmount <= 0 || exchangeAmount > 100) return "⚠️ 兑换数量需在1-100之间";
|
|
12498
|
+
const [couponItem] = await ctx.database.get("ggcevo_backpack", {
|
|
12499
|
+
handle,
|
|
12500
|
+
itemId: 8
|
|
12501
|
+
});
|
|
12502
|
+
const couponCount = couponItem?.quantity || 0;
|
|
12503
|
+
if (couponCount < exchangeAmount) {
|
|
12504
|
+
return `⚠️ 兑换券不足,需要${exchangeAmount}张,当前持有:${couponCount}张`;
|
|
12505
|
+
}
|
|
12506
|
+
const gainAmount = config2.valuePerCoupon * exchangeAmount;
|
|
12507
|
+
try {
|
|
12508
|
+
await ctx.database.withTransaction(async () => {
|
|
12509
|
+
await ctx.database.set(
|
|
12510
|
+
"ggcevo_backpack",
|
|
12511
|
+
{ handle, itemId: 8 },
|
|
12512
|
+
{ quantity: couponCount - exchangeAmount }
|
|
12513
|
+
);
|
|
12514
|
+
const [record] = await ctx.database.get(config2.table, { handle });
|
|
12515
|
+
if (record) {
|
|
12516
|
+
await ctx.database.set(
|
|
12517
|
+
config2.table,
|
|
12518
|
+
{ handle },
|
|
12519
|
+
{ [config2.currencyField]: record[config2.currencyField] + gainAmount }
|
|
12520
|
+
);
|
|
12521
|
+
} else {
|
|
12522
|
+
await ctx.database.create(config2.table, {
|
|
12523
|
+
handle,
|
|
12524
|
+
userId: session.userId,
|
|
12525
|
+
[config2.currencyField]: gainAmount,
|
|
12526
|
+
...config2.table === "ggcevo_sign" ? { lastSign: /* @__PURE__ */ new Date() } : {}
|
|
12527
|
+
});
|
|
12528
|
+
}
|
|
12529
|
+
});
|
|
12530
|
+
return `🎉 兑换成功!使用${exchangeAmount}张资源券兑换了${gainAmount}${name2 === "金币" ? "金币" : "红晶"}`;
|
|
12531
|
+
} catch (error) {
|
|
12532
|
+
console.error("资源兑换失败:", error);
|
|
12533
|
+
return "⚠️ 兑换失败,请稍后再试";
|
|
12534
|
+
}
|
|
12535
|
+
});
|
|
12544
12536
|
ctx.command("ggcevo/签到奖励").action(({}) => {
|
|
12545
12537
|
return `
|
|
12546
12538
|
签到咕咕币奖励:
|
package/lib/weapons.d.ts
CHANGED
|
@@ -450,95 +450,111 @@ export declare const modConfig: {
|
|
|
450
450
|
effect: string;
|
|
451
451
|
exclusiveTo: string;
|
|
452
452
|
isExclusive: boolean;
|
|
453
|
+
recyclable: boolean;
|
|
453
454
|
};
|
|
454
455
|
棱镜水晶: {
|
|
455
456
|
cost: number;
|
|
456
457
|
effect: string;
|
|
457
458
|
exclusiveTo: string;
|
|
458
459
|
isExclusive: boolean;
|
|
460
|
+
recyclable: boolean;
|
|
459
461
|
};
|
|
460
462
|
破甲模块: {
|
|
461
463
|
cost: number;
|
|
462
464
|
effect: string;
|
|
463
465
|
exclusiveTo: string;
|
|
464
466
|
isExclusive: boolean;
|
|
467
|
+
recyclable: boolean;
|
|
465
468
|
};
|
|
466
469
|
裂甲核心: {
|
|
467
470
|
cost: number;
|
|
468
471
|
effect: string;
|
|
469
472
|
exclusiveTo: string;
|
|
470
473
|
isExclusive: boolean;
|
|
474
|
+
recyclable: boolean;
|
|
471
475
|
};
|
|
472
476
|
棱镜超载核心: {
|
|
473
477
|
cost: number;
|
|
474
478
|
effect: string;
|
|
475
479
|
exclusiveTo: string;
|
|
476
480
|
isExclusive: boolean;
|
|
481
|
+
recyclable: boolean;
|
|
477
482
|
};
|
|
478
483
|
助燃核心: {
|
|
479
484
|
cost: number;
|
|
480
485
|
effect: string;
|
|
481
486
|
exclusiveTo: string;
|
|
482
487
|
isExclusive: boolean;
|
|
488
|
+
recyclable: boolean;
|
|
483
489
|
};
|
|
484
490
|
光束曲射晶片: {
|
|
485
491
|
cost: number;
|
|
486
492
|
effect: string;
|
|
487
493
|
exclusiveTo: string;
|
|
488
494
|
isExclusive: boolean;
|
|
495
|
+
recyclable: boolean;
|
|
489
496
|
};
|
|
490
497
|
金刚石瞄准镜: {
|
|
491
498
|
cost: number;
|
|
492
499
|
effect: string;
|
|
493
500
|
exclusiveTo: string;
|
|
494
501
|
isExclusive: boolean;
|
|
502
|
+
recyclable: boolean;
|
|
495
503
|
};
|
|
496
504
|
微型聚变核心: {
|
|
497
505
|
cost: number;
|
|
498
506
|
effect: string;
|
|
499
507
|
exclusiveTo: string;
|
|
500
508
|
isExclusive: boolean;
|
|
509
|
+
recyclable: boolean;
|
|
501
510
|
};
|
|
502
511
|
辐射充能核心: {
|
|
503
512
|
cost: number;
|
|
504
513
|
effect: string;
|
|
505
514
|
exclusiveTo: string;
|
|
506
515
|
isExclusive: boolean;
|
|
516
|
+
recyclable: boolean;
|
|
507
517
|
};
|
|
508
518
|
等离子轴承: {
|
|
509
519
|
cost: number;
|
|
510
520
|
effect: string;
|
|
511
521
|
exclusiveTo: string;
|
|
512
522
|
isExclusive: boolean;
|
|
523
|
+
recyclable: boolean;
|
|
513
524
|
};
|
|
514
525
|
脉冲稳定核心: {
|
|
515
526
|
cost: number;
|
|
516
527
|
effect: string;
|
|
517
528
|
exclusiveTo: string;
|
|
518
529
|
isExclusive: boolean;
|
|
530
|
+
recyclable: boolean;
|
|
519
531
|
};
|
|
520
532
|
高压电池: {
|
|
521
533
|
cost: number;
|
|
522
534
|
effect: string;
|
|
523
535
|
exclusiveTo: string;
|
|
524
536
|
isExclusive: boolean;
|
|
537
|
+
recyclable: boolean;
|
|
525
538
|
};
|
|
526
539
|
氮气压缩核心: {
|
|
527
540
|
cost: number;
|
|
528
541
|
effect: string;
|
|
529
542
|
exclusiveTo: string;
|
|
530
543
|
isExclusive: boolean;
|
|
544
|
+
recyclable: boolean;
|
|
531
545
|
};
|
|
532
546
|
轻型电源节点: {
|
|
533
547
|
cost: number;
|
|
534
548
|
effect: string;
|
|
535
549
|
exclusiveTo: string;
|
|
536
550
|
isExclusive: boolean;
|
|
551
|
+
recyclable: boolean;
|
|
537
552
|
};
|
|
538
553
|
强力钻刺核心: {
|
|
539
554
|
cost: number;
|
|
540
555
|
effect: string;
|
|
541
556
|
exclusiveTo: string;
|
|
542
557
|
isExclusive: boolean;
|
|
558
|
+
recyclable: boolean;
|
|
543
559
|
};
|
|
544
560
|
};
|