You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
3.3 KiB
150 lines
3.3 KiB
2 years ago
|
import {Client} from "./client"
|
||
|
import {ServerGame} from "./games/game_standard"
|
||
|
import {Memory} from "./games/memory"
|
||
|
import {Pong} from "./games/pong"
|
||
|
import {GlobalDraw} from "./games/global_draw"
|
||
|
import {Chainreact} from "./games/chainreact"
|
||
|
import {serializeObject} from "./manager";
|
||
|
import {Server} from "socket.io";
|
||
|
|
||
|
export class Room {
|
||
|
|
||
|
id: string;
|
||
|
gameName: string;
|
||
|
clientCounts: number[];
|
||
|
io: Server;
|
||
|
clients: Client[];
|
||
|
runningGame: ServerGame;
|
||
|
settings: Settings.Global;
|
||
|
gameSettings: any;
|
||
|
name: string;
|
||
|
|
||
|
constructor(name: string, id: string, settings?: Settings.Global, io?: Server) {
|
||
|
this.id = id;
|
||
|
this.name = name;
|
||
|
if (!io || !settings) return;
|
||
|
this.settings = settings;
|
||
|
this.gameName = settings.project.name;
|
||
|
this.clientCounts = settings.project.playerCounts;
|
||
|
this.io = io;
|
||
|
this.clients = [];
|
||
|
this.gameSettings = {}
|
||
|
}
|
||
|
|
||
|
get leader(): Client {
|
||
|
return this.players[0]
|
||
|
}
|
||
|
|
||
|
get players(): Client[] {
|
||
|
return this.clients.filter(c => c.isPlayer)
|
||
|
}
|
||
|
|
||
|
get spectators(): Client[] {
|
||
|
return this.clients.filter(c => c.isSpectator)
|
||
|
}
|
||
|
|
||
|
get serialized(): Serialized.Lobby {
|
||
|
return {
|
||
|
id: this.id,
|
||
|
name: this.name,
|
||
|
game: this.gameName,
|
||
|
clientCounts: this.clientCounts,
|
||
|
clients: serializeObject(this.clients),
|
||
|
hasStarted: this.hasStarted
|
||
|
};
|
||
|
}
|
||
|
|
||
|
get isEmpty(): boolean {
|
||
|
return !(this.clients.length)
|
||
|
}
|
||
|
|
||
|
get hasStarted(): boolean {
|
||
|
return this.runningGame != null
|
||
|
}
|
||
|
|
||
|
static getByRoomId(id: string, lobbies: Room[]): Room {
|
||
|
for (let l of lobbies) {
|
||
|
if (l.id === id)
|
||
|
return l
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
static getByClientId(id: string, lobbies: Room[]): Room {
|
||
|
for (let l of lobbies) {
|
||
|
for (let c of l.clients) {
|
||
|
if (c.id === id)
|
||
|
return l
|
||
|
}
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
static generateCode(elements: number): string {
|
||
|
let code = '';
|
||
|
let possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
||
|
while (elements--) {
|
||
|
code += possible.charAt(Math.floor(Math.random() * possible.length))
|
||
|
}
|
||
|
return code
|
||
|
}
|
||
|
|
||
|
startGame(): void {
|
||
|
let seed = Math.random() * 10000;
|
||
|
this.toAll('start-game', seed);
|
||
|
this.runGame()
|
||
|
}
|
||
|
|
||
|
stopGame(client: Client): void {
|
||
|
this.toAll('stop-game', client);
|
||
|
this.runningGame = null
|
||
|
}
|
||
|
|
||
|
add(client: Client): void {
|
||
|
this.clients.push(client);
|
||
|
|
||
|
let isPlayer = !this.hasStarted && this.hasValidPlayerCount();
|
||
|
client.isPlayer = isPlayer;
|
||
|
client.isSpectator = !isPlayer;
|
||
|
client.isReady = false;
|
||
|
client.join(this.id);
|
||
|
|
||
|
this.toAll('member-joined', client.id, client.name);
|
||
|
this.toAll('client-list', this.clients);
|
||
|
this.toAll('game-settings', this.gameSettings);
|
||
|
|
||
|
if (this.hasStarted)
|
||
|
this.runningGame.addClient(client)
|
||
|
}
|
||
|
|
||
|
hasValidPlayerCount(): boolean {
|
||
|
let valid = false;
|
||
|
this.clientCounts.forEach(c => {
|
||
|
if (c === this.clients.length)
|
||
|
valid = true
|
||
|
});
|
||
|
return valid
|
||
|
}
|
||
|
|
||
|
runGame(): void {
|
||
|
switch (this.gameName) {
|
||
|
case 'memory':
|
||
|
this.runningGame = new Memory(this, this.settings);
|
||
|
break;
|
||
|
case 'pong':
|
||
|
this.runningGame = new Pong(this, this.settings);
|
||
|
break;
|
||
|
case 'global-draw':
|
||
|
this.runningGame = new GlobalDraw(this, this.settings);
|
||
|
break;
|
||
|
case 'chainreact':
|
||
|
this.runningGame = new Chainreact(this, this.settings);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
toAll(event: string, ...args: any[]): void {
|
||
|
this.io.to(this.id).emit(event, serializeObject(this), ...serializeObject(args))
|
||
|
}
|
||
|
|
||
|
}
|