koishi-plugin-ggcevo-game 1.4.44 → 1.4.46
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/boss/BattleEffectProcessor.d.ts +4 -2
- package/lib/database.d.ts +14 -0
- package/lib/index.js +271 -54
- package/lib/utils.d.ts +3 -0
- package/package.json +1 -1
|
@@ -340,9 +340,12 @@ export declare const BattleEffectProcessor: {
|
|
|
340
340
|
updates: Partial<BattleStatistics>;
|
|
341
341
|
} | null;
|
|
342
342
|
} | null;
|
|
343
|
-
/** 天启超载护盾处理(层数相关群体回复) */
|
|
344
343
|
handleOverdriveShield: (targetBoss: any, activeBosses: any[]) => {
|
|
345
344
|
messages: string[];
|
|
345
|
+
targetUpdates: {
|
|
346
|
+
name: string;
|
|
347
|
+
updates: Partial<BattleStatistics>;
|
|
348
|
+
} | null;
|
|
346
349
|
otherUpdates: Array<{
|
|
347
350
|
name: string;
|
|
348
351
|
updates: Partial<BattleStatistics>;
|
|
@@ -362,7 +365,6 @@ export declare const BattleEffectProcessor: {
|
|
|
362
365
|
messages: string[];
|
|
363
366
|
tempMark: boolean;
|
|
364
367
|
};
|
|
365
|
-
/** 轰炸引导处理(层数相关能量回复) */
|
|
366
368
|
handleBombardmentGuide: (targetBoss: any) => {
|
|
367
369
|
messages: string[];
|
|
368
370
|
targetUpdates: {
|
package/lib/database.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ declare module 'koishi' {
|
|
|
22
22
|
ggcevo_Mining: MiningRecord;
|
|
23
23
|
ggcevo_task: TaskProgress;
|
|
24
24
|
ggcevo_permissions: Permissions;
|
|
25
|
+
ggcevo_pk_protection: PKProtection;
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
28
|
export interface Backpack {
|
|
@@ -186,3 +187,16 @@ export interface Permissions {
|
|
|
186
187
|
legendarypermissions: number;
|
|
187
188
|
explosiondoorauthority: number;
|
|
188
189
|
}
|
|
190
|
+
export interface PKProtection {
|
|
191
|
+
id: number;
|
|
192
|
+
handle: string;
|
|
193
|
+
startTime: Date;
|
|
194
|
+
endTime: Date;
|
|
195
|
+
/**
|
|
196
|
+
* 保护状态(建议添加)
|
|
197
|
+
* active - 保护中
|
|
198
|
+
* expired - 已过期
|
|
199
|
+
* canceled - 手动取消
|
|
200
|
+
*/
|
|
201
|
+
status: 'active' | 'expired' | 'canceled';
|
|
202
|
+
}
|
package/lib/index.js
CHANGED
|
@@ -1458,11 +1458,11 @@ var passiveConfig = {
|
|
|
1458
1458
|
},
|
|
1459
1459
|
"灵能构造炉": {
|
|
1460
1460
|
type: "状态获得(技能获得)",
|
|
1461
|
-
description: "受击时
|
|
1461
|
+
description: "受击时1%概率随机获得以下技能之一:天启超载护盾/塌缩脉冲/地毯式轰炸/轰炸引导"
|
|
1462
1462
|
},
|
|
1463
1463
|
"天启超载护盾": {
|
|
1464
1464
|
type: "生存强化(生命回复)",
|
|
1465
|
-
description: "受击时10
|
|
1465
|
+
description: "受击时10%概率触发,消耗当前「光影之刃」层数的一半(向下取整),并为所有存活异形回复(消耗层数×10)点生命"
|
|
1466
1466
|
},
|
|
1467
1467
|
"塌缩脉冲": {
|
|
1468
1468
|
type: "状态叠加(层数叠加)",
|
|
@@ -1470,11 +1470,11 @@ var passiveConfig = {
|
|
|
1470
1470
|
},
|
|
1471
1471
|
"地毯式轰炸": {
|
|
1472
1472
|
type: "状态移除+伤害增减(正面)",
|
|
1473
|
-
description: "移除孤立无援状态,受到的伤害降低
|
|
1473
|
+
description: "移除孤立无援状态,受到的伤害降低80%"
|
|
1474
1474
|
},
|
|
1475
1475
|
"轰炸引导": {
|
|
1476
1476
|
type: "生存强化(能量回复)",
|
|
1477
|
-
description: "受击时10
|
|
1477
|
+
description: "受击时10%概率触发,消耗当前「光影之刃」层数的一半(向下取整),并回复(消耗层数×10)点能量"
|
|
1478
1478
|
}
|
|
1479
1479
|
};
|
|
1480
1480
|
|
|
@@ -2390,6 +2390,21 @@ async function getRankInfo(ctx, config, handle) {
|
|
|
2390
2390
|
------------------------------`;
|
|
2391
2391
|
}
|
|
2392
2392
|
__name(getRankInfo, "getRankInfo");
|
|
2393
|
+
function isWithinProtection(protections) {
|
|
2394
|
+
const now = /* @__PURE__ */ new Date();
|
|
2395
|
+
return protections.some(
|
|
2396
|
+
(p) => p.status === "active" && now >= p.startTime && now <= p.endTime
|
|
2397
|
+
);
|
|
2398
|
+
}
|
|
2399
|
+
__name(isWithinProtection, "isWithinProtection");
|
|
2400
|
+
function formatTime(date) {
|
|
2401
|
+
return date.toLocaleString("zh-CN", {
|
|
2402
|
+
year: "numeric",
|
|
2403
|
+
month: "2-digit",
|
|
2404
|
+
day: "2-digit"
|
|
2405
|
+
});
|
|
2406
|
+
}
|
|
2407
|
+
__name(formatTime, "formatTime");
|
|
2393
2408
|
|
|
2394
2409
|
// src/boss/BattleEffectProcessor.ts
|
|
2395
2410
|
var battleStatsMap = {};
|
|
@@ -3699,7 +3714,7 @@ var BattleEffectProcessor = {
|
|
|
3699
3714
|
if (!targetBoss.skills.includes("灵能构造炉")) {
|
|
3700
3715
|
return null;
|
|
3701
3716
|
}
|
|
3702
|
-
const baseProbability = 0.
|
|
3717
|
+
const baseProbability = 0.01;
|
|
3703
3718
|
if (Math.random() >= baseProbability) {
|
|
3704
3719
|
return null;
|
|
3705
3720
|
}
|
|
@@ -3723,7 +3738,7 @@ var BattleEffectProcessor = {
|
|
|
3723
3738
|
targetUpdates
|
|
3724
3739
|
};
|
|
3725
3740
|
}, "handlePsychicForge"),
|
|
3726
|
-
|
|
3741
|
+
// 修改后的天启超载护盾处理函数
|
|
3727
3742
|
handleOverdriveShield: /* @__PURE__ */ __name(function(targetBoss, activeBosses) {
|
|
3728
3743
|
const messages = [];
|
|
3729
3744
|
const otherUpdates = [];
|
|
@@ -3733,20 +3748,31 @@ var BattleEffectProcessor = {
|
|
|
3733
3748
|
if (Math.random() >= 0.1) {
|
|
3734
3749
|
return null;
|
|
3735
3750
|
}
|
|
3736
|
-
const
|
|
3751
|
+
const currentStacks = targetBoss.skillStacks || 0;
|
|
3752
|
+
const consumedStacks = Math.floor(currentStacks / 2);
|
|
3753
|
+
if (consumedStacks <= 0) {
|
|
3754
|
+
return null;
|
|
3755
|
+
}
|
|
3737
3756
|
const survivingBosses = activeBosses.filter((boss) => boss.isActive);
|
|
3757
|
+
messages.push(`🛡️ 【天启超载护盾】触发:消耗${consumedStacks}层「光影之刃」`);
|
|
3738
3758
|
survivingBosses.forEach((boss) => {
|
|
3739
|
-
const
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
}
|
|
3746
|
-
messages.push(`🛡️ 【天启超载护盾】触发:为「${bossName}」回复${baseHealAmount}点生命值`);
|
|
3759
|
+
const healAmount = consumedStacks * 10;
|
|
3760
|
+
otherUpdates.push({
|
|
3761
|
+
name: boss.name,
|
|
3762
|
+
updates: { hpChange: healAmount }
|
|
3763
|
+
});
|
|
3764
|
+
messages.push(`为「${boss.name}」回复${healAmount}点生命值`);
|
|
3747
3765
|
});
|
|
3766
|
+
const targetUpdates = {
|
|
3767
|
+
name: targetBoss.name,
|
|
3768
|
+
updates: {
|
|
3769
|
+
skillStacksChanged: -consumedStacks
|
|
3770
|
+
// 消耗层数
|
|
3771
|
+
}
|
|
3772
|
+
};
|
|
3748
3773
|
return {
|
|
3749
3774
|
messages,
|
|
3775
|
+
targetUpdates,
|
|
3750
3776
|
otherUpdates
|
|
3751
3777
|
};
|
|
3752
3778
|
}, "handleOverdriveShield"),
|
|
@@ -3782,14 +3808,13 @@ var BattleEffectProcessor = {
|
|
|
3782
3808
|
if (!targetBoss.skills.includes("地毯式轰炸")) {
|
|
3783
3809
|
return null;
|
|
3784
3810
|
}
|
|
3785
|
-
nerfMultiplier =
|
|
3786
|
-
messages.push(`💣 【地毯式轰炸】生效:受到的伤害-
|
|
3811
|
+
nerfMultiplier = 0.8;
|
|
3812
|
+
messages.push(`💣 【地毯式轰炸】生效:受到的伤害-80%`);
|
|
3787
3813
|
return { nerfMultiplier, messages, tempMark: true };
|
|
3788
3814
|
}, "handleCarpetBombing"),
|
|
3789
|
-
|
|
3815
|
+
// 修改后的轰炸引导处理函数
|
|
3790
3816
|
handleBombardmentGuide: /* @__PURE__ */ __name(function(targetBoss) {
|
|
3791
3817
|
const messages = [];
|
|
3792
|
-
let targetUpdates = null;
|
|
3793
3818
|
if (!targetBoss.skills.includes("轰炸引导")) {
|
|
3794
3819
|
return null;
|
|
3795
3820
|
}
|
|
@@ -3797,14 +3822,21 @@ var BattleEffectProcessor = {
|
|
|
3797
3822
|
return null;
|
|
3798
3823
|
}
|
|
3799
3824
|
const currentStacks = targetBoss.skillStacks || 0;
|
|
3800
|
-
const
|
|
3801
|
-
|
|
3825
|
+
const consumedStacks = Math.floor(currentStacks / 2);
|
|
3826
|
+
if (consumedStacks <= 0) {
|
|
3827
|
+
return null;
|
|
3828
|
+
}
|
|
3829
|
+
const energyGained = consumedStacks * 10;
|
|
3830
|
+
const targetUpdates = {
|
|
3802
3831
|
name: targetBoss.name,
|
|
3803
3832
|
updates: {
|
|
3833
|
+
skillStacksChanged: -consumedStacks,
|
|
3834
|
+
// 消耗层数
|
|
3804
3835
|
energyChange: energyGained
|
|
3836
|
+
// 回复能量
|
|
3805
3837
|
}
|
|
3806
3838
|
};
|
|
3807
|
-
messages.push(`🎯
|
|
3839
|
+
messages.push(`🎯 【轰炸引导】触发:消耗${consumedStacks}层「光影之刃」,获得${energyGained}点能量`);
|
|
3808
3840
|
return {
|
|
3809
3841
|
messages,
|
|
3810
3842
|
targetUpdates
|
|
@@ -5052,6 +5084,16 @@ function apply(ctx, config) {
|
|
|
5052
5084
|
}, {
|
|
5053
5085
|
primary: "handle"
|
|
5054
5086
|
});
|
|
5087
|
+
ctx.model.extend("ggcevo_pk_protection", {
|
|
5088
|
+
id: "unsigned",
|
|
5089
|
+
handle: "string",
|
|
5090
|
+
startTime: "timestamp",
|
|
5091
|
+
endTime: "timestamp",
|
|
5092
|
+
status: "string"
|
|
5093
|
+
}, {
|
|
5094
|
+
primary: "id",
|
|
5095
|
+
autoInc: true
|
|
5096
|
+
});
|
|
5055
5097
|
ctx.setInterval(async () => {
|
|
5056
5098
|
const totalBosses = await ctx.database.select("ggcevo_boss").execute((row) => import_koishi.$.count(row.name));
|
|
5057
5099
|
const groupId = [...config.groupId];
|
|
@@ -5226,6 +5268,15 @@ function apply(ctx, config) {
|
|
|
5226
5268
|
ctx.logger.error("监控失败:", error);
|
|
5227
5269
|
}
|
|
5228
5270
|
}, config.checkInterval * 1e3);
|
|
5271
|
+
ctx.setInterval(async () => {
|
|
5272
|
+
const now = /* @__PURE__ */ new Date();
|
|
5273
|
+
await ctx.database.set("ggcevo_pk_protection", {
|
|
5274
|
+
endTime: { $lt: now },
|
|
5275
|
+
status: "active"
|
|
5276
|
+
}, {
|
|
5277
|
+
status: "expired"
|
|
5278
|
+
});
|
|
5279
|
+
}, 24 * 60 * 60 * 1e3);
|
|
5229
5280
|
ctx.command("ggcevo/抽奖").action(async (argv) => {
|
|
5230
5281
|
const session = argv.session;
|
|
5231
5282
|
let winCount = 0;
|
|
@@ -6416,6 +6467,38 @@ ${items.join("、")}
|
|
|
6416
6467
|
if (!targetCareer?.group || !validGroups.has(targetCareer.group)) {
|
|
6417
6468
|
return "❌ 对方尚未加入人类联盟或辛迪加海盗,不能参与PK";
|
|
6418
6469
|
}
|
|
6470
|
+
const targetProtections = await ctx.database.get("ggcevo_pk_protection", {
|
|
6471
|
+
handle: targetHandle,
|
|
6472
|
+
status: "active"
|
|
6473
|
+
});
|
|
6474
|
+
if (isWithinProtection(targetProtections)) {
|
|
6475
|
+
const nearestEndTime = targetProtections.reduce(
|
|
6476
|
+
(max, p) => p.endTime > max ? p.endTime : max,
|
|
6477
|
+
/* @__PURE__ */ new Date(0)
|
|
6478
|
+
);
|
|
6479
|
+
return `🛡️ ${targetRankname}正处于PK保护期(至 ${nearestEndTime.toLocaleString("zh-CN")}),无法挑战`;
|
|
6480
|
+
}
|
|
6481
|
+
const initiatorProtections = await ctx.database.get("ggcevo_pk_protection", {
|
|
6482
|
+
handle: initiatorHandle,
|
|
6483
|
+
status: "active"
|
|
6484
|
+
});
|
|
6485
|
+
let hasProtection = isWithinProtection(initiatorProtections);
|
|
6486
|
+
if (hasProtection) {
|
|
6487
|
+
const protectionList = initiatorProtections.filter((p) => /* @__PURE__ */ new Date() < p.endTime).map((p) => `🛡️ ID:${p.id} ${formatTime(p.startTime)} ~ ${formatTime(p.endTime)}`).join("\n");
|
|
6488
|
+
await session.send(`⚠️ 您正处于PK保护期:
|
|
6489
|
+
${protectionList}
|
|
6490
|
+
|
|
6491
|
+
发起PK将自动解除保护,确认继续?
|
|
6492
|
+
回复"是"继续PK,或回复其他内容退出`);
|
|
6493
|
+
const confirm = await session.prompt(3e4);
|
|
6494
|
+
if (confirm !== "是") return "已取消PK操作,保护期仍有效。";
|
|
6495
|
+
await ctx.database.set("ggcevo_pk_protection", {
|
|
6496
|
+
handle: initiatorHandle
|
|
6497
|
+
}, {
|
|
6498
|
+
status: "canceled"
|
|
6499
|
+
});
|
|
6500
|
+
hasProtection = false;
|
|
6501
|
+
}
|
|
6419
6502
|
if (targetCareer.group === "人类联盟") {
|
|
6420
6503
|
let joinDate;
|
|
6421
6504
|
if (typeof targetCareer.date === "string") {
|
|
@@ -6435,9 +6518,9 @@ ${items.join("、")}
|
|
|
6435
6518
|
handle: targetHandle
|
|
6436
6519
|
});
|
|
6437
6520
|
const isNewPlayer = !targetPKRecord;
|
|
6438
|
-
const
|
|
6521
|
+
const hasProtection2 = diffInDays < 30;
|
|
6439
6522
|
const isPKDisabled = targetPKRecord && !targetPKRecord.enable;
|
|
6440
|
-
if ((isNewPlayer || isPKDisabled) &&
|
|
6523
|
+
if ((isNewPlayer || isPKDisabled) && hasProtection2) {
|
|
6441
6524
|
return `🛡️ 该玩家是人类联盟成员,当前处于30天保护期内(剩余${30 - diffInDays}天),无法PK`;
|
|
6442
6525
|
}
|
|
6443
6526
|
}
|
|
@@ -7798,6 +7881,56 @@ ${validTypes.join("、")}`;
|
|
|
7798
7881
|
return "加入阵营时发生错误,请稍后再试";
|
|
7799
7882
|
}
|
|
7800
7883
|
});
|
|
7884
|
+
ctx.command("ggcevo/退出", "退出当前阵营").alias("退出阵营").action(async ({ session }) => {
|
|
7885
|
+
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
7886
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
7887
|
+
const { regionId, realmId, profileId } = profile;
|
|
7888
|
+
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
7889
|
+
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
7890
|
+
if (existingEntries.length > 0) {
|
|
7891
|
+
return `⛔ 您已被列入黑名单。`;
|
|
7892
|
+
}
|
|
7893
|
+
const [currentCareer] = await ctx.database.get("ggcevo_careers", { handle });
|
|
7894
|
+
if (!currentCareer || !currentCareer.group) {
|
|
7895
|
+
return "您尚未加入任何阵营。";
|
|
7896
|
+
}
|
|
7897
|
+
const [signData] = await ctx.database.get("ggcevo_sign", { handle });
|
|
7898
|
+
const userCoins = signData?.totalRewards || 0;
|
|
7899
|
+
let exitCost = 0;
|
|
7900
|
+
let exitFactionName = "";
|
|
7901
|
+
if (currentCareer.group === "人类联盟") {
|
|
7902
|
+
exitCost = 2e3;
|
|
7903
|
+
exitFactionName = "人类联盟";
|
|
7904
|
+
} else if (currentCareer.group === "辛迪加海盗") {
|
|
7905
|
+
exitCost = 4e3;
|
|
7906
|
+
exitFactionName = "辛迪加海盗";
|
|
7907
|
+
}
|
|
7908
|
+
if (userCoins < exitCost) {
|
|
7909
|
+
return `退出${exitFactionName}需要${exitCost}金币,您当前只有${userCoins}金币`;
|
|
7910
|
+
}
|
|
7911
|
+
await session.send(`确定要花费${exitCost}金币退出${exitFactionName}吗?(30秒内输入"是"确认退出)`);
|
|
7912
|
+
const confirm = await session.prompt(3e4);
|
|
7913
|
+
if (confirm !== "是") return "已取消退出操作。";
|
|
7914
|
+
try {
|
|
7915
|
+
await ctx.database.upsert("ggcevo_sign", [{
|
|
7916
|
+
handle,
|
|
7917
|
+
totalRewards: Math.max(0, signData.totalRewards - exitCost)
|
|
7918
|
+
}], ["handle"]);
|
|
7919
|
+
await ctx.database.upsert("ggcevo_careers", [{
|
|
7920
|
+
handle,
|
|
7921
|
+
group: "",
|
|
7922
|
+
career: "",
|
|
7923
|
+
redcrystal: currentCareer.redcrystal,
|
|
7924
|
+
// 保留红晶数量
|
|
7925
|
+
date: null
|
|
7926
|
+
// 清空加入日期
|
|
7927
|
+
}], ["handle"]);
|
|
7928
|
+
return `✅ 成功花费${exitCost}金币退出${exitFactionName}!`;
|
|
7929
|
+
} catch (err) {
|
|
7930
|
+
ctx.logger.error("退出阵营失败:", err);
|
|
7931
|
+
return "退出阵营时发生错误,请稍后再试";
|
|
7932
|
+
}
|
|
7933
|
+
});
|
|
7801
7934
|
ctx.command("ggcevo/转职 [profession]", "转职系统").action(async ({ session }, profession) => {
|
|
7802
7935
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
7803
7936
|
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
@@ -7886,39 +8019,62 @@ ${validTypes.join("、")}`;
|
|
|
7886
8019
|
});
|
|
7887
8020
|
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
7888
8021
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
7889
|
-
|
|
7890
|
-
if (!careerData)
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
7894
|
-
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
|
|
7899
|
-
|
|
7900
|
-
|
|
7901
|
-
|
|
7902
|
-
|
|
7903
|
-
|
|
7904
|
-
|
|
7905
|
-
|
|
7906
|
-
|
|
7907
|
-
|
|
7908
|
-
const
|
|
7909
|
-
|
|
7910
|
-
|
|
7911
|
-
|
|
7912
|
-
|
|
7913
|
-
|
|
8022
|
+
let [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
8023
|
+
if (!careerData) {
|
|
8024
|
+
await ctx.database.create("ggcevo_careers", {
|
|
8025
|
+
handle,
|
|
8026
|
+
group: "",
|
|
8027
|
+
career: "",
|
|
8028
|
+
redcrystal: 0,
|
|
8029
|
+
date: null
|
|
8030
|
+
});
|
|
8031
|
+
[careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
8032
|
+
}
|
|
8033
|
+
const infoCard = [`🎮 游戏句柄:${handle}`];
|
|
8034
|
+
try {
|
|
8035
|
+
const powerValue = await calculateTotalPower(ctx, config, handle);
|
|
8036
|
+
infoCard.push(`⚔️ 当前战力:${powerValue}`);
|
|
8037
|
+
} catch (err) {
|
|
8038
|
+
ctx.logger.warn("战力计算失败", err);
|
|
8039
|
+
}
|
|
8040
|
+
if (careerData.group) {
|
|
8041
|
+
const factionconfig = careerData.group === "辛迪加海盗" ? syndicatePirateConfig : spaceStationCrewConfig;
|
|
8042
|
+
const profession = factionconfig.find((p) => p.professionName === careerData.career);
|
|
8043
|
+
const effectDisplay = profession?.effect || "无特殊效果";
|
|
8044
|
+
infoCard.push(
|
|
8045
|
+
`🎯 当前阵营:${careerData.group}`,
|
|
8046
|
+
`👔 当前职业:${careerData.career}`,
|
|
8047
|
+
`✨ 职业效果:${effectDisplay}`
|
|
8048
|
+
);
|
|
8049
|
+
if (careerData.date) {
|
|
8050
|
+
const joinDate = new Date(careerData.date);
|
|
8051
|
+
const formattedDate = `${joinDate.getFullYear()}年${joinDate.getMonth() + 1}月${joinDate.getDate()}日`;
|
|
8052
|
+
infoCard.push(`🗓️ 加入时间:${formattedDate}`);
|
|
7914
8053
|
}
|
|
8054
|
+
if (careerData.group === "人类联盟") {
|
|
8055
|
+
const techEntries = await ctx.database.get("ggcevo_tech", { handle });
|
|
8056
|
+
const activeTechs = techEntries.filter((entry) => entry.level > 0).map((entry) => {
|
|
8057
|
+
const techConfig = Spacestationtechnology.find((t) => t.techId === entry.techId);
|
|
8058
|
+
return techConfig ? `🛠️ ${techConfig.techname} [${entry.level}/${techConfig.maxLevel}]` : null;
|
|
8059
|
+
}).filter(Boolean);
|
|
8060
|
+
if (activeTechs.length > 0) {
|
|
8061
|
+
infoCard.push("", "〓 科技研发 〓", ...activeTechs);
|
|
8062
|
+
}
|
|
8063
|
+
}
|
|
8064
|
+
} else {
|
|
8065
|
+
infoCard.push(
|
|
8066
|
+
"🎯 当前阵营:无",
|
|
8067
|
+
"👔 当前职业:无",
|
|
8068
|
+
"",
|
|
8069
|
+
'💡 使用"加入阵营"指令选择你的阵营'
|
|
8070
|
+
);
|
|
7915
8071
|
}
|
|
7916
|
-
const
|
|
8072
|
+
const divider = "〓═════════〓";
|
|
8073
|
+
const promptMessage = careerData.group === "辛迪加海盗" ? "💡 提示:红晶可通过主动发起PK获得(无论胜负)" : careerData.group ? "💡 提示:使用「转职」指令可变更职业" : "";
|
|
7917
8074
|
return [
|
|
7918
8075
|
`〓 职业档案 〓`,
|
|
7919
8076
|
...infoCard,
|
|
7920
|
-
|
|
7921
|
-
// 提示信息放在分隔线下方
|
|
8077
|
+
...promptMessage ? [divider, promptMessage] : []
|
|
7922
8078
|
].join("\n");
|
|
7923
8079
|
} catch (error) {
|
|
7924
8080
|
ctx.logger.error("查询职业信息失败:", error);
|
|
@@ -8398,7 +8554,7 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
|
|
|
8398
8554
|
// 新增累加
|
|
8399
8555
|
});
|
|
8400
8556
|
});
|
|
8401
|
-
const
|
|
8557
|
+
const formatTime2 = /* @__PURE__ */ __name((mins) => {
|
|
8402
8558
|
const hours = Math.floor(mins / 60);
|
|
8403
8559
|
const minutes = mins % 60;
|
|
8404
8560
|
return `${hours}小时${minutes}分钟`;
|
|
@@ -8407,7 +8563,7 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
|
|
|
8407
8563
|
"⛏️ 挖矿报告",
|
|
8408
8564
|
`🕒 开始时间:${record.startTime.toLocaleString("zh-CN", { hour12: false })}`,
|
|
8409
8565
|
`⏱️ 结束时间:${nowtime.toLocaleString("zh-CN", { hour12: false })}`,
|
|
8410
|
-
`⏳ 持续时间:${
|
|
8566
|
+
`⏳ 持续时间:${formatTime2(duration)}`
|
|
8411
8567
|
];
|
|
8412
8568
|
const maxHours = tech.level === 5 ? 48 : 24;
|
|
8413
8569
|
if (duration > maxHours * 60) {
|
|
@@ -8559,6 +8715,67 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
|
|
|
8559
8715
|
return "处理任务时发生错误,请稍后重试。";
|
|
8560
8716
|
}
|
|
8561
8717
|
});
|
|
8718
|
+
ctx.command("ggcevo/购买保护卡", "花费600金币购买一周PK保护卡").action(async ({ session }) => {
|
|
8719
|
+
try {
|
|
8720
|
+
const userId = session.userId;
|
|
8721
|
+
const [profile] = await ctx.database.get("sc2arcade_player", { userId });
|
|
8722
|
+
if (!profile) return "🔒 请先绑定游戏句柄。";
|
|
8723
|
+
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
8724
|
+
const isBlacklisted = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
8725
|
+
if (isBlacklisted.length > 0) return "⛔ 您已被列入黑名单。";
|
|
8726
|
+
const [signRecord] = await ctx.database.get("ggcevo_sign", { handle });
|
|
8727
|
+
if (!signRecord) return "您还没有签到记录,请先签到一次。";
|
|
8728
|
+
const currentGold = signRecord.totalRewards;
|
|
8729
|
+
const protectionCost = 600;
|
|
8730
|
+
if (currentGold < protectionCost) {
|
|
8731
|
+
return `金币不足,购买保护卡需要${protectionCost}金币(当前:${currentGold}金币)`;
|
|
8732
|
+
}
|
|
8733
|
+
await session.send(`⚠️ 请问您是否花费${protectionCost}金币购买一周的PK保护卡?
|
|
8734
|
+
回复"是"购买,或回复其他内容退出`);
|
|
8735
|
+
const confirm = await session.prompt(3e4);
|
|
8736
|
+
if (confirm !== "是") return "已取消购买操作,金币未扣除。";
|
|
8737
|
+
const startTime = /* @__PURE__ */ new Date();
|
|
8738
|
+
const endTime = /* @__PURE__ */ new Date();
|
|
8739
|
+
endTime.setDate(startTime.getDate() + 7);
|
|
8740
|
+
const formatTime2 = /* @__PURE__ */ __name((date) => {
|
|
8741
|
+
return date.toLocaleString("zh-CN", {
|
|
8742
|
+
year: "numeric",
|
|
8743
|
+
month: "2-digit",
|
|
8744
|
+
day: "2-digit"
|
|
8745
|
+
});
|
|
8746
|
+
}, "formatTime");
|
|
8747
|
+
const existingProtections = await ctx.database.get("ggcevo_pk_protection", {
|
|
8748
|
+
handle,
|
|
8749
|
+
endTime: { $gt: startTime },
|
|
8750
|
+
status: "active"
|
|
8751
|
+
});
|
|
8752
|
+
if (existingProtections.length > 0) {
|
|
8753
|
+
const nearestEnd = existingProtections.reduce(
|
|
8754
|
+
(max, p) => p.endTime > max ? p.endTime : max,
|
|
8755
|
+
/* @__PURE__ */ new Date(0)
|
|
8756
|
+
);
|
|
8757
|
+
return `您已拥有保护卡(至 ${formatTime2(nearestEnd)}),请到期后再购买`;
|
|
8758
|
+
}
|
|
8759
|
+
await ctx.database.withTransaction(async () => {
|
|
8760
|
+
await ctx.database.set("ggcevo_sign", handle, {
|
|
8761
|
+
totalRewards: currentGold - protectionCost
|
|
8762
|
+
});
|
|
8763
|
+
await ctx.database.create("ggcevo_pk_protection", {
|
|
8764
|
+
handle,
|
|
8765
|
+
startTime,
|
|
8766
|
+
endTime,
|
|
8767
|
+
status: "active"
|
|
8768
|
+
});
|
|
8769
|
+
});
|
|
8770
|
+
return `✅ 成功购买PK保护卡!
|
|
8771
|
+
💰 扣除金币: ${protectionCost}
|
|
8772
|
+
⏱️ 生效时间: ${formatTime2(startTime)}
|
|
8773
|
+
🛡️ 保护结束: ${formatTime2(endTime)}`;
|
|
8774
|
+
} catch (error) {
|
|
8775
|
+
console.error("购买保护卡出错:", error);
|
|
8776
|
+
return "购买过程中发生错误,请稍后再试";
|
|
8777
|
+
}
|
|
8778
|
+
});
|
|
8562
8779
|
}
|
|
8563
8780
|
__name(apply, "apply");
|
|
8564
8781
|
// Annotate the CommonJS export names for ESM import in node:
|
package/lib/utils.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Context } from 'koishi';
|
|
2
2
|
import { Config } from './index';
|
|
3
|
+
import { PKProtection } from './database';
|
|
3
4
|
export declare function gachaWithPity(ctx: Context, handle: string): Promise<boolean>;
|
|
4
5
|
export declare function gachaWithHiddenAward(ctx: Context, handle: string): Promise<boolean>;
|
|
5
6
|
export declare function checkSensitiveWord(ctx: Context, content: string): Promise<boolean>;
|
|
@@ -20,3 +21,5 @@ export declare function handleTechUpgrade(ctx: Context, handle: string, target:
|
|
|
20
21
|
export declare function handleWeaponUpgrade(ctx: Context, handle: string, target: string): Promise<string>;
|
|
21
22
|
export declare function generateUpgradePriceList(ctx: Context, handle: string): Promise<string>;
|
|
22
23
|
export declare function getRankInfo(ctx: Context, config: Config, handle: string): Promise<string>;
|
|
24
|
+
export declare function isWithinProtection(protections: PKProtection[]): boolean;
|
|
25
|
+
export declare function formatTime(date: Date): string;
|