mirror of https://github.com/calzoneman/sync.git
Continue refactoring
This commit is contained in:
parent
0afc184402
commit
b61970652d
793
channel-new.js
793
channel-new.js
|
@ -158,3 +158,796 @@ Channel.prototype.cacheMedia = function(media) {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Channel.prototype.banIP = function(actor, receiver) {
|
||||
if(!Rank.hasPermission(actor, "ipban"))
|
||||
return false;
|
||||
|
||||
this.ipbans[receiver.ip] = [receiver.name, actor.name];
|
||||
receiver.socket.disconnect();
|
||||
this.broadcastBanlist();
|
||||
this.logger.log(bannee.ip + " (" + bannee.name + ") was banned by " + banner.name);
|
||||
|
||||
if(!this.registered)
|
||||
return false;
|
||||
|
||||
// Update database ban table
|
||||
return Database.addChannelBan(this.name, actor, receiver);
|
||||
}
|
||||
|
||||
Channel.prototype.unbanIP = function(actor, ip) {
|
||||
if(!Rank.hasPermission(actor, "ipban"))
|
||||
return false;
|
||||
|
||||
delete this.ipbans[ip];
|
||||
|
||||
if(!this.registered)
|
||||
return false;
|
||||
|
||||
// Update database ban table
|
||||
return Database.removeChannelBan(this.name, ip);
|
||||
}
|
||||
|
||||
Channel.prototype.search = function(query) {
|
||||
query = query.toLowerCase();
|
||||
var results = [];
|
||||
for(var id in this.library) {
|
||||
if(this.library[id].title.toLowerCase().indexOf(query) != -1) {
|
||||
results.push(this.library[id]);
|
||||
}
|
||||
}
|
||||
results.sort(function(a, b) {
|
||||
var x = a.title.toLowerCase();
|
||||
var y = b.title.toLowerCase();
|
||||
|
||||
return (x == y) ? 0 : (x < y ? -1 : 1);
|
||||
});
|
||||
return results;
|
||||
}
|
||||
|
||||
/* REGION User interaction */
|
||||
|
||||
Channel.prototype.userJoin = function(user) {
|
||||
// GTFO
|
||||
if(user.ip in this.ipbans) {
|
||||
this.logger.log("--- Kicking " + user.ip + " - banned");
|
||||
user.socket.disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
// Join the socket pool for this channel
|
||||
user.socket.join(this.name);
|
||||
|
||||
// Prevent duplicate login
|
||||
if(user.name != "") {
|
||||
for(var i = 0; i < this.users.length; i++) {
|
||||
if(this.users[i].name == user.name) {
|
||||
user.name = "";
|
||||
user.loggedIn = false;
|
||||
user.socket.emit("login", {
|
||||
success: false,
|
||||
error: "The username " + user.name + " is already in use on this channel"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the channel is empty and isn't registered, the first person
|
||||
// gets ownership of the channel (temporarily)
|
||||
if(this.users.length == 0 && !this.registered) {
|
||||
user.rank = (user.rank < Rank.Owner) ? Rank.Owner + 7 : user.rank;
|
||||
user.socket.emit("channelNotRegistered");
|
||||
}
|
||||
this.users.push(user);
|
||||
if(user.name != "") {
|
||||
this.broadcastNewUser(user);
|
||||
}
|
||||
this.broadcastUsercount();
|
||||
|
||||
// Set the new guy up
|
||||
this.sendPlaylist(user);
|
||||
if(user.playerReady)
|
||||
this.sendMediaUpdate(user);
|
||||
user.socket.emit("queueLock", {locked: this.qlocked});
|
||||
this.sendUserlist(user);
|
||||
this.sendRecentChat(user);
|
||||
if(this.poll) {
|
||||
user.socket.emit("newPoll", this.poll.packUpdate());
|
||||
}
|
||||
user.socket.emit("channelOpts", this.opts);
|
||||
user.socket.emit("updateMotd", this.motd);
|
||||
|
||||
// Send things that require special permission
|
||||
this.sendRankStuff(user);
|
||||
|
||||
this.logger.log("+++ /" + user.ip + " joined");
|
||||
Logger.syslog.log("/" + user.ip + " joined channel " + this.name);
|
||||
}
|
||||
|
||||
Channel.prototype.userLeave = function(user) {
|
||||
// Their socket might already be dead, so wrap in a try-catch
|
||||
try {
|
||||
user.socket.leave(this.name);
|
||||
}
|
||||
catch(e) {}
|
||||
|
||||
// Undo vote for people who leave
|
||||
if(this.poll) {
|
||||
this.poll.unvote(user.ip);
|
||||
this.broadcastPollUpdate();
|
||||
}
|
||||
if(this.voteskip) {
|
||||
this.voteskip.unvote(user.ip);
|
||||
}
|
||||
|
||||
// If they were leading, return control to the server
|
||||
if(this.leader == user) {
|
||||
this.changeLeader("");
|
||||
}
|
||||
|
||||
// Remove the user from the client list for this channel
|
||||
var idx = this.users.indexOf(user);
|
||||
if(idx >= 0 && idx < this.users.length)
|
||||
this.users.splice(idx, 1);
|
||||
this.broadcastUsercount();
|
||||
if(user.name != "") {
|
||||
this.sendAll("userLeave", {
|
||||
name: user.name
|
||||
});
|
||||
}
|
||||
this.logger.log("--- /" + user.ip + " (" + user.name + ") left");
|
||||
}
|
||||
|
||||
Channel.prototype.sendRankStuff = function(user) {
|
||||
if(Rank.hasPermission(user, "ipban")) {
|
||||
var ents = [];
|
||||
for(var ip in this.ipbans) {
|
||||
if(this.ipbans[ip] != null) {
|
||||
ents.push({
|
||||
ip: ip,
|
||||
name: this.ipbans[ip][0],
|
||||
banner: this.ipbans[ip][1]
|
||||
});
|
||||
}
|
||||
}
|
||||
user.socket.emit("banlist", {entries: ents});
|
||||
}
|
||||
if(Rank.hasPermission(user, "chatFilter")) {
|
||||
var filts = new Array(this.filters.length);
|
||||
for(var i = 0; i < this.filters.length; i++) {
|
||||
filts[i] = [this.filters[i][0].source, this.filters[i][1], this.filters[i][2]];
|
||||
}
|
||||
user.socket.emit("chatFilters", {filters: filts});
|
||||
}
|
||||
}
|
||||
|
||||
Channel.prototype.sendPlaylist = function(user) {
|
||||
user.socket.emit("playlist", {
|
||||
pl: this.queue
|
||||
});
|
||||
user.socket.emit("updatePlaylistIdx", {
|
||||
idx: this.currentPosition
|
||||
});
|
||||
}
|
||||
|
||||
Channel.prototype.sendMediaUpdate = function(user) {
|
||||
if(this.media != null) {
|
||||
user.socket.emit("mediaUpdate", this.media.packupdate());
|
||||
}
|
||||
}
|
||||
|
||||
Channel.prototype.sendUserlist = function(user) {
|
||||
var users = [];
|
||||
for(var i = 0; i < this.users.length; i++) {
|
||||
// Skip people who haven't logged in
|
||||
if(this.users[i].name != "") {
|
||||
users.push({
|
||||
name: this.users[i].name,
|
||||
rank: this.users[i].rank,
|
||||
leader: this.users[i] == this.leader
|
||||
});
|
||||
}
|
||||
}
|
||||
user.socket.emit("userlist", users);
|
||||
}
|
||||
|
||||
// Send the last 15 messages for context
|
||||
Channel.prototype.sendRecentChat = function(user) {
|
||||
for(var i = 0; i < this.recentChat.length; i++) {
|
||||
user.socket.emit("chatMsg", this.recentChat[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* REGION Broadcasts to all clients */
|
||||
|
||||
Channel.prototype.sendAll = function(message, data) {
|
||||
io.sockets.in(this.name).emit(message, data);
|
||||
}
|
||||
|
||||
Channel.prototype.broadcastUsercount = function() {
|
||||
this.sendAll("usercount", {
|
||||
count: this.users.length
|
||||
});
|
||||
}
|
||||
|
||||
Channel.prototype.broadcastNewUser = function(user) {
|
||||
this.sendAll("addUser", {
|
||||
name: user.name,
|
||||
rank: user.rank,
|
||||
leader: this.leader == user
|
||||
});
|
||||
this.sendRankStuff(user);
|
||||
}
|
||||
|
||||
Channel.prototype.broadcastRankUpdate = function(user) {
|
||||
this.sendAll("updateUser", {
|
||||
name: user.name,
|
||||
rank: user.rank,
|
||||
leader: this.leader == user
|
||||
});
|
||||
this.sendRankStuff(user);
|
||||
}
|
||||
|
||||
Channel.prototype.broadcastPoll = function() {
|
||||
this.sendAll("newPoll", this.poll.packUpdate());
|
||||
}
|
||||
|
||||
Channel.prototype.broadcastPollUpdate = function() {
|
||||
this.sendAll("updatePoll", this.poll.packUpdate());
|
||||
}
|
||||
|
||||
Channel.prototype.broadcastPollClose = function() {
|
||||
this.sendAll("closePoll");
|
||||
}
|
||||
|
||||
Channel.prototype.broadcastOpts = function() {
|
||||
this.sendAll("channelOpts", this.opts);
|
||||
}
|
||||
|
||||
Channel.prototype.broadcastBanlist = function() {
|
||||
var ents = [];
|
||||
for(var ip in this.ipbans) {
|
||||
if(this.ipbans[ip] != null) {
|
||||
ents.push({
|
||||
ip: ip,
|
||||
name: this.ipbans[ip][0],
|
||||
banner: this.ipbans[ip][1]
|
||||
});
|
||||
}
|
||||
}
|
||||
for(var i = 0; i < this.users.length; i++) {
|
||||
if(Rank.hasPermission(this.users[i], "ipban")) {
|
||||
this.users[i].socket.emit("banlist", {entries: ents});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Channel.prototype.broadcastChatFilters = function() {
|
||||
var filts = new Array(this.filters.length);
|
||||
for(var i = 0; i < this.filters.length; i++) {
|
||||
filts[i] = [this.filters[i][0].source, this.filters[i][1], this.filters[i][2]];
|
||||
}
|
||||
for(var i = 0; i < this.users.length; i++) {
|
||||
if(Rank.hasPermission(this.users[i], "chatFilter")) {
|
||||
this.users[i].socket.emit("chatFilters", {filters: filts});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Channel.prototype.broadcastMotd = function() {
|
||||
this.sendAll("updateMotd", this.motd);
|
||||
}
|
||||
|
||||
/* REGION Playlist Stuff */
|
||||
|
||||
// The server autolead function
|
||||
function mediaUpdate(chan, id) {
|
||||
// Bail cases - video changed, someone's leader, no vidoe playing
|
||||
if(chan.currentMedia == null ||
|
||||
id != chan.currentMedia.id ||
|
||||
chan.leader != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
chan.currentMedia.currentTime += (new Date().getTime() - chan.time) / 1000.0;
|
||||
chan.time = new Date().getTime();
|
||||
|
||||
// Show's over, move on to the next thing
|
||||
if(chan.currentMedia.currentTime > chan.currentMedia.seconds) {
|
||||
chan.playNext();
|
||||
}
|
||||
// Send updates about every 5 seconds
|
||||
else if(chan.i % 5 == 0) {
|
||||
chan.sendAll("mediaUpdate", chan.currentMedia.packupdate());
|
||||
}
|
||||
chan.i++;
|
||||
|
||||
setTimeout(function() { channelVideoUpdate(chan, id); }, 1000);
|
||||
}
|
||||
|
||||
Channel.prototype.queue = function(data) {
|
||||
var idx = data.pos == "next" ? this.position + 1 : this.queue.length;
|
||||
|
||||
// Prefer cache over looking up new data
|
||||
if(data.id in this.library) {
|
||||
this.queue.splice(idx, 0, this.library[data.id]);
|
||||
this.sendAll("queue", {
|
||||
media: this.library[data.id].pack(),
|
||||
pos: idx
|
||||
});
|
||||
this.logger.log("*** Queued from cache: id=" + data.id);
|
||||
}
|
||||
else {
|
||||
switch(data.type) {
|
||||
case "yt":
|
||||
case "vi":
|
||||
case "dm":
|
||||
case "sc":
|
||||
InfoGetter.getMedia(data.id, data.type, function(media) {
|
||||
this.queue.splice(idx, 0, media);
|
||||
this.sendAll("queue", {
|
||||
media: media.pack(),
|
||||
pos: idx
|
||||
});
|
||||
this.cacheMedia(media);
|
||||
}.bind(this));
|
||||
break;
|
||||
case "li":
|
||||
var media = new Media(data.id, "Livestream ~ " + data.id, "--:--", "li");
|
||||
this.queue.splice(idx, 0, media);
|
||||
this.sendAll("queue", {
|
||||
media: media.pack(),
|
||||
pos: idx
|
||||
});
|
||||
break;
|
||||
case "tw":
|
||||
var media = new Media(data.id, "Twitch ~ " + data.id, "--:--", "li");
|
||||
this.queue.splice(idx, 0, media);
|
||||
this.sendAll("queue", {
|
||||
media: media.pack(),
|
||||
pos: idx
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Channel.prototype.tryQueue = function(user, data) {
|
||||
if(!Rank.hasPermission(user, "queue") &&
|
||||
this.leader != user &&
|
||||
!this.openqueue) {
|
||||
return;
|
||||
}
|
||||
if(data.pos == undefined || data.id == undefined || data.type == undefined) {
|
||||
return;
|
||||
}
|
||||
if(data.pos == "next" && !Rank.hasPermission(user, "queue") &&
|
||||
this.leader != user &&
|
||||
this.openqueue &&
|
||||
!this.opts.qopen_allow_qnext) {
|
||||
return;
|
||||
}
|
||||
this.queue(data);
|
||||
}
|
||||
|
||||
Channel.prototype.dequeue = function(data) {
|
||||
if(data.pos < 0 || data.pos >= this.queue.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.queue.splice(data.pos, 1);
|
||||
this.sendAll("unqueue", {
|
||||
pos: data.pos
|
||||
});
|
||||
|
||||
// If you remove the currently playing video, play the next one
|
||||
if(data.pos == this.position) {
|
||||
this.position--;
|
||||
this.playNext();
|
||||
return;
|
||||
}
|
||||
// If you remove a video whose position is before the one currently
|
||||
// playing, you have to reduce the position of the one playing
|
||||
if(data.pos < this.position) {
|
||||
this.position--;
|
||||
}
|
||||
}
|
||||
|
||||
Channel.prototype.tryDequeue = function(user, data) {
|
||||
if(!Rank.hasPermission(user, "queue") &&
|
||||
this.leader != user &&
|
||||
(!this.openqueue ||
|
||||
this.openqueue && !this.opts.qopen_allow_delete) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(data.pos == undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.dequeue(data);
|
||||
}
|
||||
|
||||
Channel.prototype.playNext = function() {
|
||||
// Nothing to play
|
||||
if(this.queue.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset voteskip
|
||||
this.voteskip = false;
|
||||
|
||||
var old = this.position;
|
||||
// Wrap around if the end is hit
|
||||
if(this.position + 1 >= this.queue.length) {
|
||||
this.position = -1;
|
||||
}
|
||||
|
||||
this.position++;
|
||||
this.media = this.queue[this.position];
|
||||
this.media.currentTime = 0;
|
||||
|
||||
this.sendAll("mediaUpdate", this.media.packupdate());
|
||||
this.sendAll("updatePlaylistIdx", {
|
||||
old: old,
|
||||
idx: this.position
|
||||
});
|
||||
|
||||
// If it's not a livestream, enable autolead
|
||||
if(this.leader == null && this.media.type != "tw"
|
||||
&& this.media.type != "li") {
|
||||
this.time = new Date().getTime();
|
||||
mediaUpdate(this, this.media.id);
|
||||
}
|
||||
}
|
||||
|
||||
Channel.prototype.tryPlayNext = function(user) {
|
||||
if(!Rank.hasPermission(user, "queue") &&
|
||||
this.leader != user &&
|
||||
(!this.openqueue ||
|
||||
this.openqueue && !this.opts.qopen_allow_playnext) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.playNext();
|
||||
}
|
||||
|
||||
Channel.prototype.jumpTo = function(pos) {
|
||||
if(pos >= this.queue.length || pos < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset voteskip
|
||||
this.voteskip = false;
|
||||
|
||||
var.old = this.position;
|
||||
this.position = pos;
|
||||
this.media = this.queue[this.position];
|
||||
this.media.currentTime = 0;
|
||||
|
||||
this.sendAll("mediaUpdate", this.media.packupdate());
|
||||
this.sendAll("updatePlaylistIdx", {
|
||||
old: old,
|
||||
idx: this.position
|
||||
});
|
||||
|
||||
// If it's not a livestream, enable autolead
|
||||
if(this.leader == null && this.media.type != "tw"
|
||||
&& this.media.type != "li") {
|
||||
this.time = new Date().getTime();
|
||||
mediaUpdate(this, this.media.id);
|
||||
}
|
||||
}
|
||||
|
||||
Channel.prototype.tryJumpTo = function(user, data) {
|
||||
if(!Rank.hasPermission(user, "jump") &&
|
||||
this.leader != user) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(data.pos == undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.jumpTo(pos);
|
||||
}
|
||||
|
||||
Channel.prototype.tryUpdate = function(user, data) {
|
||||
if(this.leader != user) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(data.id == undefined || data.title == undefined ||
|
||||
data.seconds == undefined || data.type == undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.media = new Media(data.id, data.title, data.seconds, data.type);
|
||||
this.sendAll("mediaUpdate", this.media.packupdate());
|
||||
}
|
||||
|
||||
Channel.prototype.move = function(data) {
|
||||
if(data.src < 0 || data.src >= this.queue.length) {
|
||||
return;
|
||||
}
|
||||
if(data.dest < 0 || data.dest > this.queue.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
var media = this.queue[data.src];
|
||||
var dest = data.dest > data.src ? data.dest + 1 : data.dest;
|
||||
var src = data.dest > data.src ? data.src : data.src + 1;
|
||||
|
||||
this.queue.splice(dest, 0, media);
|
||||
this.queue.splice(src, 1);
|
||||
this.sendAll("moveVideo", {
|
||||
src: data.src,
|
||||
dest: data.dest
|
||||
});
|
||||
|
||||
// Account for moving things around the active video
|
||||
if(data.src < this.position && data.dest >= this.currentPosition) {
|
||||
this.position--;
|
||||
}
|
||||
else if(data.src > this.position && data.dest < this.currentPosition) {
|
||||
this.position++
|
||||
}
|
||||
else if(data.src == this.position) {
|
||||
this.position = data.dest;
|
||||
}
|
||||
}
|
||||
|
||||
Channel.prototype.tryMove = function(user, data) {
|
||||
if(!Rank.hasPermission(user, "queue") &&
|
||||
this.leader != user &&
|
||||
(!this.openqueue ||
|
||||
this.openqueue || !this.opts.qopen_allow_move) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(data.src == undefined || data.dest == undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.move(data);
|
||||
}
|
||||
|
||||
/* REGION Polls */
|
||||
|
||||
Channel.prototype.tryClosePoll = function(user) {
|
||||
if(!Rank.hasPermission(user, "poll")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(this.poll) {
|
||||
this.poll = false;
|
||||
this.broadcastPollClose();
|
||||
}
|
||||
}
|
||||
|
||||
Channel.prototype.tryVote = function(user, data) {
|
||||
if(data.option == undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(this.poll) {
|
||||
this.poll.vote(user.ip, data.option);
|
||||
this.broadcastPollUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
Channel.prototype.voteskip = function(user) {
|
||||
if(!this.voteskip) {
|
||||
this.voteskip = new Poll("voteskip", "voteskip", ["yes"]);
|
||||
}
|
||||
this.voteskip.vote(user.ip, 0);
|
||||
if(this.voteskip.counts[0] > this.users.length / 2) {
|
||||
this.playNext();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* REGION Channel Option stuff */
|
||||
|
||||
Channel.prototype.setLock = function(locked) {
|
||||
this.openqueue = !locked;
|
||||
this.sendAll("queueLock", {locked: locked});
|
||||
}
|
||||
|
||||
Channel.prototype.trySetLock = function(user, data) {
|
||||
if(!Rank.hasPermission(user, "qlock")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(data.locked == undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setLock(data.locked);
|
||||
}
|
||||
|
||||
Channel.prototype.updateFilter = function(filter) {
|
||||
var found = false;
|
||||
for(var i = 0; i < this.filters.length; i++) {
|
||||
if(this.filters[i][0].source == filter[0].source) {
|
||||
found = true;
|
||||
this.filters[i][1] = filter[1];
|
||||
this.filters[i][2] = filter[2];
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
this.filters.push(filter);
|
||||
}
|
||||
this.broadcastChatFilters();
|
||||
}
|
||||
|
||||
Channel.prototype.removeFilter = function(regex) {
|
||||
for(var i = 0; i < this.filters.length; i++) {
|
||||
if(this.filters[i][0].source == regex) {
|
||||
this.filters.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.broadcastChatFilters();
|
||||
}
|
||||
|
||||
Channel.prototype.tryChangeFilter = function(user, data) {
|
||||
if(!Rank.hasPermission(user, "chatFilter")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(data.cmd == undefined || data.filter == undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(data.cmd == "update") {
|
||||
data.filter[0] = new RegExp(data.filter[0], "g");
|
||||
this.updateFilter(data);
|
||||
}
|
||||
else if(data.cmd == "remove") {
|
||||
this.removeFilter(data.filter[0]);
|
||||
}
|
||||
}
|
||||
|
||||
Channel.prototype.tryUpdateOptions = function(user, data) {
|
||||
if(!Rank.hasPermission(user, "channelOpts")) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(var key in this.opts) {
|
||||
if(key in data) {
|
||||
this.opts[key] = data[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Channel.prototype.updateMotd = function(motd) {
|
||||
var html = motd.replace(/\n/g, "<br>");
|
||||
html = this.filterMessage(html);
|
||||
this.motd = {
|
||||
motd: motd,
|
||||
html: html
|
||||
};
|
||||
this.broadcastMotd();
|
||||
}
|
||||
|
||||
Channel.prototype.tryUpdateMotd = function(user, data) {
|
||||
if(!Rank.hasPermission(user, "updateMotd")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(data.motd) {
|
||||
this.updateMotd(data.motd);
|
||||
}
|
||||
}
|
||||
|
||||
/* REGION Chat */
|
||||
|
||||
Channel.prototype.tryChat = function(user, msg) {
|
||||
if(msg.indexOf("/") == 0)
|
||||
ChatCommand.handle(this, user, msg);
|
||||
|
||||
else if(msg.indexOf(">") == 0)
|
||||
this.sendMessage(user.name, msg, "greentext");
|
||||
|
||||
else
|
||||
this.sendMessage(user.name, msg, "");
|
||||
}
|
||||
|
||||
Channel.prototype.filterMessage = function(msg) {
|
||||
msg = msg.replace(/(((https?)|(ftp))(:\/\/[0-9a-zA-Z\.]+(:[0-9]+)?[^\s$]+))/g, "<a href=\"$1\" target=\"_blank\">$1</a>");
|
||||
// Apply other filters
|
||||
for(var i = 0; i < this.filters.length; i++) {
|
||||
if(!this.filters[i][2])
|
||||
continue;
|
||||
var regex = this.filters[i][0];
|
||||
var replace = this.filters[i][1];
|
||||
msg = msg.replace(regex, replace);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
Channel.prototype.sendMessage = function(username, msg, msgclass) {
|
||||
// I don't want HTML from strangers
|
||||
msg = msg.replace(/</g, "<").replace(/>/g, ">");
|
||||
msg = this.filterMessage(msg);
|
||||
this.sendAll("chatMsg", {
|
||||
username: username,
|
||||
msg: msg,
|
||||
msgclass: msgclass
|
||||
});
|
||||
this.recentChat.push({
|
||||
username: username,
|
||||
msg: msg,
|
||||
msgclass: msgclass
|
||||
});
|
||||
if(this.chatbuffer.length > 15)
|
||||
this.chatbuffer.shift();
|
||||
this.logger.log("<" + username + "." + msgclass + "> " + msg);
|
||||
};
|
||||
|
||||
/* REGION Rank stuff */
|
||||
|
||||
Channel.prototype.tryPromoteUser = function(actor, data) {
|
||||
if(!Rank.hasPermission(actor, "promote")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(data.name == undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
var name = data.name;
|
||||
|
||||
var receiver;
|
||||
for(var i = 0; i < this.users.length; i++) {
|
||||
if(this.users[i].name == name) {
|
||||
receiver = this.users[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(receiver) {
|
||||
if(actor.rank > receiver.rank + 1) {
|
||||
receiver.rank++;
|
||||
if(receiver.loggedIn) {
|
||||
this.saveRank(receiver);
|
||||
}
|
||||
this.logger.log("*** " + actor.name + " promoted " + receiver.name + " from " + (receiver.rank - 1) + " to " + receiver.rank);
|
||||
this.broadcastRankUpdate(receiver);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Channel.prototype.tryDemoteUser = function(actor, data) {
|
||||
if(!Rank.hasPermission(actor, "promote")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(data.name == undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
var name = data.name;
|
||||
var receiver;
|
||||
for(var i = 0; i < this.users.length; i++) {
|
||||
if(this.users[i].name == name) {
|
||||
receiver = this.users[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(receiver) {
|
||||
if(actor.rank > receiver.rank) {
|
||||
receiver.rank--;
|
||||
if(receiver.loggedIn) {
|
||||
this.saveRank(receiver);
|
||||
}
|
||||
this.logger.log("*** " + actor.name + " demoted " + receiver.name + " from " + (receiver.rank + 1) + " to " + receiver.rank);
|
||||
this.broadcastRankUpdate(receiver);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
30
database.js
30
database.js
|
@ -228,3 +228,33 @@ exports.cacheMedia = function(channame, media) {
|
|||
db.closeSync();
|
||||
return results;
|
||||
}
|
||||
|
||||
exports.addChannelBan(channame, actor, receiver) {
|
||||
var db = exports.getConnection();
|
||||
if(!db) {
|
||||
Logger.errlog.log("exports.addChannelBan: DB connection failed");
|
||||
return false;
|
||||
}
|
||||
var query = "INSERT INTO chan_{1}_bans (`ip`, `name`, `banner`) VALUES ('{2}', '{3}', '{4}')"
|
||||
.replace("{1}", channame)
|
||||
.replace("{2}", reciever.ip)
|
||||
.replace("{3}", reciever.name)
|
||||
.replace("{4}", actor.name);
|
||||
results = db.querySync(query);
|
||||
db.closeSync();
|
||||
return results;
|
||||
}
|
||||
|
||||
exports.removeChannelBan(channame, ip) {
|
||||
var db = exports.getConnection();
|
||||
if(!db) {
|
||||
Logger.errlog.log("exports.removeChannelBan: DB connection failed");
|
||||
return false;
|
||||
}
|
||||
var query = "DELETE FROM chan_{1}_bans WHERE `ip` = '{2}'"
|
||||
.replace("{1}", channame)
|
||||
.replace("{2}", ip);
|
||||
results = db.querySync(query);
|
||||
db.closeSync();
|
||||
return results;
|
||||
}
|
||||
|
|
83
get-info.js
83
get-info.js
|
@ -12,6 +12,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|||
var http = require("http");
|
||||
var https = require("https");
|
||||
var Logger = require("./logger.js");
|
||||
var Media = require("./media.js").Media;
|
||||
|
||||
// Helper function for making an HTTP request and getting the result
|
||||
// as JSON
|
||||
|
@ -130,3 +131,85 @@ exports.getDMInfo = function(id, callback) {
|
|||
dataType: "jsonp",
|
||||
timeout: 1000}, callback);
|
||||
}
|
||||
|
||||
exports.getMedia = function(id, type, callback) {
|
||||
switch(type) {
|
||||
case "yt":
|
||||
exports.getYTInfo(id, function(res, data) {
|
||||
if(res != 200) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Whoever named this should be fired
|
||||
var seconds = data.entry.media$group.yt$duration.seconds;
|
||||
var title = data.entry.title.$t;
|
||||
var media = new Media(id, title, seconds, "yt");
|
||||
callback(media);
|
||||
}
|
||||
catch(e) {
|
||||
Logger.errlog.log("getMedia failed: ");
|
||||
Logger.errlog.log(e);
|
||||
}
|
||||
});
|
||||
break;
|
||||
case "vi":
|
||||
exports.getVIInfo(id, function(res, data) {
|
||||
if(res != 200) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
data = data[0];
|
||||
var seconds = data.duration;
|
||||
var title = data.title;
|
||||
var media = new Media(id, title, seconds, "vi");
|
||||
callback(media);
|
||||
}
|
||||
catch(e) {
|
||||
Logger.errlog.log("getMedia failed: ");
|
||||
Logger.errlog.log(e);
|
||||
}
|
||||
});
|
||||
break;
|
||||
case "dm":
|
||||
exports.getDMInfo(id, function(res, data) {
|
||||
if(res != 200) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
var seconds = data.duration;
|
||||
var title = data.title;
|
||||
var media = new Media(id, title, seconds, "dm");
|
||||
callback(media);
|
||||
}
|
||||
catch(e) {
|
||||
Logger.errlog.log("getMedia failed: ");
|
||||
Logger.errlog.log(e);
|
||||
}
|
||||
});
|
||||
break;
|
||||
case "sc":
|
||||
exports.getSCInfo(id, function(res, data) {
|
||||
if(res != 200) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Soundcloud's durations are in ms
|
||||
var seconds = data.duration / 1000;
|
||||
var title = data.title;
|
||||
var media = new Media(id, title, seconds, "sc");
|
||||
callback(media);
|
||||
}
|
||||
catch(e) {
|
||||
Logger.errlog.log("getMedia failed: ");
|
||||
Logger.errlog.log(e);
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
3
media.js
3
media.js
|
@ -12,6 +12,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|||
// Helper function for formatting a time value in seconds
|
||||
// to the format hh:mm:ss
|
||||
function formatTime(sec) {
|
||||
if(sec == "--:--")
|
||||
return sec;
|
||||
|
||||
sec = Math.floor(sec);
|
||||
var hours="", minutes="", seconds="";
|
||||
if(sec > 3600) {
|
||||
|
|
Loading…
Reference in New Issue