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.7 KiB

2 years ago
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 = $('<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
}