koishi-plugin-ggcevo-game 1.6.29 → 1.6.32
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 +1 -0
- package/lib/index.js +235 -402
- package/lib/items.d.ts +5 -0
- package/lib/utils.d.ts +1 -0
- package/package.json +1 -1
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
|
@@ -510,7 +510,7 @@ var modConfig = {
|
|
|
510
510
|
},
|
|
511
511
|
"棱镜超载核心": {
|
|
512
512
|
cost: 2250,
|
|
513
|
-
effect: "暴击率提升20%;连续
|
|
513
|
+
effect: "暴击率提升20%;连续3次未暴击时,下次攻击必定暴击",
|
|
514
514
|
exclusiveTo: "激光步枪",
|
|
515
515
|
isExclusive: true
|
|
516
516
|
},
|
|
@@ -683,6 +683,7 @@ var initDefaultItems = {
|
|
|
683
683
|
"t2级宠物扭蛋": { id: 5, type: "宠物蛋", description: "用于兑换t2系列宠物" },
|
|
684
684
|
"t1级宠物扭蛋": { id: 6, type: "宠物蛋", description: "用于兑换t1系列宠物" },
|
|
685
685
|
"t0级宠物扭蛋": { id: 7, type: "宠物蛋", description: "用于兑换t0系列宠物" },
|
|
686
|
+
"资源兑换券": { id: 8, type: "兑换货币", description: "用于兑换咕咕之战资源" },
|
|
686
687
|
"🥇先行者赛季冠军勋章": { id: 101, type: "勋章", description: "" },
|
|
687
688
|
"🥈先行者赛季亚军勋章": { id: 102, type: "勋章", description: "" },
|
|
688
689
|
"🥉先行者赛季季军勋章": { id: 103, type: "勋章", description: "" },
|
|
@@ -737,7 +738,7 @@ var spaceStationCrewConfig = [
|
|
|
737
738
|
effect: "攻击获得的金币+50%",
|
|
738
739
|
requirements: "当期伤害榜累计造成100及以上伤害",
|
|
739
740
|
Jobtransfer: true,
|
|
740
|
-
costcoins:
|
|
741
|
+
costcoins: 2e3
|
|
741
742
|
},
|
|
742
743
|
{
|
|
743
744
|
professionName: "警卫长",
|
|
@@ -748,7 +749,7 @@ var spaceStationCrewConfig = [
|
|
|
748
749
|
},
|
|
749
750
|
{
|
|
750
751
|
professionName: "武器中士",
|
|
751
|
-
effect: "攻击伤害+15%;
|
|
752
|
+
effect: "攻击伤害+15%; 购买传奇武器无需权限次数(第一次购买将消耗权限次数半价购买传奇武器)",
|
|
752
753
|
requirements: "至少拥有一把6级及以上等级的武器",
|
|
753
754
|
Jobtransfer: true,
|
|
754
755
|
costcoins: 3e3
|
|
@@ -799,14 +800,14 @@ var spaceStationCrewConfig = [
|
|
|
799
800
|
var syndicatePirateConfig = [
|
|
800
801
|
{
|
|
801
802
|
professionName: "能量武器专家",
|
|
802
|
-
effect: "能量武器攻击伤害+20%; 购买MK-4激光步枪(传奇)享有50%的折扣",
|
|
803
|
+
effect: "能量武器攻击伤害+20%; 使用能量武器攻击时暴击率+10%; 购买MK-4激光步枪(传奇)享有50%的折扣",
|
|
803
804
|
requirements: "至少拥有一把3级及以上等级的能量武器",
|
|
804
805
|
Jobtransfer: true,
|
|
805
806
|
costredcrystal: 30
|
|
806
807
|
},
|
|
807
808
|
{
|
|
808
809
|
professionName: "清洁工",
|
|
809
|
-
effect: "
|
|
810
|
+
effect: "每次攻击额外获得1枚红晶,每造成100伤害额外获得1枚红晶(至多额外获得3枚)",
|
|
810
811
|
requirements: "当期伤害榜累计攻击4次及以上",
|
|
811
812
|
Jobtransfer: true,
|
|
812
813
|
costredcrystal: 20
|
|
@@ -820,7 +821,7 @@ var syndicatePirateConfig = [
|
|
|
820
821
|
},
|
|
821
822
|
{
|
|
822
823
|
professionName: "猩红杀手",
|
|
823
|
-
effect: "“侦察步枪”攻击伤害+15%; 使用“侦察步枪”攻击时每1点护甲改为减少
|
|
824
|
+
effect: "“侦察步枪”攻击伤害+15%; 使用“侦察步枪”攻击时每1点护甲改为减少0点伤害; 购买DSR-55反器材步枪(传奇)享有50%的折扣",
|
|
824
825
|
requirements: "“侦察步枪”武器等级≥3级",
|
|
825
826
|
Jobtransfer: true,
|
|
826
827
|
costredcrystal: 30
|
|
@@ -834,7 +835,7 @@ var syndicatePirateConfig = [
|
|
|
834
835
|
},
|
|
835
836
|
{
|
|
836
837
|
professionName: "辛迪加财务经理",
|
|
837
|
-
effect: "
|
|
838
|
+
effect: "每日签到能额外获得5枚红晶",
|
|
838
839
|
requirements: "当月累计签到14天及以上",
|
|
839
840
|
Jobtransfer: true,
|
|
840
841
|
costredcrystal: 40
|
|
@@ -844,7 +845,7 @@ var syndicatePirateConfig = [
|
|
|
844
845
|
effect: "黑市订购设备工具类享有50%折扣; 主动发起的PK胜率提高10%; 每日主动PK次数增加3次",
|
|
845
846
|
requirements: "仓库中至少拥有一个黑市订购的设备工具类物品",
|
|
846
847
|
Jobtransfer: true,
|
|
847
|
-
costredcrystal:
|
|
848
|
+
costredcrystal: 20
|
|
848
849
|
},
|
|
849
850
|
{
|
|
850
851
|
professionName: "指挥官",
|
|
@@ -4627,7 +4628,7 @@ function applyPassiveEffects(targetBoss, activeBosses, weaponName, damage, hasCr
|
|
|
4627
4628
|
}
|
|
4628
4629
|
let armorDamageReduction = weaponData.armorDamageReduction || 0;
|
|
4629
4630
|
if (careerData?.career === "猩红杀手" && weaponName === "侦察步枪") {
|
|
4630
|
-
armorDamageReduction =
|
|
4631
|
+
armorDamageReduction = 0;
|
|
4631
4632
|
}
|
|
4632
4633
|
if (equippedWeapon.installedMods?.includes("氮气压缩核心")) {
|
|
4633
4634
|
armorDamageReduction = 0;
|
|
@@ -5416,6 +5417,22 @@ var ggcevoUpdates = [
|
|
|
5416
5417
|
- 异形信息新增显示护甲削减值(动力钻头和传奇高斯的削减)
|
|
5417
5418
|
- 增强了辛迪加海盗阵营的破坏者和纵火狂
|
|
5418
5419
|
`.trim()
|
|
5420
|
+
},
|
|
5421
|
+
{
|
|
5422
|
+
version: "1.6.30",
|
|
5423
|
+
time: "2025-07-16",
|
|
5424
|
+
content: `
|
|
5425
|
+
- 增强了专属改装棱镜超载核心
|
|
5426
|
+
- 增强了能量武器专家职业效果
|
|
5427
|
+
- 重制了清洁工职业效果
|
|
5428
|
+
- 增强了猩红杀手职业效果
|
|
5429
|
+
- 重制了辛迪加财务经理职业效果
|
|
5430
|
+
- 下调了警卫员下士转职价格
|
|
5431
|
+
- 新增物品:资源兑换券(可用于兑换咕咕之战资源)
|
|
5432
|
+
- 重制了击败奖励
|
|
5433
|
+
- 重制了赛季奖励
|
|
5434
|
+
- 修改了竞猜项目ID为1的竞猜赔率,并设置了最低投注
|
|
5435
|
+
`.trim()
|
|
5419
5436
|
}
|
|
5420
5437
|
];
|
|
5421
5438
|
function compareVersions(a, b) {
|
|
@@ -6267,7 +6284,8 @@ var GUESSING_ITEMS = [
|
|
|
6267
6284
|
{
|
|
6268
6285
|
id: 1,
|
|
6269
6286
|
description: "猜测下一个复活主宰的名字",
|
|
6270
|
-
odds:
|
|
6287
|
+
odds: 9.5,
|
|
6288
|
+
minBet: 10,
|
|
6271
6289
|
status: "open"
|
|
6272
6290
|
}
|
|
6273
6291
|
// 可以继续添加更多竞猜项目
|
|
@@ -6315,7 +6333,7 @@ async function calculateTotalDamage(ctx, session, config, equippedWeapon, target
|
|
|
6315
6333
|
const otherAdditive = careerAddResult.value + wishAddResult.value + rankAddResult.value;
|
|
6316
6334
|
const otherMultiplier = 1 + otherAdditive;
|
|
6317
6335
|
let finalDamage = baseDamage * tagMultiplier * modMultiplier * otherMultiplier;
|
|
6318
|
-
const { hasCrit, critSources } = await calculateCrit(ctx, handle, equippedWeapon, weaponName);
|
|
6336
|
+
const { hasCrit, critSources } = await calculateCrit(ctx, handle, equippedWeapon, weaponName, careerData, weaponData.type);
|
|
6319
6337
|
effectMessage.push(...critSources);
|
|
6320
6338
|
finalDamage = Math.max(finalDamage, 1);
|
|
6321
6339
|
return {
|
|
@@ -6326,7 +6344,7 @@ async function calculateTotalDamage(ctx, session, config, equippedWeapon, target
|
|
|
6326
6344
|
};
|
|
6327
6345
|
}
|
|
6328
6346
|
__name(calculateTotalDamage, "calculateTotalDamage");
|
|
6329
|
-
async function calculateCrit(ctx, handle, equippedWeapon, weaponName) {
|
|
6347
|
+
async function calculateCrit(ctx, handle, equippedWeapon, weaponName, careerData, weaponType) {
|
|
6330
6348
|
let critRate = 0;
|
|
6331
6349
|
const pityCounter = equippedWeapon?.pityCounter || 0;
|
|
6332
6350
|
const critSources = [];
|
|
@@ -6342,12 +6360,16 @@ async function calculateCrit(ctx, handle, equippedWeapon, weaponName) {
|
|
|
6342
6360
|
critSources: ["🔫 MK-4激光步枪:保底暴击"]
|
|
6343
6361
|
};
|
|
6344
6362
|
}
|
|
6345
|
-
if (equippedWeapon.installedMods?.includes("棱镜超载核心") && modConfig["棱镜超载核心"]?.exclusiveTo === weaponName && pityCounter >=
|
|
6363
|
+
if (equippedWeapon.installedMods?.includes("棱镜超载核心") && modConfig["棱镜超载核心"]?.exclusiveTo === weaponName && pityCounter >= 3) {
|
|
6346
6364
|
return {
|
|
6347
6365
|
hasCrit: true,
|
|
6348
6366
|
critSources: ["⚙️ 【棱镜超载核心】:保底暴击"]
|
|
6349
6367
|
};
|
|
6350
6368
|
}
|
|
6369
|
+
if (careerData?.career === "能量武器专家" && weaponType === "能量武器") {
|
|
6370
|
+
critRate += 10;
|
|
6371
|
+
critSources.push("⚔️ 能量武器专家职业:能量武器暴击率+10%");
|
|
6372
|
+
}
|
|
6351
6373
|
if (equippedWeapon.installedMods?.includes("棱镜水晶")) {
|
|
6352
6374
|
critRate += 10;
|
|
6353
6375
|
critSources.push("⚙️ 【棱镜水晶】:暴击率+10%");
|
|
@@ -6520,31 +6542,6 @@ async function getCleanerRewardBroadcast(ctx, boss, killerHandle, killerName) {
|
|
|
6520
6542
|
const bossType = boss.type;
|
|
6521
6543
|
const bossName = boss.name;
|
|
6522
6544
|
const broadcastMessages = [];
|
|
6523
|
-
let cleanerBaseReward = 0;
|
|
6524
|
-
if (["巢穴雷兽", "巢穴战士", "巢穴甲虫"].includes(bossName)) {
|
|
6525
|
-
cleanerBaseReward = 2;
|
|
6526
|
-
} else {
|
|
6527
|
-
cleanerBaseReward = bossType === "主宰" ? 10 : 5;
|
|
6528
|
-
}
|
|
6529
|
-
const allCleaners = await ctx.database.get("ggcevo_careers", {
|
|
6530
|
-
career: "清洁工"
|
|
6531
|
-
});
|
|
6532
|
-
let cleanerKillerBonus = false;
|
|
6533
|
-
if (allCleaners.length > 0) {
|
|
6534
|
-
for (const cleaner of allCleaners) {
|
|
6535
|
-
let rewardAmount = cleanerBaseReward;
|
|
6536
|
-
if (cleaner.handle === killerHandle) {
|
|
6537
|
-
rewardAmount *= 2;
|
|
6538
|
-
cleanerKillerBonus = true;
|
|
6539
|
-
}
|
|
6540
|
-
await ctx.database.upsert("ggcevo_careers", [{
|
|
6541
|
-
handle: cleaner.handle,
|
|
6542
|
-
redcrystal: (cleaner.redcrystal || 0) + rewardAmount
|
|
6543
|
-
}], ["handle"]);
|
|
6544
|
-
}
|
|
6545
|
-
const cleanerMessage = `🧹 清洁工职业因清理 ${bossName} 尸体,获得 ${cleanerBaseReward} 红晶${cleanerKillerBonus ? ` (击败者 ${killerName} 获得双倍奖励)` : ""}`;
|
|
6546
|
-
broadcastMessages.push(cleanerMessage);
|
|
6547
|
-
}
|
|
6548
6545
|
let guardBaseReward = 0;
|
|
6549
6546
|
if (["巢穴雷兽", "巢穴战士", "巢穴甲虫"].includes(bossName)) {
|
|
6550
6547
|
guardBaseReward = 200;
|
|
@@ -6591,11 +6588,6 @@ async function handleBossDefeatRewards(ctx, targetBoss) {
|
|
|
6591
6588
|
return { rewardMessages };
|
|
6592
6589
|
}
|
|
6593
6590
|
const handles = damageRecords.map((r) => r.handle);
|
|
6594
|
-
const careerData = await ctx.database.get("ggcevo_careers", {
|
|
6595
|
-
handle: { $in: handles }
|
|
6596
|
-
});
|
|
6597
|
-
const groupMap = new Map(careerData.map((c) => [c.handle, c.group]));
|
|
6598
|
-
const pirateRedcrystalRewards = /* @__PURE__ */ new Map();
|
|
6599
6591
|
const doubleWishRecords = await ctx.database.get("ggcevo_wish", {
|
|
6600
6592
|
handle: { $in: handles },
|
|
6601
6593
|
wishname: "精灵双倍",
|
|
@@ -6605,127 +6597,83 @@ async function handleBossDefeatRewards(ctx, targetBoss) {
|
|
|
6605
6597
|
});
|
|
6606
6598
|
const doubleWishIds = doubleWishRecords.map((r) => r.id);
|
|
6607
6599
|
const doubleWishHandles = new Set(doubleWishRecords.map((r) => r.handle));
|
|
6608
|
-
const
|
|
6609
|
-
|
|
6600
|
+
const allRankRewards = [];
|
|
6601
|
+
damageRecords.forEach((record, index) => {
|
|
6610
6602
|
const rank = index + 1;
|
|
6611
|
-
let
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
|
|
6615
|
-
|
|
6616
|
-
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
gold = 2500;
|
|
6620
|
-
break;
|
|
6621
|
-
case rank === 3:
|
|
6622
|
-
guguCoins = 20;
|
|
6623
|
-
gold = 2e3;
|
|
6624
|
-
break;
|
|
6625
|
-
case rank <= 10:
|
|
6626
|
-
guguCoins = 15;
|
|
6627
|
-
gold = 1500;
|
|
6628
|
-
break;
|
|
6629
|
-
}
|
|
6603
|
+
let coupons = 0;
|
|
6604
|
+
if (rank === 1) coupons = 50;
|
|
6605
|
+
else if (rank === 2) coupons = 45;
|
|
6606
|
+
else if (rank === 3) coupons = 40;
|
|
6607
|
+
else if (rank <= 10) coupons = 30;
|
|
6608
|
+
else if (rank <= 20) coupons = 20;
|
|
6609
|
+
else if (rank <= 50) coupons = 10;
|
|
6610
|
+
else coupons = 5;
|
|
6630
6611
|
const hasDoubleWish = doubleWishHandles.has(record.handle);
|
|
6631
6612
|
if (hasDoubleWish) {
|
|
6632
|
-
|
|
6633
|
-
gold *= 2;
|
|
6613
|
+
coupons *= 2;
|
|
6634
6614
|
}
|
|
6635
6615
|
const reward = {
|
|
6636
|
-
|
|
6637
|
-
gold,
|
|
6616
|
+
coupons,
|
|
6638
6617
|
playerName: record.playerName,
|
|
6618
|
+
rank,
|
|
6639
6619
|
hasDoubleWish
|
|
6640
6620
|
};
|
|
6641
6621
|
rewardMap.set(record.handle, reward);
|
|
6642
|
-
|
|
6622
|
+
allRankRewards.push(reward);
|
|
6623
|
+
});
|
|
6624
|
+
allRankRewards.slice(0, 20).forEach((reward) => {
|
|
6625
|
+
const bonusNote = reward.hasDoubleWish ? " (🧝♀ 精灵双倍生效)" : "";
|
|
6643
6626
|
rewardMessages.push(
|
|
6644
|
-
`${rank}. ${
|
|
6645
|
-
` 获得奖励: ${guguCoins} 咕咕币 + ${gold} 金币${bonusNote}`
|
|
6627
|
+
`${reward.rank}. ${reward.playerName} 获得 ${reward.coupons} 资源兑换券${bonusNote}`
|
|
6646
6628
|
);
|
|
6647
|
-
const group = groupMap.get(record.handle);
|
|
6648
|
-
if (group === "辛迪加海盗") {
|
|
6649
|
-
let redcrystal = 0;
|
|
6650
|
-
if (rank === 1) redcrystal = 30;
|
|
6651
|
-
else if (rank === 2) redcrystal = 25;
|
|
6652
|
-
else if (rank === 3) redcrystal = 20;
|
|
6653
|
-
else if (rank <= 10) redcrystal = 15;
|
|
6654
|
-
else if (rank <= 20) redcrystal = 10;
|
|
6655
|
-
pirateRedcrystalRewards.set(record.handle, redcrystal);
|
|
6656
|
-
rewardMessages.push(` 辛迪加海盗奖励: ${redcrystal} 红晶`);
|
|
6657
|
-
}
|
|
6658
6629
|
});
|
|
6659
|
-
const
|
|
6660
|
-
|
|
6661
|
-
|
|
6662
|
-
|
|
6663
|
-
|
|
6664
|
-
|
|
6665
|
-
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
|
|
6670
|
-
|
|
6671
|
-
|
|
6672
|
-
|
|
6673
|
-
|
|
6674
|
-
});
|
|
6675
|
-
}
|
|
6676
|
-
const group = groupMap.get(record.handle);
|
|
6677
|
-
if (group === "辛迪加海盗") {
|
|
6678
|
-
const redcrystal = 3;
|
|
6679
|
-
pirateRedcrystalRewards.set(record.handle, redcrystal);
|
|
6680
|
-
pirateOtherRewards.push({
|
|
6681
|
-
playerName: record.playerName,
|
|
6682
|
-
redcrystal
|
|
6683
|
-
});
|
|
6684
|
-
}
|
|
6685
|
-
rewardMap.set(record.handle, {
|
|
6686
|
-
guguCoins,
|
|
6687
|
-
gold,
|
|
6688
|
-
playerName: record.playerName,
|
|
6689
|
-
hasDoubleWish
|
|
6690
|
-
});
|
|
6691
|
-
});
|
|
6692
|
-
rewardMessages.push(`其他参与者获得基础奖励: 300 金币`);
|
|
6693
|
-
if (doubleWishOthers.length > 0) {
|
|
6694
|
-
rewardMessages.push("🧝♀ 触发精灵双倍祈愿的参与者:");
|
|
6695
|
-
doubleWishOthers.forEach((player) => {
|
|
6696
|
-
rewardMessages.push(
|
|
6697
|
-
` ${player.playerName}: +${player.guguCoins} 咕咕币 +${player.gold} 金币`
|
|
6698
|
-
);
|
|
6699
|
-
});
|
|
6630
|
+
const rank21To50 = allRankRewards.slice(20, 50);
|
|
6631
|
+
if (rank21To50.length > 0) {
|
|
6632
|
+
const totalPlayers = rank21To50.length;
|
|
6633
|
+
const doubleWishCount = rank21To50.filter((p) => p.hasDoubleWish).length;
|
|
6634
|
+
const baseRewardPerPlayer = 10;
|
|
6635
|
+
rewardMessages.push(
|
|
6636
|
+
`21-50名: ${totalPlayers}人`,
|
|
6637
|
+
` 基础奖励: 每人 ${baseRewardPerPlayer} 资源兑换券`
|
|
6638
|
+
);
|
|
6639
|
+
if (doubleWishCount > 0) {
|
|
6640
|
+
rewardMessages.push(
|
|
6641
|
+
` 精灵双倍生效: ${doubleWishCount}人 每人额外获得 ${baseRewardPerPlayer} 资源兑换券`
|
|
6642
|
+
);
|
|
6643
|
+
} else {
|
|
6644
|
+
rewardMessages.push(` (无精灵双倍玩家)`);
|
|
6700
6645
|
}
|
|
6701
6646
|
}
|
|
6702
|
-
|
|
6703
|
-
|
|
6647
|
+
const participants = allRankRewards.slice(50);
|
|
6648
|
+
if (participants.length > 0) {
|
|
6649
|
+
const totalParticipants = participants.length;
|
|
6650
|
+
const doubleWishCount = participants.filter((p) => p.hasDoubleWish).length;
|
|
6651
|
+
const baseRewardPerPlayer = 5;
|
|
6652
|
+
rewardMessages.push(
|
|
6653
|
+
`参与奖: ${totalParticipants}人`,
|
|
6654
|
+
` 基础奖励: 每人 ${baseRewardPerPlayer} 资源兑换券`
|
|
6655
|
+
);
|
|
6656
|
+
if (doubleWishCount > 0) {
|
|
6657
|
+
rewardMessages.push(
|
|
6658
|
+
` 精灵双倍生效: ${doubleWishCount}人 每人额外获得 ${baseRewardPerPlayer} 资源兑换券`
|
|
6659
|
+
);
|
|
6660
|
+
} else {
|
|
6661
|
+
rewardMessages.push(` (无精灵双倍玩家)`);
|
|
6662
|
+
}
|
|
6704
6663
|
}
|
|
6705
6664
|
await ctx.database.withTransaction(async () => {
|
|
6706
6665
|
for (const [handle, reward] of rewardMap) {
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
handle,
|
|
6710
|
-
totalRewards: (signData?.totalRewards || 0) + reward.gold
|
|
6711
|
-
}], ["handle"]);
|
|
6712
|
-
const [backpackData] = await ctx.database.get("ggcevo_backpack", {
|
|
6713
|
-
handle,
|
|
6714
|
-
itemId: 1
|
|
6715
|
-
});
|
|
6716
|
-
await ctx.database.upsert("ggcevo_backpack", [{
|
|
6717
|
-
handle,
|
|
6718
|
-
itemId: 1,
|
|
6719
|
-
quantity: (backpackData?.quantity || 0) + reward.guguCoins
|
|
6720
|
-
}], ["handle", "itemId"]);
|
|
6721
|
-
}
|
|
6722
|
-
for (const [handle, redcrystal] of pirateRedcrystalRewards) {
|
|
6723
|
-
const [career] = await ctx.database.get("ggcevo_careers", { handle });
|
|
6724
|
-
if (career) {
|
|
6725
|
-
await ctx.database.upsert("ggcevo_careers", [{
|
|
6666
|
+
if (reward.coupons > 0) {
|
|
6667
|
+
const [couponData] = await ctx.database.get("ggcevo_backpack", {
|
|
6726
6668
|
handle,
|
|
6727
|
-
|
|
6728
|
-
|
|
6669
|
+
itemId: 8
|
|
6670
|
+
// 资源兑换券ID
|
|
6671
|
+
});
|
|
6672
|
+
await ctx.database.upsert("ggcevo_backpack", [{
|
|
6673
|
+
handle,
|
|
6674
|
+
itemId: 8,
|
|
6675
|
+
quantity: (couponData?.quantity || 0) + reward.coupons
|
|
6676
|
+
}], ["handle", "itemId"]);
|
|
6729
6677
|
}
|
|
6730
6678
|
}
|
|
6731
6679
|
if (doubleWishIds.length > 0) {
|
|
@@ -6949,11 +6897,14 @@ async function calculateRewards(ctx, handle, totalDamage) {
|
|
|
6949
6897
|
const finalReward = Math.round(totalDamage * totalBonusFactor);
|
|
6950
6898
|
let redcrystalMessage = "";
|
|
6951
6899
|
if (career === "清洁工") {
|
|
6900
|
+
const baseRedCrystal = 1;
|
|
6901
|
+
const damageBonus = Math.min(Math.floor(totalDamage / 100), 3);
|
|
6902
|
+
const totalRedCrystal = baseRedCrystal + damageBonus;
|
|
6952
6903
|
await ctx.database.upsert("ggcevo_careers", [{
|
|
6953
6904
|
handle,
|
|
6954
|
-
redcrystal: (careerData?.redcrystal || 0) +
|
|
6905
|
+
redcrystal: (careerData?.redcrystal || 0) + totalRedCrystal
|
|
6955
6906
|
}], ["handle"]);
|
|
6956
|
-
redcrystalMessage =
|
|
6907
|
+
redcrystalMessage = `🔴 清洁工职业:+${totalRedCrystal}枚红晶`;
|
|
6957
6908
|
}
|
|
6958
6909
|
return {
|
|
6959
6910
|
finalReward,
|
|
@@ -7373,10 +7324,12 @@ var Config = import_koishi.Schema.intersect([
|
|
|
7373
7324
|
maxDailyBeChallenged: import_koishi.Schema.number().description("最大被挑战次数(0=无限制)").default(5),
|
|
7374
7325
|
unlimitedBossAttack: import_koishi.Schema.boolean().description("开启无限制PVE攻击").default(false)
|
|
7375
7326
|
}).description("对战限制"),
|
|
7376
|
-
// 通知系统配置组
|
|
7327
|
+
// 通知系统配置组 - 新增违规提醒开关
|
|
7377
7328
|
import_koishi.Schema.object({
|
|
7378
7329
|
groupId: import_koishi.Schema.array(import_koishi.Schema.string()).description("广播通知群组").default([]),
|
|
7379
|
-
checkInterval: import_koishi.Schema.number().description("大厅监控检查间隔(秒)").default(60)
|
|
7330
|
+
checkInterval: import_koishi.Schema.number().description("大厅监控检查间隔(秒)").default(60),
|
|
7331
|
+
enableViolationAlert: import_koishi.Schema.boolean().description("启用违规玩家房间提醒").default(false)
|
|
7332
|
+
// 新增配置项
|
|
7380
7333
|
}).description("通知设置").collapse()
|
|
7381
7334
|
]);
|
|
7382
7335
|
function apply(ctx, config) {
|
|
@@ -7703,7 +7656,7 @@ function apply(ctx, config) {
|
|
|
7703
7656
|
);
|
|
7704
7657
|
const winMessages = [];
|
|
7705
7658
|
for (const winner of winners) {
|
|
7706
|
-
const prize = Math.floor(winner.amount *
|
|
7659
|
+
const prize = Math.floor(winner.amount * 9.5);
|
|
7707
7660
|
const [signInfo] = await ctx.database.get("ggcevo_sign", {
|
|
7708
7661
|
handle: winner.handle
|
|
7709
7662
|
});
|
|
@@ -7820,70 +7773,72 @@ function apply(ctx, config) {
|
|
|
7820
7773
|
}
|
|
7821
7774
|
}, 60 * 60 * 1e3);
|
|
7822
7775
|
ctx.setInterval(async () => {
|
|
7823
|
-
|
|
7824
|
-
|
|
7825
|
-
|
|
7826
|
-
|
|
7827
|
-
|
|
7828
|
-
|
|
7829
|
-
|
|
7830
|
-
|
|
7831
|
-
|
|
7832
|
-
|
|
7833
|
-
|
|
7834
|
-
|
|
7835
|
-
|
|
7836
|
-
|
|
7837
|
-
|
|
7838
|
-
|
|
7839
|
-
|
|
7840
|
-
|
|
7841
|
-
|
|
7842
|
-
|
|
7843
|
-
|
|
7844
|
-
|
|
7845
|
-
|
|
7846
|
-
|
|
7847
|
-
|
|
7848
|
-
const
|
|
7849
|
-
|
|
7850
|
-
|
|
7851
|
-
|
|
7852
|
-
|
|
7853
|
-
|
|
7854
|
-
|
|
7855
|
-
const violators = lobbyPlayers.filter((p) => punishedHandles.has(p.handle));
|
|
7856
|
-
if (violators.length > 0) {
|
|
7857
|
-
const unpunishedPlayersData = lobbyPlayers.filter(
|
|
7858
|
-
(p) => !punishedHandles.has(p.handle)
|
|
7859
|
-
);
|
|
7860
|
-
const queryConditions = unpunishedPlayersData.map((p) => ({
|
|
7861
|
-
regionId: p.regionId,
|
|
7862
|
-
realmId: p.realmId,
|
|
7863
|
-
profileId: p.profileId
|
|
7776
|
+
if (config.enableViolationAlert) {
|
|
7777
|
+
try {
|
|
7778
|
+
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");
|
|
7779
|
+
const data = response.data;
|
|
7780
|
+
const openLobbies = data.results.filter(
|
|
7781
|
+
(lobby) => lobby.status === "open" && !processedLobbies.has(lobby.id)
|
|
7782
|
+
);
|
|
7783
|
+
const allPlayers = openLobbies.flatMap(
|
|
7784
|
+
(lobby) => lobby.slots.filter((slot) => slot.kind === "human" && slot.profile).map((slot) => ({
|
|
7785
|
+
regionId: slot.profile.regionId,
|
|
7786
|
+
realmId: slot.profile.realmId,
|
|
7787
|
+
profileId: slot.profile.profileId,
|
|
7788
|
+
handle: `${slot.profile.regionId}-S2-${slot.profile.realmId}-${slot.profile.profileId}`,
|
|
7789
|
+
name: slot.name
|
|
7790
|
+
// 保留名称用于后续展示
|
|
7791
|
+
}))
|
|
7792
|
+
);
|
|
7793
|
+
const punishmentRecords = await ctx.database.select("ggcevo_punishment").where({
|
|
7794
|
+
$and: [
|
|
7795
|
+
{ handle: { $in: allPlayers.map((p) => p.handle) } },
|
|
7796
|
+
{ id: { $gte: 1889 } },
|
|
7797
|
+
{ level: { $in: ["B", "B+", "A"] } }
|
|
7798
|
+
]
|
|
7799
|
+
}).execute();
|
|
7800
|
+
const punishedHandles = new Set(punishmentRecords.map((r) => r.handle));
|
|
7801
|
+
for (const lobby of openLobbies) {
|
|
7802
|
+
const lobbyPlayers = lobby.slots.filter((slot) => slot.kind === "human" && slot.profile).map((slot) => ({
|
|
7803
|
+
regionId: slot.profile.regionId,
|
|
7804
|
+
realmId: slot.profile.realmId,
|
|
7805
|
+
profileId: slot.profile.profileId,
|
|
7806
|
+
handle: `${slot.profile.regionId}-S2-${slot.profile.realmId}-${slot.profile.profileId}`,
|
|
7807
|
+
name: slot.name
|
|
7864
7808
|
}));
|
|
7865
|
-
const
|
|
7866
|
-
|
|
7867
|
-
|
|
7868
|
-
|
|
7869
|
-
|
|
7870
|
-
|
|
7871
|
-
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
})
|
|
7875
|
-
|
|
7876
|
-
|
|
7877
|
-
|
|
7878
|
-
|
|
7879
|
-
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
|
|
7809
|
+
const violators = lobbyPlayers.filter((p) => punishedHandles.has(p.handle));
|
|
7810
|
+
if (violators.length > 0) {
|
|
7811
|
+
const unpunishedPlayersData = lobbyPlayers.filter(
|
|
7812
|
+
(p) => !punishedHandles.has(p.handle)
|
|
7813
|
+
);
|
|
7814
|
+
const queryConditions = unpunishedPlayersData.map((p) => ({
|
|
7815
|
+
regionId: p.regionId,
|
|
7816
|
+
realmId: p.realmId,
|
|
7817
|
+
profileId: p.profileId
|
|
7818
|
+
}));
|
|
7819
|
+
const safePlayers = await ctx.database.select("sc2arcade_player").where({ $or: queryConditions }).execute().then((res) => res.map((r) => r.userId));
|
|
7820
|
+
const atElements = safePlayers.map((userId) => `<at id="${userId}"/>`).join(" ");
|
|
7821
|
+
const message = [
|
|
7822
|
+
`📺 监测到违规玩家正在房间中!`,
|
|
7823
|
+
`创建时间: ${new Date(lobby.createdAt).toLocaleString("zh-CN")}`,
|
|
7824
|
+
`🚨 违规玩家(${violators.length} 人):`,
|
|
7825
|
+
...violators.map((v) => {
|
|
7826
|
+
const record = punishmentRecords.find((r) => r.handle === v.handle);
|
|
7827
|
+
return `· ${v.name}(${record?.level}级处罚)`;
|
|
7828
|
+
}),
|
|
7829
|
+
`房主: ${lobby.hostName}`,
|
|
7830
|
+
`玩家数: ${lobby.slotsHumansTaken}/${lobby.slotsHumansTotal}`,
|
|
7831
|
+
"──────────────",
|
|
7832
|
+
`请以下玩家通知房主踢人:${atElements || "无"}`
|
|
7833
|
+
].join("\n");
|
|
7834
|
+
const groupId = [...config.groupId];
|
|
7835
|
+
await ctx.broadcast(groupId, message);
|
|
7836
|
+
processedLobbies.add(lobby.id);
|
|
7837
|
+
}
|
|
7883
7838
|
}
|
|
7839
|
+
} catch (error) {
|
|
7840
|
+
ctx.logger.error("监控失败:", error);
|
|
7884
7841
|
}
|
|
7885
|
-
} catch (error) {
|
|
7886
|
-
ctx.logger.error("监控失败:", error);
|
|
7887
7842
|
}
|
|
7888
7843
|
}, config.checkInterval * 1e3);
|
|
7889
7844
|
ctx.setInterval(async () => {
|
|
@@ -8102,22 +8057,8 @@ ${itemDetails.join("\n")}`;
|
|
|
8102
8057
|
const finalTickets = Math.round(baseFinalTickets * multiplier);
|
|
8103
8058
|
let redCrystal = 0;
|
|
8104
8059
|
if (careerData?.group === "辛迪加海盗" && careerData.career === "辛迪加财务经理") {
|
|
8105
|
-
|
|
8106
|
-
|
|
8107
|
-
else if (monthlyDays < 21) redCrystal = 3;
|
|
8108
|
-
else if (monthlyDays < 28) redCrystal = 4;
|
|
8109
|
-
else redCrystal = 5;
|
|
8110
|
-
const crystalStock = careerData.redcrystal || 0;
|
|
8111
|
-
const extraBonus = Math.min(Math.floor(crystalStock / 20), 5);
|
|
8112
|
-
if (extraBonus > 0) {
|
|
8113
|
-
redCrystal += extraBonus;
|
|
8114
|
-
messages.push(
|
|
8115
|
-
`🎖️ 辛迪加财务经理职业:+${redCrystal - extraBonus}枚红晶
|
|
8116
|
-
▸ 红晶储量加成:额外+${extraBonus}枚红晶`
|
|
8117
|
-
);
|
|
8118
|
-
} else {
|
|
8119
|
-
messages.push(`🎖️ 辛迪加财务经理职业:+${redCrystal}枚红晶`);
|
|
8120
|
-
}
|
|
8060
|
+
redCrystal = 5;
|
|
8061
|
+
messages.push("🎖️ 辛迪加财务经理职业:+5枚红晶");
|
|
8121
8062
|
}
|
|
8122
8063
|
await ctx.database.withTransaction(async () => {
|
|
8123
8064
|
await ctx.database.upsert("ggcevo_sign", [{
|
|
@@ -8499,129 +8440,41 @@ ${ticketMessage}${effectMessage}`;
|
|
|
8499
8440
|
sort: { rank: "desc" },
|
|
8500
8441
|
limit: 20
|
|
8501
8442
|
});
|
|
8502
|
-
const allHandles = [...rankedPlayers.map((p) => p.handle)];
|
|
8503
|
-
const careerData = await ctx.database.get("ggcevo_careers", {
|
|
8504
|
-
handle: { $in: allHandles }
|
|
8505
|
-
});
|
|
8506
|
-
const groupMap = new Map(careerData.map((c) => [c.handle, c.group]));
|
|
8507
8443
|
let report = `=== ${currentSeason}赛季结算报告 ===
|
|
8508
8444
|
|
|
8509
8445
|
`;
|
|
8510
8446
|
const playerDetails = [];
|
|
8511
8447
|
let positiveCount = 0;
|
|
8512
8448
|
let negativeCount = 0;
|
|
8513
|
-
let pirateTopPlayers = 0;
|
|
8514
|
-
let piratePositive = 0;
|
|
8515
|
-
let pirateNegative = 0;
|
|
8516
8449
|
for (const [index, player] of rankedPlayers.entries()) {
|
|
8517
8450
|
const rank = index + 1;
|
|
8518
|
-
const
|
|
8519
|
-
|
|
8520
|
-
handle: player.handle,
|
|
8521
|
-
itemId: 1
|
|
8522
|
-
});
|
|
8523
|
-
await ctx.database.upsert("ggcevo_backpack", [{
|
|
8524
|
-
handle: player.handle,
|
|
8525
|
-
itemId: 1,
|
|
8526
|
-
quantity: (backpack?.quantity || 0) + coins
|
|
8527
|
-
}], ["handle", "itemId"]);
|
|
8528
|
-
const [signData] = await ctx.database.get("ggcevo_sign", { handle: player.handle });
|
|
8529
|
-
await ctx.database.upsert("ggcevo_sign", [{
|
|
8530
|
-
handle: player.handle,
|
|
8531
|
-
totalRewards: (signData?.totalRewards || 0) + gold
|
|
8532
|
-
}], ["handle"]);
|
|
8451
|
+
const coins = getCoinsByRank(rank);
|
|
8452
|
+
await updateBackpack(player.handle, 1, coins);
|
|
8533
8453
|
const medalType = getMedalType(rank);
|
|
8534
8454
|
const medalName = requiredMedals[medalType];
|
|
8535
8455
|
const medalId = initDefaultItems[medalName].id;
|
|
8536
|
-
|
|
8537
|
-
|
|
8538
|
-
itemId: medalId
|
|
8539
|
-
});
|
|
8540
|
-
await ctx.database.upsert("ggcevo_backpack", [{
|
|
8541
|
-
handle: player.handle,
|
|
8542
|
-
itemId: medalId,
|
|
8543
|
-
quantity: (medalData?.quantity || 0) + 1
|
|
8544
|
-
}], ["handle", "itemId"]);
|
|
8545
|
-
const group = groupMap.get(player.handle);
|
|
8546
|
-
let playerLine = `✦ 第${rank}名:${player.handle} - ${coins}咕咕币 + ${gold}金币 + ${medalName}`;
|
|
8547
|
-
if (group === "辛迪加海盗") {
|
|
8548
|
-
pirateTopPlayers++;
|
|
8549
|
-
const [career] = await ctx.database.get("ggcevo_careers", { handle: player.handle });
|
|
8550
|
-
if (career) {
|
|
8551
|
-
await ctx.database.upsert("ggcevo_careers", [{
|
|
8552
|
-
handle: player.handle,
|
|
8553
|
-
redcrystal: (career.redcrystal || 0) + redcrystal
|
|
8554
|
-
}], ["handle"]);
|
|
8555
|
-
}
|
|
8556
|
-
playerLine += ` + ${redcrystal}红晶(海盗专属)`;
|
|
8557
|
-
}
|
|
8558
|
-
playerDetails.push(playerLine);
|
|
8456
|
+
await updateBackpack(player.handle, medalId, 1);
|
|
8457
|
+
playerDetails.push(`✦ 第${rank}名:${player.handle} - ${coins}咕咕币 + ${medalName}`);
|
|
8559
8458
|
}
|
|
8560
|
-
report += "🏆
|
|
8561
|
-
report += playerDetails.join("\n") + "\n\n";
|
|
8562
|
-
report += `ℹ️ 辛迪加海盗阵营专属奖励:前20名中共有${pirateTopPlayers}名海盗玩家获得了红晶奖励
|
|
8563
|
-
|
|
8564
|
-
`;
|
|
8459
|
+
report += "🏆 精英玩家奖励:\n" + playerDetails.join("\n") + "\n\n";
|
|
8565
8460
|
const otherPlayers = await ctx.database.get("ggcevo_rank", {
|
|
8566
8461
|
Blacklist: false,
|
|
8567
8462
|
rankseason: currentSeason,
|
|
8568
8463
|
handle: { $nin: rankedPlayers.map((p) => p.handle) }
|
|
8569
8464
|
});
|
|
8570
|
-
const otherHandles = otherPlayers.map((p) => p.handle);
|
|
8571
|
-
const otherCareerData = await ctx.database.get("ggcevo_careers", {
|
|
8572
|
-
handle: { $in: otherHandles }
|
|
8573
|
-
});
|
|
8574
|
-
const otherGroupMap = new Map(otherCareerData.map((c) => [c.handle, c.group]));
|
|
8575
8465
|
for (const player of otherPlayers) {
|
|
8576
8466
|
if (player.rank > 0) {
|
|
8577
8467
|
positiveCount++;
|
|
8578
|
-
|
|
8579
|
-
|
|
8580
|
-
const [signData] = await ctx.database.get("ggcevo_sign", { handle: player.handle });
|
|
8581
|
-
await ctx.database.upsert("ggcevo_sign", [{
|
|
8582
|
-
handle: player.handle,
|
|
8583
|
-
totalRewards: (signData?.totalRewards || 0) + gold
|
|
8584
|
-
}], ["handle"]);
|
|
8585
|
-
const group = otherGroupMap.get(player.handle);
|
|
8586
|
-
if (group === "辛迪加海盗") {
|
|
8587
|
-
piratePositive++;
|
|
8588
|
-
const [career] = await ctx.database.get("ggcevo_careers", { handle: player.handle });
|
|
8589
|
-
if (career) {
|
|
8590
|
-
await ctx.database.upsert("ggcevo_careers", [{
|
|
8591
|
-
handle: player.handle,
|
|
8592
|
-
redcrystal: (career.redcrystal || 0) + redcrystal
|
|
8593
|
-
}], ["handle"]);
|
|
8594
|
-
}
|
|
8595
|
-
}
|
|
8596
|
-
} else if (player.rank <= 0) {
|
|
8468
|
+
await updateBackpack(player.handle, 1, 20);
|
|
8469
|
+
} else {
|
|
8597
8470
|
negativeCount++;
|
|
8598
|
-
|
|
8599
|
-
const redcrystal = 10;
|
|
8600
|
-
const [signData] = await ctx.database.get("ggcevo_sign", { handle: player.handle });
|
|
8601
|
-
await ctx.database.upsert("ggcevo_sign", [{
|
|
8602
|
-
handle: player.handle,
|
|
8603
|
-
totalRewards: (signData?.totalRewards || 0) + gold
|
|
8604
|
-
}], ["handle"]);
|
|
8605
|
-
const group = otherGroupMap.get(player.handle);
|
|
8606
|
-
if (group === "辛迪加海盗") {
|
|
8607
|
-
pirateNegative++;
|
|
8608
|
-
const [career] = await ctx.database.get("ggcevo_careers", { handle: player.handle });
|
|
8609
|
-
if (career) {
|
|
8610
|
-
await ctx.database.upsert("ggcevo_careers", [{
|
|
8611
|
-
handle: player.handle,
|
|
8612
|
-
redcrystal: (career.redcrystal || 0) + redcrystal
|
|
8613
|
-
}], ["handle"]);
|
|
8614
|
-
}
|
|
8615
|
-
}
|
|
8471
|
+
await updateBackpack(player.handle, 1, 10);
|
|
8616
8472
|
}
|
|
8617
8473
|
}
|
|
8618
8474
|
report += "🎉 参与奖励发放:\n";
|
|
8619
|
-
report += `✦ 积极玩家(分数>0):${positiveCount}
|
|
8620
|
-
`;
|
|
8621
|
-
report += `✦ 奋斗玩家(分数≤0):${negativeCount}人,每人获得1000枚金币 + 10红晶(海盗专属)
|
|
8622
|
-
|
|
8475
|
+
report += `✦ 积极玩家(分数>0):${positiveCount}人 × 20咕咕币
|
|
8623
8476
|
`;
|
|
8624
|
-
report +=
|
|
8477
|
+
report += `✦ 奋斗玩家(分数≤0):${negativeCount}人 × 10咕咕币
|
|
8625
8478
|
|
|
8626
8479
|
`;
|
|
8627
8480
|
report += `✅ 总计发放:
|
|
@@ -8630,37 +8483,28 @@ ${ticketMessage}${effectMessage}`;
|
|
|
8630
8483
|
`;
|
|
8631
8484
|
report += `- 参与玩家:${otherPlayers.length}人`;
|
|
8632
8485
|
await session.send(report);
|
|
8633
|
-
|
|
8634
|
-
|
|
8635
|
-
|
|
8636
|
-
|
|
8637
|
-
|
|
8638
|
-
|
|
8639
|
-
|
|
8640
|
-
|
|
8641
|
-
|
|
8642
|
-
|
|
8643
|
-
|
|
8644
|
-
{ coins: 100, gold: 1e4, redcrystal: 100 },
|
|
8645
|
-
// 第1名
|
|
8646
|
-
{ coins: 90, gold: 9e3, redcrystal: 90 },
|
|
8647
|
-
// 第2名
|
|
8648
|
-
{ coins: 80, gold: 8e3, redcrystal: 80 },
|
|
8649
|
-
// 第3名
|
|
8650
|
-
...Array(7).fill({ coins: 60, gold: 6e3, redcrystal: 60 }),
|
|
8651
|
-
// 4-10名
|
|
8652
|
-
...Array(10).fill({ coins: 40, gold: 4e3, redcrystal: 40 })
|
|
8653
|
-
// 11-20名
|
|
8654
|
-
];
|
|
8655
|
-
return rank <= rewards.length ? rewards[rank - 1] : { coins: 0, gold: 0, redcrystal: 0 };
|
|
8486
|
+
return `${currentSeason}赛季结算完成!`;
|
|
8487
|
+
async function updateBackpack(handle, itemId, quantity) {
|
|
8488
|
+
const [item] = await ctx.database.get("ggcevo_backpack", {
|
|
8489
|
+
handle,
|
|
8490
|
+
itemId
|
|
8491
|
+
});
|
|
8492
|
+
await ctx.database.upsert("ggcevo_backpack", [{
|
|
8493
|
+
handle,
|
|
8494
|
+
itemId,
|
|
8495
|
+
quantity: (item?.quantity || 0) + quantity
|
|
8496
|
+
}], ["handle", "itemId"]);
|
|
8656
8497
|
}
|
|
8657
|
-
__name(
|
|
8498
|
+
__name(updateBackpack, "updateBackpack");
|
|
8499
|
+
function getCoinsByRank(rank) {
|
|
8500
|
+
return rank === 1 ? 100 : rank === 2 ? 90 : rank === 3 ? 80 : rank <= 10 ? 60 : 40;
|
|
8501
|
+
}
|
|
8502
|
+
__name(getCoinsByRank, "getCoinsByRank");
|
|
8658
8503
|
function getMedalType(rank) {
|
|
8659
8504
|
if (rank === 1) return "champion";
|
|
8660
8505
|
if (rank === 2) return "runnerUp";
|
|
8661
8506
|
if (rank === 3) return "thirdPlace";
|
|
8662
|
-
|
|
8663
|
-
return "top20";
|
|
8507
|
+
return rank <= 10 ? "top10" : "top20";
|
|
8664
8508
|
}
|
|
8665
8509
|
__name(getMedalType, "getMedalType");
|
|
8666
8510
|
});
|
|
@@ -9873,7 +9717,7 @@ ${discountDetails.join("\n")}`;
|
|
|
9873
9717
|
}));
|
|
9874
9718
|
return [
|
|
9875
9719
|
`🛡️ ${session.username}的武器仓库`,
|
|
9876
|
-
'使用"
|
|
9720
|
+
'使用"装备武器 武器名称"来装备武器',
|
|
9877
9721
|
"⚡表示当前装备武器",
|
|
9878
9722
|
"──────────────",
|
|
9879
9723
|
...weaponDetails.length ? weaponDetails : ["空空如也,快去“武器库”看看吧!"],
|
|
@@ -9882,7 +9726,7 @@ ${discountDetails.join("\n")}`;
|
|
|
9882
9726
|
"🔧 改装效果在战斗中生效"
|
|
9883
9727
|
].join("\n");
|
|
9884
9728
|
});
|
|
9885
|
-
ctx.command("ggcevo
|
|
9729
|
+
ctx.command("ggcevo/装备武器 <weapon>").alias("装备").action(async ({ session }, weapon) => {
|
|
9886
9730
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
9887
9731
|
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
9888
9732
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
@@ -9890,8 +9734,8 @@ ${discountDetails.join("\n")}`;
|
|
|
9890
9734
|
if (existingEntries.length > 0) {
|
|
9891
9735
|
return `⛔ 您已被列入黑名单。`;
|
|
9892
9736
|
}
|
|
9893
|
-
if (!weapon) return "
|
|
9894
|
-
if (!weaponConfig[weapon]) return "
|
|
9737
|
+
if (!weapon) return "请输入“装备武器 武器名称”来装备一把你拥有的武器。";
|
|
9738
|
+
if (!weaponConfig[weapon]) return "武器名称错误,请输入“装备武器 武器名称”来装备一把你拥有的武器。";
|
|
9895
9739
|
const config2 = weaponConfig[weapon];
|
|
9896
9740
|
const [owned] = await ctx.database.get("ggcevo_weapons", {
|
|
9897
9741
|
handle,
|
|
@@ -9933,7 +9777,7 @@ ${discountDetails.join("\n")}`;
|
|
|
9933
9777
|
}
|
|
9934
9778
|
return handleTechUpgrade(ctx, handle, target);
|
|
9935
9779
|
});
|
|
9936
|
-
ctx.command("ggcevo/升级武器 <target>", "
|
|
9780
|
+
ctx.command("ggcevo/升级武器 <target>", "升级武器").alias("升级").action(async ({ session }, target) => {
|
|
9937
9781
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
9938
9782
|
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
9939
9783
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
@@ -12610,23 +12454,24 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
|
|
|
12610
12454
|
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
12611
12455
|
const { regionId, realmId, profileId } = profile;
|
|
12612
12456
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
12457
|
+
const username = session.username;
|
|
12613
12458
|
if ((await ctx.database.get("ggcevo_blacklist", { handle })).length) {
|
|
12614
12459
|
return "⛔ 您已被列入黑名单。";
|
|
12615
12460
|
}
|
|
12616
12461
|
const [signInfo] = await ctx.database.get("ggcevo_sign", { handle });
|
|
12617
12462
|
if (!signInfo) return "⚠️ 账号数据异常,请重试";
|
|
12618
12463
|
const userCoins = signInfo.totalRewards;
|
|
12619
|
-
const username = session.username;
|
|
12620
12464
|
const availableItems = GUESSING_ITEMS.filter((item) => item.status === "open");
|
|
12621
12465
|
if (!itemId) {
|
|
12622
12466
|
return [
|
|
12623
12467
|
"🎯 可参与竞猜项目 🎯",
|
|
12624
12468
|
'使用"竞猜 项目ID 金额 内容"下注',
|
|
12625
|
-
"
|
|
12469
|
+
"=================================",
|
|
12626
12470
|
...availableItems.map(
|
|
12627
|
-
(item) => `▸ [ID
|
|
12471
|
+
(item) => `▸ [ID:${item.id}] ${item.description}
|
|
12472
|
+
赔率: ${item.odds}x | 最低投注: ${item.minBet}金币`
|
|
12628
12473
|
),
|
|
12629
|
-
"
|
|
12474
|
+
"================================="
|
|
12630
12475
|
].join("\n");
|
|
12631
12476
|
}
|
|
12632
12477
|
const parsedItemId = parseInt(itemId);
|
|
@@ -12644,12 +12489,19 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
|
|
|
12644
12489
|
`📋 项目详情 [ID:${parsedItemId}]`,
|
|
12645
12490
|
`描述: ${targetItem.description}`,
|
|
12646
12491
|
`赔率: ${targetItem.odds}x`,
|
|
12492
|
+
`最低投注: ${targetItem.minBet}金币`,
|
|
12647
12493
|
`猜中次数: ${wins} 次`,
|
|
12648
12494
|
`您的状态: ${betInfo}`
|
|
12649
12495
|
].join("\n");
|
|
12650
12496
|
}
|
|
12651
12497
|
if (!amount) return "⚠️ 请输入下注金额";
|
|
12652
12498
|
if (!guess) return "⚠️ 请填写竞猜内容";
|
|
12499
|
+
const betAmount = parseInt(amount);
|
|
12500
|
+
if (isNaN(betAmount) || betAmount < 1) return "⚠️ 请输入有效金额";
|
|
12501
|
+
if (betAmount < targetItem.minBet) {
|
|
12502
|
+
return `⚠️ 下注金额必须≥${targetItem.minBet}金币 (当前项目最低投注)`;
|
|
12503
|
+
}
|
|
12504
|
+
if (betAmount > userCoins) return `⚠️ 金币不足,当前账户只有 ${userCoins} 金币`;
|
|
12653
12505
|
const [existingBet] = await ctx.database.get("ggcevo_guess", {
|
|
12654
12506
|
handle,
|
|
12655
12507
|
itemId: parsedItemId,
|
|
@@ -12661,9 +12513,6 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
|
|
|
12661
12513
|
当前下注内容: ${existingBet.guessContent}
|
|
12662
12514
|
当前下注金额: ${existingBet.amount}金币`;
|
|
12663
12515
|
}
|
|
12664
|
-
const betAmount = parseInt(amount);
|
|
12665
|
-
if (isNaN(betAmount) || betAmount < 1) return "⚠️ 请输入有效金额";
|
|
12666
|
-
if (betAmount > userCoins) return `⚠️ 金币不足,当前账户只有 ${userCoins} 金币`;
|
|
12667
12516
|
const validBossNames = bossPool.map((pool) => pool.main.name);
|
|
12668
12517
|
if (!validBossNames.includes(guess)) {
|
|
12669
12518
|
return `⚠️ 无效的主宰名字,可用选项:
|
|
@@ -12709,11 +12558,7 @@ ${validBossNames.join("、")}`;
|
|
|
12709
12558
|
每天获得50-100金币
|
|
12710
12559
|
--------------
|
|
12711
12560
|
签到红晶奖励(辛迪加财务经理职业加成):
|
|
12712
|
-
|
|
12713
|
-
第7-13天每天获得2枚红晶
|
|
12714
|
-
第14-20天每天获得3枚红晶
|
|
12715
|
-
第21-27天每天获得4枚红晶
|
|
12716
|
-
第28天及以后每天获得5枚红晶
|
|
12561
|
+
每天签到获得5枚红晶
|
|
12717
12562
|
--------------
|
|
12718
12563
|
注意:补签只能获得咕咕币
|
|
12719
12564
|
`.trim();
|
|
@@ -12771,36 +12616,26 @@ PK同玩家限战:1次/日
|
|
|
12771
12616
|
🌟 异形主宰击败奖励规则 🌟
|
|
12772
12617
|
🏆 前20名奖励(按伤害排名):
|
|
12773
12618
|
1️⃣ 第1名:
|
|
12774
|
-
|
|
12619
|
+
50 资源兑换券
|
|
12775
12620
|
2️⃣ 第2名:
|
|
12776
|
-
|
|
12621
|
+
45 资源兑换券
|
|
12777
12622
|
3️⃣ 第3名:
|
|
12778
|
-
|
|
12623
|
+
40 资源兑换券
|
|
12779
12624
|
🎖️ 第4-10名:
|
|
12780
|
-
|
|
12625
|
+
30 资源兑换券
|
|
12781
12626
|
💫 第11-20名:
|
|
12782
|
-
|
|
12627
|
+
20 资源兑换券
|
|
12628
|
+
💫 第21-50名:
|
|
12629
|
+
10 资源兑换券
|
|
12783
12630
|
💝 其他参与者:
|
|
12784
|
-
|
|
12785
|
-
|
|
12786
|
-
|
|
12787
|
-
|
|
12788
|
-
🧹 清洁工职业加成:
|
|
12789
|
-
当子代被击败时,清理尸体获得 5 红晶
|
|
12790
|
-
当主宰被击败时,清理尸体获得 10 红晶
|
|
12791
|
-
若击败者(最后一击)为清洁工,则其获得双倍红晶奖励
|
|
12792
|
-
|
|
12793
|
-
|
|
12794
|
-
🌈 精灵双倍祈愿:
|
|
12795
|
-
生效时金币和咕咕币奖励翻倍
|
|
12796
|
-
(需要祈愿有效期内+首次使用)
|
|
12631
|
+
5 资源兑换券
|
|
12632
|
+
|
|
12633
|
+
🌈 精灵双倍祈愿生效期间,获得双倍的资源兑换券
|
|
12797
12634
|
|
|
12798
12635
|
💡 特殊说明:
|
|
12799
12636
|
1. 奖励自动发放到账户,无需手动领取
|
|
12800
|
-
2.
|
|
12801
|
-
3.
|
|
12802
|
-
4. 排名根据实际造成伤害计算
|
|
12803
|
-
5. 红晶 = 辛迪加海盗阵营货币,用途广泛
|
|
12637
|
+
2. 精灵双倍祈愿可通过“祈愿”指令概率获得
|
|
12638
|
+
3. 排名根据实际造成伤害计算
|
|
12804
12639
|
`.trim();
|
|
12805
12640
|
});
|
|
12806
12641
|
ctx.command("ggcevo/祈愿系统").action(({}) => {
|
|
@@ -12817,7 +12652,7 @@ PK同玩家限战:1次/日
|
|
|
12817
12652
|
|
|
12818
12653
|
🔮 稀有祈愿池(5%概率)
|
|
12819
12654
|
🗡️ 悲鸣之锋:攻击伤害提高10%,武器每等级提高5%伤害
|
|
12820
|
-
🧚
|
|
12655
|
+
🧚 精灵双倍:下一次击败主宰时可获得双倍的资源兑换券
|
|
12821
12656
|
🐾 喵喵财源:签到获得双倍的金币和咕咕币
|
|
12822
12657
|
🎵 暴击韵律:攻击暴击率提高20%
|
|
12823
12658
|
⚠️ 酥手空空:立即失去50枚金币(可触发彩蛋)
|
|
@@ -12827,20 +12662,18 @@ PK同玩家限战:1次/日
|
|
|
12827
12662
|
return `
|
|
12828
12663
|
🏆 赛季排名奖励规则:
|
|
12829
12664
|
🥇 第1名:
|
|
12830
|
-
100 咕咕币 +
|
|
12665
|
+
100 咕咕币 + 🥇 赛季冠军勋章
|
|
12831
12666
|
🥈 第2名:
|
|
12832
|
-
90 咕咕币 +
|
|
12667
|
+
90 咕咕币 + 🥈 赛季亚军勋章
|
|
12833
12668
|
🥉 第3名:
|
|
12834
|
-
80 咕咕币 +
|
|
12669
|
+
80 咕咕币 + 🥉 赛季季军勋章
|
|
12835
12670
|
🏅 第4-10名:
|
|
12836
|
-
60 咕咕币 +
|
|
12671
|
+
60 咕咕币 + 🏅 赛季前十勋章
|
|
12837
12672
|
🎖 第11-20名:
|
|
12838
|
-
40 咕咕币 +
|
|
12673
|
+
40 咕咕币 + 🎖 赛季前二十勋章
|
|
12839
12674
|
💝 参与奖励:
|
|
12840
|
-
▸ 所有积分 > 0 玩家:
|
|
12841
|
-
▸ 所有积分 ≤ 0 玩家:
|
|
12842
|
-
(不包含前20名已获得奖励玩家)
|
|
12843
|
-
注意:红晶只有辛迪加海盗阵营能获得
|
|
12675
|
+
▸ 所有积分 > 0 玩家:20 咕咕币
|
|
12676
|
+
▸ 所有积分 ≤ 0 玩家:10 咕咕币
|
|
12844
12677
|
|
|
12845
12678
|
📦 勋章系统:
|
|
12846
12679
|
● 每个勋章对应专属成就
|
|
@@ -12850,7 +12683,7 @@ PK同玩家限战:1次/日
|
|
|
12850
12683
|
📌 重要说明:
|
|
12851
12684
|
1. 结算后自动发放所有奖励
|
|
12852
12685
|
2. 勋章可通过背包查看
|
|
12853
|
-
3.
|
|
12686
|
+
3. 每个赛季2个月
|
|
12854
12687
|
`.trim();
|
|
12855
12688
|
});
|
|
12856
12689
|
}
|
package/lib/items.d.ts
CHANGED
|
@@ -126,6 +126,11 @@ export declare const initDefaultItems: {
|
|
|
126
126
|
type: string;
|
|
127
127
|
description: string;
|
|
128
128
|
};
|
|
129
|
+
资源兑换券: {
|
|
130
|
+
id: number;
|
|
131
|
+
type: string;
|
|
132
|
+
description: string;
|
|
133
|
+
};
|
|
129
134
|
'\uD83E\uDD47\u5148\u884C\u8005\u8D5B\u5B63\u51A0\u519B\u52CB\u7AE0': {
|
|
130
135
|
id: number;
|
|
131
136
|
type: string;
|
package/lib/utils.d.ts
CHANGED