declare let P2P: any declare let io: any class OnlineManager{ socket: any settings: Settings.Global lobby: Lobby p2p: any constructor(name: string, settings: Settings.Global){ this.connectToServer(settings.project, name, () => { this.connectToPeers(settings.project) this.setSocketEvents() this.settings = settings }); } connectToServer(project: Settings.Project, name: string, cb): void{ let urlQueries = '?game=' + project.name + '&name=' + name; $.get('data/settings/get_port.php', port => { let url = 'https://' + location.hostname + ':' + port + urlQueries this.socket = io.connect(url) this.socket.on('connect', () => console.log('Connected to ', url)); cb(); }); } connectToPeers(project: Settings.Project){ let iceServers = project.online.iceServers let opts = {peerOpts: {trickle: false, config: {iceServers: iceServers}}} this.p2p = new P2P(this.socket, opts) this.p2p.usePeerConnection = true this.p2p.useSockets = false console.log('Created WebRTC Connection:', this.p2p) } setSocketEvents(): void{ this.socket.on('connected', () => onlineAnswerFrontend()) this.socket.on('member-joined', (lobby: Serialized.Lobby) => this.setLobby(new Lobby(lobby))) this.socket.on('member-left', (lobby: Serialized.Lobby) => this.setLobby(new Lobby(lobby))) this.socket.on('join-failed', (error: string) => this.joinFailed(error)) this.socket.on('start-game', () => this.startOnlineGame()) } setPeerEvents(){ //Game actions like togglePlay this.p2p.on('game-action', (req: any) => { if (req.lobby.id !== this.lobby.id) return game[req.action](false, req.fromInitiator) }) //For every non-leader, whole game sent by leader this.p2p.on('game-data', (data: Serialized.Game) => { if (data.id !== this.lobby.id) return (game as OnlineGame).data = data }) //For leader, inputs sent by others this.p2p.on('player-input', (player: Serialized.Player) => { if (player.lobby.id !== this.lobby.id) return (game as OnlineGame).setPlayerInput(player) }) this.p2p.on('chat-msg', (req: any) => { if (req.lobby.id !== this.lobby.id) return this.addChatMessage(req.msg) }) this.p2p.on('peer-error', (data: any) => console.log('Peer-Error: ', data)) } setLobby(lobby: Lobby): void{ if (!this.lobby) this.setPeerEvents() this.lobby = lobby onlineAnswerFrontend() $('.error-label').html('') $('#setup-controls').hide() $('#lobby-members').html('') this.setLobbyMembers() this.setLeaderAbilites() this.checkPlayerCount() $('#lobby > span:eq(1)').html(this.lobby.id) $('#lobby, #chat').show() console.log('Set lobby with id: ', this.lobby.id) } setLobbyMembers(): void{ for (let c of this.lobby.clients){ let dom = $('
') dom.attr('class', 'lobby-member border-node') if (c.id === this.socket.id){ dom.attr('id', 'this-player') } if (this.lobby.leader.id === c.id){ dom.attr('id', 'lobby-leader') } dom.html(c.name) $('#lobby-members').append(dom) } console.log('Set lobby members: ', this.lobby.clients) } setLeaderAbilites(): void{ if (this.socket.id === this.lobby.leader.id){ $('#start-lobby').show() console.log('Leader: ', true) } else { $('#start-lobby').hide() console.log('Leader: ', false) } } checkPlayerCount(): void{ let wrongCount = true let lo = this.lobby let pc = lo.clientCounts for (let c of pc){ if (c === lo.clients.length) wrongCount = false } if (wrongCount){ let error = 'Only as ' for (let c of pc){ let comma = pc.indexOf(c) === pc.length - 1 ? '' : ', ' error += c + comma } $('#lobby .error-label').html(error) $('#start-lobby').prop('disabled', true) } else { $('#lobby .error-label').html('') $('#start-lobby').prop('disabled', false) } } createLobby(dom: any): void{ onlineRequestFrontend(dom) this.socket.emit('create-lobby', this.settings) console.log('Server request: create lobby') } joinLobby(dom: any): void{ let input = getValidInput('join') if (input){ onlineRequestFrontend(dom) this.socket.emit('join-lobby', input) console.log('Server request: join lobby: ', input) } } joinFailed(error: string): void{ onlineAnswerFrontend() $('.error-label').html(error) console.log('Joining lobby failed. Reason: ', error) } startLobby(dom: any): void{ onlineRequestFrontend(dom) this.socket.emit('start-game', this.lobby.id, this.settings) console.log('Server request: start lobby: ', this.lobby.id) } startOnlineGame(): void{ onlineAnswerFrontend() $('#lobby').hide() $('#game-controls').show() game = new OnlineGame(this.socket, this.p2p, this.settings.game) game.init(this.lobby) console.log('Online Game started:', game) } addChatMessage(msg: any): void{ let chat = $('#chat-content'), name: string, message = $('
') if (chat.find('.message').last().attr('name') === "0"){ name = "1" } else name = "0" message.addClass('message') message.attr('name', name) let writer = $(''), content = $('') writer.html('[' + msg.writer + ']: ') content.html(msg.content) message.append(writer, content) chat.append(message) message.get(0).scrollIntoView(false) } sendMessage(): void{ let content = $($('#chat-input > input')[0]).val(), name: string if (content === '') return $($('#chat-input > input')[0]).val('') for (let c of this.lobby.clients){ if (c.id === this.socket.id) name = c.name } let msg = {writer: name, content: content} this.addChatMessage(msg) this.p2p.emit('chat-msg', { lobby: this.lobby.serialized(), msg: { writer: name, content: content } }) } } function onlineRequestFrontend(dom: any): void{ $(dom).blur() $('.setup').prop('disabled', true) if (loader) loader.destroy() loader = new Loader($('#loader').get(0)) } function onlineAnswerFrontend(): void{ $('.setup').prop('disabled', false) if (loader) loader.destroy() } function getValidInput(type: string): string{ $('.error-label').html('') if (type === 'player-name'){ let val = $('#player-name > input').val() if (val === ''){ $('#player-name > .error-label').html('Please enter a name!') } else return val as string } if (type === 'join'){ let val = $('#lobby-code > input').val() if (val === ''){ $('#lobby-code > .error-label').html('Please enter your code!') } else return val as string } return null }