Commit 3ec356e0 authored by nanahira's avatar nanahira

add auth death

parent 8b1ba942
......@@ -157,6 +157,9 @@ export const TRANSLATIONS = {
death_finish_part2: ', You win the Duel.',
death2_finish_part1: 'Extra time match ends, congratulations. ',
death2_finish_part2: ', You win the Match.',
auto_death_part1:
'This room is an auto-extra-duel room. The Extra Duel will begin after ',
auto_death_part2: ' minutes.',
lp_low_opponent: 'もはやお前のライフは風前の灯!',
lp_low_self: '*Low LP Alert*',
botlist_menu_single: 'Single',
......@@ -308,6 +311,8 @@ export const TRANSLATIONS = {
death_finish_part2: ' 获得本次决斗的胜利。',
death2_finish_part1: '加时赛结束,恭喜 ',
death2_finish_part2: ' 获得本次比赛的胜利。',
auto_death_part1: '本房间为自动加时赛房间。比赛开始',
auto_death_part2: '分钟后,将自动进入加时赛。',
lp_low_opponent: '你的生命已经如风中残烛了!',
lp_low_self: '背水一战!',
botlist_menu_single: '单局',
......
......@@ -18,6 +18,7 @@ import { LpLowHintService } from './lp-low-hint-service';
import { LockDeckService } from './lock-deck';
import { BlockReplay } from './block-replay';
import { RoomDeathService } from './room-death-service';
import { RoomAutoDeathService } from './room-auto-death-service';
export const FeatsModule = createAppContext()
.provide(ClientKeyProvider)
......@@ -33,6 +34,7 @@ export const FeatsModule = createAppContext()
.provide(ChatgptService) // AI-room chat replies
.provide(LpLowHintService) // low LP hint in duel
.provide(RoomDeathService) // srvpro-style death mode (model 2)
.provide(RoomAutoDeathService) // auto trigger death mode after duel start
.provide(LockDeckService) // srvpro-style tournament deck lock check
.provide(RefreshFieldService)
.provide(Reconnect)
......
import { Context } from '../app';
import {
DefaultHostInfoProvider,
OnRoomFinalize,
OnRoomGameStart,
RoomManager,
} from '../room';
import { RoomDeathService } from './room-death-service';
import { ChatColor } from 'ygopro-msg-encode';
const MINUTE_MS = 60_000;
declare module 'ygopro-msg-encode' {
interface HostInfo {
auto_death?: number;
}
}
export class RoomAutoDeathService {
private logger = this.ctx.createLogger('RoomAutoDeathService');
private roomManager = this.ctx.get(() => RoomManager);
private roomDeathService = this.ctx.get(() => RoomDeathService);
private roomTimers = new Map<string, ReturnType<typeof setTimeout>>();
constructor(private ctx: Context) {
this.ctx
.get(() => DefaultHostInfoProvider)
.registerRoomMode('(DEATH|DH)(\\d*)', ({ regexResult }) => {
const deathTime = Number.parseInt(regexResult[1], 10);
return {
auto_death:
Number.isFinite(deathTime) && deathTime > 0 ? deathTime : 40,
};
});
this.ctx.middleware(OnRoomGameStart, async (event, _client, next) => {
const scheduled = this.tryScheduleAutoDeath(
event.room.name,
event.room.hostinfo.auto_death,
);
if (scheduled) {
const minutes = Number(event.room.hostinfo.auto_death || 0);
await event.room.sendChat(
`#{auto_death_part1}${minutes}#{auto_death_part2}`,
ChatColor.BABYBLUE,
);
}
return next();
});
this.ctx.middleware(OnRoomFinalize, async (event, _client, next) => {
this.clearTimer(event.room.name);
return next();
});
}
private tryScheduleAutoDeath(roomName: string, autoDeathMinutes?: number) {
const minutes = Number(autoDeathMinutes || 0);
if (!Number.isFinite(minutes) || minutes <= 0) {
return false;
}
if (this.roomTimers.has(roomName)) {
return false;
}
const delayMs = Math.max(0, Math.floor(minutes * MINUTE_MS));
const timer = setTimeout(() => {
this.roomTimers.delete(roomName);
void this.triggerAutoDeath(roomName).catch((error) => {
this.logger.warn(
{ roomName, error },
'Failed to trigger auto death for room',
);
});
}, delayMs);
this.roomTimers.set(roomName, timer);
return true;
}
private clearTimer(roomName: string) {
const timer = this.roomTimers.get(roomName);
if (!timer) {
return;
}
clearTimeout(timer);
this.roomTimers.delete(roomName);
}
private async triggerAutoDeath(roomName: string) {
const room = this.roomManager.findByName(roomName);
if (!room || room.finalizing) {
return;
}
await this.roomDeathService.startDeath(room);
}
}
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