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