Commit 446b2b75 authored by nanahira's avatar nanahira

duel stage

parent a511e23f
export enum DuelStage {
Begin = 'Begin',
Finger = 'Finger',
FirstGo = 'FirstGo',
Dueling = 'Dueling',
Siding = 'Siding',
End = 'End',
}
......@@ -58,7 +58,7 @@ export class RoomEventRegister {
// 通过 roomName 查找 room
const roomManager = this.ctx.get(() => RoomManager);
const room = roomManager.findByName(client.roomName);
if (!room) {
if (!room || room.finalizing) {
return next();
}
......
import { Context } from '../app';
import { Room } from './room';
import { Room, RoomFinalizor } from './room';
export class RoomManager {
constructor(private ctx: Context) {}
private rooms = new Map<string, Room>();
private finalizors: RoomFinalizor[] = [];
addFinalizor(finalizor: RoomFinalizor, atEnd = false) {
if (atEnd) {
this.finalizors.push(finalizor);
} else {
this.finalizors.unshift(finalizor);
}
}
findByName(name: string) {
return this.rooms.get(name);
}
......@@ -22,11 +32,13 @@ export class RoomManager {
const existing = this.findByName(name);
if (existing) return existing;
const room = await new Room(this.ctx, name)
.addFinalizor((r) => {
const room = new Room(this.ctx, name).addFinalizor((r) => {
this.rooms.delete(r.name);
})
.init();
});
for (const finalizor of this.finalizors) {
room.addFinalizor(finalizor);
}
await room.init();
this.rooms.set(name, room);
return room;
});
......
......@@ -11,6 +11,9 @@ import { CardReaderFinalized } from 'koishipro-core.js';
import { YGOProResourceLoader } from '../services/ygopro-resource-loader';
import { blankLFList } from '../utility/blank-lflist';
import { Client } from '../client/client';
import { RoomMethod } from '../utility/decorators';
import { YGOProCtosDisconnect } from '../utility/ygopro-ctos-disconnect';
import { DuelStage } from './duel-stage';
export type RoomFinalizor = (self: Room) => Awaitable<any>;
......@@ -64,13 +67,33 @@ export class Room {
return this;
}
private finalizors: RoomFinalizor[] = [];
addFinalizor(finalizor: RoomFinalizor) {
private finalizors: RoomFinalizor[] = [
() => {
this.allPlayers.forEach((p) => {
p.disconnect();
if (p.pos < NetPlayerType.OBSERVER) {
this.players[p.pos] = undefined;
}
});
this.watchers.clear();
},
];
addFinalizor(finalizor: RoomFinalizor, atEnd = false) {
if (atEnd) {
this.finalizors.unshift(finalizor);
} else {
this.finalizors.push(finalizor);
}
return this;
}
finalizing = false;
async finalize() {
if (this.finalizing) {
return;
}
this.finalizing = true;
while (this.finalizors.length) {
const finalizor = this.finalizors.pop()!;
await finalizor(this);
......@@ -94,9 +117,6 @@ export class Room {
async join(client: Client) {
client.roomName = this.name;
client.disconnect$.subscribe(({ bySystem }) =>
this.onPlayerDisconnect(client, bySystem),
);
client.isHost = !this.allPlayers.length;
const firstEmptyPlayerSlot = this.players.findIndex((p) => !p);
if (firstEmptyPlayerSlot >= 0) {
......@@ -123,13 +143,24 @@ export class Room {
}
}
async onPlayerDisconnect(client: Client) {
duelStage = DuelStage.Begin;
@RoomMethod()
async onDisconnect(client: Client, _msg: YGOProCtosDisconnect) {
if (client.pos === NetPlayerType.OBSERVER) {
this.watchers.delete(client);
for (const p of this.allPlayers) {
p.send(this.watcherSizeMessage).then();
}
return;
} else {
this.players[client.pos] = undefined;
}
if (client.isHost) {
const nextHost = this.allPlayers.find((p) => p !== client);
if (nextHost) {
nextHost.isHost = true;
await nextHost.sendTypeChange();
}
}
client.roomName = undefined;
}
......
import { Metadata } from './metadata';
export const RoomMethod = () =>
export const RoomMethod = (): MethodDecorator =>
Metadata.set('roomMethod', true, 'roomMethodKeys');
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