koishi-plugin-xxck-1 0.3.7 → 0.3.9

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
@@ -118,11 +118,6 @@ declare module 'koishi' {
118
118
  exchange_date: string;
119
119
  exchange_count: number;
120
120
  };
121
- gacha_shop_limit: {
122
- card_id: string;
123
- total_limit: number;
124
- left_limit: number;
125
- };
126
121
  gacha_event_pool: {
127
122
  code: string;
128
123
  card_id: string;
package/lib/index.js CHANGED
@@ -101,7 +101,7 @@ var zh_CN_default = {
101
101
  "error.draw.poolEmpty": "❌ 普通卡池暂无卡片!请联系主人录入卡片",
102
102
  "error.upgrade.cardNotInShop": "❌ 升格失败!编号【{cid}】不在今日店铺中!请查看WWC店铺获取最新卡片",
103
103
  "error.upgrade.cardNotInPool": "❌ 升格失败!编号【{cid}】不在卡池中!该卡片已被移除",
104
- "error.upgrade.cardLimitExceed": "❌ 升格失败!编号【{cid}】全服剩余可购买次数不足!当前剩余:{left}次",
104
+ "error.upgrade.cardLimitExceed": "❌ 升格失败!编号【{cid}】全服剩余可购买次数不足!当前剩余:{remaining}次",
105
105
  "error.upgrade.disturb.notEnough": "❌ 升格失败!热带扰动不足!当前拥有:{have},需要:{need}",
106
106
  "error.upgrade.paramInvalid": "❌ 升格参数错误!请输入店铺内的卡片编号,多个编号用空格分隔",
107
107
  "error.exchange.count.invalid": "❌ 兑换数量错误!请输入1-40之间的正整数!",
@@ -121,12 +121,7 @@ var zh_CN_default = {
121
121
  "error.disturbDraw.count.notEnough": "❌ 扰动抽数不足!\n当前剩余:{have} 次 | 需要:{need} 次(可使用 WWC扰动兑换 兑换)",
122
122
  "error.switch.private": "❌ 私信场景无需设置群开关!该指令仅可在群聊中使用",
123
123
  "error.switch.fail": "❌ 开关操作失败!{msg}",
124
- "error.shop.no7starCard": "❌ 店铺生成失败!普通卡池中无7星卡片,请联系主人录入",
125
- "error.shop.fail": "❌ 店铺功能执行异常,请稍后再试!",
126
124
  "error.shop.cardNotEnough": "店铺卡片数量不足,无法刷新",
127
- "error.shop.cardNotInShop": "卡片{cid}不在今日店铺中,无法兑换",
128
- "error.shop.cardNotInPool": "卡片{cid}未在卡池注册,无法兑换",
129
- "error.shop.cardLimitExceed": "卡片{cid}限购超限,剩余仅{remaining}张",
130
125
  "error.collection.fail": "❌ 收藏功能执行异常,请稍后再试!",
131
126
  "error.ranking.fail": "❌ 排名功能执行异常,请稍后再试!",
132
127
  // ==============================================
@@ -140,15 +135,6 @@ var zh_CN_default = {
140
135
  // ==============================================
141
136
  "image.warehouse.title": "{name} 的卡片仓库(带【限定】标记为限时卡)",
142
137
  "image.warehouse.empty": "你的仓库暂无任何卡片,快去抽卡吧!",
143
- "image.shop.title": "WWC每日商店({date})",
144
- "image.shop.userInfo": "玩家:{name}",
145
- "image.shop.asset": "热带扰动: {disturb} | 水汽:{vapor} | 剩余抽数:{draw}",
146
- "image.shop.exchangeCount": "今日普通兑换:{used}/{limit}抽(单次最多40)",
147
- "image.shop.header.card": "卡片信息",
148
- "image.shop.header.price": "升格价格",
149
- "image.shop.header.cmd": "兑换指令",
150
- "image.shop.footerTip": "每日刷新卡片,全服限购5次",
151
- "image.shop.cmdTemplate": "WWC升格 {cid}",
152
138
  "image.collection.title": "{showName} 的卡片收藏图鉴(含限定卡)",
153
139
  "image.collection.title1": "{showName} 的卡片收藏图鉴1(分类规则见配置项)",
154
140
  "image.collection.title2": "{showName} 的卡片收藏图鉴2(分类规则见配置项)",
@@ -205,6 +191,23 @@ async function getNextId(ctx, table) {
205
191
  return list.length ? list[0].id + 1 : 1;
206
192
  }
207
193
  __name(getNextId, "getNextId");
194
+ async function getShopRowsByDate(ctx, shopDate) {
195
+ const rows = await ctx.database.get("gacha_shop_daily", { shop_date: shopDate });
196
+ const merged = /* @__PURE__ */ new Map();
197
+ for (const row of rows) {
198
+ const key = String(row.card_id);
199
+ const exist = merged.get(key);
200
+ if (!exist) {
201
+ merged.set(key, { ...row });
202
+ continue;
203
+ }
204
+ if ((row.server_bought ?? 0) > (exist.server_bought ?? 0)) {
205
+ exist.server_bought = row.server_bought ?? 0;
206
+ }
207
+ }
208
+ return Array.from(merged.values());
209
+ }
210
+ __name(getShopRowsByDate, "getShopRowsByDate");
208
211
  function unescapeHtml(str) {
209
212
  if (!str || typeof str !== "string") return "";
210
213
  return str.replace(/&/gi, "&");
@@ -743,20 +746,6 @@ async function _do_sign(ctx, session, signResetHour, signResetMinute) {
743
746
  const SIGN_DRAW_COUNT = 40;
744
747
  const userAsset = await ctx.database.get("gacha_user_draw_count", { qq });
745
748
  const newDrawCount = (userAsset[0]?.draw_count ?? 0) + SIGN_DRAW_COUNT;
746
- let resetDate = new Date(now);
747
- resetDate.setHours(resetHour, resetMinute, 0, 0);
748
- if (now < resetDate) {
749
- resetDate.setDate(resetDate.getDate() - 1);
750
- }
751
- const resetDateStr = `${resetDate.getFullYear()}${String(resetDate.getMonth() + 1).padStart(2, "0")}${String(resetDate.getDate()).padStart(2, "0")}`;
752
- const allCards = await ctx.database.get("gacha_shop_limit", {});
753
- for (const card of allCards) {
754
- await ctx.database.upsert("gacha_shop_limit", [{
755
- card_id: card.card_id,
756
- left_limit: 5
757
- }]);
758
- }
759
- ctx.logger.info(`签到重置:所有店铺卡片限购次数已恢复为5次`);
760
749
  await ctx.database.upsert("gacha_user_draw_count", [{
761
750
  qq,
762
751
  draw_count: newDrawCount,
@@ -1027,7 +1016,7 @@ async function _do_upgrade(ctx, session, card_ids, signResetHour, signResetMinut
1027
1016
  let total_cost = 0;
1028
1017
  const shop_card_info = [];
1029
1018
  const [shopCards, cardPool] = await Promise.all([
1030
- ctx.database.get("gacha_shop_daily", { shop_date: today }),
1019
+ getShopRowsByDate(ctx, today),
1031
1020
  ctx.database.get("gacha_card_pool", {})
1032
1021
  ]);
1033
1022
  ctx.logger.info(`[升格] 当前店铺卡片:`, shopCards.map((s) => s.card_id));
@@ -1047,6 +1036,7 @@ async function _do_upgrade(ctx, session, card_ids, signResetHour, signResetMinut
1047
1036
  }
1048
1037
  for (let i = 0; i < num; i++) {
1049
1038
  shop_card_info.push({
1039
+ id: shopCard.id,
1050
1040
  card_id: shopCard.card_id,
1051
1041
  card_name: cardInfo.card_name,
1052
1042
  card_star: shopCard.card_star,
@@ -1089,14 +1079,17 @@ async function _do_upgrade(ctx, session, card_ids, signResetHour, signResetMinut
1089
1079
  if (d > 0) disturbance_total += d;
1090
1080
  }
1091
1081
  }
1092
- await ctx.database.upsert("gacha_shop_daily", [{
1082
+ const shopRow = {
1093
1083
  shop_date: today,
1094
1084
  card_id: card.card_id,
1095
1085
  card_star: card.card_star,
1096
1086
  price: card.price,
1097
1087
  server_limit: card.server_limit,
1098
1088
  server_bought: card.server_bought + 1
1099
- }]);
1089
+ };
1090
+ await ctx.database.upsert("gacha_shop_daily", [
1091
+ card.id != null ? { id: card.id, ...shopRow } : { ...shopRow }
1092
+ ]);
1100
1093
  }
1101
1094
  await ctx.database.upsert("gacha_user_draw_count", [{
1102
1095
  qq,
@@ -1300,7 +1293,7 @@ async function _do_shop(ctx, session, signResetHour, signResetMinute) {
1300
1293
  todayDate.setDate(todayDate.getDate() - 1);
1301
1294
  }
1302
1295
  const today = `${todayDate.getFullYear()}${String(todayDate.getMonth() + 1).padStart(2, "0")}${String(todayDate.getDate()).padStart(2, "0")}`;
1303
- let todayShop = await ctx.database.get("gacha_shop_daily", { shop_date: today });
1296
+ let todayShop = await getShopRowsByDate(ctx, today);
1304
1297
  if (todayShop.length === 0) {
1305
1298
  const [sevenStarCards, sixStarCards, fiveStarCards] = await Promise.all([
1306
1299
  ctx.database.get("gacha_card_pool", { card_star: 7 }),
@@ -1313,7 +1306,9 @@ async function _do_shop(ctx, session, signResetHour, signResetMinute) {
1313
1306
  const selected7 = sevenStarCards.sort(() => Math.random() - 0.5).slice(0, 4);
1314
1307
  const selected6 = sixStarCards.sort(() => Math.random() - 0.5).slice(0, 6);
1315
1308
  const selected5 = fiveStarCards.sort(() => Math.random() - 0.5).slice(0, 10);
1316
- const allCards = [...selected7, ...selected6, ...selected5];
1309
+ const allCards = Array.from(
1310
+ new Map([...selected7, ...selected6, ...selected5].map((c) => [String(c.card_id), c])).values()
1311
+ );
1317
1312
  const SHOP_PRICE_BASE = { 7: 800, 6: 200, 5: 20 };
1318
1313
  const SHOP_PRICE_RANGE = { 7: 80, 6: 30, 5: 0 };
1319
1314
  for (const card of allCards) {
@@ -1330,35 +1325,21 @@ async function _do_shop(ctx, session, signResetHour, signResetMinute) {
1330
1325
  server_bought: 0,
1331
1326
  server_limit: 5
1332
1327
  });
1333
- const exist = await ctx.database.get("gacha_shop_limit", { card_id: card.card_id });
1334
- if (!exist.length) {
1335
- await ctx.database.create("gacha_shop_limit", {
1336
- card_id: card.card_id,
1337
- total_limit: 5,
1338
- left_limit: 5
1339
- });
1340
- }
1341
1328
  }
1342
- todayShop = await ctx.database.get("gacha_shop_daily", { shop_date: today });
1329
+ todayShop = await getShopRowsByDate(ctx, today);
1343
1330
  }
1344
1331
  const pool = await ctx.database.get("gacha_card_pool", {});
1345
1332
  const poolMap = new Map(pool.map((p) => [p.card_id, p]));
1346
- const limitList = await ctx.database.get("gacha_shop_limit", {
1347
- card_id: { $in: todayShop.map((s) => s.card_id) }
1348
- });
1349
- const limitMap = /* @__PURE__ */ new Map();
1350
- todayShop.forEach((s) => {
1351
- const lim = limitList.find((x) => x.card_id === s.card_id);
1352
- limitMap.set(s.card_id, lim?.left_limit ?? 5);
1353
- });
1354
1333
  const shopCardList = todayShop.map((item) => {
1355
1334
  const card = poolMap.get(item.card_id);
1335
+ const limit = item.server_limit ?? 5;
1336
+ const bought = item.server_bought ?? 0;
1356
1337
  return {
1357
1338
  id: item.card_id,
1358
1339
  name: card?.card_name || "未知",
1359
1340
  star: item.card_star,
1360
1341
  price: item.price,
1361
- leftLimit: limitMap.get(item.card_id)
1342
+ leftLimit: Math.max(0, limit - bought)
1362
1343
  };
1363
1344
  });
1364
1345
  shopCardList.sort((a, b) => b.star - a.star || String(a.id).localeCompare(String(b.id)));
@@ -1724,6 +1705,11 @@ async function _do_event_draw(ctx, session, data, event6Threshold, event7Thresho
1724
1705
  hasGot: limitStar === 6 ? pityRecord[0].got6 || false : pityRecord[0].got7 || false
1725
1706
  };
1726
1707
  const threshold = limitStar === 6 ? event6Threshold : event7Threshold;
1708
+ if (!currentPity.hasGot && currentPity.pityCount >= threshold) {
1709
+ ctx.logger.warn(`[限时保底修复] ${showName}(${qq}) 卡池${code}:计数${currentPity.pityCount}≥阈值${threshold}却未标记已获得,按已触发硬保底修正`);
1710
+ currentPity.hasGot = true;
1711
+ currentPity.pityCount = 0;
1712
+ }
1727
1713
  await ctx.database.upsert("gacha_user_event_draw", [{ qq, [key]: have - count }]);
1728
1714
  ctx.logger.info(`[限时抽卡] ${showName}(${qq}) 扣除${count}次${limitStar}星限时抽数,剩余${have - count}次`);
1729
1715
  const normalCards = await ctx.database.get("gacha_card_pool", {});
@@ -1770,10 +1756,12 @@ async function _do_event_draw(ctx, session, data, event6Threshold, event7Thresho
1770
1756
  for (let i = 0; i < count; i++) {
1771
1757
  let drawCard;
1772
1758
  newPityCount++;
1773
- const isGuarantee = !currentPity.hasGot && newPityCount === threshold;
1759
+ const isGuarantee = !currentPity.hasGot && newPityCount >= threshold;
1774
1760
  if (isGuarantee) {
1775
1761
  drawCard = eventCard;
1776
- ctx.logger.info(`[限时累计保底触发] ${showName}(${qq}) 抽卡${code}期,累计${newPityCount}抽,保底获得${limitStar}星限时卡:${eventCard.card_name}`);
1762
+ currentPity.hasGot = true;
1763
+ newPityCount = 0;
1764
+ ctx.logger.info(`[限时累计保底触发] ${showName}(${qq}) 抽卡${code}期,累计${currentPity.pityCount + 1}抽,保底获得${limitStar}星限时卡:${eventCard.card_name}`);
1777
1765
  } else {
1778
1766
  const randIndex = Math.floor(Math.random() * probabilityPool.length);
1779
1767
  const selectedStar = probabilityPool[randIndex];
@@ -1895,7 +1883,7 @@ async function _do_event_draw(ctx, session, data, event6Threshold, event7Thresho
1895
1883
  info += session.text("tip.draw.vapor", { vapor: waterVaporTotal });
1896
1884
  info += session.text("tip.draw.disturb", { disturbanceTotal });
1897
1885
  if (!currentPity.hasGot) {
1898
- const remaining = threshold - newPityCount;
1886
+ const remaining = Math.max(0, threshold - newPityCount);
1899
1887
  info += session.text("tip.eventDraw.pityProgress", { star: limitStar, current: newPityCount, threshold, left: remaining });
1900
1888
  } else {
1901
1889
  info += session.text("tip.eventDraw.pityReset", { star: limitStar });
@@ -2157,11 +2145,6 @@ async function apply(ctx, config) {
2157
2145
  exchange_date: { type: "string" },
2158
2146
  exchange_count: { type: "integer" }
2159
2147
  }, { primary: ["qq", "exchange_date"] });
2160
- ctx.model.extend("gacha_shop_limit", {
2161
- card_id: { type: "string" },
2162
- total_limit: { type: "integer" },
2163
- left_limit: { type: "integer" }
2164
- }, { primary: ["card_id"] });
2165
2148
  ctx.model.extend("gacha_user_exchange", {
2166
2149
  qq: { type: "string" },
2167
2150
  create_at: { type: "integer" },
@@ -79,27 +79,13 @@ declare const _default: {
79
79
  "error.disturbDraw.count.notEnough": string;
80
80
  "error.switch.private": string;
81
81
  "error.switch.fail": string;
82
- "error.shop.no7starCard": string;
83
- "error.shop.fail": string;
84
82
  "error.shop.cardNotEnough": string;
85
- "error.shop.cardNotInShop": string;
86
- "error.shop.cardNotInPool": string;
87
- "error.shop.cardLimitExceed": string;
88
83
  "error.collection.fail": string;
89
84
  "error.ranking.fail": string;
90
85
  "draw.broadcast.title": string;
91
86
  "draw.broadcast.getCard": string;
92
87
  "image.warehouse.title": string;
93
88
  "image.warehouse.empty": string;
94
- "image.shop.title": string;
95
- "image.shop.userInfo": string;
96
- "image.shop.asset": string;
97
- "image.shop.exchangeCount": string;
98
- "image.shop.header.card": string;
99
- "image.shop.header.price": string;
100
- "image.shop.header.cmd": string;
101
- "image.shop.footerTip": string;
102
- "image.shop.cmdTemplate": string;
103
89
  "image.collection.title": string;
104
90
  "image.collection.title1": string;
105
91
  "image.collection.title2": 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.7",
4
+ "version": "0.3.9",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [