synclounge/server.js

329 lines
12 KiB
JavaScript

// ABOUT
// Runs the Plex Together Server software - handles rooms
// Defaults to 8089
// USER CONFIG
var PORT = 8089
// END USER CONFIG
var express = require('express');
var path = require('path');
var cors = require('cors')
var root = express()
root.use(cors())
var combined = express()
var ptserver = express();
// Setup our PTServer
ptserver.get('/',function(req,res){
return res.send("You've connected to the PTServer, you're probably looking for the webapp.")
})
// Merge everything together
root.use('/ptserver',ptserver)
root.get('*',function(req,res){
return res.send('You\'ve connected to the PTServer, you\'re probably looking for the webapp.')
})
var rootserver = require('http').createServer(root);
var ptserver_io = require('socket.io')(rootserver,{path: '/ptserver/socket.io'});
ptserver_io.on('connection', function(socket){
console.log('Someone connected to the ptserver socket')
socket.on('join',function(data){
//A user is attempting to join a room
if (data == null){
return
}
var tempUser = new user()
var result = true
var _data = {}
var details = "Successfully connected to " + data.room
if (socket.selfUser != null || socket.selfUser != undefined){
//Already in a room! Leave the room we're in
handleDisconnect(false)
}
var room = ptserver_io.sockets.adapter.rooms[data.room]
let isFresh = false
if (room === undefined || room.users === undefined || room.users === null){
isFresh = true
socket.join(data.room)
room = ptserver_io.sockets.adapter.rooms[data.room]
room.users = []
room.password = data.password
tempUser.role = 'host'
tempUser.username = getValidUsername([],data.username)
} else {
tempUser.username = getValidUsername(room.users,data.username)
if (room.password == null || room.password == ''){
//Check if we've already got a Host
if (room.hostUsername == null){
// We dont have a host user yet.
// This should never happen..
room.hostUsername = tempUser.username
tempUser.role = 'host'
socket.join(data.room)
} else {
tempUser.role = 'guest'
socket.join(data.room)
}
} else {
//This room has a password
if (room.password == data.password){
//Good password!
if (room.hostUsername == null){
//We dont have a host user yet.
console.log('We dont have a host user')
room.hostUsername = tempUser.username
tempUser.role = 'host'
socket.join(data.room)
} else {
tempUser.role = 'guest'
socket.join(data.room)
}
} else {
result = false
details = 'wrong password'
}
}
}
tempUser.avatarUrl = data.avatarUrl
//We've sorted out where the user should go, lets send back
var currentUsers = null
if (result){
tempUser.room = data.room
console.log('User ' + tempUser.username + ' joined ' + tempUser.room)
if (tempUser.role == 'host'){
room.hostUsername = tempUser.username
}
room.users.push(tempUser)
console.log('they joined OK and were given the username ' + tempUser.username)
socket.broadcast.to(data.room).emit('user-joined',room.users,tempUser)
//Set some objects on the socket for ease of use down the road
socket.ourRoom = data.room
socket.selfUser = tempUser
currentUsers = room.users
} else {
console.log('User failed to join a room')
}
_data = tempUser
socket.emit('join-result',result,_data,details,currentUsers)
})
socket.on('poll', function(data){
if (socket.ourRoom == null){
//console.log('This user should join a room first')
socket.emit('flowerror','You aren\' connected to a room! Use join')
socket.emit('rejoin')
return
}
//Recieved an update from a user
updateUserData(socket.selfUser.username,data,socket.selfUser.room)
//var users = io.sockets.adapter.rooms['hotline123'].users
//console.log(JSON.stringify(io.sockets.adapter.rooms, null, 2))
/*var clients_in_the_room = io.sockets.adapter.rooms[roomId];
for (var clientId in clients_in_the_room ) {
//console.log('client: %s', clientId); //Seeing is believing
var client_socket = io.sockets.connected[clientId];//Do whatever you want with this
}
*/
socket.emit('poll-result',ptserver_io.sockets.adapter.rooms[socket.selfUser.room].users)
var room = ptserver_io.sockets.adapter.rooms[socket.selfUser.room]
if (socket.selfUser.role == 'host'){
//We're the host, broadcast to all clients our data
var temp = {}
temp.time = data.time
temp.maxTime = data.maxTime
temp.title = data.title
temp.rawTitle = data.rawTitle
temp.lastHeartbeat = (new Date).getTime()
temp.playerState = data.playerState
temp.clientResponseTime = data.clientResponseTime
temp.type = data.type
temp.showName = data.showName
socket.broadcast.to(socket.selfUser.room).emit('host-update',temp)
}
});
socket.on('send_message',function(msg){
//console.log(msg)
if (socket.ourRoom == null){
//console.log('This user should join a room first')
socket.emit('flowerror','You aren\' connected to a room! Use join')
socket.emit('rejoin')
return
}
//console.log('New message in channel ' + socket.selfUser.room + ' from ' + socket.selfUser.username + ' saying ' + msg)
socket.broadcast.to(socket.selfUser.room).emit('new_message',{
msg: msg.msg,
user: {
username: socket.selfUser.username,
thumb: socket.selfUser.avatarUrl
},
type: msg.type
})
})
socket.on('connect_timeout',function(){
//console.log('timeout')
handleDisconnect(true)
})
socket.on('disconnect', function(){
handleDisconnect(true)
});
function handleDisconnect(disconnect){
if (socket.selfUser === undefined || socket.selfUser === null){
return
}
//console.log('User left: ' + socket.selfUser.username)
if (socket.selfUser.role == 'host'){
//Our Host has left, lets give the next Guest the Host role
var newHost = transferHost(socket.selfUser.room)
//console.log('The new host is ' + newHost)
//console.log(JSON.stringify(newHost,null,4))
socket.broadcast.to(socket.selfUser.room).emit('host-swap',newHost)
}
removeUser(socket.selfUser.room,socket.selfUser.username)
if (ptserver_io.sockets.adapter.rooms[socket.selfUser.room]){
socket.broadcast.to(socket.selfUser.room).emit('user-left',ptserver_io.sockets.adapter.rooms[socket.selfUser.room].users,socket.selfUser)
}
socket.disconnect(disconnect)
}
function updateUserData(username,userData,room){
for (var i in ptserver_io.sockets.adapter.rooms[room].users){
var user = ptserver_io.sockets.adapter.rooms[room].users[i]
if (user.username == username){
//This is our user
user.time = userData.time
user.maxTime = userData.maxTime
user.title = userData.title
user.lastHeartbeat = (new Date).getTime()
user.playerState = userData.playerState
user.rawTitle = userData.rawTitle
user.clientResponseTime = userData.clientResponseTime
user.type = userData.type
user.showName = userData.showName
return
}
}
}
function transferHost(roomName){
console.log('Transfering the host in the room ' + roomName)
var room = ptserver_io.sockets.adapter.rooms[roomName]
if (room === undefined){
//Room has already been destroyed!
return
}
var oldHost = removeHost(room)
if (oldHost === null || oldHost === undefined) {
return
}
for (var i in room.users){
if (room.users[i].username != oldHost.username){
//This is a valid user
//console.log('Transferred host to ' + room.users[i].username)
room.users[i].role = 'host'
room.hostUser = room.users[i]
room.hostUsername = room.users[i].username
return (room.users[i])
}
}
}
function removeHost(room){
if (room === undefined){
//Room has already been destroyed!
return
}
for (var i in room.users){
if (room.users[i].role == 'host'){
room.users[i].role = 'guest'
return(room.users[i])
}
}
}
function removeUser(roomname,username){
var room = ptserver_io.sockets.adapter.rooms[roomname]
if (room === undefined){
return
}
for (var i in room.users){
if (room.users[i].username == username){
//This is the user that we need to remove
room.users.splice(i,1)
}
}
}
function getValidUsername(usersarray,wantedname){
var tempname = wantedname
while (true){
//We need to loop through the users list until we create a valid name
var found = false;
for (var i in usersarray){
if (usersarray[i].username == tempname){
//console.log(usersarray[i].username + ' == ' + tempname)
found = true;
}
}
if (found){
//Looks like that username is taken
//Check if we've already appended '(x)'
if (tempname.indexOf('(') > -1){
//we have
var value = parseInt(tempname.substring(
tempname.indexOf('(')+1,tempname.indexOf(')')))
var newvalue = value + 1
tempname = tempname.replace('('+value+')','('+newvalue+')')
} else {
//we haven't
tempname = tempname + '(1)'
}
} else {
//This is a valid name!
return tempname
}
}
}
var user = function(){
this.username = null;
this.role = null;
this.room = null;
this.title = null;
this.time = null;
this.avatarUrl = null;
}
});
rootserver.listen(PORT);
console.log('PlexTogether Server successfully started on port ' + PORT)
setInterval(function(){
console.log('Connected users: ' + Object.keys(ptserver_io.sockets.connected).length)
},5000)