Commit c445ea24 authored by nanahira's avatar nanahira

add .cleanzombie

parent 9245ea30
...@@ -38,6 +38,11 @@ export class MatchWrapper { ...@@ -38,6 +38,11 @@ export class MatchWrapper {
(this.match.scores_csv?.length || 0) < 3 (this.match.scores_csv?.length || 0) < 3
); );
} }
isNotStarted() {
return !this.match.scores_csv && this.match.state !== 'complete';
}
getPlayerIds() { getPlayerIds() {
return [this.match.player1_id, this.match.player2_id]; return [this.match.player1_id, this.match.player2_id];
} }
...@@ -45,6 +50,12 @@ export class MatchWrapper { ...@@ -45,6 +50,12 @@ export class MatchWrapper {
hasPlayer(id: number) { hasPlayer(id: number) {
return this.getPlayerIds().includes(id); return this.getPlayerIds().includes(id);
} }
getDisplayLine(player1Name: string, player2Name: string) {
return `${player1Name} ${
this.match.scores_csv || '未开始'
} ${player2Name}`;
}
} }
export class Participant { export class Participant {
...@@ -196,4 +207,19 @@ export class TournamentWrapper { ...@@ -196,4 +207,19 @@ export class TournamentWrapper {
} }
return allRelatedMatches[allRelatedMatches.length - 1]; return allRelatedMatches[allRelatedMatches.length - 1];
} }
displayMatch(match: MatchWrapper) {
const currentMatchInfo = match.match;
const player1Name = this.getParticipantFromParticipantId(
currentMatchInfo.player1_id,
).participant.name;
const player2Name = this.getParticipantFromParticipantId(
currentMatchInfo.player2_id,
).participant.name;
return match.getDisplayLine(player1Name, player2Name);
}
getZombieMatches() {
return this.tournament.matches.filter((m) => m.isNotStarted());
}
} }
...@@ -5,7 +5,7 @@ import { ...@@ -5,7 +5,7 @@ import {
YGOTournamentPluginConfigLike, YGOTournamentPluginConfigLike,
} from './config'; } from './config';
import { classToPlain, plainToClass } from 'class-transformer'; import { classToPlain, plainToClass } from 'class-transformer';
import { TournamentWrapper } from './def/challonge'; import { MatchWrapper, TournamentWrapper } from './def/challonge';
import { S3Client } from '@aws-sdk/client-s3'; import { S3Client } from '@aws-sdk/client-s3';
import { getSignedUrl } from './presign'; import { getSignedUrl } from './presign';
import { SRVProRoomInfo } from './def/srvpro'; import { SRVProRoomInfo } from './def/srvpro';
...@@ -143,16 +143,12 @@ export class YGOTournamentPlugin { ...@@ -143,16 +143,12 @@ export class YGOTournamentPlugin {
if (!currentMatch) { if (!currentMatch) {
return '您没有正在进行的比赛。'; return '您没有正在进行的比赛。';
} }
const currentMatchInfo = currentMatch.match; return `您当前的对局信息:\n${tournament.displayMatch(currentMatch)}`;
const player1Name = tournament.getParticipantFromParticipantId( }
currentMatchInfo.player1_id,
).participant.name; private async fetchSRVProRoomlist() {
const player2Name = tournament.getParticipantFromParticipantId( const rawRoomlist = await this.config.tournament.fetchRooms(this.ctx);
currentMatchInfo.player2_id, return plainToClass(SRVProRoomInfo, rawRoomlist);
).participant.name;
return `您当前的对局信息:\n${player1Name}\t${
currentMatchInfo.scores_csv || '未开始'
}\t${player2Name}`;
} }
private async onUserDeclareLate(userId: string) { private async onUserDeclareLate(userId: string) {
...@@ -182,11 +178,7 @@ export class YGOTournamentPlugin { ...@@ -182,11 +178,7 @@ export class YGOTournamentPlugin {
if (!currentMatch.isClean()) { if (!currentMatch.isClean()) {
return '你涉及的比赛似乎已经有结果了,请联系裁判处理。'; return '你涉及的比赛似乎已经有结果了,请联系裁判处理。';
} }
const rawRoomlist = await this.config.tournament.fetchRooms(this.ctx); const roomlist = await this.fetchSRVProRoomlist();
if (!rawRoomlist) {
return '获取房间列表失败,请与技术人员联系。';
}
const roomlist = plainToClass(SRVProRoomInfo, rawRoomlist);
const roomsWithPlayer = roomlist.searchForUser(participantName); const roomsWithPlayer = roomlist.searchForUser(participantName);
if (!roomsWithPlayer.length) { if (!roomsWithPlayer.length) {
return '请先进入房间并打勾确认。'; return '请先进入房间并打勾确认。';
...@@ -236,6 +228,44 @@ export class YGOTournamentPlugin { ...@@ -236,6 +228,44 @@ export class YGOTournamentPlugin {
return '迟到杀成功。'; return '迟到杀成功。';
} }
private async getZombieMatches() {
const tournament = await this.fetchChallongeData();
const matches = tournament.getZombieMatches();
if (!matches.length) {
return { tournament, matches };
}
const roomlist = await this.fetchSRVProRoomlist();
const zombieMatches = matches.filter((m) => {
const player1 = tournament.getParticipantFromParticipantId(
m.match.player1_id,
);
const player2 = tournament.getParticipantFromParticipantId(
m.match.player2_id,
);
const player1Name = player1.getNameMatching().userName;
const player2Name = player2.getNameMatching().userName;
const roomsWithPlayer1 = roomlist.searchForUser(player1Name);
const roomsWithPlayer2 = roomlist.searchForUser(player2Name);
return (
roomsWithPlayer1.every((r) => r.istart === 'wait') &&
roomsWithPlayer2.every((r) => r.istart === 'wait')
);
});
return { tournament, matches: zombieMatches };
}
private async cleanZombieMatch(match: MatchWrapper) {
await this.ctx.http.put(
`${this.config.tournament.getChallongeUrl()}/matches/${
match.match.id
}.json`,
{
api_key: this.config.tournament.challongeKey,
match: { scores_csv: '0-0', winner_id: 'tie' },
},
);
}
private initializeDeckFetch() { private initializeDeckFetch() {
if (!this.config.isDeckFetchEnabled()) { if (!this.config.isDeckFetchEnabled()) {
return; return;
...@@ -378,6 +408,32 @@ export class YGOTournamentPlugin { ...@@ -378,6 +408,32 @@ export class YGOTournamentPlugin {
); );
return '清理缓存成功。'; return '清理缓存成功。';
}); });
judgeCommand
.subcommand('.cleanzombie', '清理僵尸对局')
.usage('会清理所有没有开始的对局,统一设置为 0-0 平。')
.action(async ({ session }) => {
try {
const { tournament, matches } = await this.getZombieMatches();
if (!matches.length) {
return '未找到僵尸对局。';
}
await session.send(
`找到了 ${matches.length} 个僵尸对局:\n${matches
.map((m) => tournament.displayMatch(m))
.join('\n')}\n\n输入 yes 进行清理。`,
);
const reply = await session.prompt();
if (reply !== 'yes') {
return '清理被取消。';
}
await Promise.all(matches.map((m) => this.cleanZombieMatch(m)));
return `清理成功,清理了 ${matches.length} 个僵尸对局。`;
} catch (e) {
this.ctx
.logger('challonge')
.error(`Failed to clean zombie matches: ${e.toString()}`);
}
});
} }
name = 'ygotournament-main'; name = 'ygotournament-main';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment