@hieuzest/koishi-plugin-mahjongpub 0.1.13 → 0.1.15
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/api.d.ts +55 -0
- package/lib/api.js +62 -0
- package/lib/index.js +50 -9
- package/lib/locales/zh-CN.json +1 -1
- package/package.json +1 -1
package/lib/api.d.ts
CHANGED
|
@@ -26,6 +26,24 @@ export declare class TeamAdmin implements Team {
|
|
|
26
26
|
read(force?: boolean): Promise<void>;
|
|
27
27
|
write(): Promise<any>;
|
|
28
28
|
}
|
|
29
|
+
declare namespace TeamAdmin {
|
|
30
|
+
interface Payload {
|
|
31
|
+
tid: string;
|
|
32
|
+
t_name: string;
|
|
33
|
+
t_player?: string;
|
|
34
|
+
t_sub?: string;
|
|
35
|
+
t_pw: string;
|
|
36
|
+
t_join_time?: string;
|
|
37
|
+
t_join_ip?: string;
|
|
38
|
+
t_type?: string;
|
|
39
|
+
t_ps?: string;
|
|
40
|
+
cid: string;
|
|
41
|
+
qq?: string;
|
|
42
|
+
ls_ip?: string;
|
|
43
|
+
ls_time?: string;
|
|
44
|
+
img?: string;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
29
47
|
export declare class ContestAdmin {
|
|
30
48
|
cid: string;
|
|
31
49
|
pw: string;
|
|
@@ -35,8 +53,45 @@ export declare class ContestAdmin {
|
|
|
35
53
|
name: string;
|
|
36
54
|
teams: Dict<Team>;
|
|
37
55
|
http: Quester;
|
|
56
|
+
raw?: ContestAdmin.Payload;
|
|
38
57
|
constructor(ctx: Context, cid: string, pw: string, options: {
|
|
39
58
|
endpoint: string;
|
|
40
59
|
});
|
|
41
60
|
read(force?: boolean): Promise<void>;
|
|
61
|
+
getRoundRecord(round: number, cls: number): Promise<ContestAdmin.MatchRoundRecord>;
|
|
62
|
+
updateRoundRecord(record: ContestAdmin.MatchRoundRecord): Promise<string>;
|
|
63
|
+
}
|
|
64
|
+
declare namespace ContestAdmin {
|
|
65
|
+
interface Payload {
|
|
66
|
+
c_admin: {
|
|
67
|
+
c_name: string;
|
|
68
|
+
c_gonggao: string;
|
|
69
|
+
c_pad: string;
|
|
70
|
+
c_round: string;
|
|
71
|
+
c_s_po: string;
|
|
72
|
+
c_sub_t: string;
|
|
73
|
+
cid: string;
|
|
74
|
+
r_type: string;
|
|
75
|
+
t_max: string;
|
|
76
|
+
t_sub: string;
|
|
77
|
+
t_type: string;
|
|
78
|
+
};
|
|
79
|
+
c_team: TeamAdmin.Payload[];
|
|
80
|
+
}
|
|
81
|
+
interface MatchPlayerRecord {
|
|
82
|
+
name: string;
|
|
83
|
+
score: number;
|
|
84
|
+
point: number;
|
|
85
|
+
}
|
|
86
|
+
interface MatchRecord {
|
|
87
|
+
players: MatchPlayerRecord[];
|
|
88
|
+
logurl: string;
|
|
89
|
+
}
|
|
90
|
+
interface MatchRoundRecord {
|
|
91
|
+
cid: string;
|
|
92
|
+
cls: number;
|
|
93
|
+
rnd: number;
|
|
94
|
+
matches: MatchRecord[];
|
|
95
|
+
}
|
|
42
96
|
}
|
|
97
|
+
export {};
|
package/lib/api.js
CHANGED
|
@@ -62,6 +62,7 @@ class ContestAdmin {
|
|
|
62
62
|
name;
|
|
63
63
|
teams;
|
|
64
64
|
http;
|
|
65
|
+
raw;
|
|
65
66
|
constructor(ctx, cid, pw, options) {
|
|
66
67
|
this.cid = cid;
|
|
67
68
|
this.pw = pw;
|
|
@@ -85,6 +86,7 @@ class ContestAdmin {
|
|
|
85
86
|
});
|
|
86
87
|
if (!data?.c_admin?.cid)
|
|
87
88
|
throw new Error('failed to read contest info');
|
|
89
|
+
this.raw = data;
|
|
88
90
|
this.name = data.c_admin.c_name;
|
|
89
91
|
this.teams = Object.fromEntries(data.c_team.map(team => [team.tid, {
|
|
90
92
|
tid: team.tid,
|
|
@@ -95,6 +97,66 @@ class ContestAdmin {
|
|
|
95
97
|
pw: team.t_pw,
|
|
96
98
|
}]));
|
|
97
99
|
}
|
|
100
|
+
async getRoundRecord(round, cls) {
|
|
101
|
+
const payload = {
|
|
102
|
+
type: 'login',
|
|
103
|
+
cid: this.cid,
|
|
104
|
+
cls: String(cls),
|
|
105
|
+
rnd: String(round),
|
|
106
|
+
};
|
|
107
|
+
const form = new FormData();
|
|
108
|
+
Object.entries(payload).forEach(([key, value]) => form.append(key, value));
|
|
109
|
+
const data = await this.http.post('/edit_class_json.php', form, {
|
|
110
|
+
responseType: 'json',
|
|
111
|
+
});
|
|
112
|
+
if (data.status !== '2')
|
|
113
|
+
throw new Error(`failed to get round record with status ${data.status}`);
|
|
114
|
+
const record = {
|
|
115
|
+
cid: this.cid,
|
|
116
|
+
cls,
|
|
117
|
+
rnd: round,
|
|
118
|
+
matches: data.data.map(x => {
|
|
119
|
+
const players = [];
|
|
120
|
+
for (let i = 0; i < x.length - 1; i += 3) {
|
|
121
|
+
players.push({
|
|
122
|
+
name: x[i],
|
|
123
|
+
point: +x[i + 1],
|
|
124
|
+
score: +x[i + 2],
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
players,
|
|
129
|
+
logurl: x[x.length - 1],
|
|
130
|
+
};
|
|
131
|
+
}),
|
|
132
|
+
};
|
|
133
|
+
return record;
|
|
134
|
+
}
|
|
135
|
+
async updateRoundRecord(record) {
|
|
136
|
+
const payload = {
|
|
137
|
+
type: 'update',
|
|
138
|
+
cid: this.cid,
|
|
139
|
+
cls: String(record.cls),
|
|
140
|
+
rnd: String(record.rnd),
|
|
141
|
+
pw: this.pw,
|
|
142
|
+
};
|
|
143
|
+
const form = new FormData();
|
|
144
|
+
Object.entries(payload).forEach(([key, value]) => form.append(key, value));
|
|
145
|
+
record.matches.forEach(match => {
|
|
146
|
+
match.players.forEach((player, i) => {
|
|
147
|
+
form.append(`name${i + 1}[]`, player.name);
|
|
148
|
+
form.append(`point${i + 1}[]`, String(player.point));
|
|
149
|
+
form.append(`score${i + 1}[]`, String(player.score));
|
|
150
|
+
});
|
|
151
|
+
form.append(`logurl[]`, match.logurl);
|
|
152
|
+
});
|
|
153
|
+
const data = await this.http.post('/edit_class_json.php', form, {
|
|
154
|
+
responseType: 'json',
|
|
155
|
+
});
|
|
156
|
+
if (data.status !== '2')
|
|
157
|
+
throw new Error(`failed to update round record with status ${data.status}`);
|
|
158
|
+
return data.data;
|
|
159
|
+
}
|
|
98
160
|
}
|
|
99
161
|
exports.ContestAdmin = ContestAdmin;
|
|
100
162
|
// namespace Contest {
|
package/lib/index.js
CHANGED
|
@@ -79,18 +79,15 @@ class MahjongPub {
|
|
|
79
79
|
return config.informNotbind ? session.text('.notbind') : '';
|
|
80
80
|
return session.text('.output', [pw]);
|
|
81
81
|
});
|
|
82
|
-
ctx.command('mahjongpub.team.stats
|
|
82
|
+
ctx.command('mahjongpub.team.stats')
|
|
83
83
|
.alias('!信息', '!信息', '!概况', '!概况')
|
|
84
84
|
.option('channel', '-c <channel:channel>')
|
|
85
85
|
.option('team', '-t <team:string>')
|
|
86
86
|
.userFields(['mahjongpub/bind-team', 'mahjongpub/bind-teams'])
|
|
87
87
|
.channelFields(['mahjongpub/bind-team', 'mahjongpub/bind-contest', 'mahjongpub/bind-contestpw'])
|
|
88
|
-
.action(async ({ session, options }
|
|
88
|
+
.action(async ({ session, options }) => {
|
|
89
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']
|
|
91
|
-
: session.channel['mahjongpub/bind-contest']
|
|
92
|
-
? (user ? session.user['mahjongpub/bind-teams'][session.channel['mahjongpub/bind-contest']] : session.user['mahjongpub/bind-team'])
|
|
93
|
-
: session.channel['mahjongpub/bind-team'] ?? session.user['mahjongpub/bind-team'];
|
|
90
|
+
: session.isDirect ? session.user['mahjongpub/bind-team'] : session.channel['mahjongpub/bind-team'] ?? session.user['mahjongpub/bind-team'];
|
|
94
91
|
if (options.team) {
|
|
95
92
|
const [cid, cpw] = [session.channel['mahjongpub/bind-contest'], session.channel['mahjongpub/bind-contestpw']];
|
|
96
93
|
if (!cid || !cpw)
|
|
@@ -287,8 +284,7 @@ class MahjongPub {
|
|
|
287
284
|
return session.text('.failed');
|
|
288
285
|
}
|
|
289
286
|
});
|
|
290
|
-
ctx.command('mahjongpub.contest.bind <cid:string> <cpw:string>')
|
|
291
|
-
// .alias('!绑定', '!绑定')
|
|
287
|
+
ctx.command('mahjongpub.contest.bind <cid:string> <cpw:string>', { authority: 4 })
|
|
292
288
|
.option('channel', '-c <channel:channel>')
|
|
293
289
|
.channelFields(['mahjongpub/bind-contest', 'mahjongpub/bind-contestpw'])
|
|
294
290
|
.action(async ({ session, options }, cid, cpw) => {
|
|
@@ -312,6 +308,49 @@ class MahjongPub {
|
|
|
312
308
|
}
|
|
313
309
|
return session.text('.success', contest);
|
|
314
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');
|
|
332
|
+
}
|
|
333
|
+
});
|
|
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
|
+
}
|
|
353
|
+
});
|
|
315
354
|
}
|
|
316
355
|
async getTeam(pw) {
|
|
317
356
|
// if (this.ctx.get('cache')) {
|
|
@@ -333,7 +372,9 @@ class MahjongPub {
|
|
|
333
372
|
await this.ctx.cache.set('contests', cid, res, 1000 * 600);
|
|
334
373
|
return res;
|
|
335
374
|
}
|
|
336
|
-
|
|
375
|
+
const res = new api_1.ContestAdmin(this.ctx, cid, pw, this.config);
|
|
376
|
+
await res.read();
|
|
377
|
+
return res;
|
|
337
378
|
}
|
|
338
379
|
}
|
|
339
380
|
exports.MahjongPub = MahjongPub;
|
package/lib/locales/zh-CN.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"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}"}}}}
|
|
1
|
+
{"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":"修改失败"}}}}
|