From 9dac257e9b25311a4d0d554b6136f694df4552d0 Mon Sep 17 00:00:00 2001 From: TheBanHammer Date: Fri, 13 May 2016 19:58:26 +0100 Subject: [PATCH] Changed how Owner is initialised. No need to restart pad. Fixes Issue #64. --- socketserver/room.js | 184 +++++++++++++++++++++++-------------------- 1 file changed, 98 insertions(+), 86 deletions(-) diff --git a/socketserver/room.js b/socketserver/room.js index 4979c09..7db3114 100644 --- a/socketserver/room.js +++ b/socketserver/room.js @@ -10,7 +10,7 @@ var DB = require('./database'); var defaultDBObj = function(){ return { - roles: {}, + roles: {}, bans: {}, // Uses UID as key, object containing reason and end time as value. history: [] }; @@ -19,7 +19,7 @@ var defaultDBObj = function(){ var Room = function(socketServer, options){ var that = this; - + this.roomInfo = extend(true, { name: "", // Room name slug: "", // Room name shorthand (no spaces, alphanumeric with dashes) @@ -30,7 +30,7 @@ var Room = function(socketServer, options){ bannedCanSeeChat: true, // Whether banned users can see the chat roomOwnerUN: null, // Username of the room owner to use with lobby API }, options); - + this.socketServer = socketServer; this.queue = new DJQueue( this ); this.attendeeList = []; @@ -42,12 +42,12 @@ var Room = function(socketServer, options){ DB.getRoom(this.roomInfo.slug, function(err, data){ // Just in case the slug doesn't exist yet data = data || {}; - + // If the slug doesn't exist, make owner will make the slug if (err && !err.notFound){console.log(err); return;} - + extend(true, that.data, data); - + that.makeOwner(); }); }; @@ -66,26 +66,30 @@ Room.prototype.getRoomMeta = function(){ Room.prototype.makeOwner = function(){ if (!config.room.ownerEmail) return; - + var that = this; - + DB.getUser(this.roomInfo.ownerEmail, function(err, data){ - if (err) { console.log('Cannot make room owner: ' + err); return; } + if (err == 'UserNotFound') { console.log('Owner does not exist yet.'); that.data.roles.owner = []; return; } + if (err) { console.log('Cannot make Room Owner: ' + err); return; } if (typeof data.uid !== 'number') { console.log('Cannot make room owner: UserUIDError'); return; } - + log.info('Granting ' + data.un + ' (' + data.uid + ') Owner permissions'); - + // Remove user from other roles to avoid interesting bugs for (var i in that.data.roles){ var ind = that.data.roles[i].indexOf(data.uid); if ( ind > -1 ) that.data.roles[i].splice(ind, 1); } - + // Only one owner, set entire array to one UID and set owner username for API that.data.roles.owner = [ data.uid ]; that.data.roomOwnerUN = data.un; that.roomInfo.roomOwnerUN = data.un; + data.role = that.findRole(data.uid); + data.banned = that.isUserBanned(data.uid); + that.sendUserUpdate(data); that.save(); }); }; @@ -95,22 +99,23 @@ Room.prototype.addUser = function( sock ){ var userSend = null; var numGuests = 0; sock.room = this.roomInfo.slug; - + if (sock.user){ + this.checkMakeOwner(); sock.user.data.role = this.findRole(sock.user.data.uid); sock.user.data.banned = this.isUserBanned(sock.user.data.uid); userSend = sock.user.getClientObj(); - + for (var i = 0; i < this.attendeeList.length; i++){ var sockObj = this.attendeeList[i]; - + if (!sockObj.user){ numGuests++; continue; } - + if (sockObj == sock) continue; - + if (sockObj.user && sock.user && sockObj.user.data.uid == sock.user.data.uid){ this.removeUser(sockObj); sockObj.close(1000, JSON.stringify({ @@ -121,13 +126,13 @@ Room.prototype.addUser = function( sock ){ }else{ for (var i = 0; i < this.attendeeList.length; i++){ var sockObj = this.attendeeList[i]; - + if (!sockObj.user){ numGuests++; } } } - + //TODO: Find and add role key to user object from room db this.sendAll({ @@ -140,24 +145,25 @@ Room.prototype.addUser = function( sock ){ function(sockObj){ return sockObj != sock; }); - + }; Room.prototype.replaceUser = function( sock_old, sock_new ){ if (!sock_old || !sock_old.user || !sock_new || !sock_new.user || sock_old.user.data.uid != sock_new.user.data.uid) return false; var ind = this.attendeeList.indexOf(sock_old); - + this.checkMakeOwner(); + if (ind == -1 ) return false; - + sock_new.room = this.roomInfo.slug; - + sock_new.user.data.role = this.findRole(sock_old.user.data.uid); sock_new.user.data.banned = this.isUserBanned(sock_old.user.data.uid); this.attendeeList[ind] = sock_new; - + this.queue.replaceSocket(sock_old, sock_new); - + return true; }; @@ -167,19 +173,19 @@ Room.prototype.removeUser = function( sock ){ if (ind > -1) { sock.room = null; - + var userSend = null; - + this.queue.remove( sock ); - + if (sock.user) { userSend = sock.user.getClientObj(); sock.user.data.role = null; sock.user.data.banned = null; } - + this.attendeeList.splice( ind, 1 ); - + this.sendAll({ type: 'userLeft', data: { @@ -217,24 +223,24 @@ Room.prototype.banUser = function(banObj, callback){ if (callback) callback(err); return; } - + if (that.isUserBanned(banObj.uid)){ if (callback) callback('UserAlreadyBanned'); return; } - + user.role = that.findRole(user.uid); - + if (!Roles.checkCanGrant(banObj.bannedBy.role, [user.role])) { if (callback) callback('UserCannotBeBanned'); return; } - + banObj.reason = banObj.reason.substr(0, 50); - + that.data.bans[banObj.uid] = banObj; that.save(); - + that.sendAll({ type: 'userBanned', data: { @@ -265,22 +271,22 @@ Room.prototype.unbanUser = function(uid, sock){ if (this.data.bans[uid]){ delete this.data.bans[uid]; this.save(); - + this.sendAll({ type: 'userUnbanned', data: { uid: uid, - unbannedBy: (sock ? sock.user.data.uid : null) + unbannedBy: (sock ? sock.user.data.uid : null) } }); - + var userSock = this.findSocketByUid(uid); - + //Check if user is online if (userSock){ userSock.sendJSON({type:'unbanned'}); } - + return true; } return false; @@ -301,47 +307,47 @@ Room.prototype.isUserBanned = function(uid){ Room.prototype.setRole = function(user, role){ if (!user) return false; - + if (!role) role = 'default'; - + role = role.toLowerCase(); - + if (Roles.roleExists(role)){ if (typeof this.data.roles[role] === 'undefined') this.data.roles[role] = []; - + var userSock = this.findSocketByUid(user.uid); var isBanned = this.isUserBanned(user.uid); - + // Remove user from other role this.removeRole(user); - + if (role != 'default') this.data.roles[role].push(user.uid); - + user.role = role; user.banned = isBanned; - - + + // Save the changes this.save(); - + if (userSock){ // We can't assign this user object to the socket because it lacks playlists userSock.user.data.role = role; userSock.user.data.banned = isBanned; } - + this.sendUserUpdate(user); - + return true; } - + return false; }; Room.prototype.removeRole = function(user){ if (!user) return; - + for (var i in this.data.roles){ var ind = this.data.roles[i].indexOf(user.uid); if ( ind > -1){ @@ -352,14 +358,14 @@ Room.prototype.removeRole = function(user){ Room.prototype.findRole = function(uid){ if (!uid) return 'default'; - + for (var i in this.data.roles){ var ind = this.data.roles[i].indexOf(uid); if ( ind > -1 && Roles.roleExists(i) ){ return i; } } - + return 'default'; }; @@ -367,10 +373,10 @@ Room.prototype.findSocketByUid = function( uid ){ for (var i in this.attendeeList){ if (!this.attendeeList[i].user) continue; - + if (this.attendeeList[i].user.data.uid == uid) return this.attendeeList[i]; } - + return null; }; @@ -382,18 +388,18 @@ Room.prototype.getBannedUsers = function(callback){ var banned = []; var rawBanned = []; var that = this; - + for (var i in this.data.bans){ // This will unban appropriately when the list is viewed. if (this.isUserBanned(this.data.bans[i].uid)) rawBanned.push(this.data.bans[i].uid); } - + if (!rawBanned.length){ callback('NoBans'); return; } - + DB.getUserByUid(rawBanned, {getPlaylists: false}, function (err, users) { for (var j in users){ var usr = users[j].getClientObj(); @@ -401,7 +407,7 @@ Room.prototype.getBannedUsers = function(callback){ usr.banned = that.isUserBanned(usr.uid); banned.push(usr); } - + callback(err, banned); }); }; @@ -410,7 +416,7 @@ Room.prototype.getRoomStaff = function(callback){ var staff = []; var rawStaff = []; var that = this; - + for (var i in this.data.roles){ if (Roles.getStaffRoles().indexOf(i) > -1) { rawStaff = rawStaff.concat(this.data.roles[i]); @@ -421,7 +427,7 @@ Room.prototype.getRoomStaff = function(callback){ callback('NoStaff'); return; } - + DB.getUserByUid(rawStaff, { getPlaylists: false }, function (err, users) { for (var j in users){ var usr = users[j].getClientObj(); @@ -429,7 +435,7 @@ Room.prototype.getRoomStaff = function(callback){ usr.banned = that.isUserBanned(usr.uid); staff.push(usr); } - + callback(err, staff); }); }; @@ -444,11 +450,11 @@ Room.prototype.sendBroadcastMessage = function(message) { Room.prototype.sendMessage = function( sock, message, ext, specdata, callback ){ var that = this; - + message = message.substring(0,255).replace(//g, '>'); callback = callback || function(){}; - + DB.logChat(sock.user.uid, message, specdata, function(err, cid){ that.sendAll({ type: 'chat', @@ -462,16 +468,16 @@ Room.prototype.sendMessage = function( sock, message, ext, specdata, callback ){ }, function(obj){ // Guests can't see chat with config variable set if (!that.roomInfo.guestCanSeeChat && !obj.user) return false; - + // Banned users can't see chat with config variable set if (!that.roomInfo.bannedCanSeeChat && obj.user && that.isUserBanned(obj.user.uid)) return false; - + // Check for extensive function if("function" === typeof ext) if(!ext(obj)) return false; - + return true; }); - + //Save last X messages to show newly connected users if(!specdata){ that.lastChat.push({ @@ -482,7 +488,7 @@ Room.prototype.sendMessage = function( sock, message, ext, specdata, callback ){ }); if(that.lastChat.length > config.room.lastmsglimit) that.lastChat.shift(); } - + callback(cid); }); }; @@ -490,17 +496,17 @@ Room.prototype.sendMessage = function( sock, message, ext, specdata, callback ){ Room.prototype.makePrevChatObj = function(){ var uids = []; var temp = extend(true, [], this.lastChat); - + for (var i = 0; i < temp.length; i++){ var ind = uids.indexOf(temp[i].user.uid); if ( ind == -1 ){ uids.push( temp[i].user.uid ); continue; } - + temp[i].user = { uid: temp[i].user.uid }; } - + return temp; }; @@ -511,7 +517,7 @@ Room.prototype.deleteChat = function(cid, uid){ break; } } - + this.sendAll({ type: 'deleteChat', data: { @@ -527,14 +533,14 @@ Room.prototype.sendAll = function (message, condition){ var obj = this.attendeeList[i]; if (obj.readyState != ws.OPEN || !condition(obj)) continue; - + obj.sendJSON(message); } }; Room.prototype.sendUserUpdate = function(user){ if (!user) return; - + this.sendAll({ type: 'userUpdate', data: { @@ -549,17 +555,17 @@ Room.prototype.getUsersObj = function(){ users: {} }; var guestCounter = 0; - + for (var i = 0; i < this.attendeeList.length; i++){ var obj = this.attendeeList[i]; if (!obj.user){ temp.guests++; continue; } - + temp.users[ obj.user.uid ] = obj.user.getClientObj(); } - + return temp; }; @@ -573,7 +579,7 @@ Room.prototype.addToHistory = function(historyObj) { while(this.data.history.length >= config.room.history.limit_save) { this.data.history.shift(); } - + //Add to history and save this.data.history.push(historyObj); this.save(); @@ -623,16 +629,16 @@ Room.prototype.updateLobbyServer = function(song, dj, callback) { postReq.end(); } catch (e) { - + } - + this.createApiTimeout(); }; Room.prototype.createApiTimeout = function() { var that = this; clearTimeout(this.apiUpdateTimeout); - + this.apiUpdateTimeout = setTimeout(function() { if (that.queue.currentsong && that.queue.currentdj) { that.updateLobbyServer(that.queue.currentsong, that.queue.currentdj ? that.queue.currentdj.user.getClientObj() : null); @@ -658,4 +664,10 @@ Room.prototype.save = function(){ DB.setRoom(this.roomInfo.slug, this.makeDbObject()); }; +Room.prototype.checkMakeOwner = function() { + if (this.data.roles.owner && this.data.roles.owner.length == 0) { + this.makeOwner(); + } +} + module.exports = Room;