@hieuzest/koishi-plugin-mahjongpub 0.1.18 → 0.1.20

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.
Files changed (2) hide show
  1. package/lib/index.js +542 -452
  2. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -1,460 +1,550 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MahjongPub = void 0;
4
- const koishi_1 = require("koishi");
5
- const api_1 = require("./api");
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
6
+ var __commonJS = (cb, mod) => function __require() {
7
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
8
+ };
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
22
+
23
+ // src/locales/zh-CN.yml
24
+ var require_zh_CN = __commonJS({
25
+ "src/locales/zh-CN.yml"(exports2, module2) {
26
+ module2.exports = { commands: { "mahjongpub.team.bind": { description: "绑定队伍", messages: { failed: "绑定失败", success: "成功: [{cid}:{tid}] {name}" } }, "mahjongpub.team.unbind": { description: "解除绑定", messages: { notbind: "未绑定", success: "成功" } }, "mahjongpub.team.password": { description: "查看密码", messages: { notbind: "未绑定", output: "密码: {0}" } }, "mahjongpub.team.stats": { description: "查看队伍信息", messages: { notbind: "未绑定", failed: "失败", output: "- [{cid}:{tid}] {name}\n{players.map((p, i) => '' + (i+1) + ': ' + p).join('\\n')}\n" } }, "mahjongpub.team.desc": { description: "队伍简介", messages: { notbind: "未绑定", failed: "失败", output: "- [{cid}:{tid}] {name}\n{description}\n" } }, "mahjongpub.team.logo": { description: "队伍头像", messages: { notbind: "未绑定", failed: "失败" } }, "mahjongpub.team.add": { description: "添加队员", messages: { notbind: "未绑定", failed: "失败", success: "- [{cid}:{tid}] {name}\n{players.map((p, i) => '' + (i+1) + ': ' + p).join('\\n')}\n" } }, "mahjongpub.team.remove": { description: "删除队员", messages: { notbind: "未绑定", failed: "失败", success: "- [{cid}:{tid}] {name}\n{players.map((p, i) => '' + (i+1) + ': ' + p).join('\\n')}\n" } }, "mahjongpub.team.swap": { description: "交换队员", messages: { notbind: "未绑定", failed: "失败", invalid: "参数错误", "wide-range": "范围过大", success: "- [{cid}:{tid}] {name}\n{players.map((p, i) => '' + (i+1) + ': ' + p).join('\\n')}\n" } }, "mahjongpub.contest.bind": { description: "绑定比赛", messages: { failed: "绑定失败", success: "成功: [{cid}] {name}" } }, "mahjongpub.contest.record.get": { description: "查询比赛记录", messages: { failed: "查询失败" } }, "mahjongpub.contest.record.update": { description: "修改比赛记录", messages: { failed: "修改失败" } }, "mahjongpub.database.record.get": { description: "查询比赛记录", messages: { failed: "查询失败" } }, "mahjongpub.database.record.update": { description: "修改比赛记录", messages: { success: "修改成功", failed: "修改失败", unmodified: "未修改" } } } };
27
+ }
28
+ });
29
+
30
+ // src/index.ts
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ MahjongPub: () => MahjongPub,
34
+ default: () => src_default
35
+ });
36
+ module.exports = __toCommonJS(src_exports);
37
+ var import_koishi = require("koishi");
38
+
39
+ // src/api.ts
40
+ var TeamAdmin = class {
41
+ constructor(ctx, pw, options) {
42
+ this.pw = pw;
43
+ this.options = options;
44
+ this.http = ctx.http.extend({
45
+ endpoint: options.endpoint
46
+ });
47
+ }
48
+ static {
49
+ __name(this, "TeamAdmin");
50
+ }
51
+ tid;
52
+ cid;
53
+ name;
54
+ description;
55
+ players;
56
+ img;
57
+ ready;
58
+ http;
59
+ async read(force = false) {
60
+ if (this.tid && !force) return;
61
+ const data = await this.http.get("/api/data.php", {
62
+ responseType: "json",
63
+ params: {
64
+ t: "tm_pw",
65
+ cid: this.pw
66
+ }
67
+ });
68
+ if (!data?.tid) throw new Error("failed to read team info");
69
+ this.tid = data.tid;
70
+ this.cid = data.cid;
71
+ this.name = data.t_name;
72
+ this.description = data.t_ps;
73
+ this.players = [...data.t_player?.split(/\s+/) ?? [], ...data.t_sub?.split(/\s+/) ?? []];
74
+ this.img = data.img;
75
+ this.ready = !!+(data.t_type ?? 0);
76
+ }
77
+ async write() {
78
+ const payload = {
79
+ posttype: "update",
80
+ t_pw: this.pw,
81
+ t_ps: this.description,
82
+ cid: this.cid,
83
+ linkurl: this.img,
84
+ team_type: this.ready ? "1" : "0",
85
+ postdata: this.players.join("\n")
86
+ };
87
+ const form = new FormData();
88
+ Object.entries(payload).forEach(([key, value]) => form.append(key, value));
89
+ return (await this.http.post("/team_post.php", form, { responseType: "json" }))?.msg;
90
+ }
91
+ };
92
+ var ContestAdmin = class {
93
+ constructor(ctx, cid, pw, options) {
94
+ this.cid = cid;
95
+ this.pw = pw;
96
+ this.options = options;
97
+ this.http = ctx.http.extend({
98
+ endpoint: options.endpoint
99
+ });
100
+ }
101
+ static {
102
+ __name(this, "ContestAdmin");
103
+ }
104
+ name;
105
+ teams;
106
+ http;
107
+ raw;
108
+ async read(force = false) {
109
+ if (this.teams && !force) return;
110
+ const payload = {
111
+ posttype: "login",
112
+ cid: this.cid,
113
+ c_pw: this.pw
114
+ };
115
+ const form = new FormData();
116
+ Object.entries(payload).forEach(([key, value]) => form.append(key, value));
117
+ const data = await this.http.post("/api/admin_post.php", form, {
118
+ responseType: "json"
119
+ });
120
+ if (!data?.c_admin?.cid) throw new Error("failed to read contest info");
121
+ this.raw = data;
122
+ this.name = data.c_admin.c_name;
123
+ this.teams = Object.fromEntries(data.c_team.map((team) => [team.tid, {
124
+ tid: team.tid,
125
+ cid: this.cid,
126
+ name: team.t_name,
127
+ qq: team.qq.split(/\s+/),
128
+ players: [...team.t_player?.split(/\s+/) ?? [], ...team.t_sub?.split(/\s+/) ?? []],
129
+ pw: team.t_pw
130
+ }]));
131
+ }
132
+ async getRoundRecord(round, cls) {
133
+ const payload = {
134
+ type: "login",
135
+ cid: this.cid,
136
+ cls: String(cls),
137
+ rnd: String(round)
138
+ };
139
+ const form = new FormData();
140
+ Object.entries(payload).forEach(([key, value]) => form.append(key, value));
141
+ const data = await this.http.post("/edit_class_json.php", form, {
142
+ responseType: "json"
143
+ });
144
+ if (data.status !== "2") throw new Error(`failed to get round record with status ${data.status}`);
145
+ const record = {
146
+ cid: this.cid,
147
+ cls,
148
+ rnd: round,
149
+ matches: data.data.map((x) => {
150
+ const players = [];
151
+ for (let i = 0; i < x.length - 1; i += 3) {
152
+ players.push({
153
+ name: x[i],
154
+ point: +x[i + 1],
155
+ score: +x[i + 2]
156
+ });
157
+ }
158
+ return {
159
+ players,
160
+ logurl: x[x.length - 1]
161
+ };
162
+ })
163
+ };
164
+ return record;
165
+ }
166
+ async updateRoundRecord(record) {
167
+ const payload = {
168
+ type: "update",
169
+ cid: this.cid,
170
+ cls: String(record.cls),
171
+ rnd: String(record.rnd),
172
+ pw: this.pw
173
+ };
174
+ const form = new FormData();
175
+ Object.entries(payload).forEach(([key, value]) => form.append(key, value));
176
+ record.matches.forEach((match) => {
177
+ match.players.forEach((player, i) => {
178
+ form.append(`name${i + 1}[]`, player.name);
179
+ form.append(`point${i + 1}[]`, String(player.point));
180
+ form.append(`score${i + 1}[]`, String(player.score));
181
+ });
182
+ form.append(`logurl[]`, match.logurl);
183
+ });
184
+ const data = await this.http.post("/edit_class_json.php", form, {
185
+ responseType: "json"
186
+ });
187
+ if (data.status !== "2") throw new Error(`failed to update round record with status ${data.status}`);
188
+ return data.data;
189
+ }
190
+ };
191
+
192
+ // src/index.ts
6
193
  function parsePlatform(target) {
7
- const index = target.startsWith('sandbox:') ? target.lastIndexOf(':') : target.indexOf(':');
8
- const platform = target.slice(0, index);
9
- const id = target.slice(index + 1);
10
- return [platform, id];
194
+ const index = target.startsWith("sandbox:") ? target.lastIndexOf(":") : target.indexOf(":");
195
+ const platform = target.slice(0, index);
196
+ const id = target.slice(index + 1);
197
+ return [platform, id];
11
198
  }
12
- class MahjongPub {
13
- ctx;
14
- config;
15
- teams = {};
16
- contests = {};
17
- constructor(ctx, config) {
18
- this.ctx = ctx;
19
- this.config = config;
20
- ctx.i18n.define('zh-CN', require('./locales/zh-CN'));
21
- ctx.model.extend('user', {
22
- 'mahjongpub/bind-team': 'string',
23
- 'mahjongpub/bind-teams': 'json',
24
- });
25
- ctx.model.extend('channel', {
26
- 'mahjongpub/bind-team': 'string',
27
- 'mahjongpub/bind-contest': 'string',
28
- 'mahjongpub/bind-contestpw': 'string',
29
- });
30
- ctx.command('mahjongpub.team.bind <pw:string>')
31
- .alias('!绑定', '!绑定')
32
- .option('user', '-u <user:user>')
33
- .option('channel', '-c <channel:channel>')
34
- .userFields(['mahjongpub/bind-team'])
35
- .channelFields(['mahjongpub/bind-team'])
36
- .action(async ({ session, options }, pw) => {
37
- if (pw?.length !== 20)
38
- return;
39
- const team = await this.getTeam(pw);
40
- try {
41
- await team.read();
42
- }
43
- catch (e) {
44
- ctx.logger.warn(e);
45
- return session.text('.failed');
46
- }
47
- if (options.user)
48
- ctx.database.setUser(...parsePlatform(options.user), { 'mahjongpub/bind-team': pw });
49
- else if (options.channel)
50
- ctx.database.setChannel(...parsePlatform(options.channel), { 'mahjongpub/bind-team': pw });
51
- else if (session.isDirect)
52
- session.user['mahjongpub/bind-team'] = pw;
53
- else
54
- session.channel['mahjongpub/bind-team'] = pw;
55
- return session.text('.success', team);
56
- });
57
- ctx.command('mahjongpub.team.unbind')
58
- .alias('!解绑', '!解绑')
59
- .option('channel', '-c <channel:channel>')
60
- .userFields(['mahjongpub/bind-team'])
61
- .channelFields(['mahjongpub/bind-team'])
62
- .action(async ({ session, options }) => {
63
- const pw = options.channel ? (await session.getChannel(parsePlatform(options.channel)[1], ['mahjongpub/bind-team']))['mahjongpub/bind-team']
64
- : session.isDirect ? session.user['mahjongpub/bind-team'] : session.channel['mahjongpub/bind-team'] ?? session.user['mahjongpub/bind-team'];
65
- if (!pw)
66
- return config.informNotbind ? session.text('.notbind') : '';
67
- if (session.isDirect)
68
- session.user['mahjongpub/bind-team'] = '';
69
- else
70
- session.channel['mahjongpub/bind-team'] = '';
71
- return session.text('.success');
72
- });
73
- ctx.private().command('mahjongpub.team.password')
74
- .alias('!密码', '!密码')
75
- .userFields(['mahjongpub/bind-team'])
76
- .action(async ({ session }) => {
77
- const pw = session.user['mahjongpub/bind-team'];
78
- if (!pw)
79
- return config.informNotbind ? session.text('.notbind') : '';
80
- return session.text('.output', [pw]);
81
- });
82
- ctx.command('mahjongpub.team.stats')
83
- .alias('!信息', '!信息', '!概况', '!概况')
84
- .option('channel', '-c <channel:channel>')
85
- .option('team', '-t <team:string>')
86
- .userFields(['mahjongpub/bind-team', 'mahjongpub/bind-teams'])
87
- .channelFields(['mahjongpub/bind-team', 'mahjongpub/bind-contest', 'mahjongpub/bind-contestpw'])
88
- .action(async ({ session, options }) => {
89
- let pw = options.channel ? (await session.getChannel(parsePlatform(options.channel)[1], ['mahjongpub/bind-team']))['mahjongpub/bind-team']
90
- : session.isDirect ? session.user['mahjongpub/bind-team'] : session.channel['mahjongpub/bind-team'] ?? session.user['mahjongpub/bind-team'];
91
- if (options.team) {
92
- const [cid, cpw] = [session.channel['mahjongpub/bind-contest'], session.channel['mahjongpub/bind-contestpw']];
93
- if (!cid || !cpw)
94
- return session.text('.notbind');
95
- const contest = await this.getContest(cid, cpw);
96
- await contest.read();
97
- pw = (contest.teams[options.team] ?? Object.values(contest.teams).find(t => t.name === options.team))?.pw;
98
- }
99
- if (!pw)
100
- return config.informNotbind ? session.text('.notbind') : '';
101
- const team = await this.getTeam(pw);
102
- try {
103
- await team.read();
104
- return session.text('.output', team);
105
- }
106
- catch (e) {
107
- ctx.logger.warn(e);
108
- return session.text('.failed');
109
- }
110
- });
111
- ctx.command('mahjongpub.team.desc [desc:rawtext]')
112
- .alias('!简介', '!简介')
113
- .option('channel', '-c <channel:channel>')
114
- .userFields(['mahjongpub/bind-team'])
115
- .channelFields(['mahjongpub/bind-team'])
116
- .action(async ({ session, options }, desc) => {
117
- const pw = options.channel ? (await session.getChannel(parsePlatform(options.channel)[1], ['mahjongpub/bind-team']))['mahjongpub/bind-team']
118
- : session.isDirect ? session.user['mahjongpub/bind-team'] : session.channel['mahjongpub/bind-team'] ?? session.user['mahjongpub/bind-team'];
119
- if (!pw)
120
- return config.informNotbind ? session.text('.notbind') : '';
121
- const team = await this.getTeam(pw);
122
- try {
123
- await team.read();
124
- if (!desc)
125
- return session.text('.output', team);
126
- team.description = desc;
127
- return await team.write();
128
- }
129
- catch (e) {
130
- ctx.logger.warn(e);
131
- return session.text('.failed');
132
- }
133
- });
134
- ctx.command('mahjongpub.team.logo [img:img]')
135
- .alias('!头像', '!头像')
136
- .option('channel', '-c <channel:channel>')
137
- .userFields(['mahjongpub/bind-team'])
138
- .channelFields(['mahjongpub/bind-team'])
139
- .action(async ({ session, options }, img) => {
140
- const pw = options.channel ? (await session.getChannel(parsePlatform(options.channel)[1], ['mahjongpub/bind-team']))['mahjongpub/bind-team']
141
- : session.isDirect ? session.user['mahjongpub/bind-team'] : session.channel['mahjongpub/bind-team'] ?? session.user['mahjongpub/bind-team'];
142
- if (!pw)
143
- return config.informNotbind ? session.text('.notbind') : '';
144
- const team = await this.getTeam(pw);
145
- try {
146
- await team.read();
147
- if (!img)
148
- return koishi_1.h.image(team.img);
149
- const url = await ctx.assets.upload('https://koishi.chat/logo.png', `${session.id}-${session.timestamp}.png`);
150
- team.img = url;
151
- return await team.write();
152
- }
153
- catch (e) {
154
- ctx.logger.warn(e);
155
- return session.text('.failed');
156
- }
157
- });
158
- ctx.command('mahjongpub.team.add <...users:string>', { authority: 3 })
159
- .alias('!添加', '!添加')
160
- .option('channel', '-c <channel:channel>')
161
- .option('team', '-t <team:string>')
162
- .userFields(['mahjongpub/bind-team', 'mahjongpub/bind-teams'])
163
- .channelFields(['mahjongpub/bind-team', 'mahjongpub/bind-contest', 'mahjongpub/bind-contestpw'])
164
- .action(async ({ session, options }, ...users) => {
165
- let pw = options.channel ? (await session.getChannel(parsePlatform(options.channel)[1], ['mahjongpub/bind-team']))['mahjongpub/bind-team']
166
- : session.isDirect ? session.user['mahjongpub/bind-team'] : session.channel['mahjongpub/bind-team'] ?? session.user['mahjongpub/bind-team'];
167
- if (options.team) {
168
- const [cid, cpw] = [session.channel['mahjongpub/bind-contest'], session.channel['mahjongpub/bind-contestpw']];
169
- if (!cid || !cpw)
170
- return session.text('.notbind');
171
- const contest = await this.getContest(cid, cpw);
172
- await contest.read();
173
- pw = (contest.teams[options.team] ?? Object.values(contest.teams).find(t => t.name === options.team))?.pw;
174
- }
175
- if (!pw)
176
- return config.informNotbind ? session.text('.notbind') : '';
177
- const team = await this.getTeam(pw);
178
- try {
179
- await team.read();
180
- team.players.push(...users);
181
- const msg = await team.write();
182
- await team.read(true);
183
- return msg + '\n' + session.text('.success', team);
184
- }
185
- catch (e) {
186
- ctx.logger.warn(e);
187
- return session.text('.failed');
188
- }
189
- });
190
- ctx.command('mahjongpub.team.remove <...indices:natural>', { authority: 3 })
191
- .alias('!删除', '!删除')
192
- .option('channel', '-c <channel:channel>')
193
- .option('team', '-t <team:string>')
194
- .userFields(['mahjongpub/bind-team', 'mahjongpub/bind-teams'])
195
- .channelFields(['mahjongpub/bind-team', 'mahjongpub/bind-contest', 'mahjongpub/bind-contestpw'])
196
- .action(async ({ session, options }, ...indices) => {
197
- let pw = options.channel ? (await session.getChannel(parsePlatform(options.channel)[1], ['mahjongpub/bind-team']))['mahjongpub/bind-team']
198
- : session.isDirect ? session.user['mahjongpub/bind-team'] : session.channel['mahjongpub/bind-team'] ?? session.user['mahjongpub/bind-team'];
199
- if (options.team) {
200
- const [cid, cpw] = [session.channel['mahjongpub/bind-contest'], session.channel['mahjongpub/bind-contestpw']];
201
- if (!cid || !cpw)
202
- return session.text('.notbind');
203
- const contest = await this.getContest(cid, cpw);
204
- await contest.read();
205
- pw = (contest.teams[options.team] ?? Object.values(contest.teams).find(t => t.name === options.team))?.pw;
206
- }
207
- if (!pw)
208
- return config.informNotbind ? session.text('.notbind') : '';
209
- const team = await this.getTeam(pw);
210
- try {
211
- await team.read();
212
- team.players = team.players.filter((_, i) => !indices.includes(i + 1));
213
- await team.write();
214
- const msg = await team.write();
215
- await team.read(true);
216
- return msg + '\n' + session.text('.success', team);
217
- }
218
- catch (e) {
219
- ctx.logger.warn(e);
220
- return session.text('.failed');
221
- }
222
- });
223
- ctx.command('mahjongpub.team.swap <...indices:natural>', { authority: 3 })
224
- .alias('!交换', '!交换')
225
- .option('channel', '-c <channel:channel>')
226
- .option('team', '-t <team:string>')
227
- .option('start', '-s <start:number>')
228
- .option('end', '-e <end:number>')
229
- .option('slim', '--slim')
230
- .userFields(['mahjongpub/bind-team', 'mahjongpub/bind-teams'])
231
- .channelFields(['mahjongpub/bind-team', 'mahjongpub/bind-contest', 'mahjongpub/bind-contestpw'])
232
- .action(async ({ session, options }, ...indices) => {
233
- let pw = options.channel ? (await session.getChannel(parsePlatform(options.channel)[1], ['mahjongpub/bind-team']))['mahjongpub/bind-team']
234
- : session.isDirect ? session.user['mahjongpub/bind-team'] : session.channel['mahjongpub/bind-team'] ?? session.user['mahjongpub/bind-team'];
235
- if (options.team) {
236
- const [cid, cpw] = [session.channel['mahjongpub/bind-contest'], session.channel['mahjongpub/bind-contestpw']];
237
- if (!cid || !cpw)
238
- return session.text('.notbind');
239
- const contest = await this.getContest(cid, cpw);
240
- await contest.read();
241
- pw = (contest.teams[options.team] ?? Object.values(contest.teams).find(t => t.name === options.team))?.pw;
242
- }
243
- else if (options.start && options.end) {
244
- if (options.end - options.start > 100)
245
- return session.text('.wide-range');
246
- const msg = [];
247
- for (let tid = options.start; tid <= options.end; tid++) {
248
- msg.push(await session.execute({
249
- name: 'mahjongpub.team.swap',
250
- args: indices,
251
- options: {
252
- channel: options.channel,
253
- team: `${tid}`,
254
- slim: true,
255
- },
256
- }, true));
257
- if (msg.length >= config.batchCount)
258
- await session.send(msg.splice(0).join('\n'));
259
- await ctx.sleep(config.batchInterval);
260
- }
261
- return msg.length ? msg.join('\n') : '';
262
- }
263
- if (!pw)
264
- return config.informNotbind ? session.text('.notbind') : '';
265
- if (!indices.length || indices.length % 2 !== 0)
266
- return session.text('.invalid');
267
- const team = await this.getTeam(pw);
268
- try {
269
- await team.read();
270
- for (let i = 0; i < indices.length; i += 2) {
271
- const t = team.players[indices[i] - 1];
272
- team.players[indices[i] - 1] = team.players[indices[i + 1] - 1];
273
- team.players[indices[i + 1] - 1] = t;
274
- }
275
- const msg = await team.write();
276
- await team.read(true);
277
- if (options.slim)
278
- return `[${team.tid} ${team.name}] ${msg} ` + indices.map(i => `${i}. ${team.players[i - 1]}`).join(' ');
279
- else
280
- return msg + '\n' + session.text('.success', team);
281
- }
282
- catch (e) {
283
- ctx.logger.warn(e);
284
- return session.text('.failed');
285
- }
286
- });
287
- ctx.command('mahjongpub.contest.bind <cid:string> <cpw:string>', { authority: 4 })
288
- .option('channel', '-c <channel:channel>')
289
- .channelFields(['mahjongpub/bind-contest', 'mahjongpub/bind-contestpw'])
290
- .action(async ({ session, options }, cid, cpw) => {
291
- const contest = await this.getContest(cid, cpw);
292
- try {
293
- await contest.read();
294
- }
295
- catch (e) {
296
- ctx.logger.warn(e);
297
- return session.text('.failed');
298
- }
299
- if (options.channel) {
300
- ctx.database.setChannel(...parsePlatform(options.channel), {
301
- 'mahjongpub/bind-contest': cid,
302
- 'mahjongpub/bind-contestpw': cpw,
303
- });
304
- }
305
- else {
306
- session.channel['mahjongpub/bind-contest'] = cid;
307
- session.channel['mahjongpub/bind-contestpw'] = cpw;
308
- }
309
- return session.text('.success', contest);
310
- });
311
- ctx.command('mahjongpub.contest.record.get <round:natural> <cls:natural>', { authority: 3 })
312
- .option('rowi', '-i <rowi:integer>')
313
- .channelFields(['mahjongpub/bind-contest', 'mahjongpub/bind-contestpw'])
314
- .action(async ({ session, options }, round, cls) => {
315
- const [cid, cpw] = [session.channel['mahjongpub/bind-contest'], session.channel['mahjongpub/bind-contestpw']];
316
- const contest = await this.getContest(cid, cpw);
317
- try {
318
- const record = await contest.getRoundRecord(round, cls);
319
- if ((0, koishi_1.isNullable)(options.rowi)) {
320
- return record.matches.map((match, i) => `[${i}] ` + match.players.map(x => `${x.name} ${x.point}`).join(' / ')).join('\n');
321
- }
322
- else {
323
- return [
324
- `[${options.rowi === -1 ? record.matches.length - 1 : options.rowi}]`,
325
- record.matches.at(options.rowi ?? -1).players.map(x => `${x.name} ${x.point}`).join(' / '),
326
- ].join(' ');
327
- }
328
- }
329
- catch (e) {
330
- ctx.logger.warn(e);
331
- return session.text('.failed');
199
+ __name(parsePlatform, "parsePlatform");
200
+ var MahjongPub = class {
201
+ constructor(ctx, config) {
202
+ this.ctx = ctx;
203
+ this.config = config;
204
+ ctx.i18n.define("zh-CN", require_zh_CN());
205
+ ctx.model.extend("user", {
206
+ "mahjongpub/bind-team": "string",
207
+ "mahjongpub/bind-teams": "json"
208
+ });
209
+ ctx.model.extend("channel", {
210
+ "mahjongpub/bind-team": "string",
211
+ "mahjongpub/bind-contest": "string",
212
+ "mahjongpub/bind-contestpw": "string"
213
+ });
214
+ ctx.command("mahjongpub.team.bind <pw:string>").alias("!绑定", "!绑定").option("user", "-u <user:user>").option("channel", "-c <channel:channel>").userFields(["mahjongpub/bind-team"]).channelFields(["mahjongpub/bind-team"]).action(async ({ session, options }, pw) => {
215
+ if (pw?.length !== 20) return;
216
+ const team = await this.getTeam(pw);
217
+ try {
218
+ await team.read();
219
+ } catch (e) {
220
+ ctx.logger.warn(e);
221
+ return session.text(".failed");
222
+ }
223
+ if (options.user) ctx.database.setUser(...parsePlatform(options.user), { "mahjongpub/bind-team": pw });
224
+ else if (options.channel) ctx.database.setChannel(...parsePlatform(options.channel), { "mahjongpub/bind-team": pw });
225
+ else if (session.isDirect) session.user["mahjongpub/bind-team"] = pw;
226
+ else session.channel["mahjongpub/bind-team"] = pw;
227
+ return session.text(".success", team);
228
+ });
229
+ ctx.command("mahjongpub.team.unbind").alias("!解绑", "!解绑").option("channel", "-c <channel:channel>").userFields(["mahjongpub/bind-team"]).channelFields(["mahjongpub/bind-team"]).action(async ({ session, options }) => {
230
+ const pw = options.channel ? (await session.getChannel(parsePlatform(options.channel)[1], ["mahjongpub/bind-team"]))["mahjongpub/bind-team"] : session.isDirect ? session.user["mahjongpub/bind-team"] : session.channel["mahjongpub/bind-team"] ?? session.user["mahjongpub/bind-team"];
231
+ if (!pw) return config.informNotbind ? session.text(".notbind") : "";
232
+ if (session.isDirect) session.user["mahjongpub/bind-team"] = "";
233
+ else session.channel["mahjongpub/bind-team"] = "";
234
+ return session.text(".success");
235
+ });
236
+ ctx.private().command("mahjongpub.team.password").alias("!密码", "!密码").userFields(["mahjongpub/bind-team"]).action(async ({ session }) => {
237
+ const pw = session.user["mahjongpub/bind-team"];
238
+ if (!pw) return config.informNotbind ? session.text(".notbind") : "";
239
+ return session.text(".output", [pw]);
240
+ });
241
+ ctx.command("mahjongpub.team.stats").alias("!信息", "!信息", "!概况", "!概况").option("channel", "-c <channel:channel>").option("team", "-t <team:string>").userFields(["mahjongpub/bind-team", "mahjongpub/bind-teams"]).channelFields(["mahjongpub/bind-team", "mahjongpub/bind-contest", "mahjongpub/bind-contestpw"]).action(async ({ session, options }) => {
242
+ let pw = options.channel ? (await session.getChannel(parsePlatform(options.channel)[1], ["mahjongpub/bind-team"]))["mahjongpub/bind-team"] : session.isDirect ? session.user["mahjongpub/bind-team"] : session.channel["mahjongpub/bind-team"] ?? session.user["mahjongpub/bind-team"];
243
+ if (options.team) {
244
+ const [cid, cpw] = [session.channel["mahjongpub/bind-contest"], session.channel["mahjongpub/bind-contestpw"]];
245
+ if (!cid || !cpw) return session.text(".notbind");
246
+ const contest = await this.getContest(cid, cpw);
247
+ await contest.read();
248
+ pw = (contest.teams[options.team] ?? Object.values(contest.teams).find((t) => t.name === options.team))?.pw;
249
+ }
250
+ if (!pw) return config.informNotbind ? session.text(".notbind") : "";
251
+ const team = await this.getTeam(pw);
252
+ try {
253
+ await team.read();
254
+ return session.text(".output", team);
255
+ } catch (e) {
256
+ ctx.logger.warn(e);
257
+ return session.text(".failed");
258
+ }
259
+ });
260
+ ctx.command("mahjongpub.team.desc [desc:rawtext]").alias("!简介", "!简介").option("channel", "-c <channel:channel>").userFields(["mahjongpub/bind-team"]).channelFields(["mahjongpub/bind-team"]).action(async ({ session, options }, desc) => {
261
+ const pw = options.channel ? (await session.getChannel(parsePlatform(options.channel)[1], ["mahjongpub/bind-team"]))["mahjongpub/bind-team"] : session.isDirect ? session.user["mahjongpub/bind-team"] : session.channel["mahjongpub/bind-team"] ?? session.user["mahjongpub/bind-team"];
262
+ if (!pw) return config.informNotbind ? session.text(".notbind") : "";
263
+ const team = await this.getTeam(pw);
264
+ try {
265
+ await team.read();
266
+ if (!desc) return session.text(".output", team);
267
+ team.description = desc;
268
+ return await team.write();
269
+ } catch (e) {
270
+ ctx.logger.warn(e);
271
+ return session.text(".failed");
272
+ }
273
+ });
274
+ ctx.command("mahjongpub.team.logo [img:img]").alias("!头像", "!头像").option("channel", "-c <channel:channel>").userFields(["mahjongpub/bind-team"]).channelFields(["mahjongpub/bind-team"]).action(async ({ session, options }, img) => {
275
+ const pw = options.channel ? (await session.getChannel(parsePlatform(options.channel)[1], ["mahjongpub/bind-team"]))["mahjongpub/bind-team"] : session.isDirect ? session.user["mahjongpub/bind-team"] : session.channel["mahjongpub/bind-team"] ?? session.user["mahjongpub/bind-team"];
276
+ if (!pw) return config.informNotbind ? session.text(".notbind") : "";
277
+ const team = await this.getTeam(pw);
278
+ try {
279
+ await team.read();
280
+ if (!img) return import_koishi.h.image(team.img);
281
+ const url = await ctx.assets.upload("https://koishi.chat/logo.png", `${session.id}-${session.timestamp}.png`);
282
+ team.img = url;
283
+ return await team.write();
284
+ } catch (e) {
285
+ ctx.logger.warn(e);
286
+ return session.text(".failed");
287
+ }
288
+ });
289
+ ctx.command("mahjongpub.team.add <...users:string>", { authority: 3 }).alias("!添加", "!添加").option("channel", "-c <channel:channel>").option("team", "-t <team:string>").userFields(["mahjongpub/bind-team", "mahjongpub/bind-teams"]).channelFields(["mahjongpub/bind-team", "mahjongpub/bind-contest", "mahjongpub/bind-contestpw"]).action(async ({ session, options }, ...users) => {
290
+ let pw = options.channel ? (await session.getChannel(parsePlatform(options.channel)[1], ["mahjongpub/bind-team"]))["mahjongpub/bind-team"] : session.isDirect ? session.user["mahjongpub/bind-team"] : session.channel["mahjongpub/bind-team"] ?? session.user["mahjongpub/bind-team"];
291
+ if (options.team) {
292
+ const [cid, cpw] = [session.channel["mahjongpub/bind-contest"], session.channel["mahjongpub/bind-contestpw"]];
293
+ if (!cid || !cpw) return session.text(".notbind");
294
+ const contest = await this.getContest(cid, cpw);
295
+ await contest.read();
296
+ pw = (contest.teams[options.team] ?? Object.values(contest.teams).find((t) => t.name === options.team))?.pw;
297
+ }
298
+ if (!pw) return config.informNotbind ? session.text(".notbind") : "";
299
+ const team = await this.getTeam(pw);
300
+ try {
301
+ await team.read();
302
+ team.players.push(...users);
303
+ const msg = await team.write();
304
+ await team.read(true);
305
+ return msg + "\n" + session.text(".success", team);
306
+ } catch (e) {
307
+ ctx.logger.warn(e);
308
+ return session.text(".failed");
309
+ }
310
+ });
311
+ ctx.command("mahjongpub.team.remove <...indices:natural>", { authority: 3 }).alias("!删除", "!删除").option("channel", "-c <channel:channel>").option("team", "-t <team:string>").userFields(["mahjongpub/bind-team", "mahjongpub/bind-teams"]).channelFields(["mahjongpub/bind-team", "mahjongpub/bind-contest", "mahjongpub/bind-contestpw"]).action(async ({ session, options }, ...indices) => {
312
+ let pw = options.channel ? (await session.getChannel(parsePlatform(options.channel)[1], ["mahjongpub/bind-team"]))["mahjongpub/bind-team"] : session.isDirect ? session.user["mahjongpub/bind-team"] : session.channel["mahjongpub/bind-team"] ?? session.user["mahjongpub/bind-team"];
313
+ if (options.team) {
314
+ const [cid, cpw] = [session.channel["mahjongpub/bind-contest"], session.channel["mahjongpub/bind-contestpw"]];
315
+ if (!cid || !cpw) return session.text(".notbind");
316
+ const contest = await this.getContest(cid, cpw);
317
+ await contest.read();
318
+ pw = (contest.teams[options.team] ?? Object.values(contest.teams).find((t) => t.name === options.team))?.pw;
319
+ }
320
+ if (!pw) return config.informNotbind ? session.text(".notbind") : "";
321
+ const team = await this.getTeam(pw);
322
+ try {
323
+ await team.read();
324
+ team.players = team.players.filter((_, i) => !indices.includes(i + 1));
325
+ await team.write();
326
+ const msg = await team.write();
327
+ await team.read(true);
328
+ return msg + "\n" + session.text(".success", team);
329
+ } catch (e) {
330
+ ctx.logger.warn(e);
331
+ return session.text(".failed");
332
+ }
333
+ });
334
+ ctx.command("mahjongpub.team.swap <...indices:natural>", { authority: 3 }).alias("!交换", "!交换").option("channel", "-c <channel:channel>").option("team", "-t <team:string>").option("start", "-s <start:number>").option("end", "-e <end:number>").option("slim", "--slim").userFields(["mahjongpub/bind-team", "mahjongpub/bind-teams"]).channelFields(["mahjongpub/bind-team", "mahjongpub/bind-contest", "mahjongpub/bind-contestpw"]).action(async ({ session, options }, ...indices) => {
335
+ let pw = options.channel ? (await session.getChannel(parsePlatform(options.channel)[1], ["mahjongpub/bind-team"]))["mahjongpub/bind-team"] : session.isDirect ? session.user["mahjongpub/bind-team"] : session.channel["mahjongpub/bind-team"] ?? session.user["mahjongpub/bind-team"];
336
+ if (options.team) {
337
+ const [cid, cpw] = [session.channel["mahjongpub/bind-contest"], session.channel["mahjongpub/bind-contestpw"]];
338
+ if (!cid || !cpw) return session.text(".notbind");
339
+ const contest = await this.getContest(cid, cpw);
340
+ await contest.read();
341
+ pw = (contest.teams[options.team] ?? Object.values(contest.teams).find((t) => t.name === options.team))?.pw;
342
+ } else if (options.start && options.end) {
343
+ if (options.end - options.start > 100) return session.text(".wide-range");
344
+ const msg = [];
345
+ for (let tid = options.start; tid <= options.end; tid++) {
346
+ msg.push(await session.execute({
347
+ name: "mahjongpub.team.swap",
348
+ args: indices,
349
+ options: {
350
+ channel: options.channel,
351
+ team: `${tid}`,
352
+ slim: true
332
353
  }
354
+ }, true));
355
+ if (msg.length >= config.batchCount) await session.send(msg.splice(0).join("\n"));
356
+ await ctx.sleep(config.batchInterval);
357
+ }
358
+ return msg.length ? msg.join("\n") : "";
359
+ }
360
+ if (!pw) return config.informNotbind ? session.text(".notbind") : "";
361
+ if (!indices.length || indices.length % 2 !== 0) return session.text(".invalid");
362
+ const team = await this.getTeam(pw);
363
+ try {
364
+ await team.read();
365
+ for (let i = 0; i < indices.length; i += 2) {
366
+ const t = team.players[indices[i] - 1];
367
+ team.players[indices[i] - 1] = team.players[indices[i + 1] - 1];
368
+ team.players[indices[i + 1] - 1] = t;
369
+ }
370
+ const msg = await team.write();
371
+ await team.read(true);
372
+ if (options.slim) return `[${team.tid} ${team.name}] ${msg} ` + indices.map((i) => `${i}. ${team.players[i - 1]}`).join(" ");
373
+ else return msg + "\n" + session.text(".success", team);
374
+ } catch (e) {
375
+ ctx.logger.warn(e);
376
+ return session.text(".failed");
377
+ }
378
+ });
379
+ ctx.command("mahjongpub.contest.bind <cid:string> <cpw:string>", { authority: 4 }).option("channel", "-c <channel:channel>").channelFields(["mahjongpub/bind-contest", "mahjongpub/bind-contestpw"]).action(async ({ session, options }, cid, cpw) => {
380
+ const contest = await this.getContest(cid, cpw);
381
+ try {
382
+ await contest.read();
383
+ } catch (e) {
384
+ ctx.logger.warn(e);
385
+ return session.text(".failed");
386
+ }
387
+ if (options.channel) {
388
+ ctx.database.setChannel(...parsePlatform(options.channel), {
389
+ "mahjongpub/bind-contest": cid,
390
+ "mahjongpub/bind-contestpw": cpw
333
391
  });
334
- ctx.command('mahjongpub.contest.record.update <round:natural> <cls:natural> <...points:integer>', { authority: 3 })
335
- .option('rowi', '-i <rowi:integer>', { fallback: -1 })
336
- .channelFields(['mahjongpub/bind-contest', 'mahjongpub/bind-contestpw'])
337
- .action(async ({ session, options }, round, cls, ...points) => {
338
- const [cid, cpw] = [session.channel['mahjongpub/bind-contest'], session.channel['mahjongpub/bind-contestpw']];
339
- const contest = await this.getContest(cid, cpw);
340
- try {
341
- await contest.read();
342
- const record = await contest.getRoundRecord(round, cls);
343
- record.matches.at(options.rowi).players.forEach((x, i) => {
344
- x.point = points[i];
345
- x.score = x.point - (options.rowi === 0 ? +contest.raw.c_admin.c_s_po : record.matches.at(options.rowi - 1).players[i].point);
346
- });
347
- return await contest.updateRoundRecord(record);
348
- }
349
- catch (e) {
350
- ctx.logger.warn(e);
351
- return session.text('.failed');
352
- }
392
+ } else {
393
+ session.channel["mahjongpub/bind-contest"] = cid;
394
+ session.channel["mahjongpub/bind-contestpw"] = cpw;
395
+ }
396
+ return session.text(".success", contest);
397
+ });
398
+ ctx.command("mahjongpub.contest.record.get <round:natural> <cls:natural>", { authority: 3 }).option("rowi", "-i <rowi:integer>").channelFields(["mahjongpub/bind-contest", "mahjongpub/bind-contestpw"]).action(async ({ session, options }, round, cls) => {
399
+ const [cid, cpw] = [session.channel["mahjongpub/bind-contest"], session.channel["mahjongpub/bind-contestpw"]];
400
+ const contest = await this.getContest(cid, cpw);
401
+ try {
402
+ const record = await contest.getRoundRecord(round, cls);
403
+ if ((0, import_koishi.isNullable)(options.rowi)) {
404
+ return record.matches.map((match, i) => `[${i}] ` + match.players.map((x) => `${x.name} ${x.point}`).join(" / ")).join("\n");
405
+ } else {
406
+ return [
407
+ `[${options.rowi === -1 ? record.matches.length - 1 : options.rowi}]`,
408
+ record.matches.at(options.rowi ?? -1).players.map((x) => `${x.name} ${x.point}`).join(" / ")
409
+ ].join(" ");
410
+ }
411
+ } catch (e) {
412
+ ctx.logger.warn(e);
413
+ return session.text(".failed");
414
+ }
415
+ });
416
+ ctx.command("mahjongpub.contest.record.update <round:natural> <cls:natural> <...points:integer>", { authority: 3 }).option("rowi", "-i <rowi:integer>", { fallback: -1 }).channelFields(["mahjongpub/bind-contest", "mahjongpub/bind-contestpw"]).action(async ({ session, options }, round, cls, ...points) => {
417
+ const [cid, cpw] = [session.channel["mahjongpub/bind-contest"], session.channel["mahjongpub/bind-contestpw"]];
418
+ const contest = await this.getContest(cid, cpw);
419
+ try {
420
+ await contest.read();
421
+ const record = await contest.getRoundRecord(round, cls);
422
+ record.matches.at(options.rowi).players.forEach((x, i) => {
423
+ x.point = points[i];
424
+ x.score = x.point - (options.rowi === 0 ? +contest.raw.c_admin.c_s_po : record.matches.at(options.rowi - 1).players[i].point);
353
425
  });
354
- if (ctx.get('mahjong.database')) {
355
- ctx.command('mahjongpub.database.record.get <round:natural> <cls:natural>', { authority: 3 })
356
- .option('rowi', '-i <rowi:integer>', { fallback: 9 })
357
- .option('ver', '-v <ver:integer>', { fallback: 0 })
358
- .channelFields(['mahjongpub/bind-contest'])
359
- .action(async ({ session, options }, round, cls) => {
360
- const [cid] = [session.channel['mahjongpub/bind-contest']];
361
- try {
362
- const record = await ctx.mahjong.database.db('scoreboard').collection('matches').findOne({
363
- cid,
364
- cls,
365
- round,
366
- rowi: options.rowi,
367
- ver: options.ver,
368
- });
369
- if (!record)
370
- return session.text('.failed');
371
- return `[${options.rowi}] ` + record.results.map((x) => `${x.name} ${x.num}`).join(' / ');
372
- }
373
- catch (e) {
374
- ctx.logger.warn(e);
375
- return session.text('.failed');
376
- }
377
- });
378
- ctx.command('mahjongpub.database.record.update <round:natural> <cls:natural> <...points:integer>', { authority: 4 })
379
- .option('rowi', '-i <rowi:integer>', { fallback: 9 })
380
- .option('ver', '-v <ver:integer>', { fallback: 0 })
381
- .channelFields(['mahjongpub/bind-contest'])
382
- .action(async ({ session, options }, round, cls, ...points) => {
383
- const [cid] = [session.channel['mahjongpub/bind-contest']];
384
- try {
385
- const res = await ctx.mahjong.database.db('scoreboard').collection('matches').updateOne({
386
- cid,
387
- cls,
388
- round,
389
- rowi: options.rowi,
390
- ver: options.ver,
391
- }, {
392
- $set: Object.fromEntries(points.map((p, i) => [`results.${i}.num`, p])),
393
- });
394
- return res.modifiedCount ? session.text('.success') : res.matchedCount ? session.text('.unmodified') : session.text('.failed');
395
- }
396
- catch (e) {
397
- ctx.logger.warn(e);
398
- return session.text('.failed');
399
- }
400
- });
401
- ctx.command('mahjongpub.admin.record.get <round:natural> <cls:natural>', { authority: 3 })
402
- .option('rowi', '-i <rowi:integer>', { fallback: 9 })
403
- .option('ver', '-v <ver:integer>', { fallback: 0 })
404
- .action(async ({ session, options }, round, cls) => {
405
- const msg = [];
406
- msg.push('- Mahjongpub');
407
- msg.push(await session.execute({
408
- name: 'mahjongpub.contest.record.get',
409
- args: [round, cls],
410
- options,
411
- }, true));
412
- msg.push('- Database');
413
- msg.push(await session.execute({
414
- name: 'mahjongpub.database.record.get',
415
- args: [round, cls],
416
- options,
417
- }, true));
418
- return msg.join('\n');
419
- });
426
+ return await contest.updateRoundRecord(record);
427
+ } catch (e) {
428
+ ctx.logger.warn(e);
429
+ return session.text(".failed");
430
+ }
431
+ });
432
+ if (ctx.get("mahjong.database")) {
433
+ ctx.command("mahjongpub.database.record.get <round:natural> <cls:natural>", { authority: 3 }).option("rowi", "-i <rowi:integer>", { fallback: -1 }).option("ver", "-v <ver:integer>", { fallback: 0 }).channelFields(["mahjongpub/bind-contest"]).action(async ({ session, options }, round, cls) => {
434
+ const [cid] = [session.channel["mahjongpub/bind-contest"]];
435
+ try {
436
+ const record = await ctx.mahjong.database.db("scoreboard").collection("matches").find({
437
+ cid,
438
+ cls,
439
+ round,
440
+ ver: options.ver,
441
+ ...options.rowi === -1 ? {} : { rowi: options.rowi }
442
+ }).sort({ rowi: -1 }).toArray();
443
+ if (!record.length) return session.text(".failed");
444
+ return record.map((r) => `[${r.rowi}] ` + r.results.map((x) => `${x.name} ${x.num}`).join(" / ")).join("\n");
445
+ } catch (e) {
446
+ ctx.logger.warn(e);
447
+ return session.text(".failed");
420
448
  }
421
- }
422
- async getTeam(pw) {
423
- // if (this.ctx.get('cache')) {
424
- // let res = await this.ctx.cache.get('teams', pw)
425
- // if (res) return res
426
- // res = new TeamAdmin(this.ctx, pw, this.config)
427
- // await this.ctx.cache.set('teams', pw, res, 1000 * 60)
428
- // return res
429
- // }
430
- return new api_1.TeamAdmin(this.ctx, pw, this.config);
431
- }
432
- async getContest(cid, pw) {
433
- if (this.ctx.get('cache')) {
434
- let res = await this.ctx.cache.get('contests', cid);
435
- if (res)
436
- return res;
437
- res = new api_1.ContestAdmin(this.ctx, cid, pw, this.config);
438
- await res.read();
439
- await this.ctx.cache.set('contests', cid, res, 1000 * 600);
440
- return res;
449
+ });
450
+ ctx.command("mahjongpub.database.record.update <round:natural> <cls:natural> <...points:integer>", { authority: 4 }).option("rowi", "-i <rowi:integer>", { fallback: 9 }).option("ver", "-v <ver:integer>", { fallback: 0 }).channelFields(["mahjongpub/bind-contest"]).action(async ({ session, options }, round, cls, ...points) => {
451
+ const [cid] = [session.channel["mahjongpub/bind-contest"]];
452
+ try {
453
+ const res = await ctx.mahjong.database.db("scoreboard").collection("matches").updateOne({
454
+ cid,
455
+ cls,
456
+ round,
457
+ rowi: options.rowi,
458
+ ver: options.ver
459
+ }, {
460
+ $set: Object.fromEntries(points.map((p, i) => [`results.${i}.num`, p]))
461
+ });
462
+ return res.modifiedCount ? session.text(".success") : res.matchedCount ? session.text(".unmodified") : session.text(".failed");
463
+ } catch (e) {
464
+ ctx.logger.warn(e);
465
+ return session.text(".failed");
441
466
  }
442
- const res = new api_1.ContestAdmin(this.ctx, cid, pw, this.config);
443
- await res.read();
444
- return res;
467
+ });
468
+ ctx.command("mahjongpub.admin.record.get <round:natural> <cls:natural>", { authority: 3 }).option("rowi", "-i <rowi:integer>", { fallback: 9 }).option("ver", "-v <ver:integer>", { fallback: 0 }).action(async ({ session, options }, round, cls) => {
469
+ const msg = [];
470
+ msg.push("- Mahjongpub");
471
+ msg.push(await session.execute({
472
+ name: "mahjongpub.contest.record.get",
473
+ args: [round, cls],
474
+ options
475
+ }, true));
476
+ msg.push("- Database");
477
+ msg.push(await session.execute({
478
+ name: "mahjongpub.database.record.get",
479
+ args: [round, cls],
480
+ options
481
+ }, true));
482
+ return msg.join("\n");
483
+ });
484
+ ctx.command("mahjongpub.admin.record.update <round:natural> <cls:natural> <...points:integer>", { authority: 4 }).option("rowi", "-i <rowi:integer>", { fallback: 9 }).option("ver", "-v <ver:integer>", { fallback: 0 }).action(async ({ session, options }, round, cls, ...points) => {
485
+ const msg = [];
486
+ msg.push("- Mahjongpub");
487
+ msg.push(await session.execute({
488
+ name: "mahjongpub.contest.record.update",
489
+ args: [round, cls, ...points],
490
+ options
491
+ }, true));
492
+ msg.push(await session.execute({
493
+ name: "mahjongpub.contest.record.update",
494
+ args: [round, cls, ...points],
495
+ options
496
+ }, true));
497
+ msg.push("- Database");
498
+ msg.push(await session.execute({
499
+ name: "mahjongpub.database.record.get",
500
+ args: [round, cls, ...points],
501
+ options
502
+ }, true));
503
+ msg.push(await session.execute({
504
+ name: "mahjongpub.database.record.get",
505
+ args: [round, cls, ...points],
506
+ options
507
+ }, true));
508
+ return msg.join("\n");
509
+ });
445
510
  }
446
- }
447
- exports.MahjongPub = MahjongPub;
448
- (function (MahjongPub) {
449
- MahjongPub.inject = {
450
- required: ['database'],
451
- optional: ['assets', 'cache', 'mahjong', 'mahjong.database'],
452
- };
453
- MahjongPub.Config = koishi_1.Schema.object({
454
- informNotbind: koishi_1.Schema.boolean().default(false),
455
- endpoint: koishi_1.Schema.string().default('https://cdn.r-mj.com/'),
456
- batchInterval: koishi_1.Schema.natural().default(300),
457
- batchCount: koishi_1.Schema.natural().default(10),
458
- });
459
- })(MahjongPub || (exports.MahjongPub = MahjongPub = {}));
460
- exports.default = MahjongPub;
511
+ }
512
+ static {
513
+ __name(this, "MahjongPub");
514
+ }
515
+ teams = {};
516
+ contests = {};
517
+ async getTeam(pw) {
518
+ return new TeamAdmin(this.ctx, pw, this.config);
519
+ }
520
+ async getContest(cid, pw) {
521
+ if (this.ctx.get("cache")) {
522
+ let res2 = await this.ctx.cache.get("contests", cid);
523
+ if (res2) return res2;
524
+ res2 = new ContestAdmin(this.ctx, cid, pw, this.config);
525
+ await res2.read();
526
+ await this.ctx.cache.set("contests", cid, res2, 1e3 * 600);
527
+ return res2;
528
+ }
529
+ const res = new ContestAdmin(this.ctx, cid, pw, this.config);
530
+ await res.read();
531
+ return res;
532
+ }
533
+ };
534
+ ((MahjongPub2) => {
535
+ MahjongPub2.inject = {
536
+ required: ["database"],
537
+ optional: ["assets", "cache", "mahjong", "mahjong.database"]
538
+ };
539
+ MahjongPub2.Config = import_koishi.Schema.object({
540
+ informNotbind: import_koishi.Schema.boolean().default(false),
541
+ endpoint: import_koishi.Schema.string().default("https://cdn.r-mj.com/"),
542
+ batchInterval: import_koishi.Schema.natural().default(300),
543
+ batchCount: import_koishi.Schema.natural().default(10)
544
+ });
545
+ })(MahjongPub || (MahjongPub = {}));
546
+ var src_default = MahjongPub;
547
+ // Annotate the CommonJS export names for ESM import in node:
548
+ 0 && (module.exports = {
549
+ MahjongPub
550
+ });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hieuzest/koishi-plugin-mahjongpub",
3
3
  "description": "Mahjong.pub API",
4
- "version": "0.1.18",
4
+ "version": "0.1.20",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [