koishi-plugin-ggcevo-game 1.0.17 → 1.0.18

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 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,84 @@ ${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 ({ session }, user) => {
1491
+ try {
1492
+ const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
1493
+ if (!profile) return "您的 QQ 未绑定句柄。";
1494
+ const parsedUser = import_koishi.h.parse(user)[0];
1495
+ if (!parsedUser || parsedUser.type !== "at") return "请使用@指定对战玩家";
1496
+ const targetUserId = parsedUser.attrs.id;
1497
+ const [targetprofile] = await ctx.database.get("sc2arcade_player", { userId: targetUserId });
1498
+ if (!targetprofile) return "对方尚未绑定句柄";
1499
+ const initiatorHandle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
1500
+ const targetHandle = `${targetprofile.regionId}-S2-${targetprofile.realmId}-${targetprofile.profileId}`;
1501
+ if (initiatorHandle === targetHandle) return "不能挑战自己哦~";
1502
+ let initiatorPK, targetPK;
1503
+ await ctx.database.withTransaction(async () => {
1504
+ [initiatorPK] = await ctx.database.get("ggcevo_pk", initiatorHandle) || [{ handle: initiatorHandle, total: 0, wins: 0, todayCount: 0, lastPK: /* @__PURE__ */ new Date(0) }];
1505
+ [targetPK] = await ctx.database.get("ggcevo_pk", targetHandle) || [{ handle: targetHandle, total: 0, wins: 0, todayCount: 0, lastPK: /* @__PURE__ */ new Date(0) }];
1506
+ });
1507
+ const now = convertUTCtoChinaTime(/* @__PURE__ */ new Date());
1508
+ if (!isSameDate(convertUTCtoChinaTime(initiatorPK.lastPK), now)) {
1509
+ initiatorPK.todayCount = 0;
1510
+ }
1511
+ if (initiatorPK.todayCount >= config.dailyPKLimit) {
1512
+ return `今日挑战次数已用尽(${config.dailyPKLimit}次/日)`;
1513
+ }
1514
+ const [initiatorData, targetData] = await Promise.all([
1515
+ ctx.database.get("ggcevo_rank", initiatorHandle),
1516
+ ctx.database.get("ggcevo_rank", targetHandle)
1517
+ ]);
1518
+ const [initiatorSign, targetSign] = await Promise.all([
1519
+ ctx.database.get("ggcevo_sign", initiatorHandle),
1520
+ ctx.database.get("ggcevo_sign", targetHandle)
1521
+ ]);
1522
+ const initiatorGold = initiatorSign[0]?.totalRewards || 0;
1523
+ const targetGold = targetSign[0]?.totalRewards || 0;
1524
+ if (initiatorGold < 100) return "发起者需要至少100金币才能挑战!";
1525
+ if (targetGold < 100) return "对方金币不足100,无法应战";
1526
+ const rankDiff = (initiatorData[0]?.rank || 0) - (targetData[0]?.rank || 0);
1527
+ const clampedDiff = Math.min(Math.max(rankDiff, -1e4), 1e4);
1528
+ const winRate = Math.min(Math.max(50 + clampedDiff * 5e-3, 5), 95);
1529
+ const isWin = Math.random() * 100 < winRate;
1530
+ const stealPercentage = getRandomInt(1, 5);
1531
+ const goldTransfer = Math.floor(
1532
+ (isWin ? targetGold : initiatorGold) * stealPercentage / 100
1533
+ );
1534
+ if ((isWin ? targetGold : initiatorGold) < goldTransfer) {
1535
+ return `${isWin ? "对方" : "你"}的金币不足以完成交易`;
1536
+ }
1537
+ await ctx.database.withTransaction(async () => {
1538
+ await ctx.database.upsert("ggcevo_pk", [{
1539
+ ...initiatorPK,
1540
+ total: initiatorPK.total + 1,
1541
+ wins: isWin ? initiatorPK.wins + 1 : initiatorPK.wins,
1542
+ todayCount: initiatorPK.todayCount + 1,
1543
+ lastPK: /* @__PURE__ */ new Date()
1544
+ }]);
1545
+ if (isWin) {
1546
+ await ctx.database.set("ggcevo_sign", targetHandle, { totalRewards: targetGold - goldTransfer });
1547
+ await ctx.database.set("ggcevo_sign", initiatorHandle, { totalRewards: initiatorGold + goldTransfer });
1548
+ } else {
1549
+ await ctx.database.set("ggcevo_sign", initiatorHandle, { totalRewards: initiatorGold - goldTransfer });
1550
+ await ctx.database.set("ggcevo_sign", targetHandle, { totalRewards: targetGold + goldTransfer });
1551
+ }
1552
+ });
1553
+ const result = [
1554
+ `⚔️【对战结果】${isWin ? "胜利" : "失败"}`,
1555
+ `🏅 挑战者:${initiatorData[0]?.name}(积分 ${initiatorData[0]?.rank})`,
1556
+ `🛡️ 应战者:${targetData[0]?.name}(积分 ${targetData[0]?.rank})`,
1557
+ `📊 胜率预测:${winRate.toFixed(1)}%`,
1558
+ `🎰 金币变动:${stealPercentage}%`
1559
+ ];
1560
+ isWin ? result.push(`💰 +${goldTransfer}`, `💸 对方损失 ${goldTransfer}`) : result.push(`💸 -${goldTransfer}`, `💰 对方获得 ${goldTransfer}`);
1561
+ result.push(`📅 剩余挑战次数:${config.dailyPKLimit - (initiatorPK.todayCount + 1)}`);
1562
+ return result.join("\n");
1563
+ } catch (error) {
1564
+ console.error("PK系统异常:", error);
1565
+ return "对战功能暂时不可用,请稍后重试";
1566
+ }
1567
+ });
1480
1568
  }
1481
1569
  __name(apply, "apply");
1482
1570
  function simpleDraw() {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-ggcevo-game",
3
3
  "description": "星际争霸2游戏大厅咕咕虫-Evo地图专属插件",
4
- "version": "1.0.17",
4
+ "version": "1.0.18",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [