koishi-plugin-ggcevo-game 1.0.17 → 1.0.19
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 +9 -0
- package/lib/index.js +91 -1
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export interface Config {
|
|
|
11
11
|
admins: string[];
|
|
12
12
|
groupId: string[];
|
|
13
13
|
checkInterval: number;
|
|
14
|
+
dailyPKLimit: number;
|
|
14
15
|
}
|
|
15
16
|
export declare const Config: Schema<Config>;
|
|
16
17
|
export declare const inject: {
|
|
@@ -29,6 +30,7 @@ declare module 'koishi' {
|
|
|
29
30
|
ggcevo_adminbenefit: adminbenefit;
|
|
30
31
|
ggcevo_blacklist: blacklist;
|
|
31
32
|
ggcevo_achievements: Achievement;
|
|
33
|
+
ggcevo_pk: PKRecord;
|
|
32
34
|
}
|
|
33
35
|
}
|
|
34
36
|
export interface backpack {
|
|
@@ -107,4 +109,11 @@ export interface Achievement {
|
|
|
107
109
|
achievementname: string;
|
|
108
110
|
gaintime: Date;
|
|
109
111
|
}
|
|
112
|
+
export interface PKRecord {
|
|
113
|
+
handle: string;
|
|
114
|
+
total: number;
|
|
115
|
+
wins: number;
|
|
116
|
+
todayCount: number;
|
|
117
|
+
lastPK: Date;
|
|
118
|
+
}
|
|
110
119
|
export declare function apply(ctx: Context, config: Config): void;
|
package/lib/index.js
CHANGED
|
@@ -38,7 +38,8 @@ var Config = import_koishi.Schema.object({
|
|
|
38
38
|
ignoreGlobalLimit: import_koishi.Schema.boolean().description("是否开启无限制兑换").default(false),
|
|
39
39
|
admins: import_koishi.Schema.array(import_koishi.Schema.string()).description("管理员QQ号列表,支持配置多个").default([]).role("table"),
|
|
40
40
|
groupId: import_koishi.Schema.array(import_koishi.Schema.string()).description("游戏大厅黑名单通知群组,例如 onebot:123456").default([]).role("table"),
|
|
41
|
-
checkInterval: import_koishi.Schema.number().default(60).description("检查间隔(秒)")
|
|
41
|
+
checkInterval: import_koishi.Schema.number().default(60).description("检查间隔(秒)"),
|
|
42
|
+
dailyPKLimit: import_koishi.Schema.number().description("每人每天可发起PK次数").default(3)
|
|
42
43
|
});
|
|
43
44
|
var inject = {
|
|
44
45
|
required: ["database"]
|
|
@@ -167,6 +168,15 @@ function apply(ctx, config) {
|
|
|
167
168
|
}, {
|
|
168
169
|
primary: ["handle", "achievementname"]
|
|
169
170
|
});
|
|
171
|
+
ctx.model.extend("ggcevo_pk", {
|
|
172
|
+
handle: "string",
|
|
173
|
+
total: "unsigned",
|
|
174
|
+
wins: "unsigned",
|
|
175
|
+
todayCount: "unsigned",
|
|
176
|
+
lastPK: "timestamp"
|
|
177
|
+
}, {
|
|
178
|
+
primary: "handle"
|
|
179
|
+
});
|
|
170
180
|
const initDefaultItems = {
|
|
171
181
|
"咕咕币": { id: 1, type: "抽奖道具", description: "用于进行抽奖" },
|
|
172
182
|
"兑换券": { id: 2, type: "兑换货币", description: "用于兑换赞助物品" },
|
|
@@ -1477,6 +1487,86 @@ ${achievementList.join("\n")}`;
|
|
|
1477
1487
|
ctx.logger.error("SC2大厅监控失败:", error);
|
|
1478
1488
|
}
|
|
1479
1489
|
}, config.checkInterval * 1e3);
|
|
1490
|
+
ctx.command("ggcevo/pk <user>", "发起玩家对战").alias("挑战").action(async (argv, user) => {
|
|
1491
|
+
try {
|
|
1492
|
+
const session = argv.session;
|
|
1493
|
+
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
1494
|
+
if (!profile) return "您的 QQ 未绑定句柄。";
|
|
1495
|
+
const parsedUser = import_koishi.h.parse(user)[0];
|
|
1496
|
+
if (!parsedUser || parsedUser.type !== "at") return "请使用@指定对战玩家";
|
|
1497
|
+
const targetUserId = parsedUser.attrs.id;
|
|
1498
|
+
let targetUsername = parsedUser.attrs.name || targetUserId;
|
|
1499
|
+
const [targetprofile] = await ctx.database.get("sc2arcade_player", { userId: targetUsername });
|
|
1500
|
+
if (!targetprofile) return "对方尚未绑定句柄";
|
|
1501
|
+
const initiatorHandle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
1502
|
+
const targetHandle = `${targetprofile.regionId}-S2-${targetprofile.realmId}-${targetprofile.profileId}`;
|
|
1503
|
+
if (initiatorHandle === targetHandle) return "不能挑战自己哦~";
|
|
1504
|
+
let initiatorPK, targetPK;
|
|
1505
|
+
await ctx.database.withTransaction(async () => {
|
|
1506
|
+
[initiatorPK] = await ctx.database.get("ggcevo_pk", initiatorHandle) || [{ handle: initiatorHandle, total: 0, wins: 0, todayCount: 0, lastPK: /* @__PURE__ */ new Date(0) }];
|
|
1507
|
+
[targetPK] = await ctx.database.get("ggcevo_pk", targetHandle) || [{ handle: targetHandle, total: 0, wins: 0, todayCount: 0, lastPK: /* @__PURE__ */ new Date(0) }];
|
|
1508
|
+
});
|
|
1509
|
+
const now = convertUTCtoChinaTime(/* @__PURE__ */ new Date());
|
|
1510
|
+
if (!isSameDate(convertUTCtoChinaTime(initiatorPK.lastPK), now)) {
|
|
1511
|
+
initiatorPK.todayCount = 0;
|
|
1512
|
+
}
|
|
1513
|
+
if (initiatorPK.todayCount >= config.dailyPKLimit) {
|
|
1514
|
+
return `今日挑战次数已用尽(${config.dailyPKLimit}次/日)`;
|
|
1515
|
+
}
|
|
1516
|
+
const [initiatorData, targetData] = await Promise.all([
|
|
1517
|
+
ctx.database.get("ggcevo_rank", initiatorHandle),
|
|
1518
|
+
ctx.database.get("ggcevo_rank", targetHandle)
|
|
1519
|
+
]);
|
|
1520
|
+
const [initiatorSign, targetSign] = await Promise.all([
|
|
1521
|
+
ctx.database.get("ggcevo_sign", initiatorHandle),
|
|
1522
|
+
ctx.database.get("ggcevo_sign", targetHandle)
|
|
1523
|
+
]);
|
|
1524
|
+
const initiatorGold = initiatorSign[0]?.totalRewards || 0;
|
|
1525
|
+
const targetGold = targetSign[0]?.totalRewards || 0;
|
|
1526
|
+
if (initiatorGold < 100) return "发起者需要至少100金币才能挑战!";
|
|
1527
|
+
if (targetGold < 100) return "对方金币不足100,无法应战";
|
|
1528
|
+
const rankDiff = (initiatorData[0]?.rank || 0) - (targetData[0]?.rank || 0);
|
|
1529
|
+
const clampedDiff = Math.min(Math.max(rankDiff, -1e4), 1e4);
|
|
1530
|
+
const winRate = Math.min(Math.max(50 + clampedDiff * 5e-3, 5), 95);
|
|
1531
|
+
const isWin = Math.random() * 100 < winRate;
|
|
1532
|
+
const stealPercentage = getRandomInt(1, 5);
|
|
1533
|
+
const goldTransfer = Math.floor(
|
|
1534
|
+
(isWin ? targetGold : initiatorGold) * stealPercentage / 100
|
|
1535
|
+
);
|
|
1536
|
+
if ((isWin ? targetGold : initiatorGold) < goldTransfer) {
|
|
1537
|
+
return `${isWin ? "对方" : "你"}的金币不足以完成交易`;
|
|
1538
|
+
}
|
|
1539
|
+
await ctx.database.withTransaction(async () => {
|
|
1540
|
+
await ctx.database.upsert("ggcevo_pk", [{
|
|
1541
|
+
...initiatorPK,
|
|
1542
|
+
total: initiatorPK.total + 1,
|
|
1543
|
+
wins: isWin ? initiatorPK.wins + 1 : initiatorPK.wins,
|
|
1544
|
+
todayCount: initiatorPK.todayCount + 1,
|
|
1545
|
+
lastPK: /* @__PURE__ */ new Date()
|
|
1546
|
+
}]);
|
|
1547
|
+
if (isWin) {
|
|
1548
|
+
await ctx.database.set("ggcevo_sign", targetHandle, { totalRewards: targetGold - goldTransfer });
|
|
1549
|
+
await ctx.database.set("ggcevo_sign", initiatorHandle, { totalRewards: initiatorGold + goldTransfer });
|
|
1550
|
+
} else {
|
|
1551
|
+
await ctx.database.set("ggcevo_sign", initiatorHandle, { totalRewards: initiatorGold - goldTransfer });
|
|
1552
|
+
await ctx.database.set("ggcevo_sign", targetHandle, { totalRewards: targetGold + goldTransfer });
|
|
1553
|
+
}
|
|
1554
|
+
});
|
|
1555
|
+
const result = [
|
|
1556
|
+
`⚔️【对战结果】${isWin ? "胜利" : "失败"}`,
|
|
1557
|
+
`🏅 挑战者:${initiatorData[0]?.name}(积分 ${initiatorData[0]?.rank})`,
|
|
1558
|
+
`🛡️ 应战者:${targetData[0]?.name}(积分 ${targetData[0]?.rank})`,
|
|
1559
|
+
`📊 胜率预测:${winRate.toFixed(1)}%`,
|
|
1560
|
+
`🎰 金币变动:${stealPercentage}%`
|
|
1561
|
+
];
|
|
1562
|
+
isWin ? result.push(`💰 +${goldTransfer}`, `💸 对方损失 ${goldTransfer}`) : result.push(`💸 -${goldTransfer}`, `💰 对方获得 ${goldTransfer}`);
|
|
1563
|
+
result.push(`📅 剩余挑战次数:${config.dailyPKLimit - (initiatorPK.todayCount + 1)}`);
|
|
1564
|
+
return result.join("\n");
|
|
1565
|
+
} catch (error) {
|
|
1566
|
+
console.error("PK系统异常:", error);
|
|
1567
|
+
return "对战功能暂时不可用,请稍后重试";
|
|
1568
|
+
}
|
|
1569
|
+
});
|
|
1480
1570
|
}
|
|
1481
1571
|
__name(apply, "apply");
|
|
1482
1572
|
function simpleDraw() {
|