koishi-plugin-ggcevo-game 1.2.13 → 1.2.14
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 +403 -335
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -50,7 +50,7 @@ var Config = import_koishi.Schema.intersect([
|
|
|
50
50
|
dailyPKLimit: import_koishi.Schema.number().description("每日最大发起PK次数").default(3),
|
|
51
51
|
sameOpponentLimit: import_koishi.Schema.boolean().description("同玩家每日单次限制").default(true),
|
|
52
52
|
maxDailyBeChallenged: import_koishi.Schema.number().description("最大被挑战次数(0=无限制)").default(5),
|
|
53
|
-
unlimitedBossAttack: import_koishi.Schema.boolean().description("
|
|
53
|
+
unlimitedBossAttack: import_koishi.Schema.boolean().description("开启无限制PVE攻击").default(false)
|
|
54
54
|
}).description("对战限制"),
|
|
55
55
|
// 通知系统配置组
|
|
56
56
|
import_koishi.Schema.object({
|
|
@@ -59,7 +59,7 @@ var Config = import_koishi.Schema.intersect([
|
|
|
59
59
|
}).description("通知设置").collapse(),
|
|
60
60
|
// 权限管理组
|
|
61
61
|
import_koishi.Schema.object({
|
|
62
|
-
admins: import_koishi.Schema.array(import_koishi.Schema.string()).description("
|
|
62
|
+
admins: import_koishi.Schema.array(import_koishi.Schema.string()).description("管理员列表").default([])
|
|
63
63
|
}).description("权限管理")
|
|
64
64
|
]);
|
|
65
65
|
var inject = {
|
|
@@ -102,8 +102,11 @@ function apply(ctx, config) {
|
|
|
102
102
|
ctx.model.extend("ggcevo_activity", {
|
|
103
103
|
id: "unsigned",
|
|
104
104
|
name: "string",
|
|
105
|
+
// 存储活动名称
|
|
105
106
|
description: "text",
|
|
106
107
|
quantity: "unsigned",
|
|
108
|
+
itemId: "unsigned",
|
|
109
|
+
// 新增物品ID字段
|
|
107
110
|
startTime: "timestamp",
|
|
108
111
|
endTime: "timestamp",
|
|
109
112
|
creator: "string",
|
|
@@ -124,7 +127,6 @@ function apply(ctx, config) {
|
|
|
124
127
|
// 比赛次数
|
|
125
128
|
Blacklist: {
|
|
126
129
|
type: "boolean",
|
|
127
|
-
// 该字段的默认值
|
|
128
130
|
initial: false
|
|
129
131
|
}
|
|
130
132
|
}, {
|
|
@@ -196,13 +198,11 @@ function apply(ctx, config) {
|
|
|
196
198
|
todayCount: "unsigned",
|
|
197
199
|
lastPK: "timestamp",
|
|
198
200
|
enable: {
|
|
199
|
-
// 新增字段
|
|
200
201
|
type: "boolean",
|
|
201
202
|
initial: true
|
|
202
203
|
// 默认开启
|
|
203
204
|
},
|
|
204
205
|
lastToggle: "timestamp"
|
|
205
|
-
// 新增字段
|
|
206
206
|
}, {
|
|
207
207
|
primary: "handle"
|
|
208
208
|
});
|
|
@@ -276,11 +276,11 @@ function apply(ctx, config) {
|
|
|
276
276
|
id: 3,
|
|
277
277
|
type: "热能武器",
|
|
278
278
|
damage: 15,
|
|
279
|
-
description: "
|
|
279
|
+
description: "基于热能的强大武器,烧烬一切",
|
|
280
280
|
price: 450,
|
|
281
281
|
tagEffects: {
|
|
282
|
-
"生物": 1.5,
|
|
283
282
|
"惧热": 2,
|
|
283
|
+
"生物": 1.2,
|
|
284
284
|
"护盾": 0.5
|
|
285
285
|
}
|
|
286
286
|
},
|
|
@@ -288,11 +288,24 @@ function apply(ctx, config) {
|
|
|
288
288
|
id: 4,
|
|
289
289
|
type: "能量武器",
|
|
290
290
|
damage: 28,
|
|
291
|
-
description: "
|
|
291
|
+
description: "由激光步枪改良而来,高效的对重甲武器",
|
|
292
292
|
price: 850,
|
|
293
293
|
tagEffects: {
|
|
294
294
|
"重甲": 2,
|
|
295
|
-
"
|
|
295
|
+
"机械": 0.5,
|
|
296
|
+
"护盾": 0.2
|
|
297
|
+
}
|
|
298
|
+
},
|
|
299
|
+
"狙击步枪": {
|
|
300
|
+
id: 5,
|
|
301
|
+
type: "实弹武器",
|
|
302
|
+
damage: 60,
|
|
303
|
+
description: "用于隐秘射击的最佳武器,但是无法穿透护甲",
|
|
304
|
+
price: 550,
|
|
305
|
+
tagEffects: {
|
|
306
|
+
"轻甲": 0.7,
|
|
307
|
+
"护盾": 0.5,
|
|
308
|
+
"重甲": 0.2
|
|
296
309
|
}
|
|
297
310
|
}
|
|
298
311
|
};
|
|
@@ -326,9 +339,18 @@ function apply(ctx, config) {
|
|
|
326
339
|
}
|
|
327
340
|
};
|
|
328
341
|
const passiveConfig = {
|
|
329
|
-
"弱化形态": {
|
|
330
|
-
|
|
331
|
-
|
|
342
|
+
"弱化形态": {
|
|
343
|
+
effect: 0.1,
|
|
344
|
+
description: "子代的防御薄弱,受到的伤害+10%"
|
|
345
|
+
},
|
|
346
|
+
"坚固外壳": {
|
|
347
|
+
effect: -0.2,
|
|
348
|
+
description: "拥有坚硬的生物甲壳,受到的伤害-20%"
|
|
349
|
+
},
|
|
350
|
+
"孤立无援": {
|
|
351
|
+
effect: 0.2,
|
|
352
|
+
description: "没有存活的子代,受到的伤害+20%"
|
|
353
|
+
}
|
|
332
354
|
};
|
|
333
355
|
const bossPool = [
|
|
334
356
|
{
|
|
@@ -353,6 +375,96 @@ function apply(ctx, config) {
|
|
|
353
375
|
]
|
|
354
376
|
}
|
|
355
377
|
];
|
|
378
|
+
function calculateModifiers(equippedWeapon, weaponName) {
|
|
379
|
+
let totalModAdd = 0;
|
|
380
|
+
let hasCrit = false;
|
|
381
|
+
let hasCrystal = false;
|
|
382
|
+
let hasOverload = false;
|
|
383
|
+
equippedWeapon.installedMods.forEach((mod) => {
|
|
384
|
+
if (mod === "动能增幅") {
|
|
385
|
+
totalModAdd += 0.2;
|
|
386
|
+
}
|
|
387
|
+
if (mod === "裂甲核心" && weaponName === modConfig[mod].exclusiveTo) {
|
|
388
|
+
totalModAdd += 0.4;
|
|
389
|
+
}
|
|
390
|
+
if (mod === "棱镜水晶") hasCrystal = true;
|
|
391
|
+
if (mod === "棱镜超载核心" && weaponName === modConfig[mod].exclusiveTo) {
|
|
392
|
+
hasOverload = true;
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
const totalCritRate = (hasCrystal ? 20 : 0) + (hasOverload ? 80 : 0);
|
|
396
|
+
if (totalCritRate > 0 && Math.random() < totalCritRate / 100) {
|
|
397
|
+
hasCrit = true;
|
|
398
|
+
totalModAdd += 1;
|
|
399
|
+
}
|
|
400
|
+
return { totalModAdd, hasCrit };
|
|
401
|
+
}
|
|
402
|
+
__name(calculateModifiers, "calculateModifiers");
|
|
403
|
+
function calculateTagEffects(weaponData, targetBossConfig, equippedWeapon) {
|
|
404
|
+
let totalTagAdd = 0;
|
|
405
|
+
const armorTags = targetBossConfig.tags?.filter((tag) => ["重甲", "轻甲", "护盾"].includes(tag)) || [];
|
|
406
|
+
const voidTags = targetBossConfig.tags?.filter((tag) => ["惧热", "惧寒"].includes(tag)) || [];
|
|
407
|
+
const typeTags = targetBossConfig.tags?.filter((tag) => ["生物", "机械", "灵能"].includes(tag)) || [];
|
|
408
|
+
armorTags.forEach((tag) => {
|
|
409
|
+
let effectValue = weaponData.tagEffects?.[tag] ?? 1;
|
|
410
|
+
if (tag === "重甲" && equippedWeapon.installedMods.includes("裂甲核心")) {
|
|
411
|
+
effectValue = 1.2;
|
|
412
|
+
}
|
|
413
|
+
totalTagAdd += effectValue - 1;
|
|
414
|
+
});
|
|
415
|
+
voidTags.forEach((tag) => {
|
|
416
|
+
const effectValue = weaponData.tagEffects?.[tag] ?? 1;
|
|
417
|
+
totalTagAdd += effectValue - 1;
|
|
418
|
+
});
|
|
419
|
+
typeTags.forEach((tag) => {
|
|
420
|
+
const effectValue = weaponData.tagEffects?.[tag] ?? 1;
|
|
421
|
+
totalTagAdd += effectValue - 1;
|
|
422
|
+
});
|
|
423
|
+
return totalTagAdd;
|
|
424
|
+
}
|
|
425
|
+
__name(calculateTagEffects, "calculateTagEffects");
|
|
426
|
+
function calculatePassiveEffects(targetBossConfig, activeMinionsCount) {
|
|
427
|
+
let passiveEffect = 0;
|
|
428
|
+
const effectivePassives = [...targetBossConfig.passive || []];
|
|
429
|
+
if (targetBossConfig.type === "主宰" && effectivePassives.includes("孤立无援")) {
|
|
430
|
+
if (activeMinionsCount !== 0) {
|
|
431
|
+
effectivePassives.splice(effectivePassives.indexOf("孤立无援"), 1);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
effectivePassives.forEach((passive) => {
|
|
435
|
+
const effect = passiveConfig[passive]?.effect || 0;
|
|
436
|
+
passiveEffect += effect;
|
|
437
|
+
});
|
|
438
|
+
return passiveEffect;
|
|
439
|
+
}
|
|
440
|
+
__name(calculatePassiveEffects, "calculatePassiveEffects");
|
|
441
|
+
function calculateRankBonus(rankRecord) {
|
|
442
|
+
if (!rankRecord || rankRecord.rank <= 0) return 0;
|
|
443
|
+
return Math.floor(rankRecord.rank / 400) * 0.01;
|
|
444
|
+
}
|
|
445
|
+
__name(calculateRankBonus, "calculateRankBonus");
|
|
446
|
+
async function calculateTotalDamage(ctx2, session, equippedWeapon, targetBoss) {
|
|
447
|
+
const weaponConfigEntry = Object.entries(weaponConfig).find(([_, c]) => c.id === equippedWeapon.weaponId);
|
|
448
|
+
const [weaponName, weaponData] = weaponConfigEntry;
|
|
449
|
+
let damage = weaponData.damage * (1 + 0.1 * equippedWeapon.level);
|
|
450
|
+
const { totalModAdd, hasCrit } = calculateModifiers(equippedWeapon, weaponName);
|
|
451
|
+
damage *= 1 + totalModAdd;
|
|
452
|
+
const targetBossConfig = targetBoss.type === "主宰" ? bossPool.find((g) => g.main.name === targetBoss.name).main : bossPool.find((g) => g.minions.some((m) => m.name === targetBoss.name)).minions[0];
|
|
453
|
+
const tagMultiplier = calculateTagEffects(weaponData, targetBossConfig, equippedWeapon);
|
|
454
|
+
damage *= 1 + tagMultiplier;
|
|
455
|
+
const activeMinions = await ctx2.database.get("ggcevo_boss", {
|
|
456
|
+
groupId: targetBoss.groupId,
|
|
457
|
+
type: "子代",
|
|
458
|
+
isActive: true
|
|
459
|
+
});
|
|
460
|
+
const passiveMultiplier = calculatePassiveEffects(targetBossConfig, activeMinions.length);
|
|
461
|
+
damage *= 1 + passiveMultiplier;
|
|
462
|
+
const [rankRecord] = await ctx2.database.get("ggcevo_rank", { handle: session.handle });
|
|
463
|
+
const rankBonus = calculateRankBonus(rankRecord);
|
|
464
|
+
damage *= 1 + rankBonus;
|
|
465
|
+
return { damage: Math.round(damage), hasCrit };
|
|
466
|
+
}
|
|
467
|
+
__name(calculateTotalDamage, "calculateTotalDamage");
|
|
356
468
|
const initDefaultItems = {
|
|
357
469
|
"咕咕币": { id: 1, type: "抽奖道具", description: "用于进行抽奖" },
|
|
358
470
|
"兑换券": { id: 2, type: "兑换货币", description: "用于兑换赞助物品" },
|
|
@@ -522,7 +634,7 @@ function apply(ctx, config) {
|
|
|
522
634
|
await activateNextBossGroup(group.groupId);
|
|
523
635
|
ctx.broadcast(
|
|
524
636
|
config.groupId,
|
|
525
|
-
`🔄
|
|
637
|
+
`🔄 新的主宰已刷新,快去挑战吧!`
|
|
526
638
|
);
|
|
527
639
|
}
|
|
528
640
|
}, 60 * 1e3);
|
|
@@ -532,21 +644,21 @@ function apply(ctx, config) {
|
|
|
532
644
|
let hiddenWinCount = 0;
|
|
533
645
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
534
646
|
if (!profile) {
|
|
535
|
-
return "
|
|
647
|
+
return "您暂未绑定句柄。";
|
|
536
648
|
}
|
|
537
649
|
const { regionId, realmId, profileId } = profile;
|
|
538
650
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
539
651
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
540
652
|
if (existingEntries.length > 0) {
|
|
541
|
-
return
|
|
653
|
+
return `❌ 拒绝访问,您已被列入黑名单。`;
|
|
542
654
|
}
|
|
543
655
|
const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 1 });
|
|
544
656
|
if (!backpack) {
|
|
545
|
-
return "
|
|
657
|
+
return "您还没有签到。";
|
|
546
658
|
}
|
|
547
659
|
const quantity = backpack.quantity;
|
|
548
660
|
if (quantity < 1) {
|
|
549
|
-
return "
|
|
661
|
+
return "您的咕咕币不足。";
|
|
550
662
|
}
|
|
551
663
|
await ctx.database.upsert("ggcevo_backpack", [{
|
|
552
664
|
handle,
|
|
@@ -571,20 +683,20 @@ function apply(ctx, config) {
|
|
|
571
683
|
const session = argv.session;
|
|
572
684
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
573
685
|
if (!profile) {
|
|
574
|
-
return "
|
|
686
|
+
return "您暂未绑定句柄。";
|
|
575
687
|
}
|
|
576
688
|
const { regionId, realmId, profileId } = profile;
|
|
577
689
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
578
690
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
579
691
|
if (existingEntries.length > 0) {
|
|
580
|
-
return
|
|
692
|
+
return `❌ 拒绝访问,您已被列入黑名单。`;
|
|
581
693
|
}
|
|
582
694
|
const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 1 });
|
|
583
695
|
if (!backpack) {
|
|
584
|
-
return "
|
|
696
|
+
return "您还没有签到。";
|
|
585
697
|
}
|
|
586
698
|
if (backpack.quantity < 1) {
|
|
587
|
-
return "
|
|
699
|
+
return "您的咕咕币不足。";
|
|
588
700
|
}
|
|
589
701
|
await ctx.database.upsert("ggcevo_backpack", [{
|
|
590
702
|
handle,
|
|
@@ -604,20 +716,20 @@ function apply(ctx, config) {
|
|
|
604
716
|
let hiddenWinCount = 0;
|
|
605
717
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
606
718
|
if (!profile) {
|
|
607
|
-
return "
|
|
719
|
+
return "您暂未绑定句柄。";
|
|
608
720
|
}
|
|
609
721
|
const { regionId, realmId, profileId } = profile;
|
|
610
722
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
611
723
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
612
724
|
if (existingEntries.length > 0) {
|
|
613
|
-
return
|
|
725
|
+
return `❌ 拒绝访问,您已被列入黑名单。`;
|
|
614
726
|
}
|
|
615
727
|
const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 1 });
|
|
616
728
|
if (!backpack) {
|
|
617
|
-
return "
|
|
729
|
+
return "您还没有签到。";
|
|
618
730
|
}
|
|
619
731
|
if (backpack.quantity < 10) {
|
|
620
|
-
return "
|
|
732
|
+
return "您的咕咕币不足。";
|
|
621
733
|
}
|
|
622
734
|
await ctx.database.upsert("ggcevo_backpack", [{
|
|
623
735
|
handle,
|
|
@@ -642,7 +754,7 @@ function apply(ctx, config) {
|
|
|
642
754
|
const session = argv.session;
|
|
643
755
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
644
756
|
if (!profile) {
|
|
645
|
-
return "
|
|
757
|
+
return "您暂未绑定句柄。";
|
|
646
758
|
}
|
|
647
759
|
const { regionId, realmId, profileId } = profile;
|
|
648
760
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
@@ -661,7 +773,7 @@ function apply(ctx, config) {
|
|
|
661
773
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
662
774
|
const items = await ctx.database.get("ggcevo_backpack", { handle });
|
|
663
775
|
const validItems = items.filter((item) => item.quantity > 0);
|
|
664
|
-
if (!validItems.length) return "
|
|
776
|
+
if (!validItems.length) return "你的背包空空如也。";
|
|
665
777
|
const itemDetails = validItems.map((userItem) => {
|
|
666
778
|
const entry = Object.entries(initDefaultItems).find(
|
|
667
779
|
([, item]) => item.id === userItem.itemId
|
|
@@ -678,11 +790,11 @@ ${itemDetails.join("\n")}`;
|
|
|
678
790
|
const session = argv.session;
|
|
679
791
|
let latestTime;
|
|
680
792
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
681
|
-
if (!profile) return "
|
|
793
|
+
if (!profile) return "您暂未绑定句柄。";
|
|
682
794
|
const { regionId, realmId, profileId } = profile;
|
|
683
795
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
684
796
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
685
|
-
if (existingEntries.length > 0) return "
|
|
797
|
+
if (existingEntries.length > 0) return "❌ 拒绝访问,您已被列入黑名单。";
|
|
686
798
|
const now = /* @__PURE__ */ new Date();
|
|
687
799
|
const currentChinaTime = convertUTCtoChinaTime(now);
|
|
688
800
|
if (config.signrequire) {
|
|
@@ -700,18 +812,18 @@ ${itemDetails.join("\n")}`;
|
|
|
700
812
|
} else {
|
|
701
813
|
latestTime = currentChinaTime;
|
|
702
814
|
}
|
|
703
|
-
if (!latestTime) return "
|
|
815
|
+
if (!latestTime) return "您还没有游玩过“咕咕虫-evolved”。";
|
|
704
816
|
const targetDateChina = new Date(latestTime);
|
|
705
817
|
targetDateChina.setUTCDate(targetDateChina.getUTCDate() + 1);
|
|
706
818
|
if (!isSameDate(latestTime, currentChinaTime) && !isSameDate(targetDateChina, currentChinaTime)) {
|
|
707
|
-
return "
|
|
819
|
+
return "暂未查询到您最近两天内游玩过“咕咕虫-evolved”,请游玩1次后签到(对局记录上传有延迟)";
|
|
708
820
|
}
|
|
709
821
|
const [record] = await ctx.database.get("ggcevo_sign", { handle });
|
|
710
822
|
const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 1 });
|
|
711
823
|
if (record) {
|
|
712
824
|
const lastSignChina = convertUTCtoChinaTime(record.lastSign);
|
|
713
825
|
if (lastSignChina.getUTCDate() === currentChinaTime.getUTCDate()) {
|
|
714
|
-
return
|
|
826
|
+
return `您今天已经签到过了!本月累计签到${record.monthlyDays}天。`;
|
|
715
827
|
}
|
|
716
828
|
}
|
|
717
829
|
let monthlyDays = 1;
|
|
@@ -754,7 +866,7 @@ ${itemDetails.join("\n")}`;
|
|
|
754
866
|
itemId: 1,
|
|
755
867
|
quantity: (backpack?.quantity || 0) + tickets
|
|
756
868
|
}]);
|
|
757
|
-
return
|
|
869
|
+
return `签到成功!本月累计签到${monthlyDays}天,获得${points}枚金币和${tickets}枚咕咕币`;
|
|
758
870
|
} catch (error) {
|
|
759
871
|
console.error("签到命令时发生错误:", error);
|
|
760
872
|
return "服务器繁忙,请稍后尝试。";
|
|
@@ -764,13 +876,13 @@ ${itemDetails.join("\n")}`;
|
|
|
764
876
|
try {
|
|
765
877
|
const session = argv.session;
|
|
766
878
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
767
|
-
if (!profile) return "
|
|
879
|
+
if (!profile) return "您暂未绑定句柄。";
|
|
768
880
|
const { regionId, realmId, profileId } = profile;
|
|
769
881
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
770
882
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
771
|
-
if (existingEntries.length > 0) return "
|
|
883
|
+
if (existingEntries.length > 0) return "❌ 拒绝访问,您已被列入黑名单。";
|
|
772
884
|
const [record] = await ctx.database.get("ggcevo_sign", { handle });
|
|
773
|
-
if (!record) return "
|
|
885
|
+
if (!record) return "您还没有签到。";
|
|
774
886
|
const lastSignChina = convertUTCtoChinaTime(record.lastSign);
|
|
775
887
|
const targetDateChina = new Date(lastSignChina);
|
|
776
888
|
const nowChina = convertUTCtoChinaTime(/* @__PURE__ */ new Date());
|
|
@@ -783,7 +895,7 @@ ${itemDetails.join("\n")}`;
|
|
|
783
895
|
}
|
|
784
896
|
const costPoints = 50;
|
|
785
897
|
if (record.totalRewards < costPoints) {
|
|
786
|
-
return
|
|
898
|
+
return `补签需要消耗${costPoints}枚金币,您的金币不足。`;
|
|
787
899
|
}
|
|
788
900
|
const newMonthlyDays = record.monthlyDays + 1;
|
|
789
901
|
let tickets = 3, points = 0;
|
|
@@ -809,14 +921,8 @@ ${itemDetails.join("\n")}`;
|
|
|
809
921
|
await ctx.database.set("ggcevo_backpack", { handle, itemId: 1 }, {
|
|
810
922
|
quantity: (backpack?.quantity || 0) + tickets
|
|
811
923
|
});
|
|
812
|
-
const
|
|
813
|
-
|
|
814
|
-
year: "numeric",
|
|
815
|
-
month: "2-digit",
|
|
816
|
-
day: "2-digit"
|
|
817
|
-
});
|
|
818
|
-
const rewardsMessage = points > 0 ? `获得 ${points} 金币和 ${tickets} 枚咕咕币` : `获得 ${tickets} 枚咕咕币`;
|
|
819
|
-
return `补签成功!本月累计签到 ${newMonthlyDays} 天,消耗 ${costPoints} 金币,${rewardsMessage}`;
|
|
924
|
+
const rewardsMessage = points > 0 ? `获得${points}枚金币和${tickets}枚咕咕币` : `获得${tickets}枚咕咕币`;
|
|
925
|
+
return `补签成功!本月累计签到${newMonthlyDays}天,消耗${costPoints}枚金币,${rewardsMessage}`;
|
|
820
926
|
} catch (error) {
|
|
821
927
|
console.error("补签错误:", error);
|
|
822
928
|
return "补签失败,请稍后重试。";
|
|
@@ -825,11 +931,11 @@ ${itemDetails.join("\n")}`;
|
|
|
825
931
|
ctx.command("ggcevo/签到记录").action(async (argv) => {
|
|
826
932
|
const session = argv.session;
|
|
827
933
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
828
|
-
if (!profile) return "
|
|
934
|
+
if (!profile) return "您暂未绑定句柄。";
|
|
829
935
|
const { regionId, realmId, profileId } = profile;
|
|
830
936
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
831
937
|
const [record] = await ctx.database.get("ggcevo_sign", { handle });
|
|
832
|
-
if (!record) return "
|
|
938
|
+
if (!record) return "您还没有签到。";
|
|
833
939
|
const chinaTime = record.lastSign.toLocaleString("zh-CN", {
|
|
834
940
|
timeZone: "Asia/Shanghai",
|
|
835
941
|
year: "numeric",
|
|
@@ -843,25 +949,25 @@ ${itemDetails.join("\n")}`;
|
|
|
843
949
|
return [
|
|
844
950
|
`您的句柄:${handle}`,
|
|
845
951
|
`📅 最后签到时间:${chinaTime}`,
|
|
846
|
-
`🔥 累计签到:${record.monthlyDays}
|
|
847
|
-
`💰
|
|
952
|
+
`🔥 累计签到:${record.monthlyDays}天`,
|
|
953
|
+
`💰 拥有财富:${record.totalRewards}枚金币`
|
|
848
954
|
].join("\n");
|
|
849
955
|
});
|
|
850
956
|
ctx.guild().command("ggcevo/每月津贴").action(async (argv) => {
|
|
851
957
|
const session = argv.session;
|
|
852
958
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
853
|
-
if (!profile) return "
|
|
959
|
+
if (!profile) return "您暂未绑定句柄。";
|
|
854
960
|
const { regionId, realmId, profileId } = profile;
|
|
855
961
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
856
962
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
857
963
|
if (existingEntries.length > 0) {
|
|
858
|
-
return
|
|
964
|
+
return `❌ 拒绝访问,您已被列入黑名单。`;
|
|
859
965
|
}
|
|
860
966
|
const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 1 });
|
|
861
|
-
if (!backpack) return "
|
|
967
|
+
if (!backpack) return "您还没有签到。";
|
|
862
968
|
const memberInfo = await session.event?.member?.roles;
|
|
863
969
|
if (memberInfo?.includes("member")) {
|
|
864
|
-
return "
|
|
970
|
+
return "❌拒绝访问,仅限管理员和群主领取每月津贴。";
|
|
865
971
|
}
|
|
866
972
|
const now = /* @__PURE__ */ new Date();
|
|
867
973
|
const chinatime = convertUTCtoChinaTime(now);
|
|
@@ -875,7 +981,7 @@ ${itemDetails.join("\n")}`;
|
|
|
875
981
|
const lastYear = lastSignTime.getUTCFullYear();
|
|
876
982
|
const lastMonth = lastSignTime.getUTCMonth();
|
|
877
983
|
if (lastYear === currentYear && lastMonth === currentMonth) {
|
|
878
|
-
return
|
|
984
|
+
return `您的本月管理津贴已领取,${currentMonth + 2}月1日后可再次领取`;
|
|
879
985
|
}
|
|
880
986
|
}
|
|
881
987
|
await ctx.database.upsert("ggcevo_adminbenefit", [{
|
|
@@ -890,111 +996,109 @@ ${itemDetails.join("\n")}`;
|
|
|
890
996
|
itemId: 1,
|
|
891
997
|
quantity: (backpack.quantity || 0) + 50
|
|
892
998
|
}]);
|
|
893
|
-
return `[管理专属]
|
|
999
|
+
return `[管理专属] 成功领取本月津贴,获得了50枚咕咕币!`;
|
|
894
1000
|
});
|
|
895
|
-
ctx.command("ggcevo
|
|
1001
|
+
ctx.command("ggcevo/领取 [name]").action(async (argv, name2) => {
|
|
896
1002
|
const session = argv.session;
|
|
897
|
-
await session.send("请在30秒内输入活动名称:");
|
|
898
|
-
const name2 = await session.prompt(3e4);
|
|
899
1003
|
if (!name2) {
|
|
900
|
-
|
|
1004
|
+
await session.send("请在30秒内输入活动名称");
|
|
1005
|
+
name2 = await session.prompt(3e4);
|
|
1006
|
+
if (!name2) return "输入超时,请重新输入。";
|
|
1007
|
+
}
|
|
1008
|
+
const itemIdToName = {};
|
|
1009
|
+
for (const [name3, item] of Object.entries(initDefaultItems)) {
|
|
1010
|
+
itemIdToName[item.id] = name3;
|
|
901
1011
|
}
|
|
902
1012
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
903
|
-
if (!profile) return "
|
|
904
|
-
const {
|
|
905
|
-
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
1013
|
+
if (!profile) return "您暂未绑定句柄。";
|
|
1014
|
+
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
906
1015
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
907
|
-
if (existingEntries.length > 0)
|
|
908
|
-
return `❌拒绝访问,您已被列入活动黑名单。`;
|
|
909
|
-
}
|
|
910
|
-
const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 1 });
|
|
911
|
-
if (!backpack) return "您还没有签到过哦";
|
|
1016
|
+
if (existingEntries.length > 0) return "❌ 拒绝访问,您已被列入黑名单。";
|
|
912
1017
|
const [activity] = await ctx.database.get("ggcevo_activity", {
|
|
913
1018
|
name: name2,
|
|
914
1019
|
status: "进行中"
|
|
915
|
-
// 新增状态条件
|
|
916
1020
|
});
|
|
917
|
-
if (!activity)
|
|
918
|
-
return "当前咕咕币活动未在进行中,请输入 咕咕币活动 查询活动名称。";
|
|
919
|
-
}
|
|
920
|
-
const id = activity.id;
|
|
921
|
-
const quantity = activity.quantity;
|
|
1021
|
+
if (!activity) return "活动未进行中。";
|
|
922
1022
|
const existing = await ctx.database.get("ggcevo_welfare", {
|
|
923
1023
|
handle,
|
|
924
|
-
activity: id
|
|
1024
|
+
activity: activity.id
|
|
925
1025
|
});
|
|
926
|
-
if (existing.length
|
|
927
|
-
const
|
|
928
|
-
timeZone: "Asia/Shanghai"
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
1026
|
+
if (existing.length) {
|
|
1027
|
+
const time = existing[0].lastdate.toLocaleString("zh-CN", {
|
|
1028
|
+
timeZone: "Asia/Shanghai"
|
|
1029
|
+
});
|
|
1030
|
+
return `您已领取过该活动奖励(领取时间:${time})。`;
|
|
1031
|
+
}
|
|
1032
|
+
if (activity.itemId === 0) {
|
|
1033
|
+
const [sign] = await ctx.database.get("ggcevo_sign", { handle });
|
|
1034
|
+
await ctx.database.upsert("ggcevo_sign", [{
|
|
1035
|
+
handle,
|
|
1036
|
+
totalRewards: (sign?.totalRewards || 0) + activity.quantity,
|
|
1037
|
+
lastSign: sign?.lastSign || /* @__PURE__ */ new Date(0),
|
|
1038
|
+
monthlyDays: sign?.monthlyDays || 0
|
|
1039
|
+
}]);
|
|
1040
|
+
} else {
|
|
1041
|
+
const [item] = await ctx.database.get("ggcevo_backpack", {
|
|
1042
|
+
handle,
|
|
1043
|
+
itemId: activity.itemId
|
|
936
1044
|
});
|
|
937
|
-
|
|
1045
|
+
await ctx.database.upsert("ggcevo_backpack", [{
|
|
1046
|
+
handle,
|
|
1047
|
+
itemId: activity.itemId,
|
|
1048
|
+
quantity: (item?.quantity || 0) + activity.quantity
|
|
1049
|
+
}]);
|
|
938
1050
|
}
|
|
939
1051
|
await ctx.database.create("ggcevo_welfare", {
|
|
940
1052
|
handle,
|
|
941
|
-
activity: id,
|
|
1053
|
+
activity: activity.id,
|
|
942
1054
|
lastdate: /* @__PURE__ */ new Date()
|
|
943
1055
|
});
|
|
944
|
-
|
|
945
|
-
handle,
|
|
946
|
-
itemId: 1,
|
|
947
|
-
quantity: (backpack.quantity || 0) + quantity
|
|
948
|
-
}]);
|
|
949
|
-
return `[活动福利] 成功领取 ${name2} 咕咕币活动奖励,获得 ${quantity} 枚咕咕币`;
|
|
1056
|
+
return `您成功领取 ${name2} 活动奖励:${activity.itemId === 0 ? `${activity.quantity}枚金币` : `${activity.quantity}个${itemIdToName[activity.itemId] || "未知物品"}`}`;
|
|
950
1057
|
});
|
|
951
|
-
ctx.command("ggcevo/创建活动 <
|
|
952
|
-
if (!
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
const
|
|
963
|
-
|
|
964
|
-
|
|
1058
|
+
ctx.command("ggcevo/创建活动 <activityName> <itemName> <quantity:number> <description>", "创建新活动", { authority: 3 }).option("start", "-s <startTime:date>", { fallback: Date.now() }).option("duration", "-d <days:number>", { fallback: 7 }).action(async ({ session, options }, activityName, itemName, quantity, description) => {
|
|
1059
|
+
if (!activityName) return "活动名称不能为空。";
|
|
1060
|
+
if (!itemName) return "物品名称不能为空。";
|
|
1061
|
+
let itemId;
|
|
1062
|
+
if (itemName === "金币") {
|
|
1063
|
+
itemId = 0;
|
|
1064
|
+
} else {
|
|
1065
|
+
const entry = Object.entries(initDefaultItems).find(([name2]) => name2 === itemName);
|
|
1066
|
+
if (!entry) return `物品 ${itemName} 不存在`;
|
|
1067
|
+
itemId = entry[1].id;
|
|
1068
|
+
}
|
|
1069
|
+
const [existing] = await ctx.database.get("ggcevo_activity", { name: activityName });
|
|
1070
|
+
if (existing) return "同名活动已存在。";
|
|
1071
|
+
const start = new Date(options.start);
|
|
1072
|
+
const end = new Date(start.getTime() + options.duration * 864e5);
|
|
1073
|
+
const status = start <= /* @__PURE__ */ new Date() ? "进行中" : "未开始";
|
|
1074
|
+
await ctx.database.create("ggcevo_activity", {
|
|
1075
|
+
name: activityName,
|
|
965
1076
|
description,
|
|
966
1077
|
quantity,
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
status
|
|
971
|
-
|
|
1078
|
+
itemId,
|
|
1079
|
+
startTime: start,
|
|
1080
|
+
endTime: end,
|
|
1081
|
+
status,
|
|
1082
|
+
creator: session.userId
|
|
972
1083
|
});
|
|
973
|
-
return
|
|
974
|
-
ID:${activity.id}
|
|
975
|
-
状态:${status}`;
|
|
1084
|
+
return `活动【${activityName}】创建成功!奖励内容:${itemName} ×${quantity}。`;
|
|
976
1085
|
});
|
|
977
|
-
ctx.command("ggcevo
|
|
978
|
-
const activities = await ctx.database.get(
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
`描述:${activity.description}`,
|
|
994
|
-
`奖励:${activity.quantity} 枚咕咕币`,
|
|
995
|
-
"━━━━━━━━━━━━━━"
|
|
996
|
-
].join("\n"));
|
|
997
|
-
return output.length ? output.join("\n\n") : "当前没有进行中的咕咕币活动";
|
|
1086
|
+
ctx.command("ggcevo/活动列表").action(async () => {
|
|
1087
|
+
const activities = await ctx.database.get(
|
|
1088
|
+
"ggcevo_activity",
|
|
1089
|
+
{ status: "进行中" },
|
|
1090
|
+
{ sort: { startTime: "desc" } }
|
|
1091
|
+
);
|
|
1092
|
+
const itemMap = /* @__PURE__ */ new Map();
|
|
1093
|
+
Object.entries(initDefaultItems).forEach(([name2, data]) => itemMap.set(data.id, name2));
|
|
1094
|
+
itemMap.set(0, "金币");
|
|
1095
|
+
return activities.length ? activities.map((a) => [
|
|
1096
|
+
`活动名称:${a.name}`,
|
|
1097
|
+
`活动时间:${formatDate(a.startTime)} - ${formatDate(a.endTime)}`,
|
|
1098
|
+
`活动描述:${a.description}`,
|
|
1099
|
+
`活动奖励:${a.quantity} × ${itemMap.get(a.itemId) || "未知物品"}`,
|
|
1100
|
+
"━".repeat(20)
|
|
1101
|
+
].join("\n")).join("\n\n") : "当前没有进行中的活动。";
|
|
998
1102
|
});
|
|
999
1103
|
ctx.setInterval(async () => {
|
|
1000
1104
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -1077,7 +1181,7 @@ ID:${activity.id}
|
|
|
1077
1181
|
}
|
|
1078
1182
|
}
|
|
1079
1183
|
}, 60 * 60 * 1e3);
|
|
1080
|
-
ctx.command("ggcevo
|
|
1184
|
+
ctx.command("ggcevo/数据同步", { authority: 3 }).action(async () => {
|
|
1081
1185
|
try {
|
|
1082
1186
|
const ggcmap = await ctx.database.get("sc2arcade_map", { guildId: config.ggcqun });
|
|
1083
1187
|
const lastdate = ggcmap[0].lastdate;
|
|
@@ -1132,13 +1236,13 @@ ID:${activity.id}
|
|
|
1132
1236
|
lastdate: new Date(currentMaxDate.toISOString())
|
|
1133
1237
|
});
|
|
1134
1238
|
}
|
|
1135
|
-
return "
|
|
1239
|
+
return "✅ 胜点榜数据同步成功!";
|
|
1136
1240
|
} catch (err) {
|
|
1137
1241
|
console.error("错误:", err);
|
|
1138
1242
|
return "服务器繁忙,请稍后尝试。";
|
|
1139
1243
|
}
|
|
1140
1244
|
});
|
|
1141
|
-
ctx.command("ggcevo/胜点榜 [page]").alias("排行榜").usage("输入
|
|
1245
|
+
ctx.command("ggcevo/胜点榜 [page]").alias("排行榜").usage("输入 胜点榜 [页码] 查看对应页的排行榜,每页10条").action(async (_, page) => {
|
|
1142
1246
|
const pageNum = parseInt(page) || 1;
|
|
1143
1247
|
if (pageNum < 1) return "请输入有效的页码。";
|
|
1144
1248
|
const offset = (pageNum - 1) * 10;
|
|
@@ -1160,9 +1264,8 @@ ID:${activity.id}
|
|
|
1160
1264
|
(item, index) => `${offset + index + 1}. ${item.displayName} | 积分: ${item.rank} | 胜率: ${item.matches === 0 ? "0.00%" : (item.wins / item.matches * 100).toFixed(2) + "%"}`
|
|
1161
1265
|
).join("\n");
|
|
1162
1266
|
return [
|
|
1163
|
-
`🏆
|
|
1164
|
-
|
|
1165
|
-
`数据同步时间: ${lastdate.toLocaleString("zh-CN", {
|
|
1267
|
+
`🏆 咕咕胜点榜 ${config.rankseason}赛季 🏆`,
|
|
1268
|
+
`数据最新同步时间: ${lastdate.toLocaleString("zh-CN", {
|
|
1166
1269
|
timeZone: "Asia/Shanghai",
|
|
1167
1270
|
year: "numeric",
|
|
1168
1271
|
month: "2-digit",
|
|
@@ -1175,7 +1278,7 @@ ID:${activity.id}
|
|
|
1175
1278
|
rankingText,
|
|
1176
1279
|
"------------------------------",
|
|
1177
1280
|
`第 ${pageNum} 页 / 共 ${totalPages} 页`,
|
|
1178
|
-
pageNum < totalPages ?
|
|
1281
|
+
pageNum < totalPages ? `输入“胜点榜 ${pageNum + 1}”查看下一页` : "已是最后一页"
|
|
1179
1282
|
].join("\n");
|
|
1180
1283
|
});
|
|
1181
1284
|
ctx.command("ggcevo/排名 [player]", "查询个人排名").alias("rank").usage("输入“排名”查看自己的排名信息").action(async (argv, player) => {
|
|
@@ -1183,29 +1286,29 @@ ID:${activity.id}
|
|
|
1183
1286
|
if (!player) {
|
|
1184
1287
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
1185
1288
|
if (!profile) {
|
|
1186
|
-
return "
|
|
1289
|
+
return "您暂未绑定句柄。";
|
|
1187
1290
|
}
|
|
1188
1291
|
const { regionId, realmId, profileId } = profile;
|
|
1189
1292
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
1190
1293
|
const [user] = await ctx.database.get("ggcevo_rank", {
|
|
1191
1294
|
handle
|
|
1192
1295
|
});
|
|
1193
|
-
if (!user) return "
|
|
1194
|
-
if (user.Blacklist) return "
|
|
1296
|
+
if (!user) return "暂未找到您的排名信息。";
|
|
1297
|
+
if (user.Blacklist) return "❌ 您已经被禁止参加本赛季胜点榜。";
|
|
1195
1298
|
const allRanks = await ctx.database.select("ggcevo_rank").where({ Blacklist: false }).orderBy("rank", "desc").execute();
|
|
1196
1299
|
const userRank = allRanks.findIndex(
|
|
1197
1300
|
(u) => u.handle === handle
|
|
1198
1301
|
) + 1;
|
|
1199
1302
|
const isSafe = await checkSensitiveWord(user.name);
|
|
1200
1303
|
const displayName = isSafe ? user.name : (user.name[0] || "") + "***";
|
|
1201
|
-
return `🎮
|
|
1304
|
+
return `🎮 您的咕咕胜点榜排名信息 🎮
|
|
1202
1305
|
------------------------------
|
|
1203
1306
|
昵称:${displayName}
|
|
1204
1307
|
句柄:${user.handle}
|
|
1205
1308
|
当前积分:${user.rank}
|
|
1206
1309
|
参赛次数:${user.matches} 次
|
|
1207
1310
|
胜率: ${user.matches === 0 ? "0.00%" : (user.wins / user.matches * 100).toFixed(2) + "%"}
|
|
1208
|
-
全服排名:第 ${userRank}
|
|
1311
|
+
全服排名:第 ${userRank} 名
|
|
1209
1312
|
------------------------------`;
|
|
1210
1313
|
} else {
|
|
1211
1314
|
const parsedUser = import_koishi.h.parse(player)[0];
|
|
@@ -1216,51 +1319,67 @@ ID:${activity.id}
|
|
|
1216
1319
|
let targetUsername = parsedUser.attrs.name || targetUserId;
|
|
1217
1320
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: targetUsername });
|
|
1218
1321
|
if (!profile) {
|
|
1219
|
-
return "
|
|
1322
|
+
return "对方暂未绑定句柄。";
|
|
1220
1323
|
}
|
|
1221
1324
|
const { regionId, realmId, profileId } = profile;
|
|
1222
1325
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
1223
1326
|
const [user] = await ctx.database.get("ggcevo_rank", {
|
|
1224
1327
|
handle
|
|
1225
1328
|
});
|
|
1226
|
-
if (!user) return "
|
|
1227
|
-
if (user.Blacklist) return "
|
|
1329
|
+
if (!user) return "暂未找到对方的排名信息。";
|
|
1330
|
+
if (user.Blacklist) return "❌ 对方已经被禁止参加本赛季胜点榜。";
|
|
1228
1331
|
const allRanks = await ctx.database.select("ggcevo_rank").where({ Blacklist: false }).orderBy("rank", "desc").execute();
|
|
1229
1332
|
const userRank = allRanks.findIndex(
|
|
1230
1333
|
(u) => u.handle === handle
|
|
1231
1334
|
) + 1;
|
|
1232
1335
|
const isSafe = await checkSensitiveWord(user.name);
|
|
1233
1336
|
const displayName = isSafe ? user.name : (user.name[0] || "") + "***";
|
|
1234
|
-
return `🎮
|
|
1337
|
+
return `🎮 对方的咕咕胜点榜排名信息 🎮
|
|
1235
1338
|
------------------------------
|
|
1236
1339
|
昵称:${displayName}
|
|
1237
1340
|
句柄:${user.handle}
|
|
1238
1341
|
当前积分:${user.rank}
|
|
1239
1342
|
参赛次数:${user.matches} 次
|
|
1240
1343
|
胜率: ${user.matches === 0 ? "0.00%" : (user.wins / user.matches * 100).toFixed(2) + "%"}
|
|
1241
|
-
全服排名:第 ${userRank}
|
|
1344
|
+
全服排名:第 ${userRank} 名
|
|
1242
1345
|
------------------------------`;
|
|
1243
1346
|
}
|
|
1244
1347
|
});
|
|
1245
|
-
ctx.command("ggcevo/给予 <handle> <
|
|
1348
|
+
ctx.command("ggcevo/给予 <handle> <itemName:string> <amount:number>", "增加用户物品/金币", { authority: 3 }).action(async (_, handle, itemName, amount) => {
|
|
1246
1349
|
try {
|
|
1247
|
-
if (!handle || !
|
|
1248
|
-
return
|
|
1350
|
+
if (!handle || !itemName || amount <= 0) {
|
|
1351
|
+
return "参数格式错误,正确格式:给予 用户句柄 物品名称 数量";
|
|
1249
1352
|
}
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1353
|
+
if (itemName === "金币") {
|
|
1354
|
+
const [signData] = await ctx.database.get("ggcevo_sign", { handle });
|
|
1355
|
+
await ctx.database.upsert("ggcevo_sign", [{
|
|
1356
|
+
handle,
|
|
1357
|
+
totalRewards: (signData?.totalRewards || 0) + Math.floor(amount),
|
|
1358
|
+
lastSign: signData?.lastSign || /* @__PURE__ */ new Date(0),
|
|
1359
|
+
// 保持原有最后签到时间
|
|
1360
|
+
monthlyDays: signData?.monthlyDays || 0
|
|
1361
|
+
// 保持月签到天数
|
|
1362
|
+
}]);
|
|
1363
|
+
return `成功为 ${handle} 添加 ${amount} 金币!当前金币总数:${(signData?.totalRewards || 0) + amount}`;
|
|
1364
|
+
}
|
|
1365
|
+
const validItems = Object.keys(initDefaultItems);
|
|
1366
|
+
if (!validItems.includes(itemName)) {
|
|
1367
|
+
return `无效物品名称,可用物品:${validItems.join("、")}`;
|
|
1368
|
+
}
|
|
1369
|
+
const itemId = initDefaultItems[itemName].id;
|
|
1370
|
+
const [backpack] = await ctx.database.get("ggcevo_backpack", {
|
|
1371
|
+
handle,
|
|
1372
|
+
itemId
|
|
1373
|
+
});
|
|
1255
1374
|
await ctx.database.upsert("ggcevo_backpack", [{
|
|
1256
1375
|
handle,
|
|
1257
1376
|
itemId,
|
|
1258
|
-
quantity: (backpack?.quantity || 0) + amount
|
|
1377
|
+
quantity: (backpack?.quantity || 0) + Math.floor(amount)
|
|
1259
1378
|
}], ["handle", "itemId"]);
|
|
1260
|
-
return `成功为 ${handle}
|
|
1379
|
+
return `成功为 ${handle} 添加 ${amount} 个${itemName}!当前总数:${(backpack?.quantity || 0) + amount}`;
|
|
1261
1380
|
} catch (err) {
|
|
1262
|
-
console.error("
|
|
1263
|
-
return "
|
|
1381
|
+
console.error("[给予命令错误]", err);
|
|
1382
|
+
return "操作失败:" + (err instanceof Error ? err.message : "数据库异常");
|
|
1264
1383
|
}
|
|
1265
1384
|
});
|
|
1266
1385
|
ctx.command("ggcevo/违规记录 [user]", "违规记录查询").usage("输入 违规记录 [@用户] -p 页码 查看处罚记录,每页1条").option("p", "-p <page:number> 指定页码").action(async (argv) => {
|
|
@@ -1270,7 +1389,7 @@ ID:${activity.id}
|
|
|
1270
1389
|
let handle;
|
|
1271
1390
|
if (!user) {
|
|
1272
1391
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
1273
|
-
if (!profile) return "
|
|
1392
|
+
if (!profile) return "您暂未绑定句柄。";
|
|
1274
1393
|
handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
1275
1394
|
} else {
|
|
1276
1395
|
const parsedUser = import_koishi.h.parse(user)[0];
|
|
@@ -1281,7 +1400,7 @@ ID:${activity.id}
|
|
|
1281
1400
|
let targetUsername = parsedUser.attrs.name || targetUserId;
|
|
1282
1401
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: targetUsername });
|
|
1283
1402
|
if (!profile) {
|
|
1284
|
-
return "
|
|
1403
|
+
return "对方暂未绑定句柄。";
|
|
1285
1404
|
}
|
|
1286
1405
|
const { regionId, realmId, profileId } = profile;
|
|
1287
1406
|
handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
@@ -1313,17 +1432,17 @@ ID:${activity.id}
|
|
|
1313
1432
|
"------------------------------",
|
|
1314
1433
|
recordText,
|
|
1315
1434
|
"------------------------------",
|
|
1316
|
-
pageNum < totalPages ? `输入 违规记录 -p ${pageNum + 1} 查看下一条` : "已是最后一页"
|
|
1435
|
+
pageNum < totalPages ? `输入 违规记录 (@用户) -p ${pageNum + 1} 查看下一条` : "已是最后一页"
|
|
1317
1436
|
].join("\n");
|
|
1318
1437
|
});
|
|
1319
1438
|
ctx.command("ggcevo/兑换", "兑换物品").action(async ({ session }) => {
|
|
1320
1439
|
try {
|
|
1321
1440
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
1322
|
-
if (!profile) return "
|
|
1441
|
+
if (!profile) return "您暂未绑定句柄";
|
|
1323
1442
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
1324
1443
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
1325
1444
|
if (existingEntries.length > 0) {
|
|
1326
|
-
return
|
|
1445
|
+
return `❌ 拒绝访问,您已被列入黑名单。`;
|
|
1327
1446
|
}
|
|
1328
1447
|
const currentSeason = config.rankseason;
|
|
1329
1448
|
const qualityGroups = {};
|
|
@@ -1349,7 +1468,7 @@ ID:${activity.id}
|
|
|
1349
1468
|
qualityGroups[quality].push(`${itemName}${quantityText}`);
|
|
1350
1469
|
}
|
|
1351
1470
|
const order = ["t0", "t1", "t2", "t3"];
|
|
1352
|
-
let message = "请在30
|
|
1471
|
+
let message = "请在30秒内输入可兑换物品(显示格式:物品名 [剩余/总量]):\n";
|
|
1353
1472
|
for (const quality of order) {
|
|
1354
1473
|
const items = qualityGroups[quality] || [];
|
|
1355
1474
|
if (!items.length) continue;
|
|
@@ -1360,11 +1479,11 @@ ${items.join("、")}
|
|
|
1360
1479
|
}
|
|
1361
1480
|
await session.send(message);
|
|
1362
1481
|
const name2 = await session.prompt(3e4);
|
|
1363
|
-
if (!name2) return "
|
|
1482
|
+
if (!name2) return "输入超时,请重新输入。";
|
|
1364
1483
|
const configname = itemConfig[name2];
|
|
1365
|
-
if (!configname) return "
|
|
1484
|
+
if (!configname) return "无效的物品名称,请重新输入。";
|
|
1366
1485
|
const userRecords = await ctx.database.get("ggcevo_exchange", { handle, item: name2 });
|
|
1367
|
-
if (userRecords.length > 0) return "
|
|
1486
|
+
if (userRecords.length > 0) return "您已经兑换过该物品。";
|
|
1368
1487
|
if (configname.quantity !== void 0 && (configname.isLimited || config.ignoreGlobalLimit === false)) {
|
|
1369
1488
|
const queryConditions = {
|
|
1370
1489
|
item: name2,
|
|
@@ -1374,7 +1493,7 @@ ${items.join("、")}
|
|
|
1374
1493
|
queryConditions.season = currentSeason;
|
|
1375
1494
|
}
|
|
1376
1495
|
const globalRecords = await ctx.database.get("ggcevo_exchange", queryConditions);
|
|
1377
|
-
if (globalRecords.length >= configname.quantity) return "
|
|
1496
|
+
if (globalRecords.length >= configname.quantity) return "该物品已被兑换完了。";
|
|
1378
1497
|
}
|
|
1379
1498
|
const qualityMap = { "t3": 4, "t2": 5, "t1": 6, "t0": 7 };
|
|
1380
1499
|
const petItems = new Set(
|
|
@@ -1397,7 +1516,7 @@ ${items.join("、")}
|
|
|
1397
1516
|
}
|
|
1398
1517
|
const [coupon] = await ctx.database.get("ggcevo_backpack", { handle, itemId });
|
|
1399
1518
|
if (!coupon || coupon.quantity < cost) {
|
|
1400
|
-
const requireMsg = petItems.has(name2) ? `需要
|
|
1519
|
+
const requireMsg = petItems.has(name2) ? `需要1个${configname.quality}级宠物扭蛋 或${configname.cost}张兑奖券` : `需要${configname.cost}张兑奖券`;
|
|
1401
1520
|
return `${requireMsg}
|
|
1402
1521
|
当前持有:${coupon?.quantity || 0}个${couponName}`;
|
|
1403
1522
|
}
|
|
@@ -1420,7 +1539,7 @@ ${items.join("、")}
|
|
|
1420
1539
|
season: currentSeason
|
|
1421
1540
|
});
|
|
1422
1541
|
});
|
|
1423
|
-
return
|
|
1542
|
+
return `兑换成功!消耗${cost}个${couponName}获得【${name2}】`;
|
|
1424
1543
|
} catch (error) {
|
|
1425
1544
|
console.error("兑换失败:", error);
|
|
1426
1545
|
return "兑换失败";
|
|
@@ -1428,7 +1547,7 @@ ${items.join("、")}
|
|
|
1428
1547
|
});
|
|
1429
1548
|
ctx.command("ggcevo/兑换记录").action(async ({ session }) => {
|
|
1430
1549
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
1431
|
-
if (!profile) return "
|
|
1550
|
+
if (!profile) return "您暂未绑定句柄";
|
|
1432
1551
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
1433
1552
|
const exchanges = await ctx.database.get("ggcevo_exchange", { handle });
|
|
1434
1553
|
if (!exchanges.length) return "您暂无兑换记录";
|
|
@@ -1447,16 +1566,16 @@ ${output}`;
|
|
|
1447
1566
|
});
|
|
1448
1567
|
ctx.command("ggcevo/兑换扭蛋币").action(async ({ session }) => {
|
|
1449
1568
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
1450
|
-
if (!profile) return "
|
|
1569
|
+
if (!profile) return "您暂未绑定句柄。";
|
|
1451
1570
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
1452
1571
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
1453
1572
|
if (existingEntries.length > 0) {
|
|
1454
|
-
return
|
|
1573
|
+
return `❌ 拒绝访问,您已被列入黑名单。`;
|
|
1455
1574
|
}
|
|
1456
1575
|
const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 3 });
|
|
1457
1576
|
const [coupon] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 2 });
|
|
1458
1577
|
if (!coupon || coupon.quantity < 3) {
|
|
1459
|
-
return `兑换扭蛋币需要
|
|
1578
|
+
return `兑换扭蛋币需要3张兑奖券,当前持有:${coupon?.quantity || 0}`;
|
|
1460
1579
|
}
|
|
1461
1580
|
await ctx.database.set(
|
|
1462
1581
|
"ggcevo_backpack",
|
|
@@ -1468,19 +1587,19 @@ ${output}`;
|
|
|
1468
1587
|
itemId: 3,
|
|
1469
1588
|
quantity: (backpack?.quantity || 0) + 1
|
|
1470
1589
|
}]);
|
|
1471
|
-
return `兑换成功!消耗
|
|
1590
|
+
return `兑换成功!消耗3张兑奖券获得1枚扭蛋币`;
|
|
1472
1591
|
});
|
|
1473
1592
|
ctx.command("ggcevo/扭蛋").action(async (argv) => {
|
|
1474
1593
|
const session = argv.session;
|
|
1475
1594
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
1476
1595
|
if (!profile) {
|
|
1477
|
-
return "
|
|
1596
|
+
return "您暂未绑定句柄。";
|
|
1478
1597
|
}
|
|
1479
1598
|
const { regionId, realmId, profileId } = profile;
|
|
1480
1599
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
1481
1600
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
1482
1601
|
if (existingEntries.length > 0) {
|
|
1483
|
-
return
|
|
1602
|
+
return `❌ 拒绝访问,您已被列入黑名单。`;
|
|
1484
1603
|
}
|
|
1485
1604
|
const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 3 });
|
|
1486
1605
|
if (!backpack || backpack.quantity < 1) {
|
|
@@ -1506,16 +1625,16 @@ ${output}`;
|
|
|
1506
1625
|
itemId: itemData.id,
|
|
1507
1626
|
quantity: currentQuantity + 1
|
|
1508
1627
|
}]);
|
|
1509
|
-
return `🎉
|
|
1628
|
+
return `🎉 恭喜您获得:${itemName}`;
|
|
1510
1629
|
});
|
|
1511
|
-
ctx.command("ggcevo
|
|
1630
|
+
ctx.command("ggcevo/拉黑", "添加用户到黑名单").action(async (argv) => {
|
|
1512
1631
|
const session = argv.session;
|
|
1513
1632
|
if (!ctx.config.admins.includes(session.userId)) {
|
|
1514
|
-
return "⚠️
|
|
1633
|
+
return "⚠️ 没有操作权限。";
|
|
1515
1634
|
}
|
|
1516
1635
|
await session.send("请在30秒内输入需要拉黑的句柄:\n(句柄格式为: [区域ID]-S2-[服务器ID]-[档案ID])");
|
|
1517
1636
|
const handle = await session.prompt(3e4);
|
|
1518
|
-
if (!handle) return "
|
|
1637
|
+
if (!handle) return "输入超时,请重新输入。";
|
|
1519
1638
|
try {
|
|
1520
1639
|
const handleRegex = /^([1235])-S2-([12])-(\d+)$/;
|
|
1521
1640
|
if (!handleRegex.test(handle)) {
|
|
@@ -1523,40 +1642,40 @@ ${output}`;
|
|
|
1523
1642
|
}
|
|
1524
1643
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
1525
1644
|
if (existingEntries.length > 0) {
|
|
1526
|
-
return `${handle}
|
|
1645
|
+
return `${handle}已在黑名单中。`;
|
|
1527
1646
|
}
|
|
1528
1647
|
await ctx.database.create("ggcevo_blacklist", {
|
|
1529
1648
|
handle,
|
|
1530
1649
|
createdAt: /* @__PURE__ */ new Date()
|
|
1531
1650
|
});
|
|
1532
|
-
return `✅
|
|
1651
|
+
return `✅ 用户${handle}已被列入黑名单。`;
|
|
1533
1652
|
} catch (error) {
|
|
1534
1653
|
console.error("黑名单操作失败:", error);
|
|
1535
1654
|
return "操作失败,请稍后重试。错误详情已记录";
|
|
1536
1655
|
}
|
|
1537
1656
|
});
|
|
1538
|
-
ctx.command("ggcevo
|
|
1657
|
+
ctx.command("ggcevo/标记", "标记用户到胜点榜黑名单").action(async (argv) => {
|
|
1539
1658
|
const session = argv.session;
|
|
1540
1659
|
if (!ctx.config.admins.includes(session.userId)) {
|
|
1541
|
-
return "⚠️
|
|
1660
|
+
return "⚠️ 没有操作权限。";
|
|
1542
1661
|
}
|
|
1543
|
-
await session.send("请在30
|
|
1662
|
+
await session.send("请在30秒内输入需要标记的句柄:\n(句柄格式为: [区域ID]-S2-[服务器ID]-[档案ID])");
|
|
1544
1663
|
const handle = await session.prompt(3e4);
|
|
1545
|
-
if (!handle) return "
|
|
1664
|
+
if (!handle) return "输入超时,请重新输入。";
|
|
1546
1665
|
try {
|
|
1547
1666
|
const handleRegex = /^([1235])-S2-([12])-(\d+)$/;
|
|
1548
1667
|
if (!handleRegex.test(handle)) {
|
|
1549
|
-
return "
|
|
1668
|
+
return "句柄格式错误,请重新输入。";
|
|
1550
1669
|
}
|
|
1551
1670
|
const existingEntries = await ctx.database.get("ggcevo_rank", { handle, Blacklist: true });
|
|
1552
1671
|
if (existingEntries.length > 0) {
|
|
1553
|
-
return `${handle}
|
|
1672
|
+
return `${handle}已被标记在咕咕胜点榜黑名单中。`;
|
|
1554
1673
|
}
|
|
1555
1674
|
await ctx.database.upsert("ggcevo_rank", [{
|
|
1556
1675
|
handle,
|
|
1557
1676
|
Blacklist: true
|
|
1558
1677
|
}]);
|
|
1559
|
-
return `✅
|
|
1678
|
+
return `✅ 用户${handle}已被标记在咕咕胜点榜黑名单。`;
|
|
1560
1679
|
} catch (error) {
|
|
1561
1680
|
console.error("黑名单操作失败:", error);
|
|
1562
1681
|
return "操作失败,请稍后重试。错误详情已记录";
|
|
@@ -1565,14 +1684,14 @@ ${output}`;
|
|
|
1565
1684
|
ctx.command("ggcevo/成就").action(async ({ session }) => {
|
|
1566
1685
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
1567
1686
|
if (!profile) {
|
|
1568
|
-
return "
|
|
1687
|
+
return "您暂未绑定句柄。";
|
|
1569
1688
|
}
|
|
1570
1689
|
const { regionId, realmId, profileId } = profile;
|
|
1571
1690
|
const achievements = await ctx.database.get("ggcevo_achievements", {
|
|
1572
1691
|
handle: `${regionId}-S2-${realmId}-${profileId}`
|
|
1573
1692
|
});
|
|
1574
1693
|
if (!achievements.length) {
|
|
1575
|
-
return "
|
|
1694
|
+
return "你还没有获得任何成就。";
|
|
1576
1695
|
}
|
|
1577
1696
|
const achievementList = achievements.map((achievement) => {
|
|
1578
1697
|
const date = new Date(achievement.gaintime);
|
|
@@ -1590,7 +1709,7 @@ ${achievementList.join("\n")}`;
|
|
|
1590
1709
|
const session = argv.session;
|
|
1591
1710
|
const output = [];
|
|
1592
1711
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
1593
|
-
if (!profile) return "
|
|
1712
|
+
if (!profile) return "您暂未绑定句柄。";
|
|
1594
1713
|
const { regionId, realmId, profileId } = profile;
|
|
1595
1714
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
1596
1715
|
output.push(`🎮 游戏句柄:${handle}
|
|
@@ -1721,22 +1840,22 @@ ${achievementList.join("\n")}`;
|
|
|
1721
1840
|
ctx.command("ggcevo/pk [user]", "发起玩家对战").alias("挑战").action(async (argv, user) => {
|
|
1722
1841
|
try {
|
|
1723
1842
|
const session = argv.session;
|
|
1724
|
-
if (!user) return
|
|
1843
|
+
if (!user) return "缺少参数,请输入“pk @指定pk玩家”。";
|
|
1725
1844
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
1726
|
-
if (!profile) return "
|
|
1845
|
+
if (!profile) return "您暂未绑定句柄。";
|
|
1727
1846
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
1728
1847
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
1729
1848
|
if (existingEntries.length > 0) {
|
|
1730
|
-
return
|
|
1849
|
+
return `❌ 拒绝访问,您已被列入黑名单。`;
|
|
1731
1850
|
}
|
|
1732
1851
|
const parsedUser = import_koishi.h.parse(user)[0];
|
|
1733
|
-
if (!parsedUser || parsedUser.type !== "at" || !parsedUser.attrs.id) return
|
|
1852
|
+
if (!parsedUser || parsedUser.type !== "at" || !parsedUser.attrs.id) return "参数格式错误,请输入“pk @指定pk玩家”。";
|
|
1734
1853
|
const targetUserId = parsedUser.attrs.id;
|
|
1735
1854
|
const [targetprofile] = await ctx.database.get("sc2arcade_player", { userId: targetUserId });
|
|
1736
|
-
if (!targetprofile) return "
|
|
1855
|
+
if (!targetprofile) return "对方尚未绑定句柄。";
|
|
1737
1856
|
const initiatorHandle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
1738
1857
|
const targetHandle = `${targetprofile.regionId}-S2-${targetprofile.realmId}-${targetprofile.profileId}`;
|
|
1739
|
-
if (initiatorHandle === targetHandle) return "
|
|
1858
|
+
if (initiatorHandle === targetHandle) return "不能挑战自己。";
|
|
1740
1859
|
let initiatorPK = {
|
|
1741
1860
|
handle: initiatorHandle,
|
|
1742
1861
|
total: 0,
|
|
@@ -1767,17 +1886,17 @@ ${achievementList.join("\n")}`;
|
|
|
1767
1886
|
if (dbTarget) Object.assign(targetPK, dbTarget);
|
|
1768
1887
|
});
|
|
1769
1888
|
if (!initiatorPK.enable) {
|
|
1770
|
-
return "您已关闭PK
|
|
1889
|
+
return "您已关闭PK功能,无法发起挑战。";
|
|
1771
1890
|
}
|
|
1772
1891
|
if (!targetPK.enable) {
|
|
1773
|
-
return "对方已关闭PK
|
|
1892
|
+
return "对方已关闭PK功能,无法接受挑战。";
|
|
1774
1893
|
}
|
|
1775
1894
|
const now = convertUTCtoChinaTime(/* @__PURE__ */ new Date());
|
|
1776
1895
|
if (!isSameDate(convertUTCtoChinaTime(initiatorPK.lastPK), now)) {
|
|
1777
1896
|
initiatorPK.todayCount = 0;
|
|
1778
1897
|
}
|
|
1779
1898
|
if (initiatorPK.todayCount >= config.dailyPKLimit) {
|
|
1780
|
-
return
|
|
1899
|
+
return `今日挑战次数已用尽(${config.dailyPKLimit}次/日)。`;
|
|
1781
1900
|
}
|
|
1782
1901
|
const nowChina = convertUTCtoChinaTime(/* @__PURE__ */ new Date());
|
|
1783
1902
|
const todayStart = new Date(nowChina);
|
|
@@ -1790,7 +1909,7 @@ ${achievementList.join("\n")}`;
|
|
|
1790
1909
|
date: { $gte: adjustedTime }
|
|
1791
1910
|
}).execute((row) => import_koishi.$.count(row.id));
|
|
1792
1911
|
if (sameOpponentCount > 0) {
|
|
1793
|
-
return "
|
|
1912
|
+
return "您今天已经挑战过该玩家,请明天再试。";
|
|
1794
1913
|
}
|
|
1795
1914
|
}
|
|
1796
1915
|
if (config.maxDailyBeChallenged > 0) {
|
|
@@ -1799,7 +1918,7 @@ ${achievementList.join("\n")}`;
|
|
|
1799
1918
|
date: { $gte: adjustedTime }
|
|
1800
1919
|
}).execute((row) => import_koishi.$.count(row.id));
|
|
1801
1920
|
if (beChallengedCount >= config.maxDailyBeChallenged) {
|
|
1802
|
-
return
|
|
1921
|
+
return `该玩家今日已被挑战太多次(最多${config.maxDailyBeChallenged}次)。`;
|
|
1803
1922
|
}
|
|
1804
1923
|
}
|
|
1805
1924
|
const [initiatorData, targetData] = await Promise.all([
|
|
@@ -1816,8 +1935,8 @@ ${achievementList.join("\n")}`;
|
|
|
1816
1935
|
]);
|
|
1817
1936
|
const initiatorGold = initiatorSign[0]?.totalRewards || 0;
|
|
1818
1937
|
const targetGold = targetSign[0]?.totalRewards || 0;
|
|
1819
|
-
if (initiatorGold < 100) return "发起者需要至少100
|
|
1820
|
-
if (targetGold < 100) return "对方金币不足100
|
|
1938
|
+
if (initiatorGold < 100) return "发起者需要至少100金币才能发起挑战。";
|
|
1939
|
+
if (targetGold < 100) return "对方金币不足100,无法应战。";
|
|
1821
1940
|
const rankDiff = initiatorRank - targetRank;
|
|
1822
1941
|
const clampedDiff = Math.min(Math.max(rankDiff, -1e4), 1e4);
|
|
1823
1942
|
const winRate = Math.min(Math.max(50 + clampedDiff * 5e-3, 5), 95);
|
|
@@ -1874,8 +1993,8 @@ ${achievementList.join("\n")}`;
|
|
|
1874
1993
|
});
|
|
1875
1994
|
const result = [
|
|
1876
1995
|
`⚔️【对战结果】${isWin ? "胜利" : "失败"}`,
|
|
1877
|
-
`🏅 挑战者:${initiatorRankname}
|
|
1878
|
-
`🛡️ 应战者:${targetRankname}
|
|
1996
|
+
`🏅 挑战者:${initiatorRankname}(积分 ${initiatorRank})`,
|
|
1997
|
+
`🛡️ 应战者:${targetRankname}(积分 ${targetRank})`,
|
|
1879
1998
|
`📊 胜率预测:${winRate.toFixed(1)}%`,
|
|
1880
1999
|
`🎰 金币变动:${stealPercentage}%`
|
|
1881
2000
|
];
|
|
@@ -1889,12 +2008,8 @@ ${achievementList.join("\n")}`;
|
|
|
1889
2008
|
});
|
|
1890
2009
|
ctx.command("ggcevo/切换pk状态", "切换玩家对战状态").action(async ({ session }) => {
|
|
1891
2010
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
1892
|
-
if (!profile) return "
|
|
2011
|
+
if (!profile) return "您暂未绑定句柄。";
|
|
1893
2012
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
1894
|
-
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
1895
|
-
if (existingEntries.length > 0) {
|
|
1896
|
-
return `❌拒绝访问,您已被列入活动黑名单。`;
|
|
1897
|
-
}
|
|
1898
2013
|
const [pkRecord] = await ctx.database.get("ggcevo_pk", { handle }) || [null];
|
|
1899
2014
|
const currentState = pkRecord?.enable ?? true;
|
|
1900
2015
|
const lastToggle = pkRecord?.lastToggle ?? /* @__PURE__ */ new Date(0);
|
|
@@ -1915,10 +2030,10 @@ ${achievementList.join("\n")}`;
|
|
|
1915
2030
|
const diffDays = Math.floor((now.getTime() - lastToggleTime.getTime()) / (1e3 * 3600 * 24));
|
|
1916
2031
|
if (diffDays < 3 && lastToggleTime.getTime() !== 0) {
|
|
1917
2032
|
const remaining = 3 - diffDays;
|
|
1918
|
-
return `状态切换冷却中,${remaining}
|
|
2033
|
+
return `状态切换冷却中,${remaining}天后再试(下次可切换时间:${new Date(lastToggle.getTime() + 3 * 864e5).toLocaleDateString("zh-CN")})。`;
|
|
1919
2034
|
}
|
|
1920
2035
|
const action = currentState ? "关闭" : "开启";
|
|
1921
|
-
await session.send(`您当前的PK状态为【${currentState ? "开启" : "关闭"}】,确认要${action}吗?(
|
|
2036
|
+
await session.send(`您当前的PK状态为【${currentState ? "开启" : "关闭"}】,确认要${action}吗?(s30秒内回复“是”确认)`);
|
|
1922
2037
|
const confirm = await session.prompt(3e4);
|
|
1923
2038
|
if (confirm !== "是") return "已取消操作";
|
|
1924
2039
|
await ctx.database.upsert("ggcevo_pk", [{
|
|
@@ -1937,8 +2052,26 @@ ${achievementList.join("\n")}`;
|
|
|
1937
2052
|
day: "2-digit"
|
|
1938
2053
|
})}`;
|
|
1939
2054
|
});
|
|
1940
|
-
ctx.command("ggcevo/武器库").action(async ({ session }) => {
|
|
1941
|
-
const
|
|
2055
|
+
ctx.command("ggcevo/武器库 [type]").usage("输入“武器库”查看类型,或“武器库 类型”查看详细武器信息").action(async ({ session }, type) => {
|
|
2056
|
+
const typeStats = Object.values(weaponConfig).reduce((stats, weapon) => {
|
|
2057
|
+
stats[weapon.type] = (stats[weapon.type] || 0) + 1;
|
|
2058
|
+
return stats;
|
|
2059
|
+
}, {});
|
|
2060
|
+
if (!type) {
|
|
2061
|
+
return [
|
|
2062
|
+
"🏪 咕咕军火武器库分类 🏪",
|
|
2063
|
+
'使用 "武器库 类型名称" 查看详细列表',
|
|
2064
|
+
"====================",
|
|
2065
|
+
...Object.entries(typeStats).map(([typeName, count]) => `▸ ${typeName} (${count}种)`)
|
|
2066
|
+
].join("\n");
|
|
2067
|
+
}
|
|
2068
|
+
const validTypes = Object.keys(typeStats);
|
|
2069
|
+
const normalizedType = validTypes.find((t) => t === type);
|
|
2070
|
+
if (!normalizedType) {
|
|
2071
|
+
return `无效武器类型,可用类型:
|
|
2072
|
+
${validTypes.join("、")}`;
|
|
2073
|
+
}
|
|
2074
|
+
const items = Object.entries(weaponConfig).filter(([_, config2]) => config2.type === normalizedType).map(([name2, config2]) => {
|
|
1942
2075
|
const tagEffectsDesc = config2.tagEffects ? Object.entries(config2.tagEffects).map(([tag, multiplier]) => `▸ 对${tag}目标造成${(multiplier * 100).toFixed(0)}%伤害`).join("\n") : "▸ 无特殊加成效果";
|
|
1943
2076
|
return [
|
|
1944
2077
|
`【${name2}】`,
|
|
@@ -1951,7 +2084,7 @@ ${achievementList.join("\n")}`;
|
|
|
1951
2084
|
].join("\n");
|
|
1952
2085
|
});
|
|
1953
2086
|
return [
|
|
1954
|
-
|
|
2087
|
+
`🏪 咕咕军火武器库 - ${normalizedType} 🏪`,
|
|
1955
2088
|
"使用“购买 武器名称”命令进行购买",
|
|
1956
2089
|
"====================",
|
|
1957
2090
|
...items
|
|
@@ -2009,15 +2142,14 @@ ${achievementList.join("\n")}`;
|
|
|
2009
2142
|
].join("\n");
|
|
2010
2143
|
}));
|
|
2011
2144
|
return [
|
|
2012
|
-
"🛡️
|
|
2145
|
+
"🛡️ 当前拥有的武器列表",
|
|
2013
2146
|
'使用"装备 武器名称"切换武器',
|
|
2014
2147
|
"⚡表示当前装备武器",
|
|
2015
2148
|
"────────────────",
|
|
2016
2149
|
...weaponDetails.length ? weaponDetails : ["空空如也,快去武器库看看吧!"],
|
|
2017
2150
|
"────────────────",
|
|
2018
2151
|
"💡 武器效果说明:",
|
|
2019
|
-
"
|
|
2020
|
-
"🔧 改装效果仅在战斗时计算"
|
|
2152
|
+
"🔧 改装效果会在战斗中生效"
|
|
2021
2153
|
].join("\n");
|
|
2022
2154
|
});
|
|
2023
2155
|
ctx.command("ggcevo/装备 <weapon>").action(async ({ session }, weapon) => {
|
|
@@ -2159,6 +2291,7 @@ ${achievementList.join("\n")}`;
|
|
|
2159
2291
|
});
|
|
2160
2292
|
ctx.command("ggcevo/攻击 <targetType>").usage("使用 攻击 主宰/zz 或 攻击 子代/zd 来选择攻击目标").action(async (argv, targetType) => {
|
|
2161
2293
|
const session = argv.session;
|
|
2294
|
+
let broadcastMessage = null;
|
|
2162
2295
|
const targetAliases = {
|
|
2163
2296
|
"主宰": ["主宰", "zz"],
|
|
2164
2297
|
"子代": ["子代", "zd"]
|
|
@@ -2172,10 +2305,10 @@ ${achievementList.join("\n")}`;
|
|
|
2172
2305
|
}
|
|
2173
2306
|
if (!normalizedTarget) return "请指定正确的攻击目标:主宰/zz 或 子代/zd";
|
|
2174
2307
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2175
|
-
if (!profile) return "
|
|
2308
|
+
if (!profile) return "您暂未绑定句柄。";
|
|
2176
2309
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
2177
2310
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
2178
|
-
if (existingEntries.length > 0) return "
|
|
2311
|
+
if (existingEntries.length > 0) return "❌ 拒绝访问,您已被列入黑名单。";
|
|
2179
2312
|
const config2 = ctx.config;
|
|
2180
2313
|
const unlimitedBossAttack = config2.unlimitedBossAttack;
|
|
2181
2314
|
if (!unlimitedBossAttack) {
|
|
@@ -2192,93 +2325,17 @@ ${achievementList.join("\n")}`;
|
|
|
2192
2325
|
handle,
|
|
2193
2326
|
equipped: true
|
|
2194
2327
|
});
|
|
2195
|
-
if (!equippedWeapon) return "
|
|
2328
|
+
if (!equippedWeapon) return "请先装备武器再挑战主宰。";
|
|
2196
2329
|
const activeBosses = await ctx.database.get("ggcevo_boss", { isActive: true });
|
|
2197
|
-
if (!activeBosses.length) return "
|
|
2330
|
+
if (!activeBosses.length) return "当前没有存活的主宰。";
|
|
2198
2331
|
const targetBoss = normalizedTarget === "主宰" ? activeBosses.find((b) => b.type === "主宰") : activeBosses.find((b) => b.type === "子代");
|
|
2199
|
-
if (!targetBoss) return `当前没有可攻击的${normalizedTarget === "主宰" ? "主宰" : "子代"}
|
|
2332
|
+
if (!targetBoss) return `当前没有可攻击的${normalizedTarget === "主宰" ? "主宰" : "子代"}。`;
|
|
2200
2333
|
const bossGroup = bossPool.find((group) => group.main.id === targetBoss.groupId);
|
|
2201
|
-
if (!bossGroup) return "无法获取BOSS
|
|
2334
|
+
if (!bossGroup) return "无法获取BOSS组信息,请联系管理员。";
|
|
2202
2335
|
const weaponConfigEntry = Object.entries(weaponConfig).find(([_, c]) => c.id === equippedWeapon.weaponId);
|
|
2203
2336
|
const [weaponName, weaponData] = weaponConfigEntry;
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
let hasCrit = false;
|
|
2207
|
-
let hasCrystal = false;
|
|
2208
|
-
let hasOverload = false;
|
|
2209
|
-
equippedWeapon.installedMods.forEach((mod) => {
|
|
2210
|
-
if (mod === "动能增幅") {
|
|
2211
|
-
totalModAdd += 0.2;
|
|
2212
|
-
}
|
|
2213
|
-
if (mod === "裂甲核心") {
|
|
2214
|
-
if (weaponName === modConfig["裂甲核心"].exclusiveTo) {
|
|
2215
|
-
totalModAdd += 0.4;
|
|
2216
|
-
}
|
|
2217
|
-
}
|
|
2218
|
-
if (mod === "棱镜水晶") {
|
|
2219
|
-
hasCrystal = true;
|
|
2220
|
-
}
|
|
2221
|
-
if (mod === "棱镜超载核心") {
|
|
2222
|
-
if (weaponName === modConfig["棱镜超载核心"].exclusiveTo) {
|
|
2223
|
-
hasOverload = true;
|
|
2224
|
-
}
|
|
2225
|
-
}
|
|
2226
|
-
});
|
|
2227
|
-
const totalCritRate = (hasCrystal ? 20 : 0) + (hasOverload ? 80 : 0);
|
|
2228
|
-
if (totalCritRate > 0 && Math.random() < totalCritRate / 100) {
|
|
2229
|
-
hasCrit = true;
|
|
2230
|
-
totalModAdd += 1;
|
|
2231
|
-
}
|
|
2232
|
-
damage = damage * (1 + totalModAdd);
|
|
2233
|
-
const targetBossConfig = targetBoss.type === "主宰" ? bossGroup.main : bossGroup.minions[0];
|
|
2234
|
-
if (targetBossConfig.tags && targetBossConfig.tags.length > 0) {
|
|
2235
|
-
const armorTags = targetBossConfig.tags.filter((tag) => ["重甲", "轻甲", "护盾"].includes(tag));
|
|
2236
|
-
const voidTags = targetBossConfig.tags.filter((tag) => ["惧热", "惧寒"].includes(tag));
|
|
2237
|
-
const typeTags = targetBossConfig.tags.filter((tag) => ["生物", "机械", "灵能"].includes(tag));
|
|
2238
|
-
let totalTagAdd = 0;
|
|
2239
|
-
armorTags.forEach((tag) => {
|
|
2240
|
-
let effectValue = weaponData.tagEffects?.[tag] ?? 1;
|
|
2241
|
-
if (tag === "重甲" && equippedWeapon.installedMods.includes("裂甲核心")) {
|
|
2242
|
-
effectValue = 1.2;
|
|
2243
|
-
}
|
|
2244
|
-
totalTagAdd += effectValue - 1;
|
|
2245
|
-
});
|
|
2246
|
-
voidTags.forEach((tag) => {
|
|
2247
|
-
const effectValue = weaponData.tagEffects?.[tag] ?? 1;
|
|
2248
|
-
totalTagAdd += effectValue - 1;
|
|
2249
|
-
});
|
|
2250
|
-
typeTags.forEach((tag) => {
|
|
2251
|
-
const effectValue = weaponData.tagEffects?.[tag] ?? 1;
|
|
2252
|
-
totalTagAdd += effectValue - 1;
|
|
2253
|
-
});
|
|
2254
|
-
damage *= 1 + totalTagAdd;
|
|
2255
|
-
}
|
|
2256
|
-
if (targetBossConfig.passive?.length) {
|
|
2257
|
-
let passiveEffect = 0;
|
|
2258
|
-
const effectivePassives = [...targetBossConfig.passive];
|
|
2259
|
-
if (targetBoss.type === "主宰" && effectivePassives.includes("孤立无援")) {
|
|
2260
|
-
const activeMinions = await ctx.database.get("ggcevo_boss", {
|
|
2261
|
-
groupId: targetBoss.groupId,
|
|
2262
|
-
type: "子代",
|
|
2263
|
-
isActive: true
|
|
2264
|
-
});
|
|
2265
|
-
if (activeMinions.length !== 0) {
|
|
2266
|
-
effectivePassives.splice(effectivePassives.indexOf("孤立无援"), 1);
|
|
2267
|
-
}
|
|
2268
|
-
}
|
|
2269
|
-
effectivePassives.forEach((passive) => {
|
|
2270
|
-
const effect = passiveConfig[passive]?.effect || 0;
|
|
2271
|
-
passiveEffect += effect;
|
|
2272
|
-
});
|
|
2273
|
-
damage *= 1 + passiveEffect;
|
|
2274
|
-
}
|
|
2275
|
-
const [rankRecord] = await ctx.database.get("ggcevo_rank", { handle });
|
|
2276
|
-
if (rankRecord?.rank > 0) {
|
|
2277
|
-
const rankBonus = Math.floor(rankRecord.rank / 400) * 0.01;
|
|
2278
|
-
damage *= 1 + rankBonus;
|
|
2279
|
-
}
|
|
2280
|
-
damage = Math.round(damage);
|
|
2281
|
-
const actualDamage = Math.min(damage, targetBoss.HP);
|
|
2337
|
+
const { damage: baseDamage, hasCrit } = await calculateTotalDamage(ctx, session, equippedWeapon, targetBoss);
|
|
2338
|
+
const actualDamage = Math.min(baseDamage, targetBoss.HP);
|
|
2282
2339
|
const updatedHP = targetBoss.HP - actualDamage;
|
|
2283
2340
|
const isDefeated = updatedHP <= 0;
|
|
2284
2341
|
const [existingRecord] = await ctx.database.get("ggcevo_boss_damage", {
|
|
@@ -2290,6 +2347,7 @@ ${achievementList.join("\n")}`;
|
|
|
2290
2347
|
handle,
|
|
2291
2348
|
bossGroupId: targetBoss.groupId
|
|
2292
2349
|
}, {
|
|
2350
|
+
playerName: session.username,
|
|
2293
2351
|
totalDamage: existingRecord.totalDamage + actualDamage,
|
|
2294
2352
|
// 改为实际伤害
|
|
2295
2353
|
attackCount: existingRecord.attackCount + 1,
|
|
@@ -2413,13 +2471,13 @@ ${achievementList.join("\n")}`;
|
|
|
2413
2471
|
await ctx.database.remove("ggcevo_boss_damage", {
|
|
2414
2472
|
bossGroupId: targetBoss.groupId
|
|
2415
2473
|
});
|
|
2416
|
-
|
|
2417
|
-
`🎯 主宰 ${targetBoss.name}
|
|
2418
|
-
`所有子代已消失,下一个主宰将在1
|
|
2474
|
+
broadcastMessage = [
|
|
2475
|
+
`🎯 主宰 ${targetBoss.name} 已被 ${session.username} 击破!`,
|
|
2476
|
+
`所有子代已消失,下一个主宰将在1小时后重生`,
|
|
2419
2477
|
"",
|
|
2420
|
-
"
|
|
2478
|
+
"🏆 伤害排行榜奖励:",
|
|
2421
2479
|
...rewardMessages
|
|
2422
|
-
]
|
|
2480
|
+
];
|
|
2423
2481
|
} else {
|
|
2424
2482
|
await ctx.database.set(
|
|
2425
2483
|
"ggcevo_boss",
|
|
@@ -2429,11 +2487,10 @@ ${achievementList.join("\n")}`;
|
|
|
2429
2487
|
HP: 0
|
|
2430
2488
|
}
|
|
2431
2489
|
);
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
);
|
|
2490
|
+
broadcastMessage = [
|
|
2491
|
+
`⚡ ${session.username} 击破了子代 ${targetBoss.name}!`,
|
|
2492
|
+
`【连锁效果】主宰获得 20% 易伤状态!`
|
|
2493
|
+
];
|
|
2437
2494
|
}
|
|
2438
2495
|
} else {
|
|
2439
2496
|
await ctx.database.set(
|
|
@@ -2455,15 +2512,20 @@ ${achievementList.join("\n")}`;
|
|
|
2455
2512
|
// 改为实际伤害
|
|
2456
2513
|
});
|
|
2457
2514
|
}
|
|
2458
|
-
|
|
2515
|
+
const resultMessage = [
|
|
2459
2516
|
`🔥 ${session.username} 使用武器 ${weaponName} 对 ${targetBoss.name} 发起攻击!`,
|
|
2460
2517
|
`造成伤害:${actualDamage}${hasCrit ? "(✨ 暴击!)" : ""}`,
|
|
2461
|
-
// 改为实际伤害
|
|
2462
2518
|
`获得金币:${actualDamage}`,
|
|
2463
|
-
// 改为实际伤害
|
|
2464
2519
|
`目标剩余HP:${isDefeated ? 0 : updatedHP}/${targetBoss.type === "主宰" ? bossGroup.main.maxHP : bossGroup.minions[0].maxHP}`,
|
|
2465
2520
|
isDefeated ? `🎉 成功击败 ${targetBoss.name}!` : ""
|
|
2466
|
-
].filter((line) => line
|
|
2521
|
+
].filter((line) => line).join("\n");
|
|
2522
|
+
await session.send(resultMessage);
|
|
2523
|
+
if (broadcastMessage) {
|
|
2524
|
+
const finalBroadcast = Array.isArray(broadcastMessage) ? broadcastMessage.join("\n") : broadcastMessage;
|
|
2525
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
2526
|
+
ctx.broadcast(config2.groupId, finalBroadcast);
|
|
2527
|
+
}
|
|
2528
|
+
return;
|
|
2467
2529
|
});
|
|
2468
2530
|
ctx.command("ggcevo/初始化主宰", "初始化或重置主宰系统", { authority: 3 }).action(async () => {
|
|
2469
2531
|
try {
|
|
@@ -2509,19 +2571,15 @@ ${achievementList.join("\n")}`;
|
|
|
2509
2571
|
pageNum < totalPages ? `输入 伤害榜 ${pageNum + 1} 查看下一页` : "已是最后一页"
|
|
2510
2572
|
].join("\n");
|
|
2511
2573
|
});
|
|
2512
|
-
ctx.command("ggcevo
|
|
2574
|
+
ctx.command("ggcevo/主宰信息", "查看当前主宰信息").alias("zz信息").action(async () => {
|
|
2513
2575
|
const activeBosses = await ctx.database.get("ggcevo_boss", { isActive: true });
|
|
2514
|
-
if (!activeBosses.length) return "
|
|
2576
|
+
if (!activeBosses.length) return "当前没有存活的主宰。";
|
|
2515
2577
|
const mainBoss = activeBosses.find((b) => b.type === "主宰");
|
|
2516
2578
|
const minions = activeBosses.filter((b) => b.type === "子代");
|
|
2517
2579
|
if (!mainBoss) return "当前BOSS数据异常,请联系管理员";
|
|
2518
2580
|
const bossGroup = bossPool.find((group) => group.main.name === mainBoss.name);
|
|
2519
2581
|
if (!bossGroup) return "BOSS配置数据异常,请联系管理员";
|
|
2520
2582
|
const mainBossHpBar = createHpBar(mainBoss.HP, bossGroup.main.maxHP);
|
|
2521
|
-
const formatEffect = /* @__PURE__ */ __name((value) => {
|
|
2522
|
-
const percentage = Math.abs(value * 100);
|
|
2523
|
-
return value > 0 ? `受到的伤害+${percentage}%` : `受到的伤害-${percentage}%`;
|
|
2524
|
-
}, "formatEffect");
|
|
2525
2583
|
let passiveDisplay = [];
|
|
2526
2584
|
if (bossGroup.main.passive) {
|
|
2527
2585
|
const activeMinions = await ctx.database.get("ggcevo_boss", {
|
|
@@ -2533,8 +2591,7 @@ ${achievementList.join("\n")}`;
|
|
|
2533
2591
|
if (p === "孤立无援") return activeMinions.length === 0;
|
|
2534
2592
|
return true;
|
|
2535
2593
|
}).map((p) => {
|
|
2536
|
-
|
|
2537
|
-
return `${p}:${formatEffect(effect)}`;
|
|
2594
|
+
return `${p}:${passiveConfig[p].description}`;
|
|
2538
2595
|
});
|
|
2539
2596
|
}
|
|
2540
2597
|
const result = [
|
|
@@ -2544,12 +2601,12 @@ ${achievementList.join("\n")}`;
|
|
|
2544
2601
|
`被动:${passiveDisplay.join(",") || "无"}`
|
|
2545
2602
|
];
|
|
2546
2603
|
if (minions.length > 0) {
|
|
2547
|
-
result.push("", "🟠
|
|
2604
|
+
result.push("", "🟠 子代:");
|
|
2548
2605
|
minions.forEach((minion) => {
|
|
2549
2606
|
const minionConfig = bossGroup.minions.find((m) => m.name === minion.name);
|
|
2550
2607
|
if (minionConfig) {
|
|
2551
2608
|
const minionHpBar = createHpBar(minion.HP, minionConfig.maxHP);
|
|
2552
|
-
const minionPassives = (minionConfig.passive || []).map((p) => `${p}:${
|
|
2609
|
+
const minionPassives = (minionConfig.passive || []).map((p) => `${p}:${passiveConfig[p].description}`).join(",");
|
|
2553
2610
|
result.push(
|
|
2554
2611
|
`${minion.name}`,
|
|
2555
2612
|
`${minionHpBar} (${minion.HP}/${minionConfig.maxHP})`,
|
|
@@ -2618,6 +2675,17 @@ function convertUTCtoChinaTime(input) {
|
|
|
2618
2675
|
return new Date(chinaTimestamp);
|
|
2619
2676
|
}
|
|
2620
2677
|
__name(convertUTCtoChinaTime, "convertUTCtoChinaTime");
|
|
2678
|
+
function formatDate(d) {
|
|
2679
|
+
return d.toLocaleString("zh-CN", {
|
|
2680
|
+
timeZone: "Asia/Shanghai",
|
|
2681
|
+
year: "numeric",
|
|
2682
|
+
month: "2-digit",
|
|
2683
|
+
day: "2-digit",
|
|
2684
|
+
hour: "2-digit",
|
|
2685
|
+
minute: "2-digit"
|
|
2686
|
+
});
|
|
2687
|
+
}
|
|
2688
|
+
__name(formatDate, "formatDate");
|
|
2621
2689
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2622
2690
|
0 && (module.exports = {
|
|
2623
2691
|
Config,
|