@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 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
- }).then((rounds) => rounds.map((round) => [round.rid, {
285
- ...round,
286
- tids: [round.tid1, round.tid2, round.tid3, round.tid4]
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(import_koishi2.noop));
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("contest.manager", { authority: 3 }).action(import_koishi2.noop);
352
- ctx.command("contest.manager.init").channelFields(["mahjongpub/bind-contest"]).option("clear", "-c").action(async ({ session, options }) => {
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("contest.manager.start [cls:number]").channelFields(["mahjongpub/bind-contest"]).action(async ({ session }, cls) => {
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)(1e3);
389
+ await (0, import_koishi2.sleep)(config.startInterval);
376
390
  }
377
391
  }
378
392
  });
379
- ctx.command("contest.manager.stop [cls:number]").channelFields(["mahjongpub/bind-contest"]).action(async ({ session }, cls) => {
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 startMatch(cid, cls, timeout, tag) {
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.PlayerNotFoundError) {
438
- this.extra[cid]?.broadcast(`[${tag}] ` + e.message + ` <timeout=${timeout}>`);
439
- if (timeout < 600) this.ctx.setTimeout(() => this.startMatch(cid, cls, timeout + 30), 30 * 1e3);
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
- throw e;
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)(2e3);
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
  }
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.2.1",
4
+ "version": "0.2.3",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [