diff --git a/basicBot.js b/basicBot.js index dd1669cd..d17d3d26 100644 --- a/basicBot.js +++ b/basicBot.js @@ -7,6 +7,11 @@ (function () { + /*window.onerror = function() { + var room = JSON.parse(localStorage.getItem("basicBotRoom")); + window.location = 'https://plug.dj' + room.name; + };*/ + API.getWaitListPosition = function(id){ if(typeof id === 'undefined' || id === null){ id = API.getUser().id; @@ -23,9 +28,48 @@ var kill = function () { clearInterval(basicBot.room.autodisableInterval); clearInterval(basicBot.room.afkInterval); + clearInterval(basicBot.room.slackInterval); basicBot.status = false; }; + // This socket server is used solely for statistical and troubleshooting purposes. + // This server may not always be up, but will be used to get live data at any given time. + + var socket = function () { + function loadSocket() { + SockJS.prototype.msg = function(a){this.send(JSON.stringify(a))}; + sock = new SockJS('https://socket-bnzi.c9.io/basicbot'); + sock.onopen = function() { + console.log('Connected to socket!'); + sendToSocket(); + }; + sock.onclose = function() { + console.log('Disconnected from socket, reconnecting every minute ..'); + var reconnect = setTimeout(function(){ loadSocket() }, 60 * 1000); + }; + sock.onmessage = function(broadcast) { + var rawBroadcast = broadcast.data; + var broadcastMessage = rawBroadcast.replace(/["\\]+/g, ''); + API.chatLog(broadcastMessage); + console.log(broadcastMessage); + }; + } + if (typeof SockJS == 'undefined') { + $.getScript('https://cdn.jsdelivr.net/sockjs/0.3.4/sockjs.min.js', loadSocket); + } else loadSocket(); + } + + var sendToSocket = function () { + var basicBotSettings = basicBot.settings; + var basicBotRoom = basicBot.room; + var basicBotInfo = { + time: Date.now(), + version: basicBot.version + }; + var data = {users:API.getUsers(),userinfo:API.getUser(),room:location.pathname,basicBotSettings:basicBotSettings,basicBotRoom:basicBotRoom,basicBotInfo:basicBotInfo}; + return sock.msg(data); + }; + var storeToStorage = function () { localStorage.setItem("basicBotsettings", JSON.stringify(basicBot.settings)); localStorage.setItem("basicBotRoom", JSON.stringify(basicBot.room)); @@ -43,6 +87,8 @@ API.chatLog("There is a chat text missing."); console.log("There is a chat text missing."); return "[Error] No text message found."; + + // TODO: Get missing chat messages from source. } var lit = '%%'; for (var prop in obj) { @@ -54,7 +100,7 @@ var loadChat = function (cb) { if (!cb) cb = function () { }; - $.get("https://rawgit.com/Yemasthui/basicBot/master/lang/langIndex.json", function (json) { + $.get("https://rawgit.com/Masterjh/basicBot/master/lang/langIndex.json", function (json) { var link = basicBot.chatLink; if (json !== null && typeof json !== "undefined") { langIndex = json; @@ -112,7 +158,7 @@ basicBot.room.afkList = room.afkList; basicBot.room.historyList = room.historyList; basicBot.room.mutedUsers = room.mutedUsers; - basicBot.room.autoskip = room.autoskip; + //basicBot.room.autoskip = room.autoskip; basicBot.room.roomstats = room.roomstats; basicBot.room.messages = room.messages; basicBot.room.queue = room.queue; @@ -120,8 +166,8 @@ API.chatLog(basicBot.chat.datarestored); } } - /*var json_sett = null; - var roominfo = document.getElementById("room-info"); + var json_sett = null; + var roominfo = document.getElementById("room-settings"); info = roominfo.textContent; var ref_bot = "@basicBot="; var ind_ref = info.indexOf(ref_bot); @@ -139,7 +185,7 @@ } } }); - }*/ + } }; @@ -161,6 +207,10 @@ return arr; }; + String.prototype.startsWith = function(str) { + return this.substring(0, str.length) === str; + }; + var linkFixer = function (msg) { var parts = msg.splitBetween('= (basicBot.settings.voteSkipLimit)) { API.sendChat(subChat(basicBot.chat.voteskipexceededlimit, {name: dj.username, limit: basicBot.settings.voteSkipLimit})); - API.moderateForceSkip(); + if (basicBot.settings.smartSkip && timeLeft > timeElapsed){ + basicBot.roomUtilities.smartSkip(); + } + else { + API.moderateForceSkip(); + } } } @@ -821,8 +962,12 @@ } }, eventDjadvance: function (obj) { - $("#woot").click(); - var user = basicBot.userUtilities.lookupUser(obj.dj.id) + if (basicBot.settings.autowoot) { + $("#woot").click(); // autowoot + } + + var user = basicBot.userUtilities.lookupUser(obj.dj.id); + var allowSong = false; for(var i = 0; i < basicBot.room.users.length; i++){ if(basicBot.room.users[i].id === user.id){ basicBot.room.users[i].lastDC = { @@ -830,6 +975,8 @@ position: null, songCount: 0 }; + allowSong = basicbot.room.users[i].allowSong; + basicbot.room.users[i].allowSong = false; } } @@ -850,51 +997,109 @@ basicBot.roomUtilities.intervalMessage(); basicBot.room.currentDJID = obj.dj.id; - var mid = obj.media.format + ':' + obj.media.cid; - for (var bl in basicBot.room.blacklists) { - if (basicBot.settings.blacklistEnabled) { - if (basicBot.room.blacklists[bl].indexOf(mid) > -1) { - API.sendChat(subChat(basicBot.chat.isblacklisted, {blacklist: bl})); + var blacklistSkip = setTimeout(function () { + var mid = obj.media.format + ':' + obj.media.cid; + for (var bl in basicBot.room.blacklists) { + if (basicBot.settings.blacklistEnabled) { + if (basicBot.room.blacklists[bl].indexOf(mid) > -1) { + API.sendChat(subChat(basicBot.chat.isblacklisted, {blacklist: bl})); + if (basicBot.settings.smartSkip){ + return basicBot.roomUtilities.smartSkip(); + } + else { + return API.moderateForceSkip(); + } + } + } + } + }, 2000); + var newMedia = obj.media; + var timeLimitSkip = setTimeout(function () { + if (basicBot.settings.timeGuard && newMedia.duration > basicBot.settings.maximumSongLength * 60 && !basicBot.room.roomevent && !allowSong ) { + var name = obj.dj.username; + API.sendChat(subChat(basicBot.chat.timelimit, {name: name, maxlength: basicBot.settings.maximumSongLength})); + if (basicBot.settings.smartSkip){ + return basicBot.roomUtilities.smartSkip(); + } + else { return API.moderateForceSkip(); } } - } - - var alreadyPlayed = false; - for (var i = 0; i < basicBot.room.historyList.length; i++) { - if (basicBot.room.historyList[i][0] === obj.media.cid) { - var firstPlayed = basicBot.room.historyList[i][1]; - var plays = basicBot.room.historyList[i].length - 1; - var lastPlayed = basicBot.room.historyList[i][plays]; - API.sendChat(subChat(basicBot.chat.songknown, {plays: plays, timetotal: basicBot.roomUtilities.msToStr(Date.now() - firstPlayed), lasttime: basicBot.roomUtilities.msToStr(Date.now() - lastPlayed)})); - basicBot.room.historyList[i].push(+new Date()); - alreadyPlayed = true; + }, 2000); + var format = obj.media.format; + var cid = obj.media.cid; + var naSkip = setTimeout(function () { + if (format == 1){ + $.getJSON('https://www.googleapis.com/youtube/v3/videos?id=' + cid + '&key=AIzaSyDcfWu9cGaDnTjPKhg_dy9mUh6H7i4ePZ0&part=snippet&callback=?', function (track){ + if (typeof(track.items[0]) === 'undefined'){ + var name = obj.dj.username; + API.sendChat(subChat(basicBot.chat.notavailable, {name: name})); + if (basicBot.settings.smartSkip){ + return basicBot.roomUtilities.smartSkip(); + } + else { + return API.moderateForceSkip(); + } + } + }); } - } - if (!alreadyPlayed) { - basicBot.room.historyList.push([obj.media.cid, +new Date()]); - } - var newMedia = obj.media; - if (basicBot.settings.timeGuard && newMedia.duration > basicBot.settings.maximumSongLength * 60 && !basicBot.room.roomevent) { + else { + var checkSong = SC.get('/tracks/' + cid, function (track){ + if (typeof track.title === 'undefined'){ + var name = obj.dj.username; + API.sendChat(subChat(basicBot.chat.notavailable, {name: name})); + if (basicBot.settings.smartSkip){ + return basicBot.roomUtilities.smartSkip(); + } + else { + return API.moderateForceSkip(); + } + } + }); + } + }, 2000); + clearTimeout(historySkip); + if (basicBot.settings.historySkip) { + var alreadyPlayed = false; + var apihistory = API.getHistory(); var name = obj.dj.username; - API.sendChat(subChat(basicBot.chat.timelimit, {name: name, maxlength: basicBot.settings.maximumSongLength})); - API.moderateForceSkip(); + var historySkip = setTimeout(function () { + for (var i = 0; i < apihistory.length; i++) { + if (apihistory[i].media.cid === obj.media.cid) { + basicBot.room.historyList[i].push(+new Date()); + alreadyPlayed = true; + API.sendChat(subChat(basicBot.chat.songknown, {name: name})); + if (basicBot.settings.smartSkip){ + return basicBot.roomUtilities.smartSkip(); + } + else { + return API.moderateForceSkip(); + } + } + } + if (!alreadyPlayed) { + basicBot.room.historyList.push([obj.media.cid, +new Date()]); + } + }, 2000); } if (user.ownSong) { API.sendChat(subChat(basicBot.chat.permissionownsong, {name: user.username})); user.ownSong = false; } clearTimeout(basicBot.room.autoskipTimer); - if (basicBot.room.autoskip) { + if (basicBot.settings.autoskip) { var remaining = obj.media.duration * 1000; - basicBot.room.autoskipTimer = setTimeout(function () { - console.log("Skipping track."); - //API.sendChat('Song stuck, skipping...'); - API.moderateForceSkip(); - }, remaining + 3000); + var startcid = API.getMedia().cid; + basicBot.room.autoskipTimer = setTimeout(function() { + var endcid = API.getMedia().cid; + if (startcid === endcid) { + //API.sendChat('Song stuck, skipping...'); + API.moderateForceSkip(); + } + }, remaining + 5000); } storeToStorage(); - + sendToSocket(); }, eventWaitlistupdate: function (users) { if (users.length < 50) { @@ -986,6 +1191,9 @@ API.moderateDeleteChat(chat.cid); return true; } + if (basicBot.settings.cmdDeletion && msg.startsWith(basicBot.settings.commandLiteral)) { + API.moderateDeleteChat(chat.cid); + } /** var plugRoomLinkPatt = /(\bhttps?:\/\/(www.)?plug\.dj[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; if (plugRoomLinkPatt.exec(msg)) { @@ -1020,14 +1228,14 @@ if ((msg.indexOf(joinedroulette) > -1 || msg.indexOf(leftroulette) > -1) && chat.uid === basicBot.loggedInID) { setTimeout(function (id) { API.moderateDeleteChat(id); - }, 2 * 1000, chat.cid); + }, 5 * 1000, chat.cid); return true; } return false; }, commandCheck: function (chat) { var cmd; - if (chat.message.charAt(0) === '!') { + if (chat.message.charAt(0) === basicBot.settings.commandLiteral) { var space = chat.message.indexOf(' '); if (space === -1) { cmd = chat.message; @@ -1037,11 +1245,11 @@ else return false; var userPerm = basicBot.userUtilities.getPermission(chat.uid); //console.log("name: " + chat.un + ", perm: " + userPerm); - if (chat.message !== "!join" && chat.message !== "!leave") { + if (chat.message !== basicBot.settings.commandLiteral + 'join' && chat.message !== basicBot.settings.commandLiteral + "leave") { if (userPerm === 0 && !basicBot.room.usercommand) return void (0); if (!basicBot.room.allcommand) return void (0); } - if (chat.message === '!eta' && basicBot.settings.etaRestriction) { + if (chat.message === basicBot.settings.commandLiteral + 'eta' && basicBot.settings.etaRestriction) { if (userPerm < 2) { var u = basicBot.userUtilities.lookupUser(chat.uid); if (u.lastEta !== null && (Date.now() - u.lastEta) < 1 * 60 * 60 * 1000) { @@ -1074,11 +1282,14 @@ }, basicBot.settings.commandCooldown * 1000); } if (executed) { - API.moderateDeleteChat(chat.cid); - basicBot.room.allcommand = false; - setTimeout(function () { + /*if (basicBot.settings.cmdDeletion) { + API.moderateDeleteChat(chat.cid); + }*/ + + //basicBot.room.allcommand = false; + //setTimeout(function () { basicBot.room.allcommand = true; - }, 5 * 1000); + //}, 5 * 1000); } return executed; }, @@ -1110,14 +1321,12 @@ eventUserskip: $.proxy(this.eventUserskip, this), eventUserjoin: $.proxy(this.eventUserjoin, this), eventUserleave: $.proxy(this.eventUserleave, this), - eventUserfan: $.proxy(this.eventUserfan, this), - eventFriendjoin: $.proxy(this.eventFriendjoin, this), - eventFanjoin: $.proxy(this.eventFanjoin, this), + //eventFriendjoin: $.proxy(this.eventFriendjoin, this), eventVoteupdate: $.proxy(this.eventVoteupdate, this), eventCurateupdate: $.proxy(this.eventCurateupdate, this), eventRoomscoreupdate: $.proxy(this.eventRoomscoreupdate, this), eventDjadvance: $.proxy(this.eventDjadvance, this), - eventDjupdate: $.proxy(this.eventDjupdate, this), + //eventDjupdate: $.proxy(this.eventDjupdate, this), eventWaitlistupdate: $.proxy(this.eventWaitlistupdate, this), eventVoteskip: $.proxy(this.eventVoteskip, this), eventModskip: $.proxy(this.eventModskip, this), @@ -1129,7 +1338,6 @@ API.on(API.USER_SKIP, this.proxy.eventUserskip); API.on(API.USER_JOIN, this.proxy.eventUserjoin); API.on(API.USER_LEAVE, this.proxy.eventUserleave); - API.on(API.USER_FAN, this.proxy.eventUserfan); API.on(API.VOTE_UPDATE, this.proxy.eventVoteupdate); API.on(API.GRAB_UPDATE, this.proxy.eventCurateupdate); API.on(API.ROOM_SCORE_UPDATE, this.proxy.eventRoomscoreupdate); @@ -1144,7 +1352,6 @@ API.off(API.USER_SKIP, this.proxy.eventUserskip); API.off(API.USER_JOIN, this.proxy.eventUserjoin); API.off(API.USER_LEAVE, this.proxy.eventUserleave); - API.off(API.USER_FAN, this.proxy.eventUserfan); API.off(API.VOTE_UPDATE, this.proxy.eventVoteupdate); API.off(API.CURATE_UPDATE, this.proxy.eventCurateupdate); API.off(API.ROOM_SCORE_UPDATE, this.proxy.eventRoomscoreupdate); @@ -1168,6 +1375,31 @@ type: "DELETE" }) }; + + basicBot.room.name = window.location.pathname; + var Check; + + console.log(basicBot.room.name); + + var detect = function(){ + if(basicBot.room.name != window.location.pathname){ + console.log("Killing bot after room change."); + storeToStorage(); + basicBot.disconnectAPI(); + setTimeout(function () { + kill(); + }, 1000); + if (basicBot.settings.roomLock){ + window.location = 'https://plug.dj' + basicBot.room.name; + } + else { + clearInterval(Check); + } + } + }; + + Check = setInterval(function(){ detect() }, 2000); + retrieveSettings(); retrieveFromStorage(); window.bot = basicBot; @@ -1208,11 +1440,16 @@ basicBot.room.autodisableInterval = setInterval(function () { basicBot.room.autodisableFunc(); }, 60 * 60 * 1000); + basicBot.room.slackInterval = setInterval(function(){ + basicBot.roomUtilities.reportUsersSlack(); + },60*60*1000) basicBot.loggedInID = API.getUser().id; basicBot.status = true; API.sendChat('/cap ' + basicBot.settings.startupCap); API.setVolume(basicBot.settings.startupVolume); - $("#woot").click(); + if (basicBot.settings.autowoot) { + $("#woot").click(); + } if (basicBot.settings.startupEmoji) { var emojibuttonoff = $(".icon-emoji-off"); if (emojibuttonoff.length > 0) { @@ -1229,6 +1466,7 @@ } API.chatLog('Avatars capped at ' + basicBot.settings.startupCap); API.chatLog('Volume set to ' + basicBot.settings.startupVolume); + socket(); loadChat(API.sendChat(subChat(basicBot.chat.online, {botname: basicBot.settings.botName, version: basicBot.version}))); }, commands: { @@ -1284,7 +1522,7 @@ if(this.type === 'exact' && chat.message.length !== cmd.length) return void (0); if( !basicBot.commands.executable(this.rank, chat) ) return void (0); else{ - + } } }, @@ -1302,7 +1540,12 @@ var now = Date.now(); var chatters = 0; var time; - if (msg.length === cmd.length) time = 60; + + var launchT = basicBot.room.roomstats.launchTime; + var durationOnline = Date.now() - launchT; + var since = durationOnline / 1000; + + if (msg.length === cmd.length) time = since; else { time = msg.substring(cmd.length + 1); if (isNaN(time)) return API.sendChat(subChat(basicBot.chat.invalidtime, {name: chat.un})); @@ -1421,7 +1664,34 @@ var lastActive = basicBot.userUtilities.getLastActivity(user); var inactivity = Date.now() - lastActive; var time = basicBot.roomUtilities.msToStr(inactivity); + + var launchT = basicBot.room.roomstats.launchTime; + var durationOnline = Date.now() - launchT; + + if (inactivity == durationOnline){ + API.sendChat(subChat(basicBot.chat.inactivelonger, {botname: basicBot.settings.botName, name: chat.un, username: name})); + } else { API.sendChat(subChat(basicBot.chat.inactivefor, {name: chat.un, username: name, time: time})); + } + } + } + }, + + allowsongCommand: { + command: 'allowsong', + rank: 'mod', + type: 'startsWith', + functionality: function (chat, cmd) { + if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); + if (!basicBot.commands.executable(this.rank, chat)) return void (0); + else { + var msg = chat.message; + if (msg.length === cmd.length) return API.sendChat(subChat(basicBot.chat.nouserspecified, {name: chat.un})); + var name; + name = msg.substring(cmd.length + 2); + var user = basicBot.userUtilities.allowSong(name); + if (typeof user === 'boolean') return API.sendChat(subChat(basicBot.chat.invaliduserspecified, {name: chat.un})); + return API.sendChat(subChat(basicBot.chat.allownextsong, {name: user.username})); } } }, @@ -1455,13 +1725,13 @@ if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); if (!basicBot.commands.executable(this.rank, chat)) return void (0); else { - if (basicBot.room.autoskip) { - basicBot.room.autoskip = !basicBot.room.autoskip; + if (basicBot.settings.autoskip) { + basicBot.settings.autoskip = !basicBot.settings.autoskip; clearTimeout(basicBot.room.autoskipTimer); return API.sendChat(subChat(basicBot.chat.toggleoff, {name: chat.un, 'function': basicBot.chat.autoskip})); } else { - basicBot.room.autoskip = !basicBot.room.autoskip; + basicBot.settings.autoskip = !basicBot.settings.autoskip; return API.sendChat(subChat(basicBot.chat.toggleon, {name: chat.un, 'function': basicBot.chat.autoskip})); } } @@ -1494,9 +1764,28 @@ } }, + ballCommand: { + command: ['8ball', 'ask'], + rank: 'user', + type: 'startsWith', + functionality: function (chat, cmd) { + if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); + if (!basicBot.commands.executable(this.rank, chat)) return void (0); + else { + var crowd = API.getUsers(); + var msg = chat.message; + var argument = msg.substring(cmd.length + 1).replace(/@/g, ''); + var randomUser = Math.floor(Math.random() * crowd.length); + var randomBall = Math.floor(Math.random() * basicBot.chat.balls.length); + var randomSentence = Math.floor(Math.random() * 1); + API.sendChat(subChat(basicBot.chat.ball, {name: chat.un, botname: basicBot.settings.botName, question: argument, response: basicBot.chat.balls[randomBall]})); + } + } + }, + banCommand: { command: 'ban', - rank: 'bouncer', + rank: 'host', type: 'startsWith', functionality: function (chat, cmd) { if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); @@ -1508,6 +1797,7 @@ var user = basicBot.userUtilities.lookupUserName(name); if (typeof user === 'boolean') return API.sendChat(subChat(basicBot.chat.invaliduserspecified, {name: chat.un})); API.moderateBanUser(user.id, 1, API.BAN.DAY); + sendSlack("!ban: "+chat.un+" banned "+name); } } }, @@ -1526,6 +1816,8 @@ if (typeof basicBot.room.blacklists[list] === 'undefined') return API.sendChat(subChat(basicBot.chat.invalidlistspecified, {name: chat.un})); else { var media = API.getMedia(); + var timeLeft = API.getTimeRemaining(); + var timeElapsed = API.getTimeElapsed(); var track = { list: list, author: media.author, @@ -1535,7 +1827,12 @@ basicBot.room.newBlacklisted.push(track); basicBot.room.blacklists[list].push(media.format + ':' + media.cid); API.sendChat(subChat(basicBot.chat.newblacklisted, {name: chat.un, blacklist: list, author: media.author, title: media.title, mid: media.format + ':' + media.cid})); - API.moderateForceSkip(); + if (basicBot.settings.smartSkip && timeLeft > timeElapsed){ + basicBot.roomUtilities.smartSkip(); + } + else { + API.moderateForceSkip(); + } if (typeof basicBot.room.newBlacklistedSongFunction === 'function') { basicBot.room.newBlacklistedSongFunction(track); } @@ -1566,7 +1863,7 @@ bouncerPlusCommand: { command: 'bouncer+', - rank: 'mod', + rank: 'manager', type: 'exact', functionality: function (chat, cmd) { if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); @@ -1592,6 +1889,25 @@ } }, + botnameCommand: { + command: 'botname', + rank: 'manager', + type: 'startsWith', + functionality: function (chat, cmd) { + if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); + if (!basicBot.commands.executable(this.rank, chat)) return void (0); + else { + var msg = chat.message; + if (msg.length <= cmd.length + 1) return API.sendChat(subChat(basicBot.chat.currentbotname, {botname: basicBot.settings.botName})); + var argument = msg.substring(cmd.length + 1); + if (argument) { + basicBot.settings.botName = argument; + API.sendChat(subChat(basicBot.chat.botnameset, {botName: basicBot.settings.botName})); + } + } + } + }, + clearchatCommand: { command: 'clearchat', rank: 'manager', @@ -1622,34 +1938,33 @@ } }, + cmddeletionCommand: { + command: ['commanddeletion', 'cmddeletion', 'cmddel'], + rank: 'mod', + type: 'exact', + functionality: function (chat, cmd) { + if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); + if (!basicBot.commands.executable(this.rank, chat)) return void (0); + else { + if (basicBot.settings.cmdDeletion) { + basicBot.settings.cmdDeletion = !basicBot.settings.cmdDeletion; + API.sendChat(subChat(basicBot.chat.toggleoff, {name: chat.un, 'function': basicBot.chat.cmddeletion})); + } + else { + basicBot.settings.cmdDeletion = !basicBot.settings.cmdDeletion; + API.sendChat(subChat(basicBot.chat.toggleon, {name: chat.un, 'function': basicBot.chat.cmddeletion})); + } + } + } + }, + cookieCommand: { command: 'cookie', rank: 'user', type: 'startsWith', - cookies: ['has given you a chocolate chip cookie!', - 'has given you a soft homemade oatmeal cookie!', - 'has given you a plain, dry, old cookie. It was the last one in the bag. Gross.', - 'gives you a sugar cookie. What, no frosting and sprinkles? 0/10 would not touch.', - 'gives you a chocolate chip cookie. Oh wait, those are raisins. Bleck!', - 'gives you an enormous cookie. Poking it gives you more cookies. Weird.', - 'gives you a fortune cookie. It reads "Why aren\'t you working on any projects?"', - 'gives you a fortune cookie. It reads "Give that special someone a compliment"', - 'gives you a fortune cookie. It reads "Take a risk!"', - 'gives you a fortune cookie. It reads "Go outside."', - 'gives you a fortune cookie. It reads "Don\'t forget to eat your veggies!"', - 'gives you a fortune cookie. It reads "Do you even lift?"', - 'gives you a fortune cookie. It reads "m808 pls"', - 'gives you a fortune cookie. It reads "If you move your hips, you\'ll get all the ladies."', - 'gives you a fortune cookie. It reads "I love you."', - 'gives you a Golden Cookie. You can\'t eat it because it is made of gold. Dammit.', - 'gives you an Oreo cookie with a glass of milk!', - 'gives you a rainbow cookie made with love :heart:', - 'gives you an old cookie that was left out in the rain, it\'s moldy.', - 'bakes you fresh cookies, it smells amazing.' - ], - getCookie: function () { - var c = Math.floor(Math.random() * this.cookies.length); - return this.cookies[c]; + getCookie: function (chat) { + var c = Math.floor(Math.random() * basicBot.chat.cookies.length); + return basicBot.chat.cookies[c]; }, functionality: function (chat, cmd) { if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); @@ -1733,49 +2048,6 @@ } }, - voteskipCommand: { - command: 'voteskip', - rank: 'manager', - type: 'startsWith', - functionality: function (chat, cmd) { - if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); - if (!basicBot.commands.executable(this.rank, chat)) return void (0); - else { - var msg = chat.message; - if (msg.length <= cmd.length + 1) return API.sendChat(subChat(basicBot.chat.voteskiplimit, {name: chat.un, limit: basicBot.settings.voteSkipLimit})); - var argument = msg.substring(cmd.length + 1); - if (!basicBot.settings.voteSkip) basicBot.settings.voteSkip = !basicBot.settings.voteSkip; - if (isNaN(argument)) { - API.sendChat(subChat(basicBot.chat.voteskipinvalidlimit, {name: chat.un})); - } - else { - basicBot.settings.voteSkipLimit = argument; - API.sendChat(subChat(basicBot.chat.voteskipsetlimit, {name: chat.un, limit: basicBot.settings.voteSkipLimit})); - } - } - } - }, - - togglevoteskipCommand: { - command: 'togglevoteskip', - rank: 'bouncer', - type: 'exact', - functionality: function (chat, cmd) { - if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); - if (!basicBot.commands.executable(this.rank, chat)) return void (0); - else { - if (basicBot.settings.voteSkip) { - basicBot.settings.voteSkip = !basicBot.settings.voteSkip; - API.sendChat(subChat(basicBot.chat.toggleoff, {name: chat.un, 'function': basicBot.chat.voteskip})); - } - else { - basicBot.settings.motdEnabled = !basicBot.settings.motdEnabled; - API.sendChat(subChat(basicBot.chat.toggleon, {name: chat.un, 'function': basicBot.chat.voteskip})); - } - } - } - }, - dclookupCommand: { command: ['dclookup', 'dc'], rank: 'user', @@ -1814,11 +2086,29 @@ var user = basicBot.userUtilities.lookupUserName(name); if (typeof user === 'boolean') return API.sendChat(subChat(basicBot.chat.invaliduserspecified, {name: chat.un})); var chats = $('.from'); + var message = $('.message'); + var emote = $('.emote'); + var from = $('.un.clickable'); for (var i = 0; i < chats.length; i++) { - var n = chats[i].textContent; + var n = from[i].textContent; if (name.trim() === n.trim()) { - var cid = $(chats[i]).parent()[0].getAttribute('data-cid'); - API.moderateDeleteChat(cid); + + // var messagecid = $(message)[i].getAttribute('data-cid'); + // var emotecid = $(emote)[i].getAttribute('data-cid'); + // API.moderateDeleteChat(messagecid); + + // try { + // API.moderateDeleteChat(messagecid); + // } + // finally { + // API.moderateDeleteChat(emotecid); + // } + + if (typeof $(message)[i].getAttribute('data-cid') == "undefined"){ + API.moderateDeleteChat($(emote)[i].getAttribute('data-cid')); // works well with normal messages but not with emotes due to emotes and messages are seperate. + } else { + API.moderateDeleteChat($(message)[i].getAttribute('data-cid')); + } } } API.sendChat(subChat(basicBot.chat.deletechat, {name: chat.un, username: name})); @@ -1840,6 +2130,39 @@ } }, + englishCommand: { + command: 'english', + rank: 'bouncer', + type: 'startsWith', + functionality: function (chat, cmd) { + if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); + if (!basicBot.commands.executable(this.rank, chat)) return void (0); + else { + if(chat.message.length === cmd.length) return API.sendChat('/me No user specified.'); + var name = chat.message.substring(cmd.length + 2); + var user = basicBot.userUtilities.lookupUserName(name); + if(typeof user === 'boolean') return API.sendChat('/me Invalid user specified.'); + var lang = basicBot.userUtilities.getUser(user).language; + var ch = '/me @' + name + ' '; + switch(lang){ + case 'en': break; + case 'da': ch += 'Vær venlig at tale engelsk.'; break; + case 'de': ch += 'Bitte sprechen Sie Englisch.'; break; + case 'es': ch += 'Por favor, hable Inglés.'; break; + case 'fr': ch += 'Parlez anglais, s\'il vous plaît.'; break; + case 'nl': ch += 'Spreek Engels, alstublieft.'; break; + case 'pl': ch += 'Proszę mówić po angielsku.'; break; + case 'pt': ch += 'Por favor, fale Inglês.'; break; + case 'sk': ch += 'Hovorte po anglicky, prosím.'; break; + case 'cs': ch += 'Mluvte prosím anglicky.'; break; + case 'sr': ch += 'Молим Вас, говорите енглески.'; break; + } + ch += ' English please.'; + API.sendChat(ch); + } + } + }, + etaCommand: { command: 'eta', rank: 'user', @@ -1850,6 +2173,7 @@ else { var perm = basicBot.userUtilities.getPermission(chat.uid); var msg = chat.message; + var dj = API.getDJ().username; var name; if (msg.length > cmd.length) { if (perm < 2) return void (0); @@ -1858,11 +2182,14 @@ var user = basicBot.userUtilities.lookupUserName(name); if (typeof user === 'boolean') return API.sendChat(subChat(basicBot.chat.invaliduserspecified, {name: chat.un})); var pos = API.getWaitListPosition(user.id); + var realpos = pos + 1; + if (name == dj) return API.sendChat(subChat(basicBot.chat.youaredj, {name: name})); if (pos < 0) return API.sendChat(subChat(basicBot.chat.notinwaitlist, {name: name})); + if (pos == 0) return API.sendChat(subChat(basicBot.chat.youarenext, {name: name})); var timeRemaining = API.getTimeRemaining(); var estimateMS = ((pos + 1) * 4 * 60 + timeRemaining) * 1000; var estimateString = basicBot.roomUtilities.msToStr(estimateMS); - API.sendChat(subChat(basicBot.chat.eta, {name: name, time: estimateString})); + API.sendChat(subChat(basicBot.chat.eta, {name: name, time: estimateString, position: realpos})); } } }, @@ -1901,6 +2228,117 @@ } }, + forceskipCommand: { + command: ['forceskip', 'fs'], + rank: 'bouncer', + type: 'exact', + functionality: function (chat, cmd) { + if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); + if (!basicBot.commands.executable(this.rank, chat)) return void (0); + else { + API.sendChat(subChat(basicBot.chat.forceskip, {name: chat.un})); + API.moderateForceSkip(); + basicBot.room.skippable = false; + setTimeout(function () { + basicBot.room.skippable = true + }, 5 * 1000); + + } + } + }, + + ghostbusterCommand: { + command: 'ghostbuster', + rank: 'user', + type: 'startsWith', + functionality: function (chat, cmd) { + if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); + if (!basicBot.commands.executable(this.rank, chat)) return void (0); + else { + var msg = chat.message; + var name; + if (msg.length === cmd.length) name = chat.un; + else { + name = msg.substr(cmd.length + 2); + } + var user = basicBot.userUtilities.lookupUserName(name); + if (user === false || !user.inRoom) { + return API.sendChat(subChat(basicBot.chat.ghosting, {name1: chat.un, name2: name})); + } + else API.sendChat(subChat(basicBot.chat.notghosting, {name1: chat.un, name2: name})); + } + } + }, + + gifCommand: { + command: ['gif', 'giphy'], + rank: 'user', + type: 'startsWith', + functionality: function (chat, cmd) { + if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); + if (!basicBot.commands.executable(this.rank, chat)) return void (0); + else { + var msg = chat.message; + if (msg.length !== cmd.length) { + function get_id(api_key, fixedtag, func) + { + $.getJSON( + "https://tv.giphy.com/v1/gifs/random?", + { + "format": "json", + "api_key": api_key, + "rating": rating, + "tag": fixedtag + }, + function(response) + { + func(response.data.id); + } + ) + } + var api_key = "dc6zaTOxFJmzC"; // public beta key + var rating = "pg-13"; // PG 13 gifs + var tag = msg.substr(cmd.length + 1); + var fixedtag = tag.replace(/ /g,"+"); + var commatag = tag.replace(/ /g,", "); + get_id(api_key, tag, function(id) { + if (typeof id !== 'undefined') { + API.sendChat(subChat(basicBot.chat.validgiftags, {name: chat.un, id: id, tags: commatag})); + } else { + API.sendChat(subChat(basicBot.chat.invalidgiftags, {name: chat.un, tags: commatag})); + } + }); + } + else { + function get_random_id(api_key, func) + { + $.getJSON( + "https://tv.giphy.com/v1/gifs/random?", + { + "format": "json", + "api_key": api_key, + "rating": rating + }, + function(response) + { + func(response.data.id); + } + ) + } + var api_key = "dc6zaTOxFJmzC"; // public beta key + var rating = "pg-13"; // PG 13 gifs + get_random_id(api_key, function(id) { + if (typeof id !== 'undefined') { + API.sendChat(subChat(basicBot.chat.validgifrandom, {name: chat.un, id: id})); + } else { + API.sendChat(subChat(basicBot.chat.invalidgifrandom, {name: chat.un})); + } + }); + } + } + } + }, + helpCommand: { command: 'help', rank: 'user', @@ -1909,12 +2347,32 @@ if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); if (!basicBot.commands.executable(this.rank, chat)) return void (0); else { - var link = "http://i.imgur.com/SBAso1N.jpg"; + var link = "http://i.imgur.com/RJnr0d9.jpg"; API.sendChat(subChat(basicBot.chat.starterhelp, {link: link})); } } }, + historyskipCommand: { + command: 'historyskip', + rank: 'bouncer', + type: 'exact', + functionality: function (chat, cmd) { + if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); + if (!basicBot.commands.executable(this.rank, chat)) return void (0); + else { + if (basicBot.settings.historySkip) { + basicBot.settings.historySkip = !basicBot.settings.historySkip; + API.sendChat(subChat(basicBot.chat.toggleoff, {name: chat.un, 'function': basicBot.chat.historyskip})); + } + else { + basicBot.settings.historySkip = !basicBot.settings.historySkip; + API.sendChat(subChat(basicBot.chat.toggleon, {name: chat.un, 'function': basicBot.chat.historyskip})); + } + } + } + }, + joinCommand: { command: 'join', rank: 'user', @@ -1954,7 +2412,7 @@ kickCommand: { command: 'kick', - rank: 'bouncer', + rank: 'host', type: 'startsWith', functionality: function (chat, cmd) { if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); @@ -1987,6 +2445,7 @@ API.sendChat(subChat(basicBot.chat.kick, {name: chat.un, username: name, time: time})); if (time > 24 * 60 * 60) API.moderateBanUser(user.id, 1, API.BAN.PERMA); else API.moderateBanUser(user.id, 1, API.BAN.DAY); + sendSlack("!kick: "+chat.un+" kicked "+name+" for "+time+" minutes"); setTimeout(function (id, name) { API.moderateUnbanUser(id); console.log('Unbanned @' + name + '. (' + id + ')'); @@ -2006,6 +2465,7 @@ if (!basicBot.commands.executable(this.rank, chat)) return void (0); else { storeToStorage(); + sendToSocket(); API.sendChat(basicBot.chat.kill); basicBot.disconnectAPI(); setTimeout(function () { @@ -2015,6 +2475,34 @@ } }, + languageCommand: { + command: 'language', + rank: 'manager', + type: 'startsWith', + functionality: function (chat, cmd) { + if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); + if (!basicBot.commands.executable(this.rank, chat)) return void (0); + else { + var msg = chat.message; + if (msg.length <= cmd.length + 1) return API.sendChat(subChat(basicBot.chat.currentlang, {language: basicBot.settings.language})); + var argument = msg.substring(cmd.length + 1); + + $.get("https://rawgit.com/Masterjh/basicBot/master/lang/langIndex.json", function (json) { + var langIndex = json; + var link = langIndex[argument.toLowerCase()]; + if (typeof link === "undefined") { + API.sendChat(subChat(basicBot.chat.langerror, {link: "http://git.io/vJ9nI"})); + } + else { + basicBot.settings.language = argument; + loadChat(); + API.sendChat(subChat(basicBot.chat.langset, {language: basicBot.settings.language})); + } + }); + } + } + }, + leaveCommand: { command: 'leave', rank: 'user', @@ -2049,7 +2537,7 @@ if (dj === chat.uid) isDj = true; if (perm >= 1 || isDj) { if (media.format === 1) { - var linkToSong = "https://www.youtube.com/watch?v=" + media.cid; + var linkToSong = "http://youtu.be/" + media.cid; API.sendChat(subChat(basicBot.chat.songlink, {name: from, link: linkToSong})); } if (media.format === 2) { @@ -2064,7 +2552,7 @@ lockCommand: { command: 'lock', - rank: 'mod', + rank: 'manager', type: 'exact', functionality: function (chat, cmd) { if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); @@ -2077,7 +2565,7 @@ lockdownCommand: { command: 'lockdown', - rank: 'mod', + rank: 'manager', type: 'exact', functionality: function (chat, cmd) { if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); @@ -2103,7 +2591,7 @@ else { if (basicBot.settings.lockGuard) { basicBot.settings.lockGuard = !basicBot.settings.lockGuard; - return API.sendChat(subChat(basicBot.chat.toggleoff, {name: chat.un, 'function': basicBot.chat.lockdown})); + return API.sendChat(subChat(basicBot.chat.toggleoff, {name: chat.un, 'function': basicBot.chat.lockguard})); } else { basicBot.settings.lockGuard = !basicBot.settings.lockGuard; @@ -2182,8 +2670,8 @@ } }, - lockskipposCommand: { - command: 'lockskippos', + locktimerCommand: { + command: 'locktimer', rank: 'manager', type: 'startsWith', functionality: function (chat, cmd) { @@ -2191,31 +2679,28 @@ if (!basicBot.commands.executable(this.rank, chat)) return void (0); else { var msg = chat.message; - var pos = msg.substring(cmd.length + 1); - if (!isNaN(pos)) { - basicBot.settings.lockskipPosition = pos; - return API.sendChat(subChat(basicBot.chat.lockskippos, {name: chat.un, position: basicBot.settings.lockskipPosition})); + var lockTime = msg.substring(cmd.length + 1); + if (!isNaN(lockTime) && lockTime !== "") { + basicBot.settings.maximumLocktime = lockTime; + return API.sendChat(subChat(basicBot.chat.lockguardtime, {name: chat.un, time: basicBot.settings.maximumLocktime})); } - else return API.sendChat(subChat(basicBot.chat.invalidpositionspecified, {name: chat.un})); + else return API.sendChat(subChat(basicBot.chat.invalidtime, {name: chat.un})); } } }, - locktimerCommand: { - command: 'locktimer', + logoutCommand: { + command: 'logout', rank: 'manager', - type: 'startsWith', + type: 'exact', functionality: function (chat, cmd) { if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); if (!basicBot.commands.executable(this.rank, chat)) return void (0); else { - var msg = chat.message; - var lockTime = msg.substring(cmd.length + 1); - if (!isNaN(lockTime) && lockTime !== "") { - basicBot.settings.maximumLocktime = lockTime; - return API.sendChat(subChat(basicBot.chat.lockguardtime, {name: chat.un, time: basicBot.settings.maximumLocktime})); - } - else return API.sendChat(subChat(basicBot.chat.invalidtime, {name: chat.un})); + API.sendChat(subChat(basicBot.chat.logout, {name: chat.un, botname: basicBot.settings.botName})); + setTimeout(function () { + $(".logout").mousedown() + }, 1000); } } }, @@ -2376,10 +2861,12 @@ else { API.moderateMuteUser(user.id, 1, API.MUTE.SHORT); API.sendChat(subChat(basicBot.chat.mutedtime, {name: chat.un, username: name, time: time})); + setTimeout(function (id) { API.moderateUnmuteUser(id); }, time * 60 * 1000, user.id); } + sendSlack("!mute: "+chat.un+" muted "+name+" for "+time+" minutes"); } else API.sendChat(subChat(basicBot.chat.muterank, {name: chat.un})); } @@ -2421,6 +2908,7 @@ if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); if (!basicBot.commands.executable(this.rank, chat)) return void (0); else { + sendToSocket(); storeToStorage(); basicBot.disconnectAPI(); setTimeout(function () { @@ -2440,6 +2928,7 @@ if (!basicBot.commands.executable(this.rank, chat)) return void (0); else { API.sendChat(basicBot.chat.reload); + sendToSocket(); storeToStorage(); basicBot.disconnectAPI(); kill(); @@ -2503,7 +2992,7 @@ rouletteCommand: { command: 'roulette', - rank: 'mod', + rank: 'manager', type: 'exact', functionality: function (chat, cmd) { if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); @@ -2548,20 +3037,72 @@ }, skipCommand: { - command: 'skip', + command: ['skip', 'smartskip'], rank: 'bouncer', - type: 'exact', + type: 'startsWith', functionality: function (chat, cmd) { if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); if (!basicBot.commands.executable(this.rank, chat)) return void (0); else { - API.sendChat(subChat(basicBot.chat.skip, {name: chat.un})); - API.moderateForceSkip(); - basicBot.room.skippable = false; - setTimeout(function () { - basicBot.room.skippable = true - }, 5 * 1000); + if (basicBot.room.skippable) { + var timeLeft = API.getTimeRemaining(); + var timeElapsed = API.getTimeElapsed(); + var dj = API.getDJ(); + var name = dj.username; + var msgSend = '@' + name + ', '; + + if (chat.message.length === cmd.length) { + API.sendChat(subChat(basicBot.chat.usedskip, {name: chat.un})); + if (basicBot.settings.smartSkip && timeLeft > timeElapsed){ + basicBot.roomUtilities.smartSkip(); + } + else { + API.moderateForceSkip(); + } + } + var validReason = false; + var msg = chat.message; + var reason = msg.substring(cmd.length + 1); + for (var i = 0; i < basicBot.settings.skipReasons.length; i++) { + var r = basicBot.settings.skipReasons[i][0]; + if (reason.indexOf(r) !== -1) { + validReason = true; + msgSend += basicBot.settings.skipReasons[i][1]; + } + } + if (validReason) { + API.sendChat(subChat(basicBot.chat.usedskip, {name: chat.un})); + if (basicBot.settings.smartSkip && timeLeft > timeElapsed){ + basicBot.roomUtilities.smartSkip(msgSend); + } + else { + API.moderateForceSkip(); + setTimeout(function () { + API.sendChat(msgSend); + }, 500); + } + } + } + } + } + }, + + skipposCommand: { + command: 'skippos', + rank: 'manager', + type: 'startsWith', + functionality: function (chat, cmd) { + if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); + if (!basicBot.commands.executable(this.rank, chat)) return void (0); + else { + var msg = chat.message; + var pos = msg.substring(cmd.length + 1); + if (!isNaN(pos)) { + basicBot.settings.skipPosition = pos; + return API.sendChat(subChat(basicBot.chat.skippos, {name: chat.un, position: basicBot.settings.skipPosition})); + } + else return API.sendChat(subChat(basicBot.chat.invalidpositionspecified, {name: chat.un})); } } }, @@ -2608,7 +3149,7 @@ if (!basicBot.commands.executable(this.rank, chat)) return void (0); else { var from = chat.un; - var msg = '/me [@' + from + '] '; + var msg = '[@' + from + '] '; msg += basicBot.chat.afkremoval + ': '; if (basicBot.settings.afkRemoval) msg += 'ON'; @@ -2621,7 +3162,7 @@ if (basicBot.settings.bouncerPlus) msg += 'ON'; else msg += 'OFF'; msg += '. '; - + msg += basicBot.chat.blacklist + ': '; if (basicBot.settings.blacklistEnabled) msg += 'ON'; else msg += 'OFF'; @@ -2647,17 +3188,63 @@ else msg += 'OFF'; msg += '. '; + msg += basicBot.chat.historyskip + ': '; + if (basicBot.settings.historySkip) msg += 'ON'; + else msg += 'OFF'; + msg += '. '; + msg += basicBot.chat.voteskip + ': '; - if (basicBot.settings.voteskip) msg += 'ON'; + if (basicBot.settings.voteSkip) msg += 'ON'; else msg += 'OFF'; msg += '. '; + msg += basicBot.chat.cmddeletion + ': '; + if (basicBot.settings.cmdDeletion) msg += 'ON'; + else msg += 'OFF'; + msg += '. '; + + msg += basicBot.chat.autoskip + ': '; + if (basicBot.settings.autoskip) msg += 'ON'; + else msg += 'OFF'; + msg += '. '; + + // TODO: Display more toggleable bot settings. + var launchT = basicBot.room.roomstats.launchTime; var durationOnline = Date.now() - launchT; var since = basicBot.roomUtilities.msToStr(durationOnline); msg += subChat(basicBot.chat.activefor, {time: since}); - return API.sendChat(msg); + /* + // least efficient way to go about this, but it works :) + if (msg.length > 256){ + firstpart = msg.substr(0, 256); + secondpart = msg.substr(256); + API.sendChat(firstpart); + setTimeout(function () { + API.sendChat(secondpart); + }, 300); + } + else { + API.sendChat(msg); + } + */ + + // This is a more efficient solution + if (msg.length > 241){ + var split = msg.match(/.{1,241}/g); + for (var i = 0; i < split.length; i++) { + var func = function(index) { + setTimeout(function() { + API.sendChat("/me " + split[index]); + }, 500 * index); + } + func(i); + } + } + else { + return API.sendChat(msg); + } } } }, @@ -2752,7 +3339,7 @@ } } }, - + togglemotdCommand: { command: 'togglemotd', rank: 'bouncer', @@ -2773,6 +3360,26 @@ } }, + togglevoteskipCommand: { + command: 'togglevoteskip', + rank: 'bouncer', + type: 'exact', + functionality: function (chat, cmd) { + if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); + if (!basicBot.commands.executable(this.rank, chat)) return void (0); + else { + if (basicBot.settings.voteSkip) { + basicBot.settings.voteSkip = !basicBot.settings.voteSkip; + API.sendChat(subChat(basicBot.chat.toggleoff, {name: chat.un, 'function': basicBot.chat.voteskip})); + } + else { + basicBot.settings.voteSkip = !basicBot.settings.voteSkip; + API.sendChat(subChat(basicBot.chat.toggleon, {name: chat.un, 'function': basicBot.chat.voteskip})); + } + } + } + }, + unbanCommand: { command: 'unban', rank: 'bouncer', @@ -2939,9 +3546,32 @@ } }, + voteskipCommand: { + command: 'voteskip', + rank: 'manager', + type: 'startsWith', + functionality: function (chat, cmd) { + if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); + if (!basicBot.commands.executable(this.rank, chat)) return void (0); + else { + var msg = chat.message; + if (msg.length <= cmd.length + 1) return API.sendChat(subChat(basicBot.chat.voteskiplimit, {name: chat.un, limit: basicBot.settings.voteSkipLimit})); + var argument = msg.substring(cmd.length + 1); + if (!basicBot.settings.voteSkip) basicBot.settings.voteSkip = !basicBot.settings.voteSkip; + if (isNaN(argument)) { + API.sendChat(subChat(basicBot.chat.voteskipinvalidlimit, {name: chat.un})); + } + else { + basicBot.settings.voteSkipLimit = argument; + API.sendChat(subChat(basicBot.chat.voteskipsetlimit, {name: chat.un, limit: basicBot.settings.voteSkipLimit})); + } + } + } + }, + welcomeCommand: { command: 'welcome', - rank: 'mod', + rank: 'manager', type: 'exact', functionality: function (chat, cmd) { if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); @@ -2973,6 +3603,83 @@ } }, + whoisCommand: { + command: 'whois', + rank: 'bouncer', + type: 'startsWith', + functionality: function (chat, cmd) { + if (this.type === 'exact' && chat.message.length !== cmd.length) return void (0); + if (!basicBot.commands.executable(this.rank, chat)) return void (0); + else { + var msg = chat.message; + var name; + if (msg.length === cmd.length) name = chat.un; + else { + name = msg.substr(cmd.length + 2); + } + users = API.getUsers(); + var len = users.length; + for (var i = 0; i < len; ++i){ + if (users[i].username == name){ + var id = users[i].id; + var avatar = API.getUser(id).avatarID; + var level = API.getUser(id).level; + var rawjoined = API.getUser(id).joined; + var joined = rawjoined.substr(0, 10); + var rawlang = API.getUser(id).language; + if (rawlang == "en"){ + var language = "English"; + } else if (rawlang == "bg"){ + var language = "Bulgarian"; + } else if (rawlang == "cs"){ + var language = "Czech"; + } else if (rawlang == "fi"){ + var language = "Finnish" + } else if (rawlang == "fr"){ + var language = "French" + } else if (rawlang == "pt"){ + var language = "Portuguese" + } else if (rawlang == "zh"){ + var language = "Chinese" + } else if (rawlang == "sk"){ + var language = "Slovak" + } else if (rawlang == "nl"){ + var language = "Dutch" + } else if (rawlang == "ms"){ + var language = "Malay" + } + var rawrank = API.getUser(id).role; + if (rawrank == "0"){ + var rank = "User"; + } else if (rawrank == "1"){ + var rank = "Resident DJ"; + } else if (rawrank == "2"){ + var rank = "Bouncer"; + } else if (rawrank == "3"){ + var rank = "Manager" + } else if (rawrank == "4"){ + var rank = "Co-Host" + } else if (rawrank == "5"){ + var rank = "Host" + } else if (rawrank == "7"){ + var rank = "Brand Ambassador" + } else if (rawrank == "10"){ + var rank = "Admin" + } + var slug = API.getUser(id).slug; + if (typeof slug !== 'undefined') { + var profile = "https://plug.dj/@/" + slug; + } else { + var profile = "~"; + } + + API.sendChat(subChat(basicBot.chat.whois, {name1: chat.un, name2: name, id: id, avatar: avatar, profile: profile, language: language, level: level, joined: joined, rank: rank})); + } + } + } + } + }, + youtubeCommand: { command: 'youtube', rank: 'user', diff --git a/commands.md b/commands.md index 7395be83..1249d4c5 100644 --- a/commands.md +++ b/commands.md @@ -16,6 +16,7 @@ Manager |!cycletimer | X | set the maximum DJ cycle time for when cycleguard is enabled | |!locktimer | X | set the maximum time the waitlist can be locked if lockguard is enabled | |!refresh | | refreshes the browser of whoever runs the bot | +|!roulette | | start a roulette | |!usercmdcd | X | set the cooldown on commands by grey users | |!usercommands | | toggle user commands | |!voteskip | (X) | when no argument is specified, returns the current voteskip limit, when X is specified, voteskip limit is updated to the new specified limit. | @@ -35,8 +36,8 @@ Bouncer+ |!maxlength | X | specify the maximum length a song can be when timeguard is enabled | |!move | @user (X) | moves user to position X on the waitlist, default is position 1 | |!remove | @user | remove user from the waitlist | -|!roulette | | start a roulette | |!songstats | | toggle song statistics | +|!swap | @user @user | swaps positions of two users | |!unlock | | unlock the waitlist | |!welcome | | toggle the welcome message on user join | diff --git a/lang/en.json b/lang/en.json index eaf17396..81079ed3 100644 --- a/lang/en.json +++ b/lang/en.json @@ -1,70 +1,126 @@ { - + "cookies": [ + "has given you a chocolate chip cookie!", + "has given you a soft homemade oatmeal cookie!", + "has given you a plain, dry, old cookie. It was the last one in the bag. Gross.", + "gives you a sugar cookie. What, no frosting and sprinkles? 0\/10 would not touch.", + "gives you a chocolate chip cookie. Oh wait, those are raisins. Bleck!", + "gives you an enormous cookie. Poking it gives you more cookies. Weird.", + "gives you a fortune cookie. It reads \"Why aren't you working on any projects?\"", + "gives you a fortune cookie. It reads \"Give that special someone a compliment\"", + "gives you a fortune cookie. It reads \"Take a risk!\"", + "gives you a fortune cookie. It reads \"Go outside.\"", + "gives you a fortune cookie. It reads \"Don't forget to eat your veggies!\"", + "gives you a fortune cookie. It reads \"Do you even lift?\"", + "gives you a fortune cookie. It reads \"m808 pls\"", + "gives you a fortune cookie. It reads \"If you move your hips, you'll get all the ladies.\"", + "gives you a fortune cookie. It reads \"I love you.\"", + "gives you a Golden Cookie. You can't eat it because it is made of gold. Dammit.", + "gives you an Oreo cookie with a glass of milk!", + "gives you a rainbow cookie made with love :heart:", + "gives you an old cookie that was left out in the rain, it's moldy.", + "bakes you fresh cookies, it smells amazing." + "gives you a cookie from his personal stash." + ], + "balls": [ + "Signs point to yes.", + "Yes.", + "Reply hazy, try again.", + "Without a doubt.", + "My sources say no.", + "As I see it, yes.", + "You may rely on it.", + "Concentrate and ask again.", + "Outlook not so good.", + "It is decidedly so.", + "Better not tell you now.", + "Very doubtful.", + "Yes - definitely.", + "It is certain.", + "Cannot predict now.", + "Most likely.", + "Ask again later.", + "My reply is no.", + "Outlook good.", + "Don't count on it.", + "Yes, in due time.", + "My sources say no.", + "Definitely not.", + "You will have to wait.", + "I have my doubts.", + "Outlook so so.", + "Looks good to me!", + "Who knows?", + "Looking good!", + "Probably.", + "Are you kidding?", + "Don't bet on it.", + "Forget about it." + ], "nodatafound": "No previous data found.", + "currentlang": "\/me Language currently set to: %%LANGUAGE%%", + "langerror": "\/me The language you've selected isn't available. Please visit %%LINK%% to find a list of languages available.", + "langset": "\/me Language now set to: %%LANGUAGE%%", "retrievingdata": "Retrieving previously stored data.", "datarestored": "Previously stored data successfully retrieved.", "greyuser": "Only bouncers and up can run a bot.", "bouncer": "The bot can't move people when it's run as a bouncer.", - "online": "/me %%BOTNAME%% v%%VERSION%% online!", - - - "welcome": "/me Welcome %%NAME%%", - "welcomeback": "/me Welcome back, %%NAME%%", - "songknown": "/me :repeat: This song has been played %%PLAYS%% time(s) in the last %%TIMETOTAL%%, last play was %%LASTTIME%% ago. :repeat:", - "timelimit": "/me @%%NAME%%, your song is longer than %%MAXLENGTH%% minutes, you need permission to play longer songs.", - "permissionownsong": "/me :up: @%%NAME%% has permission to play their own production!", - "isblacklisted": "/me This track is on the %%BLACKLIST%% blacklist! Skipping...", - - - "isopen": "/me The roulette is now open! Type !join to participate!", - "winnerpicked": "/me A winner has been picked! @%%NAME%% to position %%POSITION%%.", - - - "alreadyadding": "/me User is already being added! Changed the desired position to %%POSITION%%.", - "adding": "/me Added @%%NAME%% to the queue. Current queue: %%POSITION%%.", - - - "usernotfound": "/me User not found.", - "notdisconnected": "/me @%%NAME%% did not disconnect during my time here.", - "noposition": "/me No last position known. The waitlist needs to update at least once to register a user's last position.", - "toolongago": "/me @%%NAME%%'s last disconnect (DC or leave) was too long ago: %%TIME%%.", - "valid": "/me @%%NAME%% disconnected %%TIME%% ago and should be at position %%POSITION%%.", - - - "warning1": "/me @%%NAME%%, you have been afk for %%TIME%%, please respond within 2 minutes or you will be removed.", - "warning2": "/me @%%NAME%%, you will be removed due to AFK soon if you don't respond.", - "afkremove": "/me @%%NAME%%, you have been removed for being afk for %%TIME%%. You were at position %%POSITION%%. Chat at least once every %%MAXIMUMAFK%% minutes if you want to play a song.", - - - "caps": "/me @%%NAME%%, unglue your capslock button please.", - "askskip": "/me @%%NAME%%, don't ask for skips.", - "spam": "/me @%%NAME%%, please don't spam.", - "roomadvertising": "/me @%%NAME%%, don't post links to other rooms please.", - "adfly": "/me @%%NAME%%, please change your autowoot program. We suggest PlugCubed: http://plugcubed.net/", - - - "invalidtime": "/me [@%%NAME%%] Invalid time specified.", - "nouserspecified": "/me [@%%NAME%%] No user specified.", - "invaliduserspecified": "/me [@%%NAME%%] Invalid user specified.", - "nolistspecified": "/me [@%%NAME%%] No list specified.", - "invalidlistspecified": "/me [@%%NAME%%] Invalid list specified.", - "novaliduserspecified": "/me [@%%NAME%%] No valid user specified.", - "nolimitspecified": "/me [@%%NAME%%] No limit specified.", - "invalidlimitspecified": "/me [@%%NAME%%] Invalid limit.", - "invalidpositionspecified": "/me [@%%NAME%%] Invalid position specified.", - "toggleon": "/me [@%%NAME%%] %%FUNCTION%% enabled.", - "toggleoff": "/me [@%%NAME%%] %%FUNCTION%% disabled.", + "online": "\/me %%BOTNAME%% v%%VERSION%% online!", + "welcome": "\/me Welcome %%NAME%%", + "welcomeback": "\/me Welcome back, %%NAME%%", + "songknown": "\/me @%%NAME%%, this song is in the DJ history.", + "timelimit": "\/me @%%NAME%%, your song is longer than %%MAXLENGTH%% minutes, you need permission to play longer songs.", + "permissionownsong": "\/me :up: @%%NAME%% has permission to play their own production!", + "isblacklisted": "\/me This track is on the %%BLACKLIST%% blacklist! Skipping...", + "isopen": "\/me The roulette is now open! Type !join to participate!", + "winnerpicked": "\/me A winner has been picked! @%%NAME%% to position %%POSITION%%.", + "ball": "\/me %%NAME%%'s question was: \"%%QUESTION%%\" and %%BOTNAME%%'s response is: \"%%RESPONSE%%\"", + "notghosting": "[%%NAME1%%] %%NAME2%% is not ghosting.", + "ghosting": "[%%NAME1%%] %%NAME2%% is either ghosting or not here.", + "alreadyadding": "\/me User is already being added! Changed the desired position to %%POSITION%%.", + "adding": "\/me Added @%%NAME%% to the queue. Current queue: %%POSITION%%.", + "usernotfound": "\/me User not found.", + "notdisconnected": "\/me @%%NAME%% did not disconnect during my time here.", + "noposition": "\/me No last position known. The waitlist needs to update at least once to register a user's last position.", + "toolongago": "\/me @%%NAME%%'s last disconnect (DC or leave) was too long ago: %%TIME%%.", + "valid": "\/me @%%NAME%% disconnected %%TIME%% ago and should be at position %%POSITION%%.", + "warning1": "\/me @%%NAME%%, you have been afk for %%TIME%%, please respond within 2 minutes or you will be removed.", + "warning2": "\/me @%%NAME%%, you will be removed due to AFK soon if you don't respond.", + "afkremove": "\/me @%%NAME%%, you have been removed for being afk for %%TIME%%. You were at position %%POSITION%%. Chat at least once every %%MAXIMUMAFK%% minutes if you want to play a song.", + "caps": "\/me @%%NAME%%, unglue your capslock button please.", + "askskip": "\/me @%%NAME%%, don't ask for skips.", + "spam": "\/me @%%NAME%%, please don't spam.", + "roomadvertising": "\/me @%%NAME%%, don't post links to other rooms please.", + "adfly": "\/me @%%NAME%%, please change your autowoot program. We suggest RCS: http:\/\/rcs.radiant.dj\/", + "validgiftags": "\/me [@%%NAME%%] http:\/\/media.giphy.com\/media\/%%ID%%\/giphy.gif [Tags: %%TAGS%%]", + "invalidgiftags": "\/me [@%%NAME%%] Invalid tags, try something different. [Tags: %%TAGS%%]", + "validgifrandom": "\/me [@%%NAME%%] http:\/\/media.giphy.com\/media\/%%ID%%\/giphy.gif [Random GIF]", + "invalidgifrandom": "\/me [@%%NAME%%] Invalid request, try again.", + "invalidtime": "\/me [@%%NAME%%] Invalid time specified.", + "nouserspecified": "\/me [@%%NAME%%] No user specified.", + "invaliduserspecified": "\/me [@%%NAME%%] Invalid user specified.", + "nolistspecified": "\/me [@%%NAME%%] No list specified.", + "invalidlistspecified": "\/me [@%%NAME%%] Invalid list specified.", + "novaliduserspecified": "\/me [@%%NAME%%] No valid user specified.", + "nolimitspecified": "\/me [@%%NAME%%] No limit specified.", + "invalidlimitspecified": "\/me [@%%NAME%%] Invalid limit.", + "invalidpositionspecified": "\/me [@%%NAME%%] Invalid position specified.", + "whois": "\/me [%%NAME1%%] Username: %%NAME2%%, ID: %%ID%%, Rank: %%RANK%%, Joined: %%JOINED%%, Level: %%LEVEL%%, Language: %%LANGUAGE%%, Avatar: %%AVATAR%%, Status: %%STATUS%%%%PROFILE%%", + "toggleon": "\/me [@%%NAME%%] %%FUNCTION%% enabled.", + "toggleoff": "\/me [@%%NAME%%] %%FUNCTION%% disabled.", + "cmddeletion": "command deletion", "afkremoval": "AFK removal", "afksremoved": "AFK's removed", "afklimit": "AFK limit", "autodisable": "autodisable", "autoskip": "autoskip", - "newblacklisted": "/me [@%%NAME%%] This track belongs on the %%BLACKLIST%% blacklist! [ %%AUTHOR%% - %%TITLE%% - %%MID%% ]", + "newblacklisted": "\/me [@%%NAME%%] This track belongs on the %%BLACKLIST%% blacklist! [ %%AUTHOR%% - %%TITLE%% - %%MID%% ]", "blinfo": "[@%%NAME%%] Blacklist Info - author: %%AUTHOR%%, title: %%TITLE%%, mid: %%SONGID%%", "blacklist": "blacklist", "cycleguard": "cycleguard", "timeguard": "timeguard", "chatfilter": "chatfilter", + "historyskip": "historyskip", "lockdown": "lockdown", "lockguard": "lockguard", "usercommands": "usercommands", @@ -73,72 +129,77 @@ "songstats": "song statistics", "etarestriction": "eta restriction", "voteskip": "voteskip", - "voteskiplimit": "/me [@%%NAME%%] Voteskip limit is currently set to %%LIMIT%% mehs.", - "voteskipexceededlimit": "/me @%%NAME%%, your song has exceeded the voteskip limit (%%LIMIT%% mehs).", - "voteskipinvalidlimit": "/me [@%%NAME%%] Invalid voteskip limit, please try again using a number to signify the number of mehs.", - "voteskipsetlimit": "/me [@%%NAME%%] Voteskip limit set to %%LIMIT%%.", - "activeusersintime": "/me [@%%NAME%% There have been %%AMOUNT%% users chatting in the past %%TIME%% minutes.", - "maximumafktimeset": "/me [@%%NAME%%] Maximum afk duration set to %%TIME%% minutes.", - "afkstatusreset": "/me [@%%NAME%%] Reset the afk status of @%%USERNAME%%.", - "inactivefor": "/me [@%%NAME%%] @%%USERNAME%% has been inactive for %%TIME%%.", - "autowoot": "/me We recommend PlugCubed for autowooting: http://plugcubed.net/", - "brandambassador": "/me A Brand Ambassador is the voice of the plug.dj users. They promote events, engage the community and share the plug.dj message around the world. For more info: https://plug.dj/ba", - "bouncerplusrank": "/me [@%%NAME%%] You have to be manager or up to enable Bouncer+.", - "chatcleared": "/me [@%%NAME%%] Cleared the chat.", - "deletechat": "/me [@%%NAME%%] Cleared the chat of %%USERNAME%%.", - "commandslink": "/me %%BOTNAME%% commands: %%LINK%%", - "eatcookie": "/me eats a cookie.", - "nousercookie": "/em doesn't see %%NAME%% in room and eats a cookie himself.", - "selfcookie": "/me @%%NAME%%, you're a bit greedy, aren't you? Giving cookies to yourself, bah. Share some with other people!", - "cookie": "/me @%%NAMETO%%, @%%NAMEFROM%% %%COOKIE%%", - "cycleguardtime": "/me [@%%NAME%%] The cycleguard is set to %%TIME%% minute(s).", - "dclookuprank": "/me [@%%NAME%%] Only bouncers and above can do a lookup for others.", - "emojilist": "/me Emoji list: %%LINK%%", - "notinwaitlist": "/me @%%NAME%%, you are not on the waitlist.", - "eta": "/me @%%NAME%% you will reach the booth in approximately %%TIME%%.", - "facebook": "/me Like us on facebook: %%LINK%%", - "starterhelp": "/me This image will get you started on plug: %%LINK%%", - "roulettejoin": "/me @%%NAME%% joined the roulette! (!leave if you regret it.)", - "jointime": "/me [@%%NAMEFROM%%] @%%USERNAME%% has been in the room for %%TIME%%.", - "kickrank": "/me [@%%NAME%%] you can't kick users with an equal or higher rank than you!", - "kick": "/me [@%%NAME%%], @%%USERNAME%% you are being kicked from the community for %%TIME%% minutes.", - "kill": "/me Shutting down.", - "rouletteleave": "/me @%%NAME%% left the roulette!", - "songlink": "/me [@%%NAME%%] Link to current song: %%LINK%%", - "usedlockskip": "/me [%%NAME%% used lockskip.]", - "lockskippos": "/me [@%%NAME%%] Lockskip will now move the dj to position %%POSITION%%.", - "lockguardtime": "/me [@%%NAME%%] The lockguard is set to %%TIME%% minute(s).", - "maxlengthtime": "/me [@%%NAME%%] The maximum song duration is set to %%TIME%% minutes.", - "motdset": "/me MotD set to: %%MSG%%", - "motdintervalset": "/me MotD interval set to %%INTERVAL%%.", - "addbotwaitlist": "/me @%%NAME%%, don't try to add me to the waitlist, please.", - "move": "/me [%%NAME%% used move.]", - "mutednotime": "/me [@%%NAME%%] Muted @%%USERNAME%%.", - "mutedmaxtime": "/me [@%%NAME%%] You can only mute for maximum %%TIME%% minutes.", - "mutedtime": "/me [@%%NAME%%] Muted @%%USERNAME%% for %%TIME%% minutes.", - "unmuted": "/me [@%%NAME%%] Unmuted @%%USERNAME%%.", - "muterank": "/me [@%%NAME%%] You can't mute persons with an equal or higher rank than you.", - "oplist": "/me OP list: %%LINK%%", - "pong": "/me Pong!", - "reload": "/me Be right back.", - "removenotinwl": "/me [@%%NAME%%] Specified user @%%USERNAME%% is not in the waitlist.", - "roomrules": "/me Please find the room rules here: %%LINK%%", - "sessionstats": "/me [@%%NAME%%] Total woots: %%WOOTS%%, total mehs: %%MEHS%%, total grabs: %%GRABS%%.", - "skip": "/me [%%NAME%% used skip.]", - "madeby": "/me This bot was made by %%NAME%%.", + "voteskiplimit": "\/me [@%%NAME%%] Voteskip limit is currently set to %%LIMIT%% mehs.", + "voteskipexceededlimit": "\/me @%%NAME%%, your song has exceeded the voteskip limit (%%LIMIT%% mehs).", + "voteskipinvalidlimit": "\/me [@%%NAME%%] Invalid voteskip limit, please try again using a number to signify the number of mehs.", + "voteskipsetlimit": "\/me [@%%NAME%%] Voteskip limit set to %%LIMIT%%.", + "activeusersintime": "\/me [@%%NAME%% There have been %%AMOUNT%% users chatting in the past %%TIME%% minutes.", + "maximumafktimeset": "\/me [@%%NAME%%] Maximum afk duration set to %%TIME%% minutes.", + "afkstatusreset": "\/me [@%%NAME%%] Reset the afk status of @%%USERNAME%%.", + "inactivefor": "\/me [@%%NAME%%] @%%USERNAME%% has been inactive for %%TIME%%.", + "inactivelonger": "\/me [@%%NAME%%] @%%USERNAME%% has been inactive longer than %%BOTNAME%%'s been online.", + "autowoot": "\/me We recommend RCS for autowooting: http:\/\/rcs.radiant.dj\/", + "brandambassador": "\/me A Brand Ambassador is the voice of the plug.dj users. They promote events, engage the community and share the plug.dj message around the world. For more info: https:\/\/plug.dj\/ba", + "bouncerplusrank": "\/me [@%%NAME%%] You have to be manager or up to enable Bouncer+.", + "chatcleared": "\/me [@%%NAME%%] Cleared the chat.", + "deletechat": "\/me [@%%NAME%%] Cleared the chat of %%USERNAME%%.", + "commandslink": "\/me %%BOTNAME%% commands: %%LINK%%", + "eatcookie": "\/me eats a cookie.", + "nousercookie": "\/em doesn't see %%NAME%% in room and eats a cookie himself.", + "selfcookie": "\/me @%%NAME%%, you're a bit greedy, aren't you? Giving cookies to yourself, bah. Share some with other people!", + "cookie": "\/me @%%NAMETO%%, %%NAMEFROM%% %%COOKIE%%", + "cycleguardtime": "\/me [@%%NAME%%] The cycleguard is set to %%TIME%% minute(s).", + "dclookuprank": "\/me [@%%NAME%%] Only bouncers and above can do a lookup for others.", + "emojilist": "\/me Emoji list: %%LINK%%", + "notinwaitlist": "\/me @%%NAME%%, you are not on the waitlist.", + "eta": "\/me @%%NAME%% you will reach the booth in approximately %%TIME%%.", + "facebook": "\/me Like us on facebook: %%LINK%%", + "starterhelp": "\/me This image will get you started on plug: %%LINK%%", + "roulettejoin": "\/me @%%NAME%% joined the roulette! (!leave if you regret it.)", + "jointime": "\/me [@%%NAMEFROM%%] @%%USERNAME%% has been in the room for %%TIME%%.", + "kickrank": "\/me [@%%NAME%%] you can't kick users with an equal or higher rank than you!", + "kick": "\/me [@%%NAME%%], @%%USERNAME%% you are being kicked from the community for %%TIME%% minutes.", + "kill": "\/me Shutting down.", + "logout": "\/me [@%%NAME%%] Logging out %%BOTNAME%%", + "rouletteleave": "\/me @%%NAME%% left the roulette!", + "songlink": "\/me [@%%NAME%%] Link to current song: %%LINK%%", + "usedlockskip": "\/me [%%NAME%% used lockskip.]", + "lockskippos": "\/me [@%%NAME%%] Lockskip will now move the dj to position %%POSITION%%.", + "lockguardtime": "\/me [@%%NAME%%] The lockguard is set to %%TIME%% minute(s).", + "maxlengthtime": "\/me [@%%NAME%%] The maximum song duration is set to %%TIME%% minutes.", + "motdset": "\/me MotD set to: %%MSG%%", + "motdintervalset": "\/me MotD interval set to %%INTERVAL%%.", + "currentbotname": "\/me Bot name currently set to: %%BOTNAME%%", + "botnameset": "\/me Bot name now set to: %%BOTNAME%%", + "addbotwaitlist": "\/me @%%NAME%%, don't try to add me to the waitlist, please.", + "move": "\/me [%%NAME%% used move.]", + "mutednotime": "\/me [@%%NAME%%] Muted @%%USERNAME%%.", + "mutedmaxtime": "\/me [@%%NAME%%] You can only mute for maximum %%TIME%% minutes.", + "mutedtime": "\/me [@%%NAME%%] Muted @%%USERNAME%% for %%TIME%% minutes.", + "unmuted": "\/me [@%%NAME%%] Unmuted @%%USERNAME%%.", + "muterank": "\/me [@%%NAME%%] You can't mute persons with an equal or higher rank than you.", + "oplist": "\/me OP list: %%LINK%%", + "pong": "\/me Pong!", + "reload": "\/me Be right back.", + "removenotinwl": "\/me [@%%NAME%%] Specified user @%%USERNAME%% is not in the waitlist.", + "roomrules": "\/me Please find the room rules here: %%LINK%%", + "sessionstats": "\/me [@%%NAME%%] Total woots: %%WOOTS%%, total mehs: %%MEHS%%, total grabs: %%GRABS%%.", + "skip": "\/me [%%NAME%% used skip.]", + "madeby": "\/me This bot was made by %%NAME%%.", "activefor": "I have been active for %%TIME%%.", - "swapinvalid": "/me [@%%NAME%%] Invalid user specified. (No names with spaces!)", - "swapwlonly": "/me [@%%NAME%%] Please only swap users that are in the waitlist!", - "swapping": "/me Swapping %%NAME1%% with %%NAME2%%.", - "genres": "/me Please find the permissible room genres here: %%LINK%%", - "notbanned": "/me [@%%NAME%%] The user was not banned.", - "unmutedeveryone": "/me [@%%NAME%%] Unmuted everyone.", - "unmuteeveryonerank": "/me [@%%NAME%%] Only managers and up can unmute everyone at once.", - "notmuted": "/me [@%%NAME%%] that user wasn't muted.", - "unmuterank": "/me [@%%NAME%%] You can't unmute persons with an equal or higher rank than you.", - "commandscd": "/me [@%%NAME%%] The cooldown for commands by users is now set to %%TIME%% seconds.", - "voteratio": "/me [@%%NAME%%] @%%USERNAME%% ~ woots: %%WOOT%%, mehs: %%MEHS%%, ratio (w/m): %%RATIO%%.", - "website": "/me Please visit our website: %%LINK%%", - "youtube": "/me [%%NAME%%] Subscribe to us on youtube: %%LINK%%", - "songstatistics": "/me %%ARTIST%% - %%TITLE%%: %%WOOTS%%W/%%GRABS%%G/%%MEHS%%M." + "swapinvalid": "\/me [@%%NAME%%] Invalid user specified. (No names with spaces!)", + "swapwlonly": "\/me [@%%NAME%%] Please only swap users that are in the waitlist!", + "swapping": "\/me Swapping %%NAME1%% with %%NAME2%%.", + "genres": "\/me Please find the permissible room genres here: %%LINK%%", + "notbanned": "\/me [@%%NAME%%] The user was not banned.", + "unmutedeveryone": "\/me [@%%NAME%%] Unmuted everyone.", + "unmuteeveryonerank": "\/me [@%%NAME%%] Only managers and up can unmute everyone at once.", + "notmuted": "\/me [@%%NAME%%] that user wasn't muted.", + "unmuterank": "\/me [@%%NAME%%] You can't unmute persons with an equal or higher rank than you.", + "commandscd": "\/me [@%%NAME%%] The cooldown for commands by users is now set to %%TIME%% seconds.", + "voteratio": "\/me [@%%NAME%%] @%%USERNAME%% ~ woots: %%WOOT%%, mehs: %%MEHS%%, ratio (w\/m): %%RATIO%%.", + "website": "\/me Please visit our website: %%LINK%%", + "youtube": "\/me [%%NAME%%] Subscribe to us on youtube: %%LINK%%", + "songstatistics": "\/me %%ARTIST%% - %%TITLE%%: %%WOOTS%%W\/%%GRABS%%G\/%%MEHS%%M.", + "allownextsong": "\/me Allowing next song by @%%NAME%% to be played over limit." }