koishi-plugin-xxck-1 0.1.21 → 0.1.22
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.js +132 -25
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -61,7 +61,7 @@ function getToday() {
|
|
|
61
61
|
__name(getToday, "getToday");
|
|
62
62
|
async function _warehouse_draw_image(ctx, user_cards, show_name) {
|
|
63
63
|
try {
|
|
64
|
-
logger.info("开始绘制 WWC
|
|
64
|
+
logger.info("开始绘制 WWC 仓库图片(限定卡独立显示)");
|
|
65
65
|
const STAR_COLOR = {
|
|
66
66
|
7: "#FF00FF",
|
|
67
67
|
6: "#C00000",
|
|
@@ -78,9 +78,28 @@ async function _warehouse_draw_image(ctx, user_cards, show_name) {
|
|
|
78
78
|
const ROW_HEIGHT = 26;
|
|
79
79
|
const PADDING = 20;
|
|
80
80
|
const TITLE_HEIGHT = 50;
|
|
81
|
-
const
|
|
81
|
+
const [normalCards, eventCards] = await Promise.all([
|
|
82
|
+
ctx.database.get("gacha_card_pool", {}),
|
|
83
|
+
ctx.database.get("gacha_event_pool", {})
|
|
84
|
+
// 读取所有限时卡池
|
|
85
|
+
]);
|
|
82
86
|
const cardPool = /* @__PURE__ */ new Map();
|
|
83
|
-
|
|
87
|
+
normalCards.forEach((c) => cardPool.set(c.card_id, {
|
|
88
|
+
name: c.card_name,
|
|
89
|
+
star: c.card_star,
|
|
90
|
+
isLimit: false
|
|
91
|
+
// 标记普通卡
|
|
92
|
+
}));
|
|
93
|
+
eventCards.forEach((c) => {
|
|
94
|
+
if (!cardPool.has(c.card_id)) {
|
|
95
|
+
cardPool.set(c.card_id, {
|
|
96
|
+
name: c.card_name,
|
|
97
|
+
star: c.card_star,
|
|
98
|
+
isLimit: true
|
|
99
|
+
// 标记限定卡
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
});
|
|
84
103
|
const cardMap = /* @__PURE__ */ new Map();
|
|
85
104
|
for (const item of user_cards || []) {
|
|
86
105
|
const card_id = item.card_id;
|
|
@@ -99,13 +118,15 @@ async function _warehouse_draw_image(ctx, user_cards, show_name) {
|
|
|
99
118
|
const pool = cardPool.get(item.card_id) || {};
|
|
100
119
|
return {
|
|
101
120
|
id: item.card_id,
|
|
102
|
-
name: pool.
|
|
121
|
+
name: pool.name || "未知",
|
|
103
122
|
level: item.card_level ?? 0,
|
|
104
|
-
|
|
105
|
-
|
|
123
|
+
star: pool.star || 0,
|
|
124
|
+
isLimit: pool.isLimit || false
|
|
125
|
+
// 传递限定标记
|
|
106
126
|
};
|
|
107
127
|
});
|
|
108
128
|
const sortedCards = [...validCards].sort((a, b) => {
|
|
129
|
+
if (a.isLimit !== b.isLimit) return b.isLimit ? 1 : -1;
|
|
109
130
|
if (b.star !== a.star) return b.star - a.star;
|
|
110
131
|
return String(a.id).localeCompare(String(b.id), void 0, { numeric: true });
|
|
111
132
|
});
|
|
@@ -123,18 +144,19 @@ async function _warehouse_draw_image(ctx, user_cards, show_name) {
|
|
|
123
144
|
ctx2d.textAlign = "left";
|
|
124
145
|
ctx2d.font = "20px Microsoft YaHei";
|
|
125
146
|
ctx2d.fillStyle = "#000";
|
|
126
|
-
ctx2d.fillText(`玩家:${show_name}
|
|
147
|
+
ctx2d.fillText(`玩家:${show_name}(带【限定】标记为限时卡)`, PADDING, PADDING);
|
|
127
148
|
const getStarText = /* @__PURE__ */ __name((star) => {
|
|
128
149
|
const s = Math.max(0, Math.min(7, star));
|
|
129
150
|
return "★".repeat(s) + "☆".repeat(7 - s);
|
|
130
151
|
}, "getStarText");
|
|
131
152
|
sortedCards.forEach((card, index) => {
|
|
132
|
-
const { level, id, name: name2, star } = card;
|
|
153
|
+
const { level, id, name: name2, star, isLimit } = card;
|
|
133
154
|
const col = Math.floor(index / COL_MAX);
|
|
134
155
|
const row = index % COL_MAX;
|
|
135
156
|
const x = PADDING + col * (COLUMN_WIDTH + COLUMN_GAP);
|
|
136
157
|
const y = TITLE_HEIGHT + row * ROW_HEIGHT;
|
|
137
|
-
const
|
|
158
|
+
const limitTag = isLimit ? "【限定】" : "";
|
|
159
|
+
const text = `[${level}] ${id.padStart(4, "0")} ${name2} ${limitTag}${getStarText(star)}`;
|
|
138
160
|
ctx2d.font = "16px Microsoft YaHei";
|
|
139
161
|
ctx2d.fillStyle = STAR_COLOR[star] || "#333";
|
|
140
162
|
ctx2d.fillText(text, x, y);
|
|
@@ -195,17 +217,73 @@ async function _shop_draw_image(ctx, shopCards, user_disturbance, user_water_vap
|
|
|
195
217
|
}
|
|
196
218
|
__name(_shop_draw_image, "_shop_draw_image");
|
|
197
219
|
async function _collection_draw_image(ctx, show_name, total_collected, total_all, categoryProgress, categoryCards) {
|
|
198
|
-
logger.info("
|
|
220
|
+
logger.info("开始绘制收藏图片(含限定卡,不同步普通卡池)");
|
|
199
221
|
try {
|
|
200
222
|
if (!ctx.canvas) return null;
|
|
201
223
|
const BASE_X = 40;
|
|
202
224
|
const CARD_SIZE = 70;
|
|
203
225
|
const CARD_GAP = 10;
|
|
204
226
|
const ROW_HEIGHT = CARD_SIZE + CARD_GAP;
|
|
227
|
+
const [normalCards, eventCards] = await Promise.all([
|
|
228
|
+
ctx.database.get("gacha_card_pool", {}),
|
|
229
|
+
ctx.database.get("gacha_event_pool", {})
|
|
230
|
+
]);
|
|
231
|
+
const allCardMap = /* @__PURE__ */ new Map();
|
|
232
|
+
normalCards.forEach((c) => allCardMap.set(c.card_id, {
|
|
233
|
+
name: c.card_name,
|
|
234
|
+
star: c.card_star,
|
|
235
|
+
category: c.category,
|
|
236
|
+
isLimit: false
|
|
237
|
+
}));
|
|
238
|
+
eventCards.forEach((c) => {
|
|
239
|
+
if (!allCardMap.has(c.card_id)) {
|
|
240
|
+
allCardMap.set(c.card_id, {
|
|
241
|
+
name: c.card_name,
|
|
242
|
+
star: c.card_star,
|
|
243
|
+
category: c.card_type,
|
|
244
|
+
// 限定卡类别用 card_type
|
|
245
|
+
isLimit: true
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
const allMergedCards = Array.from(allCardMap.values());
|
|
250
|
+
total_all = allMergedCards.length;
|
|
251
|
+
const newCategoryCards = {};
|
|
252
|
+
const newCategoryTotal = {};
|
|
253
|
+
allMergedCards.forEach((card) => {
|
|
254
|
+
const category = card.category;
|
|
255
|
+
if (!category) return;
|
|
256
|
+
if (!newCategoryCards[category]) {
|
|
257
|
+
newCategoryCards[category] = [];
|
|
258
|
+
newCategoryTotal[category] = 0;
|
|
259
|
+
}
|
|
260
|
+
newCategoryCards[category].push(card.card_id);
|
|
261
|
+
newCategoryTotal[category]++;
|
|
262
|
+
});
|
|
263
|
+
const newCategoryProgress = {};
|
|
264
|
+
for (const category in newCategoryCards) {
|
|
265
|
+
const cards = newCategoryCards[category];
|
|
266
|
+
let collected = 0;
|
|
267
|
+
const cardMap = {};
|
|
268
|
+
cards.forEach((cid) => {
|
|
269
|
+
const card = allCardMap.get(cid);
|
|
270
|
+
if (card) {
|
|
271
|
+
const isCollected = categoryProgress[category]?.[2]?.[cid] || false;
|
|
272
|
+
if (isCollected) collected++;
|
|
273
|
+
cardMap[cid] = {
|
|
274
|
+
name: card.name,
|
|
275
|
+
star: card.star,
|
|
276
|
+
isLimit: card.isLimit
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
newCategoryProgress[category] = [collected, newCategoryTotal[category], cardMap];
|
|
281
|
+
}
|
|
282
|
+
total_collected = Object.values(newCategoryProgress).reduce((sum, [collected]) => sum + collected, 0);
|
|
205
283
|
let totalHeight = 140;
|
|
206
|
-
const years = Object.keys(
|
|
284
|
+
const years = Object.keys(newCategoryProgress);
|
|
207
285
|
for (const year of years) {
|
|
208
|
-
const cardCount =
|
|
286
|
+
const cardCount = newCategoryCards[year]?.length || 0;
|
|
209
287
|
const rows = Math.ceil(cardCount / 10);
|
|
210
288
|
totalHeight += 35 + 40 + rows * ROW_HEIGHT + 30;
|
|
211
289
|
}
|
|
@@ -227,7 +305,7 @@ async function _collection_draw_image(ctx, show_name, total_collected, total_all
|
|
|
227
305
|
ctx2d.fillStyle = "#000";
|
|
228
306
|
ctx2d.textAlign = "center";
|
|
229
307
|
ctx2d.font = "28px Microsoft YaHei";
|
|
230
|
-
ctx2d.fillText(`${show_name}
|
|
308
|
+
ctx2d.fillText(`${show_name} 的收藏进度(含限定卡)`, 450, 50);
|
|
231
309
|
ctx2d.font = "22px Microsoft YaHei";
|
|
232
310
|
ctx2d.fillStyle = "#E53E3E";
|
|
233
311
|
const pct = total_all > 0 ? (total_collected / total_all * 100).toFixed(1) : "0.0";
|
|
@@ -237,8 +315,8 @@ async function _collection_draw_image(ctx, show_name, total_collected, total_all
|
|
|
237
315
|
ctx2d.textBaseline = "alphabetic";
|
|
238
316
|
ctx2d.font = "20px Microsoft YaHei";
|
|
239
317
|
for (const year of years) {
|
|
240
|
-
const [collected, total, cardMap] =
|
|
241
|
-
const cids =
|
|
318
|
+
const [collected, total, cardMap] = newCategoryProgress[year];
|
|
319
|
+
const cids = newCategoryCards[year] || [];
|
|
242
320
|
const cardCount = cids.length;
|
|
243
321
|
ctx2d.fillStyle = "#222";
|
|
244
322
|
ctx2d.fillText(`【${year}】`, BASE_X, y);
|
|
@@ -258,7 +336,8 @@ async function _collection_draw_image(ctx, show_name, total_collected, total_all
|
|
|
258
336
|
y += ROW_HEIGHT;
|
|
259
337
|
}
|
|
260
338
|
ctx2d.fillStyle = "#fff";
|
|
261
|
-
ctx2d.strokeStyle = "#e5e5e5";
|
|
339
|
+
ctx2d.strokeStyle = card?.isLimit ? "#FF0000" : "#e5e5e5";
|
|
340
|
+
ctx2d.lineWidth = card?.isLimit ? 2 : 1;
|
|
262
341
|
ctx2d.fillRect(x, y, CARD_SIZE, CARD_SIZE);
|
|
263
342
|
ctx2d.strokeRect(x, y, CARD_SIZE, CARD_SIZE);
|
|
264
343
|
ctx2d.textAlign = "center";
|
|
@@ -266,7 +345,8 @@ async function _collection_draw_image(ctx, show_name, total_collected, total_all
|
|
|
266
345
|
if (hasCard) {
|
|
267
346
|
const star = card.star || 0;
|
|
268
347
|
ctx2d.fillStyle = STAR_COLOR[star];
|
|
269
|
-
|
|
348
|
+
const displayName = card.isLimit ? `${card.name}限` : card.name;
|
|
349
|
+
ctx2d.fillText(displayName, x + CARD_SIZE / 2, y + CARD_SIZE / 2 + 5);
|
|
270
350
|
} else {
|
|
271
351
|
ctx2d.fillStyle = "#999";
|
|
272
352
|
ctx2d.fillText("?", x + CARD_SIZE / 2, y + CARD_SIZE / 2 + 5);
|
|
@@ -279,7 +359,7 @@ async function _collection_draw_image(ctx, show_name, total_collected, total_all
|
|
|
279
359
|
ctx2d.font = "20px Microsoft YaHei";
|
|
280
360
|
}
|
|
281
361
|
const buffer = await canvas.toBuffer("image/png");
|
|
282
|
-
logger.info("
|
|
362
|
+
logger.info("收藏图片生成成功(含限定卡)✅");
|
|
283
363
|
return import_koishi.h.image(buffer, "image/png");
|
|
284
364
|
} catch (err) {
|
|
285
365
|
logger.error("收藏绘图失败:", err);
|
|
@@ -865,7 +945,7 @@ async function _do_exchange(ctx, session, exchange_num) {
|
|
|
865
945
|
}
|
|
866
946
|
__name(_do_exchange, "_do_exchange");
|
|
867
947
|
async function _do_collection(ctx, session) {
|
|
868
|
-
logger.info("收到指令:WWC
|
|
948
|
+
logger.info("收到指令:WWC收藏(含限定卡统计)");
|
|
869
949
|
try {
|
|
870
950
|
const qq = session.userId;
|
|
871
951
|
const user = await ctx.database.get("gacha_user", { qq });
|
|
@@ -873,15 +953,41 @@ async function _do_collection(ctx, session) {
|
|
|
873
953
|
const show_name = user[0].status === 1 ? user[0].nickname : qq;
|
|
874
954
|
const userCards = await ctx.database.get("gacha_user_card", { qq });
|
|
875
955
|
const cardIds = userCards.map((uc) => uc.card_id);
|
|
876
|
-
const
|
|
956
|
+
const [normalCards, eventCards] = await Promise.all([
|
|
957
|
+
ctx.database.get("gacha_card_pool", {}),
|
|
958
|
+
ctx.database.get("gacha_event_pool", {})
|
|
959
|
+
]);
|
|
960
|
+
const allCardMap = /* @__PURE__ */ new Map();
|
|
961
|
+
normalCards.forEach((c) => allCardMap.set(c.card_id, {
|
|
962
|
+
name: c.card_name,
|
|
963
|
+
star: c.card_star,
|
|
964
|
+
category: c.category,
|
|
965
|
+
isLimit: false
|
|
966
|
+
}));
|
|
967
|
+
eventCards.forEach((c) => {
|
|
968
|
+
if (!allCardMap.has(c.card_id)) {
|
|
969
|
+
allCardMap.set(c.card_id, {
|
|
970
|
+
name: c.card_name,
|
|
971
|
+
star: c.card_star,
|
|
972
|
+
category: c.card_type,
|
|
973
|
+
isLimit: true
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
});
|
|
977
|
+
const allCards = Array.from(allCardMap.values());
|
|
877
978
|
const collectedSet = /* @__PURE__ */ new Set();
|
|
878
979
|
const cardStarMap = {};
|
|
879
980
|
for (const card of allCards) {
|
|
880
981
|
if (!card.category) continue;
|
|
881
|
-
|
|
882
|
-
|
|
982
|
+
const cardId = Array.from(allCardMap.keys()).find((id) => allCardMap.get(id) === card);
|
|
983
|
+
if (cardIds.includes(cardId)) {
|
|
984
|
+
collectedSet.add(`${card.category}-${cardId}`);
|
|
883
985
|
if (!cardStarMap[card.category]) cardStarMap[card.category] = {};
|
|
884
|
-
cardStarMap[card.category][
|
|
986
|
+
cardStarMap[card.category][cardId] = {
|
|
987
|
+
name: card.name,
|
|
988
|
+
star: card.star,
|
|
989
|
+
isLimit: card.isLimit
|
|
990
|
+
};
|
|
885
991
|
}
|
|
886
992
|
}
|
|
887
993
|
const total_collected = collectedSet.size;
|
|
@@ -890,11 +996,12 @@ async function _do_collection(ctx, session) {
|
|
|
890
996
|
const categoryTotal = {};
|
|
891
997
|
for (const card of allCards) {
|
|
892
998
|
if (!card.category) continue;
|
|
999
|
+
const cardId = Array.from(allCardMap.keys()).find((id) => allCardMap.get(id) === card);
|
|
893
1000
|
if (!categoryCards[card.category]) {
|
|
894
1001
|
categoryCards[card.category] = [];
|
|
895
1002
|
categoryTotal[card.category] = 0;
|
|
896
1003
|
}
|
|
897
|
-
categoryCards[card.category].push(
|
|
1004
|
+
categoryCards[card.category].push(cardId);
|
|
898
1005
|
categoryTotal[card.category]++;
|
|
899
1006
|
}
|
|
900
1007
|
const categoryProgress = {};
|
|
@@ -902,7 +1009,7 @@ async function _do_collection(ctx, session) {
|
|
|
902
1009
|
const collected = Object.keys(cardStarMap[category] || {}).length;
|
|
903
1010
|
categoryProgress[category] = [collected, categoryTotal[category], cardStarMap[category] || {}];
|
|
904
1011
|
}
|
|
905
|
-
logger.info("
|
|
1012
|
+
logger.info("收藏数据获取成功(含限定卡),开始生成图片");
|
|
906
1013
|
const img_base64 = await _collection_draw_image(ctx, show_name, total_collected, total_all, categoryProgress, categoryCards);
|
|
907
1014
|
if (!img_base64) {
|
|
908
1015
|
logger.error("收藏图片生成失败!");
|
package/package.json
CHANGED