import {Room} from "./room" import {ConnectionManager, serializeObject} from "./manager" import {log} from "./logger"; import SocketIO = require("socket.io"); export class Client { socket: SocketIO.Socket; name: string; game: string; id: string; isReady: boolean; isPlayer: boolean; isSpectator: boolean; constructor(socket: SocketIO.Socket, manager: ConnectionManager) { this.socket = socket; // @ts-ignore this.name = socket.handshake.query.name; // @ts-ignore this.game = socket.handshake.query.game; this.id = socket.id; this.setEvents(manager) } get serialized(): Serialized.Client { return { id: this.id, name: this.name, game: this.game, isReady: this.isReady, isPlayer: this.isPlayer, isSpectator: this.isSpectator }; } setEvents(mng: ConnectionManager): void { let s = this.socket; s.on('room-list', () => this.sendRoomList()); s.on('client-list', () => this.sendClientList()); s.on('set-ready', ready => this.setReady(ready)); s.on('game-settings', settings => this.setGameSettings(settings)); s.on('create-lobby', (settings, name) => this.createRoom(settings, name)); s.on('join-lobby', roomId => this.joinRoom(roomId)); s.on('leave-lobby', roomId => this.leaveRoom(roomId)); s.on('join-spectators', () => this.joinSpectators()); s.on('join-players', () => this.joinPlayers()); s.on('start-game', lobbyId => mng.startGame(this, lobbyId)); s.on('stop-game', lobbyId => mng.stopGame(this, lobbyId)); s.on('feedback', content => mng.saveFeedbackToFile(this, content)); s.on('disconnect', () => mng.disconnected(this)); this.send('connected') } sendRoomList(): void { let rooms = ConnectionManager.RoomListByGame(this.game); this.send('room-list', rooms) } sendClientList(): void { let clients = ConnectionManager.ClientListByClientId(this.id); this.send('client-list', clients) } setReady(ready: boolean): void { let room = Room.getByClientId(this.id, ConnectionManager.Instance.rooms); if (room) { this.isReady = ready; room.toAll('client-list', room.clients) } } setGameSettings(settings: any): void { let room = Room.getByClientId(this.id, ConnectionManager.Instance.rooms); if (room) { room.gameSettings = settings; room.toAll('game-settings', settings) } } createRoom(settings: Settings.Global, name: string): void { let room = ConnectionManager.Instance.createRoom(settings, name); room.add(this); this.send('created-lobby', room); log('lobby-created', this, room) } joinRoom(roomId: string): Room { let room = Room.getByRoomId(roomId, ConnectionManager.Instance.rooms); if (!room) { this.send('join-failed', 'Room does not exist!'); log('join-non-existent', this, new Room('not-existent', roomId)) } else if (room.hasStarted && !room.settings.spectators) { this.send('join-failed', 'Game has started yet!'); log('join-started', this, room) } else { room.add(this); log('member-joined', this, room) } return room } leaveRoom(_roomId: string): void { let room = Room.getByClientId(this.id, ConnectionManager.Instance.rooms); if (!room) return; this.leave(room.id); if (room.runningGame) room.runningGame.removeClient(this); room.clients.splice(room.clients.indexOf(this), 1); room.toAll('member-left', this.id, this.name); room.toAll('client-list', room.clients); this.send('left-lobby'); log('member-left', this, room); if (room.isEmpty && !room.settings.always) { ConnectionManager.Instance.deleteRoom(room) } } joinSpectators() { let room = Room.getByClientId(this.id, ConnectionManager.Instance.rooms); if (!room) return; this.isSpectator = true; this.isPlayer = false; room.toAll('client-list', room.clients) } joinPlayers() { let room = Room.getByClientId(this.id, ConnectionManager.Instance.rooms); if (!room) return; if (room.hasStarted) return; this.isSpectator = false; this.isPlayer = true; room.toAll('client-list', room.clients) } send(event: string, ...args: any[]): void { this.socket.emit(event, ...serializeObject(args)) } join(roomId: string): void { this.socket.join(roomId) } leave(roomId: string): void { this.socket.leave(roomId) } }