@hieuzest/koishi-plugin-mahjongpub 0.2.11 → 0.2.13
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 +61 -20
- package/lib/mahjongpub.d.ts +1 -1
- package/lib/manager.d.ts +1 -0
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Context, Dict, Schema, Service } from 'koishi';
|
|
2
2
|
import { ContestAdmin, TeamAdmin } from './api';
|
|
3
3
|
import { ContestManager } from './manager';
|
|
4
|
+
import { MahjongPub as Contest } from './mahjongpub';
|
|
4
5
|
declare module 'koishi' {
|
|
5
6
|
interface Context {
|
|
6
7
|
mahjongpub: MahjongPub;
|
|
@@ -26,6 +27,7 @@ export declare class MahjongPub extends Service {
|
|
|
26
27
|
config: MahjongPub.Config;
|
|
27
28
|
teams: Dict<TeamAdmin>;
|
|
28
29
|
contests: Dict<ContestAdmin>;
|
|
30
|
+
contest: Contest;
|
|
29
31
|
constructor(ctx: Context, config: MahjongPub.Config);
|
|
30
32
|
getTeam(pw: string): Promise<TeamAdmin>;
|
|
31
33
|
getContest(cid: string, pw: string): Promise<ContestAdmin>;
|
package/lib/index.js
CHANGED
|
@@ -242,6 +242,7 @@ var ContestAdmin = class {
|
|
|
242
242
|
// src/manager.ts
|
|
243
243
|
var import_koishi2 = require("koishi");
|
|
244
244
|
var import_api = require("@hieuzest/koishi-plugin-majsoul-dhs/api");
|
|
245
|
+
var import_api2 = require("@hieuzest/koishi-plugin-riichi-city/api");
|
|
245
246
|
var import_lobby = require("@hieuzest/koishi-plugin-riichi-city/lobby");
|
|
246
247
|
|
|
247
248
|
// src/mahjongpub.ts
|
|
@@ -321,7 +322,7 @@ var MahjongPub = class _MahjongPub {
|
|
|
321
322
|
maxAge: 60
|
|
322
323
|
},
|
|
323
324
|
"getTeams": {
|
|
324
|
-
maxAge:
|
|
325
|
+
maxAge: 15
|
|
325
326
|
},
|
|
326
327
|
"getMatches": {
|
|
327
328
|
maxAge: 120
|
|
@@ -350,15 +351,18 @@ var ContestExtra = class {
|
|
|
350
351
|
type;
|
|
351
352
|
round;
|
|
352
353
|
lobby;
|
|
354
|
+
playerIndex;
|
|
353
355
|
ver = 0;
|
|
354
356
|
async broadcast(msg) {
|
|
355
357
|
this.subscribers.forEach((channel) => this.ctx.sendMessage(channel, msg).catch((e) => this.ctx.logger.debug(e)));
|
|
356
358
|
}
|
|
357
359
|
};
|
|
358
|
-
function getRowPlayer(contest, team, rowi) {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
360
|
+
function getRowPlayer(contest, team, rowi, index) {
|
|
361
|
+
if ((0, import_koishi2.isNullable)(index)) {
|
|
362
|
+
const roleList = contest.t_type.split(/\s+/);
|
|
363
|
+
const roleSet = [...new Set(roleList).values()];
|
|
364
|
+
index = roleSet.indexOf(roleList[rowi]);
|
|
365
|
+
}
|
|
362
366
|
return team.players[index]?.split("##", 1)[0];
|
|
363
367
|
}
|
|
364
368
|
__name(getRowPlayer, "getRowPlayer");
|
|
@@ -368,7 +372,7 @@ var ContestManager = class {
|
|
|
368
372
|
this.config = config;
|
|
369
373
|
this.mahjongpub = MahjongPub.new(ctx);
|
|
370
374
|
ctx.command("mahjongpub.manager", { authority: 3 }).action(import_koishi2.noop);
|
|
371
|
-
ctx.command("mahjongpub.manager.init").channelFields(["mahjongpub/bind-contest"]).option("clear", "-c").option("type", "-t [type:string]").option("ver", "-v [ver:number]").option("round", "-r [round:number]").option("lobby", "-l [lobby:string]").action(async ({ session, options }) => {
|
|
375
|
+
ctx.command("mahjongpub.manager.init").channelFields(["mahjongpub/bind-contest"]).option("clear", "-c").option("type", "-t [type:string]").option("ver", "-v [ver:number]").option("round", "-r [round:number]").option("lobby", "-l [lobby:string]").option("index", "-i [index:number]").action(async ({ session, options }) => {
|
|
372
376
|
const cid = +(session.channel["mahjongpub/bind-contest"] || 0);
|
|
373
377
|
if (!cid) return "Unauthorized.";
|
|
374
378
|
this.extra[cid] ??= new ContestExtra(ctx);
|
|
@@ -378,6 +382,7 @@ var ContestManager = class {
|
|
|
378
382
|
if (!(0, import_koishi2.isNullable)(options.ver)) this.extra[cid].ver = options.ver;
|
|
379
383
|
if (!(0, import_koishi2.isNullable)(options.round)) this.extra[cid].round = options.round;
|
|
380
384
|
if (!(0, import_koishi2.isNullable)(options.lobby)) this.extra[cid].lobby = options.lobby;
|
|
385
|
+
if (!(0, import_koishi2.isNullable)(options.index)) this.extra[cid].playerIndex = options.index;
|
|
381
386
|
return "Finished.";
|
|
382
387
|
});
|
|
383
388
|
ctx.command("mahjongpub.manager.deinit").channelFields(["mahjongpub/bind-contest"]).option("clear", "-c").action(async ({ session, options }) => {
|
|
@@ -387,14 +392,16 @@ var ContestManager = class {
|
|
|
387
392
|
this.extra[cid].subscribers.delete(session.cid);
|
|
388
393
|
return "Finished.";
|
|
389
394
|
});
|
|
390
|
-
ctx.command("mahjongpub.manager.start [cls:number]").channelFields(["mahjongpub/bind-contest"]).option("force", "-f").action(async ({ session, options },
|
|
395
|
+
ctx.command("mahjongpub.manager.start [...cls:number]").channelFields(["mahjongpub/bind-contest"]).option("force", "-f").action(async ({ session, options }, ...clsz) => {
|
|
391
396
|
const cid = +(session.channel["mahjongpub/bind-contest"] || 0);
|
|
392
397
|
if (!cid) return "Unauthorized.";
|
|
393
398
|
const cextra = this.extra[cid] ??= new ContestExtra(ctx);
|
|
394
399
|
cextra.subscribers.add(session.cid);
|
|
395
|
-
if (
|
|
396
|
-
|
|
397
|
-
|
|
400
|
+
if (clsz.length) {
|
|
401
|
+
for (const cls of clsz) {
|
|
402
|
+
cextra.stopCls.delete(cls);
|
|
403
|
+
await this.startMatch(cid, cls, 0, options.force);
|
|
404
|
+
}
|
|
398
405
|
} else {
|
|
399
406
|
cextra.stopCls.clear();
|
|
400
407
|
const contest = await this.mahjongpub.getContest(cid);
|
|
@@ -406,12 +413,14 @@ var ContestManager = class {
|
|
|
406
413
|
}
|
|
407
414
|
}
|
|
408
415
|
});
|
|
409
|
-
ctx.command("mahjongpub.manager.stop [cls:number]").channelFields(["mahjongpub/bind-contest"]).action(async ({ session },
|
|
416
|
+
ctx.command("mahjongpub.manager.stop [...cls:number]").channelFields(["mahjongpub/bind-contest"]).action(async ({ session }, ...clsz) => {
|
|
410
417
|
const cid = +(session.channel["mahjongpub/bind-contest"] || 0);
|
|
411
|
-
if (!cid) return "Unauthorized
|
|
418
|
+
if (!cid) return "Unauthorized.";
|
|
412
419
|
const cextra = this.extra[cid] ??= new ContestExtra(ctx);
|
|
413
|
-
if (
|
|
414
|
-
|
|
420
|
+
if (clsz.length) {
|
|
421
|
+
for (const cls of clsz) {
|
|
422
|
+
cextra.stopCls.add(cls);
|
|
423
|
+
}
|
|
415
424
|
} else {
|
|
416
425
|
const contest = await this.mahjongpub.getContest(cid);
|
|
417
426
|
const rounds = await this.mahjongpub.getRounds(cid);
|
|
@@ -473,31 +482,36 @@ var ContestManager = class {
|
|
|
473
482
|
return;
|
|
474
483
|
}
|
|
475
484
|
const round = Object.values(rounds).find((x) => x.round === (cextra.round ?? contest.c_round) && x.t_class === cls);
|
|
476
|
-
const players = round.tids.map((tid) => getRowPlayer(contest, teams[tid], rowi));
|
|
485
|
+
const players = round.tids.map((tid) => getRowPlayer(contest, teams[tid], rowi, cextra.playerIndex));
|
|
477
486
|
if (!players.every((x) => x)) {
|
|
478
487
|
cextra.broadcast(`[${tag}] 失败: 名单未填写`);
|
|
479
488
|
return;
|
|
480
489
|
}
|
|
490
|
+
let failPatterns;
|
|
481
491
|
try {
|
|
482
492
|
if (cextra.type === "ti") {
|
|
483
|
-
|
|
493
|
+
failPatterns = players.map((x, i) => `${x} ${lastRecord ? lastRecord.results?.[i].num : 1e5}`).join(", ");
|
|
494
|
+
this.ctx.logger.info(`starting ti match ${cid}-${cls}, players ${failPatterns}`);
|
|
484
495
|
await this.ctx["zx-dhs"].startMatch(
|
|
485
496
|
+(cextra.lobby ?? round.code),
|
|
486
497
|
players.map((x, i) => import_lobby.Player.fromPattern(x, lastRecord ? lastRecord.results?.[i].num : 1e5))
|
|
487
498
|
);
|
|
488
499
|
} else if (cextra.type === "ssb") {
|
|
489
|
-
|
|
500
|
+
failPatterns = players.join(", ");
|
|
501
|
+
this.ctx.logger.info(`starting ssb match ${cid}-${cls}, players ${failPatterns}`);
|
|
490
502
|
await this.ctx["majsoul-dhs"].startMatch(+(cextra.lobby ?? round.code), players.map((x) => import_api.Player.fromPattern(x, 25e3)));
|
|
503
|
+
} else {
|
|
504
|
+
throw new Error(`unknown contest type: ${cextra.type}`);
|
|
491
505
|
}
|
|
492
|
-
cextra.broadcast(`[${tag}] 成功:` + players.join("
|
|
506
|
+
cextra.broadcast(`[${tag}] 成功:` + players.join(", "));
|
|
493
507
|
} catch (e) {
|
|
494
|
-
if (e instanceof import_lobby.DHSError || e instanceof import_api.DHSError) {
|
|
508
|
+
if (e instanceof import_lobby.DHSError || e instanceof import_api2.RiichiCityError || e instanceof import_api.DHSError) {
|
|
495
509
|
cextra.broadcast(`[${tag}] 失败:` + e.message + ` (timeout=${timeout / import_koishi2.Time.second}s)`);
|
|
496
510
|
if (timeout < this.config.startMaxTimeout) {
|
|
497
511
|
this.ctx.setTimeout(() => this.startMatch(cid, cls, timeout + this.config.startTimeoutInterval), this.config.startTimeoutInterval);
|
|
498
512
|
} else {
|
|
499
513
|
this.ctx.logger.warn(`start match ${cid}-${cls} exceed max retires`);
|
|
500
|
-
cextra.broadcast(`[${tag}] 失败:超过最大重试时间 【${
|
|
514
|
+
cextra.broadcast(`[${tag}] 失败:超过最大重试时间 【${failPatterns}】`);
|
|
501
515
|
}
|
|
502
516
|
} else {
|
|
503
517
|
this.ctx.logger.warn(`start match ${cid}-${cls} failed: ${e.message}`);
|
|
@@ -553,6 +567,7 @@ var MahjongPub2 = class extends import_koishi3.Service {
|
|
|
553
567
|
this.config = config;
|
|
554
568
|
ctx.plugin(ContestManager, config.manager);
|
|
555
569
|
ctx.i18n.define("zh-CN", require_zh_CN());
|
|
570
|
+
this.contest = MahjongPub.new(ctx);
|
|
556
571
|
ctx.model.extend("user", {
|
|
557
572
|
"mahjongpub/bind-team": "string",
|
|
558
573
|
"mahjongpub/bind-teams": "json"
|
|
@@ -813,6 +828,31 @@ var MahjongPub2 = class extends import_koishi3.Service {
|
|
|
813
828
|
}
|
|
814
829
|
});
|
|
815
830
|
if (ctx.get("mahjong.database")) {
|
|
831
|
+
ctx.command("mahjongpub.database.record.last <round: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) => {
|
|
832
|
+
const [cid] = [session.channel["mahjongpub/bind-contest"]];
|
|
833
|
+
try {
|
|
834
|
+
const cteams = await this.contest.getTeams(+cid);
|
|
835
|
+
const record = await ctx.mahjong.database.db("scoreboard").collection("matches").find({
|
|
836
|
+
cid,
|
|
837
|
+
round,
|
|
838
|
+
ver: options.ver,
|
|
839
|
+
...options.rowi === -1 ? {} : { rowi: options.rowi }
|
|
840
|
+
}).sort({ cls: 1, rowi: -1 }).toArray();
|
|
841
|
+
if (!record.length) return session.text(".failed");
|
|
842
|
+
const filtered = [];
|
|
843
|
+
const seenCls = /* @__PURE__ */ new Set();
|
|
844
|
+
record.forEach((r) => {
|
|
845
|
+
if (!seenCls.has(r.cls)) {
|
|
846
|
+
filtered.push(r);
|
|
847
|
+
seenCls.add(r.cls);
|
|
848
|
+
}
|
|
849
|
+
});
|
|
850
|
+
return filtered.map((r) => `[${r.cls}-${r.rowi + 1}] ` + r.results.map((x, i) => `${cteams[r.tids[i]].t_name} ${x.num}`).join(" / ")).join("\n");
|
|
851
|
+
} catch (e) {
|
|
852
|
+
ctx.logger.warn(e);
|
|
853
|
+
return session.text(".failed");
|
|
854
|
+
}
|
|
855
|
+
});
|
|
816
856
|
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) => {
|
|
817
857
|
const [cid] = [session.channel["mahjongpub/bind-contest"]];
|
|
818
858
|
try {
|
|
@@ -897,6 +937,7 @@ var MahjongPub2 = class extends import_koishi3.Service {
|
|
|
897
937
|
}
|
|
898
938
|
teams = {};
|
|
899
939
|
contests = {};
|
|
940
|
+
contest;
|
|
900
941
|
async getTeam(pw) {
|
|
901
942
|
return new TeamAdmin(this.ctx, pw, this.config);
|
|
902
943
|
}
|
package/lib/mahjongpub.d.ts
CHANGED
package/lib/manager.d.ts
CHANGED