koishi-plugin-xxck-1 0.0.1
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 +9 -0
- package/lib/index.js +1089 -0
- package/package.json +30 -0
- package/readme.md +5 -0
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Context, Schema } from 'koishi';
|
|
2
|
+
export declare const name = "xxck-1";
|
|
3
|
+
export interface Config {
|
|
4
|
+
masterQQ: string;
|
|
5
|
+
signResetHour: number;
|
|
6
|
+
signResetMinute: number;
|
|
7
|
+
}
|
|
8
|
+
export declare const Config: Schema<Config>;
|
|
9
|
+
export declare function apply(ctx: Context, config: Config): Promise<void>;
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,1089 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name2 in all)
|
|
10
|
+
__defProp(target, name2, { get: all[name2], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var src_exports = {};
|
|
32
|
+
__export(src_exports, {
|
|
33
|
+
Config: () => Config,
|
|
34
|
+
apply: () => apply,
|
|
35
|
+
name: () => name
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(src_exports);
|
|
38
|
+
var import_koishi = require("koishi");
|
|
39
|
+
var import_fs = __toESM(require("fs"));
|
|
40
|
+
var import_path = __toESM(require("path"));
|
|
41
|
+
var import_sqlite3 = __toESM(require("sqlite3"));
|
|
42
|
+
var import_seedrandom = __toESM(require("seedrandom"));
|
|
43
|
+
var import_sqlite = require("sqlite");
|
|
44
|
+
var import_random = __toESM(require("random"));
|
|
45
|
+
var import_luxon = require("luxon");
|
|
46
|
+
var import_canvas = require("@napi-rs/canvas");
|
|
47
|
+
var name = "xxck-1";
|
|
48
|
+
var Config = import_koishi.Schema.object({
|
|
49
|
+
masterQQ: import_koishi.Schema.string().description("主人QQ号,拥有最高权限").required(),
|
|
50
|
+
signResetHour: import_koishi.Schema.number().description("签到重置小时").default(0),
|
|
51
|
+
signResetMinute: import_koishi.Schema.number().description("签到重置分钟").default(0)
|
|
52
|
+
});
|
|
53
|
+
var BASE_DIR = import_path.default.resolve(__dirname, "../data");
|
|
54
|
+
if (!import_fs.default.existsSync(BASE_DIR)) import_fs.default.mkdirSync(BASE_DIR, { recursive: true });
|
|
55
|
+
var DB_PATH = import_path.default.join(BASE_DIR, "tian_gacha.db");
|
|
56
|
+
var INVENTORY_IMG_PATH = import_path.default.join(BASE_DIR, "tian_inventory_temp.png");
|
|
57
|
+
var COLLECTION_IMG_PATH = import_path.default.join(BASE_DIR, "tian_collection_temp.png");
|
|
58
|
+
var HELP_IMG_PATH = import_path.default.join(BASE_DIR, "tian_help_temp.png");
|
|
59
|
+
var GACHA_STAR_PROB = {
|
|
60
|
+
0: 30,
|
|
61
|
+
1: 25,
|
|
62
|
+
2: 20,
|
|
63
|
+
3: 15,
|
|
64
|
+
4: 7.5,
|
|
65
|
+
5: 2,
|
|
66
|
+
6: 0.4,
|
|
67
|
+
7: 0.1
|
|
68
|
+
};
|
|
69
|
+
var STAR_TO_DISTURBANCE = {
|
|
70
|
+
0: 0,
|
|
71
|
+
1: 0,
|
|
72
|
+
2: 0,
|
|
73
|
+
3: 1,
|
|
74
|
+
4: 5,
|
|
75
|
+
5: 20,
|
|
76
|
+
6: 100,
|
|
77
|
+
7: 500
|
|
78
|
+
};
|
|
79
|
+
var INIT_WATER_VAPOR = {
|
|
80
|
+
0: 50,
|
|
81
|
+
1: 100,
|
|
82
|
+
2: 150,
|
|
83
|
+
3: 200,
|
|
84
|
+
4: 500,
|
|
85
|
+
5: 1e3,
|
|
86
|
+
6: 2e3,
|
|
87
|
+
7: 5e3
|
|
88
|
+
};
|
|
89
|
+
var UPGRADE_WATER_VAPOR = {
|
|
90
|
+
0: 25,
|
|
91
|
+
1: 50,
|
|
92
|
+
2: 75,
|
|
93
|
+
3: 100,
|
|
94
|
+
4: 200,
|
|
95
|
+
5: 500,
|
|
96
|
+
6: 1e3,
|
|
97
|
+
7: 2e3
|
|
98
|
+
};
|
|
99
|
+
var CARD_LEVEL_MAX = 5;
|
|
100
|
+
var SHOP_CONFIG = {
|
|
101
|
+
"7star_count": 4,
|
|
102
|
+
"6star_count": 8,
|
|
103
|
+
"7star_price_range": [800, 810],
|
|
104
|
+
"6star_price_range": [205, 215],
|
|
105
|
+
"exchange_ratio": 100,
|
|
106
|
+
"daily_exchange_limit": 80,
|
|
107
|
+
"server_buy_limit": 20
|
|
108
|
+
};
|
|
109
|
+
var GUARANTEE_CONFIG = {
|
|
110
|
+
"6star_threshold": 300,
|
|
111
|
+
"7star_threshold": 1500,
|
|
112
|
+
"guarantee_6star_prob": 95,
|
|
113
|
+
"guarantee_7star_prob": 5
|
|
114
|
+
};
|
|
115
|
+
var DATE_FORMAT = "yyyyMMdd";
|
|
116
|
+
function get_star_symbol(star) {
|
|
117
|
+
star = Math.max(0, Math.min(7, parseInt(star.toString())));
|
|
118
|
+
return "★".repeat(star) + "☆".repeat(7 - star);
|
|
119
|
+
}
|
|
120
|
+
__name(get_star_symbol, "get_star_symbol");
|
|
121
|
+
function build_msg(session, content) {
|
|
122
|
+
return session.channelId?.startsWith("private") === false ? `[CQ:at,qq=${session.userId}] ${content}` : content;
|
|
123
|
+
}
|
|
124
|
+
__name(build_msg, "build_msg");
|
|
125
|
+
function getToday() {
|
|
126
|
+
return import_luxon.DateTime.now().format(DATE_FORMAT);
|
|
127
|
+
}
|
|
128
|
+
__name(getToday, "getToday");
|
|
129
|
+
async function initDB() {
|
|
130
|
+
const db = await (0, import_sqlite.open)({
|
|
131
|
+
filename: DB_PATH,
|
|
132
|
+
driver: import_sqlite3.default.Database,
|
|
133
|
+
mode: import_sqlite3.default.OPEN_READWRITE | import_sqlite3.default.OPEN_CREATE
|
|
134
|
+
});
|
|
135
|
+
await db.exec(`
|
|
136
|
+
CREATE TABLE IF NOT EXISTS gacha_user (
|
|
137
|
+
qq TEXT PRIMARY KEY,
|
|
138
|
+
nickname TEXT NOT NULL,
|
|
139
|
+
status INTEGER NOT NULL DEFAULT 0,
|
|
140
|
+
protect INTEGER NOT NULL DEFAULT 0
|
|
141
|
+
)`);
|
|
142
|
+
await db.exec(`
|
|
143
|
+
CREATE TABLE IF NOT EXISTS gacha_global_switch (
|
|
144
|
+
id INTEGER PRIMARY KEY DEFAULT 1,
|
|
145
|
+
status INTEGER NOT NULL DEFAULT 1
|
|
146
|
+
)`);
|
|
147
|
+
await db.run("INSERT OR IGNORE INTO gacha_global_switch (id, status) VALUES (1, 1)");
|
|
148
|
+
await db.exec(`
|
|
149
|
+
CREATE TABLE IF NOT EXISTS gacha_group_switch (
|
|
150
|
+
group_id TEXT PRIMARY KEY,
|
|
151
|
+
status INTEGER NOT NULL DEFAULT 0
|
|
152
|
+
)`);
|
|
153
|
+
await db.exec(`
|
|
154
|
+
CREATE TABLE IF NOT EXISTS gacha_sign_config (
|
|
155
|
+
id INTEGER PRIMARY KEY DEFAULT 1,
|
|
156
|
+
reset_hour INTEGER NOT NULL DEFAULT 0,
|
|
157
|
+
reset_minute INTEGER NOT NULL DEFAULT 0
|
|
158
|
+
)`);
|
|
159
|
+
await db.exec(`
|
|
160
|
+
CREATE TABLE IF NOT EXISTS gacha_card_pool (
|
|
161
|
+
card_id TEXT PRIMARY KEY,
|
|
162
|
+
card_name TEXT NOT NULL,
|
|
163
|
+
card_star INTEGER NOT NULL,
|
|
164
|
+
category TEXT NOT NULL
|
|
165
|
+
)`);
|
|
166
|
+
await db.exec(`
|
|
167
|
+
CREATE TABLE IF NOT EXISTS gacha_user_draw_count (
|
|
168
|
+
qq TEXT PRIMARY KEY,
|
|
169
|
+
draw_count INTEGER NOT NULL DEFAULT 0,
|
|
170
|
+
tropical_disturbance INTEGER NOT NULL DEFAULT 0,
|
|
171
|
+
water_vapor INTEGER NOT NULL DEFAULT 0,
|
|
172
|
+
no_6star_draws INTEGER NOT NULL DEFAULT 0,
|
|
173
|
+
no_7star_draws INTEGER NOT NULL DEFAULT 0,
|
|
174
|
+
FOREIGN KEY (qq) REFERENCES gacha_user (qq)
|
|
175
|
+
)`);
|
|
176
|
+
await db.exec(`
|
|
177
|
+
CREATE TABLE IF NOT EXISTS gacha_user_sign (
|
|
178
|
+
qq TEXT PRIMARY KEY,
|
|
179
|
+
last_sign_time TEXT NOT NULL DEFAULT "",
|
|
180
|
+
FOREIGN KEY (qq) REFERENCES gacha_user (qq)
|
|
181
|
+
)`);
|
|
182
|
+
await db.exec(`
|
|
183
|
+
CREATE TABLE IF NOT EXISTS gacha_user_card (
|
|
184
|
+
qq TEXT NOT NULL,
|
|
185
|
+
card_id TEXT NOT NULL,
|
|
186
|
+
card_level INTEGER NOT NULL DEFAULT 0,
|
|
187
|
+
PRIMARY KEY (qq, card_id),
|
|
188
|
+
FOREIGN KEY (qq) REFERENCES gacha_user (qq),
|
|
189
|
+
FOREIGN KEY (card_id) REFERENCES gacha_card_pool (card_id)
|
|
190
|
+
)`);
|
|
191
|
+
await db.exec(`
|
|
192
|
+
CREATE TABLE IF NOT EXISTS gacha_shop_daily (
|
|
193
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
194
|
+
shop_date TEXT NOT NULL,
|
|
195
|
+
card_id TEXT NOT NULL,
|
|
196
|
+
card_star INTEGER NOT NULL,
|
|
197
|
+
price INTEGER NOT NULL,
|
|
198
|
+
server_bought INTEGER NOT NULL DEFAULT 0,
|
|
199
|
+
server_limit INTEGER NOT NULL DEFAULT 20,
|
|
200
|
+
FOREIGN KEY (card_id) REFERENCES gacha_card_pool (card_id)
|
|
201
|
+
)`);
|
|
202
|
+
await db.exec("CREATE UNIQUE INDEX IF NOT EXISTS idx_shop_date_card ON gacha_shop_daily (shop_date, card_id)");
|
|
203
|
+
await db.exec(`
|
|
204
|
+
CREATE TABLE IF NOT EXISTS gacha_shop_exchange (
|
|
205
|
+
qq TEXT NOT NULL,
|
|
206
|
+
exchange_date TEXT NOT NULL,
|
|
207
|
+
exchange_count INTEGER NOT NULL DEFAULT 0,
|
|
208
|
+
PRIMARY KEY (qq, exchange_date),
|
|
209
|
+
FOREIGN KEY (qq) REFERENCES gacha_user (qq)
|
|
210
|
+
)`);
|
|
211
|
+
console.log("✅ 习习抽卡系统数据库初始化完成!");
|
|
212
|
+
return db;
|
|
213
|
+
}
|
|
214
|
+
__name(initDB, "initDB");
|
|
215
|
+
async function _warehouse_draw_image(user_cards, show_name) {
|
|
216
|
+
try {
|
|
217
|
+
const STAR_COLOR = {
|
|
218
|
+
7: "#FF00FF",
|
|
219
|
+
6: "#C00000",
|
|
220
|
+
5: "#FF0000",
|
|
221
|
+
4: "#ED7D31",
|
|
222
|
+
3: "#F7B309",
|
|
223
|
+
2: "#C4D44C",
|
|
224
|
+
1: "#56CA85",
|
|
225
|
+
0: "#33CAFD"
|
|
226
|
+
};
|
|
227
|
+
const COL_NUM = 60;
|
|
228
|
+
const total_cards = user_cards.length;
|
|
229
|
+
const col_count = Math.ceil(total_cards / COL_NUM);
|
|
230
|
+
const bg_color = [255, 255, 255];
|
|
231
|
+
const col_width = 320, col_gap = 10, row_height = 26, title_height = 60, padding = 15;
|
|
232
|
+
const img_width = padding + col_count * (col_width + col_gap) - col_gap;
|
|
233
|
+
const max_rows = Math.max(60, total_cards % COL_NUM || COL_NUM);
|
|
234
|
+
const img_height = title_height + max_rows * row_height + padding;
|
|
235
|
+
const canvas = (0, import_canvas.createCanvas)(img_width, img_height);
|
|
236
|
+
const ctx = canvas.getContext("2d");
|
|
237
|
+
ctx.fillStyle = `rgb(${bg_color.join(",")})`;
|
|
238
|
+
ctx.fillRect(0, 0, img_width, img_height);
|
|
239
|
+
ctx.font = "20px SimHei";
|
|
240
|
+
ctx.fillStyle = "#000000";
|
|
241
|
+
ctx.fillText(`用户:${show_name}`, padding, padding + 20);
|
|
242
|
+
if (!total_cards) {
|
|
243
|
+
ctx.fillText("暂无卡片", padding, title_height + padding);
|
|
244
|
+
} else {
|
|
245
|
+
user_cards.forEach((card, idx) => {
|
|
246
|
+
const [card_level, card_id, card_name, card_star] = card;
|
|
247
|
+
const col = Math.floor(idx / COL_NUM);
|
|
248
|
+
const row = idx % COL_NUM;
|
|
249
|
+
const x = padding + col * (col_width + col_gap);
|
|
250
|
+
const y = title_height + row * row_height;
|
|
251
|
+
const star_symbol = get_star_symbol(card_star);
|
|
252
|
+
const card_text = `[${card_level}] ${card_id} ${card_name} ${star_symbol}`;
|
|
253
|
+
ctx.fillStyle = STAR_COLOR[card_star];
|
|
254
|
+
ctx.fillText(card_text, x, y + 18);
|
|
255
|
+
ctx.fillStyle = "#000000";
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
const buffer = canvas.toBuffer("image/png");
|
|
259
|
+
return `base64://${buffer.toString("base64")}`;
|
|
260
|
+
} catch (e) {
|
|
261
|
+
console.error("仓库图片绘制失败:", e);
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
__name(_warehouse_draw_image, "_warehouse_draw_image");
|
|
266
|
+
async function _shop_draw_image(shop_cards, user_disturbance, user_water_vapor, user_exchange_count, daily_exchange_limit, user_show_name, today) {
|
|
267
|
+
try {
|
|
268
|
+
const STAR_COLOR = {
|
|
269
|
+
7: "#FF00FF",
|
|
270
|
+
6: "#C00000",
|
|
271
|
+
5: "#FF0000",
|
|
272
|
+
4: "#ED7D31",
|
|
273
|
+
3: "#F7B309",
|
|
274
|
+
2: "#C4D44C",
|
|
275
|
+
1: "#56CA85",
|
|
276
|
+
0: "#33CAFD"
|
|
277
|
+
};
|
|
278
|
+
const unified_font_size = 20, unified_line_height = 30;
|
|
279
|
+
const exchange_ratio = SHOP_CONFIG.exchange_ratio;
|
|
280
|
+
const bg_color = [255, 255, 255], padding = 20, img_width = 500;
|
|
281
|
+
const title_height = 60, nickname_height = 40, footer_height = 40;
|
|
282
|
+
const card_count = shop_cards.length;
|
|
283
|
+
const card_module_height = card_count * (unified_line_height * 2);
|
|
284
|
+
const asset_module_height = unified_line_height, empty_line_height = unified_line_height;
|
|
285
|
+
const exchange_module_height = unified_line_height * 2, vapor_line_height = unified_line_height;
|
|
286
|
+
const total_height = title_height + nickname_height + card_module_height + asset_module_height + empty_line_height + exchange_module_height + vapor_line_height + footer_height + padding * 2;
|
|
287
|
+
const canvas = (0, import_canvas.createCanvas)(img_width, total_height);
|
|
288
|
+
const ctx = canvas.getContext("2d");
|
|
289
|
+
ctx.fillStyle = `rgb(${bg_color.join(",")})`;
|
|
290
|
+
ctx.fillRect(0, 0, img_width, total_height);
|
|
291
|
+
ctx.font = "36px SimHei";
|
|
292
|
+
ctx.fillStyle = "#FF0000";
|
|
293
|
+
const title_text = "今日店铺";
|
|
294
|
+
const title_width = ctx.measureText(title_text).width;
|
|
295
|
+
ctx.fillText(title_text, (img_width - title_width) / 2, padding + 36);
|
|
296
|
+
ctx.font = "22px SimHei";
|
|
297
|
+
ctx.fillStyle = "#000000";
|
|
298
|
+
ctx.fillText(user_show_name, padding, padding + title_height + 22);
|
|
299
|
+
ctx.font = `${unified_font_size}px SimHei`;
|
|
300
|
+
shop_cards.forEach((card, idx) => {
|
|
301
|
+
const [cid, cname, cstar, price, server_bought, server_limit] = card;
|
|
302
|
+
const star_symbol = get_star_symbol(cstar);
|
|
303
|
+
const card_main_text = `${cid} ${cname} ${star_symbol}.........${price}`;
|
|
304
|
+
const card_sub_text = `全服购买上限:${server_bought}/${server_limit}`;
|
|
305
|
+
const main_y = padding + title_height + nickname_height + idx * (unified_line_height * 2);
|
|
306
|
+
const sub_y = main_y + unified_line_height;
|
|
307
|
+
ctx.fillStyle = STAR_COLOR[cstar];
|
|
308
|
+
ctx.fillText(card_main_text, padding, main_y + 20);
|
|
309
|
+
ctx.fillStyle = "#808080";
|
|
310
|
+
ctx.fillText(card_sub_text, padding, sub_y + 20);
|
|
311
|
+
});
|
|
312
|
+
ctx.fillStyle = "#000000";
|
|
313
|
+
const disturbance_text = `热带扰动当前拥有:${user_disturbance}`;
|
|
314
|
+
const disturbance_width = ctx.measureText(disturbance_text).width;
|
|
315
|
+
ctx.fillText(
|
|
316
|
+
disturbance_text,
|
|
317
|
+
img_width - padding - disturbance_width,
|
|
318
|
+
padding + title_height + nickname_height + card_module_height + 20
|
|
319
|
+
);
|
|
320
|
+
ctx.fillStyle = "#C8C8C8";
|
|
321
|
+
ctx.fillText(
|
|
322
|
+
"-".repeat(42),
|
|
323
|
+
padding,
|
|
324
|
+
padding + title_height + nickname_height + card_module_height + asset_module_height + 20
|
|
325
|
+
);
|
|
326
|
+
ctx.fillStyle = "#000000";
|
|
327
|
+
const rule_text = `${exchange_ratio}水汽 = 1次抽卡`;
|
|
328
|
+
ctx.fillText(
|
|
329
|
+
rule_text,
|
|
330
|
+
padding,
|
|
331
|
+
padding + title_height + nickname_height + card_module_height + asset_module_height + empty_line_height + 20
|
|
332
|
+
);
|
|
333
|
+
ctx.fillStyle = "#808080";
|
|
334
|
+
const used_text = `今日已兑换:${user_exchange_count}/${daily_exchange_limit}`;
|
|
335
|
+
ctx.fillText(
|
|
336
|
+
used_text,
|
|
337
|
+
padding,
|
|
338
|
+
padding + title_height + nickname_height + card_module_height + asset_module_height + empty_line_height + unified_line_height + 20
|
|
339
|
+
);
|
|
340
|
+
ctx.fillStyle = "#000000";
|
|
341
|
+
const vapor_text = `水汽当前拥有:${user_water_vapor}`;
|
|
342
|
+
const vapor_width = ctx.measureText(vapor_text).width;
|
|
343
|
+
ctx.fillText(
|
|
344
|
+
vapor_text,
|
|
345
|
+
img_width - padding - vapor_width,
|
|
346
|
+
padding + title_height + nickname_height + card_module_height + asset_module_height + empty_line_height + exchange_module_height + 20
|
|
347
|
+
);
|
|
348
|
+
ctx.font = "18px SimHei";
|
|
349
|
+
ctx.fillStyle = "#646464";
|
|
350
|
+
const footer_width = ctx.measureText(today).width;
|
|
351
|
+
ctx.fillText(today, (img_width - footer_width) / 2, total_height - padding - 20);
|
|
352
|
+
const buffer = canvas.toBuffer("image/png");
|
|
353
|
+
return `base64://${buffer.toString("base64")}`;
|
|
354
|
+
} catch (e) {
|
|
355
|
+
console.error("店铺图片绘制失败:", e);
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
__name(_shop_draw_image, "_shop_draw_image");
|
|
360
|
+
async function _collection_draw_image(show_name, total_collected, total_all, category_progress, category_cards) {
|
|
361
|
+
try {
|
|
362
|
+
const STAR_COLOR = {
|
|
363
|
+
7: "#FF00FF",
|
|
364
|
+
6: "#C00000",
|
|
365
|
+
5: "#FF0000",
|
|
366
|
+
4: "#ED7D31",
|
|
367
|
+
3: "#F7B309",
|
|
368
|
+
2: "#C4D44C",
|
|
369
|
+
1: "#56CA85",
|
|
370
|
+
0: "#33CAFD"
|
|
371
|
+
};
|
|
372
|
+
const items_per_line = 10, item_width = 90, line_height = 28, padding = 18, img_width = 936;
|
|
373
|
+
let total_height = padding * 2 + line_height * 2;
|
|
374
|
+
for (const key in category_progress) {
|
|
375
|
+
const [_, total_num] = category_progress[key];
|
|
376
|
+
const category_lines = Math.ceil(total_num / items_per_line);
|
|
377
|
+
total_height += line_height * (2 + category_lines);
|
|
378
|
+
}
|
|
379
|
+
total_height += line_height * 2;
|
|
380
|
+
const canvas = (0, import_canvas.createCanvas)(img_width, total_height);
|
|
381
|
+
const ctx = canvas.getContext("2d");
|
|
382
|
+
ctx.fillStyle = "#FFFFFF";
|
|
383
|
+
ctx.fillRect(0, 0, img_width, total_height);
|
|
384
|
+
let y_offset = padding;
|
|
385
|
+
ctx.font = "18px SimHei";
|
|
386
|
+
ctx.fillStyle = "#000000";
|
|
387
|
+
const main_title = `${show_name} 的收藏进度`;
|
|
388
|
+
const main_title_width = ctx.measureText(main_title).width;
|
|
389
|
+
ctx.fillText(main_title, (img_width - main_title_width) / 2, y_offset + 18);
|
|
390
|
+
y_offset += line_height;
|
|
391
|
+
ctx.fillStyle = "#FF0000";
|
|
392
|
+
const total_progress = `总进度:${total_collected}/${total_all}(${(total_collected / total_all * 100).toFixed(1)}%)`;
|
|
393
|
+
const total_progress_width = ctx.measureText(total_progress).width;
|
|
394
|
+
ctx.fillText(total_progress, (img_width - total_progress_width) / 2, y_offset + 18);
|
|
395
|
+
ctx.font = "16px SimHei";
|
|
396
|
+
for (const category in category_progress) {
|
|
397
|
+
const [collected_num, total_num, card_star_map] = category_progress[category];
|
|
398
|
+
y_offset += line_height;
|
|
399
|
+
ctx.fillStyle = "#000000";
|
|
400
|
+
ctx.fillText(`【${category}】`, padding, y_offset + 16);
|
|
401
|
+
y_offset += line_height;
|
|
402
|
+
ctx.fillStyle = "#808080";
|
|
403
|
+
ctx.fillText(`收藏进度:${collected_num}/${total_num}(${(collected_num / total_num * 100).toFixed(1)}%)`, padding, y_offset + 16);
|
|
404
|
+
const cid_list = category_cards[category].sort();
|
|
405
|
+
cid_list.forEach((cid, idx) => {
|
|
406
|
+
const line_idx = Math.floor(idx / items_per_line);
|
|
407
|
+
const col_idx = idx % items_per_line;
|
|
408
|
+
const x = padding + col_idx * item_width;
|
|
409
|
+
const y = y_offset + (line_idx + 1) * line_height;
|
|
410
|
+
if (card_star_map[cid]) {
|
|
411
|
+
const { name: name2, star } = card_star_map[cid];
|
|
412
|
+
ctx.fillStyle = STAR_COLOR[star];
|
|
413
|
+
ctx.fillText(name2, x, y + 16);
|
|
414
|
+
} else {
|
|
415
|
+
ctx.fillStyle = "#808080";
|
|
416
|
+
ctx.fillText("?", x, y + 16);
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
y_offset += Math.ceil(total_num / items_per_line) * line_height;
|
|
420
|
+
}
|
|
421
|
+
const buffer = canvas.toBuffer("image/png");
|
|
422
|
+
return `base64://${buffer.toString("base64")}`;
|
|
423
|
+
} catch (e) {
|
|
424
|
+
console.error("收藏图片绘制失败:", e);
|
|
425
|
+
return null;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
__name(_collection_draw_image, "_collection_draw_image");
|
|
429
|
+
async function _ranking_draw_image(ranking_list, user_rank, user_collected, show_name) {
|
|
430
|
+
try {
|
|
431
|
+
const bg_color = [255, 255, 255], img_width = 580, line_height = 36;
|
|
432
|
+
const title_line_height = 48, padding = 20, fixed_value_x = 520;
|
|
433
|
+
const rank_count = ranking_list.length;
|
|
434
|
+
const extra_line = user_rank > 20 ? line_height : 0;
|
|
435
|
+
const total_height = padding * 2 + title_line_height + line_height + rank_count * line_height + extra_line;
|
|
436
|
+
const canvas = (0, import_canvas.createCanvas)(img_width, total_height);
|
|
437
|
+
const ctx = canvas.getContext("2d");
|
|
438
|
+
ctx.fillStyle = `rgb(${bg_color.join(",")})`;
|
|
439
|
+
ctx.fillRect(0, 0, img_width, total_height);
|
|
440
|
+
let y_offset = padding;
|
|
441
|
+
ctx.font = "30px SimHei";
|
|
442
|
+
ctx.fillStyle = "#000000";
|
|
443
|
+
const title = "WWC收藏总数排行";
|
|
444
|
+
const title_width = ctx.measureText(title).width;
|
|
445
|
+
ctx.fillText(title, (img_width - title_width) / 2, y_offset + 30);
|
|
446
|
+
y_offset += title_line_height;
|
|
447
|
+
ctx.font = "28px SimHei";
|
|
448
|
+
const time = import_luxon.DateTime.now().format("yyyy-MM-dd HH:mm:ss");
|
|
449
|
+
ctx.fillText(`查询时间:${time}`, padding, y_offset + 28);
|
|
450
|
+
y_offset += line_height;
|
|
451
|
+
ranking_list.forEach(([rank, nickname, collected_num], idx) => {
|
|
452
|
+
const current_y = y_offset + idx * line_height;
|
|
453
|
+
const is_user = rank === user_rank && nickname === show_name;
|
|
454
|
+
ctx.fillStyle = is_user ? "#FF00FF" : "#000000";
|
|
455
|
+
const left_text = `${rank.toString().padStart(2, " ")} ${nickname}`;
|
|
456
|
+
ctx.fillText(left_text, padding, current_y + 28);
|
|
457
|
+
const right_text = collected_num.toString();
|
|
458
|
+
const right_width = ctx.measureText(right_text).width;
|
|
459
|
+
ctx.fillText(right_text, fixed_value_x - right_width, current_y + 28);
|
|
460
|
+
});
|
|
461
|
+
if (user_rank > 20) {
|
|
462
|
+
const current_y = y_offset + rank_count * line_height;
|
|
463
|
+
ctx.fillStyle = "#FF00FF";
|
|
464
|
+
const left_text = `${user_rank.toString().padStart(2, " ")} ${show_name}`;
|
|
465
|
+
ctx.fillText(left_text, padding, current_y + 28);
|
|
466
|
+
const right_text = user_collected.toString();
|
|
467
|
+
const right_width = ctx.measureText(right_text).width;
|
|
468
|
+
ctx.fillText(right_text, fixed_value_x - right_width, current_y + 28);
|
|
469
|
+
}
|
|
470
|
+
const buffer = canvas.toBuffer("image/png");
|
|
471
|
+
return `base64://${buffer.toString("base64")}`;
|
|
472
|
+
} catch (e) {
|
|
473
|
+
console.error("排行图片绘制失败:", e);
|
|
474
|
+
return null;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
__name(_ranking_draw_image, "_ranking_draw_image");
|
|
478
|
+
async function _do_register(session, db, nickname, masterQQ) {
|
|
479
|
+
const qq = session.userId;
|
|
480
|
+
const exist = await db.get("SELECT qq FROM gacha_user WHERE qq=?", [qq]);
|
|
481
|
+
if (!exist) {
|
|
482
|
+
await db.run("INSERT INTO gacha_user (qq,nickname,status) VALUES (?,?,0)", [qq, nickname]);
|
|
483
|
+
await session.send(build_msg(session, "✅ 注册成功!昵称等待审核。"));
|
|
484
|
+
} else {
|
|
485
|
+
await db.run("UPDATE gacha_user SET nickname=?,status=0 WHERE qq=?", [nickname, qq]);
|
|
486
|
+
await session.send(build_msg(session, "✅ 昵称修改请求已提交!请等待审核。"));
|
|
487
|
+
}
|
|
488
|
+
await session.bot.sendPrivateMessage(masterQQ, `收到WWC昵称审核请求!
|
|
489
|
+
用户ID:${qq}
|
|
490
|
+
昵称:${nickname}`);
|
|
491
|
+
}
|
|
492
|
+
__name(_do_register, "_do_register");
|
|
493
|
+
async function _do_check(session, db, check_qq, masterQQ) {
|
|
494
|
+
if (session.userId !== masterQQ) {
|
|
495
|
+
return await session.send(build_msg(session, "❌ 无权限!审核仅主人可用!"));
|
|
496
|
+
}
|
|
497
|
+
const exist = await db.get("SELECT qq FROM gacha_user WHERE qq=?", [check_qq]);
|
|
498
|
+
if (!exist) {
|
|
499
|
+
return await session.send(build_msg(session, "❌ 该用户未注册!"));
|
|
500
|
+
}
|
|
501
|
+
await db.run("UPDATE gacha_user SET status=1 WHERE qq=?", [check_qq]);
|
|
502
|
+
await session.send(build_msg(session, "✅ 审核完成!"));
|
|
503
|
+
}
|
|
504
|
+
__name(_do_check, "_do_check");
|
|
505
|
+
async function _do_sign(session, db, resetHour, resetMinute) {
|
|
506
|
+
const qq = session.userId;
|
|
507
|
+
const user = await db.get("SELECT qq FROM gacha_user WHERE qq=?", [qq]);
|
|
508
|
+
if (!user) return await session.send(build_msg(session, "❌ 请先完成注册后再签到!"));
|
|
509
|
+
const now = import_luxon.DateTime.now();
|
|
510
|
+
const reset_time_today = now.set({ hour: resetHour, minute: resetMinute, second: 0, millisecond: 0 });
|
|
511
|
+
const reset_time = now < reset_time_today ? reset_time_today.minus({ days: 1 }) : reset_time_today;
|
|
512
|
+
const last_sign = await db.get("SELECT last_sign_time FROM gacha_user_sign WHERE qq=?", [qq]);
|
|
513
|
+
let can_sign = true;
|
|
514
|
+
if (last_sign?.last_sign_time) {
|
|
515
|
+
const last_sign_time = import_luxon.DateTime.fromFormat(last_sign.last_sign_time, "yyyy-MM-dd HH:mm:ss");
|
|
516
|
+
can_sign = last_sign_time < reset_time;
|
|
517
|
+
}
|
|
518
|
+
if (!can_sign) return await session.send(build_msg(session, "❌当前时段已签到,请等待重置!"));
|
|
519
|
+
const now_str = now.format("yyyy-MM-dd HH:mm:ss");
|
|
520
|
+
if (last_sign) {
|
|
521
|
+
await db.run("UPDATE gacha_user_sign SET last_sign_time=? WHERE qq=?", [now_str, qq]);
|
|
522
|
+
} else {
|
|
523
|
+
await db.run("INSERT INTO gacha_user_sign (qq, last_sign_time) VALUES (?, ?)", [qq, now_str]);
|
|
524
|
+
}
|
|
525
|
+
const user_count = await db.get("SELECT draw_count FROM gacha_user_draw_count WHERE qq=?", [qq]);
|
|
526
|
+
if (user_count) {
|
|
527
|
+
await db.run("UPDATE gacha_user_draw_count SET draw_count=? WHERE qq=?", [user_count.draw_count + 40, qq]);
|
|
528
|
+
} else {
|
|
529
|
+
await db.run("INSERT INTO gacha_user_draw_count (qq, draw_count) VALUES (?, 40)", [qq]);
|
|
530
|
+
}
|
|
531
|
+
await session.send(build_msg(session, "✅签到成功!获得抽卡次数*40"));
|
|
532
|
+
}
|
|
533
|
+
__name(_do_sign, "_do_sign");
|
|
534
|
+
async function _do_add_card(session, db, card_lines, masterQQ) {
|
|
535
|
+
if (session.userId !== masterQQ) {
|
|
536
|
+
return await session.send(build_msg(session, "❌ 无权限!卡片录入仅主人可用!"));
|
|
537
|
+
}
|
|
538
|
+
let success = 0, repeat = 0, error = 0;
|
|
539
|
+
for (const line of card_lines) {
|
|
540
|
+
const info = line.split(/\s+/);
|
|
541
|
+
if (info.length !== 4) {
|
|
542
|
+
error++;
|
|
543
|
+
continue;
|
|
544
|
+
}
|
|
545
|
+
const [card_id, card_name, card_star_str, category] = info;
|
|
546
|
+
const card_star = parseInt(card_star_str);
|
|
547
|
+
if (isNaN(card_star)) {
|
|
548
|
+
error++;
|
|
549
|
+
continue;
|
|
550
|
+
}
|
|
551
|
+
const exist = await db.get("SELECT card_id FROM gacha_card_pool WHERE card_id=?", [card_id]);
|
|
552
|
+
if (exist) {
|
|
553
|
+
repeat++;
|
|
554
|
+
continue;
|
|
555
|
+
}
|
|
556
|
+
await db.run(
|
|
557
|
+
"INSERT INTO gacha_card_pool (card_id, card_name, card_star, category) VALUES (?, ?, ?, ?)",
|
|
558
|
+
[card_id, card_name, card_star, category]
|
|
559
|
+
);
|
|
560
|
+
success++;
|
|
561
|
+
}
|
|
562
|
+
await session.send(build_msg(
|
|
563
|
+
session,
|
|
564
|
+
`✅ 卡片信息录入完成!
|
|
565
|
+
成功:${success} 条
|
|
566
|
+
重复:${repeat} 条
|
|
567
|
+
错误:${error} 条`
|
|
568
|
+
));
|
|
569
|
+
}
|
|
570
|
+
__name(_do_add_card, "_do_add_card");
|
|
571
|
+
async function _do_draw(session, db, draw_times) {
|
|
572
|
+
const qq = session.userId;
|
|
573
|
+
const user = await db.get("SELECT qq FROM gacha_user WHERE qq=?", [qq]);
|
|
574
|
+
if (!user) return await session.send(build_msg(session, "❌ 请先完成注册后再抽卡!"));
|
|
575
|
+
if (!Number.isInteger(draw_times) || draw_times < 1 || draw_times > 40) {
|
|
576
|
+
return await session.send(build_msg(session, "❌ 抽卡次数参数错误!请输入1-40之间的正整数!"));
|
|
577
|
+
}
|
|
578
|
+
const user_count = await db.get(`
|
|
579
|
+
SELECT draw_count, tropical_disturbance, water_vapor, no_6star_draws, no_7star_draws
|
|
580
|
+
FROM gacha_user_draw_count WHERE qq=?`, [qq]);
|
|
581
|
+
const have_draw = user_count?.draw_count || 0;
|
|
582
|
+
if (have_draw < draw_times) {
|
|
583
|
+
return await session.send(build_msg(session, `❌ 抽卡次数不足!当前剩余:${have_draw} 次,需要:${draw_times} 次`));
|
|
584
|
+
}
|
|
585
|
+
const card_total = await db.get("SELECT COUNT(*) as cnt FROM gacha_card_pool");
|
|
586
|
+
if (card_total.cnt === 0) {
|
|
587
|
+
return await session.send(build_msg(session, "❌ 卡池暂无卡片!请先录入卡片后再抽卡!"));
|
|
588
|
+
}
|
|
589
|
+
const all_cards = await db.all("SELECT card_id, card_name, card_star FROM gacha_card_pool");
|
|
590
|
+
const star_card_map = {};
|
|
591
|
+
all_cards.forEach((card) => {
|
|
592
|
+
const { card_star } = card;
|
|
593
|
+
if (!star_card_map[card_star]) star_card_map[card_star] = [];
|
|
594
|
+
star_card_map[card_star].push(card);
|
|
595
|
+
});
|
|
596
|
+
const draw_result = [];
|
|
597
|
+
let is_upgrade = false, disturbance_total = 0, water_vapor_total = 0;
|
|
598
|
+
let no_6star = user_count?.no_6star_draws || 0, no_7star = user_count?.no_7star_draws || 0;
|
|
599
|
+
for (let i = 0; i < draw_times; i++) {
|
|
600
|
+
let selected_star = null;
|
|
601
|
+
let guarantee_triggered = false, guarantee_type = "none";
|
|
602
|
+
if (no_7star >= GUARANTEE_CONFIG["7star_threshold"]) {
|
|
603
|
+
selected_star = 7;
|
|
604
|
+
guarantee_triggered = true;
|
|
605
|
+
guarantee_type = "7star";
|
|
606
|
+
} else if (no_6star >= GUARANTEE_CONFIG["6star_threshold"]) {
|
|
607
|
+
guarantee_triggered = true;
|
|
608
|
+
guarantee_type = "6star";
|
|
609
|
+
const random_prob = import_random.default.int(1, 100);
|
|
610
|
+
selected_star = random_prob <= GUARANTEE_CONFIG["guarantee_6star_prob"] ? 6 : 7;
|
|
611
|
+
} else {
|
|
612
|
+
while (!selected_star) {
|
|
613
|
+
const prob_list = [];
|
|
614
|
+
for (const [star, prob] of Object.entries(GACHA_STAR_PROB)) {
|
|
615
|
+
prob_list.push(...Array(Math.floor(prob * 10)).fill(parseInt(star)));
|
|
616
|
+
}
|
|
617
|
+
const random_star = prob_list[import_random.default.int(0, prob_list.length - 1)];
|
|
618
|
+
if (star_card_map[random_star] && star_card_map[random_star].length > 0) {
|
|
619
|
+
selected_star = random_star;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
const card_list = star_card_map[selected_star];
|
|
624
|
+
const selected_card = card_list[import_random.default.int(0, card_list.length - 1)];
|
|
625
|
+
const { card_id, card_name } = selected_card;
|
|
626
|
+
draw_result.push([get_star_symbol(selected_star), card_id, card_name]);
|
|
627
|
+
const user_card = await db.get("SELECT card_level FROM gacha_user_card WHERE qq=? AND card_id=?", [qq, card_id]);
|
|
628
|
+
if (!user_card) {
|
|
629
|
+
await db.run("INSERT INTO gacha_user_card (qq, card_id, card_level) VALUES (?, ?, 0)", [qq, card_id]);
|
|
630
|
+
water_vapor_total += INIT_WATER_VAPOR[selected_star];
|
|
631
|
+
} else {
|
|
632
|
+
if (user_card.card_level < CARD_LEVEL_MAX) {
|
|
633
|
+
await db.run(
|
|
634
|
+
"UPDATE gacha_user_card SET card_level=? WHERE qq=? AND card_id=?",
|
|
635
|
+
[user_card.card_level + 1, qq, card_id]
|
|
636
|
+
);
|
|
637
|
+
is_upgrade = true;
|
|
638
|
+
water_vapor_total += UPGRADE_WATER_VAPOR[selected_star];
|
|
639
|
+
} else {
|
|
640
|
+
const disturb = STAR_TO_DISTURBANCE[selected_star];
|
|
641
|
+
if (disturb > 0) disturbance_total += disturb;
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
if (guarantee_triggered) {
|
|
645
|
+
if (guarantee_type === "7star") {
|
|
646
|
+
no_7star = 0;
|
|
647
|
+
no_6star++;
|
|
648
|
+
} else if (guarantee_type === "6star") {
|
|
649
|
+
no_6star = 0;
|
|
650
|
+
if (selected_star === 7) no_7star = 0;
|
|
651
|
+
else no_7star++;
|
|
652
|
+
}
|
|
653
|
+
} else {
|
|
654
|
+
if (selected_star === 7) {
|
|
655
|
+
no_6star++;
|
|
656
|
+
no_7star = 0;
|
|
657
|
+
} else if (selected_star === 6) {
|
|
658
|
+
no_6star = 0;
|
|
659
|
+
no_7star++;
|
|
660
|
+
} else {
|
|
661
|
+
no_6star++;
|
|
662
|
+
no_7star++;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
if (disturbance_total > 0) {
|
|
667
|
+
await db.run(
|
|
668
|
+
"UPDATE gacha_user_draw_count SET tropical_disturbance = tropical_disturbance + ? WHERE qq=?",
|
|
669
|
+
[disturbance_total, qq]
|
|
670
|
+
);
|
|
671
|
+
}
|
|
672
|
+
if (water_vapor_total > 0) {
|
|
673
|
+
await db.run(
|
|
674
|
+
"UPDATE gacha_user_draw_count SET water_vapor = water_vapor + ? WHERE qq=?",
|
|
675
|
+
[water_vapor_total, qq]
|
|
676
|
+
);
|
|
677
|
+
}
|
|
678
|
+
await db.run(`
|
|
679
|
+
UPDATE gacha_user_draw_count
|
|
680
|
+
SET no_6star_draws=?, no_7star_draws=?, draw_count=?
|
|
681
|
+
WHERE qq=?`, [no_6star, no_7star, have_draw - draw_times, qq]);
|
|
682
|
+
let msg = "🎉抽卡成功!恭喜您获得了以下卡片:\n";
|
|
683
|
+
msg += draw_result.map(([s, cid, cname]) => `${s} ${cid} ${cname}`).join("\n");
|
|
684
|
+
let append = "";
|
|
685
|
+
if (is_upgrade) append += "已对重复卡片升级。";
|
|
686
|
+
if (water_vapor_total > 0) append += `额外获得水汽*${water_vapor_total}
|
|
687
|
+
`;
|
|
688
|
+
if (disturbance_total > 0) append += `已满级卡片已自动转化为热带扰动*${disturbance_total}`;
|
|
689
|
+
if (append) msg += "\n" + append.trim();
|
|
690
|
+
await session.send(build_msg(session, msg));
|
|
691
|
+
}
|
|
692
|
+
__name(_do_draw, "_do_draw");
|
|
693
|
+
async function _do_warehouse(session, db) {
|
|
694
|
+
const qq = session.userId;
|
|
695
|
+
const user = await db.get("SELECT nickname, status FROM gacha_user WHERE qq=?", [qq]);
|
|
696
|
+
if (!user) return await session.send(build_msg(session, "❌ 请先完成注册后再查看仓库!"));
|
|
697
|
+
const show_name = user.status === 1 ? user.nickname : qq;
|
|
698
|
+
const user_cards = await db.all(`
|
|
699
|
+
SELECT u.card_level, p.card_id, p.card_name, p.card_star
|
|
700
|
+
FROM gacha_user_card u
|
|
701
|
+
JOIN gacha_card_pool p ON u.card_id = p.card_id
|
|
702
|
+
WHERE u.qq = ?
|
|
703
|
+
ORDER BY p.card_star DESC, p.card_id ASC`, [qq]);
|
|
704
|
+
const img_base64 = await _warehouse_draw_image(user_cards, show_name);
|
|
705
|
+
if (!img_base64) return await session.send(build_msg(session, "❌ 仓库图片生成失败,请稍后再试!"));
|
|
706
|
+
await session.send(`[CQ:image,file=${img_base64}]`);
|
|
707
|
+
}
|
|
708
|
+
__name(_do_warehouse, "_do_warehouse");
|
|
709
|
+
async function _do_shop(session, db) {
|
|
710
|
+
const qq = session.userId;
|
|
711
|
+
const user = await db.get("SELECT nickname, status FROM gacha_user WHERE qq=?", [qq]);
|
|
712
|
+
if (!user) return await session.send(build_msg(session, "❌ 请先完成注册后再查看店铺!"));
|
|
713
|
+
const show_name = user.status === 1 ? user.nickname : qq;
|
|
714
|
+
const today = getToday();
|
|
715
|
+
await db.run("BEGIN EXCLUSIVE TRANSACTION");
|
|
716
|
+
try {
|
|
717
|
+
const shop_exist = await db.get("SELECT COUNT(*) as cnt FROM gacha_shop_daily WHERE shop_date=?", [today]);
|
|
718
|
+
if (shop_exist.cnt === 0) {
|
|
719
|
+
await db.run("DELETE FROM gacha_shop_daily WHERE shop_date != ?", [today]);
|
|
720
|
+
(0, import_seedrandom.default)(today);
|
|
721
|
+
const star7_cards = await db.all("SELECT card_id FROM gacha_card_pool WHERE card_star=7 ORDER BY card_id ASC");
|
|
722
|
+
const shuffled7 = import_random.default.shuffle(star7_cards).slice(0, SHOP_CONFIG["7star_count"]);
|
|
723
|
+
for (const { card_id } of shuffled7) {
|
|
724
|
+
const price = import_random.default.int(SHOP_CONFIG["7star_price_range"][0], SHOP_CONFIG["7star_price_range"][1]);
|
|
725
|
+
await db.run(`
|
|
726
|
+
INSERT INTO gacha_shop_daily (shop_date, card_id, card_star, price, server_limit)
|
|
727
|
+
VALUES (?, ?, 7, ?, ?)`, [today, card_id, price, SHOP_CONFIG["server_buy_limit"]]);
|
|
728
|
+
}
|
|
729
|
+
const star6_cards = await db.all("SELECT card_id FROM gacha_card_pool WHERE card_star=6 ORDER BY card_id ASC");
|
|
730
|
+
const shuffled6 = import_random.default.shuffle(star6_cards).slice(0, SHOP_CONFIG["6star_count"]);
|
|
731
|
+
for (const { card_id } of shuffled6) {
|
|
732
|
+
const price = import_random.default.int(SHOP_CONFIG["6star_price_range"][0], SHOP_CONFIG["6star_price_range"][1]);
|
|
733
|
+
await db.run(`
|
|
734
|
+
INSERT INTO gacha_shop_daily (shop_date, card_id, card_star, price, server_limit)
|
|
735
|
+
VALUES (?, ?, 6, ?, ?)`, [today, card_id, price, SHOP_CONFIG["server_buy_limit"]]);
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
await db.run("COMMIT");
|
|
739
|
+
} catch (e) {
|
|
740
|
+
await db.run("ROLLBACK");
|
|
741
|
+
console.error("店铺生成失败:", e);
|
|
742
|
+
return await session.send(build_msg(session, "❌ 店铺加载失败,请稍后再试!"));
|
|
743
|
+
}
|
|
744
|
+
const shop_cards = await db.all(`
|
|
745
|
+
SELECT p.card_id, p.card_name, p.card_star, s.price, s.server_bought, s.server_limit
|
|
746
|
+
FROM gacha_shop_daily s
|
|
747
|
+
JOIN gacha_card_pool p ON s.card_id = p.card_id
|
|
748
|
+
WHERE s.shop_date=?
|
|
749
|
+
ORDER BY p.card_star DESC, p.card_id ASC`, [today]);
|
|
750
|
+
const user_asset = await db.get("SELECT tropical_disturbance, water_vapor FROM gacha_user_draw_count WHERE qq=?", [qq]);
|
|
751
|
+
const user_disturbance = user_asset?.tropical_disturbance || 0;
|
|
752
|
+
const user_water_vapor = user_asset?.water_vapor || 0;
|
|
753
|
+
const exchange = await db.get("SELECT exchange_count FROM gacha_shop_exchange WHERE qq=? AND exchange_date=?", [qq, today]);
|
|
754
|
+
const user_exchange_count = exchange?.exchange_count || 0;
|
|
755
|
+
const img_base64 = await _shop_draw_image(
|
|
756
|
+
shop_cards,
|
|
757
|
+
user_disturbance,
|
|
758
|
+
user_water_vapor,
|
|
759
|
+
user_exchange_count,
|
|
760
|
+
SHOP_CONFIG["daily_exchange_limit"],
|
|
761
|
+
show_name,
|
|
762
|
+
today
|
|
763
|
+
);
|
|
764
|
+
if (!img_base64) return await session.send(build_msg(session, "❌ 店铺图片生成失败,请稍后再试!"));
|
|
765
|
+
await session.send(`[CQ:image,file=${img_base64}]`);
|
|
766
|
+
}
|
|
767
|
+
__name(_do_shop, "_do_shop");
|
|
768
|
+
async function _do_upgrade(session, db, card_ids) {
|
|
769
|
+
const qq = session.userId;
|
|
770
|
+
const user = await db.get("SELECT qq FROM gacha_user WHERE qq=?", [qq]);
|
|
771
|
+
if (!user) return await session.send(build_msg(session, "❌ 请先完成注册后再进行升格!"));
|
|
772
|
+
if (!card_ids.length) {
|
|
773
|
+
return await session.send(build_msg(session, "❌ 升格参数错误!请输入店铺内的卡片编号!"));
|
|
774
|
+
}
|
|
775
|
+
const cid_count = {};
|
|
776
|
+
card_ids.forEach((cid) => {
|
|
777
|
+
cid_count[cid] = (cid_count[cid] || 0) + 1;
|
|
778
|
+
});
|
|
779
|
+
const today = getToday();
|
|
780
|
+
let total_cost = 0;
|
|
781
|
+
const shop_card_info = [];
|
|
782
|
+
for (const [cid, num] of Object.entries(cid_count)) {
|
|
783
|
+
const card = await db.get(`
|
|
784
|
+
SELECT p.card_id, p.card_name, p.card_star, s.price, s.server_bought, s.server_limit
|
|
785
|
+
FROM gacha_shop_daily s
|
|
786
|
+
JOIN gacha_card_pool p ON s.card_id = p.card_id
|
|
787
|
+
WHERE s.shop_date=? AND s.card_id=?`, [today, cid]);
|
|
788
|
+
if (!card) {
|
|
789
|
+
return await session.send(build_msg(session, `❌ 升格失败!编号【${cid}】不在今日店铺中!`));
|
|
790
|
+
}
|
|
791
|
+
const remaining = card.server_limit - card.server_bought;
|
|
792
|
+
if (num > remaining) {
|
|
793
|
+
return await session.send(build_msg(session, `❌ 升格失败!编号【${cid}】全服剩余可购买次数不足!当前剩余:${remaining}次`));
|
|
794
|
+
}
|
|
795
|
+
for (let i = 0; i < num; i++) {
|
|
796
|
+
shop_card_info.push(card);
|
|
797
|
+
total_cost += card.price;
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
const user_asset = await db.get("SELECT tropical_disturbance FROM gacha_user_draw_count WHERE qq=?", [qq]);
|
|
801
|
+
const user_disturbance = user_asset?.tropical_disturbance || 0;
|
|
802
|
+
if (user_disturbance < total_cost) {
|
|
803
|
+
return await session.send(build_msg(session, `❌ 升格失败!热带扰动不足!当前拥有:${user_disturbance},需要:${total_cost}`));
|
|
804
|
+
}
|
|
805
|
+
const upgrade_result = [];
|
|
806
|
+
let is_upgrade = false, disturbance_total = 0, water_vapor_total = 0;
|
|
807
|
+
for (const card of shop_card_info) {
|
|
808
|
+
const { card_id, card_name, card_star, price, server_limit } = card;
|
|
809
|
+
const star_symbol = get_star_symbol(card_star);
|
|
810
|
+
upgrade_result.push([star_symbol, card_id, card_name]);
|
|
811
|
+
const user_card = await db.get("SELECT card_level FROM gacha_user_card WHERE qq=? AND card_id=?", [qq, card_id]);
|
|
812
|
+
if (!user_card) {
|
|
813
|
+
await db.run("INSERT INTO gacha_user_card (qq, card_id, card_level) VALUES (?, ?, 0)", [qq, card_id]);
|
|
814
|
+
water_vapor_total += INIT_WATER_VAPOR[card_star];
|
|
815
|
+
} else {
|
|
816
|
+
if (user_card.card_level < CARD_LEVEL_MAX) {
|
|
817
|
+
await db.run(
|
|
818
|
+
"UPDATE gacha_user_card SET card_level=? WHERE qq=? AND card_id=?",
|
|
819
|
+
[user_card.card_level + 1, qq, card_id]
|
|
820
|
+
);
|
|
821
|
+
is_upgrade = true;
|
|
822
|
+
water_vapor_total += UPGRADE_WATER_VAPOR[card_star];
|
|
823
|
+
} else {
|
|
824
|
+
const disturb = STAR_TO_DISTURBANCE[card_star];
|
|
825
|
+
if (disturb > 0) disturbance_total += disturb;
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
await db.run(
|
|
829
|
+
"UPDATE gacha_shop_daily SET server_bought = server_bought + 1 WHERE shop_date=? AND card_id=?",
|
|
830
|
+
[today, card_id]
|
|
831
|
+
);
|
|
832
|
+
}
|
|
833
|
+
await db.run(
|
|
834
|
+
"UPDATE gacha_user_draw_count SET tropical_disturbance=? WHERE qq=?",
|
|
835
|
+
[user_disturbance - total_cost, qq]
|
|
836
|
+
);
|
|
837
|
+
if (water_vapor_total > 0) {
|
|
838
|
+
await db.run(
|
|
839
|
+
"UPDATE gacha_user_draw_count SET water_vapor = water_vapor + ? WHERE qq=?",
|
|
840
|
+
[water_vapor_total, qq]
|
|
841
|
+
);
|
|
842
|
+
}
|
|
843
|
+
if (disturbance_total > 0) {
|
|
844
|
+
await db.run(
|
|
845
|
+
"UPDATE gacha_user_draw_count SET tropical_disturbance = tropical_disturbance + ? WHERE qq=?",
|
|
846
|
+
[disturbance_total, qq]
|
|
847
|
+
);
|
|
848
|
+
}
|
|
849
|
+
let msg = "✅升格成功!恭喜您获得了以下卡片:\n";
|
|
850
|
+
msg += upgrade_result.map(([s, cid, cname]) => `${s} ${cid} ${cname}`).join("\n");
|
|
851
|
+
let append = "";
|
|
852
|
+
if (is_upgrade) append += "已对重复卡片升级。";
|
|
853
|
+
if (water_vapor_total > 0) append += `额外获得水汽*${water_vapor_total}
|
|
854
|
+
`;
|
|
855
|
+
if (disturbance_total > 0) append += `已满级卡片已自动转化为热带扰动*${disturbance_total}`;
|
|
856
|
+
if (append) msg += "\n" + append.trim();
|
|
857
|
+
await session.send(build_msg(session, msg));
|
|
858
|
+
}
|
|
859
|
+
__name(_do_upgrade, "_do_upgrade");
|
|
860
|
+
async function _do_exchange(session, db, exchange_num) {
|
|
861
|
+
const qq = session.userId;
|
|
862
|
+
const user = await db.get("SELECT qq FROM gacha_user WHERE qq=?", [qq]);
|
|
863
|
+
if (!user) return await session.send(build_msg(session, "❌ 请先完成注册后再进行兑换!"));
|
|
864
|
+
if (!Number.isInteger(exchange_num) || exchange_num < 1) {
|
|
865
|
+
return await session.send(build_msg(session, "❌ 兑换参数错误!请输入正整数数量!"));
|
|
866
|
+
}
|
|
867
|
+
const ratio = SHOP_CONFIG.exchange_ratio;
|
|
868
|
+
const daily_limit = SHOP_CONFIG.daily_exchange_limit;
|
|
869
|
+
const need_vapor = exchange_num * ratio;
|
|
870
|
+
const user_asset = await db.get("SELECT draw_count, water_vapor FROM gacha_user_draw_count WHERE qq=?", [qq]);
|
|
871
|
+
const user_vapor = user_asset?.water_vapor || 0;
|
|
872
|
+
const today = getToday();
|
|
873
|
+
const exchange = await db.get("SELECT exchange_count FROM gacha_shop_exchange WHERE qq=? AND exchange_date=?", [qq, today]);
|
|
874
|
+
const used = exchange?.exchange_count || 0;
|
|
875
|
+
if (user_vapor < need_vapor) {
|
|
876
|
+
return await session.send(build_msg(session, `❌ 兑换失败!水汽不足!当前拥有:${user_vapor},需要:${need_vapor}(${ratio}水汽=1次抽卡)`));
|
|
877
|
+
}
|
|
878
|
+
if (used + exchange_num > daily_limit) {
|
|
879
|
+
return await session.send(build_msg(session, `❌ 兑换失败!超出今日兑换上限!今日已兑换:${used}次,剩余:${daily_limit - used}次`));
|
|
880
|
+
}
|
|
881
|
+
await db.run(
|
|
882
|
+
"UPDATE gacha_user_draw_count SET water_vapor=?, draw_count=draw_count+? WHERE qq=?",
|
|
883
|
+
[user_vapor - need_vapor, exchange_num, qq]
|
|
884
|
+
);
|
|
885
|
+
if (exchange) {
|
|
886
|
+
await db.run(
|
|
887
|
+
"UPDATE gacha_shop_exchange SET exchange_count=? WHERE qq=? AND exchange_date=?",
|
|
888
|
+
[used + exchange_num, qq, today]
|
|
889
|
+
);
|
|
890
|
+
} else {
|
|
891
|
+
await db.run(
|
|
892
|
+
"INSERT INTO gacha_shop_exchange (qq, exchange_date, exchange_count) VALUES (?, ?, ?)",
|
|
893
|
+
[qq, today, exchange_num]
|
|
894
|
+
);
|
|
895
|
+
}
|
|
896
|
+
await session.send(build_msg(session, `✅兑换成功!消耗${need_vapor}水汽获得抽卡次数*${exchange_num}`));
|
|
897
|
+
}
|
|
898
|
+
__name(_do_exchange, "_do_exchange");
|
|
899
|
+
async function _do_collection(session, db) {
|
|
900
|
+
const qq = session.userId;
|
|
901
|
+
const user = await db.get("SELECT nickname, status FROM gacha_user WHERE qq=?", [qq]);
|
|
902
|
+
if (!user) return await session.send(build_msg(session, "❌ 请先完成注册后再查看收藏!"));
|
|
903
|
+
const show_name = user.status === 1 ? user.nickname : qq;
|
|
904
|
+
const collected_cards = await db.all(`
|
|
905
|
+
SELECT DISTINCT p.card_id, p.card_name, p.card_star, p.category
|
|
906
|
+
FROM gacha_user_card u
|
|
907
|
+
JOIN gacha_card_pool p ON u.card_id = p.card_id
|
|
908
|
+
WHERE u.qq = ?`, [qq]);
|
|
909
|
+
const collected_set = /* @__PURE__ */ new Set();
|
|
910
|
+
const card_star_map = {};
|
|
911
|
+
collected_cards.forEach(({ card_id, card_name, card_star, category }) => {
|
|
912
|
+
collected_set.add(`${category}-${card_id}`);
|
|
913
|
+
if (!card_star_map[category]) card_star_map[category] = {};
|
|
914
|
+
card_star_map[category][card_id] = { name: card_name, star: card_star };
|
|
915
|
+
});
|
|
916
|
+
const total_collected = collected_set.size;
|
|
917
|
+
const all_cards = await db.all("SELECT card_id, category FROM gacha_card_pool ORDER BY category ASC, card_id ASC");
|
|
918
|
+
const total_all = all_cards.length;
|
|
919
|
+
const category_cards = {};
|
|
920
|
+
const category_total = {};
|
|
921
|
+
all_cards.forEach(({ card_id, category }) => {
|
|
922
|
+
if (!category_cards[category]) {
|
|
923
|
+
category_cards[category] = [];
|
|
924
|
+
category_total[category] = 0;
|
|
925
|
+
}
|
|
926
|
+
category_cards[category].push(card_id);
|
|
927
|
+
category_total[category]++;
|
|
928
|
+
});
|
|
929
|
+
const category_progress = {};
|
|
930
|
+
for (const category in category_cards) {
|
|
931
|
+
const collected = Object.keys(card_star_map[category] || {}).length;
|
|
932
|
+
category_progress[category] = [collected, category_total[category], card_star_map[category] || {}];
|
|
933
|
+
}
|
|
934
|
+
const img_base64 = await _collection_draw_image(show_name, total_collected, total_all, category_progress, category_cards);
|
|
935
|
+
if (!img_base64) return await session.send(build_msg(session, "❌ 收藏图片生成失败,请稍后再试!"));
|
|
936
|
+
await session.send(`[CQ:image,file=${img_base64}]`);
|
|
937
|
+
}
|
|
938
|
+
__name(_do_collection, "_do_collection");
|
|
939
|
+
async function _do_ranking(session, db) {
|
|
940
|
+
const qq = session.userId;
|
|
941
|
+
const user = await db.get("SELECT nickname, status FROM gacha_user WHERE qq=?", [qq]);
|
|
942
|
+
if (!user) return await session.send(build_msg(session, "❌ 请先完成注册后再查看排行!"));
|
|
943
|
+
const show_name = user.status === 1 ? user.nickname : qq;
|
|
944
|
+
const all_ranking = await db.all(`
|
|
945
|
+
SELECT
|
|
946
|
+
u.qq,
|
|
947
|
+
CASE WHEN u.status=1 THEN u.nickname ELSE u.qq END AS show_name,
|
|
948
|
+
COUNT(DISTINCT c.card_id) AS collected_num,
|
|
949
|
+
u.rowid
|
|
950
|
+
FROM gacha_user u
|
|
951
|
+
LEFT JOIN gacha_user_card c ON u.qq = c.qq
|
|
952
|
+
GROUP BY u.qq, u.nickname, u.status, u.rowid
|
|
953
|
+
ORDER BY collected_num DESC, u.rowid ASC`);
|
|
954
|
+
const ranking_list = [];
|
|
955
|
+
let user_rank = 0, user_collected = 0;
|
|
956
|
+
all_ranking.forEach((item, idx) => {
|
|
957
|
+
const rank = idx + 1;
|
|
958
|
+
if (item.qq === qq) {
|
|
959
|
+
user_rank = rank;
|
|
960
|
+
user_collected = item.collected_num || 0;
|
|
961
|
+
}
|
|
962
|
+
if (rank <= 20) {
|
|
963
|
+
ranking_list.push([rank, item.show_name, item.collected_num || 0]);
|
|
964
|
+
}
|
|
965
|
+
});
|
|
966
|
+
if (!ranking_list.length) {
|
|
967
|
+
ranking_list.push([1, show_name, 0]);
|
|
968
|
+
user_rank = 1;
|
|
969
|
+
}
|
|
970
|
+
const img_base64 = await _ranking_draw_image(ranking_list, user_rank, user_collected, show_name);
|
|
971
|
+
if (!img_base64) return await session.send(build_msg(session, "❌ 排行图片生成失败,请稍后再试!"));
|
|
972
|
+
await session.send(`[CQ:image,file=${img_base64}]`);
|
|
973
|
+
}
|
|
974
|
+
__name(_do_ranking, "_do_ranking");
|
|
975
|
+
async function _do_switch(session, db, type, action, masterQQ) {
|
|
976
|
+
if (session.userId !== masterQQ) {
|
|
977
|
+
return await session.send(build_msg(session, "❌ 无权限!开关功能仅主人可用!"));
|
|
978
|
+
}
|
|
979
|
+
const status = action === "open" ? 1 : 0;
|
|
980
|
+
if (type === "global") {
|
|
981
|
+
await db.run("UPDATE gacha_global_switch SET status=? WHERE id=1", [status]);
|
|
982
|
+
await session.send(build_msg(session, status ? "✅ WWC抽卡功能已全部开启!" : "❌ WWC抽卡功能已全部关闭!"));
|
|
983
|
+
} else if (type === "group") {
|
|
984
|
+
if (!session.channelId?.startsWith("private") === false) return await session.send(build_msg(session, "❌ 私信场景无需设置群开关!"));
|
|
985
|
+
const group_id = session.guildId;
|
|
986
|
+
await db.run("INSERT OR REPLACE INTO gacha_group_switch (group_id, status) VALUES (?, ?)", [group_id, status]);
|
|
987
|
+
await session.send(build_msg(session, status ? "✅ 本群WWC抽卡功能已开启!" : "❌ 本群WWC抽卡功能已关闭!"));
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
__name(_do_switch, "_do_switch");
|
|
991
|
+
function _parse_all_gacha_cmd(raw_message) {
|
|
992
|
+
const raw_strip = raw_message.trim();
|
|
993
|
+
if (raw_strip.startsWith("WWC注册 ")) {
|
|
994
|
+
const nickname = raw_strip.replace("WWC注册 ", "").trim();
|
|
995
|
+
return { func: "register", data: nickname };
|
|
996
|
+
}
|
|
997
|
+
if (raw_strip.startsWith("WWC审核 ")) {
|
|
998
|
+
const qq = raw_strip.replace("WWC审核 ", "").trim();
|
|
999
|
+
return { func: "check", data: qq };
|
|
1000
|
+
}
|
|
1001
|
+
if (raw_strip === "WWC签到") return { func: "sign", data: null };
|
|
1002
|
+
if (raw_message.startsWith("WWC录入")) {
|
|
1003
|
+
const lines = raw_message.split("\n").slice(1).map((l) => l.trim()).filter((l) => l);
|
|
1004
|
+
return { func: "add_card", data: lines };
|
|
1005
|
+
}
|
|
1006
|
+
if (raw_strip.startsWith("WWC抽卡")) {
|
|
1007
|
+
const parts = raw_strip.split(/\s+/);
|
|
1008
|
+
const times = parts.length === 1 ? 1 : parseInt(parts[1]);
|
|
1009
|
+
return { func: "draw", data: isNaN(times) ? 1 : times };
|
|
1010
|
+
}
|
|
1011
|
+
if (raw_strip === "WWC仓库") return { func: "warehouse", data: null };
|
|
1012
|
+
if (raw_strip === "WWC店铺") return { func: "shop", data: null };
|
|
1013
|
+
if (raw_strip.startsWith("WWC升格")) {
|
|
1014
|
+
const card_ids = raw_strip.split(/\s+/).slice(1).filter((c) => c.trim());
|
|
1015
|
+
return { func: "upgrade", data: card_ids };
|
|
1016
|
+
}
|
|
1017
|
+
if (raw_strip.startsWith("WWC兑换")) {
|
|
1018
|
+
const parts = raw_strip.split(/\s+/);
|
|
1019
|
+
if (parts.length !== 2) return null;
|
|
1020
|
+
const num = parseInt(parts[1]);
|
|
1021
|
+
return isNaN(num) || num < 1 ? null : { func: "exchange", data: num };
|
|
1022
|
+
}
|
|
1023
|
+
if (raw_strip === "WWC收藏") return { func: "collection", data: null };
|
|
1024
|
+
if (raw_strip === "WWC排行1") return { func: "ranking", data: null };
|
|
1025
|
+
if (raw_strip === "WWC开启") return { func: "switch", data: { type: "group", action: "open" } };
|
|
1026
|
+
if (raw_strip === "WWC关闭") return { func: "switch", data: { type: "group", action: "close" } };
|
|
1027
|
+
if (raw_strip === "WWC开启全部") return { func: "switch", data: { type: "global", action: "open" } };
|
|
1028
|
+
if (raw_strip === "WWC关闭全部") return { func: "switch", data: { type: "global", action: "close" } };
|
|
1029
|
+
return null;
|
|
1030
|
+
}
|
|
1031
|
+
__name(_parse_all_gacha_cmd, "_parse_all_gacha_cmd");
|
|
1032
|
+
async function apply(ctx, config) {
|
|
1033
|
+
const db = await initDB();
|
|
1034
|
+
await db.run(
|
|
1035
|
+
"INSERT OR REPLACE INTO gacha_sign_config (id, reset_hour, reset_minute) VALUES (1, ?, ?)",
|
|
1036
|
+
[config.signResetHour, config.signResetMinute]
|
|
1037
|
+
);
|
|
1038
|
+
ctx.on("message", async (session) => {
|
|
1039
|
+
if (session.channelId?.startsWith("private") === false) {
|
|
1040
|
+
const group_id = session.guildId;
|
|
1041
|
+
await db.run("INSERT OR IGNORE INTO gacha_group_switch (group_id, status) VALUES (?, 0)", [group_id]);
|
|
1042
|
+
}
|
|
1043
|
+
});
|
|
1044
|
+
ctx.middleware(async (session, next) => {
|
|
1045
|
+
const raw_message = session.content.trim();
|
|
1046
|
+
if (!raw_message.startsWith("WWC")) return next();
|
|
1047
|
+
const cmd = _parse_all_gacha_cmd(raw_message);
|
|
1048
|
+
if (!cmd) return next();
|
|
1049
|
+
if (cmd.func !== "switch") {
|
|
1050
|
+
const global_switch = await db.get("SELECT status FROM gacha_global_switch WHERE id=1");
|
|
1051
|
+
if (global_switch.status === 0) return;
|
|
1052
|
+
if (session.channelId?.startsWith("private") === false) {
|
|
1053
|
+
const group_switch = await db.get("SELECT status FROM gacha_group_switch WHERE group_id=?", [session.guildId]);
|
|
1054
|
+
if (group_switch?.status === 0) return;
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
const func_map = {
|
|
1058
|
+
register: /* @__PURE__ */ __name((data) => _do_register(session, db, data, config.masterQQ), "register"),
|
|
1059
|
+
check: /* @__PURE__ */ __name((data) => _do_check(session, db, data, config.masterQQ), "check"),
|
|
1060
|
+
sign: /* @__PURE__ */ __name(() => _do_sign(session, db, config.signResetHour, config.signResetMinute), "sign"),
|
|
1061
|
+
add_card: /* @__PURE__ */ __name((data) => _do_add_card(session, db, data, config.masterQQ), "add_card"),
|
|
1062
|
+
draw: /* @__PURE__ */ __name((data) => _do_draw(session, db, data), "draw"),
|
|
1063
|
+
warehouse: /* @__PURE__ */ __name(() => _do_warehouse(session, db), "warehouse"),
|
|
1064
|
+
shop: /* @__PURE__ */ __name(() => _do_shop(session, db), "shop"),
|
|
1065
|
+
upgrade: /* @__PURE__ */ __name((data) => _do_upgrade(session, db, data), "upgrade"),
|
|
1066
|
+
exchange: /* @__PURE__ */ __name((data) => _do_exchange(session, db, data), "exchange"),
|
|
1067
|
+
collection: /* @__PURE__ */ __name(() => _do_collection(session, db), "collection"),
|
|
1068
|
+
ranking: /* @__PURE__ */ __name(() => _do_ranking(session, db), "ranking"),
|
|
1069
|
+
switch: /* @__PURE__ */ __name((data) => _do_switch(session, db, data.type, data.action, config.masterQQ), "switch")
|
|
1070
|
+
};
|
|
1071
|
+
if (func_map[cmd.func]) {
|
|
1072
|
+
await func_map[cmd.func](cmd.data);
|
|
1073
|
+
return;
|
|
1074
|
+
}
|
|
1075
|
+
return next();
|
|
1076
|
+
});
|
|
1077
|
+
ctx.on("dispose", async () => {
|
|
1078
|
+
await db.close();
|
|
1079
|
+
console.log("✅ 习习抽卡系统数据库已关闭!");
|
|
1080
|
+
});
|
|
1081
|
+
console.log("✅ 习习抽卡系统(xxck-1)插件加载成功!");
|
|
1082
|
+
}
|
|
1083
|
+
__name(apply, "apply");
|
|
1084
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1085
|
+
0 && (module.exports = {
|
|
1086
|
+
Config,
|
|
1087
|
+
apply,
|
|
1088
|
+
name
|
|
1089
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "koishi-plugin-xxck-1",
|
|
3
|
+
"description": "自用抽卡",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"typings": "lib/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"lib",
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"scripts": {},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"chatbot",
|
|
15
|
+
"koishi",
|
|
16
|
+
"plugin"
|
|
17
|
+
],
|
|
18
|
+
"devDependencies": {},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"koishi": "^4.18.7"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@napi-rs/canvas": "^0.1.97",
|
|
24
|
+
"luxon": "^3.7.2",
|
|
25
|
+
"random": "^5.4.1",
|
|
26
|
+
"seedrandom": "^3.0.5",
|
|
27
|
+
"sqlite": "^5.1.1",
|
|
28
|
+
"sqlite3": "^6.0.1"
|
|
29
|
+
}
|
|
30
|
+
}
|