From e9d3959ddb5d80b23545b718d95a7f6167f36e69 Mon Sep 17 00:00:00 2001 From: Adam Mitchell Date: Sat, 10 Feb 2018 02:35:37 -0600 Subject: [PATCH 1/4] Bot DJ commands - Adding list join and leave, grab, and shuffle. --- README.md | 13 ++++++++ basicBot.js | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++ commands.md | 5 +++ 3 files changed, 112 insertions(+) diff --git a/README.md b/README.md index 246ed549..a0346ee3 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,19 @@ If this does not work, go to [basicBot.js](https://raw.githubusercontent.com/bas These can be found in [the commands list](commands.md). +### Bot DJ + +Bots can now join the wait list and dj along with you. See the noted commands in the commands section. +Anyone with a role of Bouncer or higher can run the bot's dj commands. + +Expected usage: +1. Ensure the account running the bot has at least one playlist and a playlist set to active and start the bot as usual. +2. Others can then type !listjoin, !jumpup, or !dj into the room chat to have your bot join the waitlist. +3. When done, type !listleave, !jumpdown, or !dj to have your bot leave the waitlist. + +Grab - Adding to the bot playlist: +Run the !grab command to tell the bot to grab the current song. The song will always be added to the playlist that appears at the top of the bot's grab popup menu and will be moved to the bottom of the playlist. + ### Blacklists Examples of blacklists can be found in [the customization repository](https://github.com/basicBot/custom/tree/master/blacklists). diff --git a/basicBot.js b/basicBot.js index e78e0c66..f1807930 100644 --- a/basicBot.js +++ b/basicBot.js @@ -2571,6 +2571,20 @@ } }, + grabCommand: { + command: 'grab', + rank: 'user', + 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 { + $('#grab').click(); + $('.pop-menu.grab > .menu > ul > li:first-child').mousedown(); + } + } + }, + helpCommand: { command: 'help', rank: 'user', @@ -2819,6 +2833,66 @@ } }, + listjoinCommand: { + command: ['listjoin', 'jumpup'], + 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 { + el = $('#dj-button'); + + // Check that bot is not already djing or waiting. + if(el.hasClass('is-join') || el.hasClass('is-wait')){ + el.click(); + } + } + } + }, + + listleaveCommand: { + command: ['listleave', 'jumpdown'], + 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 { + el = $('#dj-button'); + + // Check that the bot is djing or waiting. + if(el.hasClass('is-quit') || el.hasClass('is-leave')){ + el.click(); + setTimeout(function (){ + $('#dialog-confirm > .dialog-frame .submit').click(); + }, 500); + } + } + } + }, + + listtoggleCommand: { + command: ['listtoggle', 'botdj', 'dj'], + 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 { + el = $('#dj-button'); + el.click(); + + // If we are quitting or leaving, handle the confirmation popup. + if(el.hasClass('is-quit') || el.hasClass('is-leave')){ + setTimeout(function (){ + $('#dialog-confirm > .dialog-frame .submit').click(); + }, 500); + } + } + } + }, + lockCommand: { command: 'lock', rank: 'mod', @@ -3357,6 +3431,26 @@ } }, + + shuffleCommand: { + command: 'shuffle', + 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 { + $('#playlist-button').click(); + setTimeout(function(){ + $('#playlist-shuffle-button').click(); + }, 250); + setTimeout(function(){ + $('#playlist-button').click(); + }, 500); + } + } + }, + skipCommand: { command: ['skip', 'smartskip'], rank: 'bouncer', diff --git a/commands.md b/commands.md index 7eb358fd..307ea0cc 100644 --- a/commands.md +++ b/commands.md @@ -62,10 +62,14 @@ | !eta | (@user) | shows when user will reach the booth. | | !filter | — | toggles the chat filter. | | !forceskip / !fs | — | forceskips the current song. | +| !grab | - | Tells the bot to grab the current song and add to their playlist. (See Bot DJ section of README.md) | | !historyskip | — | toggles the history skip. | | !jointime | @user | shows how long the user has been in the room. | | !kick | (X) | kicks user for X minutes, default is 0.25 minutes (15 seconds). | | !kill | — | shut down the bot. | +| !listjoin / !jumpup | - | Tell the bot to start djing or join the wait list. (See Bot DJ section of README.md) | +| !listleave / !jumpdown | - | Tell the bot to stop djing or leave the wait list. (See Bot DJ section of README.md) | +| !listtoggle / !botdj / !dj | - | Shortcut to do !listjoin or !listleave as appropriate. (See Bot DJ section of README.md) | | !lockguard | — | toggle the lockguard. | | !lockskip | (reason) | skips, locks and moves the dj back up (the position can be set with `!skippos)`. | | !motd | (X)/(message) | when no argument is specified, returns the Message of the Day, when X is specified, the MotD is given every X songs, when "message" is given, it sets the MotD to message. | @@ -73,6 +77,7 @@ | !reload | — | reload the bot. | | !restricteta | — | toggles the restriction on eta: grey users can use it once an hour. | | !sessionstats | — | display stats for the current session. | +| !shuffle | - | Tell the bot to shuffle their playlist, useful after !grab if the bot is djing. (See Bot DJ section of README.md) | | !skip / !smartskip | (reason) | skips the dj using smartskip. actions such as locking and moving user depends on various factors (the position the dj is moved to can be set with `!skippos`). | | !status | — | display the bot's status and some settings. | | !timeguard | — | toggle the timeguard. | From 261eadbd851332d81533c4dd1d6b1a685e084fc7 Mon Sep 17 00:00:00 2001 From: Adam Mitchell Date: Mon, 12 Feb 2018 11:20:49 -0600 Subject: [PATCH 2/4] Adding playlist commands for Bot DJ. --- README.md | 4 +- basicBot.js | 186 ++++++++++++++++++++++++++++++++++++++++++---------- commands.md | 4 +- 3 files changed, 156 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index a0346ee3..6feaabc3 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,9 @@ Expected usage: 3. When done, type !listleave, !jumpdown, or !dj to have your bot leave the waitlist. Grab - Adding to the bot playlist: -Run the !grab command to tell the bot to grab the current song. The song will always be added to the playlist that appears at the top of the bot's grab popup menu and will be moved to the bottom of the playlist. +Run the !grab command to tell the bot to grab the current song. The song will be added to the bot's current active playlist. + +Users with Bouncer+ permissions in the room can also use !showplaylists or !botpls to list the bot's available playlists and !switchplaylist or !botpl to switch the bot's current playlist. ### Blacklists diff --git a/basicBot.js b/basicBot.js index f1807930..dbf25904 100644 --- a/basicBot.js +++ b/basicBot.js @@ -576,7 +576,120 @@ return msg; } }, + botInterfaceUtilities: { + grab: function() { + $('#grab').click(); + setTimeout(function (){ + $('.pop-menu.grab > .menu > ul > li > i.icon-check-purple').parent().mousedown(); + }, 500); + }, + listJoin: function() { + el = $('#dj-button'); + // Check that bot is not already djing or waiting. + if(el.hasClass('is-join') || el.hasClass('is-wait')){ + el.click(); + } + }, + listLeave: function() { + el = $('#dj-button'); + // Check that the bot is djing or waiting. + if(el.hasClass('is-quit') || el.hasClass('is-leave')){ + el.click(); + setTimeout(function (){ + $('#dialog-confirm > .dialog-frame .submit').click(); + }, 500); + } + }, + listToggle: function() { + el = $('#dj-button'); + el.click(); + // If we are quitting or leaving, handle the confirmation popup. + if(el.hasClass('is-quit') || el.hasClass('is-leave')){ + setTimeout(function (){ + $('#dialog-confirm > .dialog-frame .submit').click(); + }, 500); + } + }, + meh: function() { + $('#meh').click(); + }, + togglePlaylistDrawer: function(wait){ + if ($.isNumeric(wait)) { + // If we were passed a wait time, wait. + setTimeout(function(){ + $('#playlist-button').click(); + }, wait); + }else{ + // no wait time, do it now. + $('#playlist-button').click(); + } + }, + showPlaylists: function() { + basicBot.botInterfaceUtilities.togglePlaylistDrawer(); + setTimeout(function(){ + var playlists = $('#playlist-menu .row').map(function( index ){ + var lead = '--- '; + var trail = ' ---'; + if($(this).hasClass('selected') === true) { + lead = '==> '; + var trail = ' ==='; + } + var id = index+1; + + var msg = lead + id + ": " + $( this ).children('.name').text() + trail; + return msg; + }).get(); + var len = playlists.length; + var msg = ''; + var waittime = 250; + for(var i = 0; i < len; i++) { + waittime += 250; + setTimeout(function(msg){ + API.sendChat(msg); + }, waittime, playlists[i]); + } + basicBot.botInterfaceUtilities.togglePlaylistDrawer(1500); + }, 500); + }, + shufflePlaylist: function() { + basicBot.botInterfaceUtilities.togglePlaylistDrawer(); + setTimeout(function(){ + $('#playlist-shuffle-button').click(); + basicBot.botInterfaceUtilities.togglePlaylistDrawer(500); + }, 250); + }, + switchPlaylist: function(listname) { + basicBot.botInterfaceUtilities.togglePlaylistDrawer(); + if($.isNumeric(listname)) { + setTimeout(function(){ + $('#playlist-menu .container .row:nth-child('+listname+')').mouseup(); + setTimeout(function(){ + $('#playlist-menu .container .row:nth-child('+listname+')').children('.activate-button').click(); + }, 500); + }, 250); + }else{ + setTimeout(function(){ + el = $('#playlist-menu span:contains("'+listname+'")'); + if(el.length > 0){ + $('#playlist-menu span:contains("'+listname+'")').parent().mouseup(); + setTimeout(function(){ + $('#playlist-menu span:contains("'+listname+'")').siblings('.activate-button').click(); + }, 500); + } + }, 500); + } + basicBot.botInterfaceUtilities.togglePlaylistDrawer(500); + + setTimeout(function(){ + basicBot.botInterfaceUtilities.showPlaylists(); + }, 1000) + + }, + woot: function() { + $('#woot').click(); + } + }, roomUtilities: { rankToNumber: function(rankString) { var rankInt = null; @@ -2579,8 +2692,7 @@ if (this.type === 'exact' && chat.message.length !== cmd.length) return void(0); if (!basicBot.commands.executable(this.rank, chat)) return void(0); else { - $('#grab').click(); - $('.pop-menu.grab > .menu > ul > li:first-child').mousedown(); + basicBot.botInterfaceUtilities.grab(); } } }, @@ -2841,12 +2953,7 @@ if (this.type === 'exact' && chat.message.length !== cmd.length) return void(0); if (!basicBot.commands.executable(this.rank, chat)) return void(0); else { - el = $('#dj-button'); - - // Check that bot is not already djing or waiting. - if(el.hasClass('is-join') || el.hasClass('is-wait')){ - el.click(); - } + basicBot.botInterfaceUtilities.listJoin(); } } }, @@ -2859,15 +2966,7 @@ if (this.type === 'exact' && chat.message.length !== cmd.length) return void(0); if (!basicBot.commands.executable(this.rank, chat)) return void(0); else { - el = $('#dj-button'); - - // Check that the bot is djing or waiting. - if(el.hasClass('is-quit') || el.hasClass('is-leave')){ - el.click(); - setTimeout(function (){ - $('#dialog-confirm > .dialog-frame .submit').click(); - }, 500); - } + basicBot.botInterfaceUtilities.listLeave(); } } }, @@ -2880,15 +2979,7 @@ if (this.type === 'exact' && chat.message.length !== cmd.length) return void(0); if (!basicBot.commands.executable(this.rank, chat)) return void(0); else { - el = $('#dj-button'); - el.click(); - - // If we are quitting or leaving, handle the confirmation popup. - if(el.hasClass('is-quit') || el.hasClass('is-leave')){ - setTimeout(function (){ - $('#dialog-confirm > .dialog-frame .submit').click(); - }, 500); - } + basicBot.botInterfaceUtilities.listToggle(); } } }, @@ -3100,7 +3191,7 @@ if (this.type === 'exact' && chat.message.length !== cmd.length) return void(0); if (!basicBot.commands.executable(this.rank, chat)) return void(0); else { - $('#meh').click(); + basicBot.botInterfaceUtilities.meh(); } } }, @@ -3431,22 +3522,28 @@ } }, + showplaylistsCommand: { + command: ['showplaylists', 'botpls'], + rank: 'manager', + 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 { + basicBot.botInterfaceUtilities.showplaylists(); + } + } + }, shuffleCommand: { command: 'shuffle', - rank: 'mod', + rank: 'manager', 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 { - $('#playlist-button').click(); - setTimeout(function(){ - $('#playlist-shuffle-button').click(); - }, 250); - setTimeout(function(){ - $('#playlist-button').click(); - }, 500); + basicBot.botInterfaceUtilities.shufflePlaylist(); } } }, @@ -3734,6 +3831,23 @@ } }, + switchPlaylistCommand: { + command: ['switchplaylist', 'botpl'], + 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) return; + + var listname = msg.substring(cmd.length + 1); + basicBot.botInterfaceUtilities.switchPlaylist(listname); + } + } + }, + themeCommand: { command: 'theme', rank: 'user', @@ -4297,7 +4411,7 @@ if (this.type === 'exact' && chat.message.length !== cmd.length) return void(0); if (!basicBot.commands.executable(this.rank, chat)) return void(0); else { - $('#woot').click(); + basicBot.botInterfaceUtilities.woot(); } } }, diff --git a/commands.md b/commands.md index 307ea0cc..0bb0a9ba 100644 --- a/commands.md +++ b/commands.md @@ -38,8 +38,10 @@ | !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. | +| !showplaylists / !botpls | - | makes the bot list its playlists. (See Bot DJ section of README.md) | | !songstats | — | toggle song statistics. | | !swap | @user1 @user2 | swaps the position of two users in the waitlist. | +| !switchplaylist / !botpl | @playlistID | playlistID can be either the full playlist name, or the id of the playlist in the list displayed by !showplaylists (See Bot DJ section of README.md) | !unlock | — | unlock the waitlist. | | !welcome | — | toggle the welcome message on user join. | | !woot | — | makes the bot woot the current song. | @@ -62,7 +64,7 @@ | !eta | (@user) | shows when user will reach the booth. | | !filter | — | toggles the chat filter. | | !forceskip / !fs | — | forceskips the current song. | -| !grab | - | Tells the bot to grab the current song and add to their playlist. (See Bot DJ section of README.md) | +| !grab | - | Tells the bot to grab the current song and add to their current playlist. (See Bot DJ section of README.md) | | !historyskip | — | toggles the history skip. | | !jointime | @user | shows how long the user has been in the room. | | !kick | (X) | kicks user for X minutes, default is 0.25 minutes (15 seconds). | From 788cfb606c8aea894d1253d164eabf4395b869bf Mon Sep 17 00:00:00 2001 From: Adam Mitchell Date: Mon, 12 Feb 2018 11:56:49 -0600 Subject: [PATCH 3/4] Updating Bot DJ command permissions. --- README.md | 2 +- basicBot.js | 4 ++-- commands.md | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 6feaabc3..a8cfca06 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Expected usage: Grab - Adding to the bot playlist: Run the !grab command to tell the bot to grab the current song. The song will be added to the bot's current active playlist. -Users with Bouncer+ permissions in the room can also use !showplaylists or !botpls to list the bot's available playlists and !switchplaylist or !botpl to switch the bot's current playlist. +Users can also use !showplaylists or !botpls to list the bot's available playlists and !switchplaylist or !botpl to switch the bot's current playlist. ### Blacklists diff --git a/basicBot.js b/basicBot.js index dbf25904..9999958f 100644 --- a/basicBot.js +++ b/basicBot.js @@ -3524,7 +3524,7 @@ showplaylistsCommand: { command: ['showplaylists', 'botpls'], - rank: 'manager', + rank: 'bouncer', type: 'exact', functionality: function(chat, cmd) { if (this.type === 'exact' && chat.message.length !== cmd.length) return void(0); @@ -3833,7 +3833,7 @@ switchPlaylistCommand: { command: ['switchplaylist', 'botpl'], - rank: 'manager', + rank: 'bouncer', type: 'startsWith', functionality: function(chat, cmd) { if (this.type === 'exact' && chat.message.length !== cmd.length) return void(0); diff --git a/commands.md b/commands.md index 0bb0a9ba..107703b0 100644 --- a/commands.md +++ b/commands.md @@ -38,10 +38,8 @@ | !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. | -| !showplaylists / !botpls | - | makes the bot list its playlists. (See Bot DJ section of README.md) | | !songstats | — | toggle song statistics. | | !swap | @user1 @user2 | swaps the position of two users in the waitlist. | -| !switchplaylist / !botpl | @playlistID | playlistID can be either the full playlist name, or the id of the playlist in the list displayed by !showplaylists (See Bot DJ section of README.md) | !unlock | — | unlock the waitlist. | | !welcome | — | toggle the welcome message on user join. | | !woot | — | makes the bot woot the current song. | @@ -79,9 +77,11 @@ | !reload | — | reload the bot. | | !restricteta | — | toggles the restriction on eta: grey users can use it once an hour. | | !sessionstats | — | display stats for the current session. | +| !showplaylists / !botpls | - | makes the bot list its playlists. (See Bot DJ section of README.md) | | !shuffle | - | Tell the bot to shuffle their playlist, useful after !grab if the bot is djing. (See Bot DJ section of README.md) | | !skip / !smartskip | (reason) | skips the dj using smartskip. actions such as locking and moving user depends on various factors (the position the dj is moved to can be set with `!skippos`). | | !status | — | display the bot's status and some settings. | +| !switchplaylist / !botpl | @playlistID | playlistID can be either the full playlist name, or the id of the playlist in the list displayed by !showplaylists (See Bot DJ section of README.md) | | !timeguard | — | toggle the timeguard. | | !togglebl | — | toggle the blacklist. | | !togglemotd | — | toggle the motd. | From d336204a2ab9a775d723acc876bc2e7683ffcfca Mon Sep 17 00:00:00 2001 From: Adam Mitchell Date: Mon, 12 Feb 2018 12:08:40 -0600 Subject: [PATCH 4/4] Bugfix --- basicBot.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basicBot.js b/basicBot.js index 9999958f..2f8db1b5 100644 --- a/basicBot.js +++ b/basicBot.js @@ -3530,7 +3530,7 @@ if (this.type === 'exact' && chat.message.length !== cmd.length) return void(0); if (!basicBot.commands.executable(this.rank, chat)) return void(0); else { - basicBot.botInterfaceUtilities.showplaylists(); + basicBot.botInterfaceUtilities.showPlaylists(); } } },