From 89cca0d552a4a749d744e88d59279dcdd1dc1c7d Mon Sep 17 00:00:00 2001 From: calzoneman Date: Wed, 1 Jan 2014 22:18:33 -0500 Subject: [PATCH] continue working on channel.js --- lib/channel-new.js | 251 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 250 insertions(+), 1 deletion(-) diff --git a/lib/channel-new.js b/lib/channel-new.js index 8fd768fa..ceda41e1 100644 --- a/lib/channel-new.js +++ b/lib/channel-new.js @@ -845,7 +845,7 @@ Channel.prototype.sendChatFilters = function (users) { */ Channel.prototype.sendPlaylist = function (users) { var self = this; - + var pl = self.playlist.items.toArray(); var current = null; if (self.playlist.current) { @@ -1129,6 +1129,255 @@ Channel.prototype.sendDrinks = function (users) { }); }; +/** + * Resets video-related variables + */ +Channel.prototype.resetVideo = function () { + this.voteskip = false; + this.sendVoteskipUpdate(this.users); + this.drinks = 0; + this.sendDrinks(this.users); +}; + +/** + * Handles a queue message from a client + */ +Channel.prototype.handleQueue = function (user, data) { + // Verify the user has permission to add + if (!this.hasPermission(user, "playlistadd")) { + return; + } + + // Verify data types + if (typeof data.id !== "string" && data.id !== false) { + return; + } + var id = data.id || false; + + if (typeof data.type !== "string") { + return; + } + var type = data.type; + var link = util.formatLink(id, type); + + // Verify user has the permission to add at the position given + if (data.pos === "next" && !this.hasPermission(user, "playlistnext")) { + return; + } + var pos = data.pos || "end"; + + // Verify user has permission to add a YouTube playlist, if relevant + if (data.type === "yp" && !this.hasPermission(user, "playlistaddlist")) { + user.socket.emit("queueFail", { + msg: "You don't have permission to add playlists", + link: link + }); + return; + } + + // Verify the user has permission to add livestreams, if relevant + if (isLive(type) && !this.hasPermission(user, "playlistaddlive")) { + user.socket.emit("queueFail", { + msg: "You don't have permission to add livestreams", + link: link + }); + return; + } + + // Verify the user has permission to add a Custom Embed, if relevant + if (data.type === "cu" && !this.hasPermission(user, "playlistaddcustom")) { + user.socket.emit("queueFail", { + msg: "You don't have permission to add custom embeds", + link: null + }); + return; + } + + /** + * Always reset any user-provided title if it's not a custom embed. + * Additionally reset if it is a custom embed but a title is not provided + */ + if (typeof data.title !== "string" || data.type !== "cu") { + data.title = false; + } + var title = data.title || false; + + var queueby = user != null ? user.name : ""; + var temp = data.temp || !this.hasPermission(user, "addnontemp"); + + // Throttle video adds + var limit = { + burst: 3, + sustained: 1 + }; + + if (user.rank >= 2 || this.leader === user) { + limit = { + burst: 10, + sustained: 2 + }; + } + + if (user.queueLimiter.throttle(limit)) { + user.socket.emit("queueFail", { + msg: "You are adding videos too quickly", + link: null + }); + return; + } + + // Actually add the video + this.addMedia({ + id: id, + title: title, + pos: pos, + queueby: queueby, + temp: temp, + type: type, + maxlength: this.hasPermission(user, "exceedmaxlength") ? 0 : this.opts.maxlength + }, function (err, media) { + if (err) { + user.socket.emit("queueFail", { + msg: err, + link: link + }); + return; + } + + if (media.restricted) { + user.socket.emit("queueWarn", { + msg: "This video is blocked in the following countries: " + + media.restricted, + link: link + }); + return; + } + }); +}; + +/** + * Add a video to the playlist + */ +Channel.prototype.addMedia = function (data, callback) { + var self = this; + + if (data.type === "cu" && typeof data.title === "string") { + var t = data.title; + if (t.length > 100) { + t = t.substring(0, 97) + "..."; + } + data.title = t; + } + + if (data.pos === "end") { + data.pos === "append"; + } + + var afterLookup = function (lock, shouldCache, media) { + if (data.maxlength && media.seconds > data.maxlength) { + callback("Maximum length exceeded: " + data.maxlength + " seconds", null); + lock.release(); + return; + } + + media.pos = data.pos; + media.queueby = data.queueby; + media.temp = data.temp; + var res = self.playlist.addMedia(media); + if (res.error) { + callback(res.error, null); + lock.release(); + return; + } + + self.logger.log("### " + data.queueby + " queued " + media.title); + + var item = res.item; + var packet = { + item: item.pack(), + after: item.prev ? item.prev.uid : "prepend" + }; + self.users.forEach(function (u) { + u.socket.emit("queue", packet); + }); + + self.sendPlaylistMeta(self.users); + + if (shouldCache) { + self.cacheMedia(media); + } + + lock.release(); + callback(null, media); + }; + + // Cached video data + if (data.type !== "cu" && typeof data.title === "string") { + self.plqueue.queue(function (lock) { + var m = new Media(data.id, data.title, data.seconds, data.type); + afterData(lock, false, m); + }); + return; + } + + // YouTube playlists + if (data.type === "yp") { + self.plqueue.queue(function (lock) { + InfoGetter.getMedia(data.id, data.type, function (e, vids) { + if (e) { + callback(e, null); + lock.release(); + return; + } + + // If queueing next, reverse queue order so the videos end up + // in the correct order + if (data.pos === "next") { + vids.reverse(); + // Special case to ensure correct playlist order + if (self.playlist.length === 0) { + vids.unshift(vids.pop()); + } + } + + // We only want to release the lock after the entire playlist + // is processed. Set up a dummy so the same code will work. + var dummy = { + release: function () { } + }; + + for (var i = 0; i < vids.length; i++) { + afterData(dummy, false, vids[i]); + } + + lock.release(); + }); + }); + return; + } + + // Cases where there is no cached data in the database + if (!self.registered || util.isLive(data.type)) { + self.plqueue.queue(function (lock) { + InfoGetter.getMedia(data.id, data.type, function (e, media) { + if (e) { + callback(e, null); + lock.release(); + return; + } + + afterData(lock, false, media); + }); + }); + return; + } + + // Finally, the "normal" case + self.plqueue.queue(function (lock) { + + }); +}; + /** * Searches channel library */