koishi-plugin-xxck-1 0.3.3 → 0.3.5

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
@@ -9,6 +9,8 @@ export interface PluginConfig {
9
9
  exchangeVaporPerDraw: number;
10
10
  eventExchangePrice6: number;
11
11
  eventExchangePrice7: number;
12
+ collectionPart1Pattern: string;
13
+ collectionPart2Pattern: string;
12
14
  normalStar7Threshold: number;
13
15
  normalStar6Threshold: number;
14
16
  normalStar6Prob: number;
@@ -23,6 +25,8 @@ export declare const Config: Schema<Schemastery.ObjectS<{
23
25
  exchangeVaporPerDraw: Schema<number, number>;
24
26
  eventExchangePrice6: Schema<number, number>;
25
27
  eventExchangePrice7: Schema<number, number>;
28
+ collectionPart1Pattern: Schema<string, string>;
29
+ collectionPart2Pattern: Schema<string, string>;
26
30
  normalStar7Threshold: Schema<number, number>;
27
31
  normalStar6Threshold: Schema<number, number>;
28
32
  normalStar6Prob: Schema<number, number>;
@@ -36,6 +40,8 @@ export declare const Config: Schema<Schemastery.ObjectS<{
36
40
  exchangeVaporPerDraw: Schema<number, number>;
37
41
  eventExchangePrice6: Schema<number, number>;
38
42
  eventExchangePrice7: Schema<number, number>;
43
+ collectionPart1Pattern: Schema<string, string>;
44
+ collectionPart2Pattern: Schema<string, string>;
39
45
  normalStar7Threshold: Schema<number, number>;
40
46
  normalStar6Threshold: Schema<number, number>;
41
47
  normalStar6Prob: Schema<number, number>;
package/lib/index.js CHANGED
@@ -43,8 +43,8 @@ var zh_CN_default = {
43
43
  "command.wwc.help.shop": "店铺:查看今日可升格卡片 | 指令:WWC店铺 | 说明:每日随机刷新3个7星卡,全服限购",
44
44
  "command.wwc.help.upgrade": "升格:兑换店铺卡片 | 指令:WWC升格 [卡片编号...] | 说明:消耗热带扰动,重复卡片自动升级",
45
45
  "command.wwc.help.exchange": "兑换:水汽换普通抽数 | 指令:WWC兑换 [次数] | 说明:100水汽=1抽,每日上限80抽,单次1-40",
46
- "command.wwc.help.collection": "收藏:查看卡片收藏进度 | 指令:WWC收藏 | 说明:生成收藏进度图片,含普通+限定卡",
47
- "command.wwc.help.ranking": "排名:查看全服收藏排行 | 指令:WWC排名1/WWC排行1 | 说明:显示前20名+自身排名,按收藏数排序",
46
+ "command.wwc.help.collection": "收藏:查看卡片收藏进度 | 指令:WWC收藏(全部分类);WWC收藏1 / WWC收藏2 / WWC收藏3 为拆分版(分类正则可在插件配置项 collectionPart1Pattern / collectionPart2Pattern 中定义,收藏3 = 两者都不匹配的类别)| 说明:含普通+限定卡",
47
+ "command.wwc.help.ranking": "排名:查看全服排行 | 指令:WWC排名1(按收藏数);WWC排名2(按7/6星战力分:7星0级20分每级+15,普通6星0级5分每级+3,限时6星0级8分每级+6)| 说明:显示前20名+自身排名",
48
48
  "command.wwc.help.eventStatus": "限时状态:查看开放的限时卡池 | 指令:WWC限时状态 | 说明:显示期数/名称/星级/开放时间",
49
49
  "command.wwc.help.eventDraw": "限时抽卡:参与限时卡池 | 指令:WWC限时抽卡 [期数] [次数] | 说明:1-20连,消耗限时抽数,无期限数匹配唯一开放池",
50
50
  "command.wwc.help.eventExchange": "限时兑换:水汽换限时抽数 | 指令:WWC限时兑换 [期数] [次数] | 说明:6星300水汽/抽,7星450水汽/抽,单次1-40",
@@ -142,6 +142,9 @@ var zh_CN_default = {
142
142
  "image.shop.footerTip": "每日刷新卡片,全服限购5次",
143
143
  "image.shop.cmdTemplate": "WWC升格 {cid}",
144
144
  "image.collection.title": "{showName} 的卡片收藏图鉴(含限定卡)",
145
+ "image.collection.title1": "{showName} 的卡片收藏图鉴1(分类规则见配置项)",
146
+ "image.collection.title2": "{showName} 的卡片收藏图鉴2(分类规则见配置项)",
147
+ "image.collection.title3": "{showName} 的卡片收藏图鉴3(其他类别)",
145
148
  "image.collection.totalProgress": "总收藏进度:{collected}/{total}({rate}%)",
146
149
  "image.collection.emptyText": "暂无任何卡片收藏,快去抽卡解锁图鉴吧!",
147
150
  "image.collection.cateTitleFormat": "【{cate}】",
@@ -151,6 +154,9 @@ var zh_CN_default = {
151
154
  "image.ranking.header.player": "玩家",
152
155
  "image.ranking.header.count": "收藏数量",
153
156
  "image.ranking.mine": "你的排名:第{rank}名 | 收藏卡片:{count}张",
157
+ "image.ranking2.title": "WWC全服7/6星战力排行榜(前20名)",
158
+ "image.ranking2.header.score": "综合得分",
159
+ "image.ranking2.mine": "你的排名:第{rank}名 | 综合得分:{score}分",
154
160
  // ==============================================
155
161
  // 6. 系统日志/通知(主人私信)
156
162
  // ==============================================
@@ -172,6 +178,8 @@ var Config = import_koishi.Schema.object({
172
178
  exchangeVaporPerDraw: import_koishi.Schema.number().description("普通兑换每抽消耗的水汽量(默认100)").default(100).min(0).max(1e4),
173
179
  eventExchangePrice6: import_koishi.Schema.number().description("限时卡池6星兑换每抽消耗的水汽量(默认300)").default(300).min(1).max(1e4),
174
180
  eventExchangePrice7: import_koishi.Schema.number().description("限时卡池7星兑换每抽消耗的水汽量(默认450)").default(450).min(1).max(1e4),
181
+ collectionPart1Pattern: import_koishi.Schema.string().description('WWC收藏1的分类正则:类别名匹配此正则的归入收藏图1(默认匹配"纯数字且≥2000")').default("^([2-9]\\d{3}|\\d{5,})$").role("textarea"),
182
+ collectionPart2Pattern: import_koishi.Schema.string().description('WWC收藏2的分类正则:类别名匹配此正则的归入收藏图2(默认匹配"纯数字且<2000");两个正则都不匹配的类别归入WWC收藏3').default("^(\\d{1,3}|1\\d{3})$").role("textarea"),
175
183
  normalStar7Threshold: import_koishi.Schema.number().description("普通卡池7星保底抽数(默认1500)").default(1500).min(1).max(1e4),
176
184
  normalStar6Threshold: import_koishi.Schema.number().description("普通卡池6星保底抽数(默认300)").default(300).min(1).max(1e4),
177
185
  normalStar6Prob: import_koishi.Schema.number().description("普通卡池6星保底抽出6星概率百分比(减去为抽出7星概率)").default(90).min(0).max(100),
@@ -1157,8 +1165,27 @@ ${session.text("tip.exchange.info", {
1157
1165
  ctx.logger.info(`[普通兑换抽数] 玩家${qq}兑换成功:获得${exchange_num}抽,今日剩余${leftToday}抽`);
1158
1166
  }
1159
1167
  __name(_do_exchange, "_do_exchange");
1160
- async function _do_collection(ctx, session) {
1161
- ctx.logger.info("收到指令:WWC收藏(含限定卡+灰色占位)");
1168
+ var DEFAULT_COLLECTION_PART1_PATTERN = "^([2-9]\\d{3}|\\d{5,})$";
1169
+ var DEFAULT_COLLECTION_PART2_PATTERN = "^(\\d{1,3}|1\\d{3})$";
1170
+ function compileCollectionPatterns(ctx, part1, part2) {
1171
+ const compile = /* @__PURE__ */ __name((pattern, fallback, label) => {
1172
+ const source = (pattern ?? "").trim() || fallback;
1173
+ try {
1174
+ return new RegExp(source);
1175
+ } catch (e) {
1176
+ ctx.logger.warn(`收藏图${label}分类正则无效(${source}),已回退默认规则`);
1177
+ return new RegExp(fallback);
1178
+ }
1179
+ }, "compile");
1180
+ return {
1181
+ part1: compile(part1, DEFAULT_COLLECTION_PART1_PATTERN, "1"),
1182
+ part2: compile(part2, DEFAULT_COLLECTION_PART2_PATTERN, "2")
1183
+ };
1184
+ }
1185
+ __name(compileCollectionPatterns, "compileCollectionPatterns");
1186
+ async function _do_collection(ctx, session, part, patterns) {
1187
+ const partPatterns = patterns ?? compileCollectionPatterns(ctx);
1188
+ ctx.logger.info(`收到指令:WWC收藏${part ?? ""}(含限定卡+灰色占位)`);
1162
1189
  try {
1163
1190
  const qq = await getUnifiedQQ(ctx, session);
1164
1191
  const user = await ctx.database.get("gacha_user", { qq });
@@ -1194,11 +1221,19 @@ async function _do_collection(ctx, session) {
1194
1221
  }
1195
1222
  });
1196
1223
  const allCards = Array.from(allCardMap.values());
1197
- const totalAll = allCards.length;
1198
- const totalCollected = allCards.filter((c) => userCardIds.has(c.id)).length;
1224
+ const isTargetCategory = /* @__PURE__ */ __name((cate) => {
1225
+ if (!part) return true;
1226
+ const c = cate || "";
1227
+ if (part === 1) return partPatterns.part1.test(c);
1228
+ if (part === 2) return partPatterns.part2.test(c);
1229
+ return !partPatterns.part1.test(c) && !partPatterns.part2.test(c);
1230
+ }, "isTargetCategory");
1231
+ const partCards = allCards.filter((c) => isTargetCategory(c.category));
1232
+ const totalAll = partCards.length;
1233
+ const totalCollected = partCards.filter((c) => userCardIds.has(c.id)).length;
1199
1234
  const totalRate = totalAll > 0 ? (totalCollected / totalAll * 100).toFixed(1) : "0.0";
1200
1235
  const categoryGroup = {};
1201
- allCards.forEach((card) => {
1236
+ partCards.forEach((card) => {
1202
1237
  const cate = card.category || "未分类";
1203
1238
  if (!categoryGroup[cate]) categoryGroup[cate] = [];
1204
1239
  categoryGroup[cate].push({
@@ -1208,7 +1243,8 @@ async function _do_collection(ctx, session) {
1208
1243
  });
1209
1244
  });
1210
1245
  const categories = Object.keys(categoryGroup).sort();
1211
- const titleText = session.text("image.collection.title", { showName: show_name });
1246
+ const titleKey = part === 1 ? "image.collection.title1" : part === 2 ? "image.collection.title2" : part === 3 ? "image.collection.title3" : "image.collection.title";
1247
+ const titleText = session.text(titleKey, { showName: show_name });
1212
1248
  const totalText = session.text("image.collection.totalProgress", {
1213
1249
  collected: totalCollected,
1214
1250
  total: totalAll,
@@ -1396,6 +1432,97 @@ async function _do_ranking(ctx, session) {
1396
1432
  }
1397
1433
  }
1398
1434
  __name(_do_ranking, "_do_ranking");
1435
+ async function _do_ranking2(ctx, session) {
1436
+ ctx.logger.info("WWC排名2 开始执行");
1437
+ try {
1438
+ const qq = await getUnifiedQQ(ctx, session);
1439
+ const user = await ctx.database.get("gacha_user", { qq });
1440
+ if (!user.length) {
1441
+ await session.send(build_msg(session, session.text("error.common.notRegister")));
1442
+ return;
1443
+ }
1444
+ const show_name = user[0].status === 1 ? user[0].nickname : qq;
1445
+ const [normalPoolCards, eventPoolCards] = await Promise.all([
1446
+ ctx.database.get("gacha_card_pool", {}, { fields: ["card_id", "card_star"] }),
1447
+ ctx.database.get("gacha_event_pool", {}, { fields: ["card_id", "card_star"] })
1448
+ ]);
1449
+ const poolInfo = /* @__PURE__ */ new Map();
1450
+ normalPoolCards.forEach((c) => {
1451
+ if (!poolInfo.has(c.card_id)) poolInfo.set(c.card_id, { star: c.card_star, isLimit: false });
1452
+ });
1453
+ eventPoolCards.forEach((c) => {
1454
+ if (!poolInfo.has(c.card_id)) poolInfo.set(c.card_id, { star: c.card_star, isLimit: true });
1455
+ });
1456
+ const all_users = await ctx.database.get("gacha_user", {});
1457
+ const ranking_data = [];
1458
+ for (const u of all_users) {
1459
+ try {
1460
+ const cards = await ctx.database.get("gacha_user_card", { qq: u.qq }, { fields: ["card_id", "card_level"] });
1461
+ const levelMap = /* @__PURE__ */ new Map();
1462
+ cards.forEach((c) => {
1463
+ const lv = c.card_level || 0;
1464
+ const prev = levelMap.get(c.card_id);
1465
+ if (prev === void 0 || lv > prev) levelMap.set(c.card_id, lv);
1466
+ });
1467
+ let totalScore = 0;
1468
+ levelMap.forEach((lv, cid) => {
1469
+ const info = poolInfo.get(cid);
1470
+ if (!info) return;
1471
+ if (info.star >= 7) totalScore += 20 + 15 * lv;
1472
+ else if (info.star === 6) totalScore += info.isLimit ? 8 + 6 * lv : 5 + 3 * lv;
1473
+ });
1474
+ ranking_data.push({
1475
+ qq: u.qq,
1476
+ show_name: u.status === 1 ? u.nickname : u.qq,
1477
+ total_score: totalScore
1478
+ });
1479
+ } catch (e) {
1480
+ continue;
1481
+ }
1482
+ }
1483
+ ranking_data.sort((a, b) => b.total_score - a.total_score);
1484
+ const ranking_list = [];
1485
+ let user_rank = 0;
1486
+ let user_score = 0;
1487
+ ranking_data.forEach((item, idx) => {
1488
+ const rank = idx + 1;
1489
+ if (item.qq === qq) {
1490
+ user_rank = rank;
1491
+ user_score = item.total_score;
1492
+ }
1493
+ if (rank <= 20) {
1494
+ ranking_list.push([rank, item.show_name, item.total_score]);
1495
+ }
1496
+ });
1497
+ const titleText = session.text("image.ranking2.title");
1498
+ const headerRankText = session.text("image.ranking.header.rank");
1499
+ const headerPlayerText = session.text("image.ranking.header.player");
1500
+ const headerCountText = session.text("image.ranking2.header.score");
1501
+ const mineText = session.text("image.ranking2.mine", { rank: user_rank, score: user_score });
1502
+ const img_base64 = await _ranking_draw_image(
1503
+ ctx,
1504
+ ranking_list,
1505
+ user_rank,
1506
+ user_score,
1507
+ show_name,
1508
+ titleText,
1509
+ headerRankText,
1510
+ headerPlayerText,
1511
+ headerCountText,
1512
+ mineText
1513
+ );
1514
+ if (img_base64) {
1515
+ await session.send(img_base64);
1516
+ ctx.logger.info("WWC排名2 图片发送成功");
1517
+ } else {
1518
+ await session.send(build_msg(session, session.text("error.common.imageGenerate")));
1519
+ }
1520
+ } catch (e) {
1521
+ ctx.logger.error("WWC排名2 报错:", e);
1522
+ await session.send(build_msg(session, session.text("error.ranking.fail")));
1523
+ }
1524
+ }
1525
+ __name(_do_ranking2, "_do_ranking2");
1399
1526
  async function _do_switch(ctx, session, type, action, masterQQ) {
1400
1527
  const userQQ = await getUnifiedQQ(ctx, session);
1401
1528
  if (userQQ !== masterQQ) {
@@ -2031,16 +2158,37 @@ async function apply(ctx, config) {
2031
2158
  const num = Number.isInteger(Number(count)) && Number(count) >= 1 && Number(count) <= 40 ? Number(count) : 1;
2032
2159
  await _do_exchange(ctx, session, num, config.dailyExchangeLimit, config.exchangeVaporPerDraw);
2033
2160
  });
2161
+ const collectionPatterns = compileCollectionPatterns(ctx, config.collectionPart1Pattern, config.collectionPart2Pattern);
2034
2162
  ctx.command("WWC收藏", "查看卡片收藏进度,含限定卡,生成可视化收藏图").alias("wwc收藏").alias("WWC收集进度").action(async (argv) => {
2035
2163
  if (!argv.session) return;
2036
2164
  const session = argv.session;
2037
2165
  await _do_collection(ctx, session);
2038
2166
  });
2167
+ ctx.command("WWC收藏1", "查看卡片收藏进度1(分类正则见配置项 collectionPart1Pattern),含限定卡,生成可视化收藏图").alias("wwc收藏1").action(async (argv) => {
2168
+ if (!argv.session) return;
2169
+ const session = argv.session;
2170
+ await _do_collection(ctx, session, 1, collectionPatterns);
2171
+ });
2172
+ ctx.command("WWC收藏2", "查看卡片收藏进度2(分类正则见配置项 collectionPart2Pattern),含限定卡,生成可视化收藏图").alias("wwc收藏2").action(async (argv) => {
2173
+ if (!argv.session) return;
2174
+ const session = argv.session;
2175
+ await _do_collection(ctx, session, 2, collectionPatterns);
2176
+ });
2177
+ ctx.command("WWC收藏3", "查看卡片收藏进度3(不匹配收藏1/2正则的类别),含限定卡,生成可视化收藏图").alias("wwc收藏3").action(async (argv) => {
2178
+ if (!argv.session) return;
2179
+ const session = argv.session;
2180
+ await _do_collection(ctx, session, 3, collectionPatterns);
2181
+ });
2039
2182
  ctx.command("WWC排名1", "查看全服收藏排行,显示前20名+自身排名,生成可视化排行图").alias("wwc排名1").alias("WWC排行1").alias("WWC榜单").action(async (argv) => {
2040
2183
  if (!argv.session) return;
2041
2184
  const session = argv.session;
2042
2185
  await _do_ranking(ctx, session);
2043
2186
  });
2187
+ ctx.command("WWC排名2", "查看全服7/6星战力评分排行(7星0级20分每级+15,普通6星0级5分每级+3,限时6星0级8分每级+6),显示前20名+自身排名").alias("wwc排名2").alias("WWC排行2").action(async (argv) => {
2188
+ if (!argv.session) return;
2189
+ const session = argv.session;
2190
+ await _do_ranking2(ctx, session);
2191
+ });
2044
2192
  ctx.command("WWC开启", "开启本群WWC功能,仅主人可用").alias("wwc开启").action(async (argv) => {
2045
2193
  if (!argv.session) return;
2046
2194
  const session = argv.session;
@@ -93,6 +93,9 @@ declare const _default: {
93
93
  "image.shop.footerTip": string;
94
94
  "image.shop.cmdTemplate": string;
95
95
  "image.collection.title": string;
96
+ "image.collection.title1": string;
97
+ "image.collection.title2": string;
98
+ "image.collection.title3": string;
96
99
  "image.collection.totalProgress": string;
97
100
  "image.collection.emptyText": string;
98
101
  "image.collection.cateTitleFormat": string;
@@ -102,6 +105,9 @@ declare const _default: {
102
105
  "image.ranking.header.player": string;
103
106
  "image.ranking.header.count": string;
104
107
  "image.ranking.mine": string;
108
+ "image.ranking2.title": string;
109
+ "image.ranking2.header.score": string;
110
+ "image.ranking2.mine": string;
105
111
  "sys.notify.register": string;
106
112
  "sys.notify.sign": string;
107
113
  "sys.notify.draw": string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-xxck-1",
3
3
  "description": "抽卡系统|完整指令说明见readme|建议使用skia-canvas",
4
- "version": "0.3.3",
4
+ "version": "0.3.5",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [