koishi-plugin-ggcevo-game 1.2.13 → 1.2.15
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 +406 -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,112 @@ ${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
|
-
|
|
994
|
-
|
|
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 ? [
|
|
1096
|
+
...activities.map((a) => [
|
|
1097
|
+
`活动名称:${a.name}`,
|
|
1098
|
+
`活动时间:${formatDate(a.startTime)} - ${formatDate(a.endTime)}`,
|
|
1099
|
+
`活动描述:${a.description}`,
|
|
1100
|
+
`活动奖励:${a.quantity} × ${itemMap.get(a.itemId) || "未知物品"}`,
|
|
1101
|
+
"━".repeat(20)
|
|
1102
|
+
].join("\n")),
|
|
1103
|
+
"请输入「领取 活动名称」领取奖励"
|
|
1104
|
+
].join("\n") : "当前没有进行中的活动。";
|
|
998
1105
|
});
|
|
999
1106
|
ctx.setInterval(async () => {
|
|
1000
1107
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -1077,7 +1184,7 @@ ID:${activity.id}
|
|
|
1077
1184
|
}
|
|
1078
1185
|
}
|
|
1079
1186
|
}, 60 * 60 * 1e3);
|
|
1080
|
-
ctx.command("ggcevo
|
|
1187
|
+
ctx.command("ggcevo/数据同步", { authority: 3 }).action(async () => {
|
|
1081
1188
|
try {
|
|
1082
1189
|
const ggcmap = await ctx.database.get("sc2arcade_map", { guildId: config.ggcqun });
|
|
1083
1190
|
const lastdate = ggcmap[0].lastdate;
|
|
@@ -1132,13 +1239,13 @@ ID:${activity.id}
|
|
|
1132
1239
|
lastdate: new Date(currentMaxDate.toISOString())
|
|
1133
1240
|
});
|
|
1134
1241
|
}
|
|
1135
|
-
return "
|
|
1242
|
+
return "✅ 胜点榜数据同步成功!";
|
|
1136
1243
|
} catch (err) {
|
|
1137
1244
|
console.error("错误:", err);
|
|
1138
1245
|
return "服务器繁忙,请稍后尝试。";
|
|
1139
1246
|
}
|
|
1140
1247
|
});
|
|
1141
|
-
ctx.command("ggcevo/胜点榜 [page]").alias("排行榜").usage("输入
|
|
1248
|
+
ctx.command("ggcevo/胜点榜 [page]").alias("排行榜").usage("输入 胜点榜 [页码] 查看对应页的排行榜,每页10条").action(async (_, page) => {
|
|
1142
1249
|
const pageNum = parseInt(page) || 1;
|
|
1143
1250
|
if (pageNum < 1) return "请输入有效的页码。";
|
|
1144
1251
|
const offset = (pageNum - 1) * 10;
|
|
@@ -1160,9 +1267,8 @@ ID:${activity.id}
|
|
|
1160
1267
|
(item, index) => `${offset + index + 1}. ${item.displayName} | 积分: ${item.rank} | 胜率: ${item.matches === 0 ? "0.00%" : (item.wins / item.matches * 100).toFixed(2) + "%"}`
|
|
1161
1268
|
).join("\n");
|
|
1162
1269
|
return [
|
|
1163
|
-
`🏆
|
|
1164
|
-
|
|
1165
|
-
`数据同步时间: ${lastdate.toLocaleString("zh-CN", {
|
|
1270
|
+
`🏆 咕咕胜点榜 ${config.rankseason}赛季 🏆`,
|
|
1271
|
+
`数据最新同步时间: ${lastdate.toLocaleString("zh-CN", {
|
|
1166
1272
|
timeZone: "Asia/Shanghai",
|
|
1167
1273
|
year: "numeric",
|
|
1168
1274
|
month: "2-digit",
|
|
@@ -1175,7 +1281,7 @@ ID:${activity.id}
|
|
|
1175
1281
|
rankingText,
|
|
1176
1282
|
"------------------------------",
|
|
1177
1283
|
`第 ${pageNum} 页 / 共 ${totalPages} 页`,
|
|
1178
|
-
pageNum < totalPages ?
|
|
1284
|
+
pageNum < totalPages ? `输入“胜点榜 ${pageNum + 1}”查看下一页` : "已是最后一页"
|
|
1179
1285
|
].join("\n");
|
|
1180
1286
|
});
|
|
1181
1287
|
ctx.command("ggcevo/排名 [player]", "查询个人排名").alias("rank").usage("输入“排名”查看自己的排名信息").action(async (argv, player) => {
|
|
@@ -1183,29 +1289,29 @@ ID:${activity.id}
|
|
|
1183
1289
|
if (!player) {
|
|
1184
1290
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
1185
1291
|
if (!profile) {
|
|
1186
|
-
return "
|
|
1292
|
+
return "您暂未绑定句柄。";
|
|
1187
1293
|
}
|
|
1188
1294
|
const { regionId, realmId, profileId } = profile;
|
|
1189
1295
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
1190
1296
|
const [user] = await ctx.database.get("ggcevo_rank", {
|
|
1191
1297
|
handle
|
|
1192
1298
|
});
|
|
1193
|
-
if (!user) return "
|
|
1194
|
-
if (user.Blacklist) return "
|
|
1299
|
+
if (!user) return "暂未找到您的排名信息。";
|
|
1300
|
+
if (user.Blacklist) return "❌ 您已经被禁止参加本赛季胜点榜。";
|
|
1195
1301
|
const allRanks = await ctx.database.select("ggcevo_rank").where({ Blacklist: false }).orderBy("rank", "desc").execute();
|
|
1196
1302
|
const userRank = allRanks.findIndex(
|
|
1197
1303
|
(u) => u.handle === handle
|
|
1198
1304
|
) + 1;
|
|
1199
1305
|
const isSafe = await checkSensitiveWord(user.name);
|
|
1200
1306
|
const displayName = isSafe ? user.name : (user.name[0] || "") + "***";
|
|
1201
|
-
return `🎮
|
|
1307
|
+
return `🎮 您的咕咕胜点榜排名信息 🎮
|
|
1202
1308
|
------------------------------
|
|
1203
1309
|
昵称:${displayName}
|
|
1204
1310
|
句柄:${user.handle}
|
|
1205
1311
|
当前积分:${user.rank}
|
|
1206
1312
|
参赛次数:${user.matches} 次
|
|
1207
1313
|
胜率: ${user.matches === 0 ? "0.00%" : (user.wins / user.matches * 100).toFixed(2) + "%"}
|
|
1208
|
-
全服排名:第 ${userRank}
|
|
1314
|
+
全服排名:第 ${userRank} 名
|
|
1209
1315
|
------------------------------`;
|
|
1210
1316
|
} else {
|
|
1211
1317
|
const parsedUser = import_koishi.h.parse(player)[0];
|
|
@@ -1216,51 +1322,67 @@ ID:${activity.id}
|
|
|
1216
1322
|
let targetUsername = parsedUser.attrs.name || targetUserId;
|
|
1217
1323
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: targetUsername });
|
|
1218
1324
|
if (!profile) {
|
|
1219
|
-
return "
|
|
1325
|
+
return "对方暂未绑定句柄。";
|
|
1220
1326
|
}
|
|
1221
1327
|
const { regionId, realmId, profileId } = profile;
|
|
1222
1328
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
1223
1329
|
const [user] = await ctx.database.get("ggcevo_rank", {
|
|
1224
1330
|
handle
|
|
1225
1331
|
});
|
|
1226
|
-
if (!user) return "
|
|
1227
|
-
if (user.Blacklist) return "
|
|
1332
|
+
if (!user) return "暂未找到对方的排名信息。";
|
|
1333
|
+
if (user.Blacklist) return "❌ 对方已经被禁止参加本赛季胜点榜。";
|
|
1228
1334
|
const allRanks = await ctx.database.select("ggcevo_rank").where({ Blacklist: false }).orderBy("rank", "desc").execute();
|
|
1229
1335
|
const userRank = allRanks.findIndex(
|
|
1230
1336
|
(u) => u.handle === handle
|
|
1231
1337
|
) + 1;
|
|
1232
1338
|
const isSafe = await checkSensitiveWord(user.name);
|
|
1233
1339
|
const displayName = isSafe ? user.name : (user.name[0] || "") + "***";
|
|
1234
|
-
return `🎮
|
|
1340
|
+
return `🎮 对方的咕咕胜点榜排名信息 🎮
|
|
1235
1341
|
------------------------------
|
|
1236
1342
|
昵称:${displayName}
|
|
1237
1343
|
句柄:${user.handle}
|
|
1238
1344
|
当前积分:${user.rank}
|
|
1239
1345
|
参赛次数:${user.matches} 次
|
|
1240
1346
|
胜率: ${user.matches === 0 ? "0.00%" : (user.wins / user.matches * 100).toFixed(2) + "%"}
|
|
1241
|
-
全服排名:第 ${userRank}
|
|
1347
|
+
全服排名:第 ${userRank} 名
|
|
1242
1348
|
------------------------------`;
|
|
1243
1349
|
}
|
|
1244
1350
|
});
|
|
1245
|
-
ctx.command("ggcevo/给予 <handle> <
|
|
1351
|
+
ctx.command("ggcevo/给予 <handle> <itemName:string> <amount:number>", "增加用户物品/金币", { authority: 3 }).action(async (_, handle, itemName, amount) => {
|
|
1246
1352
|
try {
|
|
1247
|
-
if (!handle || !
|
|
1248
|
-
return
|
|
1353
|
+
if (!handle || !itemName || amount <= 0) {
|
|
1354
|
+
return "参数格式错误,正确格式:给予 用户句柄 物品名称 数量";
|
|
1249
1355
|
}
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1356
|
+
if (itemName === "金币") {
|
|
1357
|
+
const [signData] = await ctx.database.get("ggcevo_sign", { handle });
|
|
1358
|
+
await ctx.database.upsert("ggcevo_sign", [{
|
|
1359
|
+
handle,
|
|
1360
|
+
totalRewards: (signData?.totalRewards || 0) + Math.floor(amount),
|
|
1361
|
+
lastSign: signData?.lastSign || /* @__PURE__ */ new Date(0),
|
|
1362
|
+
// 保持原有最后签到时间
|
|
1363
|
+
monthlyDays: signData?.monthlyDays || 0
|
|
1364
|
+
// 保持月签到天数
|
|
1365
|
+
}]);
|
|
1366
|
+
return `成功为 ${handle} 添加 ${amount} 金币!当前金币总数:${(signData?.totalRewards || 0) + amount}`;
|
|
1367
|
+
}
|
|
1368
|
+
const validItems = Object.keys(initDefaultItems);
|
|
1369
|
+
if (!validItems.includes(itemName)) {
|
|
1370
|
+
return `无效物品名称,可用物品:${validItems.join("、")}`;
|
|
1371
|
+
}
|
|
1372
|
+
const itemId = initDefaultItems[itemName].id;
|
|
1373
|
+
const [backpack] = await ctx.database.get("ggcevo_backpack", {
|
|
1374
|
+
handle,
|
|
1375
|
+
itemId
|
|
1376
|
+
});
|
|
1255
1377
|
await ctx.database.upsert("ggcevo_backpack", [{
|
|
1256
1378
|
handle,
|
|
1257
1379
|
itemId,
|
|
1258
|
-
quantity: (backpack?.quantity || 0) + amount
|
|
1380
|
+
quantity: (backpack?.quantity || 0) + Math.floor(amount)
|
|
1259
1381
|
}], ["handle", "itemId"]);
|
|
1260
|
-
return `成功为 ${handle}
|
|
1382
|
+
return `成功为 ${handle} 添加 ${amount} 个${itemName}!当前总数:${(backpack?.quantity || 0) + amount}`;
|
|
1261
1383
|
} catch (err) {
|
|
1262
|
-
console.error("
|
|
1263
|
-
return "
|
|
1384
|
+
console.error("[给予命令错误]", err);
|
|
1385
|
+
return "操作失败:" + (err instanceof Error ? err.message : "数据库异常");
|
|
1264
1386
|
}
|
|
1265
1387
|
});
|
|
1266
1388
|
ctx.command("ggcevo/违规记录 [user]", "违规记录查询").usage("输入 违规记录 [@用户] -p 页码 查看处罚记录,每页1条").option("p", "-p <page:number> 指定页码").action(async (argv) => {
|
|
@@ -1270,7 +1392,7 @@ ID:${activity.id}
|
|
|
1270
1392
|
let handle;
|
|
1271
1393
|
if (!user) {
|
|
1272
1394
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
1273
|
-
if (!profile) return "
|
|
1395
|
+
if (!profile) return "您暂未绑定句柄。";
|
|
1274
1396
|
handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
1275
1397
|
} else {
|
|
1276
1398
|
const parsedUser = import_koishi.h.parse(user)[0];
|
|
@@ -1281,7 +1403,7 @@ ID:${activity.id}
|
|
|
1281
1403
|
let targetUsername = parsedUser.attrs.name || targetUserId;
|
|
1282
1404
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: targetUsername });
|
|
1283
1405
|
if (!profile) {
|
|
1284
|
-
return "
|
|
1406
|
+
return "对方暂未绑定句柄。";
|
|
1285
1407
|
}
|
|
1286
1408
|
const { regionId, realmId, profileId } = profile;
|
|
1287
1409
|
handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
@@ -1313,17 +1435,17 @@ ID:${activity.id}
|
|
|
1313
1435
|
"------------------------------",
|
|
1314
1436
|
recordText,
|
|
1315
1437
|
"------------------------------",
|
|
1316
|
-
pageNum < totalPages ? `输入 违规记录 -p ${pageNum + 1} 查看下一条` : "已是最后一页"
|
|
1438
|
+
pageNum < totalPages ? `输入 违规记录 (@用户) -p ${pageNum + 1} 查看下一条` : "已是最后一页"
|
|
1317
1439
|
].join("\n");
|
|
1318
1440
|
});
|
|
1319
1441
|
ctx.command("ggcevo/兑换", "兑换物品").action(async ({ session }) => {
|
|
1320
1442
|
try {
|
|
1321
1443
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
1322
|
-
if (!profile) return "
|
|
1444
|
+
if (!profile) return "您暂未绑定句柄";
|
|
1323
1445
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
1324
1446
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
1325
1447
|
if (existingEntries.length > 0) {
|
|
1326
|
-
return
|
|
1448
|
+
return `❌ 拒绝访问,您已被列入黑名单。`;
|
|
1327
1449
|
}
|
|
1328
1450
|
const currentSeason = config.rankseason;
|
|
1329
1451
|
const qualityGroups = {};
|
|
@@ -1349,7 +1471,7 @@ ID:${activity.id}
|
|
|
1349
1471
|
qualityGroups[quality].push(`${itemName}${quantityText}`);
|
|
1350
1472
|
}
|
|
1351
1473
|
const order = ["t0", "t1", "t2", "t3"];
|
|
1352
|
-
let message = "请在30
|
|
1474
|
+
let message = "请在30秒内输入可兑换物品(显示格式:物品名 [剩余/总量]):\n";
|
|
1353
1475
|
for (const quality of order) {
|
|
1354
1476
|
const items = qualityGroups[quality] || [];
|
|
1355
1477
|
if (!items.length) continue;
|
|
@@ -1360,11 +1482,11 @@ ${items.join("、")}
|
|
|
1360
1482
|
}
|
|
1361
1483
|
await session.send(message);
|
|
1362
1484
|
const name2 = await session.prompt(3e4);
|
|
1363
|
-
if (!name2) return "
|
|
1485
|
+
if (!name2) return "输入超时,请重新输入。";
|
|
1364
1486
|
const configname = itemConfig[name2];
|
|
1365
|
-
if (!configname) return "
|
|
1487
|
+
if (!configname) return "无效的物品名称,请重新输入。";
|
|
1366
1488
|
const userRecords = await ctx.database.get("ggcevo_exchange", { handle, item: name2 });
|
|
1367
|
-
if (userRecords.length > 0) return "
|
|
1489
|
+
if (userRecords.length > 0) return "您已经兑换过该物品。";
|
|
1368
1490
|
if (configname.quantity !== void 0 && (configname.isLimited || config.ignoreGlobalLimit === false)) {
|
|
1369
1491
|
const queryConditions = {
|
|
1370
1492
|
item: name2,
|
|
@@ -1374,7 +1496,7 @@ ${items.join("、")}
|
|
|
1374
1496
|
queryConditions.season = currentSeason;
|
|
1375
1497
|
}
|
|
1376
1498
|
const globalRecords = await ctx.database.get("ggcevo_exchange", queryConditions);
|
|
1377
|
-
if (globalRecords.length >= configname.quantity) return "
|
|
1499
|
+
if (globalRecords.length >= configname.quantity) return "该物品已被兑换完了。";
|
|
1378
1500
|
}
|
|
1379
1501
|
const qualityMap = { "t3": 4, "t2": 5, "t1": 6, "t0": 7 };
|
|
1380
1502
|
const petItems = new Set(
|
|
@@ -1397,7 +1519,7 @@ ${items.join("、")}
|
|
|
1397
1519
|
}
|
|
1398
1520
|
const [coupon] = await ctx.database.get("ggcevo_backpack", { handle, itemId });
|
|
1399
1521
|
if (!coupon || coupon.quantity < cost) {
|
|
1400
|
-
const requireMsg = petItems.has(name2) ? `需要
|
|
1522
|
+
const requireMsg = petItems.has(name2) ? `需要1个${configname.quality}级宠物扭蛋 或${configname.cost}张兑奖券` : `需要${configname.cost}张兑奖券`;
|
|
1401
1523
|
return `${requireMsg}
|
|
1402
1524
|
当前持有:${coupon?.quantity || 0}个${couponName}`;
|
|
1403
1525
|
}
|
|
@@ -1420,7 +1542,7 @@ ${items.join("、")}
|
|
|
1420
1542
|
season: currentSeason
|
|
1421
1543
|
});
|
|
1422
1544
|
});
|
|
1423
|
-
return
|
|
1545
|
+
return `兑换成功!消耗${cost}个${couponName}获得【${name2}】`;
|
|
1424
1546
|
} catch (error) {
|
|
1425
1547
|
console.error("兑换失败:", error);
|
|
1426
1548
|
return "兑换失败";
|
|
@@ -1428,7 +1550,7 @@ ${items.join("、")}
|
|
|
1428
1550
|
});
|
|
1429
1551
|
ctx.command("ggcevo/兑换记录").action(async ({ session }) => {
|
|
1430
1552
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
1431
|
-
if (!profile) return "
|
|
1553
|
+
if (!profile) return "您暂未绑定句柄";
|
|
1432
1554
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
1433
1555
|
const exchanges = await ctx.database.get("ggcevo_exchange", { handle });
|
|
1434
1556
|
if (!exchanges.length) return "您暂无兑换记录";
|
|
@@ -1447,16 +1569,16 @@ ${output}`;
|
|
|
1447
1569
|
});
|
|
1448
1570
|
ctx.command("ggcevo/兑换扭蛋币").action(async ({ session }) => {
|
|
1449
1571
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
1450
|
-
if (!profile) return "
|
|
1572
|
+
if (!profile) return "您暂未绑定句柄。";
|
|
1451
1573
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
1452
1574
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
1453
1575
|
if (existingEntries.length > 0) {
|
|
1454
|
-
return
|
|
1576
|
+
return `❌ 拒绝访问,您已被列入黑名单。`;
|
|
1455
1577
|
}
|
|
1456
1578
|
const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 3 });
|
|
1457
1579
|
const [coupon] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 2 });
|
|
1458
1580
|
if (!coupon || coupon.quantity < 3) {
|
|
1459
|
-
return `兑换扭蛋币需要
|
|
1581
|
+
return `兑换扭蛋币需要3张兑奖券,当前持有:${coupon?.quantity || 0}`;
|
|
1460
1582
|
}
|
|
1461
1583
|
await ctx.database.set(
|
|
1462
1584
|
"ggcevo_backpack",
|
|
@@ -1468,19 +1590,19 @@ ${output}`;
|
|
|
1468
1590
|
itemId: 3,
|
|
1469
1591
|
quantity: (backpack?.quantity || 0) + 1
|
|
1470
1592
|
}]);
|
|
1471
|
-
return `兑换成功!消耗
|
|
1593
|
+
return `兑换成功!消耗3张兑奖券获得1枚扭蛋币`;
|
|
1472
1594
|
});
|
|
1473
1595
|
ctx.command("ggcevo/扭蛋").action(async (argv) => {
|
|
1474
1596
|
const session = argv.session;
|
|
1475
1597
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
1476
1598
|
if (!profile) {
|
|
1477
|
-
return "
|
|
1599
|
+
return "您暂未绑定句柄。";
|
|
1478
1600
|
}
|
|
1479
1601
|
const { regionId, realmId, profileId } = profile;
|
|
1480
1602
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
1481
1603
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
1482
1604
|
if (existingEntries.length > 0) {
|
|
1483
|
-
return
|
|
1605
|
+
return `❌ 拒绝访问,您已被列入黑名单。`;
|
|
1484
1606
|
}
|
|
1485
1607
|
const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 3 });
|
|
1486
1608
|
if (!backpack || backpack.quantity < 1) {
|
|
@@ -1506,16 +1628,16 @@ ${output}`;
|
|
|
1506
1628
|
itemId: itemData.id,
|
|
1507
1629
|
quantity: currentQuantity + 1
|
|
1508
1630
|
}]);
|
|
1509
|
-
return `🎉
|
|
1631
|
+
return `🎉 恭喜您获得:${itemName}`;
|
|
1510
1632
|
});
|
|
1511
|
-
ctx.command("ggcevo
|
|
1633
|
+
ctx.command("ggcevo/拉黑", "添加用户到黑名单").action(async (argv) => {
|
|
1512
1634
|
const session = argv.session;
|
|
1513
1635
|
if (!ctx.config.admins.includes(session.userId)) {
|
|
1514
|
-
return "⚠️
|
|
1636
|
+
return "⚠️ 没有操作权限。";
|
|
1515
1637
|
}
|
|
1516
1638
|
await session.send("请在30秒内输入需要拉黑的句柄:\n(句柄格式为: [区域ID]-S2-[服务器ID]-[档案ID])");
|
|
1517
1639
|
const handle = await session.prompt(3e4);
|
|
1518
|
-
if (!handle) return "
|
|
1640
|
+
if (!handle) return "输入超时,请重新输入。";
|
|
1519
1641
|
try {
|
|
1520
1642
|
const handleRegex = /^([1235])-S2-([12])-(\d+)$/;
|
|
1521
1643
|
if (!handleRegex.test(handle)) {
|
|
@@ -1523,40 +1645,40 @@ ${output}`;
|
|
|
1523
1645
|
}
|
|
1524
1646
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
1525
1647
|
if (existingEntries.length > 0) {
|
|
1526
|
-
return `${handle}
|
|
1648
|
+
return `${handle}已在黑名单中。`;
|
|
1527
1649
|
}
|
|
1528
1650
|
await ctx.database.create("ggcevo_blacklist", {
|
|
1529
1651
|
handle,
|
|
1530
1652
|
createdAt: /* @__PURE__ */ new Date()
|
|
1531
1653
|
});
|
|
1532
|
-
return `✅
|
|
1654
|
+
return `✅ 用户${handle}已被列入黑名单。`;
|
|
1533
1655
|
} catch (error) {
|
|
1534
1656
|
console.error("黑名单操作失败:", error);
|
|
1535
1657
|
return "操作失败,请稍后重试。错误详情已记录";
|
|
1536
1658
|
}
|
|
1537
1659
|
});
|
|
1538
|
-
ctx.command("ggcevo
|
|
1660
|
+
ctx.command("ggcevo/标记", "标记用户到胜点榜黑名单").action(async (argv) => {
|
|
1539
1661
|
const session = argv.session;
|
|
1540
1662
|
if (!ctx.config.admins.includes(session.userId)) {
|
|
1541
|
-
return "⚠️
|
|
1663
|
+
return "⚠️ 没有操作权限。";
|
|
1542
1664
|
}
|
|
1543
|
-
await session.send("请在30
|
|
1665
|
+
await session.send("请在30秒内输入需要标记的句柄:\n(句柄格式为: [区域ID]-S2-[服务器ID]-[档案ID])");
|
|
1544
1666
|
const handle = await session.prompt(3e4);
|
|
1545
|
-
if (!handle) return "
|
|
1667
|
+
if (!handle) return "输入超时,请重新输入。";
|
|
1546
1668
|
try {
|
|
1547
1669
|
const handleRegex = /^([1235])-S2-([12])-(\d+)$/;
|
|
1548
1670
|
if (!handleRegex.test(handle)) {
|
|
1549
|
-
return "
|
|
1671
|
+
return "句柄格式错误,请重新输入。";
|
|
1550
1672
|
}
|
|
1551
1673
|
const existingEntries = await ctx.database.get("ggcevo_rank", { handle, Blacklist: true });
|
|
1552
1674
|
if (existingEntries.length > 0) {
|
|
1553
|
-
return `${handle}
|
|
1675
|
+
return `${handle}已被标记在咕咕胜点榜黑名单中。`;
|
|
1554
1676
|
}
|
|
1555
1677
|
await ctx.database.upsert("ggcevo_rank", [{
|
|
1556
1678
|
handle,
|
|
1557
1679
|
Blacklist: true
|
|
1558
1680
|
}]);
|
|
1559
|
-
return `✅
|
|
1681
|
+
return `✅ 用户${handle}已被标记在咕咕胜点榜黑名单。`;
|
|
1560
1682
|
} catch (error) {
|
|
1561
1683
|
console.error("黑名单操作失败:", error);
|
|
1562
1684
|
return "操作失败,请稍后重试。错误详情已记录";
|
|
@@ -1565,14 +1687,14 @@ ${output}`;
|
|
|
1565
1687
|
ctx.command("ggcevo/成就").action(async ({ session }) => {
|
|
1566
1688
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
1567
1689
|
if (!profile) {
|
|
1568
|
-
return "
|
|
1690
|
+
return "您暂未绑定句柄。";
|
|
1569
1691
|
}
|
|
1570
1692
|
const { regionId, realmId, profileId } = profile;
|
|
1571
1693
|
const achievements = await ctx.database.get("ggcevo_achievements", {
|
|
1572
1694
|
handle: `${regionId}-S2-${realmId}-${profileId}`
|
|
1573
1695
|
});
|
|
1574
1696
|
if (!achievements.length) {
|
|
1575
|
-
return "
|
|
1697
|
+
return "你还没有获得任何成就。";
|
|
1576
1698
|
}
|
|
1577
1699
|
const achievementList = achievements.map((achievement) => {
|
|
1578
1700
|
const date = new Date(achievement.gaintime);
|
|
@@ -1590,7 +1712,7 @@ ${achievementList.join("\n")}`;
|
|
|
1590
1712
|
const session = argv.session;
|
|
1591
1713
|
const output = [];
|
|
1592
1714
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
1593
|
-
if (!profile) return "
|
|
1715
|
+
if (!profile) return "您暂未绑定句柄。";
|
|
1594
1716
|
const { regionId, realmId, profileId } = profile;
|
|
1595
1717
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
1596
1718
|
output.push(`🎮 游戏句柄:${handle}
|
|
@@ -1721,22 +1843,22 @@ ${achievementList.join("\n")}`;
|
|
|
1721
1843
|
ctx.command("ggcevo/pk [user]", "发起玩家对战").alias("挑战").action(async (argv, user) => {
|
|
1722
1844
|
try {
|
|
1723
1845
|
const session = argv.session;
|
|
1724
|
-
if (!user) return
|
|
1846
|
+
if (!user) return "缺少参数,请输入“pk @指定pk玩家”。";
|
|
1725
1847
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
1726
|
-
if (!profile) return "
|
|
1848
|
+
if (!profile) return "您暂未绑定句柄。";
|
|
1727
1849
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
1728
1850
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
1729
1851
|
if (existingEntries.length > 0) {
|
|
1730
|
-
return
|
|
1852
|
+
return `❌ 拒绝访问,您已被列入黑名单。`;
|
|
1731
1853
|
}
|
|
1732
1854
|
const parsedUser = import_koishi.h.parse(user)[0];
|
|
1733
|
-
if (!parsedUser || parsedUser.type !== "at" || !parsedUser.attrs.id) return
|
|
1855
|
+
if (!parsedUser || parsedUser.type !== "at" || !parsedUser.attrs.id) return "参数格式错误,请输入“pk @指定pk玩家”。";
|
|
1734
1856
|
const targetUserId = parsedUser.attrs.id;
|
|
1735
1857
|
const [targetprofile] = await ctx.database.get("sc2arcade_player", { userId: targetUserId });
|
|
1736
|
-
if (!targetprofile) return "
|
|
1858
|
+
if (!targetprofile) return "对方尚未绑定句柄。";
|
|
1737
1859
|
const initiatorHandle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
1738
1860
|
const targetHandle = `${targetprofile.regionId}-S2-${targetprofile.realmId}-${targetprofile.profileId}`;
|
|
1739
|
-
if (initiatorHandle === targetHandle) return "
|
|
1861
|
+
if (initiatorHandle === targetHandle) return "不能挑战自己。";
|
|
1740
1862
|
let initiatorPK = {
|
|
1741
1863
|
handle: initiatorHandle,
|
|
1742
1864
|
total: 0,
|
|
@@ -1767,17 +1889,17 @@ ${achievementList.join("\n")}`;
|
|
|
1767
1889
|
if (dbTarget) Object.assign(targetPK, dbTarget);
|
|
1768
1890
|
});
|
|
1769
1891
|
if (!initiatorPK.enable) {
|
|
1770
|
-
return "您已关闭PK
|
|
1892
|
+
return "您已关闭PK功能,无法发起挑战。";
|
|
1771
1893
|
}
|
|
1772
1894
|
if (!targetPK.enable) {
|
|
1773
|
-
return "对方已关闭PK
|
|
1895
|
+
return "对方已关闭PK功能,无法接受挑战。";
|
|
1774
1896
|
}
|
|
1775
1897
|
const now = convertUTCtoChinaTime(/* @__PURE__ */ new Date());
|
|
1776
1898
|
if (!isSameDate(convertUTCtoChinaTime(initiatorPK.lastPK), now)) {
|
|
1777
1899
|
initiatorPK.todayCount = 0;
|
|
1778
1900
|
}
|
|
1779
1901
|
if (initiatorPK.todayCount >= config.dailyPKLimit) {
|
|
1780
|
-
return
|
|
1902
|
+
return `今日挑战次数已用尽(${config.dailyPKLimit}次/日)。`;
|
|
1781
1903
|
}
|
|
1782
1904
|
const nowChina = convertUTCtoChinaTime(/* @__PURE__ */ new Date());
|
|
1783
1905
|
const todayStart = new Date(nowChina);
|
|
@@ -1790,7 +1912,7 @@ ${achievementList.join("\n")}`;
|
|
|
1790
1912
|
date: { $gte: adjustedTime }
|
|
1791
1913
|
}).execute((row) => import_koishi.$.count(row.id));
|
|
1792
1914
|
if (sameOpponentCount > 0) {
|
|
1793
|
-
return "
|
|
1915
|
+
return "您今天已经挑战过该玩家,请明天再试。";
|
|
1794
1916
|
}
|
|
1795
1917
|
}
|
|
1796
1918
|
if (config.maxDailyBeChallenged > 0) {
|
|
@@ -1799,7 +1921,7 @@ ${achievementList.join("\n")}`;
|
|
|
1799
1921
|
date: { $gte: adjustedTime }
|
|
1800
1922
|
}).execute((row) => import_koishi.$.count(row.id));
|
|
1801
1923
|
if (beChallengedCount >= config.maxDailyBeChallenged) {
|
|
1802
|
-
return
|
|
1924
|
+
return `该玩家今日已被挑战太多次(最多${config.maxDailyBeChallenged}次)。`;
|
|
1803
1925
|
}
|
|
1804
1926
|
}
|
|
1805
1927
|
const [initiatorData, targetData] = await Promise.all([
|
|
@@ -1816,8 +1938,8 @@ ${achievementList.join("\n")}`;
|
|
|
1816
1938
|
]);
|
|
1817
1939
|
const initiatorGold = initiatorSign[0]?.totalRewards || 0;
|
|
1818
1940
|
const targetGold = targetSign[0]?.totalRewards || 0;
|
|
1819
|
-
if (initiatorGold < 100) return "发起者需要至少100
|
|
1820
|
-
if (targetGold < 100) return "对方金币不足100
|
|
1941
|
+
if (initiatorGold < 100) return "发起者需要至少100金币才能发起挑战。";
|
|
1942
|
+
if (targetGold < 100) return "对方金币不足100,无法应战。";
|
|
1821
1943
|
const rankDiff = initiatorRank - targetRank;
|
|
1822
1944
|
const clampedDiff = Math.min(Math.max(rankDiff, -1e4), 1e4);
|
|
1823
1945
|
const winRate = Math.min(Math.max(50 + clampedDiff * 5e-3, 5), 95);
|
|
@@ -1874,8 +1996,8 @@ ${achievementList.join("\n")}`;
|
|
|
1874
1996
|
});
|
|
1875
1997
|
const result = [
|
|
1876
1998
|
`⚔️【对战结果】${isWin ? "胜利" : "失败"}`,
|
|
1877
|
-
`🏅 挑战者:${initiatorRankname}
|
|
1878
|
-
`🛡️ 应战者:${targetRankname}
|
|
1999
|
+
`🏅 挑战者:${initiatorRankname}(积分 ${initiatorRank})`,
|
|
2000
|
+
`🛡️ 应战者:${targetRankname}(积分 ${targetRank})`,
|
|
1879
2001
|
`📊 胜率预测:${winRate.toFixed(1)}%`,
|
|
1880
2002
|
`🎰 金币变动:${stealPercentage}%`
|
|
1881
2003
|
];
|
|
@@ -1889,12 +2011,8 @@ ${achievementList.join("\n")}`;
|
|
|
1889
2011
|
});
|
|
1890
2012
|
ctx.command("ggcevo/切换pk状态", "切换玩家对战状态").action(async ({ session }) => {
|
|
1891
2013
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
1892
|
-
if (!profile) return "
|
|
2014
|
+
if (!profile) return "您暂未绑定句柄。";
|
|
1893
2015
|
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
2016
|
const [pkRecord] = await ctx.database.get("ggcevo_pk", { handle }) || [null];
|
|
1899
2017
|
const currentState = pkRecord?.enable ?? true;
|
|
1900
2018
|
const lastToggle = pkRecord?.lastToggle ?? /* @__PURE__ */ new Date(0);
|
|
@@ -1915,10 +2033,10 @@ ${achievementList.join("\n")}`;
|
|
|
1915
2033
|
const diffDays = Math.floor((now.getTime() - lastToggleTime.getTime()) / (1e3 * 3600 * 24));
|
|
1916
2034
|
if (diffDays < 3 && lastToggleTime.getTime() !== 0) {
|
|
1917
2035
|
const remaining = 3 - diffDays;
|
|
1918
|
-
return `状态切换冷却中,${remaining}
|
|
2036
|
+
return `状态切换冷却中,${remaining}天后再试(下次可切换时间:${new Date(lastToggle.getTime() + 3 * 864e5).toLocaleDateString("zh-CN")})。`;
|
|
1919
2037
|
}
|
|
1920
2038
|
const action = currentState ? "关闭" : "开启";
|
|
1921
|
-
await session.send(`您当前的PK状态为【${currentState ? "开启" : "关闭"}】,确认要${action}吗?(
|
|
2039
|
+
await session.send(`您当前的PK状态为【${currentState ? "开启" : "关闭"}】,确认要${action}吗?(s30秒内回复“是”确认)`);
|
|
1922
2040
|
const confirm = await session.prompt(3e4);
|
|
1923
2041
|
if (confirm !== "是") return "已取消操作";
|
|
1924
2042
|
await ctx.database.upsert("ggcevo_pk", [{
|
|
@@ -1937,8 +2055,26 @@ ${achievementList.join("\n")}`;
|
|
|
1937
2055
|
day: "2-digit"
|
|
1938
2056
|
})}`;
|
|
1939
2057
|
});
|
|
1940
|
-
ctx.command("ggcevo/武器库").action(async ({ session }) => {
|
|
1941
|
-
const
|
|
2058
|
+
ctx.command("ggcevo/武器库 [type]").usage("输入“武器库”查看类型,或“武器库 类型”查看详细武器信息").action(async ({ session }, type) => {
|
|
2059
|
+
const typeStats = Object.values(weaponConfig).reduce((stats, weapon) => {
|
|
2060
|
+
stats[weapon.type] = (stats[weapon.type] || 0) + 1;
|
|
2061
|
+
return stats;
|
|
2062
|
+
}, {});
|
|
2063
|
+
if (!type) {
|
|
2064
|
+
return [
|
|
2065
|
+
"🏪 咕咕军火武器库分类 🏪",
|
|
2066
|
+
'使用 "武器库 类型名称" 查看详细列表',
|
|
2067
|
+
"====================",
|
|
2068
|
+
...Object.entries(typeStats).map(([typeName, count]) => `▸ ${typeName} (${count}种)`)
|
|
2069
|
+
].join("\n");
|
|
2070
|
+
}
|
|
2071
|
+
const validTypes = Object.keys(typeStats);
|
|
2072
|
+
const normalizedType = validTypes.find((t) => t === type);
|
|
2073
|
+
if (!normalizedType) {
|
|
2074
|
+
return `无效武器类型,可用类型:
|
|
2075
|
+
${validTypes.join("、")}`;
|
|
2076
|
+
}
|
|
2077
|
+
const items = Object.entries(weaponConfig).filter(([_, config2]) => config2.type === normalizedType).map(([name2, config2]) => {
|
|
1942
2078
|
const tagEffectsDesc = config2.tagEffects ? Object.entries(config2.tagEffects).map(([tag, multiplier]) => `▸ 对${tag}目标造成${(multiplier * 100).toFixed(0)}%伤害`).join("\n") : "▸ 无特殊加成效果";
|
|
1943
2079
|
return [
|
|
1944
2080
|
`【${name2}】`,
|
|
@@ -1951,7 +2087,7 @@ ${achievementList.join("\n")}`;
|
|
|
1951
2087
|
].join("\n");
|
|
1952
2088
|
});
|
|
1953
2089
|
return [
|
|
1954
|
-
|
|
2090
|
+
`🏪 咕咕军火武器库 - ${normalizedType} 🏪`,
|
|
1955
2091
|
"使用“购买 武器名称”命令进行购买",
|
|
1956
2092
|
"====================",
|
|
1957
2093
|
...items
|
|
@@ -2009,15 +2145,14 @@ ${achievementList.join("\n")}`;
|
|
|
2009
2145
|
].join("\n");
|
|
2010
2146
|
}));
|
|
2011
2147
|
return [
|
|
2012
|
-
"🛡️
|
|
2148
|
+
"🛡️ 当前拥有的武器列表",
|
|
2013
2149
|
'使用"装备 武器名称"切换武器',
|
|
2014
2150
|
"⚡表示当前装备武器",
|
|
2015
2151
|
"────────────────",
|
|
2016
2152
|
...weaponDetails.length ? weaponDetails : ["空空如也,快去武器库看看吧!"],
|
|
2017
2153
|
"────────────────",
|
|
2018
2154
|
"💡 武器效果说明:",
|
|
2019
|
-
"
|
|
2020
|
-
"🔧 改装效果仅在战斗时计算"
|
|
2155
|
+
"🔧 改装效果会在战斗中生效"
|
|
2021
2156
|
].join("\n");
|
|
2022
2157
|
});
|
|
2023
2158
|
ctx.command("ggcevo/装备 <weapon>").action(async ({ session }, weapon) => {
|
|
@@ -2159,6 +2294,7 @@ ${achievementList.join("\n")}`;
|
|
|
2159
2294
|
});
|
|
2160
2295
|
ctx.command("ggcevo/攻击 <targetType>").usage("使用 攻击 主宰/zz 或 攻击 子代/zd 来选择攻击目标").action(async (argv, targetType) => {
|
|
2161
2296
|
const session = argv.session;
|
|
2297
|
+
let broadcastMessage = null;
|
|
2162
2298
|
const targetAliases = {
|
|
2163
2299
|
"主宰": ["主宰", "zz"],
|
|
2164
2300
|
"子代": ["子代", "zd"]
|
|
@@ -2172,10 +2308,10 @@ ${achievementList.join("\n")}`;
|
|
|
2172
2308
|
}
|
|
2173
2309
|
if (!normalizedTarget) return "请指定正确的攻击目标:主宰/zz 或 子代/zd";
|
|
2174
2310
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2175
|
-
if (!profile) return "
|
|
2311
|
+
if (!profile) return "您暂未绑定句柄。";
|
|
2176
2312
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
2177
2313
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
2178
|
-
if (existingEntries.length > 0) return "
|
|
2314
|
+
if (existingEntries.length > 0) return "❌ 拒绝访问,您已被列入黑名单。";
|
|
2179
2315
|
const config2 = ctx.config;
|
|
2180
2316
|
const unlimitedBossAttack = config2.unlimitedBossAttack;
|
|
2181
2317
|
if (!unlimitedBossAttack) {
|
|
@@ -2192,93 +2328,17 @@ ${achievementList.join("\n")}`;
|
|
|
2192
2328
|
handle,
|
|
2193
2329
|
equipped: true
|
|
2194
2330
|
});
|
|
2195
|
-
if (!equippedWeapon) return "
|
|
2331
|
+
if (!equippedWeapon) return "请先装备武器再挑战主宰。";
|
|
2196
2332
|
const activeBosses = await ctx.database.get("ggcevo_boss", { isActive: true });
|
|
2197
|
-
if (!activeBosses.length) return "
|
|
2333
|
+
if (!activeBosses.length) return "当前没有存活的主宰。";
|
|
2198
2334
|
const targetBoss = normalizedTarget === "主宰" ? activeBosses.find((b) => b.type === "主宰") : activeBosses.find((b) => b.type === "子代");
|
|
2199
|
-
if (!targetBoss) return `当前没有可攻击的${normalizedTarget === "主宰" ? "主宰" : "子代"}
|
|
2335
|
+
if (!targetBoss) return `当前没有可攻击的${normalizedTarget === "主宰" ? "主宰" : "子代"}。`;
|
|
2200
2336
|
const bossGroup = bossPool.find((group) => group.main.id === targetBoss.groupId);
|
|
2201
|
-
if (!bossGroup) return "无法获取BOSS
|
|
2337
|
+
if (!bossGroup) return "无法获取BOSS组信息,请联系管理员。";
|
|
2202
2338
|
const weaponConfigEntry = Object.entries(weaponConfig).find(([_, c]) => c.id === equippedWeapon.weaponId);
|
|
2203
2339
|
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);
|
|
2340
|
+
const { damage: baseDamage, hasCrit } = await calculateTotalDamage(ctx, session, equippedWeapon, targetBoss);
|
|
2341
|
+
const actualDamage = Math.min(baseDamage, targetBoss.HP);
|
|
2282
2342
|
const updatedHP = targetBoss.HP - actualDamage;
|
|
2283
2343
|
const isDefeated = updatedHP <= 0;
|
|
2284
2344
|
const [existingRecord] = await ctx.database.get("ggcevo_boss_damage", {
|
|
@@ -2290,6 +2350,7 @@ ${achievementList.join("\n")}`;
|
|
|
2290
2350
|
handle,
|
|
2291
2351
|
bossGroupId: targetBoss.groupId
|
|
2292
2352
|
}, {
|
|
2353
|
+
playerName: session.username,
|
|
2293
2354
|
totalDamage: existingRecord.totalDamage + actualDamage,
|
|
2294
2355
|
// 改为实际伤害
|
|
2295
2356
|
attackCount: existingRecord.attackCount + 1,
|
|
@@ -2413,13 +2474,13 @@ ${achievementList.join("\n")}`;
|
|
|
2413
2474
|
await ctx.database.remove("ggcevo_boss_damage", {
|
|
2414
2475
|
bossGroupId: targetBoss.groupId
|
|
2415
2476
|
});
|
|
2416
|
-
|
|
2417
|
-
`🎯 主宰 ${targetBoss.name}
|
|
2418
|
-
`所有子代已消失,下一个主宰将在1
|
|
2477
|
+
broadcastMessage = [
|
|
2478
|
+
`🎯 主宰 ${targetBoss.name} 已被 ${session.username} 击破!`,
|
|
2479
|
+
`所有子代已消失,下一个主宰将在1小时后重生`,
|
|
2419
2480
|
"",
|
|
2420
|
-
"
|
|
2481
|
+
"🏆 伤害排行榜奖励:",
|
|
2421
2482
|
...rewardMessages
|
|
2422
|
-
]
|
|
2483
|
+
];
|
|
2423
2484
|
} else {
|
|
2424
2485
|
await ctx.database.set(
|
|
2425
2486
|
"ggcevo_boss",
|
|
@@ -2429,11 +2490,10 @@ ${achievementList.join("\n")}`;
|
|
|
2429
2490
|
HP: 0
|
|
2430
2491
|
}
|
|
2431
2492
|
);
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
);
|
|
2493
|
+
broadcastMessage = [
|
|
2494
|
+
`⚡ ${session.username} 击破了子代 ${targetBoss.name}!`,
|
|
2495
|
+
`【连锁效果】主宰获得 20% 易伤状态!`
|
|
2496
|
+
];
|
|
2437
2497
|
}
|
|
2438
2498
|
} else {
|
|
2439
2499
|
await ctx.database.set(
|
|
@@ -2455,15 +2515,20 @@ ${achievementList.join("\n")}`;
|
|
|
2455
2515
|
// 改为实际伤害
|
|
2456
2516
|
});
|
|
2457
2517
|
}
|
|
2458
|
-
|
|
2518
|
+
const resultMessage = [
|
|
2459
2519
|
`🔥 ${session.username} 使用武器 ${weaponName} 对 ${targetBoss.name} 发起攻击!`,
|
|
2460
2520
|
`造成伤害:${actualDamage}${hasCrit ? "(✨ 暴击!)" : ""}`,
|
|
2461
|
-
// 改为实际伤害
|
|
2462
2521
|
`获得金币:${actualDamage}`,
|
|
2463
|
-
// 改为实际伤害
|
|
2464
2522
|
`目标剩余HP:${isDefeated ? 0 : updatedHP}/${targetBoss.type === "主宰" ? bossGroup.main.maxHP : bossGroup.minions[0].maxHP}`,
|
|
2465
2523
|
isDefeated ? `🎉 成功击败 ${targetBoss.name}!` : ""
|
|
2466
|
-
].filter((line) => line
|
|
2524
|
+
].filter((line) => line).join("\n");
|
|
2525
|
+
await session.send(resultMessage);
|
|
2526
|
+
if (broadcastMessage) {
|
|
2527
|
+
const finalBroadcast = Array.isArray(broadcastMessage) ? broadcastMessage.join("\n") : broadcastMessage;
|
|
2528
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
2529
|
+
ctx.broadcast(config2.groupId, finalBroadcast);
|
|
2530
|
+
}
|
|
2531
|
+
return;
|
|
2467
2532
|
});
|
|
2468
2533
|
ctx.command("ggcevo/初始化主宰", "初始化或重置主宰系统", { authority: 3 }).action(async () => {
|
|
2469
2534
|
try {
|
|
@@ -2509,19 +2574,15 @@ ${achievementList.join("\n")}`;
|
|
|
2509
2574
|
pageNum < totalPages ? `输入 伤害榜 ${pageNum + 1} 查看下一页` : "已是最后一页"
|
|
2510
2575
|
].join("\n");
|
|
2511
2576
|
});
|
|
2512
|
-
ctx.command("ggcevo
|
|
2577
|
+
ctx.command("ggcevo/主宰信息", "查看当前主宰信息").alias("zz信息").action(async () => {
|
|
2513
2578
|
const activeBosses = await ctx.database.get("ggcevo_boss", { isActive: true });
|
|
2514
|
-
if (!activeBosses.length) return "
|
|
2579
|
+
if (!activeBosses.length) return "当前没有存活的主宰。";
|
|
2515
2580
|
const mainBoss = activeBosses.find((b) => b.type === "主宰");
|
|
2516
2581
|
const minions = activeBosses.filter((b) => b.type === "子代");
|
|
2517
2582
|
if (!mainBoss) return "当前BOSS数据异常,请联系管理员";
|
|
2518
2583
|
const bossGroup = bossPool.find((group) => group.main.name === mainBoss.name);
|
|
2519
2584
|
if (!bossGroup) return "BOSS配置数据异常,请联系管理员";
|
|
2520
2585
|
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
2586
|
let passiveDisplay = [];
|
|
2526
2587
|
if (bossGroup.main.passive) {
|
|
2527
2588
|
const activeMinions = await ctx.database.get("ggcevo_boss", {
|
|
@@ -2533,8 +2594,7 @@ ${achievementList.join("\n")}`;
|
|
|
2533
2594
|
if (p === "孤立无援") return activeMinions.length === 0;
|
|
2534
2595
|
return true;
|
|
2535
2596
|
}).map((p) => {
|
|
2536
|
-
|
|
2537
|
-
return `${p}:${formatEffect(effect)}`;
|
|
2597
|
+
return `${p}:${passiveConfig[p].description}`;
|
|
2538
2598
|
});
|
|
2539
2599
|
}
|
|
2540
2600
|
const result = [
|
|
@@ -2544,12 +2604,12 @@ ${achievementList.join("\n")}`;
|
|
|
2544
2604
|
`被动:${passiveDisplay.join(",") || "无"}`
|
|
2545
2605
|
];
|
|
2546
2606
|
if (minions.length > 0) {
|
|
2547
|
-
result.push("", "🟠
|
|
2607
|
+
result.push("", "🟠 子代:");
|
|
2548
2608
|
minions.forEach((minion) => {
|
|
2549
2609
|
const minionConfig = bossGroup.minions.find((m) => m.name === minion.name);
|
|
2550
2610
|
if (minionConfig) {
|
|
2551
2611
|
const minionHpBar = createHpBar(minion.HP, minionConfig.maxHP);
|
|
2552
|
-
const minionPassives = (minionConfig.passive || []).map((p) => `${p}:${
|
|
2612
|
+
const minionPassives = (minionConfig.passive || []).map((p) => `${p}:${passiveConfig[p].description}`).join(",");
|
|
2553
2613
|
result.push(
|
|
2554
2614
|
`${minion.name}`,
|
|
2555
2615
|
`${minionHpBar} (${minion.HP}/${minionConfig.maxHP})`,
|
|
@@ -2618,6 +2678,17 @@ function convertUTCtoChinaTime(input) {
|
|
|
2618
2678
|
return new Date(chinaTimestamp);
|
|
2619
2679
|
}
|
|
2620
2680
|
__name(convertUTCtoChinaTime, "convertUTCtoChinaTime");
|
|
2681
|
+
function formatDate(d) {
|
|
2682
|
+
return d.toLocaleString("zh-CN", {
|
|
2683
|
+
timeZone: "Asia/Shanghai",
|
|
2684
|
+
year: "numeric",
|
|
2685
|
+
month: "2-digit",
|
|
2686
|
+
day: "2-digit",
|
|
2687
|
+
hour: "2-digit",
|
|
2688
|
+
minute: "2-digit"
|
|
2689
|
+
});
|
|
2690
|
+
}
|
|
2691
|
+
__name(formatDate, "formatDate");
|
|
2621
2692
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2622
2693
|
0 && (module.exports = {
|
|
2623
2694
|
Config,
|