koishi-plugin-ggcevo-game 0.3.9 → 0.3.12

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
@@ -13,7 +13,6 @@ export declare const inject: {
13
13
  };
14
14
  declare module 'koishi' {
15
15
  interface Tables {
16
- ggcevo_items: Item;
17
16
  ggcevo_backpack: backpack;
18
17
  ggcevo_sign: sign;
19
18
  ggcevo_records: record;
@@ -23,15 +22,9 @@ declare module 'koishi' {
23
22
  ggcevo_Punishment: Punishment;
24
23
  ggcevo_exchange: exchange;
25
24
  ggcevo_adminbenefit: adminbenefit;
25
+ ggcevo_blacklist: blacklist;
26
26
  }
27
27
  }
28
- export interface Item {
29
- id: number;
30
- name: string;
31
- type: 'consumable' | 'equipment' | 'material';
32
- description: string;
33
- effect?: any;
34
- }
35
28
  export interface backpack {
36
29
  handle: string;
37
30
  itemId: number;
@@ -85,7 +78,6 @@ export interface Punishment {
85
78
  comment?: string;
86
79
  }
87
80
  export interface exchange {
88
- id: number;
89
81
  userId: string;
90
82
  handle: string;
91
83
  item: string;
@@ -98,4 +90,9 @@ export interface adminbenefit {
98
90
  signmonth: number;
99
91
  lastSign: Date;
100
92
  }
93
+ export interface blacklist {
94
+ userId: string;
95
+ handle: string;
96
+ createdAt: Date;
97
+ }
101
98
  export declare function apply(ctx: Context, config: Config): void;
package/lib/index.js CHANGED
@@ -39,15 +39,6 @@ var inject = {
39
39
  required: ["database"]
40
40
  };
41
41
  function apply(ctx, config) {
42
- ctx.model.extend("ggcevo_items", {
43
- id: "unsigned",
44
- name: "string",
45
- type: "string",
46
- description: "text",
47
- effect: "json"
48
- }, {
49
- primary: "name"
50
- });
51
42
  ctx.model.extend("ggcevo_backpack", {
52
43
  handle: "string",
53
44
  itemId: "unsigned",
@@ -138,7 +129,6 @@ function apply(ctx, config) {
138
129
  });
139
130
  ctx.model.extend("ggcevo_exchange", {
140
131
  // 各字段定义
141
- id: "unsigned",
142
132
  userId: "string",
143
133
  handle: "string",
144
134
  // 句柄
@@ -148,9 +138,7 @@ function apply(ctx, config) {
148
138
  date: "timestamp"
149
139
  }, {
150
140
  // 额外配置
151
- primary: "id",
152
- autoInc: true
153
- // 启用自增ID
141
+ primary: ["handle", "item"]
154
142
  });
155
143
  ctx.model.extend("ggcevo_adminbenefit", {
156
144
  // 各字段定义
@@ -163,19 +151,24 @@ function apply(ctx, config) {
163
151
  // 额外配置
164
152
  primary: "userId"
165
153
  });
166
- async function initDefaultItems() {
167
- const defaultItems = [
168
- { id: 1, name: "咕咕币", type: "consumable", description: "用于进行抽奖" },
169
- { id: 2, name: "兑换券", type: "material", description: "用于兑换赞助物品,输入 兑换图 查看详情" },
170
- { id: 3, name: "扭蛋币", type: "consumable", description: "用于进行宠物扭蛋" },
171
- { id: 4, name: "t3级宠物扭蛋", type: "material", description: "用于兑换t3系列宠物" },
172
- { id: 5, name: "t2级宠物扭蛋", type: "material", description: "用于兑换t2系列宠物" },
173
- { id: 6, name: "t1级宠物扭蛋", type: "material", description: "用于兑换t1系列宠物" },
174
- { id: 7, name: "t0级宠物扭蛋", type: "material", description: "用于兑换t0系列宠物" }
175
- ];
176
- await ctx.database.upsert("ggcevo_items", defaultItems, ["name"]);
177
- }
178
- __name(initDefaultItems, "initDefaultItems");
154
+ ctx.model.extend("ggcevo_blacklist", {
155
+ // 各字段定义
156
+ userId: "string",
157
+ handle: "string",
158
+ createdAt: "timestamp"
159
+ }, {
160
+ // 额外配置
161
+ primary: "userId"
162
+ });
163
+ const initDefaultItems = {
164
+ "咕咕币": { id: 1, type: "抽奖道具", description: "用于进行抽奖" },
165
+ "兑换券": { id: 2, type: "兑换货币", description: "用于兑换赞助物品" },
166
+ "扭蛋币": { id: 3, type: "抽奖道具", description: "用于进行宠物扭蛋" },
167
+ "t3级宠物扭蛋": { id: 4, type: "宠物蛋", description: "用于兑换t3系列宠物" },
168
+ "t2级宠物扭蛋": { id: 5, type: "宠物蛋", description: "用于兑换t2系列宠物" },
169
+ "t1级宠物扭蛋": { id: 6, type: "宠物蛋", description: "用于兑换t1系列宠物" },
170
+ "t0级宠物扭蛋": { id: 7, type: "宠物蛋", description: "用于兑换t0系列宠物" }
171
+ };
179
172
  async function gachaWithPity(handle) {
180
173
  const [record] = await ctx.database.get("ggcevo_records", { handle });
181
174
  const currentPity = record?.pityCounter ?? 0;
@@ -237,15 +230,6 @@ function apply(ctx, config) {
237
230
  }
238
231
  }
239
232
  __name(checkSensitiveWord, "checkSensitiveWord");
240
- ctx.command("ggcevo/物品初始化", "初始化物品数据", { authority: 3 }).action(async (_) => {
241
- try {
242
- await initDefaultItems();
243
- return "物品初始化成功";
244
- } catch (e) {
245
- ctx.logger.error("初始化失败:", e);
246
- return "物品初始化失败,请查看日志";
247
- }
248
- });
249
233
  ctx.command("ggcevo/抽奖").action(async (argv) => {
250
234
  const session = argv.session;
251
235
  let winCount = 0;
@@ -365,17 +349,18 @@ function apply(ctx, config) {
365
349
  ctx.command("ggcevo/背包").action(async (argv) => {
366
350
  const session = argv.session;
367
351
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
368
- if (!profile) {
369
- return "您的 QQ 未绑定句柄。";
370
- }
371
- const { regionId, realmId, profileId } = profile;
372
- const handle = `${regionId}-S2-${realmId}-${profileId}`;
352
+ if (!profile) return "您的 QQ 未绑定句柄。";
353
+ const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
373
354
  const items = await ctx.database.get("ggcevo_backpack", { handle });
374
355
  if (!items.length) return "你的背包空空如也~";
375
- const itemDetails = await Promise.all(items.map(async (userItem) => {
376
- const item = await ctx.database.get("ggcevo_items", { id: userItem.itemId }).then((res) => res[0]);
377
- return `${item.name} × ${userItem.quantity}:${item.description}`;
378
- }));
356
+ const itemDetails = items.map((userItem) => {
357
+ const entry = Object.entries(initDefaultItems).find(
358
+ ([name2, item]) => item.id === userItem.itemId
359
+ );
360
+ if (!entry) return `未知物品 × ${userItem.quantity}:数据异常,请联系管理员`;
361
+ const [itemName, itemData] = entry;
362
+ return `${itemName} × ${userItem.quantity}:${itemData.description}`;
363
+ });
379
364
  return `【你的背包】
380
365
  ${itemDetails.join("\n")}`;
381
366
  });
@@ -409,7 +394,8 @@ ${itemDetails.join("\n")}`;
409
394
  }
410
395
  const now = /* @__PURE__ */ new Date();
411
396
  const chinatime = convertUTCtoChinaTime(now);
412
- if (!isSameDate(latestTime, chinatime)) {
397
+ const is23Hour = chinatime.getHours() === 23;
398
+ if (!is23Hour && !isSameDate(latestTime, chinatime)) {
413
399
  return "暂未查询到您今天最近的20场战绩内游玩过 咕咕虫-evolved 地图,请游玩1次后签到(对局记录上传有延迟)";
414
400
  }
415
401
  const [record] = await ctx.database.get("ggcevo_sign", { handle });
@@ -515,10 +501,12 @@ ${itemDetails.join("\n")}`;
515
501
  }]);
516
502
  return `[管理专属] 成功领取本月津贴!获得 50 枚咕咕币`;
517
503
  });
518
- ctx.command("ggcevo/领取福利 <name>").action(async (argv, name2) => {
504
+ ctx.command("ggcevo/领取福利").alias("领取奖励").action(async (argv) => {
519
505
  const session = argv.session;
506
+ await session.send("请在30秒内输入活动名称:\n(输入 咕咕币活动 以查看活动列表)");
507
+ const name2 = await session.prompt(3e4);
520
508
  if (!name2) {
521
- return "活动名称不能为空,请输入 咕咕币活动 查看进行中的活动";
509
+ return "输入超时,请重新输入指令。";
522
510
  }
523
511
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
524
512
  if (!profile) return "您的 QQ 未绑定句柄。";
@@ -591,7 +579,7 @@ ${itemDetails.join("\n")}`;
591
579
  ID:${activity.id}
592
580
  状态:${status}`;
593
581
  });
594
- ctx.command("ggcevo/咕咕币活动", "查看进行中的活动").action(async () => {
582
+ ctx.command("ggcevo/咕咕币活动", "查看进行中的活动").alias("活动列表").action(async () => {
595
583
  const activities = await ctx.database.get("ggcevo_activity", {
596
584
  status: "进行中"
597
585
  // 完全依赖数据库状态
@@ -758,7 +746,7 @@ ID:${activity.id}
758
746
  return "服务器繁忙,请稍后尝试。";
759
747
  }
760
748
  });
761
- ctx.command("ggcevo/胜点榜 [page]").usage("输入 rank [页码] 查看对应页的排行榜,每页10条").action(async (_, page) => {
749
+ ctx.command("ggcevo/胜点榜 [page]").alias("排行榜").usage("输入 rank [页码] 查看对应页的排行榜,每页10条").action(async (_, page) => {
762
750
  const pageNum = parseInt(page) || 1;
763
751
  if (pageNum < 1) return "请输入有效的页码。";
764
752
  const offset = (pageNum - 1) * 10;
@@ -964,7 +952,7 @@ ${items.join("、")}
964
952
  if (userRecords.length > 0) return "您已经兑换过该物品";
965
953
  if (configname.quantity !== void 0) {
966
954
  const globalRecords = await ctx.database.get("ggcevo_exchange", { item: name2 });
967
- if (globalRecords.length >= configname.quantity) return "该物品已兑尽";
955
+ if (globalRecords.length >= configname.quantity) return "该物品已被兑换尽了";
968
956
  }
969
957
  const qualityMap = { "t3": 4, "t2": 5, "t1": 6, "t0": 7 };
970
958
  const petItems = new Set(
@@ -987,7 +975,7 @@ ${items.join("、")}
987
975
  }
988
976
  const [coupon] = await ctx.database.get("ggcevo_backpack", { handle, itemId });
989
977
  if (!coupon || coupon.quantity < cost) {
990
- const requireMsg = petItems.has(name2) ? `需要 1 个${configname.quality}级扭蛋 或 ${configname.cost}个兑奖券` : `需要 ${configname.cost}个兑奖券`;
978
+ const requireMsg = petItems.has(name2) ? `需要 1 个${configname.quality}级宠物扭蛋 或 ${configname.cost}个兑奖券` : `需要 ${configname.cost}个兑奖券`;
991
979
  return `${requireMsg}
992
980
  当前持有:${coupon?.quantity || 0}个${couponName}`;
993
981
  }
@@ -1068,25 +1056,58 @@ ${output}`;
1068
1056
  if (!backpack || backpack.quantity < 1) {
1069
1057
  return `当前扭蛋币不足,剩余:${backpack?.quantity || 0}枚`;
1070
1058
  }
1071
- const award = PetCapsuleToy();
1072
- const items = await ctx.database.get("ggcevo_items", { name: award });
1073
- if (items.length === 0) {
1074
- return `系统错误,奖品${award}不存在,请联系管理员。`;
1059
+ const awardName = PetCapsuleToy();
1060
+ const awardItem = Object.entries(initDefaultItems).find(
1061
+ ([name2, item]) => name2 === awardName
1062
+ );
1063
+ if (!awardItem) {
1064
+ return `系统错误,奖品「${awardName}」不存在,请联系管理员。`;
1075
1065
  }
1076
- const item = items[0];
1066
+ const [itemName, itemData] = awardItem;
1077
1067
  await ctx.database.upsert("ggcevo_backpack", [{
1078
1068
  handle,
1079
1069
  itemId: 3,
1080
1070
  quantity: backpack.quantity - 1
1081
1071
  }]);
1082
- const [userAward] = await ctx.database.get("ggcevo_backpack", { handle, itemId: item.id });
1072
+ const [userAward] = await ctx.database.get("ggcevo_backpack", { handle, itemId: itemData.id });
1083
1073
  const currentQuantity = userAward ? userAward.quantity : 0;
1084
1074
  await ctx.database.upsert("ggcevo_backpack", [{
1085
1075
  handle,
1086
- itemId: item.id,
1076
+ itemId: itemData.id,
1087
1077
  quantity: currentQuantity + 1
1088
1078
  }]);
1089
- return `🎉 恭喜获得:${award}`;
1079
+ return `🎉 恭喜获得:${itemName}`;
1080
+ });
1081
+ ctx.command("ggcevo/拉黑 <handle>", "添加用户到黑名单", { authority: 3 }).action(async (_, handle) => {
1082
+ if (!handle) return "请指定需要拉黑的用户";
1083
+ try {
1084
+ const handleRegex = /^([1235])-S2-([12])-(\d+)$/;
1085
+ if (!handleRegex.test(handle)) {
1086
+ return "句柄格式错误,请重新输入";
1087
+ }
1088
+ const [, regionId, realmId, profileId] = handle.match(handleRegex).map(Number);
1089
+ const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
1090
+ if (existingEntries.length > 0) {
1091
+ return `${handle} 已在黑名单中`;
1092
+ }
1093
+ const [profile] = await ctx.database.get("sc2arcade_player", {
1094
+ regionId,
1095
+ realmId,
1096
+ profileId
1097
+ }, ["userId"]);
1098
+ if (!profile) {
1099
+ return `未找到与 ${handle} 绑定的QQ号`;
1100
+ }
1101
+ await ctx.database.create("ggcevo_blacklist", {
1102
+ userId: profile.userId,
1103
+ handle,
1104
+ createdAt: /* @__PURE__ */ new Date()
1105
+ });
1106
+ return `✅ 用户 ${handle} 已被列入黑名单`;
1107
+ } catch (error) {
1108
+ ctx.logger.error("黑名单操作失败:", error);
1109
+ return "操作失败,请稍后重试。错误详情已记录";
1110
+ }
1090
1111
  });
1091
1112
  }
1092
1113
  __name(apply, "apply");
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-ggcevo-game",
3
3
  "description": "星际争霸2游戏大厅地图咕咕虫-evo小游戏",
4
- "version": "0.3.9",
4
+ "version": "0.3.12",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [