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.
264 lines
7.6 KiB
264 lines
7.6 KiB
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;
|
|
let url = 'https://' + location.hostname + urlQueries
|
|
this.socket = io.connect(url, {
|
|
path: "/pong/"
|
|
})
|
|
|
|
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 = $('<div></div>')
|
|
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 = $('<div></div>')
|
|
if (chat.find('.message').last().attr('name') === "0"){
|
|
name = "1"
|
|
} else name = "0"
|
|
message.addClass('message')
|
|
message.attr('name', name)
|
|
let writer = $('<span></span>'),
|
|
content = $('<span></span>')
|
|
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
|
|
} |