@hieuzest/koishi-plugin-mahjongpub 0.2.1 → 0.2.3
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 +2 -0
- package/lib/index.js +62 -27
- package/lib/manager.d.ts +5 -0
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Context, Dict, Schema, Service } from 'koishi';
|
|
2
2
|
import { ContestAdmin, TeamAdmin } from './api';
|
|
3
|
+
import { ContestManager } from './manager';
|
|
3
4
|
declare module 'koishi' {
|
|
4
5
|
interface Context {
|
|
5
6
|
mahjongpub: MahjongPub;
|
|
@@ -39,6 +40,7 @@ export declare namespace MahjongPub {
|
|
|
39
40
|
endpoint: string;
|
|
40
41
|
batchInterval: number;
|
|
41
42
|
batchCount: number;
|
|
43
|
+
manager: ContestManager.Config;
|
|
42
44
|
}
|
|
43
45
|
const Config: Schema<Config>;
|
|
44
46
|
}
|
package/lib/index.js
CHANGED
|
@@ -261,7 +261,8 @@ var MahjongPub = class _MahjongPub {
|
|
|
261
261
|
params: {
|
|
262
262
|
t: "admin",
|
|
263
263
|
cid
|
|
264
|
-
}
|
|
264
|
+
},
|
|
265
|
+
responseType: "json"
|
|
265
266
|
});
|
|
266
267
|
}
|
|
267
268
|
async getTeams(cid) {
|
|
@@ -269,7 +270,8 @@ var MahjongPub = class _MahjongPub {
|
|
|
269
270
|
params: {
|
|
270
271
|
t: "team",
|
|
271
272
|
cid
|
|
272
|
-
}
|
|
273
|
+
},
|
|
274
|
+
responseType: "json"
|
|
273
275
|
}).then((teams) => (0, import_koishi.mapValues)(teams, (team) => ({
|
|
274
276
|
...team,
|
|
275
277
|
players: [...team.t_player?.split(/\s+/) ?? [], ...team.t_sub?.split(/\s+/) ?? []]
|
|
@@ -280,11 +282,14 @@ var MahjongPub = class _MahjongPub {
|
|
|
280
282
|
params: {
|
|
281
283
|
t: "class",
|
|
282
284
|
cid
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
285
|
+
},
|
|
286
|
+
responseType: "json"
|
|
287
|
+
}).then((rounds) => {
|
|
288
|
+
return rounds.map((round) => [round.rid, {
|
|
289
|
+
...round,
|
|
290
|
+
tids: [round.tid1, round.tid2, round.tid3, round.tid4]
|
|
291
|
+
}]);
|
|
292
|
+
}));
|
|
288
293
|
}
|
|
289
294
|
async getMatches(cid, round) {
|
|
290
295
|
return await this.http.get(`${this.serverUri}/api/data.php`, {
|
|
@@ -292,7 +297,8 @@ var MahjongPub = class _MahjongPub {
|
|
|
292
297
|
t: "c_data",
|
|
293
298
|
cid,
|
|
294
299
|
r: round
|
|
295
|
-
}
|
|
300
|
+
},
|
|
301
|
+
responseType: "json"
|
|
296
302
|
});
|
|
297
303
|
}
|
|
298
304
|
async getAllMatches(cid) {
|
|
@@ -302,7 +308,8 @@ var MahjongPub = class _MahjongPub {
|
|
|
302
308
|
t: "multi_log",
|
|
303
309
|
cid,
|
|
304
310
|
r: [...Array(contest.c_round).keys()].map((x) => x + 1).map((x) => x.toString()).join(",")
|
|
305
|
-
}
|
|
311
|
+
},
|
|
312
|
+
responseType: "json"
|
|
306
313
|
});
|
|
307
314
|
}
|
|
308
315
|
static cacheOptions = {
|
|
@@ -340,7 +347,7 @@ var ContestExtra = class {
|
|
|
340
347
|
subscribers;
|
|
341
348
|
stopCls;
|
|
342
349
|
async broadcast(msg) {
|
|
343
|
-
this.subscribers.forEach((channel) => this.ctx.sendMessage(channel, msg).catch(
|
|
350
|
+
this.subscribers.forEach((channel) => this.ctx.sendMessage(channel, msg).catch((e) => this.ctx.logger.debug(e)));
|
|
344
351
|
}
|
|
345
352
|
};
|
|
346
353
|
var ContestManager = class {
|
|
@@ -348,8 +355,8 @@ var ContestManager = class {
|
|
|
348
355
|
this.ctx = ctx;
|
|
349
356
|
this.config = config;
|
|
350
357
|
this.mahjongpub = MahjongPub.new(ctx);
|
|
351
|
-
ctx.command("
|
|
352
|
-
ctx.command("
|
|
358
|
+
ctx.command("mahjongpub.manager", { authority: 3 }).action(import_koishi2.noop);
|
|
359
|
+
ctx.command("mahjongpub.manager.init").channelFields(["mahjongpub/bind-contest"]).option("clear", "-c").action(async ({ session, options }) => {
|
|
353
360
|
const cid = +(session.channel["mahjongpub/bind-contest"] || 0);
|
|
354
361
|
if (!cid) return "Unauthorized.";
|
|
355
362
|
this.extra[cid] ??= new ContestExtra(ctx);
|
|
@@ -357,7 +364,14 @@ var ContestManager = class {
|
|
|
357
364
|
if (options.clear) this.extra[cid].stopCls.clear();
|
|
358
365
|
return "Finished.";
|
|
359
366
|
});
|
|
360
|
-
ctx.command("
|
|
367
|
+
ctx.command("mahjongpub.manager.deinit").channelFields(["mahjongpub/bind-contest"]).option("clear", "-c").action(async ({ session, options }) => {
|
|
368
|
+
const cid = +(session.channel["mahjongpub/bind-contest"] || 0);
|
|
369
|
+
if (!cid) return "Unauthorized.";
|
|
370
|
+
this.extra[cid] ??= new ContestExtra(ctx);
|
|
371
|
+
this.extra[cid].subscribers.delete(session.cid);
|
|
372
|
+
return "Finished.";
|
|
373
|
+
});
|
|
374
|
+
ctx.command("mahjongpub.manager.start [cls:number]").channelFields(["mahjongpub/bind-contest"]).action(async ({ session }, cls) => {
|
|
361
375
|
const cid = +(session.channel["mahjongpub/bind-contest"] || 0);
|
|
362
376
|
if (!cid) return "Unauthorized.";
|
|
363
377
|
this.extra[cid] ??= new ContestExtra(ctx);
|
|
@@ -372,11 +386,11 @@ var ContestManager = class {
|
|
|
372
386
|
for (const r of Object.values(rounds)) {
|
|
373
387
|
if (r.round !== contest.c_round) continue;
|
|
374
388
|
await this.startMatch(cid, r.t_class);
|
|
375
|
-
await (0, import_koishi2.sleep)(
|
|
389
|
+
await (0, import_koishi2.sleep)(config.startInterval);
|
|
376
390
|
}
|
|
377
391
|
}
|
|
378
392
|
});
|
|
379
|
-
ctx.command("
|
|
393
|
+
ctx.command("mahjongpub.manager.stop [cls:number]").channelFields(["mahjongpub/bind-contest"]).action(async ({ session }, cls) => {
|
|
380
394
|
const cid = +(session.channel["mahjongpub/bind-contest"] || 0);
|
|
381
395
|
if (!cid) return "Unauthorized/";
|
|
382
396
|
this.extra[cid] ??= new ContestExtra(ctx);
|
|
@@ -405,12 +419,12 @@ var ContestManager = class {
|
|
|
405
419
|
static {
|
|
406
420
|
__name(this, "ContestManager");
|
|
407
421
|
}
|
|
408
|
-
static inject = ["server", "mahjong", "mahjong.database", "mahjongpub", "sendMessage"];
|
|
422
|
+
static inject = ["server", "mahjong", "mahjong.database", "mahjongpub", "sendMessage", "zx-dhs"];
|
|
409
423
|
mahjongpub;
|
|
410
424
|
extra = /* @__PURE__ */ Object.create(null);
|
|
411
|
-
async
|
|
425
|
+
async _startMatch(cid, cls, timeout = 0, tag) {
|
|
412
426
|
tag ||= `${cls}组`;
|
|
413
|
-
if (this.extra[cid]?.stopCls.has(cls)) {
|
|
427
|
+
if (!this.extra[cid] || this.extra[cid]?.stopCls.has(cls)) {
|
|
414
428
|
this.ctx.logger.info(`try starting match ${cid}-${cls}, but stopped`);
|
|
415
429
|
return;
|
|
416
430
|
}
|
|
@@ -429,29 +443,49 @@ var ContestManager = class {
|
|
|
429
443
|
}
|
|
430
444
|
const rowi = lastRecord ? lastRecord.rowi + 1 : 0;
|
|
431
445
|
const round = Object.values(rounds).find((x) => x.round === contest.c_round && x.t_class === cls);
|
|
432
|
-
const players = round.tids.map((tid) => teams[tid].players[rowi]);
|
|
446
|
+
const players = round.tids.map((tid) => teams[tid].players[Math.floor(rowi / 2)]);
|
|
447
|
+
if (!players.every((x) => x)) {
|
|
448
|
+
this.extra[cid]?.broadcast(`[${tag}] 失败: 名单未填写`);
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
433
451
|
try {
|
|
452
|
+
this.ctx.logger.info(`starting match ${cid}-${cls}, players ${players.map((x, i) => `${x} ${lastRecord ? lastRecord.results?.[i].num : 1e5}`).join(", ")}`);
|
|
434
453
|
await this.ctx["zx-dhs"].startMatch(+round.code, players.map((x, i) => import_lobby.Player.fromPattern(x, lastRecord ? lastRecord.results?.[i].num : 1e5)));
|
|
435
454
|
this.extra[cid]?.broadcast(`[${tag}] 成功:` + players.join(","));
|
|
436
455
|
} catch (e) {
|
|
437
|
-
if (e instanceof import_lobby.
|
|
438
|
-
this.extra[cid]?.broadcast(`[${tag}]
|
|
439
|
-
if (timeout <
|
|
456
|
+
if (e instanceof import_lobby.DHSError) {
|
|
457
|
+
this.extra[cid]?.broadcast(`[${tag}] 失败:` + e.message + ` (timeout=${timeout / import_koishi2.Time.second}s)`);
|
|
458
|
+
if (timeout < this.config.startMaxTimeout) {
|
|
459
|
+
this.ctx.setTimeout(() => this.startMatch(cid, cls, timeout + this.config.startTimeoutInterval), this.config.startTimeoutInterval);
|
|
460
|
+
}
|
|
440
461
|
} else {
|
|
441
|
-
|
|
462
|
+
this.ctx.logger.warn(`start match ${cid}-${cls} failed: ${e.message}`);
|
|
463
|
+
this.extra[cid]?.broadcast(`[${tag}] 失败:` + e.message);
|
|
442
464
|
}
|
|
443
465
|
}
|
|
444
466
|
}
|
|
467
|
+
async startMatch(cid, cls, timeout = 0, tag) {
|
|
468
|
+
try {
|
|
469
|
+
return await this._startMatch(cid, cls, timeout, tag);
|
|
470
|
+
} catch (e) {
|
|
471
|
+
this.ctx.logger.warn(`start match ${cid}-${cls} internal failed: `, e);
|
|
472
|
+
this.extra[cid]?.broadcast(`[${tag}] 失败:内部错误`);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
445
475
|
async onMatchFinished(record) {
|
|
446
476
|
this.extra[record.cid]?.broadcast(`对局完成:
|
|
447
477
|
` + record.results.map((x) => `${x.name} ${x.num}`).join("\n"));
|
|
448
|
-
await (0, import_koishi2.sleep)(
|
|
478
|
+
await (0, import_koishi2.sleep)(this.config.finishInterval);
|
|
449
479
|
return this.startMatch(+record.cid, record.cls);
|
|
450
480
|
}
|
|
451
481
|
};
|
|
452
482
|
((ContestManager2) => {
|
|
453
483
|
ContestManager2.Config = import_koishi2.Schema.object({
|
|
454
|
-
token: import_koishi2.Schema.string()
|
|
484
|
+
token: import_koishi2.Schema.string(),
|
|
485
|
+
startInterval: import_koishi2.Schema.number().default(import_koishi2.Time.second).description("比赛开始间隔"),
|
|
486
|
+
startTimeoutInterval: import_koishi2.Schema.number().default(import_koishi2.Time.second * 30).description("比赛开始重试间隔"),
|
|
487
|
+
startMaxTimeout: import_koishi2.Schema.number().default(import_koishi2.Time.second * 600).description("比赛开始最大重试间隔"),
|
|
488
|
+
finishInterval: import_koishi2.Schema.number().default(import_koishi2.Time.second * 10).description("比赛结束间隔")
|
|
455
489
|
});
|
|
456
490
|
})(ContestManager || (ContestManager = {}));
|
|
457
491
|
|
|
@@ -468,7 +502,7 @@ var MahjongPub2 = class extends import_koishi3.Service {
|
|
|
468
502
|
super(ctx, "mahjongpub", true);
|
|
469
503
|
this.ctx = ctx;
|
|
470
504
|
this.config = config;
|
|
471
|
-
ctx.plugin(ContestManager);
|
|
505
|
+
ctx.plugin(ContestManager, config.manager);
|
|
472
506
|
ctx.i18n.define("zh-CN", require_zh_CN());
|
|
473
507
|
ctx.model.extend("user", {
|
|
474
508
|
"mahjongpub/bind-team": "string",
|
|
@@ -840,7 +874,8 @@ var MahjongPub2 = class extends import_koishi3.Service {
|
|
|
840
874
|
informNotbind: import_koishi3.Schema.boolean().default(false),
|
|
841
875
|
endpoint: import_koishi3.Schema.string().default("https://cdn.r-mj.com/"),
|
|
842
876
|
batchInterval: import_koishi3.Schema.natural().default(300),
|
|
843
|
-
batchCount: import_koishi3.Schema.natural().default(10)
|
|
877
|
+
batchCount: import_koishi3.Schema.natural().default(10),
|
|
878
|
+
manager: ContestManager.Config
|
|
844
879
|
});
|
|
845
880
|
})(MahjongPub2 || (MahjongPub2 = {}));
|
|
846
881
|
var index_default = MahjongPub2;
|
package/lib/manager.d.ts
CHANGED
|
@@ -35,12 +35,17 @@ export declare class ContestManager {
|
|
|
35
35
|
mahjongpub: MahjongPub;
|
|
36
36
|
extra: Dict<ContestExtra>;
|
|
37
37
|
constructor(ctx: Context, config: ContestManager.Config);
|
|
38
|
+
_startMatch(cid: number, cls: number, timeout?: number, tag?: string): Promise<void>;
|
|
38
39
|
startMatch(cid: number, cls: number, timeout?: number, tag?: string): Promise<void>;
|
|
39
40
|
onMatchFinished(record: MatchRecord): Promise<void>;
|
|
40
41
|
}
|
|
41
42
|
export declare namespace ContestManager {
|
|
42
43
|
interface Config {
|
|
43
44
|
token?: string;
|
|
45
|
+
startInterval: number;
|
|
46
|
+
startTimeoutInterval: number;
|
|
47
|
+
startMaxTimeout: number;
|
|
48
|
+
finishInterval: number;
|
|
44
49
|
}
|
|
45
50
|
const Config: Schema<Config>;
|
|
46
51
|
}
|